@catbee/utils 2.0.0-next.0 → 2.0.0-next.1

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 (97) hide show
  1. package/README.md +52 -16
  2. package/array/index.cjs +180 -71
  3. package/array/index.d.ts +293 -1
  4. package/array/index.mjs +171 -72
  5. package/async/index.cjs +92 -36
  6. package/async/index.d.ts +275 -1
  7. package/async/index.mjs +92 -36
  8. package/cache/index.cjs +1 -1
  9. package/cache/index.d.ts +155 -1
  10. package/cache/index.mjs +2 -2
  11. package/config/index.cjs +78 -64
  12. package/config/index.d.ts +64 -2
  13. package/config/index.mjs +76 -64
  14. package/context-store/index.d.ts +192 -1
  15. package/crypto/index.d.ts +163 -1
  16. package/date/index.cjs +46 -1
  17. package/date/index.d.ts +190 -1
  18. package/date/index.mjs +45 -2
  19. package/decorators/index.cjs +1156 -18
  20. package/decorators/index.d.ts +684 -1
  21. package/decorators/index.mjs +1156 -18
  22. package/dir/index.cjs +4 -3
  23. package/dir/index.d.ts +195 -1
  24. package/dir/index.mjs +4 -3
  25. package/env/index.cjs +10 -26
  26. package/env/index.d.ts +379 -1
  27. package/env/index.mjs +10 -26
  28. package/exception/index.d.ts +232 -1
  29. package/fs/index.cjs +70 -36
  30. package/fs/index.d.ts +205 -1
  31. package/fs/index.mjs +64 -34
  32. package/http-status-codes/index.d.ts +267 -1
  33. package/id/index.d.ts +37 -1
  34. package/index.cjs +3 -3
  35. package/index.d.ts +1 -1
  36. package/index.mjs +1 -1
  37. package/logger/index.cjs +11 -11
  38. package/logger/index.d.ts +189 -1
  39. package/logger/index.mjs +12 -12
  40. package/middleware/index.d.ts +103 -1
  41. package/obj/index.cjs +150 -162
  42. package/obj/index.d.ts +136 -1
  43. package/obj/index.mjs +150 -162
  44. package/package.json +11 -11
  45. package/performance/index.cjs +2 -2
  46. package/performance/index.d.ts +138 -1
  47. package/performance/index.mjs +2 -2
  48. package/request/index.cjs +1 -1
  49. package/request/index.d.ts +241 -2
  50. package/request/index.mjs +1 -1
  51. package/response/index.d.ts +318 -2
  52. package/server/index.cjs +27 -23
  53. package/server/index.d.ts +785 -4
  54. package/server/index.mjs +28 -23
  55. package/stream/index.d.ts +90 -1
  56. package/string/index.d.ts +102 -1
  57. package/type/index.cjs +1 -1
  58. package/type/index.d.ts +107 -1
  59. package/type/index.mjs +1 -1
  60. package/types/index.d.ts +774 -4
  61. package/url/index.cjs +2 -4
  62. package/url/index.d.ts +142 -1
  63. package/url/index.mjs +2 -4
  64. package/{validate → validation}/index.cjs +89 -42
  65. package/{validate/validate.utils.d.ts → validation/index.d.ts} +32 -23
  66. package/{validate → validation}/index.mjs +85 -42
  67. package/array/array.utils.d.ts +0 -191
  68. package/async/async.utils.d.ts +0 -296
  69. package/cache/cache.utils.d.ts +0 -176
  70. package/config/config.d.ts +0 -57
  71. package/context-store/context-store.utils.d.ts +0 -212
  72. package/crypto/crypto.utils.d.ts +0 -183
  73. package/date/date.utils.d.ts +0 -190
  74. package/decorators/decorators.utils.d.ts +0 -705
  75. package/dir/dir.utils.d.ts +0 -216
  76. package/env/env.utils.d.ts +0 -400
  77. package/exception/exception.utils.d.ts +0 -253
  78. package/fs/fs.utils.d.ts +0 -196
  79. package/http-status-codes/http-status-codes.d.ts +0 -289
  80. package/id/id.utils.d.ts +0 -59
  81. package/logger/logger.utils.d.ts +0 -210
  82. package/middleware/middleware.utils.d.ts +0 -123
  83. package/obj/obj.utils.d.ts +0 -156
  84. package/performance/performance.utils.d.ts +0 -159
  85. package/request/request.utils.d.ts +0 -109
  86. package/response/response.utils.d.ts +0 -186
  87. package/server/server.builder.d.ts +0 -531
  88. package/server/server.d.ts +0 -303
  89. package/stream/stream.utils.d.ts +0 -111
  90. package/string/string.utils.d.ts +0 -124
  91. package/type/type.utils.d.ts +0 -129
  92. package/types/api-response.d.ts +0 -175
  93. package/types/common.d.ts +0 -148
  94. package/types/config.d.ts +0 -88
  95. package/types/server.d.ts +0 -291
  96. package/url/url.utils.d.ts +0 -164
  97. package/validate/index.d.ts +0 -25
