@taladel/common 1.0.13 → 1.0.16
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/events/auth/user-created-event.d.ts +11 -0
- package/dist/events/auth/user-created-event.d.ts.map +1 -0
- package/dist/events/auth/user-created-event.js +3 -0
- package/dist/events/auth/user-created-event.js.map +1 -0
- package/dist/events/base-event.d.ts +6 -0
- package/dist/events/base-event.d.ts.map +1 -0
- package/dist/events/base-event.js +3 -0
- package/dist/events/base-event.js.map +1 -0
- package/dist/events/base-listener.d.ts +12 -0
- package/dist/events/base-listener.d.ts.map +1 -0
- package/dist/events/base-listener.js +34 -0
- package/dist/events/base-listener.js.map +1 -0
- package/dist/events/base-publisher.d.ts +9 -0
- package/dist/events/base-publisher.d.ts.map +1 -0
- package/dist/events/base-publisher.js +27 -0
- package/dist/events/base-publisher.js.map +1 -0
- package/dist/events/subjects.d.ts +12 -0
- package/dist/events/subjects.d.ts.map +1 -0
- package/dist/events/subjects.js +19 -0
- package/dist/events/subjects.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/services/jwt.service.d.ts +1 -0
- package/dist/services/jwt.service.d.ts.map +1 -1
- package/dist/services/jwt.service.js.map +1 -1
- package/package.json +4 -3
- package/src/events/auth/user-created-event.ts +17 -0
- package/src/events/base-event.ts +13 -0
- package/src/events/base-listener.ts +42 -0
- package/src/events/base-publisher.ts +30 -0
- package/src/events/subjects.ts +17 -0
- package/src/index.ts +8 -1
- package/src/services/jwt.service.ts +1 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Subjects } from '../subjects';
|
|
2
|
+
import { Event } from '../base-event';
|
|
3
|
+
export interface UserCreatedEvent extends Event {
|
|
4
|
+
subject: Subjects.UserCreated;
|
|
5
|
+
data: {
|
|
6
|
+
id: string;
|
|
7
|
+
email: string;
|
|
8
|
+
name: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=user-created-event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-created-event.d.ts","sourceRoot":"","sources":["../../../src/events/auth/user-created-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAQtC,MAAM,WAAW,gBAAiB,SAAQ,KAAK;IAC7C,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC;IAC9B,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-created-event.js","sourceRoot":"","sources":["../../../src/events/auth/user-created-event.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-event.d.ts","sourceRoot":"","sources":["../../src/events/base-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAStC,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,QAAQ,CAAC;IAClB,IAAI,EAAE,GAAG,CAAC;CACX"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-event.js","sourceRoot":"","sources":["../../src/events/base-event.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Consumer } from 'kafkajs';
|
|
2
|
+
import { Event } from './base-event';
|
|
3
|
+
export declare abstract class BaseListener<T extends Event> {
|
|
4
|
+
abstract subject: T['subject'];
|
|
5
|
+
abstract groupId: string;
|
|
6
|
+
abstract onMessage(data: T['data']): Promise<void>;
|
|
7
|
+
protected consumer: Consumer;
|
|
8
|
+
constructor(consumer: Consumer);
|
|
9
|
+
listen(): Promise<void>;
|
|
10
|
+
parseMessage(data: Buffer | null): T['data'];
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=base-listener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-listener.d.ts","sourceRoot":"","sources":["../../src/events/base-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsB,MAAM,SAAS,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AASrC,8BAAsB,YAAY,CAAC,CAAC,SAAS,KAAK;IAChD,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAElD,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBAEjB,QAAQ,EAAE,QAAQ;IAIxB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAc7B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC;CAM7C"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseListener = void 0;
|
|
4
|
+
// Abstract base class for all listeners.
|
|
5
|
+
// Each concrete listener (like UserCreatedListener) will:
|
|
6
|
+
// 1. Specify which topic (subject) to listen to
|
|
7
|
+
// 2. Specify the consumer group name (Kafka's version of queue groups)
|
|
8
|
+
// 3. Implement onMessage() to handle the event
|
|
9
|
+
//
|
|
10
|
+
// The Kafka Consumer is injected via constructor — we don't create it here.
|
|
11
|
+
class BaseListener {
|
|
12
|
+
constructor(consumer) {
|
|
13
|
+
this.consumer = consumer;
|
|
14
|
+
}
|
|
15
|
+
async listen() {
|
|
16
|
+
await this.consumer.connect();
|
|
17
|
+
await this.consumer.subscribe({ topic: this.subject, fromBeginning: true });
|
|
18
|
+
await this.consumer.run({
|
|
19
|
+
eachMessage: async ({ message }) => {
|
|
20
|
+
console.log(`Event received: ${this.subject}`);
|
|
21
|
+
const parsedData = this.parseMessage(message.value);
|
|
22
|
+
await this.onMessage(parsedData);
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
parseMessage(data) {
|
|
27
|
+
if (!data) {
|
|
28
|
+
throw new Error('Received empty message');
|
|
29
|
+
}
|
|
30
|
+
return JSON.parse(data.toString('utf8'));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.BaseListener = BaseListener;
|
|
34
|
+
//# sourceMappingURL=base-listener.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-listener.js","sourceRoot":"","sources":["../../src/events/base-listener.ts"],"names":[],"mappings":";;;AAGA,yCAAyC;AACzC,0DAA0D;AAC1D,kDAAkD;AAClD,yEAAyE;AACzE,iDAAiD;AACjD,EAAE;AACF,4EAA4E;AAC5E,MAAsB,YAAY;IAOhC,YAAY,QAAkB;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5E,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YACtB,WAAW,EAAE,KAAK,EAAE,EAAE,OAAO,EAAsB,EAAE,EAAE;gBACrD,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;gBAE/C,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACpD,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACnC,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,YAAY,CAAC,IAAmB;QAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC;CACF;AA/BD,oCA+BC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Producer } from 'kafkajs';
|
|
2
|
+
import { Event } from './base-event';
|
|
3
|
+
export declare abstract class BasePublisher<T extends Event> {
|
|
4
|
+
abstract subject: T['subject'];
|
|
5
|
+
protected producer: Producer;
|
|
6
|
+
constructor(producer: Producer);
|
|
7
|
+
publish(data: T['data']): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=base-publisher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-publisher.d.ts","sourceRoot":"","sources":["../../src/events/base-publisher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAQrC,8BAAsB,aAAa,CAAC,CAAC,SAAS,KAAK;IACjD,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IAC/B,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBAEjB,QAAQ,EAAE,QAAQ;IAIxB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAY9C"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BasePublisher = void 0;
|
|
4
|
+
// Abstract base class for all publishers.
|
|
5
|
+
// Each concrete publisher (like UserCreatedPublisher) will:
|
|
6
|
+
// 1. Specify which topic (subject) it publishes to
|
|
7
|
+
// 2. Call publish() with the typed data
|
|
8
|
+
//
|
|
9
|
+
// The Kafka Producer is injected via constructor — we don't create it here.
|
|
10
|
+
class BasePublisher {
|
|
11
|
+
constructor(producer) {
|
|
12
|
+
this.producer = producer;
|
|
13
|
+
}
|
|
14
|
+
async publish(data) {
|
|
15
|
+
await this.producer.send({
|
|
16
|
+
topic: this.subject,
|
|
17
|
+
messages: [
|
|
18
|
+
{
|
|
19
|
+
value: JSON.stringify(data),
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
});
|
|
23
|
+
console.log(`Event published to topic: ${this.subject}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.BasePublisher = BasePublisher;
|
|
27
|
+
//# sourceMappingURL=base-publisher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-publisher.js","sourceRoot":"","sources":["../../src/events/base-publisher.ts"],"names":[],"mappings":";;;AAGA,0CAA0C;AAC1C,4DAA4D;AAC5D,qDAAqD;AACrD,0CAA0C;AAC1C,EAAE;AACF,4EAA4E;AAC5E,MAAsB,aAAa;IAIjC,YAAY,QAAkB;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,IAAe;QAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACvB,KAAK,EAAE,IAAI,CAAC,OAAO;YACnB,QAAQ,EAAE;gBACR;oBACE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;iBAC5B;aACF;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;CACF;AApBD,sCAoBC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare enum Subjects {
|
|
2
|
+
UserCreated = "user:created",
|
|
3
|
+
ProductCreated = "product:created",
|
|
4
|
+
ProductUpdated = "product:updated",
|
|
5
|
+
ProductDeleted = "product:deleted",
|
|
6
|
+
OrderCreated = "order:created",
|
|
7
|
+
OrderUpdated = "order:updated",
|
|
8
|
+
OrderComplete = "order:complete",
|
|
9
|
+
OrderExpired = "order:expired",
|
|
10
|
+
PaymentComplete = "payment:complete"
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=subjects.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subjects.d.ts","sourceRoot":"","sources":["../../src/events/subjects.ts"],"names":[],"mappings":"AAGA,oBAAY,QAAQ;IAChB,WAAW,iBAAiB;IAE5B,cAAc,oBAAoB;IAClC,cAAc,oBAAoB;IAClC,cAAc,oBAAoB;IAElC,YAAY,kBAAkB;IAC9B,YAAY,kBAAkB;IAC9B,aAAa,mBAAmB;IAChC,YAAY,kBAAkB;IAE9B,eAAe,qBAAqB;CACrC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Subjects = void 0;
|
|
4
|
+
// Enum of all Kafka topic names.
|
|
5
|
+
// Think of this as the "master list" of all possible events in the system.
|
|
6
|
+
// If a topic isn't here, it doesn't exist.
|
|
7
|
+
var Subjects;
|
|
8
|
+
(function (Subjects) {
|
|
9
|
+
Subjects["UserCreated"] = "user:created";
|
|
10
|
+
Subjects["ProductCreated"] = "product:created";
|
|
11
|
+
Subjects["ProductUpdated"] = "product:updated";
|
|
12
|
+
Subjects["ProductDeleted"] = "product:deleted";
|
|
13
|
+
Subjects["OrderCreated"] = "order:created";
|
|
14
|
+
Subjects["OrderUpdated"] = "order:updated";
|
|
15
|
+
Subjects["OrderComplete"] = "order:complete";
|
|
16
|
+
Subjects["OrderExpired"] = "order:expired";
|
|
17
|
+
Subjects["PaymentComplete"] = "payment:complete";
|
|
18
|
+
})(Subjects || (exports.Subjects = Subjects = {}));
|
|
19
|
+
//# sourceMappingURL=subjects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subjects.js","sourceRoot":"","sources":["../../src/events/subjects.ts"],"names":[],"mappings":";;;AAAA,iCAAiC;AACjC,2EAA2E;AAC3E,2CAA2C;AAC3C,IAAY,QAaT;AAbH,WAAY,QAAQ;IAChB,wCAA4B,CAAA;IAE5B,8CAAkC,CAAA;IAClC,8CAAkC,CAAA;IAClC,8CAAkC,CAAA;IAElC,0CAA8B,CAAA;IAC9B,0CAA8B,CAAA;IAC9B,4CAAgC,CAAA;IAChC,0CAA8B,CAAA;IAE9B,gDAAoC,CAAA;AACtC,CAAC,EAbS,QAAQ,wBAAR,QAAQ,QAajB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,4 +14,9 @@ export * from './middlewares/error-handler';
|
|
|
14
14
|
export * from './middlewares/validate-request';
|
|
15
15
|
export * from './correlation/middleware';
|
|
16
16
|
export * from './correlation/types';
|
|
17
|
+
export * from './events/subjects';
|
|
18
|
+
export * from './events/base-listener';
|
|
19
|
+
export * from './events/base-publisher';
|
|
20
|
+
export * from './events/base-event';
|
|
21
|
+
export * from './events/auth/user-created-event';
|
|
17
22
|
//# 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;;GAEG;AACH,OAAO,EACH,uBAAuB,EACvB,gBAAgB,GACnB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,YAAY,EACR,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAE5C,cAAc,uBAAuB,CAAC;AAEtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAG/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACH,uBAAuB,EACvB,gBAAgB,GACnB,MAAM,0BAA0B,CAAC;AAElC;;GAEG;AACH,YAAY,EACR,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAE5C,cAAc,uBAAuB,CAAC;AAEtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAG/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,kCAAkC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -29,4 +29,9 @@ __exportStar(require("./middlewares/error-handler"), exports);
|
|
|
29
29
|
__exportStar(require("./middlewares/validate-request"), exports);
|
|
30
30
|
__exportStar(require("./correlation/middleware"), exports);
|
|
31
31
|
__exportStar(require("./correlation/types"), exports);
|
|
32
|
+
__exportStar(require("./events/subjects"), exports);
|
|
33
|
+
__exportStar(require("./events/base-listener"), exports);
|
|
34
|
+
__exportStar(require("./events/base-publisher"), exports);
|
|
35
|
+
__exportStar(require("./events/base-event"), exports);
|
|
36
|
+
__exportStar(require("./events/auth/user-created-event"), exports);
|
|
32
37
|
//# 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;;GAEG;AACH,uDAGkC;AAF9B,qHAAA,uBAAuB,OAAA;AACvB,8GAAA,gBAAgB,OAAA;AAWpB,yDAAuC;AACvC,8DAA4C;AAE5C,wDAAsC;AAEtC,yDAAuC;AACvC,8DAA4C;AAC5C,iEAA+C;AAG/C,2DAAyC;AACzC,sDAAoC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA;;GAEG;AACH,uDAGkC;AAF9B,qHAAA,uBAAuB,OAAA;AACvB,8GAAA,gBAAgB,OAAA;AAWpB,yDAAuC;AACvC,8DAA4C;AAE5C,wDAAsC;AAEtC,yDAAuC;AACvC,8DAA4C;AAC5C,iEAA+C;AAG/C,2DAAyC;AACzC,sDAAoC;AAEpC,oDAAkC;AAClC,yDAAuC;AACvC,0DAAwC;AACxC,sDAAoC;AAEpC,mEAAiD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.service.d.ts","sourceRoot":"","sources":["../../src/services/jwt.service.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"jwt.service.d.ts","sourceRoot":"","sources":["../../src/services/jwt.service.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CAEjB;AAED,MAAM,CAAC,OAAO,OAAO,UAAU;IAC3B,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM;IAWjD,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;CAUhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt.service.js","sourceRoot":"","sources":["../../src/services/jwt.service.ts"],"names":[],"mappings":";;;;;AAAA,gEAA+B;AAC/B,yDAAqD;
|
|
1
|
+
{"version":3,"file":"jwt.service.js","sourceRoot":"","sources":["../../src/services/jwt.service.ts"],"names":[],"mappings":";;;;;AAAA,gEAA+B;AAC/B,yDAAqD;AASrD,MAAqB,UAAU;IAC3B,MAAM,CAAC,aAAa,CAAC,OAAmB;QACpC,OAAO,sBAAG,CAAC,IAAI,CACX,OAAO,EACP,OAAO,CAAC,GAAG,CAAC,UAAW,EACvB;YACE,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,OAAO;SACnB,CACJ,CAAC;IACN,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,KAAa;QAC5B,IAAI,CAAC;YACL,OAAO,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW,EAAE;gBACtC,UAAU,EAAE,CAAC,OAAO,CAAC;aAC5B,CAAe,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,0BAAW,CAAC,GAAG,EAAE,0BAA0B,CAAC,CAAC;QAC3D,CAAC;IACL,CAAC;CAEJ;AAtBD,6BAsBC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taladel/common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "common utilities for microservices",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"clean": "rm -rf dist",
|
|
12
12
|
"build": "npm run clean && tsc",
|
|
13
|
-
"pub": "git add . && git commit -m \"Updates\" && npm version patch && npm
|
|
13
|
+
"pub": "npm run build && git add . && git commit -m \"Updates\" && npm version patch && npm publish --access public && git push && git push --tags"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [],
|
|
16
16
|
"author": "",
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"bcryptjs": "^3.0.3",
|
|
24
24
|
"cls-rtracer": "^2.6.3",
|
|
25
25
|
"express-validator": "^7.3.1",
|
|
26
|
-
"jsonwebtoken": "^9.0.3"
|
|
26
|
+
"jsonwebtoken": "^9.0.3",
|
|
27
|
+
"kafkajs": "^2.2.4"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"@types/bcryptjs": "^2.4.6",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Subjects } from '../subjects';
|
|
2
|
+
import { Event } from '../base-event';
|
|
3
|
+
|
|
4
|
+
// This is the CONCRETE event.
|
|
5
|
+
// It takes the generic Event interface and fills in the specifics:
|
|
6
|
+
// - subject is locked to 'user:created'
|
|
7
|
+
// - data is locked to this exact shape: { id, email, name }
|
|
8
|
+
//
|
|
9
|
+
// Think of Event as "event template", and this as "filled-out form".
|
|
10
|
+
export interface UserCreatedEvent extends Event {
|
|
11
|
+
subject: Subjects.UserCreated;
|
|
12
|
+
data: {
|
|
13
|
+
id: string;
|
|
14
|
+
email: string;
|
|
15
|
+
name: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Subjects } from './subjects';
|
|
2
|
+
|
|
3
|
+
// This is a TypeScript contract.
|
|
4
|
+
// Every event in the system MUST have:
|
|
5
|
+
// 1. A subject (the Kafka topic name from the Subjects enum)
|
|
6
|
+
// 2. A data payload (the shape depends on the specific event)
|
|
7
|
+
//
|
|
8
|
+
// Think of it like a form template: "All events need these two fields."
|
|
9
|
+
// The actual events (like UserCreatedEvent) will fill in the specifics.
|
|
10
|
+
export interface Event {
|
|
11
|
+
subject: Subjects;
|
|
12
|
+
data: any;
|
|
13
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Consumer, EachMessagePayload } from 'kafkajs';
|
|
2
|
+
import { Event } from './base-event';
|
|
3
|
+
|
|
4
|
+
// Abstract base class for all listeners.
|
|
5
|
+
// Each concrete listener (like UserCreatedListener) will:
|
|
6
|
+
// 1. Specify which topic (subject) to listen to
|
|
7
|
+
// 2. Specify the consumer group name (Kafka's version of queue groups)
|
|
8
|
+
// 3. Implement onMessage() to handle the event
|
|
9
|
+
//
|
|
10
|
+
// The Kafka Consumer is injected via constructor — we don't create it here.
|
|
11
|
+
export abstract class BaseListener<T extends Event> {
|
|
12
|
+
abstract subject: T['subject'];
|
|
13
|
+
abstract groupId: string; // Kafka's "consumer group" = NATS "queue group"
|
|
14
|
+
abstract onMessage(data: T['data']): Promise<void>;
|
|
15
|
+
|
|
16
|
+
protected consumer: Consumer;
|
|
17
|
+
|
|
18
|
+
constructor(consumer: Consumer) {
|
|
19
|
+
this.consumer = consumer;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async listen(): Promise<void> {
|
|
23
|
+
await this.consumer.connect();
|
|
24
|
+
await this.consumer.subscribe({ topic: this.subject, fromBeginning: true });
|
|
25
|
+
|
|
26
|
+
await this.consumer.run({
|
|
27
|
+
eachMessage: async ({ message }: EachMessagePayload) => {
|
|
28
|
+
console.log(`Event received: ${this.subject}`);
|
|
29
|
+
|
|
30
|
+
const parsedData = this.parseMessage(message.value);
|
|
31
|
+
await this.onMessage(parsedData);
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
parseMessage(data: Buffer | null): T['data'] {
|
|
37
|
+
if (!data) {
|
|
38
|
+
throw new Error('Received empty message');
|
|
39
|
+
}
|
|
40
|
+
return JSON.parse(data.toString('utf8'));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Producer } from 'kafkajs';
|
|
2
|
+
import { Event } from './base-event';
|
|
3
|
+
|
|
4
|
+
// Abstract base class for all publishers.
|
|
5
|
+
// Each concrete publisher (like UserCreatedPublisher) will:
|
|
6
|
+
// 1. Specify which topic (subject) it publishes to
|
|
7
|
+
// 2. Call publish() with the typed data
|
|
8
|
+
//
|
|
9
|
+
// The Kafka Producer is injected via constructor — we don't create it here.
|
|
10
|
+
export abstract class BasePublisher<T extends Event> {
|
|
11
|
+
abstract subject: T['subject'];
|
|
12
|
+
protected producer: Producer;
|
|
13
|
+
|
|
14
|
+
constructor(producer: Producer) {
|
|
15
|
+
this.producer = producer;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async publish(data: T['data']): Promise<void> {
|
|
19
|
+
await this.producer.send({
|
|
20
|
+
topic: this.subject,
|
|
21
|
+
messages: [
|
|
22
|
+
{
|
|
23
|
+
value: JSON.stringify(data),
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
console.log(`Event published to topic: ${this.subject}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Enum of all Kafka topic names.
|
|
2
|
+
// Think of this as the "master list" of all possible events in the system.
|
|
3
|
+
// If a topic isn't here, it doesn't exist.
|
|
4
|
+
export enum Subjects {
|
|
5
|
+
UserCreated = 'user:created',
|
|
6
|
+
|
|
7
|
+
ProductCreated = 'product:created',
|
|
8
|
+
ProductUpdated = 'product:updated',
|
|
9
|
+
ProductDeleted = 'product:deleted',
|
|
10
|
+
|
|
11
|
+
OrderCreated = 'order:created',
|
|
12
|
+
OrderUpdated = 'order:updated',
|
|
13
|
+
OrderComplete = 'order:complete',
|
|
14
|
+
OrderExpired = 'order:expired',
|
|
15
|
+
|
|
16
|
+
PaymentComplete = 'payment:complete',
|
|
17
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -25,4 +25,11 @@ export * from './middlewares/validate-request';
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
export * from './correlation/middleware';
|
|
28
|
-
export * from './correlation/types';
|
|
28
|
+
export * from './correlation/types';
|
|
29
|
+
|
|
30
|
+
export * from './events/subjects';
|
|
31
|
+
export * from './events/base-listener';
|
|
32
|
+
export * from './events/base-publisher';
|
|
33
|
+
export * from './events/base-event';
|
|
34
|
+
|
|
35
|
+
export * from './events/auth/user-created-event';
|