@catbee/utils 2.0.0-next.0 → 2.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 (122) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +102 -52
  3. package/array/index.cjs +215 -74
  4. package/array/index.d.ts +345 -2
  5. package/array/index.mjs +201 -74
  6. package/async/index.cjs +116 -39
  7. package/async/index.d.ts +292 -2
  8. package/async/index.mjs +116 -40
  9. package/cache/index.cjs +2 -2
  10. package/cache/index.d.ts +156 -2
  11. package/cache/index.mjs +3 -3
  12. package/config/index.cjs +80 -66
  13. package/config/index.d.ts +65 -3
  14. package/config/index.mjs +77 -65
  15. package/context-store/index.cjs +2 -3
  16. package/context-store/index.d.ts +193 -2
  17. package/context-store/index.mjs +2 -3
  18. package/crypto/index.cjs +55 -5
  19. package/crypto/index.d.ts +225 -2
  20. package/crypto/index.mjs +52 -7
  21. package/date/index.cjs +676 -2
  22. package/date/index.d.ts +676 -2
  23. package/date/index.mjs +665 -3
  24. package/decorator/index.cjs +2172 -0
  25. package/{decorators/decorators.utils.d.ts → decorator/index.d.ts} +58 -54
  26. package/decorator/index.mjs +2131 -0
  27. package/{dir → directory}/index.cjs +5 -4
  28. package/{dir/dir.utils.d.ts → directory/index.d.ts} +24 -21
  29. package/{dir → directory}/index.mjs +5 -4
  30. package/env/index.cjs +100 -68
  31. package/env/index.d.ts +391 -2
  32. package/env/index.mjs +100 -68
  33. package/exception/index.cjs +1 -1
  34. package/exception/index.d.ts +233 -2
  35. package/exception/index.mjs +1 -1
  36. package/fs/index.cjs +71 -37
  37. package/fs/index.d.ts +206 -2
  38. package/fs/index.mjs +65 -35
  39. package/http-status-codes/index.cjs +1 -1
  40. package/http-status-codes/index.d.ts +268 -2
  41. package/http-status-codes/index.mjs +1 -1
  42. package/id/index.cjs +1 -1
  43. package/id/index.d.ts +38 -2
  44. package/id/index.mjs +1 -1
  45. package/index.cjs +13 -13
  46. package/index.d.ts +5 -5
  47. package/index.mjs +5 -5
  48. package/logger/index.cjs +13 -15
  49. package/logger/index.d.ts +190 -2
  50. package/logger/index.mjs +14 -16
  51. package/middleware/index.cjs +1 -1
  52. package/middleware/index.d.ts +104 -2
  53. package/middleware/index.mjs +1 -1
  54. package/object/index.cjs +379 -0
  55. package/{obj/obj.utils.d.ts → object/index.d.ts} +73 -33
  56. package/object/index.mjs +360 -0
  57. package/package.json +41 -23
  58. package/performance/index.cjs +4 -4
  59. package/performance/index.d.ts +139 -2
  60. package/performance/index.mjs +4 -4
  61. package/request/index.cjs +37 -25
  62. package/request/index.d.ts +242 -3
  63. package/request/index.mjs +37 -25
  64. package/response/index.cjs +1 -1
  65. package/response/index.d.ts +319 -3
  66. package/response/index.mjs +1 -1
  67. package/server/index.cjs +249 -146
  68. package/server/index.d.ts +866 -5
  69. package/server/index.mjs +248 -144
  70. package/stream/index.cjs +1 -1
  71. package/stream/index.d.ts +91 -2
  72. package/stream/index.mjs +1 -1
  73. package/string/index.cjs +34 -1
  74. package/string/index.d.ts +146 -2
  75. package/string/index.mjs +31 -2
  76. package/type/index.cjs +19 -2
  77. package/type/index.d.ts +144 -2
  78. package/type/index.mjs +17 -3
  79. package/types/index.cjs +1 -1
  80. package/types/index.d.ts +775 -5
  81. package/types/index.mjs +1 -1
  82. package/url/index.cjs +63 -5
  83. package/url/index.d.ts +200 -2
  84. package/url/index.mjs +59 -6
  85. package/{validate → validation}/index.cjs +91 -44
  86. package/{validate/validate.utils.d.ts → validation/index.d.ts} +33 -24
  87. package/{validate → validation}/index.mjs +87 -44
  88. package/array/array.utils.d.ts +0 -191
  89. package/async/async.utils.d.ts +0 -296
  90. package/cache/cache.utils.d.ts +0 -176
  91. package/config/config.d.ts +0 -57
  92. package/context-store/context-store.utils.d.ts +0 -212
  93. package/crypto/crypto.utils.d.ts +0 -183
  94. package/date/date.utils.d.ts +0 -190
  95. package/decorators/index.cjs +0 -913
  96. package/decorators/index.d.ts +0 -25
  97. package/decorators/index.mjs +0 -872
  98. package/dir/index.d.ts +0 -25
  99. package/env/env.utils.d.ts +0 -400
  100. package/exception/exception.utils.d.ts +0 -253
  101. package/fs/fs.utils.d.ts +0 -196
  102. package/http-status-codes/http-status-codes.d.ts +0 -289
  103. package/id/id.utils.d.ts +0 -59
  104. package/logger/logger.utils.d.ts +0 -210
  105. package/middleware/middleware.utils.d.ts +0 -123
  106. package/obj/index.cjs +0 -317
  107. package/obj/index.d.ts +0 -25
  108. package/obj/index.mjs +0 -301
  109. package/performance/performance.utils.d.ts +0 -159
  110. package/request/request.utils.d.ts +0 -109
  111. package/response/response.utils.d.ts +0 -186
  112. package/server/server.builder.d.ts +0 -531
  113. package/server/server.d.ts +0 -303
  114. package/stream/stream.utils.d.ts +0 -111
  115. package/string/string.utils.d.ts +0 -124
  116. package/type/type.utils.d.ts +0 -129
  117. package/types/api-response.d.ts +0 -175
  118. package/types/common.d.ts +0 -148
  119. package/types/config.d.ts +0 -88
  120. package/types/server.d.ts +0 -291
  121. package/url/url.utils.d.ts +0 -164
  122. package/validate/index.d.ts +0 -25
