codeweaver 3.1.3 → 4.0.0

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 (79) hide show
  1. package/README.md +56 -73
  2. package/package.json +23 -1
  3. package/src/config.ts +17 -15
  4. package/src/constants.ts +1 -0
  5. package/src/core/aws/api-gateway.ts +187 -0
  6. package/src/core/aws/basic-types.ts +147 -0
  7. package/src/core/aws/dynamodb.ts +187 -0
  8. package/src/core/aws/index.ts +9 -0
  9. package/src/core/aws/lambda.ts +199 -0
  10. package/src/core/aws/message-broker.ts +167 -0
  11. package/src/core/aws/message.ts +259 -0
  12. package/src/core/aws/s3.ts +136 -0
  13. package/src/core/aws/utilities.ts +44 -0
  14. package/src/core/cache/basic-types.ts +17 -0
  15. package/src/core/cache/decorator.ts +72 -0
  16. package/src/core/cache/index.ts +4 -0
  17. package/src/core/cache/memory-cache.class.ts +119 -0
  18. package/src/{utilities/cache/redis-cache.ts → core/cache/redis-cache.class.ts} +58 -10
  19. package/src/core/container/basic-types.ts +10 -0
  20. package/src/{utilities → core/container}/container.ts +7 -17
  21. package/src/core/container/index.ts +2 -0
  22. package/src/{utilities → core/error}/error-handling.ts +1 -65
  23. package/src/core/error/index.ts +3 -0
  24. package/src/core/error/response-error.ts +45 -0
  25. package/src/core/error/send-http-error.ts +15 -0
  26. package/src/core/file/file-helpers.ts +166 -0
  27. package/src/core/file/index.ts +1 -0
  28. package/src/{utilities → core/helpers}/assignment.ts +2 -2
  29. package/src/core/helpers/comparison.ts +86 -0
  30. package/src/{utilities → core/helpers}/conversion.ts +2 -2
  31. package/src/core/helpers/decorators.ts +316 -0
  32. package/src/core/helpers/format.ts +9 -0
  33. package/src/core/helpers/index.ts +7 -0
  34. package/src/core/helpers/range.ts +67 -0
  35. package/src/core/helpers/types.ts +3 -0
  36. package/src/core/logger/index.ts +4 -0
  37. package/src/{utilities/logger/logger.config.ts → core/logger/winston-logger.config.ts} +1 -1
  38. package/src/{utilities → core}/logger/winston-logger.service.ts +3 -3
  39. package/src/core/message-broker/bullmq/basic-types.ts +67 -0
  40. package/src/core/message-broker/bullmq/broker.ts +141 -0
  41. package/src/core/message-broker/bullmq/index.ts +3 -0
  42. package/src/core/message-broker/bullmq/queue.ts +58 -0
  43. package/src/core/message-broker/bullmq/worker.ts +68 -0
  44. package/src/core/message-broker/kafka/basic-types.ts +45 -0
  45. package/src/core/message-broker/kafka/consumer.ts +95 -0
  46. package/src/core/message-broker/kafka/index.ts +3 -0
  47. package/src/core/message-broker/kafka/producer.ts +113 -0
  48. package/src/core/message-broker/rabitmq/basic-types.ts +44 -0
  49. package/src/core/message-broker/rabitmq/channel.ts +95 -0
  50. package/src/core/message-broker/rabitmq/consumer.ts +94 -0
  51. package/src/core/message-broker/rabitmq/index.ts +4 -0
  52. package/src/core/message-broker/rabitmq/producer.ts +100 -0
  53. package/src/core/message-broker/utilities.ts +50 -0
  54. package/src/core/middlewares/basic-types.ts +39 -0
  55. package/src/core/middlewares/decorators.ts +244 -0
  56. package/src/core/middlewares/index.ts +3 -0
  57. package/src/core/middlewares/middlewares.ts +246 -0
  58. package/src/core/parallel/index.ts +3 -0
  59. package/src/{utilities → core}/parallel/parallel.ts +11 -1
  60. package/src/core/rate-limit/basic-types.ts +43 -0
  61. package/src/core/rate-limit/index.ts +4 -0
  62. package/src/core/rate-limit/memory-store.ts +65 -0
  63. package/src/core/rate-limit/rate-limit.ts +134 -0
  64. package/src/core/rate-limit/redis-store.ts +141 -0
  65. package/src/core/retry/basic-types.ts +21 -0
  66. package/src/core/retry/decorator.ts +139 -0
  67. package/src/core/retry/index.ts +2 -0
  68. package/src/main.ts +6 -8
  69. package/src/routers/orders/index.router.ts +5 -1
  70. package/src/routers/orders/order.controller.ts +46 -59
  71. package/src/routers/products/index.router.ts +2 -1
  72. package/src/routers/products/product.controller.ts +25 -63
  73. package/src/routers/users/index.router.ts +1 -1
  74. package/src/routers/users/user.controller.ts +22 -50
  75. package/src/utilities/cache/memory-cache.ts +0 -74
  76. /package/src/{utilities → core}/logger/base-logger.interface.ts +0 -0
  77. /package/src/{utilities → core}/logger/logger.service.ts +0 -0
  78. /package/src/{utilities → core}/parallel/chanel.ts +0 -0
  79. /package/src/{utilities → core}/parallel/worker-pool.ts +0 -0