package/async/index.mjs CHANGED
@@ -43,7 +43,13 @@ function debounce(fn, delay) {
43
43
  pendingArgs = args;
44
44
  if (timer) clearTimeout(timer);
45
45
  timer = setTimeout(() => {
46
- fn(...pendingArgs);
46
+ try {
47
+ fn(...pendingArgs);
48
+ } catch (err) {
49
+ getLogger().error({
50
+ err
51
+ }, "Error in debounced function");
52
+ }
47
53
  timer = null;
48
54
  }, delay);
49
55
  }
@@ -56,7 +62,13 @@ function debounce(fn, delay) {
56
62
  debounced.flush = () => {
57
63
  if (timer) {
58
64
  clearTimeout(timer);
59
- fn(...pendingArgs);
65
+ try {
66
+ fn(...pendingArgs);
67
+ } catch (err) {
68
+ getLogger().error({
69
+ err
70
+ }, "Error in debounced.flush");
71
+ }
60
72
  timer = null;
61
73
  pendingArgs = null;
62
74
  }
@@ -82,14 +94,28 @@ function throttle(fn, limit, opts = {
82
94
  timer = null;
83
95
  }
84
96
  lastCall = now;
85
- fn(...args);
97
+ try {
98
+ fn(...args);
99
+ } catch (err) {
100
+ getLogger().error({
101
+ err
102
+ }, "Error in throttled function");
103
+ }
86
104
  } else if (trailing) {
87
105
  savedArgs = args;
88
106
  if (!timer) {
89
107
  timer = setTimeout(() => {
90
108
  lastCall = leading ? Date.now() : 0;
91
109
  timer = null;
92
- if (savedArgs) fn(...savedArgs);
110
+ if (savedArgs) {
111
+ try {
112
+ fn(...savedArgs);
113
+ } catch (err) {
114
+ getLogger().error({
115
+ err
116
+ }, "Error in throttled trailing call");
117
+ }
118
+ }
93
119
  }, remaining);
94
120
  }
95
121
  }
@@ -140,7 +166,7 @@ function singletonAsync(fn, drop = false) {
140
166
  promise = null;
141
167
  });
142
168
  } else if (drop) {
143
- return Promise.reject(new Error("Busy: function already running"));
169
+ throw new Error("Function is already in progress");
144
170
  }
145
171
  return promise;
146
172
  };
