@eratu/common 1.0.19 → 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.
Files changed (61) hide show
  1. package/build/__tests__/enum/roles.test.js +1 -1
  2. package/build/__tests__/errors/request-validation-error.test.js +1 -3
  3. package/build/__tests__/events/base-listener.test.js +4 -3
  4. package/build/__tests__/events/streams.test.js +1 -7
  5. package/build/__tests__/events/subjects.test.js +1 -1
  6. package/build/__tests__/middlewares/current-user.test.js +1 -1
  7. package/build/__tests__/middlewares/require-auth.test.js +2 -2
  8. package/build/__tests__/nats-wrapper.test.js +2 -1
  9. package/build/__tests__/redis-wrapper.test.js +2 -1
  10. package/build/enum/image.d.ts +14 -0
  11. package/build/enum/image.js +18 -0
  12. package/build/errors/conflict-error.d.ts +9 -0
  13. package/build/errors/conflict-error.js +16 -0
  14. package/build/errors/forbidden-error.d.ts +1 -1
  15. package/build/errors/forbidden-error.js +1 -1
  16. package/build/errors/internal-error.d.ts +9 -0
  17. package/build/errors/internal-error.js +16 -0
  18. package/build/errors/not-authorized-error.d.ts +1 -1
  19. package/build/errors/not-authorized-error.js +1 -1
  20. package/build/errors/not-found-error.d.ts +1 -1
  21. package/build/errors/not-found-error.js +2 -2
  22. package/build/errors/request-validation-error.js +1 -1
  23. package/build/events/event-types/auth/admin-deleted-event.d.ts +2 -2
  24. package/build/events/event-types/auth/admin-signed-up-event.d.ts +2 -2
  25. package/build/events/event-types/auth/admin-updated-event.d.ts +2 -2
  26. package/build/events/event-types/auth/author-deleted-event.d.ts +2 -2
  27. package/build/events/event-types/auth/author-signed-in-event.d.ts +2 -2
  28. package/build/events/event-types/auth/author-signed-out-event.d.ts +2 -2
  29. package/build/events/event-types/auth/author-signed-up-event.d.ts +2 -2
  30. package/build/events/event-types/auth/author-updated-event.d.ts +2 -2
  31. package/build/events/event-types/auth/author-verified-event.d.ts +2 -2
  32. package/build/events/event-types/auth/reader-deleted-event.d.ts +2 -2
  33. package/build/events/event-types/auth/reader-signed-in-event.d.ts +2 -2
  34. package/build/events/event-types/auth/reader-signed-out-event.d.ts +2 -2
  35. package/build/events/event-types/auth/reader-signed-up-event.d.ts +2 -2
  36. package/build/events/event-types/auth/reader-updated-event.d.ts +2 -2
  37. package/build/events/event-types/auth/reader-verified-event.d.ts +2 -2
  38. package/build/events/event-types/books/book-created-event.d.ts +2 -2
  39. package/build/events/event-types/books/book-deleted-event.d.ts +2 -2
  40. package/build/events/event-types/books/book-updated-event.d.ts +2 -2
  41. package/build/events/event-types/media/avatar-uploaded-event.d.ts +14 -0
  42. package/build/events/event-types/media/avatar-uploaded-event.js +2 -0
  43. package/build/events/event-types/orders/order-created-event.d.ts +2 -2
  44. package/build/events/listeners/base-listener.d.ts +4 -4
  45. package/build/events/listeners/base-listener.js +2 -1
  46. package/build/events/publishers/base-publisher.d.ts +4 -4
  47. package/build/events/streams.d.ts +2 -3
  48. package/build/events/streams.js +1 -2
  49. package/build/events/subjects.d.ts +1 -0
  50. package/build/events/subjects.js +2 -0
  51. package/build/index.d.ts +42 -38
  52. package/build/index.js +5 -0
  53. package/build/middlewares/allow-roles.d.ts +2 -2
  54. package/build/middlewares/current-user.d.ts +4 -4
  55. package/build/middlewares/current-user.js +6 -4
  56. package/build/middlewares/error-handler.js +2 -1
  57. package/build/middlewares/validation.js +2 -2
  58. package/build/nats-wrapper.js +17 -5
  59. package/build/redis-wrapper.d.ts +1 -1
  60. package/build/redis-wrapper.js +11 -11
  61. 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((key) => isNaN(Number(key)));
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
- const listenPromise = listener.listen();
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.fn()
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
- const listenPromise = listener.listen();
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(5);
16
+ expect(streams.length).toBe(4);
23
17
  });