package/types/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * The MIT License
3
3
  *
4
- * Copyright (c) 2025 Catbee Technologies. https://catbee.in/license
4
+ * Copyright (c) 2026 Catbee Technologies. https://catbee.in/license
5
5
  *
6
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  * of this software and associated documentation files (the "Software"), to deal
@@ -22,7 +22,777 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- export * from './common';
26
- export * from './server';
27
- export * from './api-response';
28
- export * from './config';
25
+ import { json, urlencoded, Request, Response, Express, NextFunction } from 'express';
26
+ import http from 'node:http';
27
+ import { ExpressServer } from '@catbee/utils/server';
28
+ import { HelmetOptions } from 'helmet';
29
+ import { CompressionOptions } from 'compression';
30
+ import { CookieParseOptions } from 'cookie-parser';
31
+ import { CorsOptions } from 'cors';
32
+ import { LoggerLevels } from '@catbee/utils/logger';
33
+
34
+ /**
35
+ * A type that represents a configurable toggle.
36
+ * Can be `true`, `false`, or a custom configuration object `T`.
37
+ */
38
+ type ToggleConfig<T> = boolean | T;
39
+ /**
40
+ * A type representing a value that can be `null` or `undefined`.
41
+ */
42
+ type Nullable<T> = T | null | undefined;
43
+ /**
44
+ * A type representing a value that may or may not be present.
45
+ */
46
+ type Optional<T> = T | undefined;
47
+ /**
48
+ * A type that makes all properties of `T` deeply optional.
49
+ */
50
+ type DeepPartial<T> = {
51
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
52
+ };
53
+ /**
54
+ * A type that makes all properties of `T` readonly, recursively.
55
+ */
56
+ type DeepReadonly<T> = {
57
+ readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
58
+ };
59
+ /**
60
+ * A type that converts a union of types into an intersection.
61
+ */
62
+ type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
63
+ /**
64
+ * A type representing a promise or a plain value.
65
+ */
66
+ type MaybePromise<T> = T | Promise<T>;
67
+ /**
68
+ * A type representing a record with string keys and values of type `T`.
69
+ */
70
+ type StringKeyedRecord<T> = Record<string, T>;
71
+ /**
72
+ * A type representing a function that returns `R` and optionally receives arguments `A`.
73
+ */
74
+ type Func<A extends any[] = any[], R = any> = (...args: A) => R;
75
+ /**
76
+ * A type representing a partial pick from `T` (like Partial + Pick combined)
77
+ */
78
+ type PartialPick<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>;
79
+ /**
80
+ * A type that deeply stringifies all properties of T or makes them null.
81
+ */
82
+ type DeepStringifyOrNull<T> = T extends string | number | bigint | boolean | symbol | null | undefined ? string | null : T extends Array<infer U> ? Array<DeepStringifyOrNull<U>> : T extends object ? {
83
+ [K in keyof T]: DeepStringifyOrNull<T[K]>;
84
+ } : string | null;
85
+ /**
86
+ * A type representing a non-empty array of T.
87
+ */
88
+ type NonEmptyArray<T> = [T, ...T[]];
89
+ /**
90
+ * A type representing the union of all property values of T.
91
+ */
92
+ type ValueOf<T> = T[keyof T];
93
+ /**
94
+ * A type that makes all properties of T mutable (removes readonly).
95
+ */
96
+ type Mutable<T> = {
97
+ -readonly [P in keyof T]: T[P];
98
+ };
99
+ /**
100
+ * A type that gets the keys of T whose values are assignable to U.
101
+ */
102
+ type KeysOfType<T, U> = {
103
+ [K in keyof T]: T[K] extends U ? K : never;
104
+ }[keyof T];
105
+ /**
106
+ * Require at least one of the keys in K to be present in T.
107
+ */
108
+ type RequireAtLeastOne<T, K extends keyof T = keyof T> = K extends keyof T ? {
109
+ [P in K]-?: T[P];
110
+ } & Omit<T, K> : never;
111
+ /**
112
+ * A record type with optional keys.
113
+ */
114
+ type RecordOptional<K extends string | number | symbol, T> = {
115
+ [P in K]?: T;
116
+ };
117
+ /**
118
+ * Primitive types in TypeScript.
119
+ */
120
+ type Primitive = string | number | boolean | bigint | symbol | undefined | null;
121
+ /**
122
+ * Recursively unwraps Promise types to get their resolved value type.
123
+ */
124
+ type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T;
125
+ /**
126
+ * Picks properties from T that are of type U.
127
+ */
128
+ type PickByType<T, U> = {
129
+ [P in keyof T as T[P] extends U ? P : never]: T[P];
130
+ };
131
+ /**
132
+ * Makes all properties of T required recursively.
133
+ */
134
+ type DeepRequired<T> = {
135
+ [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
136
+ };
137
+ /**
138
+ * Checks if two types are exactly equal.
139
+ * Returns true or false as type.
140
+ */
141
+ type IsEqual<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U ? 1 : 2 ? true : false;
142
+ /**
143
+ * Makes all properties of an object writable (removes readonly).
144
+ */
145
+ type Writable<T> = {
146
+ -readonly [P in keyof T]: T[P];
147
+ };
148
+ /**
149
+ * Makes specific keys K of type T optional.
150
+ */
151
+ type Optional2<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
152
+ /**
153
+ * Creates a type with all properties of T except those with types assignable to U.
154
+ */
155
+ type Without<T, U> = {
156
+ [P in keyof T as T[P] extends U ? never : P]: T[P];
157
+ };
158
+
159
+ /**
160
+ * Server configuration for Catbee HTTP/Express server.
161
+ * Designed with secure and high-performance defaults for production use.
162
+ * All features remain fully overridable by consumers.
163
+ */
164
+ interface CatbeeServerConfig {
165
+ /** Server port
166
+ * - **default**: `3000`
167
+ * - **env**: `SERVER_PORT` || `PORT`
168
+ */
169
+ port: number;
170
+ /** Host address to bind the server
171
+ * - **default**: `'0.0.0.0'`
172
+ * - **env**: `SERVER_HOST` || `HOST`
173
+ */
174
+ host?: string;
175
+ /** CORS configuration toggle or options
176
+ * - **default**: `false`
177
+ * - **env**: `SERVER_CORS_ENABLE`
178
+ * - `true` -> enable with default settings
179
+ * - `CorsOptions` -> enable with custom settings
180
+ *
181
+ * **example**:
182
+ * ```ts
183
+ * cors: {
184
+ * origin: 'https://example.com',
185
+ * methods: ['GET', 'POST'],
186
+ * credentials: true
187
+ * }
188
+ * ```
189
+ */
190
+ cors?: ToggleConfig<CorsOptions>;
191
+ /** Helmet security headers toggle or options
192
+ * - **default**: `false`
193
+ * - **env**: `SERVER_HELMET_ENABLE`
194
+ * - `true` -> enable with default settings
195
+ * - `HelmetOptions` -> enable with custom settings
196
+ *
197
+ * **example**:
198
+ * ```ts
199
+ * helmet: {
200
+ * contentSecurityPolicy: {
201
+ * directives: {
202
+ * defaultSrc: ["'self'"],
203
+ * scriptSrc: ["'self'", 'trusted.com']
204
+ * }
205
+ * }
206
+ * }
207
+ * ```
208
+ */
209
+ helmet?: ToggleConfig<HelmetOptions>;
210
+ /** HTTP response compression toggle or options
211
+ * - **default**: `false`
212
+ * - **env**: `SERVER_COMPRESSION_ENABLE`
213
+ * - `true` -> enable with default settings
214
+ * - `CompressionOptions` -> enable with custom settings
215
+ *
216
+ * **example**:
217
+ * ```ts
218
+ * compression: { level: 6 }
219
+ * ```
220
+ */
221
+ compression?: ToggleConfig<CompressionOptions>;
222
+ /** Body parser configuration for incoming requests
223
+ * - **default**: `{ json: { limit: '1mb' }, urlencoded: { extended: true, limit: '1mb' } }`
224
+ * - **env**:
225
+ * - `SERVER_BODY_PARSER_JSON_LIMIT`
226
+ * - `SERVER_BODY_PARSER_URLENCODED_LIMIT`
227
+ */
228
+ bodyParser?: {
229
+ /** JSON body parser options
230
+ * - **default**: `{ limit: '1mb' }`
231
+ */
232
+ json?: Parameters<typeof json>[0];
233
+ /** URL-encoded body parser options
234
+ * - **default**: `{ extended: true, limit: '1mb' }`
235
+ */
236
+ urlencoded?: Parameters<typeof urlencoded>[0];
237
+ };
238
+ /** Cookie parser toggle or options
239
+ * - **default**: `false`
240
+ * - **env**: `SERVER_COOKIE_PARSER_ENABLE`
241
+ * - `true` -> enable with default decode
242
+ * - `CookieParseOptions` -> enable with custom settings
243
+ *
244
+ * **example**:
245
+ * ```ts
246
+ * cookieParser: {
247
+ * decode: (val) => decodeURIComponent(val)
248
+ * }
249
+ * ```
250
+ */
251
+ cookieParser?: ToggleConfig<CookieParseOptions>;
252
+ /** Trust proxy configuration
253
+ * - **default**: `false`
254
+ * - **env**: `SERVER_TRUST_PROXY_ENABLE`
255
+ * - `true` -> trust first proxy
256
+ * - `number` -> trust N proxies
257
+ * - `string | string[]` -> trust specific proxy IP(s)
258
+ */
259
+ trustProxy?: boolean | number | string | string[];
260
+ /** Static folder serving configuration
261
+ * - **path**: file system path to serve
262
+ * - **route**: URL route prefix (default: "/")
263
+ * - **maxAge**: cache max age (default: 0)
264
+ * - **etag**: enable ETag headers (default: true)
265
+ * - **immutable**: enable immutable caching (default: false)
266
+ * - **lastModified**: enable last-modified caching (default: true)
267
+ * - **cacheControl**: enable Cache-Control headers (default: true)
268
+ */
269
+ staticFolders?: Array<{
270
+ /** URL mount path prefix
271
+ * - **default**: `/`
272
+ */
273
+ path?: string;
274
+ /** Local directory path to serve (required) */
275
+ directory: string;
276
+ /** Cache-Control max-age value
277
+ * - **default**: `0`
278
+ */
279
+ maxAge?: string;
280
+ /** Enable ETag header
281
+ * - **default**: `true`
282
+ */
283
+ etag?: boolean;
284
+ /** Immutable caching
285
+ * - **default**: `false`
286
+ */
287
+ immutable?: boolean;
288
+ /** Last-Modified header support
289
+ * - **default**: `true`
290
+ */
291
+ lastModified?: boolean;
292
+ /** Include Cache-Control header
293
+ * - **default**: `true`
294
+ */
295
+ cacheControl?: boolean;
296
+ }>;
297
+ /** Enable microservice mode
298
+ * - **default**: `false`
299
+ * - **env**: `SERVER_IS_MICROSERVICE`
300
+ */
301
+ isMicroservice?: boolean;
302
+ /** Application/service name used for logs, headers, and metrics
303
+ * - **default**: `'catbee_server'`
304
+ * - **env**: `SERVER_APP_NAME` or `npm_package_name`
305
+ */
306
+ appName?: string;
307
+ /** Global headers applied to all responses
308
+ * - **default**: {}
309
+ * - **env**: `SERVER_GLOBAL_HEADERS` (JSON)
310
+ */
311
+ globalHeaders?: Record<string, string | (() => string)>;
312
+ /** Rate limiting settings
313
+ * - **enable**: `false` - **env**: `SERVER_RATE_LIMIT_ENABLE`
314
+ * - **windowMs**: `900000` (15 minutes) - **env**: `SERVER_RATE_LIMIT_WINDOW_MS`
315
+ * - **max**: `100` - **env**: `SERVER_RATE_LIMIT_MAX`
316
+ * - **message**: `'Too many requests'` - **env**: `SERVER_RATE_LIMIT_MESSAGE`
317
+ * - **standardHeaders**: `true` - **env**: `SERVER_RATE_LIMIT_STANDARD_HEADERS`
318
+ * - **legacyHeaders**: `false` - **env**: `SERVER_RATE_LIMIT_LEGACY_HEADERS`
319
+ */
320
+ rateLimit?: {
321
+ /** Enable rate-limiting
322
+ * - **default**: `false`
323
+ * - **env**: `SERVER_RATE_LIMIT_ENABLE`
324
+ */
325
+ enable: boolean;
326
+ /** Window duration in ms
327
+ * - **default**: `900000` (15 minutes)
328
+ * - **env**: `SERVER_RATE_LIMIT_WINDOW_MS`
329
+ */
330
+ windowMs?: number;
331
+ /** Max requests per window
332
+ * - **default**: `100`
333
+ * - **env**: `SERVER_RATE_LIMIT_MAX`
334
+ */
335
+ max?: number;
336
+ /** Custom message when limit is reached
337
+ * - **default**: `'Too many requests'`
338
+ * - **env**: `SERVER_RATE_LIMIT_MESSAGE`
339
+ */
340
+ message?: string;
341
+ /** Include standard rate-limit headers
342
+ * - **default**: `true`
343
+ * - **env**: `SERVER_RATE_LIMIT_STANDARD_HEADERS`
344
+ */
345
+ standardHeaders?: boolean;
346
+ /** Include legacy rate-limit headers
347
+ * - **default**: `false`
348
+ * - **env**: `SERVER_RATE_LIMIT_LEGACY_HEADERS`
349
+ */
350
+ legacyHeaders?: boolean;
351
+ };
352
+ /** Request logging configuration
353
+ * - **enable**: `true` in `development`, `false` in `production` - **env**: `SERVER_REQUEST_LOGGING_ENABLE`
354
+ * - **ignorePaths**: skips `/healthz`, `/favicon.ico`, `/metrics`, `/docs`, `/.well-known`
355
+ * - **skipNotFoundRoutes**: `false` - **env**: `SERVER_REQUEST_LOGGING_SKIP_NOT_FOUND_ROUTES`
356
+ */
357
+ requestLogging?: {
358
+ /** Enable request logging
359
+ * - **default**: `true` in `development`, `false` in `production`
360
+ * - **env**: `SERVER_REQUEST_LOGGING_ENABLE`
361
+ */
362
+ enable: boolean;
363
+ /** Ignore specific paths or apply custom logic to skip logging */
364
+ ignorePaths?: string[] | ((req: Request, res: Response) => boolean);
365
+ /** Skip 404 routes from logs
366
+ * - **default**: `false`
367
+ * - **env**: `SERVER_REQUEST_LOGGING_SKIP_NOT_FOUND_ROUTES`
368
+ */
369
+ skipNotFoundRoutes?: boolean;
370
+ };
371
+ /** Health-check configuration
372
+ * - **path**: `/healthz`
373
+ * - **detailed**: `true`
374
+ * - **withGlobalPrefix**: `false`
375
+ */
376
+ healthCheck?: {
377
+ /** Health-check endpoint path
378
+ * - **default**: `'/healthz'`
379
+ * - **env**: `SERVER_HEALTH_CHECK_PATH`
380
+ */
381
+ path?: string;
382
+ /** Include detailed check results in the response
383
+ * - **default**: `true`
384
+ * - **env**: `SERVER_HEALTH_CHECK_DETAILED_OUTPUT`
385
+ */
386
+ detailed?: boolean;
387
+ /** Apply global route prefix
388
+ * - **default**: `false`
389
+ * - **env**: `SERVER_HEALTH_CHECK_WITH_GLOBAL_PREFIX`
390
+ */
391
+ withGlobalPrefix?: boolean;
392
+ /** Custom health checks */
393
+ checks?: Array<{
394
+ /** Name of the health check */
395
+ name: string;
396
+ /** Check function that returns boolean or Promise<boolean> */
397
+ check: () => Promise<boolean> | boolean;
398
+ }>;
399
+ };
400
+ /** Request timeout in ms
401
+ * - **default**: `30000` (30 seconds)
402
+ * - **env**: `SERVER_REQUEST_TIMEOUT_MS`
403
+ */
404
+ requestTimeout?: number;
405
+ /** Response timing configuration
406
+ * - **enable**: `false`
407
+ * - **addHeader**: `true`
408
+ * - **logOnComplete**: `false`
409
+ */
410
+ responseTime?: {
411
+ /** Enable timing
412
+ * - **default**: `false`
413
+ * - **env**: `SERVER_RESPONSE_TIME_ENABLE`
414
+ */
415
+ enable: boolean;
416
+ /** Add X-Response-Time header
417
+ * - **default**: `true`
418
+ * - **env**: `SERVER_RESPONSE_TIME_ADD_HEADER`
419
+ */
420
+ addHeader?: boolean;
421
+ /** Log completion time
422
+ * - **default**: `false`
423
+ * - **env**: `SERVER_RESPONSE_TIME_LOG_ON_COMPLETE`
424
+ */
425
+ logOnComplete?: boolean;
426
+ };
427
+ /** Request ID tracking configuration
428
+ * - **enable**: `false` - **env**: `SERVER_REQUEST_ID_ENABLE`
429
+ * - **headerName**: `'x-request-id'` - **env**: `SERVER_REQUEST_ID_HEADER_NAME`
430
+ * - **exposeHeader**: `true` - **env**: `SERVER_REQUEST_ID_EXPOSE_HEADER`
431
+ * - **generator**: `uuid()`
432
+ */
433
+ requestId?: {
434
+ /** Header name for request tracing
435
+ * - **default**: `'x-request-id'`
436
+ * - **env**: `SERVER_REQUEST_ID_HEADER_NAME`
437
+ */
438
+ headerName?: string;
439
+ /** Expose request ID in response headers
440
+ * - **default**: `true`
441
+ * - **env**: `SERVER_REQUEST_ID_EXPOSE_HEADER`
442
+ */
443
+ exposeHeader?: boolean;
444
+ /** Function to generate request ID
445
+ * - **default**: `uuid()`
446
+ */
447
+ generator?: () => string;
448
+ };
449
+ /** Global route prefix for all endpoints
450
+ * - **default**: `/`
451
+ */
452
+ globalPrefix?: string;
453
+ /** OpenAPI/Swagger documentation config
454
+ * - **enable**: `false` - **env**: `SERVER_OPENAPI_ENABLE`
455
+ * - **mountPath**: `'/docs'` - **env**: `SERVER_OPENAPI_MOUNT_PATH`
456
+ * - **verbose**: `false` - **env**: `SERVER_OPENAPI_VERBOSE`
457
+ * - **withGlobalPrefix**: `false` - **env**: `SERVER_OPENAPI_WITH_GLOBAL_PREFIX`
458
+ */
459
+ openApi?: {
460
+ /** Enable OpenAPI spec serving
461
+ * - **default**: `false`
462
+ * - **env**: `SERVER_OPENAPI_ENABLE`
463
+ */
464
+ enable: boolean;
465
+ /** Mount path for API docs UI
466
+ * - **default**: `'/docs'`
467
+ * - **env**: `SERVER_OPENAPI_MOUNT_PATH`
468
+ */
469
+ mountPath?: string;
470
+ /** Local OpenAPI spec file path (required if enabled)
471
+ * - **env**: `SERVER_OPENAPI_FILE_PATH`
472
+ */
473
+ filePath?: string;
474
+ /** Verbose OpenAPI logs
475
+ * - **default**: `false`
476
+ * - **env**: `SERVER_OPENAPI_VERBOSE`
477
+ */
478
+ verbose?: boolean;
479
+ /** Apply global prefix to docs route
480
+ * - **default**: `false`
481
+ * - **env**: `SERVER_OPENAPI_WITH_GLOBAL_PREFIX`
482
+ */
483
+ withGlobalPrefix?: boolean;
484
+ };
485
+ /** Prometheus metrics config
486
+ * - **enable**: `false` - **env**: `SERVER_METRICS_ENABLE`
487
+ * - **path**: `'/metrics'` - **env**: `SERVER_METRICS_PATH`
488
+ * - **withGlobalPrefix**: `false` - **env**: `SERVER_METRICS_WITH_GLOBAL_PREFIX`
489
+ */
490
+ metrics?: {
491
+ /** Enable metrics endpoint
492
+ * - **default**: `false`
493
+ * - **env**: `SERVER_METRICS_ENABLE`
494
+ */
495
+ enable: boolean;
496
+ /** Metrics endpoint path
497
+ * - **default**: `'/metrics'`
498
+ * - **env**: `SERVER_METRICS_PATH`
499
+ */
500
+ path?: string;
501
+ /** Apply global prefix
502
+ * - **default**: `false`
503
+ * - **env**: `SERVER_METRICS_WITH_GLOBAL_PREFIX`
504
+ */
505
+ withGlobalPrefix?: boolean;
506
+ };
507
+ /** Service version header config
508
+ * - **enable**: `false` - **env**: `SERVER_SERVICE_VERSION_ENABLE`
509
+ * - **headerName**: `'x-service-version'` - **env**: `SERVER_SERVICE_VERSION_HEADER_NAME`
510
+ * - **version**: `'0.0.0'` - **env**: `SERVER_SERVICE_VERSION`
511
+ */
512
+ serviceVersion?: {
513
+ /** Enable version header
514
+ * - **default**: `false`
515
+ */
516
+ enable: boolean;
517
+ /** Header name
518
+ * - **default**: `'x-service-version'`
519
+ * - **env**: `SERVER_SERVICE_VERSION_HEADER_NAME`
520
+ */
521
+ headerName?: string;
522
+ /** Version value
523
+ * - **default**: `'0.0.0'`
524
+ * - **env**: `SERVER_SERVICE_VERSION`
525
+ */
526
+ version?: string | (() => string);
527
+ };
528
+ /**
529
+ * HTTPS configuration (if provided, server will use HTTPS)
530
+ * Requires 'key' and 'cert' at minimum.
531
+ * @command - to generate self-signed certificates
532
+ * ```bash
533
+ * choco install mkcert
534
+ * mkcert -key-file localhost-key.pem -cert-file localhost-cert.pem localhost 127.0.0.1 ::1
535
+ * ```
536
+ */
537
+ https?: {
538
+ /** SSL private key file path (PEM) */
539
+ key: string;
540
+ /** SSL certificate file path (PEM) */
541
+ cert: string;
542
+ /** Optional CA bundle path (PEM) */
543
+ ca?: string;
544
+ /** Optional private key passphrase */
545
+ passphrase?: string;
546
+ /** Additional Node.js `https.ServerOptions` */
547
+ [key: string]: any;
548
+ };
549
+ }
550
+ /**
551
+ * Lifecycle hooks for Catbee server runtime.
552
+ * Allows injecting custom behavior without modifying Catbee core internals.
553
+ */
554
+ interface CatbeeServerHooks {
555
+ /** Called before middleware & routes initialize */
556
+ beforeInit?: (server: ExpressServer) => Promise<void> | void;
557
+ /** Called after middleware & routes initialize */
558
+ afterInit?: (server: ExpressServer) => Promise<void> | void;
559
+ /** Called before server starts listening */
560
+ beforeStart?: (app: Express) => Promise<void> | void;
561
+ /** Called after server is ready */
562
+ afterStart?: (server: http.Server) => Promise<void> | void;
563
+ /** Called before graceful shutdown */
564
+ beforeStop?: (server: http.Server) => Promise<void> | void;
565
+ /** Called after server stops */
566
+ afterStop?: () => Promise<void> | void;
567
+ /** Custom error handler (overrides Catbee default if provided) */
568
+ onError?: (error: Error, req: Request, res: Response, next: NextFunction) => void;
569
+ /** Called when a request is received (middleware-style injection) */
570
+ onRequest?: (req: Request, res: Response, next: NextFunction) => void;
571
+ /** Called before response is sent */
572
+ onResponse?: (req: Request, res: Response, next: NextFunction) => void;
573
+ }
574
+ interface GlobalServerAddons {
575
+ /**
576
+ * Skip healthz endpoint even if health checks are configured
577
+ * - **default**: `false`
578
+ * - **env**: `SERVER_SKIP_HEALTHZ_CHECKS_VALIDATION`
579
+ *
580
+ * @additionalInfo
581
+ * Set to true to return `200 OK` for `/healthz` without checks
582
+ * Useful in environments where a simple liveness probe is needed
583
+ * without performing actual health checks
584
+ * Example: Kubernetes liveness probe
585
+ * Note: This does not disable the health check functionality itself
586
+ * Health checks can still be performed programmatically
587
+ * or via other endpoints if needed
588
+ */
589
+ skipHealthzChecksValidation: boolean;
590
+ }
591
+ /** Combined global server configuration type */
592
+ type CatbeeGlobalServerConfig = CatbeeServerConfig & GlobalServerAddons;
593
+
594
+ /**
595
+ * Generic API response format.
596
+ * Used to wrap any successful or failed response from the server.
597
+ */
598
+ interface ApiResponse<T = any> {
599
+ /** Payload returned from the API. Can be any shape depending on the endpoint. */
600
+ data: T | null;
601
+ /** Indicates whether an error occurred (true = error, false = success). */
602
+ error: boolean;
603
+ /** Success message describing the result of the operation. */
604
+ message: string;
605
+ /** Unique request ID for traceability in logs (e.g., from a middleware). */
606
+ requestId: string;
607
+ /** ISO timestamp when the response was generated. */
608
+ timestamp: string;
609
+ }
610
+ /**
611
+ * Generic pagination structure used for paged lists (e.g., /users?page=1).
612
+ */
613
+ interface Pagination<T = any> {
614
+ /** List of records for the current page. */
615
+ content: T[];
616
+ /** Metadata about the pagination state. */
617
+ pagination: {
618
+ /** Total number of records across all pages. */
619
+ totalRecords: number;
620
+ /** Total number of pages available. */
621
+ totalPages: number;
622
+ /** Current page number (1-based index). */
623
+ page: number;
624
+ /** Number of records per page. */
625
+ limit: number;
626
+ /** Field by which the data is sorted. */
627
+ sortBy: string;
628
+ /** Sort order: ascending or descending. */
629
+ sortOrder: 'asc' | 'desc';
630
+ };
631
+ }
632
+ /**
633
+ * Alias for paginated API response.
634
+ * Allows semantic naming like `PaginationResponse<User>` or `PaginationResponse<Post>`.
635
+ */
636
+ type PaginationResponse<T = any> = Pagination<T>;
637
+ /**
638
+ * Error response structure with additional metadata.
639
+ * Used for providing richer error information to clients.
640
+ */
641
+ interface ApiErrorResponse extends Omit<ApiResponse<never>, 'data'> {
642
+ /** Error always true for error responses */
643
+ error: true;
644
+ /** HTTP status code */
645
+ status: number;
646
+ /** Path to the resource that caused the error */
647
+ path: string;
648
+ /** Stack trace of the error (if available) */
649
+ stack?: string[];
650
+ }
651
+ /**
652
+ * Success response structure with strongly typed data.
653
+ * Used for providing successful responses to clients.
654
+ */
655
+ interface ApiSuccessResponse<T = any> extends ApiResponse<T> {
656
+ /** Error always false for success responses */
657
+ error: false;
658
+ /** HTTP status code (usually 200) */
659
+ status?: number;
660
+ }
661
+ /**
662
+ * Response structure for batch operations.
663
+ * Used when multiple operations are performed in a single request.
664
+ */
665
+ interface BatchResponse<T = any> {
666
+ /** Overall success/failure indicator */
667
+ success: boolean;
668
+ /** Total number of operations */
669
+ total: number;
670
+ /** Number of successful operations */
671
+ successful: number;
672
+ /** Number of failed operations */
673
+ failed: number;
674
+ /** Results of individual operations */
675
+ results: Array<{
676
+ /** Identifier for this operation */
677
+ id: string | number;
678
+ /** Success/failure indicator for this operation */
679
+ success: boolean;
680
+ /** Response data for this operation */
681
+ data?: T;
682
+ /** Error information if this operation failed */
683
+ error?: {
684
+ message: string;
685
+ code?: string;
686
+ };
687
+ }>;
688
+ }
689
+ /**
690
+ * Response structure for asynchronous operations.
691
+ * Used when the operation will complete in the future.
692
+ */
693
+ interface AsyncOperationResponse {
694
+ /** Always true for async operations */
695
+ async: true;
696
+ /** Job or task ID to check status later */
697
+ jobId: string;
698
+ /** Estimated completion time in seconds (if known) */
699
+ estimatedTime?: number;
700
+ /** URL to check status */
701
+ statusUrl: string;
702
+ }
703
+ /**
704
+ * Response structure for streaming operations.
705
+ * Used when data is returned as a stream rather than all at once.
706
+ */
707
+ interface StreamResponse {
708
+ /** Stream identifier */
709
+ streamId: string;
710
+ /** Stream type (e.g., 'json', 'binary') */
711
+ streamType: string;
712
+ /** Total size in bytes (if known) */
713
+ totalSize?: number;
714
+ /** Chunk size in bytes */
715
+ chunkSize: number;
716
+ }
717
+ /**
718
+ * Sort direction enumeration.
719
+ */
720
+ declare enum SortDirection {
721
+ /** Ascending sort order */
722
+ ASC = "asc",
723
+ /** Descending sort order */
724
+ DESC = "desc"
725
+ }
726
+ /**
727
+ * Pagination parameters for API requests.
728
+ */
729
+ interface PaginationParams {
730
+ /** Current page number (1-based index) */
731
+ page: number;
732
+ /** Number of records per page */
733
+ limit: number;
734
+ /** Field by which the data is sorted */
735
+ sortBy: string;
736
+ /** Sort order: ascending or descending */
737
+ sortOrder: SortDirection;
738
+ /** Optional search query */
739
+ search?: string;
740
+ }
741
+ /**
742
+ * Type that combines pagination parameters with additional data.
743
+ */
744
+ type WithPagination<T = {}> = PaginationParams & T;
745
+
746
+ interface CatbeeConfig {
747
+ logger?: {
748
+ /**
749
+ * Logging level (e.g., 'info', 'debug', 'warn', 'error')
750
+ * Environment variable: LOGGER_LEVEL
751
+ * Default: 'info' in production, 'debug' in development
752
+ */
753
+ level?: LoggerLevels;
754
+ /**
755
+ * Name of the logger instance (defaults to npm package name)
756
+ * Environment variable: LOGGER_NAME
757
+ * Default: value of npm_package_name or '@catbee/utils'
758
+ */
759
+ name?: string;
760
+ /**
761
+ * Enables pretty-print logging in development.
762
+ * Has no effect in production.
763
+ * Environment variable: LOGGER_PRETTY
764
+ * Default: true in development, false in production
765
+ */
766
+ pretty?: boolean;
767
+ /**
768
+ * Enables colorized output for pretty-print (default: true)
769
+ * Environment variable: LOGGER_PRETTY_COLORIZE
770
+ */
771
+ colorize?: boolean;
772
+ /**
773
+ * Single line output for pretty-print (default: false)
774
+ * Environment variable: LOGGER_PRETTY_SINGLE_LINE
775
+ */
776
+ singleLine?: boolean;
777
+ /**
778
+ * Directory to write log files to (if empty, file logging is disabled)
779
+ * Environment variable: LOGGER_DIR
780
+ * Eg: process.cwd() + '/logs'
781
+ * Note: Directory must exist, it is not created automatically
782
+ */
783
+ dir?: string;
784
+ };
785
+ cache: {
786
+ /**
787
+ * Default TTL (time to live) for cache entries in milliseconds
788
+ * Environment variable: CACHE_DEFAULT_TTL_SECONDS
789
+ * Default: 3600000 (1 hour)
790
+ */
791
+ defaultTtl: number;
792
+ };
793
+ /** Server configuration */
794
+ server: CatbeeGlobalServerConfig;
795
+ }
796
+
797
+ export { SortDirection };
798
+ export type { ApiErrorResponse, ApiResponse, ApiSuccessResponse, AsyncOperationResponse, Awaited, BatchResponse, CatbeeConfig, CatbeeGlobalServerConfig, CatbeeServerConfig, CatbeeServerHooks, DeepPartial, DeepReadonly, DeepRequired, DeepStringifyOrNull, Func, GlobalServerAddons, IsEqual, KeysOfType, MaybePromise, Mutable, NonEmptyArray, Nullable, Optional, Optional2, Pagination, PaginationParams, PaginationResponse, PartialPick, PickByType, Primitive, RecordOptional, RequireAtLeastOne, StreamResponse, StringKeyedRecord, ToggleConfig, UnionToIntersection, ValueOf, WithPagination, Without, Writable };