@cargolift-cdi/util-rabbitmq 0.1.64 → 0.1.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/integration-publisher.service.d.ts.map +1 -1
- package/dist/integration-publisher.service.js +1 -2
- package/dist/integration-publisher.service.js.map +1 -1
- package/dist/rabbitmq-connection.manager.d.ts +19 -0
- package/dist/rabbitmq-connection.manager.d.ts.map +1 -0
- package/dist/rabbitmq-connection.manager.js +57 -0
- package/dist/rabbitmq-connection.manager.js.map +1 -0
- package/dist/rabbitmq-publisher-dlq.service.d.ts +1 -1
- package/dist/rabbitmq-publisher-dlq.service.d.ts.map +1 -1
- package/dist/rabbitmq-publisher-dlq.service.js +61 -11
- package/dist/rabbitmq-publisher-dlq.service.js.map +1 -1
- package/dist/rabbitmq-publisher.service.d.ts +10 -7
- package/dist/rabbitmq-publisher.service.d.ts.map +1 -1
- package/dist/rabbitmq-publisher.service.js +18 -156
- package/dist/rabbitmq-publisher.service.js.map +1 -1
- package/dist/rabbitmq.constants.d.ts +7 -0
- package/dist/rabbitmq.constants.d.ts.map +1 -0
- package/dist/rabbitmq.constants.js +14 -0
- package/dist/rabbitmq.constants.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
export * from './rabbitmq-publisher.service.js';
|
|
6
6
|
export * from './rabbitmq-publisher-dlq.service.js';
|
|
7
7
|
export * from './integration-publisher.service.js';
|
|
8
|
+
export * from './rabbitmq-connection.manager.js';
|
|
9
|
+
export * from './rabbitmq.constants.js';
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,oCAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
export * from './rabbitmq-publisher.service.js';
|
|
6
6
|
export * from './rabbitmq-publisher-dlq.service.js';
|
|
7
7
|
export * from './integration-publisher.service.js';
|
|
8
|
+
export * from './rabbitmq-connection.manager.js';
|
|
9
|
+
export * from './rabbitmq.constants.js';
|
|
8
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,oCAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,iCAAiC,CAAC;AAChD,cAAc,qCAAqC,CAAC;AACpD,cAAc,oCAAoC,CAAC;AACnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-publisher.service.d.ts","sourceRoot":"","sources":["../src/integration-publisher.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAkB,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"integration-publisher.service.d.ts","sourceRoot":"","sources":["../src/integration-publisher.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAkB,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvE;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAA4B;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,GAAG,CAAC,EAAE;QACJ,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,qBAAqB,CAAC,EAAE,GAAG,CAAC;QAC5B,cAAc,CAAC,EAAE,GAAG,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAGD,qBACa,2BAA2B;IAMpC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0D;IAC1F,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAW;IAC/C,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAuE;gBAG7F,SAAS,EAAE,wBAAwB,EACnC,MAAM,EAAE,oBAAoB;IAG/C;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;CA8CxD"}
|
|
@@ -36,7 +36,6 @@ let IntegrationPublisherService = class IntegrationPublisherService {
|
|
|
36
36
|
source: {
|
|
37
37
|
ip: opts.envelope?.source?.ip || ip,
|
|
38
38
|
user_agent: opts.envelope?.source?.user_agent || userAgent,
|
|
39
|
-
...(opts.envelope?.source || {}),
|
|
40
39
|
},
|
|
41
40
|
timestamp: opts.envelope?.timestamp, // será preenchido pelo publisher se faltar
|
|
42
41
|
...opts.envelope,
|
|
@@ -44,7 +43,7 @@ let IntegrationPublisherService = class IntegrationPublisherService {
|
|
|
44
43
|
const headers = {
|
|
45
44
|
'x-correlation-id': envelope.correlation_id,
|
|
46
45
|
'x-trace': envelope?.trace || ctx?.trace,
|
|
47
|
-
'x-source': envelope
|
|
46
|
+
'x-source': JSON.stringify(envelope.source),
|
|
48
47
|
...(opts.headers || {}),
|
|
49
48
|
};
|
|
50
49
|
await this.publisher.publish(exchange, routingKey, envelope, (opts.payload || opts.req?.body), {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-publisher.service.js","sourceRoot":"","sources":["../src/integration-publisher.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"integration-publisher.service.js","sourceRoot":"","sources":["../src/integration-publisher.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { LoggerContextService } from '@cargolift-cdi/common';
|
|
2
|
+
/**
|
|
3
|
+
* Singleton leve para reutilizar conexão e (opcionalmente) canais de confirmação.
|
|
4
|
+
* Não implementa pool complexo; foco em reduzir overhead de connect.
|
|
5
|
+
*/
|
|
6
|
+
export declare class RabbitMQConnectionManager {
|
|
7
|
+
private readonly url;
|
|
8
|
+
private readonly logger?;
|
|
9
|
+
private static instance;
|
|
10
|
+
private connection?;
|
|
11
|
+
private connecting?;
|
|
12
|
+
private constructor();
|
|
13
|
+
static get(url: string, logger?: LoggerContextService): RabbitMQConnectionManager;
|
|
14
|
+
getConnection(): Promise<any>;
|
|
15
|
+
createConfirmChannel(): Promise<any>;
|
|
16
|
+
close(force?: boolean): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export declare function getRabbitConnectionManager(logger?: LoggerContextService): RabbitMQConnectionManager;
|
|
19
|
+
//# sourceMappingURL=rabbitmq-connection.manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rabbitmq-connection.manager.d.ts","sourceRoot":"","sources":["../src/rabbitmq-connection.manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAG7D;;;GAGG;AACH,qBAAa,yBAAyB;IAOhB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAN1E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA4B;IAGnD,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,UAAU,CAAC,CAAe;IAElC,OAAO;IAEP,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,oBAAoB;IAK/C,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC;IAkB7B,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC;IAMpC,KAAK,CAAC,KAAK,UAAQ;CAM1B;AAED,wBAAgB,0BAA0B,CAAC,MAAM,CAAC,EAAE,oBAAoB,6BAIvE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as amqplib from 'amqplib';
|
|
2
|
+
import { assertRabbitEnv } from './rabbitmq.constants.js';
|
|
3
|
+
/**
|
|
4
|
+
* Singleton leve para reutilizar conexão e (opcionalmente) canais de confirmação.
|
|
5
|
+
* Não implementa pool complexo; foco em reduzir overhead de connect.
|
|
6
|
+
*/
|
|
7
|
+
export class RabbitMQConnectionManager {
|
|
8
|
+
constructor(url, logger) {
|
|
9
|
+
this.url = url;
|
|
10
|
+
this.logger = logger;
|
|
11
|
+
}
|
|
12
|
+
static get(url, logger) {
|
|
13
|
+
if (!this.instance)
|
|
14
|
+
this.instance = new RabbitMQConnectionManager(url, logger);
|
|
15
|
+
return this.instance;
|
|
16
|
+
}
|
|
17
|
+
async getConnection() {
|
|
18
|
+
if (this.connection)
|
|
19
|
+
return this.connection;
|
|
20
|
+
if (this.connecting)
|
|
21
|
+
return this.connecting;
|
|
22
|
+
this.connecting = amqplib.connect(this.url).then((conn) => {
|
|
23
|
+
this.connection = conn;
|
|
24
|
+
conn.on('error', (err) => {
|
|
25
|
+
try {
|
|
26
|
+
this.logger?.error('RabbitMQ connection error', err, { application: { name: 'util-rabbitmq', function: 'RabbitMQConnectionManager' } });
|
|
27
|
+
}
|
|
28
|
+
catch { }
|
|
29
|
+
});
|
|
30
|
+
conn.on('close', () => {
|
|
31
|
+
this.connection = undefined;
|
|
32
|
+
});
|
|
33
|
+
return conn;
|
|
34
|
+
}).finally(() => { this.connecting = undefined; });
|
|
35
|
+
return this.connecting;
|
|
36
|
+
}
|
|
37
|
+
async createConfirmChannel() {
|
|
38
|
+
const conn = await this.getConnection();
|
|
39
|
+
const channel = await conn.createConfirmChannel();
|
|
40
|
+
return channel;
|
|
41
|
+
}
|
|
42
|
+
async close(force = false) {
|
|
43
|
+
if (force && this.connection) {
|
|
44
|
+
try {
|
|
45
|
+
await this.connection.close();
|
|
46
|
+
}
|
|
47
|
+
catch { }
|
|
48
|
+
this.connection = undefined;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function getRabbitConnectionManager(logger) {
|
|
53
|
+
assertRabbitEnv(logger);
|
|
54
|
+
const url = process.env.RABBITMQ_URL;
|
|
55
|
+
return RabbitMQConnectionManager.get(url, logger);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=rabbitmq-connection.manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rabbitmq-connection.manager.js","sourceRoot":"","sources":["../src/rabbitmq-connection.manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D;;;GAGG;AACH,MAAM,OAAO,yBAAyB;IAOpC,YAAqC,GAAW,EAAmB,MAA6B;QAA3D,QAAG,GAAH,GAAG,CAAQ;QAAmB,WAAM,GAAN,MAAM,CAAuB;IAAG,CAAC;IAEpG,MAAM,CAAC,GAAG,CAAC,GAAW,EAAE,MAA6B;QACnD,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC/E,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QAC5C,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QAE5C,IAAI,CAAC,UAAU,GAAI,OAAe,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAS,EAAE,EAAE;YACtE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAQ,EAAE,EAAE;gBACxB,IAAI,CAAC;oBAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,2BAA2B,EAAE,GAAU,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,2BAA2B,EAAE,EAAE,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YAClK,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACpB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;YAC9B,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnD,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,oBAAoB;QACxB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK;QACvB,IAAI,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC7B,IAAI,CAAC;gBAAC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAC/C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC9B,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,0BAA0B,CAAC,MAA6B;IACtE,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAa,CAAC;IACtC,OAAO,yBAAyB,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -8,5 +8,5 @@ import { LoggerContextService } from '@cargolift-cdi/common';
|
|
|
8
8
|
* @param dlqExchange Exchange da DLQ (opcional)
|
|
9
9
|
* @param dlqRoutingKey Routing key da DLQ (opcional)
|
|
10
10
|
*/
|
|
11
|
-
export declare function publishToDlqAndAck(channel: RabbitMQChannel, originalMsg: RabbitMQMessage, logger: LoggerContextService, error:
|
|
11
|
+
export declare function publishToDlqAndAck(channel: RabbitMQChannel, originalMsg: RabbitMQMessage, logger: LoggerContextService, error: unknown, dlqExchange?: string, dlqRoutingKey?: string): void;
|
|
12
12
|
//# sourceMappingURL=rabbitmq-publisher-dlq.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rabbitmq-publisher-dlq.service.d.ts","sourceRoot":"","sources":["../src/rabbitmq-publisher-dlq.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAiB,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE5E;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,eAAe,EAC5B,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"rabbitmq-publisher-dlq.service.d.ts","sourceRoot":"","sources":["../src/rabbitmq-publisher-dlq.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAiB,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE5E;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,eAAe,EAC5B,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,OAAO,EACd,WAAW,SAAc,EACzB,aAAa,SAAmB,QA2DjC"}
|
|
@@ -8,20 +8,70 @@ import { BusinessError } from '@cargolift-cdi/common';
|
|
|
8
8
|
* @param dlqRoutingKey Routing key da DLQ (opcional)
|
|
9
9
|
*/
|
|
10
10
|
export function publishToDlqAndAck(channel, originalMsg, logger, error, dlqExchange = 'email.dlx', dlqRoutingKey = 'email.send.dlq') {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
11
|
+
let normalized = { name: 'Error', message: 'Erro desconhecido' };
|
|
12
|
+
if (error instanceof Error) {
|
|
13
|
+
normalized = { name: error.name, message: error.message, stack: error.stack };
|
|
14
|
+
}
|
|
15
|
+
else if (typeof error === 'string') {
|
|
16
|
+
normalized = { name: 'Error', message: error };
|
|
17
|
+
}
|
|
18
|
+
else if (error && typeof error === 'object') {
|
|
19
|
+
try {
|
|
20
|
+
const anyErr = error;
|
|
21
|
+
normalized = { name: anyErr.name || 'Error', message: anyErr.message || JSON.stringify(anyErr), stack: anyErr.stack };
|
|
22
|
+
}
|
|
23
|
+
catch { }
|
|
24
|
+
}
|
|
18
25
|
if (error instanceof BusinessError) {
|
|
19
|
-
logger.businessError(
|
|
26
|
+
logger.businessError(normalized.message, { error: normalized });
|
|
20
27
|
}
|
|
21
28
|
else {
|
|
22
|
-
logger.error(
|
|
29
|
+
logger.error(normalized.message, { error: normalized });
|
|
30
|
+
}
|
|
31
|
+
const originalHeaders = originalMsg.properties.headers || {};
|
|
32
|
+
const headers = {
|
|
33
|
+
...originalHeaders,
|
|
34
|
+
'x-trace': logger.getContext().trace || originalHeaders['x-trace'] || `trace-missing:${process.env.npm_package_name}`,
|
|
35
|
+
'x-error-reason': normalized.message,
|
|
36
|
+
'x-exception-name': normalized.name,
|
|
37
|
+
};
|
|
38
|
+
if (normalized.stack) {
|
|
39
|
+
headers['x-error-stacktrace'] = normalized.stack.substring(0, 4000); // limita tamanho
|
|
40
|
+
}
|
|
41
|
+
// Payload enriquecido mantendo compatibilidade (fallback para conteúdo original)
|
|
42
|
+
let buffer = originalMsg.content;
|
|
43
|
+
try {
|
|
44
|
+
const enriched = {
|
|
45
|
+
failedAt: new Date().toISOString(),
|
|
46
|
+
error: normalized,
|
|
47
|
+
originalHeaders,
|
|
48
|
+
// tenta parsear original para permitir reprocessamento com contexto
|
|
49
|
+
originalPayload: safeParse(originalMsg.content),
|
|
50
|
+
};
|
|
51
|
+
buffer = Buffer.from(JSON.stringify(enriched));
|
|
52
|
+
headers['x-dlq-enriched'] = '1';
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
headers['x-dlq-enriched'] = '0';
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
channel.publish(dlqExchange, dlqRoutingKey, buffer, { headers });
|
|
59
|
+
channel.ack(originalMsg);
|
|
60
|
+
}
|
|
61
|
+
catch (pubErr) {
|
|
62
|
+
logger.error('Falha ao publicar mensagem em DLQ', { originalError: normalized, publishError: pubErr });
|
|
63
|
+
try {
|
|
64
|
+
channel.ack(originalMsg);
|
|
65
|
+
}
|
|
66
|
+
catch { /* evita loop */ }
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function safeParse(buf) {
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(buf.toString('utf8'));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return undefined;
|
|
23
75
|
}
|
|
24
|
-
channel.publish(dlqExchange, dlqRoutingKey, originalMsg.content, { headers });
|
|
25
|
-
channel.ack(originalMsg);
|
|
26
76
|
}
|
|
27
77
|
//# sourceMappingURL=rabbitmq-publisher-dlq.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rabbitmq-publisher-dlq.service.js","sourceRoot":"","sources":["../src/rabbitmq-publisher-dlq.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAwB,MAAM,uBAAuB,CAAC;AAE5E;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAwB,EACxB,WAA4B,EAC5B,MAA4B,EAC5B,
|
|
1
|
+
{"version":3,"file":"rabbitmq-publisher-dlq.service.js","sourceRoot":"","sources":["../src/rabbitmq-publisher-dlq.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,12 +4,6 @@ import { LoggerContextService } from '@cargolift-cdi/common';
|
|
|
4
4
|
export declare class RabbitMQPublisherService {
|
|
5
5
|
private readonly logger;
|
|
6
6
|
constructor(logger: LoggerContextService);
|
|
7
|
-
/**
|
|
8
|
-
* Emite mensagem diretamente com amqplib para garantir que headers virem nas Properties.
|
|
9
|
-
* - pattern: nome da fila/routingKey (ex: 'notifications')
|
|
10
|
-
* - payload: corpo da mensagem
|
|
11
|
-
* - opts: opções opcionais: { exchange, exchangeType, routingKey, headers }
|
|
12
|
-
*/
|
|
13
7
|
/**
|
|
14
8
|
* Publica mensagem em exchange usando ConfirmChannel para garantir confirmação (publisher confirms).
|
|
15
9
|
* Boas práticas amqplib aplicadas:
|
|
@@ -34,6 +28,15 @@ export declare class RabbitMQPublisherService {
|
|
|
34
28
|
persistent?: boolean;
|
|
35
29
|
timeoutMs?: number;
|
|
36
30
|
serialize?: (data: any) => Buffer;
|
|
37
|
-
|
|
31
|
+
returnMeta?: boolean;
|
|
32
|
+
}): Promise<void | {
|
|
33
|
+
correlationId: string;
|
|
34
|
+
exchange: string;
|
|
35
|
+
routingKey: string;
|
|
36
|
+
pattern: string;
|
|
37
|
+
sizeBytes: number;
|
|
38
|
+
durationMs: number;
|
|
39
|
+
confirmedAt: string;
|
|
40
|
+
}>;
|
|
38
41
|
}
|
|
39
42
|
//# sourceMappingURL=rabbitmq-publisher.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rabbitmq-publisher.service.d.ts","sourceRoot":"","sources":["../src/rabbitmq-publisher.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rabbitmq-publisher.service.d.ts","sourceRoot":"","sources":["../src/rabbitmq-publisher.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAO7D,qBACa,wBAAwB;IACO,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,oBAAoB;IAEvF;;;;;;;;;;;;;;OAcG;IACG,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,GAAG,EACZ,IAAI,CAAC,EAAE;QACL,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,qBAAqB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;QACpD,cAAc,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACtC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,MAAM,CAAC;QAClC,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,GACA,OAAO,CAAC,IAAI,GAAG;QAChB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CAgHH"}
|
|
@@ -11,148 +11,14 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
13
|
import { Inject, Injectable } from '@nestjs/common';
|
|
14
|
-
import * as amqp from 'amqplib';
|
|
15
14
|
import { LoggerContextService } from '@cargolift-cdi/common';
|
|
16
15
|
import { v4 as uuidv4 } from 'uuid';
|
|
16
|
+
import { getRabbitConnectionManager } from './rabbitmq-connection.manager.js';
|
|
17
|
+
import { DEFAULT_PUBLISH_TIMEOUT_MS } from './rabbitmq.constants.js';
|
|
17
18
|
let RabbitMQPublisherService = class RabbitMQPublisherService {
|
|
18
|
-
//constructor(private readonly logger: LoggerContextService) { }
|
|
19
19
|
constructor(logger) {
|
|
20
20
|
this.logger = logger;
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Emite mensagem diretamente com amqplib para garantir que headers virem nas Properties.
|
|
24
|
-
* - pattern: nome da fila/routingKey (ex: 'notifications')
|
|
25
|
-
* - payload: corpo da mensagem
|
|
26
|
-
* - opts: opções opcionais: { exchange, exchangeType, routingKey, headers }
|
|
27
|
-
*/
|
|
28
|
-
/*
|
|
29
|
-
async emit(
|
|
30
|
-
pattern: string,
|
|
31
|
-
payload: any,
|
|
32
|
-
opts?: {
|
|
33
|
-
exchange?: string;
|
|
34
|
-
exchangeType?: string;
|
|
35
|
-
routingKey?: string;
|
|
36
|
-
headers?: Record<string, any>;
|
|
37
|
-
},
|
|
38
|
-
): Promise<void> {
|
|
39
|
-
const ctx = this.logger.getContext();
|
|
40
|
-
const headers: Record<string, any> = { ...(opts?.headers || {}) };
|
|
41
|
-
|
|
42
|
-
if (ctx?.correlation_id) headers['x-correlation-id'] = ctx.correlation_id;
|
|
43
|
-
if (ctx?.trace) headers['x-trace'] = ctx.trace;
|
|
44
|
-
if (ctx?.producer) headers['x-producer'] = ctx.producer;
|
|
45
|
-
|
|
46
|
-
headers['pattern'] = pattern;
|
|
47
|
-
const messageBody = { pattern, data: payload };
|
|
48
|
-
|
|
49
|
-
// URL do RabbitMQ (use a mesma que está no ClientsModule)
|
|
50
|
-
const url = process.env.RABBITMQ_URL;
|
|
51
|
-
if (!url) throw new Error('RABBITMQ_URL não definido');
|
|
52
|
-
|
|
53
|
-
const connection = await amqp.connect(url);
|
|
54
|
-
|
|
55
|
-
// Evita crash por "Unhandled 'error' event" e garante log com contexto atual
|
|
56
|
-
connection.on('error', (err) => {
|
|
57
|
-
try {
|
|
58
|
-
this.logger?.error('AMQP connection error', err as any,
|
|
59
|
-
{
|
|
60
|
-
application: { name: "util-rabbitmq", function: "RabbitMQPublisherService", action: "emit" },
|
|
61
|
-
data: { rabbitmq: { url, queue: pattern } }
|
|
62
|
-
});
|
|
63
|
-
} catch { }
|
|
64
|
-
});
|
|
65
|
-
connection.on('close', () => {
|
|
66
|
-
// intentionally left blank
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
let channel: amqp.Channel | null = null;
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
channel = await connection.createChannel();
|
|
73
|
-
|
|
74
|
-
channel.on('error', (err) => {
|
|
75
|
-
// intentionally left blank
|
|
76
|
-
});
|
|
77
|
-
channel.on('close', () => {
|
|
78
|
-
// intentionally left blank
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Alinhar arguments da fila com o que já foi criado (ex.: x-dead-letter-exchange)
|
|
82
|
-
const queueArgs: Record<string, any> = {};
|
|
83
|
-
if (process.env.RABBITMQ_DLX) {
|
|
84
|
-
queueArgs['x-dead-letter-exchange'] = process.env.RABBITMQ_DLX;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Declare a fila com os mesmos argumentos (se houver) para evitar PRECONDITION_FAILED
|
|
88
|
-
const queueOptions = Object.keys(queueArgs).length
|
|
89
|
-
? { durable: true, arguments: queueArgs }
|
|
90
|
-
: { durable: true };
|
|
91
|
-
|
|
92
|
-
const content = Buffer.from(JSON.stringify(messageBody));
|
|
93
|
-
|
|
94
|
-
// Prioridade: opts.exchange > variável de ambiente RABBITMQ_EXCHANGE > enviar direto para fila
|
|
95
|
-
const exchangeToUse = opts?.exchange ?? process.env.RABBITMQ_EXCHANGE;
|
|
96
|
-
const exchangeType = opts?.exchangeType ?? (process.env.RABBITMQ_EXCHANGE_TYPE as any) ?? 'direct';
|
|
97
|
-
const routingKey = opts?.routingKey ?? pattern;
|
|
98
|
-
|
|
99
|
-
if (exchangeToUse) {
|
|
100
|
-
await channel.assertExchange(exchangeToUse, exchangeType, { durable: true });
|
|
101
|
-
const published = channel.publish(exchangeToUse, routingKey, content, {
|
|
102
|
-
persistent: true,
|
|
103
|
-
headers,
|
|
104
|
-
});
|
|
105
|
-
if (!published) {
|
|
106
|
-
// backpressure: aguardar 'drain' se necessário (simplificado)
|
|
107
|
-
await new Promise<void>((res) => channel!.once('drain', () => res()));
|
|
108
|
-
}
|
|
109
|
-
this.logger.info(`Mensagem publicada no exchange "${exchangeToUse}" com routingKey "${routingKey}"`, {
|
|
110
|
-
application: { name: "util-rabbitmq", function: "RabbitMQPublisherService", action: "emit" },
|
|
111
|
-
data: { rabbitmq: { queue: pattern, exchange: exchangeToUse, routingKey } },
|
|
112
|
-
});
|
|
113
|
-
} else {
|
|
114
|
-
// certifica que a fila existe antes de enviar diretamente
|
|
115
|
-
|
|
116
|
-
// await channel.assertQueue(pattern, queueOptions);
|
|
117
|
-
// channel.sendToQueue(pattern, content, {
|
|
118
|
-
// persistent: true,
|
|
119
|
-
// headers,
|
|
120
|
-
// });
|
|
121
|
-
|
|
122
|
-
channel.sendToQueue(pattern, content, {
|
|
123
|
-
persistent: true,
|
|
124
|
-
headers,
|
|
125
|
-
});
|
|
126
|
-
this.logger.info(`Mensagem publicada na fila do RabbitMQ "${pattern}"`, {
|
|
127
|
-
application: { name: "util-rabbitmq", function: "RabbitMQPublisherService", action: "emit" },
|
|
128
|
-
data: { rabbitmq: { queue: pattern } },
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
await channel.close();
|
|
133
|
-
} catch (err) {
|
|
134
|
-
// Loga com contexto e relança para que o controller/filtro capture
|
|
135
|
-
this.logger.error(`Erro ao publicar mensagem no RabbitMQ "${pattern}"`, err as any, {
|
|
136
|
-
application: { name: "util-rabbitmq", function: "RabbitMQPublisherService", action: "emit" },
|
|
137
|
-
data: { rabbitmq: { queue: pattern } },
|
|
138
|
-
});
|
|
139
|
-
throw err;
|
|
140
|
-
} finally {
|
|
141
|
-
try {
|
|
142
|
-
if (channel) {
|
|
143
|
-
try {
|
|
144
|
-
await channel.close();
|
|
145
|
-
} catch { }
|
|
146
|
-
}
|
|
147
|
-
} catch { }
|
|
148
|
-
try {
|
|
149
|
-
await connection.close();
|
|
150
|
-
} catch {
|
|
151
|
-
// ignora erros ao fechar conexão
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
*/
|
|
156
22
|
/**
|
|
157
23
|
* Publica mensagem em exchange usando ConfirmChannel para garantir confirmação (publisher confirms).
|
|
158
24
|
* Boas práticas amqplib aplicadas:
|
|
@@ -200,23 +66,11 @@ let RabbitMQPublisherService = class RabbitMQPublisherService {
|
|
|
200
66
|
};
|
|
201
67
|
const serialize = opts?.serialize || ((data) => Buffer.from(JSON.stringify(data)));
|
|
202
68
|
const content = serialize(messageBody);
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
throw new Error('RABBITMQ_URL não definido');
|
|
206
|
-
const connection = await amqp.connect(url);
|
|
207
|
-
connection.on('error', (err) => {
|
|
208
|
-
try {
|
|
209
|
-
this.logger?.error('AMQP connection error', err, {
|
|
210
|
-
application: { ...this.logger.getContext().application, function: 'RabbitMQPublisherService', action: 'publish', method: undefined },
|
|
211
|
-
data: { rabbitmq: { url, exchange, routingKey } },
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
catch { }
|
|
215
|
-
});
|
|
216
|
-
connection.on('close', () => { });
|
|
69
|
+
const started = performance.now?.() || Date.now();
|
|
70
|
+
const manager = getRabbitConnectionManager(this.logger);
|
|
217
71
|
let channel = null;
|
|
218
72
|
try {
|
|
219
|
-
channel = await
|
|
73
|
+
channel = await manager.createConfirmChannel();
|
|
220
74
|
channel.on('error', (err) => {
|
|
221
75
|
this.logger.error('Erro no ConfirmChannel', err, {
|
|
222
76
|
application: { ...this.logger.getContext().application, function: 'RabbitMQPublisherService', action: 'publish', method: undefined },
|
|
@@ -233,7 +87,7 @@ let RabbitMQPublisherService = class RabbitMQPublisherService {
|
|
|
233
87
|
contentType: 'application/json',
|
|
234
88
|
...opts?.publishOptions,
|
|
235
89
|
};
|
|
236
|
-
const timeoutMs = opts?.timeoutMs ??
|
|
90
|
+
const timeoutMs = opts?.timeoutMs ?? DEFAULT_PUBLISH_TIMEOUT_MS;
|
|
237
91
|
await new Promise((resolve, reject) => {
|
|
238
92
|
let settled = false;
|
|
239
93
|
const timer = setTimeout(() => {
|
|
@@ -265,6 +119,18 @@ let RabbitMQPublisherService = class RabbitMQPublisherService {
|
|
|
265
119
|
application: { ...this.logger.getContext().application, function: 'RabbitMQPublisherService', action: 'publish', method: undefined },
|
|
266
120
|
data: { rabbitmq: { exchange, routingKey, pattern } },
|
|
267
121
|
});
|
|
122
|
+
if (opts?.returnMeta) {
|
|
123
|
+
const end = performance.now?.() || Date.now();
|
|
124
|
+
return {
|
|
125
|
+
correlationId: envelope.correlation_id,
|
|
126
|
+
exchange,
|
|
127
|
+
routingKey,
|
|
128
|
+
pattern,
|
|
129
|
+
sizeBytes: content.byteLength,
|
|
130
|
+
durationMs: +(end - started),
|
|
131
|
+
confirmedAt: new Date().toISOString()
|
|
132
|
+
};
|
|
133
|
+
}
|
|
268
134
|
}
|
|
269
135
|
catch (err) {
|
|
270
136
|
this.logger.error(`Erro ao publicar (publishConfirm) no exchange "${exchange}"`, err, {
|
|
@@ -283,10 +149,6 @@ let RabbitMQPublisherService = class RabbitMQPublisherService {
|
|
|
283
149
|
}
|
|
284
150
|
}
|
|
285
151
|
catch { }
|
|
286
|
-
try {
|
|
287
|
-
await connection.close();
|
|
288
|
-
}
|
|
289
|
-
catch { }
|
|
290
152
|
}
|
|
291
153
|
}
|
|
292
154
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rabbitmq-publisher.service.js","sourceRoot":"","sources":["../src/rabbitmq-publisher.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"rabbitmq-publisher.service.js","sourceRoot":"","sources":["../src/rabbitmq-publisher.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LoggerContextService } from '@cargolift-cdi/common';
|
|
2
|
+
export declare const DEFAULT_EXCHANGE: string;
|
|
3
|
+
export declare const DEFAULT_EXCHANGE_TYPE: string;
|
|
4
|
+
export declare const DEFAULT_ALTERNATE_EXCHANGE: string;
|
|
5
|
+
export declare const DEFAULT_PUBLISH_TIMEOUT_MS: number;
|
|
6
|
+
export declare function assertRabbitEnv(logger?: LoggerContextService): void;
|
|
7
|
+
//# sourceMappingURL=rabbitmq.constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rabbitmq.constants.d.ts","sourceRoot":"","sources":["../src/rabbitmq.constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D,eAAO,MAAM,gBAAgB,QAAyD,CAAC;AACvF,eAAO,MAAM,qBAAqB,QAAgD,CAAC;AACnF,eAAO,MAAM,0BAA0B,QAAsE,CAAC;AAC9G,eAAO,MAAM,0BAA0B,QAA0D,CAAC;AAElG,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,oBAAoB,QAQ5D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const DEFAULT_EXCHANGE = process.env.RABBITMQ_EXCHANGE || 'integration.inbound';
|
|
2
|
+
export const DEFAULT_EXCHANGE_TYPE = process.env.RABBITMQ_EXCHANGE_TYPE || 'topic';
|
|
3
|
+
export const DEFAULT_ALTERNATE_EXCHANGE = process.env.RABBITMQ_ALTERNATE_EXCHANGE || 'integration.inbound.ae';
|
|
4
|
+
export const DEFAULT_PUBLISH_TIMEOUT_MS = Number(process.env.RABBITMQ_PUBLISH_TIMEOUT_MS || 5000);
|
|
5
|
+
export function assertRabbitEnv(logger) {
|
|
6
|
+
const required = ['RABBITMQ_URL'];
|
|
7
|
+
const missing = required.filter((k) => !process.env[k]);
|
|
8
|
+
if (missing.length) {
|
|
9
|
+
const msg = `Variáveis de ambiente ausentes para RabbitMQ: ${missing.join(', ')}`;
|
|
10
|
+
logger?.error?.(msg, { application: { name: 'util-rabbitmq', function: 'assertRabbitEnv' } });
|
|
11
|
+
throw new Error(msg);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=rabbitmq.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rabbitmq.constants.js","sourceRoot":"","sources":["../src/rabbitmq.constants.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,qBAAqB,CAAC;AACvF,MAAM,CAAC,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC;AACnF,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,wBAAwB,CAAC;AAC9G,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,IAAI,CAAC,CAAC;AAElG,MAAM,UAAU,eAAe,CAAC,MAA6B;IAC3D,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,iDAAiD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAClF,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAC9F,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|