24
18
  });
@@ -74,6 +74,6 @@ describe('Subjects Enum', () => {
74
74
  });
75
75
  it('should have exactly 23 subjects', () => {
76
76
  const subjects = Object.values(subjects_1.Subjects);
77
- expect(subjects.length).toBe(23);
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((role) => {
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-ignore - testing edge case
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((role) => {
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 { connect: mockConnect } = require('nats');
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 { Redis: MockRedis } = require('ioredis');
25
+ const MockRedis = ioredis_1.Redis;
25
26
  describe('RedisWrapper', () => {
26
27
  let redisWrapper;
27
28
  beforeEach(() => {
@@ -0,0 +1,14 @@
1
+ export declare enum ImageType {
2
+ cover = 1,
3
+ profile = 2,
4
+ book = 3,
5
+ banner = 4,
6
+ genreImage = 5,
7
+ genreIcon = 6,
8
+ subgenreImage = 7,
9
+ subgenreIcon = 8,
10
+ promoImage = 9,
11
+ promoIcon = 10,
12
+ chapter = 11,
13
+ authorDocument = 12
14
+ }
@@ -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,9 @@
1
+ import { CustomError } from './custom-error';
2
+ export declare class ConflictError extends CustomError {
3
+ message: string;
4
+ statusCode: number;
5
+ constructor(message?: string);
6
+ serializeErrors(): {
7
+ message: string;
8
+ }[];
9
+ }
@@ -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;
@@ -1,4 +1,4 @@
1
- import { CustomError } from "./custom-error";
1
+ import { CustomError } from './custom-error';
2
2
  export declare class ForbiddenError extends CustomError {
3
3
  message: string;
4
4
  statusCode: number;
@@ -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 = "Forbidden") {
6
+ constructor(message = 'Forbidden') {
7
7
  super(message);
8
8
  this.message = message;
9
9
  this.statusCode = 403;
@@ -0,0 +1,9 @@
1
+ import { CustomError } from './custom-error';
2
+ export declare class InternalError extends CustomError {
3
+ message: string;
4
+ statusCode: number;
5
+ constructor(message?: string);
6
+ serializeErrors(): {
7
+ message: string;
8
+ }[];
9
+ }
@@ -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;
@@ -1,4 +1,4 @@
1
- import { CustomError } from "./custom-error";
1
+ import { CustomError } from './custom-error';
2
2
  export declare class NotAuthorizedError extends CustomError {
3
3
  statusCode: number;
4
4
  constructor(message?: string);
@@ -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 = "Not Authorized") {
6
+ constructor(message = 'Not Authorized') {
7
7
  super(message);
8
8
  this.statusCode = 401;
9
9
  Object.setPrototypeOf(this, NotAuthorizedError.prototype);
@@ -1,4 +1,4 @@
1
- import { CustomError } from "./custom-error";
1
+ import { CustomError } from './custom-error';
2
2
  export declare class NotFoundError extends CustomError {
3
3
  message: string;
4
4
  statusCode: number;
@@ -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 = "Not Found") {
7
- super("Route not found");
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((err) => {
14
+ return this.errors.map(err => {
15
15
  if (err.type === 'field') {
16
16
  return { message: err.msg, field: err.path };
17
17
  }
@@ -1,5 +1,5 @@
1
- import { Streams } from "../../streams";
2
- import { Subjects } from "../../subjects";
1
+ import { Streams } from '../../streams';
2
+ import { Subjects } from '../../subjects';
3
3
  export interface AdminDeletedEvent {
4
4
  subject: Subjects.AdminDeleted;
5
5
  stream: Streams.AuthServiceStream;
@@ -1,5 +1,5 @@
1
- import { Streams } from "../../streams";
2
- import { Subjects } from "../../subjects";
1
+ import { Streams } from '../../streams';
2
+ import { Subjects } from '../../subjects';
3
3
  export interface AdminSignedUpEvent {
4
4
  subject: Subjects.AdminSignedUp;
5
5
  stream: Streams.AuthServiceStream;
@@ -1,5 +1,5 @@
1
- import { Streams } from "../../streams";
2
- import { Subjects } from "../../subjects";
1
+ import { Streams } from '../../streams';
2
+ import { Subjects } from '../../subjects';
3
3
  export interface AdminUpdatedEvent {
4
4
  subject: Subjects.AdminUpdated;
5
5
  stream: Streams.AuthServiceStream;
@@ -1,5 +1,5 @@
1
- import { Streams } from "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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 "../../streams";
2
- import { Subjects } from "../../subjects";
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
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,5 @@
1
- import { Streams } from "../../streams";
2
- import { Subjects } from "../../subjects";
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 "nats";
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["subject"];
9
- abstract stream: T["stream"];
8
+ abstract subject: T['subject'];
9
+ abstract stream: T['stream'];
10
10
  abstract durableName: string;
11
- abstract onMessage(data: T["data"], msg: JsMsg): void;
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((res) => setTimeout(res, 2000));
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 "nats";
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["subject"];
9
- abstract stream: T["stream"];
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["data"]): Promise<void>;
13
+ publish(data: T['data']): Promise<void>;
14
14
  }
@@ -1,7 +1,6 @@
1
1
  export declare enum Streams {
2
2
  OrderServiceStream = "orders",
3
3
  BookServiceStream = "books",
4
- ReaderServiceStream = "readers",
5
- AuthorServiceStream = "authors",
6
- AuthServiceStream = "auth"
4
+ AuthServiceStream = "auth",
5
+ MediaServiceStream = "media"
7
6
  }
@@ -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 = {}));
@@ -14,6 +14,7 @@ export declare enum Subjects {
14
14
  AdminSignedUp = "admin:signed-up",
15
15
  AdminDeleted = "admin:deleted",
16
16
  AdminUpdated = "admin:updated",
17
+ AvatarUploaded = "avatar:uploaded",
17
18
  BookCreated = "book:created",
18
19
  BookUpdated = "book:updated",
19
20
  BookDeleted = "book:deleted",
@@ -21,6 +21,8 @@ var Subjects;
21
21
  Subjects["AdminSignedUp"] = "admin:signed-up";
22
22
  Subjects["AdminDeleted"] = "admin:deleted";
23
23
  Subjects["AdminUpdated"] = "admin:updated";
24
+ // Media event subjects
25
+ Subjects["AvatarUploaded"] = "avatar:uploaded";
24
26
  // Books related event subjects
25
27
  Subjects["BookCreated"] = "book:created";
26
28
  Subjects["BookUpdated"] = "book:updated";
package/build/index.d.ts CHANGED
@@ -1,38 +1,42 @@
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 "./middlewares/current-user";
9
- export * from "./middlewares/require-auth";
10
- export * from "./middlewares/validation";
11
- export * from "./middlewares/error-handler";
12
- export * from "./middlewares/allow-roles";
13
- export * from "./enum/roles";
14
- export * from "./events/listeners/base-listener";
15
- export * from "./events/publishers/base-publisher";
16
- export * from "./events/event-types/books/book-created-event";
17
- export * from "./events/event-types/books/book-updated-event";
18
- export * from "./events/event-types/books/book-deleted-event";
19
- export * from "./events/event-types/auth/author-updated-event";
20
- export * from "./events/event-types/auth/author-deleted-event";
21
- export * from "./events/event-types/auth/author-verified-event";
22
- export * from "./events/event-types/auth/author-signed-up-event";
23
- export * from "./events/event-types/auth/author-signed-in-event";
24
- export * from "./events/event-types/auth/author-signed-out-event";
25
- export * from "./events/event-types/auth/reader-updated-event";
26
- export * from "./events/event-types/auth/reader-deleted-event";
27
- export * from "./events/event-types/auth/reader-signed-up-event";
28
- export * from "./events/event-types/auth/reader-signed-in-event";
29
- export * from "./events/event-types/auth/reader-signed-out-event";
30
- export * from "./events/event-types/auth/reader-verified-event";
31
- export * from "./events/event-types/auth/admin-signed-up-event";
32
- export * from "./events/event-types/auth/admin-deleted-event";
33
- export * from "./events/event-types/auth/admin-updated-event";
34
- export * from "./events/event-types/orders/order-created-event";
35
- export * from "./events/subjects";
36
- export * from "./events/streams";
37
- export * from "./nats-wrapper";
38
- export * from "./redis-wrapper";
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);
@@ -53,6 +56,8 @@ __exportStar(require("./events/event-types/auth/reader-verified-event"), exports
53
56
  __exportStar(require("./events/event-types/auth/admin-signed-up-event"), exports);
54
57
  __exportStar(require("./events/event-types/auth/admin-deleted-event"), exports);
55
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);
56
61
  __exportStar(require("./events/event-types/orders/order-created-event"), exports);
57
62
  __exportStar(require("./events/subjects"), exports);
58
63
  __exportStar(require("./events/streams"), exports);
@@ -1,3 +1,3 @@
1
- import { UserRoles } from "../enum/roles";
2
- import { Request, Response, NextFunction } from "express";
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 "express";
2
- import { UserRoles } from "../enum/roles";
3
- import { RedisWrapper } from "../redis-wrapper";
4
- import NodeCache from "node-cache";
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["authorization"]) === null || _a === void 0 ? void 0 : _a.split(" ")[1];
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("Auth error:", err);
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["authorization"]) === null || _a === void 0 ? void 0 : _a.split(" ")[1];
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((error) => {
29
+ errors.forEach(error => {
30
30
  if (error.constraints) {
31
- Object.values(error.constraints).forEach((message) => {
31
+ Object.values(error.constraints).forEach(message => {
32
32
  validationErrors.push({
33
33
  message,
34
34
  field: error.property,
@@ -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 (_c) {
48
- yield ((_b = this.jetStreamManager) === null || _b === void 0 ? void 0 : _b.streams.add({
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
  }
@@ -1,4 +1,4 @@
1
- import { Redis } from "ioredis";
1
+ import { Redis } from 'ioredis';
2
2
  declare class RedisWrapper {
3
3
  private _client;
4
4
  private host;
@@ -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) || "localhost";
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("✅ Connected to Redis");
33
+ console.log('✅ Connected to Redis');
34
34
  return;
35
35
  }
36
36
  catch (e) {
37
- console.error("❌ Error connecting to Redis:", e.message);
37
+ console.error('❌ Error connecting to Redis:', e.message);
38
38
  }
39
- console.log("❌ Failed to connect to Redis");
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("❌ Error disconnecting from Redis:", e.message);
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("Redis not connected");
57
+ throw new Error('Redis not connected');
58
58
  }
59
- yield this._client.set(key, value, "EX", expireInSeconds);
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("Redis not connected");
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("Cannot access Redis client before connecting");
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.19",
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": "^4.21.2",
42
+ "express": "^5.2.1",
36
43
  "express-validator": "^7.2.1",
37
44
  "ioredis": "^5.8.2",
38
45
  "jsonwebtoken": "^9.0.2",