@@ -1,20 +1,21 @@
1
- import { memoizeAsync, onError, rateLimit, timeout } from "utils-decorators";
2
1
  import { OrderDto, OrderCreationDto, ZodOrderDto } from "./dto/order.dto";
3
- import { ResponseError } from "@/utilities/error-handling";
4
- import { convert, stringToInteger } from "@/utilities/conversion";
2
+ import { ResponseError } from "@/core/error";
3
+ import { convert, stringToInteger } from "@/core/helpers";
5
4
  import { config } from "@/config";
6
5
  import { orders } from "@/db";
7
6
  import { Order, ZodOrder } from "@/entities/order.entity";
8
- import { MapAsyncCache } from "@/utilities/cache/memory-cache";
9
- import { Injectable } from "@/utilities/container";
10
- import { parallelMap } from "@/utilities/parallel/parallel";
7
+ import { Invalidate, MapAsyncCache, Memoize } from "@/core/cache";
8
+ import { Injectable } from "@/core/container";
9
+ import { parallelMap } from "@/core/parallel";
10
+ import { RateLimit } from "@/core/rate-limit";
11
+ import { ErrorHandler, Timeout } from "@/core/middlewares";
11
12
 
12
- function exceedHandler() {
13
+ async function exceedHandler() {
13
14
  const message = "Too much call in allowed window";
14
15
  throw new ResponseError(message, 429);
15
16
  }
16
17
 
17
- function invalidInputHandler(e: ResponseError) {
18
+ async function invalidInputHandler(e: ResponseError) {
18
19
  const message = "Invalid input";
19
20
  throw new ResponseError(message, 400, e.message);
20
21
  }
@@ -31,9 +32,7 @@ const orderCache = new MapAsyncCache<OrderDto>(config.cacheSize);
31
32
  export default class OrderController {
32
33
  // constructor(private readonly orderService: OrderService) { }
33
34
 
34
- @onError({
35
- func: invalidInputHandler,
36
- })
35
+ @ErrorHandler(invalidInputHandler)
37
36
  /**
38
37
  * Validates a string ID and converts it to a number.
39
38
  *
@@ -44,9 +43,7 @@ export default class OrderController {
44
43
  return stringToInteger(id);
45
44
  }
46
45
 
47
- @onError({
48
- func: invalidInputHandler,
49
- })
46
+ @ErrorHandler(invalidInputHandler)
50
47
  /**
51
48
  * Validates and creates a new Order from the given DTO.
52
49
  *
@@ -66,11 +63,12 @@ export default class OrderController {
66
63
  return convert(newOrder, ZodOrder);
67
64
  }
68
65
 
69
- @rateLimit({
70
- timeSpanMs: config.rateLimitTimeSpan,
71
- allowedCalls: config.rateLimitAllowedCalls,
72
- exceedHandler,
73
- })
66
+ @Invalidate(ordersCache)
67
+ @RateLimit(
68
+ config.rateLimitTimeSpan,
69
+ config.rateLimitAllowedCalls,
70
+ exceedHandler
71
+ )
74
72
  /**
75
73
  * Create a new order
76
74
  * @param {Order} order - Order creation data
@@ -80,20 +78,15 @@ export default class OrderController {
80
78
  */
81
79
  public async create(order: Order): Promise<void> {
82
80
  orders.push(order);
83
- await ordersCache.delete("key");
84
81
  }
85
82
 
86
- @memoizeAsync({
87
- cache: ordersCache,
88
- keyResolver: () => "key",
89
- expirationTimeMs: config.memoizeTime,
90
- })
91
- @timeout(config.timeout)
92
- @rateLimit({
93
- timeSpanMs: config.rateLimitTimeSpan,
94
- allowedCalls: config.rateLimitAllowedCalls,
95
- exceedHandler,
96
- })
83
+ @Memoize(orderCache)
84
+ @Timeout(config.timeout)
85
+ @RateLimit(
86
+ config.rateLimitTimeSpan,
87
+ config.rateLimitAllowedCalls,
88
+ exceedHandler
89
+ )
97
90
  /**
98
91
  * Retrieves all orders
99
92
  * @returns List of orders
@@ -105,16 +98,12 @@ export default class OrderController {
105
98
  );
106
99
  }
107
100
 
108
- @memoizeAsync({
109
- cache: orderCache,
110
- keyResolver: (id: number) => id.toString(),
111
- expirationTimeMs: config.memoizeTime,
112
- })
113
- @rateLimit({
114
- timeSpanMs: config.rateLimitTimeSpan,
115
- allowedCalls: config.rateLimitAllowedCalls,
116
- exceedHandler,
117
- })
101
+ @Memoize(orderCache)
102
+ @RateLimit(
103
+ config.rateLimitTimeSpan,
104
+ config.rateLimitAllowedCalls,
105
+ exceedHandler
106
+ )
118
107
  /**
119
108
  * Finds an order by its ID
120
109
  * @param {number} id - Order ID as string
@@ -128,11 +117,13 @@ export default class OrderController {
128
117
  return await convert(order, ZodOrder);
129
118
  }
130
119
 
131
- @rateLimit({
132
- timeSpanMs: config.rateLimitTimeSpan,
133
- allowedCalls: config.rateLimitAllowedCalls,
134
- exceedHandler,
135
- })
120
+ @Invalidate(orderCache, false)
121
+ @Invalidate(ordersCache)
122
+ @RateLimit(
123
+ config.rateLimitTimeSpan,
124
+ config.rateLimitAllowedCalls,
125
+ exceedHandler
126
+ )
136
127
  /**
137
128
  * Cancel an existing order
138
129
  * @param {number} id - Order ID to cancel
@@ -145,21 +136,20 @@ export default class OrderController {
145
136
  if (order.status != "Processing") {
146
137
  throw new ResponseError(
147
138
  "Cancellation is not available unless the order is in processing status.",
148
- 400
139
+ 409
149
140
  );
150
141
  }
151
142
  order.status = "Canceled";
152
143
  order.deliveredAt = new Date();
153
-
154
- await orderCache.delete(id.toString());
155
- await ordersCache.delete("key");
156
144
  }
157
145
 
158
- @rateLimit({
159
- timeSpanMs: config.rateLimitTimeSpan,
160
- allowedCalls: config.rateLimitAllowedCalls,
161
- exceedHandler,
162
- })
146
+ @Invalidate(orderCache, false)
147
+ @Invalidate(ordersCache)
148
+ @RateLimit(
149
+ config.rateLimitTimeSpan,
150
+ config.rateLimitAllowedCalls,
151
+ exceedHandler
152
+ )
163
153
  /**
164
154
  * Mark an order as delivered
165
155
  * @param {number} id - Order ID to mark as delivered
@@ -172,13 +162,10 @@ export default class OrderController {
172
162
  if (order.status != "Processing") {
173
163
  throw new ResponseError(
174
164
  "Delivery is only available when the order is in processing status.",
175
- 400
165
+ 409
176
166
  );
177
167
  }
178
168
  order.status = "Delivered";
179
169
  order.deliveredAt = new Date();
180
-
181
- await orderCache.delete(id.toString());
182
- await ordersCache.delete("key");
183
170
  }
184
171
  }
@@ -1,7 +1,7 @@
1
1
  import { Router, Request, Response } from "express";
2
2
  import asyncHandler from "express-async-handler";
3
3
  import ProductController from "./product.controller";
4
- import { resolve } from "@/utilities/container";
4
+ import { resolve } from "@/core/container";
5
5
 
6
6
  const router = Router();
7
7
  const productController = resolve(ProductController);
@@ -201,6 +201,7 @@ router.delete(
201
201
  asyncHandler(async (req: Request, res: Response) => {
202
202
  const id = await productController.validateId(req.params.id);
203
203
  await productController.delete(id);
204
+ res.status(204).send();
204
205
  })
205
206
  );
206
207
 
@@ -1,26 +1,22 @@
1
- import { memoizeAsync, onError, rateLimit, timeout } from "utils-decorators";
2
1
  import {
3
2
  ProductCreationDto,
4
3
  ProductDto,
5
4
  ProductUpdateDto,
6
5
  ZodProductDto,
7
6
  } from "./dto/product.dto";
8
- import { MapAsyncCache } from "@/utilities/cache/memory-cache";
9
- import { convert, stringToInteger } from "@/utilities/conversion";
7
+ import { Invalidate, MapAsyncCache, Memoize } from "@/core/cache";
8
+ import { convert, stringToInteger } from "@/core/helpers";
10
9
  import { config } from "@/config";
11
- import { ResponseError } from "@/utilities/error-handling";
10
+ import { ResponseError } from "@/core/error";
12
11
  import { products } from "@/db";
13
12
  import { Product, ZodProduct } from "@/entities/product.entity";
14
- import { Injectable } from "@/utilities/container";
15
- import assign from "@/utilities/assignment";
16
- import { parallelMap } from "@/utilities/parallel/parallel";
13
+ import { Injectable } from "@/core/container";
14
+ import { assign } from "@/core/helpers";
15
+ import { parallelMap } from "@/core/parallel";
16
+ import { ErrorHandler, Timeout } from "@/core/middlewares";
17
+ import { RateLimit } from "@/core/rate-limit";
17
18
 
18
- function exceedHandler() {
19
- const message = "Too much call in allowed window";
20
- throw new ResponseError(message, 429);
21
- }
22
-
23
- function invalidInputHandler(e: ResponseError) {
19
+ async function invalidInputHandler(e: ResponseError) {
24
20
  const message = "Invalid input";
25
21
  throw new ResponseError(message, 400, e.message);
26
22
  }
@@ -37,9 +33,7 @@ const productCache = new MapAsyncCache<ProductDto>(config.cacheSize);
37
33
  export default class ProductController {
38
34
  // constructor(private readonly productService: ProductService) { }
39
35
 
40
- @onError({
41
- func: invalidInputHandler,
42
- })
36
+ @ErrorHandler(invalidInputHandler)
43
37
  /**
44
38
  * Validates a string ID and converts it to a number.
45
39
  *
@@ -50,9 +44,7 @@ export default class ProductController {
50
44
  return stringToInteger(id);
51
45
  }
52
46
 
53
- @onError({
54
- func: invalidInputHandler,
55
- })
47
+ @ErrorHandler(invalidInputHandler)
56
48
  /**
57
49
  * Validates and creates a new Product from the given DTO.
58
50
  *
@@ -65,9 +57,7 @@ export default class ProductController {
65
57
  return await convert({ ...product, id: products.length + 1 }, ZodProduct);
66
58
  }
67
59
 
68
- @onError({
69
- func: invalidInputHandler,
70
- })
60
+ @ErrorHandler(invalidInputHandler)
71
61
  /**
72
62
  * Validates and creates a new Product from the given DTO.
73
63
  *
@@ -80,11 +70,8 @@ export default class ProductController {
80
70
  return await convert(product, ZodProduct);
81
71
  }
82
72
 
83
- @rateLimit({
84
- timeSpanMs: config.rateLimitTimeSpan,
85
- allowedCalls: config.rateLimitAllowedCalls,
86
- exceedHandler,
87
- })
73
+ @Invalidate(productsCache)
74
+ @RateLimit(config.rateLimitTimeSpan, config.rateLimitAllowedCalls)
88
75
  /**
89
76
  * Creates a new product with validated data
90
77
  * @param {Product} product - Product creation data validated by Zod schema
@@ -94,20 +81,11 @@ export default class ProductController {
94
81
  */
95
82
  public async create(product: Product): Promise<void> {
96
83
  products.push(product);
97
- await productsCache.delete("key");
98
84
  }
99
85
 
100
- @memoizeAsync({
101
- cache: productsCache,
102
- keyResolver: () => "key",
103
- expirationTimeMs: config.memoizeTime,
104
- })
105
- @timeout(config.timeout)
106
- @rateLimit({
107
- timeSpanMs: config.rateLimitTimeSpan,
108
- allowedCalls: config.rateLimitAllowedCalls,
109
- exceedHandler,
110
- })
86
+ @Memoize(productsCache)
87
+ @Timeout(config.timeout)
88
+ @RateLimit(config.rateLimitTimeSpan, config.rateLimitAllowedCalls)
111
89
  /**
112
90
  * Retrieves all products with truncated descriptions
113
91
  * @returns List of products with summarized descriptions
@@ -119,16 +97,8 @@ export default class ProductController {
119
97
  );
120
98
  }
121
99
 
122
- @memoizeAsync({
123
- cache: productCache,
124
- keyResolver: (id: number) => id.toString(),
125
- expirationTimeMs: config.memoizeTime,
126
- })
127
- @rateLimit({
128
- timeSpanMs: config.rateLimitTimeSpan,
129
- allowedCalls: config.rateLimitAllowedCalls,
130
- exceedHandler,
131
- })
100
+ @Memoize(productCache)
101
+ @RateLimit(config.rateLimitTimeSpan, config.rateLimitAllowedCalls)
132
102
  /**
133
103
  * Finds a product by its ID
134
104
  * @param {number} id - Product ID as string
@@ -142,11 +112,9 @@ export default class ProductController {
142
112
  return await convert(product, ZodProduct);
143
113
  }
144
114
 
145
- @rateLimit({
146
- timeSpanMs: config.rateLimitTimeSpan,
147
- allowedCalls: config.rateLimitAllowedCalls,
148
- exceedHandler,
149
- })
115
+ @Invalidate(productCache, false)
116
+ @Invalidate(productsCache)
117
+ @RateLimit(config.rateLimitTimeSpan, config.rateLimitAllowedCalls)
150
118
  /**
151
119
  * Updates an existing product
152
120
  * @param {number} id - Product ID to update
@@ -162,18 +130,14 @@ export default class ProductController {
162
130
  const product = await this.get(id);
163
131
  if (product != null) {
164
132
  await assign(product, updateData, ZodProduct);
165
- await productCache.delete(updateData.id.toString());
166
- await productsCache.delete("key");
167
133
  } else {
168
134
  throw new ResponseError("Product dose not exist.", 404);
169
135
  }
170
136
  }
171
137
 
172
- @rateLimit({
173
- timeSpanMs: config.rateLimitTimeSpan,
174
- allowedCalls: config.rateLimitAllowedCalls,
175
- exceedHandler,
176
- })
138
+ @Invalidate(productCache, false)
139
+ @Invalidate(productsCache)
140
+ @RateLimit(config.rateLimitTimeSpan, config.rateLimitAllowedCalls)
177
141
  /**
178
142
  * Deletes a product by ID
179
143
  * @param {number} id - Product ID to delete
@@ -186,8 +150,6 @@ export default class ProductController {
186
150
  if (index == -1) {
187
151
  throw new ResponseError("Product dose not exist.", 404);
188
152
  }
189
- await productCache.delete(id.toString());
190
- await productsCache.delete("key");
191
153
  products.splice(index, 1)[0];
192
154
  }
193
155
  }
@@ -1,7 +1,7 @@
1
1
  import { Router, Request, Response } from "express";
2
2
  import asyncHandler from "express-async-handler";
3
3
  import UserController from "./user.controller";
4
- import { resolve } from "@/utilities/container";
4
+ import { resolve } from "@/core/container";
5
5
 
6
6
  const router = Router();
7
7
  const userController = resolve(UserController);
@@ -1,26 +1,21 @@
1
1
  import { UserCreationDto, UserDto, ZodUserDto } from "./dto/user.dto";
2
- import { memoizeAsync, onError, rateLimit, timeout } from "utils-decorators";
3
- import { ResponseError } from "@/utilities/error-handling";
4
- import { convert, stringToInteger } from "@/utilities/conversion";
2
+ import { ResponseError } from "@/core/error";
3
+ import { convert, stringToInteger } from "@/core/helpers";
5
4
  import { config } from "@/config";
6
5
  import { users } from "@/db";
7
6
  import { User, ZodUser } from "@/entities/user.entity";
8
- import { MapAsyncCache } from "@/utilities/cache/memory-cache";
9
- import { Injectable } from "@/utilities/container";
10
- import { parallelMap } from "@/utilities/parallel/parallel";
7
+ import { Invalidate, MapAsyncCache, Memoize } from "@/core/cache";
8
+ import { Injectable } from "@/core/container";
9
+ import { parallelMap } from "@/core/parallel";
10
+ import { ErrorHandler, LogMethod, Timeout } from "@/core/middlewares";
11
+ import { RateLimit } from "@/core/rate-limit";
11
12
 
12
- function exceedHandler() {
13
- const message = "Too much call in allowed window";
14
- throw new ResponseError(message, 429);
15
- }
16
-
17
- function invalidInputHandler(e: ResponseError) {
13
+ async function invalidInputHandler(e: ResponseError) {
18
14
  const message = "Invalid input";
19
15
  throw new ResponseError(message, 400, e?.message);
20
16
  }
21
17
 
22
18
  const usersCache = new MapAsyncCache<UserDto[]>(config.cacheSize);
23
- const userCache = new MapAsyncCache<UserDto>(config.cacheSize);
24
19
 
25
20
  @Injectable()
26
21
  /**
@@ -31,9 +26,7 @@ const userCache = new MapAsyncCache<UserDto>(config.cacheSize);
31
26
  export default class UserController {
32
27
  // constructor(private readonly userService: UserService) { }
33
28
 
34
- @onError({
35
- func: invalidInputHandler,
36
- })
29
+ @ErrorHandler(invalidInputHandler)
37
30
  /**
38
31
  * Validates a string ID and converts it to a number.
39
32
  *
@@ -44,9 +37,7 @@ export default class UserController {
44
37
  return stringToInteger(id);
45
38
  }
46
39
 
47
- @onError({
48
- func: invalidInputHandler,
49
- })
40
+ @ErrorHandler(invalidInputHandler)
50
41
  /**
51
42
  * Validates and creates a new User from the given DTO.
52
43
  *
@@ -57,11 +48,8 @@ export default class UserController {
57
48
  return await convert(user, ZodUser);
58
49
  }
59
50
 
60
- @rateLimit({
61
- timeSpanMs: config.rateLimitTimeSpan,
62
- allowedCalls: config.rateLimitAllowedCalls,
63
- exceedHandler,
64
- })
51
+ @Invalidate(usersCache)
52
+ @RateLimit(config.rateLimitTimeSpan, config.rateLimitAllowedCalls)
65
53
  /**
66
54
  * Create a new user
67
55
  * @param {User} user - User creation data validated by Zod schema
@@ -71,42 +59,26 @@ export default class UserController {
71
59
  */
72
60
  public async create(user: User): Promise<void> {
73
61
  users.push(user);
74
- await usersCache.delete("key");
75
62
  }
76
63
 
77
- @memoizeAsync({
78
- cache: usersCache,
79
- keyResolver: () => "key",
80
- expirationTimeMs: config.memoizeTime,
81
- })
82
- @timeout(config.timeout)
83
- @rateLimit({
84
- timeSpanMs: config.rateLimitTimeSpan,
85
- allowedCalls: config.rateLimitAllowedCalls,
86
- exceedHandler,
87
- })
64
+ @Memoize(usersCache)
65
+ @Timeout(config.timeout)
66
+ @RateLimit(config.rateLimitTimeSpan, config.rateLimitAllowedCalls)
88
67
  /**
89
68
  * Get all users
90
69
  * @returns {Promise<UserDto[]>} List of users with hidden password fields
91
70
  * @throws {ResponseError} 500 - When rate limit exceeded
92
71
  */
93
- public async getAll(): Promise<UserDto[]> {
94
- return await parallelMap(
95
- users,
96
- async (user) => await convert(user, ZodUserDto)
72
+ public async getAll(signal?: AbortSignal): Promise<(UserDto | null)[]> {
73
+ return await parallelMap(users, async (user) =>
74
+ signal?.aborted == false
75
+ ? await convert<User, UserDto>(user!, ZodUserDto)
76
+ : null
97
77
  );
98
78
  }
99
79
 
100
- @memoizeAsync({
101
- cache: userCache,
102
- keyResolver: (id: number) => id.toString(),
103
- expirationTimeMs: config.memoizeTime,
104
- })
105
- @rateLimit({
106
- timeSpanMs: config.rateLimitTimeSpan,
107
- allowedCalls: config.rateLimitAllowedCalls,
108
- exceedHandler,
109
- })
80
+ @Memoize(usersCache)
81
+ @RateLimit(config.rateLimitTimeSpan, config.rateLimitAllowedCalls)
110
82
  /**
111
83
  * Get user by ID
112
84
  * @param {number} id - User ID as string
@@ -1,74 +0,0 @@
1
- import { AsyncCache } from "utils-decorators";
2
-
3
- /**
4
- * A simple in-memory map-based cache implementing AsyncCache<T>.
5
- * This is a straightforward wrapper around a Map<string, T>.
6
- */
7
- export class MapAsyncCache<T> implements AsyncCache<T> {
8
- public constructor(
9
- private capacity?: number,
10
- private cache?: Map<string, T>
11
- ) {
12
- this.capacity = this.capacity ?? Number.POSITIVE_INFINITY;
13
- this.cache = this.cache ?? new Map<string, T>();
14
- }
15
-
16
- /**
17
- * Asynchronously set a value by key.
18
- * @param key The cache key
19
- * @param value The value to cache
20
- */
21
- async set(key: string, value: T): Promise<void> {
22
- if (value != null) {
23
- if (this.cache?.has(key)) {
24
- this.cache?.set(key, value);
25
- } else {
26
- if (
27
- (this.capacity ?? Number.POSITIVE_INFINITY) > (this.cache?.size ?? 0)
28
- ) {
29
- this.cache?.set(key, value);
30
- }
31
- }
32
- } else {
33
- this.cache?.delete(key);
34
- }
35
- }
36
-
37
- /**
38
- * Asynchronously get a value by key.
39
- * - If the key exists, returns the value.
40
- * - If the key does not exist, returns undefined cast to T to satisfy the Promise<T> return type.
41
- *
42
- * Note: Returning undefined may be surprising for callers expecting a strict A/B.
43
- * Consider returning `T | undefined` from AsyncCache if you can adjust the interface,
44
- * or throw a ResponseError for "not found" depending on your usage.
45
- */
46
- async get(key: string): Promise<T> {
47
- if (this.cache?.has(key)) {
48
- return this.cache?.get(key) ?? (null as T);
49
- }
50
-
51
- return null as T;
52
- }
53
-
54
- /**
55
- * Asynchronously delete a value by key.
56
- */
57
- async delete(key: string): Promise<void> {
58
- this.cache?.delete(key);
59
- }
60
-
61
- /**
62
- * Asynchronously check if a key exists in the cache.
63
- */
64
- async has(key: string): Promise<boolean> {
65
- return this.cache?.has(key) ?? false;
66
- }
67
-
68
- /**
69
- * Asynchronously clear the cache.
70
- */
71
- async clear(key: string): Promise<void> {
72
- this.cache?.clear();
73
- }
74
- }
File without changes
File without changes