@eratu/common 1.0.21 → 1.0.22
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/package.json +1 -1
- package/build/__tests__/enum/roles.test.d.ts +0 -1
- package/build/__tests__/enum/roles.test.js +0 -31
- package/build/__tests__/errors/bad-request-error.test.d.ts +0 -1
- package/build/__tests__/errors/bad-request-error.test.js +0 -30
- package/build/__tests__/errors/database-connection-error.test.d.ts +0 -1
- package/build/__tests__/errors/database-connection-error.test.js +0 -28
- package/build/__tests__/errors/forbidden-error.test.d.ts +0 -1
- package/build/__tests__/errors/forbidden-error.test.js +0 -39
- package/build/__tests__/errors/not-authorized-error.test.d.ts +0 -1
- package/build/__tests__/errors/not-authorized-error.test.js +0 -39
- package/build/__tests__/errors/not-found-error.test.d.ts +0 -1
- package/build/__tests__/errors/not-found-error.test.js +0 -39
- package/build/__tests__/errors/request-validation-error.test.d.ts +0 -1
- package/build/__tests__/errors/request-validation-error.test.js +0 -99
- package/build/__tests__/events/base-listener.test.d.ts +0 -1
- package/build/__tests__/events/base-listener.test.js +0 -223
- package/build/__tests__/events/base-publisher.test.d.ts +0 -1
- package/build/__tests__/events/base-publisher.test.js +0 -85
- package/build/__tests__/events/streams.test.d.ts +0 -1
- package/build/__tests__/events/streams.test.js +0 -18
- package/build/__tests__/events/subjects.test.d.ts +0 -1
- package/build/__tests__/events/subjects.test.js +0 -79
- package/build/__tests__/middlewares/allow-roles.test.d.ts +0 -1
- package/build/__tests__/middlewares/allow-roles.test.js +0 -112
- package/build/__tests__/middlewares/current-user.test.d.ts +0 -1
- package/build/__tests__/middlewares/current-user.test.js +0 -261
- package/build/__tests__/middlewares/error-handler.test.d.ts +0 -1
- package/build/__tests__/middlewares/error-handler.test.js +0 -102
- package/build/__tests__/middlewares/require-auth.test.d.ts +0 -1
- package/build/__tests__/middlewares/require-auth.test.js +0 -57
- package/build/__tests__/middlewares/validation.test.d.ts +0 -1
- package/build/__tests__/middlewares/validation.test.js +0 -198
- package/build/__tests__/nats-wrapper.test.d.ts +0 -1
- package/build/__tests__/nats-wrapper.test.js +0 -159
- package/build/__tests__/redis-wrapper.test.d.ts +0 -1
- package/build/__tests__/redis-wrapper.test.js +0 -159
- package/build/enum/image.d.ts +0 -14
- package/build/enum/image.js +0 -18
- package/build/enum/roles.d.ts +0 -6
- package/build/enum/roles.js +0 -10
- package/build/errors/bad-request-error.d.ts +0 -9
- package/build/errors/bad-request-error.js +0 -16
- package/build/errors/conflict-error.d.ts +0 -9
- package/build/errors/conflict-error.js +0 -16
- package/build/errors/custom-error.d.ts +0 -8
- package/build/errors/custom-error.js +0 -10
- package/build/errors/database-connection-error.d.ts +0 -9
- package/build/errors/database-connection-error.js +0 -16
- package/build/errors/forbidden-error.d.ts +0 -9
- package/build/errors/forbidden-error.js +0 -16
- package/build/errors/internal-error.d.ts +0 -9
- package/build/errors/internal-error.js +0 -16
- package/build/errors/not-authorized-error.d.ts +0 -8
- package/build/errors/not-authorized-error.js +0 -15
- package/build/errors/not-found-error.d.ts +0 -9
- package/build/errors/not-found-error.js +0 -16
- package/build/errors/request-validation-error.d.ts +0 -14
- package/build/errors/request-validation-error.js +0 -22
- package/build/events/event-types/auth/admin-deleted-event.d.ts +0 -11
- package/build/events/event-types/auth/admin-deleted-event.js +0 -2
- package/build/events/event-types/auth/admin-signed-up-event.d.ts +0 -13
- package/build/events/event-types/auth/admin-signed-up-event.js +0 -2
- package/build/events/event-types/auth/admin-updated-event.d.ts +0 -14
- package/build/events/event-types/auth/admin-updated-event.js +0 -2
- package/build/events/event-types/auth/author-deleted-event.d.ts +0 -11
- package/build/events/event-types/auth/author-deleted-event.js +0 -2
- package/build/events/event-types/auth/author-signed-in-event.d.ts +0 -12
- package/build/events/event-types/auth/author-signed-in-event.js +0 -2
- package/build/events/event-types/auth/author-signed-out-event.d.ts +0 -11
- package/build/events/event-types/auth/author-signed-out-event.js +0 -2
- package/build/events/event-types/auth/author-signed-up-event.d.ts +0 -13
- package/build/events/event-types/auth/author-signed-up-event.js +0 -2
- package/build/events/event-types/auth/author-updated-event.d.ts +0 -14
- package/build/events/event-types/auth/author-updated-event.js +0 -2
- package/build/events/event-types/auth/author-verified-event.d.ts +0 -14
- package/build/events/event-types/auth/author-verified-event.js +0 -2
- package/build/events/event-types/auth/reader-deleted-event.d.ts +0 -11
- package/build/events/event-types/auth/reader-deleted-event.js +0 -2
- package/build/events/event-types/auth/reader-signed-in-event.d.ts +0 -13
- package/build/events/event-types/auth/reader-signed-in-event.js +0 -2
- package/build/events/event-types/auth/reader-signed-out-event.d.ts +0 -11
- package/build/events/event-types/auth/reader-signed-out-event.js +0 -2
- package/build/events/event-types/auth/reader-signed-up-event.d.ts +0 -13
- package/build/events/event-types/auth/reader-signed-up-event.js +0 -2
- package/build/events/event-types/auth/reader-updated-event.d.ts +0 -14
- package/build/events/event-types/auth/reader-updated-event.js +0 -2
- package/build/events/event-types/auth/reader-verified-event.d.ts +0 -14
- package/build/events/event-types/auth/reader-verified-event.js +0 -2
- package/build/events/event-types/books/book-created-event.d.ts +0 -34
- package/build/events/event-types/books/book-created-event.js +0 -2
- package/build/events/event-types/books/book-deleted-event.d.ts +0 -10
- package/build/events/event-types/books/book-deleted-event.js +0 -2
- package/build/events/event-types/books/book-updated-event.d.ts +0 -35
- package/build/events/event-types/books/book-updated-event.js +0 -2
- package/build/events/event-types/books/chapter-created-event.d.ts +0 -16
- package/build/events/event-types/books/chapter-created-event.js +0 -2
- package/build/events/event-types/books/chapter-deleted-event.d.ts +0 -10
- package/build/events/event-types/books/chapter-deleted-event.js +0 -2
- package/build/events/event-types/books/chapter-updated-event.d.ts +0 -17
- package/build/events/event-types/books/chapter-updated-event.js +0 -2
- package/build/events/event-types/books/genre-created-event.d.ts +0 -13
- package/build/events/event-types/books/genre-created-event.js +0 -2
- package/build/events/event-types/books/genre-deleted-event.d.ts +0 -9
- package/build/events/event-types/books/genre-deleted-event.js +0 -2
- package/build/events/event-types/books/genre-updated-event.d.ts +0 -13
- package/build/events/event-types/books/genre-updated-event.js +0 -2
- package/build/events/event-types/books/subgenre-created-event.d.ts +0 -14
- package/build/events/event-types/books/subgenre-created-event.js +0 -2
- package/build/events/event-types/books/subgenre-deleted-event.d.ts +0 -9
- package/build/events/event-types/books/subgenre-deleted-event.js +0 -2
- package/build/events/event-types/books/subgenre-updated-event.d.ts +0 -14
- package/build/events/event-types/books/subgenre-updated-event.js +0 -2
- package/build/events/event-types/books/tag-created-event.d.ts +0 -12
- package/build/events/event-types/books/tag-created-event.js +0 -2
- package/build/events/event-types/books/tag-deleted-event.d.ts +0 -9
- package/build/events/event-types/books/tag-deleted-event.js +0 -2
- package/build/events/event-types/books/tag-updated-event.d.ts +0 -12
- package/build/events/event-types/books/tag-updated-event.js +0 -2
- package/build/events/event-types/books/trigger-created-event.d.ts +0 -12
- package/build/events/event-types/books/trigger-created-event.js +0 -2
- package/build/events/event-types/books/trigger-deleted-event.d.ts +0 -9
- package/build/events/event-types/books/trigger-deleted-event.js +0 -2
- package/build/events/event-types/books/trigger-updated-event.d.ts +0 -12
- package/build/events/event-types/books/trigger-updated-event.js +0 -2
- package/build/events/event-types/books/trope-created-event.d.ts +0 -12
- package/build/events/event-types/books/trope-created-event.js +0 -2
- package/build/events/event-types/books/trope-deleted-event.d.ts +0 -9
- package/build/events/event-types/books/trope-deleted-event.js +0 -2
- package/build/events/event-types/books/trope-updated-event.d.ts +0 -12
- package/build/events/event-types/books/trope-updated-event.js +0 -2
- package/build/events/event-types/media/avatar-uploaded-event.d.ts +0 -14
- package/build/events/event-types/media/avatar-uploaded-event.js +0 -2
- package/build/events/event-types/orders/order-created-event.d.ts +0 -12
- package/build/events/event-types/orders/order-created-event.js +0 -2
- package/build/events/listeners/base-listener.d.ts +0 -23
- package/build/events/listeners/base-listener.js +0 -97
- package/build/events/publishers/base-publisher.d.ts +0 -14
- package/build/events/publishers/base-publisher.js +0 -27
- package/build/events/streams.d.ts +0 -6
- package/build/events/streams.js +0 -10
- package/build/events/subjects.d.ts +0 -41
- package/build/events/subjects.js +0 -52
- package/build/index.d.ts +0 -60
- package/build/index.js +0 -89
- package/build/middlewares/allow-roles.d.ts +0 -3
- package/build/middlewares/allow-roles.js +0 -18
- package/build/middlewares/current-user.d.ts +0 -40
- package/build/middlewares/current-user.js +0 -88
- package/build/middlewares/error-handler.d.ts +0 -2
- package/build/middlewares/error-handler.js +0 -14
- package/build/middlewares/require-auth.d.ts +0 -2
- package/build/middlewares/require-auth.js +0 -11
- package/build/middlewares/validation.d.ts +0 -3
- package/build/middlewares/validation.js +0 -57
- package/build/nats-wrapper.d.ts +0 -17
- package/build/nats-wrapper.js +0 -92
- package/build/redis-wrapper.d.ts +0 -20
- package/build/redis-wrapper.js +0 -77
- package/build/test/setup.d.ts +0 -8
- package/build/test/setup.js +0 -45
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
-
});
|
|
19
|
-
};
|
|
20
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
const class_validator_1 = require("class-validator");
|
|
22
|
-
const validation_1 = require("../../middlewares/validation");
|
|
23
|
-
// Test DTOs
|
|
24
|
-
class TestUserDto {
|
|
25
|
-
}
|
|
26
|
-
__decorate([
|
|
27
|
-
(0, class_validator_1.IsEmail)(),
|
|
28
|
-
__metadata("design:type", String)
|
|
29
|
-
], TestUserDto.prototype, "email", void 0);
|
|
30
|
-
__decorate([
|
|
31
|
-
(0, class_validator_1.IsString)(),
|
|
32
|
-
(0, class_validator_1.MinLength)(8),
|
|
33
|
-
__metadata("design:type", String)
|
|
34
|
-
], TestUserDto.prototype, "password", void 0);
|
|
35
|
-
__decorate([
|
|
36
|
-
(0, class_validator_1.IsOptional)(),
|
|
37
|
-
(0, class_validator_1.IsString)(),
|
|
38
|
-
__metadata("design:type", String)
|
|
39
|
-
], TestUserDto.prototype, "firstName", void 0);
|
|
40
|
-
class TestQueryDto {
|
|
41
|
-
}
|
|
42
|
-
__decorate([
|
|
43
|
-
(0, class_validator_1.IsOptional)(),
|
|
44
|
-
(0, class_validator_1.IsInt)(),
|
|
45
|
-
(0, class_validator_1.Min)(1),
|
|
46
|
-
__metadata("design:type", Number)
|
|
47
|
-
], TestQueryDto.prototype, "page", void 0);
|
|
48
|
-
describe('validationMiddleware', () => {
|
|
49
|
-
let mockReq;
|
|
50
|
-
let mockRes;
|
|
51
|
-
let mockNext;
|
|
52
|
-
beforeEach(() => {
|
|
53
|
-
mockReq = {
|
|
54
|
-
body: {},
|
|
55
|
-
query: {},
|
|
56
|
-
params: {},
|
|
57
|
-
};
|
|
58
|
-
mockRes = {
|
|
59
|
-
status: jest.fn().mockReturnThis(),
|
|
60
|
-
json: jest.fn(),
|
|
61
|
-
};
|
|
62
|
-
mockNext = jest.fn();
|
|
63
|
-
});
|
|
64
|
-
describe('body validation', () => {
|
|
65
|
-
it('should call next() when body is valid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
66
|
-
mockReq.body = {
|
|
67
|
-
email: 'test@example.com',
|
|
68
|
-
password: 'password123',
|
|
69
|
-
};
|
|
70
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto);
|
|
71
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
72
|
-
expect(mockNext).toHaveBeenCalledTimes(1);
|
|
73
|
-
expect(mockRes.status).not.toHaveBeenCalled();
|
|
74
|
-
}));
|
|
75
|
-
it('should return 400 when email is invalid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
76
|
-
mockReq.body = {
|
|
77
|
-
email: 'invalid-email',
|
|
78
|
-
password: 'password123',
|
|
79
|
-
};
|
|
80
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto);
|
|
81
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
82
|
-
expect(mockNext).not.toHaveBeenCalled();
|
|
83
|
-
expect(mockRes.status).toHaveBeenCalledWith(400);
|
|
84
|
-
expect(mockRes.json).toHaveBeenCalledWith(expect.objectContaining({
|
|
85
|
-
status: 400,
|
|
86
|
-
message: 'Validation failed',
|
|
87
|
-
errors: expect.arrayContaining([
|
|
88
|
-
expect.objectContaining({
|
|
89
|
-
field: 'email',
|
|
90
|
-
}),
|
|
91
|
-
]),
|
|
92
|
-
}));
|
|
93
|
-
}));
|
|
94
|
-
it('should return 400 when password is too short', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
-
mockReq.body = {
|
|
96
|
-
email: 'test@example.com',
|
|
97
|
-
password: 'short',
|
|
98
|
-
};
|
|
99
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto);
|
|
100
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
101
|
-
expect(mockNext).not.toHaveBeenCalled();
|
|
102
|
-
expect(mockRes.status).toHaveBeenCalledWith(400);
|
|
103
|
-
expect(mockRes.json).toHaveBeenCalledWith(expect.objectContaining({
|
|
104
|
-
errors: expect.arrayContaining([
|
|
105
|
-
expect.objectContaining({
|
|
106
|
-
field: 'password',
|
|
107
|
-
}),
|
|
108
|
-
]),
|
|
109
|
-
}));
|
|
110
|
-
}));
|
|
111
|
-
it('should return 400 when required fields are missing', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
|
-
mockReq.body = {};
|
|
113
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto);
|
|
114
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
115
|
-
expect(mockNext).not.toHaveBeenCalled();
|
|
116
|
-
expect(mockRes.status).toHaveBeenCalledWith(400);
|
|
117
|
-
expect(mockRes.json).toHaveBeenCalledWith(expect.objectContaining({
|
|
118
|
-
errors: expect.arrayContaining([
|
|
119
|
-
expect.objectContaining({ field: 'email' }),
|
|
120
|
-
expect.objectContaining({ field: 'password' }),
|
|
121
|
-
]),
|
|
122
|
-
}));
|
|
123
|
-
}));
|
|
124
|
-
it('should handle optional fields correctly', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
125
|
-
mockReq.body = {
|
|
126
|
-
email: 'test@example.com',
|
|
127
|
-
password: 'password123',
|
|
128
|
-
firstName: 'John',
|
|
129
|
-
};
|
|
130
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto);
|
|
131
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
132
|
-
expect(mockNext).toHaveBeenCalledTimes(1);
|
|
133
|
-
expect(mockReq.body.firstName).toBe('John');
|
|
134
|
-
}));
|
|
135
|
-
it('should return 400 when non-whitelisted properties are present', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
136
|
-
mockReq.body = {
|
|
137
|
-
email: 'test@example.com',
|
|
138
|
-
password: 'password123',
|
|
139
|
-
hackerField: 'malicious',
|
|
140
|
-
};
|
|
141
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto);
|
|
142
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
143
|
-
expect(mockNext).not.toHaveBeenCalled();
|
|
144
|
-
expect(mockRes.status).toHaveBeenCalledWith(400);
|
|
145
|
-
}));
|
|
146
|
-
it('should skip missing properties when skipMissingProperties is true', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
147
|
-
mockReq.body = {
|
|
148
|
-
email: 'test@example.com',
|
|
149
|
-
// password is missing
|
|
150
|
-
};
|
|
151
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto, 'body', true);
|
|
152
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
153
|
-
expect(mockNext).toHaveBeenCalledTimes(1);
|
|
154
|
-
}));
|
|
155
|
-
});
|
|
156
|
-
describe('query validation', () => {
|
|
157
|
-
it('should validate query parameters', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
-
mockReq.query = {
|
|
159
|
-
page: 1,
|
|
160
|
-
};
|
|
161
|
-
const middleware = (0, validation_1.validationMiddleware)(TestQueryDto, 'query');
|
|
162
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
163
|
-
expect(mockNext).toHaveBeenCalledTimes(1);
|
|
164
|
-
}));
|
|
165
|
-
});
|
|
166
|
-
describe('error handling', () => {
|
|
167
|
-
it('should return 500 when an internal error occurs', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
168
|
-
// Force an error by providing invalid input that causes plainToClass to fail
|
|
169
|
-
// We'll mock plainToClass to throw
|
|
170
|
-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
171
|
-
// Create a scenario that causes internal error
|
|
172
|
-
mockReq.body = null;
|
|
173
|
-
// This might not throw, but let's test that errors are handled
|
|
174
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto);
|
|
175
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
176
|
-
// In this case, it may pass validation since null becomes empty object
|
|
177
|
-
// The point is to ensure the middleware doesn't crash
|
|
178
|
-
consoleErrorSpy.mockRestore();
|
|
179
|
-
}));
|
|
180
|
-
});
|
|
181
|
-
describe('body transformation', () => {
|
|
182
|
-
it('should attach transformed DTO to request body', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
183
|
-
mockReq.body = {
|
|
184
|
-
email: 'test@example.com',
|
|
185
|
-
password: 'password123',
|
|
186
|
-
firstName: 'John',
|
|
187
|
-
};
|
|
188
|
-
const middleware = (0, validation_1.validationMiddleware)(TestUserDto);
|
|
189
|
-
yield middleware(mockReq, mockRes, mockNext);
|
|
190
|
-
expect(mockNext).toHaveBeenCalledTimes(1);
|
|
191
|
-
expect(mockReq.body).toEqual(expect.objectContaining({
|
|
192
|
-
email: 'test@example.com',
|
|
193
|
-
password: 'password123',
|
|
194
|
-
firstName: 'John',
|
|
195
|
-
}));
|
|
196
|
-
}));
|
|
197
|
-
});
|
|
198
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const nats_1 = require("nats");
|
|
13
|
-
const nats_wrapper_1 = require("../nats-wrapper");
|
|
14
|
-
const streams_1 = require("../events/streams");
|
|
15
|
-
const subjects_1 = require("../events/subjects");
|
|
16
|
-
// Mock nats module
|
|
17
|
-
jest.mock('nats', () => ({
|
|
18
|
-
connect: jest.fn(),
|
|
19
|
-
}));
|
|
20
|
-
const mockConnect = nats_1.connect;
|
|
21
|
-
describe('NatsWrapper', () => {
|
|
22
|
-
let natsWrapper;
|
|
23
|
-
beforeEach(() => {
|
|
24
|
-
jest.clearAllMocks();
|
|
25
|
-
natsWrapper = new nats_wrapper_1.NatsWrapper(streams_1.Streams.AuthServiceStream, [
|
|
26
|
-
subjects_1.Subjects.AuthorSignedUp,
|
|
27
|
-
subjects_1.Subjects.ReaderSignedUp,
|
|
28
|
-
]);
|
|
29
|
-
});
|
|
30
|
-
describe('getters before initialization', () => {
|
|
31
|
-
it('should throw error when accessing natsConnection before init', () => {
|
|
32
|
-
expect(() => natsWrapper.natsConnection).toThrow('Cannot access NATS client before initialization');
|
|
33
|
-
});
|
|
34
|
-
it('should throw error when accessing jetStreamClient before init', () => {
|
|
35
|
-
expect(() => natsWrapper.jetStreamClient).toThrow('Cannot access JetStream client before initialization');
|
|
36
|
-
});
|
|
37
|
-
it('should throw error when accessing jetStreamManager before init', () => {
|
|
38
|
-
expect(() => natsWrapper.jetStreamManager).toThrow('Cannot access JetStream manager before initialization');
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
describe('connect', () => {
|
|
42
|
-
it('should connect to NATS successfully', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
-
const mockJsm = {
|
|
44
|
-
streams: {
|
|
45
|
-
info: jest.fn().mockResolvedValue({}),
|
|
46
|
-
add: jest.fn().mockResolvedValue({}),
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
const mockJs = jest.fn();
|
|
50
|
-
const mockConnection = {
|
|
51
|
-
jetstream: jest.fn().mockReturnValue(mockJs),
|
|
52
|
-
jetstreamManager: jest.fn().mockResolvedValue(mockJsm),
|
|
53
|
-
};
|
|
54
|
-
mockConnect.mockResolvedValueOnce(mockConnection);
|
|
55
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
56
|
-
yield natsWrapper.connect('nats://localhost:4222');
|
|
57
|
-
expect(mockConnect).toHaveBeenCalledWith({ servers: ['nats://localhost:4222'] });
|
|
58
|
-
expect(consoleSpy).toHaveBeenCalledWith('✅ Connected to NATS');
|
|
59
|
-
expect(natsWrapper.natsConnection).toBe(mockConnection);
|
|
60
|
-
expect(natsWrapper.jetStreamClient).toBe(mockJs);
|
|
61
|
-
consoleSpy.mockRestore();
|
|
62
|
-
}));
|
|
63
|
-
it('should create stream if it does not exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
-
const mockJsm = {
|
|
65
|
-
streams: {
|
|
66
|
-
info: jest.fn().mockRejectedValueOnce(new Error('Stream not found')),
|
|
67
|
-
add: jest.fn().mockResolvedValue({}),
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
const mockJs = jest.fn();
|
|
71
|
-
const mockConnection = {
|
|
72
|
-
jetstream: jest.fn().mockReturnValue(mockJs),
|
|
73
|
-
jetstreamManager: jest.fn().mockResolvedValue(mockJsm),
|
|
74
|
-
};
|
|
75
|
-
mockConnect.mockResolvedValueOnce(mockConnection);
|
|
76
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
77
|
-
yield natsWrapper.connect('nats://localhost:4222');
|
|
78
|
-
expect(mockJsm.streams.add).toHaveBeenCalledWith({
|
|
79
|
-
name: streams_1.Streams.AuthServiceStream,
|
|
80
|
-
subjects: [subjects_1.Subjects.AuthorSignedUp, subjects_1.Subjects.ReaderSignedUp],
|
|
81
|
-
});
|
|
82
|
-
consoleSpy.mockRestore();
|
|
83
|
-
}));
|
|
84
|
-
it('should retry connection on failure', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
85
|
-
const mockJsm = {
|
|
86
|
-
streams: {
|
|
87
|
-
info: jest.fn().mockResolvedValue({}),
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
const mockConnection = {
|
|
91
|
-
jetstream: jest.fn().mockReturnValue({}),
|
|
92
|
-
jetstreamManager: jest.fn().mockResolvedValue(mockJsm),
|
|
93
|
-
};
|
|
94
|
-
mockConnect
|
|
95
|
-
.mockRejectedValueOnce(new Error('Connection failed'))
|
|
96
|
-
.mockRejectedValueOnce(new Error('Connection failed'))
|
|
97
|
-
.mockResolvedValueOnce(mockConnection);
|
|
98
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
99
|
-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
100
|
-
// Override setTimeout to speed up test
|
|
101
|
-
jest.useFakeTimers();
|
|
102
|
-
const connectPromise = natsWrapper.connect('nats://localhost:4222');
|
|
103
|
-
// Fast-forward through retries
|
|
104
|
-
yield jest.advanceTimersByTimeAsync(3000);
|
|
105
|
-
yield jest.advanceTimersByTimeAsync(3000);
|
|
106
|
-
yield connectPromise;
|
|
107
|
-
expect(mockConnect).toHaveBeenCalledTimes(3);
|
|
108
|
-
expect(consoleErrorSpy).toHaveBeenCalledTimes(2);
|
|
109
|
-
expect(consoleSpy).toHaveBeenCalledWith('✅ Connected to NATS');
|
|
110
|
-
consoleSpy.mockRestore();
|
|
111
|
-
consoleErrorSpy.mockRestore();
|
|
112
|
-
jest.useRealTimers();
|
|
113
|
-
}));
|
|
114
|
-
it('should throw error after max retry attempts', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
115
|
-
mockConnect.mockRejectedValue(new Error('Connection failed'));
|
|
116
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
117
|
-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
118
|
-
jest.useFakeTimers();
|
|
119
|
-
// Start the connection and immediately attach the rejection handler
|
|
120
|
-
const connectPromise = natsWrapper.connect('nats://localhost:4222').catch(e => e);
|
|
121
|
-
// Run all timers and pending promises to completion
|
|
122
|
-
yield jest.runAllTimersAsync();
|
|
123
|
-
const error = yield connectPromise;
|
|
124
|
-
expect(error).toBeInstanceOf(Error);
|
|
125
|
-
expect(error.message).toBe('NATS connection failed');
|
|
126
|
-
expect(mockConnect).toHaveBeenCalledTimes(6);
|
|
127
|
-
expect(consoleErrorSpy).toHaveBeenCalledTimes(6);
|
|
128
|
-
consoleSpy.mockRestore();
|
|
129
|
-
consoleErrorSpy.mockRestore();
|
|
130
|
-
jest.useRealTimers();
|
|
131
|
-
}));
|
|
132
|
-
});
|
|
133
|
-
describe('getters after initialization', () => {
|
|
134
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
|
-
const mockJsm = {
|
|
136
|
-
streams: {
|
|
137
|
-
info: jest.fn().mockResolvedValue({}),
|
|
138
|
-
},
|
|
139
|
-
};
|
|
140
|
-
const mockJs = { publish: jest.fn() };
|
|
141
|
-
const mockConnection = {
|
|
142
|
-
jetstream: jest.fn().mockReturnValue(mockJs),
|
|
143
|
-
jetstreamManager: jest.fn().mockResolvedValue(mockJsm),
|
|
144
|
-
};
|
|
145
|
-
mockConnect.mockResolvedValueOnce(mockConnection);
|
|
146
|
-
jest.spyOn(console, 'log').mockImplementation();
|
|
147
|
-
yield natsWrapper.connect('nats://localhost:4222');
|
|
148
|
-
}));
|
|
149
|
-
it('should return natsConnection after init', () => {
|
|
150
|
-
expect(natsWrapper.natsConnection).toBeDefined();
|
|
151
|
-
});
|
|
152
|
-
it('should return jetStreamClient after init', () => {
|
|
153
|
-
expect(natsWrapper.jetStreamClient).toBeDefined();
|
|
154
|
-
});
|
|
155
|
-
it('should return jetStreamManager after init', () => {
|
|
156
|
-
expect(natsWrapper.jetStreamManager).toBeDefined();
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const ioredis_1 = require("ioredis");
|
|
13
|
-
const redis_wrapper_1 = require("../redis-wrapper");
|
|
14
|
-
// Mock ioredis
|
|
15
|
-
jest.mock('ioredis', () => {
|
|
16
|
-
return {
|
|
17
|
-
Redis: jest.fn().mockImplementation(() => ({
|
|
18
|
-
connect: jest.fn().mockResolvedValue(undefined),
|
|
19
|
-
quit: jest.fn().mockResolvedValue(undefined),
|
|
20
|
-
set: jest.fn().mockResolvedValue('OK'),
|
|
21
|
-
get: jest.fn().mockResolvedValue('value'),
|
|
22
|
-
})),
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
const MockRedis = ioredis_1.Redis;
|
|
26
|
-
describe('RedisWrapper', () => {
|
|
27
|
-
let redisWrapper;
|
|
28
|
-
beforeEach(() => {
|
|
29
|
-
jest.clearAllMocks();
|
|
30
|
-
redisWrapper = new redis_wrapper_1.RedisWrapper();
|
|
31
|
-
});
|
|
32
|
-
describe('constructor', () => {
|
|
33
|
-
it('should use default values when no params provided', () => {
|
|
34
|
-
const wrapper = new redis_wrapper_1.RedisWrapper();
|
|
35
|
-
// The wrapper is created, defaults are used internally
|
|
36
|
-
expect(wrapper).toBeDefined();
|
|
37
|
-
});
|
|
38
|
-
it('should accept custom params', () => {
|
|
39
|
-
const wrapper = new redis_wrapper_1.RedisWrapper({
|
|
40
|
-
host: 'custom-host',
|
|
41
|
-
port: 6380,
|
|
42
|
-
username: 'user',
|
|
43
|
-
password: 'pass',
|
|
44
|
-
});
|
|
45
|
-
expect(wrapper).toBeDefined();
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
describe('client getter before connection', () => {
|
|
49
|
-
it('should throw error when accessing client before connecting', () => {
|
|
50
|
-
expect(() => redisWrapper.client).toThrow('Cannot access Redis client before connecting');
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
describe('connect', () => {
|
|
54
|
-
it('should connect to Redis successfully', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
56
|
-
yield redisWrapper.connect();
|
|
57
|
-
expect(MockRedis).toHaveBeenCalledWith({
|
|
58
|
-
host: 'localhost',
|
|
59
|
-
port: 6379,
|
|
60
|
-
username: '',
|
|
61
|
-
password: '',
|
|
62
|
-
lazyConnect: true,
|
|
63
|
-
});
|
|
64
|
-
expect(consoleSpy).toHaveBeenCalledWith('✅ Connected to Redis');
|
|
65
|
-
consoleSpy.mockRestore();
|
|
66
|
-
}));
|
|
67
|
-
it('should connect with custom params', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
68
|
-
const customWrapper = new redis_wrapper_1.RedisWrapper({
|
|
69
|
-
host: 'redis.example.com',
|
|
70
|
-
port: 6380,
|
|
71
|
-
username: 'admin',
|
|
72
|
-
password: 'secret',
|
|
73
|
-
});
|
|
74
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
75
|
-
yield customWrapper.connect();
|
|
76
|
-
expect(MockRedis).toHaveBeenCalledWith({
|
|
77
|
-
host: 'redis.example.com',
|
|
78
|
-
port: 6380,
|
|
79
|
-
username: 'admin',
|
|
80
|
-
password: 'secret',
|
|
81
|
-
lazyConnect: true,
|
|
82
|
-
});
|
|
83
|
-
consoleSpy.mockRestore();
|
|
84
|
-
}));
|
|
85
|
-
it('should handle connection error', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
|
-
MockRedis.mockImplementationOnce(() => ({
|
|
87
|
-
connect: jest.fn().mockRejectedValue(new Error('Connection failed')),
|
|
88
|
-
}));
|
|
89
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
90
|
-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
91
|
-
const wrapper = new redis_wrapper_1.RedisWrapper();
|
|
92
|
-
yield wrapper.connect();
|
|
93
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith('❌ Error connecting to Redis:', 'Connection failed');
|
|
94
|
-
expect(consoleSpy).toHaveBeenCalledWith('❌ Failed to connect to Redis');
|
|
95
|
-
consoleSpy.mockRestore();
|
|
96
|
-
consoleErrorSpy.mockRestore();
|
|
97
|
-
}));
|
|
98
|
-
});
|
|
99
|
-
describe('disconnect', () => {
|
|
100
|
-
it('should disconnect from Redis successfully', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
101
|
-
jest.spyOn(console, 'log').mockImplementation();
|
|
102
|
-
yield redisWrapper.connect();
|
|
103
|
-
yield redisWrapper.disconnect();
|
|
104
|
-
// No error thrown means success
|
|
105
|
-
expect(true).toBe(true);
|
|
106
|
-
}));
|
|
107
|
-
it('should handle disconnect error gracefully', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
|
-
MockRedis.mockImplementationOnce(() => ({
|
|
109
|
-
connect: jest.fn().mockResolvedValue(undefined),
|
|
110
|
-
quit: jest.fn().mockRejectedValue(new Error('Disconnect failed')),
|
|
111
|
-
}));
|
|
112
|
-
const wrapper = new redis_wrapper_1.RedisWrapper();
|
|
113
|
-
const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
114
|
-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
115
|
-
yield wrapper.connect();
|
|
116
|
-
yield wrapper.disconnect();
|
|
117
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith('❌ Error disconnecting from Redis:', 'Disconnect failed');
|
|
118
|
-
consoleSpy.mockRestore();
|
|
119
|
-
consoleErrorSpy.mockRestore();
|
|
120
|
-
}));
|
|
121
|
-
it('should handle disconnect when not connected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
122
|
-
yield redisWrapper.disconnect();
|
|
123
|
-
// Should not throw
|
|
124
|
-
expect(true).toBe(true);
|
|
125
|
-
}));
|
|
126
|
-
});
|
|
127
|
-
describe('set', () => {
|
|
128
|
-
it('should throw error when not connected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
129
|
-
yield expect(redisWrapper.set('key', 'value', 60)).rejects.toThrow('Redis not connected');
|
|
130
|
-
}));
|
|
131
|
-
it('should set value with expiration', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
132
|
-
jest.spyOn(console, 'log').mockImplementation();
|
|
133
|
-
yield redisWrapper.connect();
|
|
134
|
-
yield redisWrapper.set('testKey', 'testValue', 300);
|
|
135
|
-
const mockClient = MockRedis.mock.results[0].value;
|
|
136
|
-
expect(mockClient.set).toHaveBeenCalledWith('testKey', 'testValue', 'EX', 300);
|
|
137
|
-
}));
|
|
138
|
-
});
|
|
139
|
-
describe('get', () => {
|
|
140
|
-
it('should throw error when not connected', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
141
|
-
yield expect(redisWrapper.get('key')).rejects.toThrow('Redis not connected');
|
|
142
|
-
}));
|
|
143
|
-
it('should get value', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
|
-
jest.spyOn(console, 'log').mockImplementation();
|
|
145
|
-
yield redisWrapper.connect();
|
|
146
|
-
const result = yield redisWrapper.get('testKey');
|
|
147
|
-
expect(result).toBe('value');
|
|
148
|
-
const mockClient = MockRedis.mock.results[0].value;
|
|
149
|
-
expect(mockClient.get).toHaveBeenCalledWith('testKey');
|
|
150
|
-
}));
|
|
151
|
-
});
|
|
152
|
-
describe('client getter after connection', () => {
|
|
153
|
-
it('should return client after connecting', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
154
|
-
jest.spyOn(console, 'log').mockImplementation();
|
|
155
|
-
yield redisWrapper.connect();
|
|
156
|
-
expect(redisWrapper.client).toBeDefined();
|
|
157
|
-
}));
|
|
158
|
-
});
|
|
159
|
-
});
|
package/build/enum/image.d.ts
DELETED
package/build/enum/image.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
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 = {}));
|
package/build/enum/roles.d.ts
DELETED
package/build/enum/roles.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UserRoles = void 0;
|
|
4
|
-
var UserRoles;
|
|
5
|
-
(function (UserRoles) {
|
|
6
|
-
UserRoles[UserRoles["superAdmin"] = 1] = "superAdmin";
|
|
7
|
-
UserRoles[UserRoles["admin"] = 2] = "admin";
|
|
8
|
-
UserRoles[UserRoles["author"] = 3] = "author";
|
|
9
|
-
UserRoles[UserRoles["reader"] = 4] = "reader";
|
|
10
|
-
})(UserRoles || (exports.UserRoles = UserRoles = {}));
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BadRequestError = void 0;
|
|
4
|
-
const custom_error_1 = require("./custom-error");
|
|
5
|
-
class BadRequestError extends custom_error_1.CustomError {
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.message = message;
|
|
9
|
-
this.statusCode = 400;
|
|
10
|
-
Object.setPrototypeOf(this, BadRequestError.prototype);
|
|
11
|
-
}
|
|
12
|
-
serializeErrors() {
|
|
13
|
-
return [{ message: this.message }];
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.BadRequestError = BadRequestError;
|
|
@@ -1,16 +0,0 @@
|
|
|
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,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CustomError = void 0;
|
|
4
|
-
class CustomError extends Error {
|
|
5
|
-
constructor(message) {
|
|
6
|
-
super(message);
|
|
7
|
-
Object.setPrototypeOf(this, CustomError.prototype);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
exports.CustomError = CustomError;
|