@@ -211,11 +237,19 @@ async function runInSeries(tasks) {
211
237
  __name(runInSeries, "runInSeries");
212
238
  function memoizeAsync(fn, options = {}) {
213
239
  const cache = /* @__PURE__ */ new Map();
214
- const { ttl, keyFn = JSON.stringify } = options;
215
- return async function(...args) {
216
- const key = keyFn(args);
240
+ const { ttl } = options;
241
+ const generateKey = /* @__PURE__ */ __name((args) => {
242
+ try {
243
+ return options.keyFn?.(args) ?? JSON.stringify(args);
244
+ } catch {
245
+ getLogger().warn("memoizeAsync: key generation failed, falling back to JSON.stringify");
246
+ return JSON.stringify(args);
247
+ }
248
+ }, "generateKey");
249
+ return async (...args) => {
250
+ const key = generateKey(args);
217
251
  const cached = cache.get(key);
218
- if (cached && (!ttl || Date.now() < cached.expires)) {
252
+ if (cached && Date.now() < cached.expires) {
219
253
  return cached.value;
220
254
  }
221
255
  const result = await fn(...args);
@@ -234,7 +268,10 @@ function abortable(promise, signal, abortValue = new Error("Operation aborted"))
234
268
  return Promise.race([
235
269
  promise,
236
270
  new Promise((_, reject) => {
237
- const abort = /* @__PURE__ */ __name(() => reject(abortValue), "abort");
271
+ const abort = /* @__PURE__ */ __name(() => {
272
+ reject(abortValue);
273
+ signal.removeEventListener("abort", abort);
274
+ }, "abort");
238
275
  signal.addEventListener("abort", abort, {
239
276
  once: true
240
277
  });
@@ -303,39 +340,53 @@ var CircuitBreakerState = /* @__PURE__ */ (function(CircuitBreakerState2) {
303
340
  function circuitBreaker(fn, options = {}) {
304
341
  const { failureThreshold = 5, resetTimeout = 1e4, successThreshold = 1, onOpen, onClose, onHalfOpen } = options;
305
342
  let state = "CLOSED";
306
- let failureCount = 0;
307
- let successCount = 0;
308
- let nextAttempt = Date.now();
309
- return async function(...args) {
310
- if (state === "OPEN") {
311
- if (Date.now() < nextAttempt) {
312
- throw new CircuitBreakerOpenError();
313
- }
314
- state = "HALF_OPEN";
315
- if (onHalfOpen) onHalfOpen();
343
+ let fails = 0;
344
+ let halfSuccess = 0;
345
+ let unlockAt = 0;
346
+ const reset = /* @__PURE__ */ __name(() => {
347
+ fails = 0;
348
+ halfSuccess = 0;
349
+ state = "CLOSED";
350
+ onClose?.();
351
+ }, "reset");
352
+ const open = /* @__PURE__ */ __name(() => {
353
+ state = "OPEN";
354
+ unlockAt = Date.now() + resetTimeout;
355
+ onOpen?.();
356
+ }, "open");
357
+ const halfOpen = /* @__PURE__ */ __name(() => {
358
+ state = "HALF_OPEN";
359
+ onHalfOpen?.();
360
+ }, "halfOpen");
361
+ return async (...args) => {
362
+ const now = Date.now();
363
+ if (state === "OPEN" && now < unlockAt) {
364
+ throw new CircuitBreakerOpenError();
365
+ }
366
+ if (state === "OPEN" && now >= unlockAt) {
367
+ halfOpen();
316
368
  }
317
369
  try {
318
- const result = await fn(...args);
370
+ const res = await fn(...args);
319
371
  if (state === "HALF_OPEN") {
320
- successCount++;
321
- if (successCount >= successThreshold) {
322
- successCount = 0;
323
- failureCount = 0;
324
- state = "CLOSED";
325
- if (onClose) onClose();
372
+ halfSuccess++;
373
+ if (halfSuccess >= successThreshold) {
374
+ reset();
375
+ } else {
376
+ state = "HALF_OPEN";
326
377
  }
327
378
  } else {
328
- failureCount = 0;
379
+ fails = 0;
329
380
  }
330
- return result;
331
- } catch (error) {
332
- failureCount++;
333
- if ((state === "CLOSED" || state === "HALF_OPEN") && failureCount >= failureThreshold) {
334
- state = "OPEN";
335
- nextAttempt = Date.now() + resetTimeout;
336
- if (onOpen) onOpen();
381
+ return res;
382
+ } catch (err) {
383
+ fails++;
384
+ if (state === "HALF_OPEN" || state === "CLOSED") {
385
+ if (fails >= failureThreshold) {
386
+ open();
387
+ }
337
388
  }
338
- throw error;
389
+ throw err;
339
390
  }
340
391
  };
341
392
  }
@@ -351,12 +402,15 @@ async function runWithConcurrency(tasks, options = {}) {
351
402
  }
352
403
  return new Promise((resolve, reject) => {
353
404
  let taskIndex = 0;
405
+ let rejected = false;
354
406
  const processNext = /* @__PURE__ */ __name(async () => {
407
+ if (rejected) return;
355
408
  const currentTaskIndex = taskIndex++;
356
409
  if (currentTaskIndex >= totalTasks) return;
357
410
  try {
358
411
  const result = await tasks[currentTaskIndex]();
359
412
  if (signal?.aborted) {
413
+ rejected = true;
360
414
  reject(new Error("Aborted"));
361
415
  return;
362
416
  }
@@ -372,6 +426,7 @@ async function runWithConcurrency(tasks, options = {}) {
372
426
  }
373
427
  }
374
428
  } catch (error) {
429
+ rejected = true;
375
430
  reject(error);
376
431
  return;
377
432
  }
@@ -387,6 +442,7 @@ async function runWithConcurrency(tasks, options = {}) {
387
442
  }
388
443
  if (signal) {
389
444
  signal.addEventListener("abort", () => {
445
+ rejected = true;
390
446
  reject(new Error("Aborted"));
391
447
  }, {
392
448
  once: true
package/cache/index.cjs CHANGED
@@ -40,7 +40,7 @@ var TTLCache = class {
40
40
  * @param options - Configuration options for the cache
41
41
  */
42
42
  constructor(options = {}) {
43
- this.ttlMs = options.ttlMs ?? config.defaultCatbeeConfig.cache.defaultTtl;
43
+ this.ttlMs = options.ttlMs ?? config.getCatbeeGlobalConfig().cache.defaultTtl;
44
44
  this.maxSize = options.maxSize;
45
45
  const autoCleanupMs = options.autoCleanupMs;
46
46
  if (autoCleanupMs && autoCleanupMs > 0) {
package/cache/index.d.ts CHANGED
@@ -22,4 +22,158 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- export * from './cache.utils';
25
+ /**
26
+ * Options for configuring a TTLCache instance.
27
+ */
28
+ interface TTLCacheOptions {
29
+ /** Default time-to-live in milliseconds for cache entries */
30
+ ttlMs?: number;
31
+ /** Maximum number of entries to keep in cache (uses LRU eviction policy) */
32
+ maxSize?: number;
33
+ /** Auto-cleanup interval in milliseconds (disabled if 0 or negative) */
34
+ autoCleanupMs?: number;
35
+ }
36
+ /**
37
+ * An in-memory cache with time-to-live (TTL) support for each entry.
38
+ *
39
+ * @typeParam K - Type of the key.
40
+ * @typeParam V - Type of the value.
41
+ *
42
+ * @example
43
+ * const cache = new TTLCache<string, number>({ ttlMs: 1000 });
44
+ * cache.set("x", 123);
45
+ * const value = cache.get("x"); // 123
46
+ */
47
+ declare class TTLCache<K, V> {
48
+ private readonly cache;
49
+ private readonly ttlMs;
50
+ private readonly maxSize?;
51
+ private cleanupInterval?;
52
+ /**
53
+ * @param options - Configuration options for the cache
54
+ */
55
+ constructor(options?: TTLCacheOptions);
56
+ /**
57
+ * Sets a key-value pair in the cache with the default TTL.
58
+ *
59
+ * @param key - The key to set.
60
+ * @param value - The value to associate with the key.
61
+ */
62
+ set(key: K, value: V): void;
63
+ /**
64
+ * Sets a key-value pair in the cache with a custom TTL.
65
+ *
66
+ * @param key - The key to set.
67
+ * @param value - The value to associate with the key.
68
+ * @param ttlMs - Time-to-live in milliseconds.
69
+ */
70
+ setWithTTL(key: K, value: V, ttlMs: number): void;
71
+ /**
72
+ * Retrieves the value for a given key if it hasn't expired.
73
+ *
74
+ * @param key - The key to retrieve.
75
+ * @returns The cached value, or undefined if not found or expired.
76
+ */
77
+ get(key: K): V | undefined;
78
+ /**
79
+ * Retrieves or computes a value if it's not in the cache or has expired.
80
+ *
81
+ * @param key - The key to retrieve
82
+ * @param producer - Function to generate the value if not cached
83
+ * @param ttlMs - Optional custom TTL for the computed value
84
+ * @returns The cached or computed value
85
+ */
86
+ getOrCompute(key: K, producer: () => Promise<V>, ttlMs?: number): Promise<V>;
87
+ /**
88
+ * Checks if the key exists and hasn't expired.
89
+ *
90
+ * @param key - The key to check.
91
+ * @returns `true` if key exists and is valid, otherwise `false`.
92
+ */
93
+ has(key: K): boolean;
94
+ /**
95
+ * Deletes a key from the cache.
96
+ *
97
+ * @param key - The key to delete.
98
+ * @returns `true` if the key existed and was removed, `false` otherwise.
99
+ */
100
+ delete(key: K): boolean;
101
+ /**
102
+ * Clears all entries from the cache.
103
+ */
104
+ clear(): void;
105
+ /**
106
+ * Returns the number of entries currently in the cache (includes expired entries until next access/cleanup).
107
+ *
108
+ * @returns Number of items in the cache (may include expired keys).
109
+ */
110
+ size(): number;
111
+ /**
112
+ * Set multiple key-value pairs at once with the default TTL.
113
+ *
114
+ * @param entries - Array of [key, value] tuples to set
115
+ */
116
+ setMany(entries: [K, V][]): void;
117
+ /**
118
+ * Get multiple values at once.
119
+ *
120
+ * @param keys - Array of keys to retrieve
121
+ * @returns Array of values (undefined for keys that don't exist or expired)
122
+ */
123
+ getMany(keys: K[]): (V | undefined)[];
124
+ /**
125
+ * Removes all expired entries from the cache.
126
+ *
127
+ * @returns Number of entries removed.
128
+ */
129
+ cleanup(): number;
130
+ /**
131
+ * Returns an iterator of all current valid [key, value] pairs.
132
+ *
133
+ * @returns IterableIterator<[K, V]>
134
+ */
135
+ entries(): IterableIterator<[K, V]>;
136
+ /**
137
+ * Returns an iterator of all current valid keys.
138
+ *
139
+ * @returns IterableIterator<K>
140
+ */
141
+ keys(): IterableIterator<K>;
142
+ /**
143
+ * Returns an iterator of all current valid values.
144
+ *
145
+ * @returns IterableIterator<V>
146
+ */
147
+ values(): IterableIterator<V>;
148
+ /**
149
+ * Extends the expiration of a key by the specified time or default TTL.
150
+ *
151
+ * @param key - The key to refresh
152
+ * @param ttlMs - Optional new TTL in milliseconds (uses default if not specified)
153
+ * @returns true if the key was found and refreshed, false otherwise
154
+ */
155
+ refresh(key: K, ttlMs?: number): boolean;
156
+ /**
157
+ * Returns a snapshot of cache stats.
158
+ *
159
+ * @returns Object containing cache statistics
160
+ */
161
+ stats(): {
162
+ size: number;
163
+ validEntries: number;
164
+ expiredEntries: number;
165
+ maxSize: number | undefined;
166
+ };
167
+ /**
168
+ * Stop the auto-cleanup interval if it's running.
169
+ */
170
+ destroy(): void;
171
+ /**
172
+ * Evict the least recently used entry from the cache.
173
+ * @private
174
+ */
175
+ private evictLRU;
176
+ }
177
+
178
+ export { TTLCache };
179
+ export type { TTLCacheOptions };
package/cache/index.mjs CHANGED
@@ -22,7 +22,7 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- import { defaultCatbeeConfig } from '@catbee/utils/config';
25
+ import { getCatbeeGlobalConfig } from '@catbee/utils/config';
26
26
 
27
27
  var __defProp = Object.defineProperty;
28
28
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -38,7 +38,7 @@ var TTLCache = class {
38
38
  * @param options - Configuration options for the cache
39
39
  */
40
40
  constructor(options = {}) {
41
- this.ttlMs = options.ttlMs ?? defaultCatbeeConfig.cache.defaultTtl;
41
+ this.ttlMs = options.ttlMs ?? getCatbeeGlobalConfig().cache.defaultTtl;
42
42
  this.maxSize = options.maxSize;
43
43
  const autoCleanupMs = options.autoCleanupMs;
44
44
  if (autoCleanupMs && autoCleanupMs > 0) {
package/config/index.cjs CHANGED
@@ -30,53 +30,35 @@ var obj = require('@catbee/utils/obj');
30
30
 
31
31
  var __defProp = Object.defineProperty;
32
32
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
33
- var defaultCatbeeConfig = {
34
- logger: {
35
- level: env.Env.get("LOGGER_LEVEL", env.Env.isDev() ? "debug" : "info"),
36
- name: env.Env.get("LOGGER_NAME", env.Env.get("npm_package_name", "@catbee/utils")),
37
- pretty: env.Env.getBoolean("LOGGER_PRETTY", false),
38
- colorize: env.Env.getBoolean("LOGGER_PRETTY_COLORIZE", true),
39
- singleLine: env.Env.getBoolean("LOGGER_PRETTY_SINGLE_LINE", false),
40
- dir: env.Env.getPath("LOGGER_DIR", "", {
41
- mustExist: false
42
- })
43
- },
44
- cache: {
45
- defaultTtl: env.Env.getNumber("CACHE_DEFAULT_TTL_SECONDS", 3600) * 1e3
46
- },
47
- server: {
48
- skipHealthz: env.Env.getBoolean("SERVER_SKIP_HEALTHZ", false)
49
- }
50
- };
51
33
  var defaultServerConfig = {
52
- port: 3e3,
53
- host: "0.0.0.0",
54
- cors: false,
55
- helmet: false,
56
- compression: false,
34
+ port: env.Env.getNumber("SERVER_PORT", 0) || env.Env.getNumber("PORT", 3e3),
35
+ host: env.Env.get("SERVER_HOST", "") || env.Env.get("HOST", "0.0.0.0"),
36
+ cors: env.Env.getBoolean("SERVER_CORS_ENABLE", false) ? {} : false,
37
+ helmet: env.Env.getBoolean("SERVER_HELMET_ENABLE", false) ? {} : false,
38
+ compression: env.Env.getBoolean("SERVER_COMPRESSION_ENABLE", false) ? {} : false,
57
39
  bodyParser: {
58
40
  json: {
59
- limit: "1mb"
41
+ limit: env.Env.get("SERVER_BODY_PARSER_JSON_LIMIT", "1mb")
60
42
  },
61
43
  urlencoded: {
62
44
  extended: true,
63
- limit: "1mb"
45
+ limit: env.Env.get("SERVER_BODY_PARSER_URLENCODED_LIMIT", "1mb")
64
46
  }
65
47
  },
66
- cookieParser: false,
67
- isMicroservice: false,
68
- appName: "express_app",
69
- globalHeaders: {},
48
+ cookieParser: env.Env.getBoolean("SERVER_COOKIE_PARSER_ENABLE", false) ? {} : false,
49
+ isMicroservice: env.Env.getBoolean("SERVER_IS_MICROSERVICE", false),
50
+ appName: env.Env.get("SERVER_APP_NAME", env.Env.get("npm_package_name", "catbee_server")),
51
+ globalHeaders: env.Env.getJSON("SERVER_GLOBAL_HEADERS", {}),
70
52
  rateLimit: {
71
- enable: false,
72
- windowMs: 15 * 60 * 1e3,
73
- max: 100,
74
- message: "Too many requests",
75
- standardHeaders: true,
76
- legacyHeaders: false
53
+ enable: env.Env.getBoolean("SERVER_RATE_LIMIT_ENABLE", false),
54
+ windowMs: env.Env.getDuration("SERVER_RATE_LIMIT_WINDOW_MS", 15 * 60 * 1e3),
55
+ max: env.Env.getNumber("SERVER_RATE_LIMIT_MAX", 100),
56
+ message: env.Env.get("SERVER_RATE_LIMIT_MESSAGE", "Too many requests, please try again later."),
57
+ standardHeaders: env.Env.getBoolean("SERVER_RATE_LIMIT_STANDARD_HEADERS", true),
58
+ legacyHeaders: env.Env.getBoolean("SERVER_RATE_LIMIT_LEGACY_HEADERS", false)
77
59
  },
78
60
  requestLogging: {
79
- enable: env.Env.isDev(),
61
+ enable: env.Env.getBoolean("SERVER_REQUEST_LOGGING_ENABLE", env.Env.isDev()),
80
62
  ignorePaths: /* @__PURE__ */ __name((req, _res) => {
81
63
  const skipPaths = [
82
64
  "/healthz",
@@ -87,50 +69,82 @@ var defaultServerConfig = {
87
69
  ];
88
70
  return skipPaths.some((path) => req.path.startsWith(path));
89
71
  }, "ignorePaths"),
90
- skipNotFoundRoutes: false
72
+ skipNotFoundRoutes: env.Env.getBoolean("SERVER_REQUEST_LOGGING_SKIP_NOT_FOUND_ROUTES", true)
91
73
  },
74
+ trustProxy: env.Env.getBoolean("SERVER_TRUST_PROXY_ENABLE", false),
92
75
  openApi: {
93
- enable: false,
94
- mountPath: "/docs",
95
- verbose: false,
96
- withGlobalPrefix: false
76
+ enable: env.Env.getBoolean("SERVER_OPENAPI_ENABLE", false),
77
+ mountPath: env.Env.get("SERVER_OPENAPI_MOUNT_PATH", "/docs"),
78
+ verbose: env.Env.getBoolean("SERVER_OPENAPI_VERBOSE", false),
79
+ withGlobalPrefix: env.Env.getBoolean("SERVER_OPENAPI_WITH_GLOBAL_PREFIX", false)
97
80
  },
98
81
  healthCheck: {
99
- path: "/healthz",
100
- detailed: true
82
+ path: env.Env.get("SERVER_HEALTH_CHECK_PATH", "/healthz"),
83
+ detailed: env.Env.getBoolean("SERVER_HEALTH_CHECK_DETAILED_OUTPUT", true),
84
+ withGlobalPrefix: env.Env.getBoolean("SERVER_HEALTH_CHECK_WITH_GLOBAL_PREFIX", false)
101
85
  },
102
- requestTimeout: 3e4,
86
+ requestTimeout: env.Env.getDuration("SERVER_REQUEST_TIMEOUT_MS", 0),
103
87
  responseTime: {
104
- enable: false,
105
- addHeader: true,
106
- logOnComplete: false
88
+ enable: env.Env.getBoolean("SERVER_RESPONSE_TIME_ENABLE", false),
89
+ addHeader: env.Env.getBoolean("SERVER_RESPONSE_TIME_ADD_HEADER", true),
90
+ logOnComplete: env.Env.getBoolean("SERVER_RESPONSE_TIME_LOG_ON_COMPLETE", false)
107
91
  },
108
92
  requestId: {
109
- headerName: "x-request-id",
110
- exposeHeader: true,
93
+ headerName: env.Env.get("SERVER_REQUEST_ID_HEADER_NAME", "x-request-id"),
94
+ exposeHeader: env.Env.getBoolean("SERVER_REQUEST_ID_EXPOSE_HEADER", true),
111
95
  generator: /* @__PURE__ */ __name(() => id.uuid(), "generator")
112
96
  },
113
97
  metrics: {
114
- enable: false,
115
- path: "/metrics",
116
- withGlobalPrefix: false
98
+ enable: env.Env.getBoolean("SERVER_METRICS_ENABLE", false),
99
+ path: env.Env.get("SERVER_METRICS_PATH", "/metrics"),
100
+ withGlobalPrefix: env.Env.getBoolean("SERVER_METRICS_WITH_GLOBAL_PREFIX", false)
117
101
  },
118
102
  serviceVersion: {
119
- enable: false,
120
- headerName: "x-service-version",
121
- version: "0.0.0"
122
- }
103
+ enable: env.Env.getBoolean("SERVER_SERVICE_VERSION_ENABLE", false),
104
+ headerName: env.Env.get("SERVER_SERVICE_VERSION_HEADER_NAME", "x-service-version"),
105
+ version: env.Env.get("SERVER_SERVICE_VERSION", "0.0.0")
106
+ },
107
+ skipHealthz: env.Env.getBoolean("SERVER_SKIP_HEALTHZ", false)
123
108
  };
124
- function setConfig(value) {
125
- obj.deepObjMerge(defaultCatbeeConfig, value);
109
+ var defaultCatbeeConfig = {
110
+ logger: {
111
+ level: env.Env.get("LOGGER_LEVEL", env.Env.isDev() || env.Env.isTest() ? "debug" : "info"),
112
+ name: env.Env.get("LOGGER_NAME", env.Env.get("npm_package_name", "@catbee/utils")),
113
+ pretty: env.Env.getBoolean("LOGGER_PRETTY", false),
114
+ colorize: env.Env.getBoolean("LOGGER_PRETTY_COLORIZE", true),
115
+ singleLine: env.Env.getBoolean("LOGGER_PRETTY_SINGLE_LINE", false),
116
+ dir: env.Env.getPath("LOGGER_DIR", "", {
117
+ mustExist: false
118
+ })
119
+ },
120
+ cache: {
121
+ defaultTtl: env.Env.getNumber("CACHE_DEFAULT_TTL_SECONDS", 3600) * 1e3
122
+ },
123
+ server: defaultServerConfig
124
+ };
125
+ var _config = obj.deepClone(defaultCatbeeConfig);
126
+ function getCatbeeGlobalConfig() {
127
+ return obj.deepClone(_config);
128
+ }
129
+ __name(getCatbeeGlobalConfig, "getCatbeeGlobalConfig");
130
+ var getConfig = getCatbeeGlobalConfig;
131
+ function setCatbeeGlobalConfig(value) {
132
+ _config = obj.deepObjMerge(_config, value);
133
+ }
134
+ __name(setCatbeeGlobalConfig, "setCatbeeGlobalConfig");
135
+ var setConfig = setCatbeeGlobalConfig;
136
+ function setCatbeeServerGlobalConfig(value) {
137
+ _config.server = obj.deepObjMerge(_config.server, value);
126
138
  }
127
- __name(setConfig, "setConfig");
128
- function getConfig() {
129
- return defaultCatbeeConfig;
139
+ __name(setCatbeeServerGlobalConfig, "setCatbeeServerGlobalConfig");
140
+ function getCatbeeServerGlobalConfig() {
141
+ return getCatbeeGlobalConfig().server;
130
142
  }
131
- __name(getConfig, "getConfig");
143
+ __name(getCatbeeServerGlobalConfig, "getCatbeeServerGlobalConfig");
132
144
 
133
- exports.defaultCatbeeConfig = defaultCatbeeConfig;
134
- exports.defaultServerConfig = defaultServerConfig;
145
+ exports.getCatbeeGlobalConfig = getCatbeeGlobalConfig;
146
+ exports.getCatbeeServerGlobalConfig = getCatbeeServerGlobalConfig;
135
147
  exports.getConfig = getConfig;
148
+ exports.setCatbeeGlobalConfig = setCatbeeGlobalConfig;
149
+ exports.setCatbeeServerGlobalConfig = setCatbeeServerGlobalConfig;
136
150
  exports.setConfig = setConfig;
package/config/index.d.ts CHANGED
@@ -22,5 +22,67 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- export { setConfig, getConfig } from './config';
26
- export { defaultCatbeeConfig, defaultServerConfig } from './config';
25
+ import { CatbeeConfig, CatbeeGlobalServerConfig } from '@catbee/utils/types';
26
+ import { Logger } from '@catbee/utils/logger';
27
+
28
+ /**
29
+ * Extends Express Request interface to add request ID tracking.
30
+ * Added by requestId middleware during request processing.
31
+ */
32
+ declare global {
33
+ namespace Express {
34
+ interface Request {
35
+ /** Unique request identifier (set by middleware) */
36
+ id?: string;
37
+ /** Logger instance for the request (set by middleware) */
38
+ logger?: Logger;
39
+ /** User information (set by authentication middleware) */
40
+ user?: any;
41
+ }
42
+ }
43
+ }
44
+ /**
45
+ * Gets the global Catbee configuration.
46
+ *
47
+ * @returns The current Catbee configuration.
48
+ */
49
+ declare function getCatbeeGlobalConfig(): CatbeeConfig;
50
+ /**
51
+ * Gets the global Catbee configuration.
52
+ *
53
+ * @deprecated Use `getCatbeeGlobalConfig` from `@catbee/utils/config` instead.
54
+ * @alias getCatbeeGlobalConfig
55
+ * @returns The current Catbee configuration.
56
+ */
57
+ declare const getConfig: typeof getCatbeeGlobalConfig;
58
+ /**
59
+ * Sets the global Catbee configuration.
60
+ * Merges the provided partial configuration with the existing one.
61
+ *
62
+ * @param value - Partial Catbee configuration to set
63
+ */
64
+ declare function setCatbeeGlobalConfig(value: Partial<CatbeeConfig>): void;
65
+ /**
66
+ * Sets the global Catbee configuration.
67
+ * Merges the provided partial configuration with the existing one.
68
+ *
69
+ * @deprecated Use `setCatbeeGlobalConfig` from `@catbee/utils/config` instead.
70
+ * @alias setCatbeeGlobalConfig
71
+ * @param value - Partial Catbee configuration to set
72
+ */
73
+ declare const setConfig: typeof setCatbeeGlobalConfig;
74
+ /**
75
+ * Sets the global Catbee server configuration.
76
+ * Merges the provided partial server configuration with the existing one.
77
+ *
78
+ * @param value - Partial Catbee server configuration to set
79
+ */
80
+ declare function setCatbeeServerGlobalConfig(value: Partial<CatbeeGlobalServerConfig>): void;
81
+ /**
82
+ * Gets the global Catbee server configuration.
83
+ *
84
+ * @returns The current Catbee server configuration.
85
+ */
86
+ declare function getCatbeeServerGlobalConfig(): CatbeeGlobalServerConfig;
87
+
88
+ export { getCatbeeGlobalConfig, getCatbeeServerGlobalConfig, getConfig, setCatbeeGlobalConfig, setCatbeeServerGlobalConfig, setConfig };