@eratu/common 1.0.18 → 1.0.20
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/build/__tests__/enum/roles.test.js +1 -1
- package/build/__tests__/errors/request-validation-error.test.js +1 -3
- package/build/__tests__/events/base-listener.test.js +4 -3
- package/build/__tests__/events/streams.test.js +1 -7
- package/build/__tests__/events/subjects.test.js +2 -2
- package/build/__tests__/middlewares/current-user.test.js +1 -1
- package/build/__tests__/middlewares/require-auth.test.js +2 -2
- package/build/__tests__/nats-wrapper.test.js +2 -1
- package/build/__tests__/redis-wrapper.test.js +2 -1
- package/build/enum/image.d.ts +14 -0
- package/build/enum/image.js +18 -0
- package/build/errors/conflict-error.d.ts +9 -0
- package/build/errors/conflict-error.js +16 -0
- package/build/errors/forbidden-error.d.ts +1 -1
- package/build/errors/forbidden-error.js +1 -1
- package/build/errors/internal-error.d.ts +9 -0
- package/build/errors/internal-error.js +16 -0
- package/build/errors/not-authorized-error.d.ts +1 -1
- package/build/errors/not-authorized-error.js +1 -1
- package/build/errors/not-found-error.d.ts +1 -1
- package/build/errors/not-found-error.js +2 -2
- package/build/errors/request-validation-error.js +1 -1
- package/build/events/event-types/auth/admin-deleted-event.d.ts +11 -0
- package/build/events/event-types/auth/admin-deleted-event.js +2 -0
- package/build/events/event-types/auth/admin-signed-up-event.d.ts +13 -0
- package/build/events/event-types/auth/admin-signed-up-event.js +2 -0
- package/build/events/event-types/auth/admin-updated-event.d.ts +14 -0
- package/build/events/event-types/auth/admin-updated-event.js +2 -0
- package/build/events/event-types/auth/author-deleted-event.d.ts +2 -2
- package/build/events/event-types/auth/author-signed-in-event.d.ts +2 -2
- package/build/events/event-types/auth/author-signed-out-event.d.ts +2 -2
- package/build/events/event-types/auth/author-signed-up-event.d.ts +2 -2
- package/build/events/event-types/auth/author-updated-event.d.ts +2 -2
- package/build/events/event-types/auth/author-verified-event.d.ts +2 -2
- package/build/events/event-types/auth/reader-deleted-event.d.ts +2 -2
- package/build/events/event-types/auth/reader-signed-in-event.d.ts +2 -2
- package/build/events/event-types/auth/reader-signed-out-event.d.ts +2 -2
- package/build/events/event-types/auth/reader-signed-up-event.d.ts +2 -2
- package/build/events/event-types/auth/reader-updated-event.d.ts +2 -2
- package/build/events/event-types/auth/reader-verified-event.d.ts +2 -2
- package/build/events/event-types/books/book-created-event.d.ts +2 -2
- package/build/events/event-types/books/book-deleted-event.d.ts +2 -2
- package/build/events/event-types/books/book-updated-event.d.ts +2 -2
- package/build/events/event-types/media/avatar-uploaded-event.d.ts +14 -0
- package/build/events/event-types/media/avatar-uploaded-event.js +2 -0
- package/build/events/event-types/orders/order-created-event.d.ts +2 -2
- package/build/events/listeners/base-listener.d.ts +4 -4
- package/build/events/listeners/base-listener.js +2 -1
- package/build/events/publishers/base-publisher.d.ts +4 -4
- package/build/events/streams.d.ts +2 -3
- package/build/events/streams.js +1 -2
- package/build/events/subjects.d.ts +4 -0
- package/build/events/subjects.js +6 -0
- package/build/index.d.ts +42 -35
- package/build/index.js +9 -0
- package/build/middlewares/allow-roles.d.ts +2 -2
- package/build/middlewares/current-user.d.ts +4 -4
- package/build/middlewares/current-user.js +6 -4
- package/build/middlewares/error-handler.js +2 -1
- package/build/middlewares/validation.js +2 -2
- package/build/nats-wrapper.js +17 -5
- package/build/redis-wrapper.d.ts +1 -1
- package/build/redis-wrapper.js +11 -11
- package/package.json +12 -5
|
@@ -15,7 +15,7 @@ describe('UserRoles Enum', () => {
|
|
|
15
15
|
expect(roles_1.UserRoles.reader).toBe(4);
|
|
16
16
|
});
|
|
17
17
|
it('should have exactly 4 roles', () => {
|
|
18
|
-
const roles = Object.keys(roles_1.UserRoles).filter(
|
|
18
|
+
const roles = Object.keys(roles_1.UserRoles).filter(key => isNaN(Number(key)));
|
|
19
19
|
expect(roles.length).toBe(4);
|
|
20
20
|
expect(roles).toContain('superAdmin');
|
|
21
21
|
expect(roles).toContain('admin');
|
|
@@ -50,9 +50,7 @@ describe('RequestValidationError', () => {
|
|
|
50
50
|
];
|
|
51
51
|
const error = new request_validation_error_1.RequestValidationError(validationErrors);
|
|
52
52
|
const serialized = error.serializeErrors();
|
|
53
|
-
expect(serialized).toEqual([
|
|
54
|
-
{ message: 'At least one field is required' },
|
|
55
|
-
]);
|
|
53
|
+
expect(serialized).toEqual([{ message: 'At least one field is required' }]);
|
|
56
54
|
});
|
|
57
55
|
it('should serialize mixed errors correctly', () => {
|
|
58
56
|
const validationErrors = [
|
|
@@ -61,7 +61,7 @@ describe('Listener', () => {
|
|
|
61
61
|
mockJs.consumers.get.mockResolvedValue(mockConsumer);
|
|
62
62
|
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
63
63
|
// We need to start listen and then stop it to test waitForStream
|
|
64
|
-
|
|
64
|
+
listener.listen();
|
|
65
65
|
// Let it resolve
|
|
66
66
|
yield Promise.resolve();
|
|
67
67
|
yield Promise.resolve();
|
|
@@ -71,7 +71,8 @@ describe('Listener', () => {
|
|
|
71
71
|
}));
|
|
72
72
|
it('should retry when stream does not exist initially', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
73
|
jest.useFakeTimers();
|
|
74
|
-
mockJsm.streams.info = jest
|
|
74
|
+
mockJsm.streams.info = jest
|
|
75
|
+
.fn()
|
|
75
76
|
.mockRejectedValueOnce(new Error('Stream not found'))
|
|
76
77
|
.mockResolvedValueOnce({});
|
|
77
78
|
const mockConsumer = {
|
|
@@ -83,7 +84,7 @@ describe('Listener', () => {
|
|
|
83
84
|
};
|
|
84
85
|
mockJs.consumers.get.mockResolvedValue(mockConsumer);
|
|
85
86
|
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
86
|
-
|
|
87
|
+
listener.listen();
|
|
87
88
|
// First attempt fails, advance time for retry
|
|
88
89
|
yield jest.advanceTimersByTimeAsync(2000);
|
|
89
90
|
yield Promise.resolve();
|
|
@@ -8,17 +8,11 @@ describe('Streams Enum', () => {
|
|
|
8
8
|
it('should have BookServiceStream with value "books"', () => {
|
|
9
9
|
expect(streams_1.Streams.BookServiceStream).toBe('books');
|
|
10
10
|
});
|
|
11
|
-
it('should have ReaderServiceStream with value "readers"', () => {
|
|
12
|
-
expect(streams_1.Streams.ReaderServiceStream).toBe('readers');
|
|
13
|
-
});
|
|
14
|
-
it('should have AuthorServiceStream with value "authors"', () => {
|
|
15
|
-
expect(streams_1.Streams.AuthorServiceStream).toBe('authors');
|
|
16
|
-
});
|
|
17
11
|
it('should have AuthServiceStream with value "auth"', () => {
|
|
18
12
|
expect(streams_1.Streams.AuthServiceStream).toBe('auth');
|
|
19
13
|
});
|
|
20
14
|
it('should have exactly 5 streams', () => {
|
|
21
15
|
const streams = Object.values(streams_1.Streams);
|
|
22
|
-
expect(streams.length).toBe(
|
|
16
|
+
expect(streams.length).toBe(4);
|
|
23
17
|
});
|
|
24
18
|
});
|
|
@@ -72,8 +72,8 @@ describe('Subjects Enum', () => {
|
|
|
72
72
|
expect(subjects_1.Subjects.OrderCancelled).toBe('order:cancelled');
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
|
-
it('should have exactly
|
|
75
|
+
it('should have exactly 23 subjects', () => {
|
|
76
76
|
const subjects = Object.values(subjects_1.Subjects);
|
|
77
|
-
expect(subjects.length).toBe(
|
|
77
|
+
expect(subjects.length).toBe(24);
|
|
78
78
|
});
|
|
79
79
|
});
|
|
@@ -83,7 +83,7 @@ describe('currentUser function', () => {
|
|
|
83
83
|
});
|
|
84
84
|
it('should handle different user roles correctly', () => {
|
|
85
85
|
const roles = [roles_1.UserRoles.admin, roles_1.UserRoles.author, roles_1.UserRoles.reader, roles_1.UserRoles.superAdmin];
|
|
86
|
-
roles.forEach(
|
|
86
|
+
roles.forEach(role => {
|
|
87
87
|
var _a;
|
|
88
88
|
const req = { headers: {} };
|
|
89
89
|
const token = (0, setup_1.createTestToken)('user123', role);
|
|
@@ -20,7 +20,7 @@ describe('requireAuth Middleware', () => {
|
|
|
20
20
|
expect(mockNext).not.toHaveBeenCalled();
|
|
21
21
|
});
|
|
22
22
|
it('should throw NotAuthorizedError when currentUser is null-ish', () => {
|
|
23
|
-
// @ts-
|
|
23
|
+
// @ts-expect-error - testing edge case
|
|
24
24
|
mockReq.currentUser = null;
|
|
25
25
|
expect(() => {
|
|
26
26
|
(0, require_auth_1.requireAuth)(mockReq, mockRes, mockNext);
|
|
@@ -41,7 +41,7 @@ describe('requireAuth Middleware', () => {
|
|
|
41
41
|
});
|
|
42
42
|
it('should work with different user roles', () => {
|
|
43
43
|
const roles = [roles_1.UserRoles.admin, roles_1.UserRoles.author, roles_1.UserRoles.reader, roles_1.UserRoles.superAdmin];
|
|
44
|
-
roles.forEach(
|
|
44
|
+
roles.forEach(role => {
|
|
45
45
|
const next = jest.fn();
|
|
46
46
|
mockReq.currentUser = {
|
|
47
47
|
id: '507f1f77bcf86cd799439011',
|
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const nats_1 = require("nats");
|
|
12
13
|
const nats_wrapper_1 = require("../nats-wrapper");
|
|
13
14
|
const streams_1 = require("../events/streams");
|
|
14
15
|
const subjects_1 = require("../events/subjects");
|
|
@@ -16,7 +17,7 @@ const subjects_1 = require("../events/subjects");
|
|
|
16
17
|
jest.mock('nats', () => ({
|
|
17
18
|
connect: jest.fn(),
|
|
18
19
|
}));
|
|
19
|
-
const
|
|
20
|
+
const mockConnect = nats_1.connect;
|
|
20
21
|
describe('NatsWrapper', () => {
|
|
21
22
|
let natsWrapper;
|
|
22
23
|
beforeEach(() => {
|
|
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const ioredis_1 = require("ioredis");
|
|
12
13
|
const redis_wrapper_1 = require("../redis-wrapper");
|
|
13
14
|
// Mock ioredis
|
|
14
15
|
jest.mock('ioredis', () => {
|
|
@@ -21,7 +22,7 @@ jest.mock('ioredis', () => {
|
|
|
21
22
|
})),
|
|
22
23
|
};
|
|
23
24
|
});
|
|
24
|
-
const
|
|
25
|
+
const MockRedis = ioredis_1.Redis;
|
|
25
26
|
describe('RedisWrapper', () => {
|
|
26
27
|
let redisWrapper;
|
|
27
28
|
beforeEach(() => {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ImageType = void 0;
|
|
4
|
+
var ImageType;
|
|
5
|
+
(function (ImageType) {
|
|
6
|
+
ImageType[ImageType["cover"] = 1] = "cover";
|
|
7
|
+
ImageType[ImageType["profile"] = 2] = "profile";
|
|
8
|
+
ImageType[ImageType["book"] = 3] = "book";
|
|
9
|
+
ImageType[ImageType["banner"] = 4] = "banner";
|
|
10
|
+
ImageType[ImageType["genreImage"] = 5] = "genreImage";
|
|
11
|
+
ImageType[ImageType["genreIcon"] = 6] = "genreIcon";
|
|
12
|
+
ImageType[ImageType["subgenreImage"] = 7] = "subgenreImage";
|
|
13
|
+
ImageType[ImageType["subgenreIcon"] = 8] = "subgenreIcon";
|
|
14
|
+
ImageType[ImageType["promoImage"] = 9] = "promoImage";
|
|
15
|
+
ImageType[ImageType["promoIcon"] = 10] = "promoIcon";
|
|
16
|
+
ImageType[ImageType["chapter"] = 11] = "chapter";
|
|
17
|
+
ImageType[ImageType["authorDocument"] = 12] = "authorDocument";
|
|
18
|
+
})(ImageType || (exports.ImageType = ImageType = {}));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConflictError = void 0;
|
|
4
|
+
const custom_error_1 = require("./custom-error");
|
|
5
|
+
class ConflictError extends custom_error_1.CustomError {
|
|
6
|
+
constructor(message = 'Internal Server Error') {
|
|
7
|
+
super(message);
|
|
8
|
+
this.message = message;
|
|
9
|
+
this.statusCode = 409;
|
|
10
|
+
Object.setPrototypeOf(this, ConflictError.prototype);
|
|
11
|
+
}
|
|
12
|
+
serializeErrors() {
|
|
13
|
+
return [{ message: this.message }];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.ConflictError = ConflictError;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ForbiddenError = void 0;
|
|
4
4
|
const custom_error_1 = require("./custom-error");
|
|
5
5
|
class ForbiddenError extends custom_error_1.CustomError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Forbidden') {
|
|
7
7
|
super(message);
|
|
8
8
|
this.message = message;
|
|
9
9
|
this.statusCode = 403;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InternalError = void 0;
|
|
4
|
+
const custom_error_1 = require("./custom-error");
|
|
5
|
+
class InternalError extends custom_error_1.CustomError {
|
|
6
|
+
constructor(message = 'Internal Server Error') {
|
|
7
|
+
super(message);
|
|
8
|
+
this.message = message;
|
|
9
|
+
this.statusCode = 500;
|
|
10
|
+
Object.setPrototypeOf(this, InternalError.prototype);
|
|
11
|
+
}
|
|
12
|
+
serializeErrors() {
|
|
13
|
+
return [{ message: this.message }];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.InternalError = InternalError;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.NotAuthorizedError = void 0;
|
|
4
4
|
const custom_error_1 = require("./custom-error");
|
|
5
5
|
class NotAuthorizedError extends custom_error_1.CustomError {
|
|
6
|
-
constructor(message =
|
|
6
|
+
constructor(message = 'Not Authorized') {
|
|
7
7
|
super(message);
|
|
8
8
|
this.statusCode = 401;
|
|
9
9
|
Object.setPrototypeOf(this, NotAuthorizedError.prototype);
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.NotFoundError = void 0;
|
|
4
4
|
const custom_error_1 = require("./custom-error");
|
|
5
5
|
class NotFoundError extends custom_error_1.CustomError {
|
|
6
|
-
constructor(message =
|
|
7
|
-
super(
|
|
6
|
+
constructor(message = 'Not Found') {
|
|
7
|
+
super('Route not found');
|
|
8
8
|
this.message = message;
|
|
9
9
|
this.statusCode = 404;
|
|
10
10
|
Object.setPrototypeOf(this, NotFoundError.prototype);
|
|
@@ -11,7 +11,7 @@ class RequestValidationError extends custom_error_1.CustomError {
|
|
|
11
11
|
Object.setPrototypeOf(this, RequestValidationError.prototype);
|
|
12
12
|
}
|
|
13
13
|
serializeErrors() {
|
|
14
|
-
return this.errors.map(
|
|
14
|
+
return this.errors.map(err => {
|
|
15
15
|
if (err.type === 'field') {
|
|
16
16
|
return { message: err.msg, field: err.path };
|
|
17
17
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
|
+
export interface AdminDeletedEvent {
|
|
4
|
+
subject: Subjects.AdminDeleted;
|
|
5
|
+
stream: Streams.AuthServiceStream;
|
|
6
|
+
data: {
|
|
7
|
+
id: string;
|
|
8
|
+
version: number;
|
|
9
|
+
adminVersion?: number;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
|
+
export interface AdminSignedUpEvent {
|
|
4
|
+
subject: Subjects.AdminSignedUp;
|
|
5
|
+
stream: Streams.AuthServiceStream;
|
|
6
|
+
data: {
|
|
7
|
+
id: string;
|
|
8
|
+
email: string;
|
|
9
|
+
firstName: string;
|
|
10
|
+
lastName: string;
|
|
11
|
+
createdAt: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
|
+
export interface AdminUpdatedEvent {
|
|
4
|
+
subject: Subjects.AdminUpdated;
|
|
5
|
+
stream: Streams.AuthServiceStream;
|
|
6
|
+
data: {
|
|
7
|
+
id: string;
|
|
8
|
+
firstName: string;
|
|
9
|
+
lastName: string;
|
|
10
|
+
email: string;
|
|
11
|
+
version: number;
|
|
12
|
+
adminVersion?: number;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface AuthorDeletedEvent {
|
|
4
4
|
subject: Subjects.AuthorDeleted;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface AuthorSignedInEvent {
|
|
4
4
|
subject: Subjects.AuthorSignedIn;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface AuthorSignedOutEvent {
|
|
4
4
|
subject: Subjects.AuthorSignedOut;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface AuthorSignedUpEvent {
|
|
4
4
|
subject: Subjects.AuthorSignedUp;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface AuthorUpdatedEvent {
|
|
4
4
|
subject: Subjects.AuthorUpdated;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface AuthorVerifiedEvent {
|
|
4
4
|
subject: Subjects.AuthorVerified;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface ReaderDeletedEvent {
|
|
4
4
|
subject: Subjects.ReaderDeleted;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface ReaderSignedInEvent {
|
|
4
4
|
subject: Subjects.ReaderSignedIn;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface ReaderSignedOutEvent {
|
|
4
4
|
subject: Subjects.ReaderSignedOut;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface ReaderSignedUpEvent {
|
|
4
4
|
subject: Subjects.ReaderSignedUp;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface ReaderUpdatedEvent {
|
|
4
4
|
subject: Subjects.ReaderUpdated;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface ReaderVerifiedEvent {
|
|
4
4
|
subject: Subjects.ReaderVerified;
|
|
5
5
|
stream: Streams.AuthServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface BookCreatedEvent {
|
|
4
4
|
subject: Subjects.BookCreated;
|
|
5
5
|
stream: Streams.BookServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface BookDeletedEvent {
|
|
4
4
|
subject: Subjects.BookDeleted;
|
|
5
5
|
stream: Streams.BookServiceStream;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface BookUpdatedEvent {
|
|
4
4
|
subject: Subjects.BookUpdated;
|
|
5
5
|
stream: Streams.BookServiceStream;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
|
+
export interface AvatarUploadedEvent {
|
|
4
|
+
subject: Subjects.AvatarUploaded;
|
|
5
|
+
stream: Streams.MediaServiceStream;
|
|
6
|
+
data: {
|
|
7
|
+
userId: string;
|
|
8
|
+
imageId: string;
|
|
9
|
+
variants: {
|
|
10
|
+
original: string;
|
|
11
|
+
thumbnail: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Streams } from
|
|
2
|
-
import { Subjects } from
|
|
1
|
+
import { Streams } from '../../streams';
|
|
2
|
+
import { Subjects } from '../../subjects';
|
|
3
3
|
export interface OrderCreatedEvent {
|
|
4
4
|
subject: Subjects.OrderCreated;
|
|
5
5
|
stream: Streams.OrderServiceStream;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { JetStreamManager, JsMsg, Consumer, JetStreamClient } from
|
|
1
|
+
import { JetStreamManager, JsMsg, Consumer, JetStreamClient } from 'nats';
|
|
2
2
|
interface Event {
|
|
3
3
|
subject: string;
|
|
4
4
|
stream: string;
|
|
5
5
|
data: any;
|
|
6
6
|
}
|
|
7
7
|
export declare abstract class Listener<T extends Event> {
|
|
8
|
-
abstract subject: T[
|
|
9
|
-
abstract stream: T[
|
|
8
|
+
abstract subject: T['subject'];
|
|
9
|
+
abstract stream: T['stream'];
|
|
10
10
|
abstract durableName: string;
|
|
11
|
-
abstract onMessage(data: T[
|
|
11
|
+
abstract onMessage(data: T['data'], msg: JsMsg): void;
|
|
12
12
|
protected jsm: JetStreamManager;
|
|
13
13
|
protected js: JetStreamClient;
|
|
14
14
|
protected consumer: Consumer;
|
|
@@ -28,6 +28,7 @@ class Listener {
|
|
|
28
28
|
waitForStream() {
|
|
29
29
|
return __awaiter(this, void 0, void 0, function* () {
|
|
30
30
|
let retryCount = 0;
|
|
31
|
+
// eslint-disable-next-line no-constant-condition
|
|
31
32
|
while (true) {
|
|
32
33
|
try {
|
|
33
34
|
yield this.jsm.streams.info(this.stream);
|
|
@@ -36,7 +37,7 @@ class Listener {
|
|
|
36
37
|
}
|
|
37
38
|
catch (_a) {
|
|
38
39
|
console.log(`⏳ Waiting for stream "${this.stream}"...`);
|
|
39
|
-
yield new Promise(
|
|
40
|
+
yield new Promise(res => setTimeout(res, 2000));
|
|
40
41
|
}
|
|
41
42
|
retryCount++;
|
|
42
43
|
if (retryCount > 5) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { JetStreamClient } from
|
|
1
|
+
import { JetStreamClient } from 'nats';
|
|
2
2
|
export interface Event {
|
|
3
3
|
subject: string;
|
|
4
4
|
stream: string;
|
|
5
5
|
data: any;
|
|
6
6
|
}
|
|
7
7
|
export declare abstract class Publisher<T extends Event> {
|
|
8
|
-
abstract subject: T[
|
|
9
|
-
abstract stream: T[
|
|
8
|
+
abstract subject: T['subject'];
|
|
9
|
+
abstract stream: T['stream'];
|
|
10
10
|
protected jsClient: JetStreamClient;
|
|
11
11
|
protected codec: import("nats").Codec<unknown>;
|
|
12
12
|
constructor(js: JetStreamClient);
|
|
13
|
-
publish(data: T[
|
|
13
|
+
publish(data: T['data']): Promise<void>;
|
|
14
14
|
}
|
package/build/events/streams.js
CHANGED
|
@@ -5,7 +5,6 @@ var Streams;
|
|
|
5
5
|
(function (Streams) {
|
|
6
6
|
Streams["OrderServiceStream"] = "orders";
|
|
7
7
|
Streams["BookServiceStream"] = "books";
|
|
8
|
-
Streams["ReaderServiceStream"] = "readers";
|
|
9
|
-
Streams["AuthorServiceStream"] = "authors";
|
|
10
8
|
Streams["AuthServiceStream"] = "auth";
|
|
9
|
+
Streams["MediaServiceStream"] = "media";
|
|
11
10
|
})(Streams || (exports.Streams = Streams = {}));
|
|
@@ -11,6 +11,10 @@ export declare enum Subjects {
|
|
|
11
11
|
ReaderUpdated = "reader:updated",
|
|
12
12
|
ReaderDeleted = "reader:deleted",
|
|
13
13
|
ReaderVerified = "reader:verified",
|
|
14
|
+
AdminSignedUp = "admin:signed-up",
|
|
15
|
+
AdminDeleted = "admin:deleted",
|
|
16
|
+
AdminUpdated = "admin:updated",
|
|
17
|
+
AvatarUploaded = "avatar:uploaded",
|
|
14
18
|
BookCreated = "book:created",
|
|
15
19
|
BookUpdated = "book:updated",
|
|
16
20
|
BookDeleted = "book:deleted",
|
package/build/events/subjects.js
CHANGED
|
@@ -17,6 +17,12 @@ var Subjects;
|
|
|
17
17
|
Subjects["ReaderUpdated"] = "reader:updated";
|
|
18
18
|
Subjects["ReaderDeleted"] = "reader:deleted";
|
|
19
19
|
Subjects["ReaderVerified"] = "reader:verified";
|
|
20
|
+
// Admins related event subjects
|
|
21
|
+
Subjects["AdminSignedUp"] = "admin:signed-up";
|
|
22
|
+
Subjects["AdminDeleted"] = "admin:deleted";
|
|
23
|
+
Subjects["AdminUpdated"] = "admin:updated";
|
|
24
|
+
// Media event subjects
|
|
25
|
+
Subjects["AvatarUploaded"] = "avatar:uploaded";
|
|
20
26
|
// Books related event subjects
|
|
21
27
|
Subjects["BookCreated"] = "book:created";
|
|
22
28
|
Subjects["BookUpdated"] = "book:updated";
|
package/build/index.d.ts
CHANGED
|
@@ -1,35 +1,42 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
12
|
-
export * from
|
|
13
|
-
export * from
|
|
14
|
-
export * from
|
|
15
|
-
export * from
|
|
16
|
-
export * from
|
|
17
|
-
export * from
|
|
18
|
-
export * from
|
|
19
|
-
export * from
|
|
20
|
-
export * from
|
|
21
|
-
export * from
|
|
22
|
-
export * from
|
|
23
|
-
export * from
|
|
24
|
-
export * from
|
|
25
|
-
export * from
|
|
26
|
-
export * from
|
|
27
|
-
export * from
|
|
28
|
-
export * from
|
|
29
|
-
export * from
|
|
30
|
-
export * from
|
|
31
|
-
export * from
|
|
32
|
-
export * from
|
|
33
|
-
export * from
|
|
34
|
-
export * from
|
|
35
|
-
export * from
|
|
1
|
+
export * from './errors/bad-request-error';
|
|
2
|
+
export * from './errors/custom-error';
|
|
3
|
+
export * from './errors/database-connection-error';
|
|
4
|
+
export * from './errors/not-authorized-error';
|
|
5
|
+
export * from './errors/not-found-error';
|
|
6
|
+
export * from './errors/request-validation-error';
|
|
7
|
+
export * from './errors/forbidden-error';
|
|
8
|
+
export * from './errors/internal-error';
|
|
9
|
+
export * from './errors/conflict-error';
|
|
10
|
+
export * from './middlewares/current-user';
|
|
11
|
+
export * from './middlewares/require-auth';
|
|
12
|
+
export * from './middlewares/validation';
|
|
13
|
+
export * from './middlewares/error-handler';
|
|
14
|
+
export * from './middlewares/allow-roles';
|
|
15
|
+
export * from './enum/roles';
|
|
16
|
+
export * from './enum/image';
|
|
17
|
+
export * from './events/listeners/base-listener';
|
|
18
|
+
export * from './events/publishers/base-publisher';
|
|
19
|
+
export * from './events/event-types/books/book-created-event';
|
|
20
|
+
export * from './events/event-types/books/book-updated-event';
|
|
21
|
+
export * from './events/event-types/books/book-deleted-event';
|
|
22
|
+
export * from './events/event-types/auth/author-updated-event';
|
|
23
|
+
export * from './events/event-types/auth/author-deleted-event';
|
|
24
|
+
export * from './events/event-types/auth/author-verified-event';
|
|
25
|
+
export * from './events/event-types/auth/author-signed-up-event';
|
|
26
|
+
export * from './events/event-types/auth/author-signed-in-event';
|
|
27
|
+
export * from './events/event-types/auth/author-signed-out-event';
|
|
28
|
+
export * from './events/event-types/auth/reader-updated-event';
|
|
29
|
+
export * from './events/event-types/auth/reader-deleted-event';
|
|
30
|
+
export * from './events/event-types/auth/reader-signed-up-event';
|
|
31
|
+
export * from './events/event-types/auth/reader-signed-in-event';
|
|
32
|
+
export * from './events/event-types/auth/reader-signed-out-event';
|
|
33
|
+
export * from './events/event-types/auth/reader-verified-event';
|
|
34
|
+
export * from './events/event-types/auth/admin-signed-up-event';
|
|
35
|
+
export * from './events/event-types/auth/admin-deleted-event';
|
|
36
|
+
export * from './events/event-types/auth/admin-updated-event';
|
|
37
|
+
export * from './events/event-types/media/avatar-uploaded-event';
|
|
38
|
+
export * from './events/event-types/orders/order-created-event';
|
|
39
|
+
export * from './events/subjects';
|
|
40
|
+
export * from './events/streams';
|
|
41
|
+
export * from './nats-wrapper';
|
|
42
|
+
export * from './redis-wrapper';
|
package/build/index.js
CHANGED
|
@@ -22,6 +22,8 @@ __exportStar(require("./errors/not-authorized-error"), exports);
|
|
|
22
22
|
__exportStar(require("./errors/not-found-error"), exports);
|
|
23
23
|
__exportStar(require("./errors/request-validation-error"), exports);
|
|
24
24
|
__exportStar(require("./errors/forbidden-error"), exports);
|
|
25
|
+
__exportStar(require("./errors/internal-error"), exports);
|
|
26
|
+
__exportStar(require("./errors/conflict-error"), exports);
|
|
25
27
|
// Middlewares
|
|
26
28
|
__exportStar(require("./middlewares/current-user"), exports);
|
|
27
29
|
__exportStar(require("./middlewares/require-auth"), exports);
|
|
@@ -30,6 +32,7 @@ __exportStar(require("./middlewares/error-handler"), exports);
|
|
|
30
32
|
__exportStar(require("./middlewares/allow-roles"), exports);
|
|
31
33
|
// Enums
|
|
32
34
|
__exportStar(require("./enum/roles"), exports);
|
|
35
|
+
__exportStar(require("./enum/image"), exports);
|
|
33
36
|
__exportStar(require("./events/listeners/base-listener"), exports);
|
|
34
37
|
__exportStar(require("./events/publishers/base-publisher"), exports);
|
|
35
38
|
__exportStar(require("./events/event-types/books/book-created-event"), exports);
|
|
@@ -49,6 +52,12 @@ __exportStar(require("./events/event-types/auth/reader-signed-up-event"), export
|
|
|
49
52
|
__exportStar(require("./events/event-types/auth/reader-signed-in-event"), exports);
|
|
50
53
|
__exportStar(require("./events/event-types/auth/reader-signed-out-event"), exports);
|
|
51
54
|
__exportStar(require("./events/event-types/auth/reader-verified-event"), exports);
|
|
55
|
+
// Admin events
|
|
56
|
+
__exportStar(require("./events/event-types/auth/admin-signed-up-event"), exports);
|
|
57
|
+
__exportStar(require("./events/event-types/auth/admin-deleted-event"), exports);
|
|
58
|
+
__exportStar(require("./events/event-types/auth/admin-updated-event"), exports);
|
|
59
|
+
// Media events
|
|
60
|
+
__exportStar(require("./events/event-types/media/avatar-uploaded-event"), exports);
|
|
52
61
|
__exportStar(require("./events/event-types/orders/order-created-event"), exports);
|
|
53
62
|
__exportStar(require("./events/subjects"), exports);
|
|
54
63
|
__exportStar(require("./events/streams"), exports);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { UserRoles } from
|
|
2
|
-
import { Request, Response, NextFunction } from
|
|
1
|
+
import { UserRoles } from '../enum/roles';
|
|
2
|
+
import { Request, Response, NextFunction } from 'express';
|
|
3
3
|
export declare const allowRoles: (roles: UserRoles[]) => (req: Request, res: Response, next: NextFunction) => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from
|
|
2
|
-
import { UserRoles } from
|
|
3
|
-
import { RedisWrapper } from
|
|
4
|
-
import NodeCache from
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import { UserRoles } from '../enum/roles';
|
|
3
|
+
import { RedisWrapper } from '../redis-wrapper';
|
|
4
|
+
import NodeCache from 'node-cache';
|
|
5
5
|
export interface UserJwtPayload {
|
|
6
6
|
id: string;
|
|
7
7
|
email: string;
|
|
@@ -23,7 +23,7 @@ class CurrentUserMiddleware {
|
|
|
23
23
|
return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
24
24
|
var _a, _b, _c, _d;
|
|
25
25
|
try {
|
|
26
|
-
const token = (_a = req.headers[
|
|
26
|
+
const token = (_a = req.headers['authorization']) === null || _a === void 0 ? void 0 : _a.split(' ')[1];
|
|
27
27
|
if (!token) {
|
|
28
28
|
return next();
|
|
29
29
|
}
|
|
@@ -56,7 +56,7 @@ class CurrentUserMiddleware {
|
|
|
56
56
|
next();
|
|
57
57
|
}
|
|
58
58
|
catch (err) {
|
|
59
|
-
console.error(
|
|
59
|
+
console.error('Auth error:', err);
|
|
60
60
|
return next();
|
|
61
61
|
}
|
|
62
62
|
});
|
|
@@ -65,7 +65,7 @@ class CurrentUserMiddleware {
|
|
|
65
65
|
exports.CurrentUserMiddleware = CurrentUserMiddleware;
|
|
66
66
|
const currentUser = (req, res, next) => {
|
|
67
67
|
var _a;
|
|
68
|
-
const token = (_a = req.headers[
|
|
68
|
+
const token = (_a = req.headers['authorization']) === null || _a === void 0 ? void 0 : _a.split(' ')[1];
|
|
69
69
|
if (!token) {
|
|
70
70
|
return next();
|
|
71
71
|
}
|
|
@@ -80,7 +80,9 @@ const currentUser = (req, res, next) => {
|
|
|
80
80
|
};
|
|
81
81
|
req.currentUser = userData;
|
|
82
82
|
}
|
|
83
|
-
catch (err) {
|
|
83
|
+
catch (err) {
|
|
84
|
+
console.log(err);
|
|
85
|
+
}
|
|
84
86
|
next();
|
|
85
87
|
};
|
|
86
88
|
exports.currentUser = currentUser;
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.errorHandler = void 0;
|
|
4
4
|
const custom_error_1 = require("../errors/custom-error");
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
5
6
|
const errorHandler = (err, req, res, next) => {
|
|
6
7
|
if (err instanceof custom_error_1.CustomError) {
|
|
7
8
|
return res.status(err.statusCode).send({ errors: err.serializeErrors() });
|
|
8
9
|
}
|
|
9
10
|
res.status(400).send({
|
|
10
|
-
errors: [{ message: 'Something went wrong' }]
|
|
11
|
+
errors: [{ message: 'Something went wrong' }],
|
|
11
12
|
});
|
|
12
13
|
};
|
|
13
14
|
exports.errorHandler = errorHandler;
|
|
@@ -26,9 +26,9 @@ function validationMiddleware(type, field = 'body', skipMissingProperties = fals
|
|
|
26
26
|
if (errors.length > 0) {
|
|
27
27
|
// Transform validation errors to our format
|
|
28
28
|
const validationErrors = [];
|
|
29
|
-
errors.forEach(
|
|
29
|
+
errors.forEach(error => {
|
|
30
30
|
if (error.constraints) {
|
|
31
|
-
Object.values(error.constraints).forEach(
|
|
31
|
+
Object.values(error.constraints).forEach(message => {
|
|
32
32
|
validationErrors.push({
|
|
33
33
|
message,
|
|
34
34
|
field: error.property,
|
package/build/nats-wrapper.js
CHANGED
|
@@ -39,16 +39,28 @@ class NatsWrapper {
|
|
|
39
39
|
}
|
|
40
40
|
ensureStreamExists() {
|
|
41
41
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
var _a, _b;
|
|
43
|
-
// Ensure AuthServiceStream exists for auth-specific events
|
|
42
|
+
var _a, _b, _c;
|
|
44
43
|
try {
|
|
45
|
-
yield ((_a = this.jetStreamManager) === null || _a === void 0 ? void 0 : _a.streams.info(this.stream));
|
|
44
|
+
const streamInfo = yield ((_a = this.jetStreamManager) === null || _a === void 0 ? void 0 : _a.streams.info(this.stream));
|
|
45
|
+
// Check if subjects need to be updated
|
|
46
|
+
const existingSubjects = (streamInfo === null || streamInfo === void 0 ? void 0 : streamInfo.config.subjects) || [];
|
|
47
|
+
const missingSubjects = this.subjects.filter(s => !existingSubjects.includes(s));
|
|
48
|
+
if (missingSubjects.length > 0) {
|
|
49
|
+
// Merge existing subjects with new ones and update the stream
|
|
50
|
+
const allSubjects = [...new Set([...existingSubjects, ...this.subjects])];
|
|
51
|
+
yield ((_b = this.jetStreamManager) === null || _b === void 0 ? void 0 : _b.streams.update(this.stream, {
|
|
52
|
+
subjects: allSubjects,
|
|
53
|
+
}));
|
|
54
|
+
console.log(`✅ Updated stream "${this.stream}" with new subjects:`, missingSubjects);
|
|
55
|
+
}
|
|
46
56
|
}
|
|
47
|
-
catch (
|
|
48
|
-
|
|
57
|
+
catch (_d) {
|
|
58
|
+
// Stream doesn't exist, create it
|
|
59
|
+
yield ((_c = this.jetStreamManager) === null || _c === void 0 ? void 0 : _c.streams.add({
|
|
49
60
|
name: this.stream,
|
|
50
61
|
subjects: this.subjects,
|
|
51
62
|
}));
|
|
63
|
+
console.log(`✅ Created stream "${this.stream}" with subjects:`, this.subjects);
|
|
52
64
|
}
|
|
53
65
|
});
|
|
54
66
|
}
|
package/build/redis-wrapper.d.ts
CHANGED
package/build/redis-wrapper.js
CHANGED
|
@@ -14,10 +14,10 @@ const ioredis_1 = require("ioredis");
|
|
|
14
14
|
class RedisWrapper {
|
|
15
15
|
constructor(params) {
|
|
16
16
|
this._client = null;
|
|
17
|
-
this.host = (params === null || params === void 0 ? void 0 : params.host) ||
|
|
17
|
+
this.host = (params === null || params === void 0 ? void 0 : params.host) || 'localhost';
|
|
18
18
|
this.port = (params === null || params === void 0 ? void 0 : params.port) || 6379;
|
|
19
|
-
this.username = (params === null || params === void 0 ? void 0 : params.username) ||
|
|
20
|
-
this.password = (params === null || params === void 0 ? void 0 : params.password) ||
|
|
19
|
+
this.username = (params === null || params === void 0 ? void 0 : params.username) || '';
|
|
20
|
+
this.password = (params === null || params === void 0 ? void 0 : params.password) || '';
|
|
21
21
|
}
|
|
22
22
|
connect() {
|
|
23
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -30,13 +30,13 @@ class RedisWrapper {
|
|
|
30
30
|
lazyConnect: true,
|
|
31
31
|
});
|
|
32
32
|
yield this._client.connect();
|
|
33
|
-
console.log(
|
|
33
|
+
console.log('✅ Connected to Redis');
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
catch (e) {
|
|
37
|
-
console.error(
|
|
37
|
+
console.error('❌ Error connecting to Redis:', e.message);
|
|
38
38
|
}
|
|
39
|
-
console.log(
|
|
39
|
+
console.log('❌ Failed to connect to Redis');
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
disconnect() {
|
|
@@ -47,29 +47,29 @@ class RedisWrapper {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
catch (e) {
|
|
50
|
-
console.error(
|
|
50
|
+
console.error('❌ Error disconnecting from Redis:', e.message);
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
set(key, value, expireInSeconds) {
|
|
55
55
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
56
|
if (!this._client) {
|
|
57
|
-
throw new Error(
|
|
57
|
+
throw new Error('Redis not connected');
|
|
58
58
|
}
|
|
59
|
-
yield this._client.set(key, value,
|
|
59
|
+
yield this._client.set(key, value, 'EX', expireInSeconds);
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
get(key) {
|
|
63
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
64
|
if (!this._client) {
|
|
65
|
-
throw new Error(
|
|
65
|
+
throw new Error('Redis not connected');
|
|
66
66
|
}
|
|
67
67
|
return yield this._client.get(key);
|
|
68
68
|
});
|
|
69
69
|
}
|
|
70
70
|
get client() {
|
|
71
71
|
if (!this._client) {
|
|
72
|
-
throw new Error(
|
|
72
|
+
throw new Error('Cannot access Redis client before connecting');
|
|
73
73
|
}
|
|
74
74
|
return this._client;
|
|
75
75
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eratu/common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
4
4
|
"description": "A package for shared code across microservices",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -12,27 +12,34 @@
|
|
|
12
12
|
"build": "npm run clean && tsc",
|
|
13
13
|
"pub": "git add . && git commit -m \"Updates\" && npm version patch && npm publish",
|
|
14
14
|
"test": "jest --forceExit --detectOpenHandles",
|
|
15
|
-
"test:cov": "jest --coverage --forceExit --detectOpenHandles"
|
|
15
|
+
"test:cov": "jest --coverage --forceExit --detectOpenHandles",
|
|
16
|
+
"lint": "eslint src --ext .ts",
|
|
17
|
+
"lint:fix": "eslint src --ext .ts --fix"
|
|
16
18
|
},
|
|
17
19
|
"keywords": [],
|
|
18
20
|
"author": "",
|
|
19
21
|
"license": "ISC",
|
|
20
22
|
"type": "commonjs",
|
|
21
23
|
"devDependencies": {
|
|
24
|
+
"@types/express": "^5.0.6",
|
|
22
25
|
"@types/jest": "^29.5.14",
|
|
26
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
23
27
|
"@types/node": "^22.13.1",
|
|
28
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
29
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
24
30
|
"del-cli": "^6.0.0",
|
|
31
|
+
"eslint": "^8.45.0",
|
|
32
|
+
"eslint-config-prettier": "^8.8.0",
|
|
33
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
25
34
|
"jest": "^29.7.0",
|
|
26
35
|
"ts-jest": "^29.2.5",
|
|
27
36
|
"typescript": "^5.7.3"
|
|
28
37
|
},
|
|
29
38
|
"dependencies": {
|
|
30
|
-
"@types/express": "^5.0.3",
|
|
31
|
-
"@types/jsonwebtoken": "^9.0.10",
|
|
32
39
|
"class-transformer": "^0.5.1",
|
|
33
40
|
"class-validator": "^0.14.2",
|
|
34
41
|
"cookie-session": "^2.1.0",
|
|
35
|
-
"express": "^
|
|
42
|
+
"express": "^5.2.1",
|
|
36
43
|
"express-validator": "^7.2.1",
|
|
37
44
|
"ioredis": "^5.8.2",
|
|
38
45
|
"jsonwebtoken": "^9.0.2",
|