@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/dir/index.cjs CHANGED
@@ -142,7 +142,7 @@ function watchDir(dirPath, callback) {
142
142
  __name(watchDir, "watchDir");
143
143
  async function findFilesByPattern(pattern, options = {}) {
144
144
  const matchPattern = /* @__PURE__ */ __name((name, pattern2) => {
145
- let escaped = pattern2.replaceAll(/[.+^${}()|[\]\\]/g, "\\$&");
145
+ let escaped = pattern2.replaceAll(/[.+^${}()|[\]\\]/g, String.raw`\$&`);
146
146
  escaped = escaped.replaceAll("*", ".*").replaceAll("?", ".");
147
147
  const regex = new RegExp(`^${escaped}$`);
148
148
  return regex.test(name);
@@ -152,7 +152,7 @@ async function findFilesByPattern(pattern, options = {}) {
152
152
  async function walk(dir, segIndex) {
153
153
  if (segIndex >= segments.length) return [];
154
154
  const segment = segments[segIndex];
155
- const entries = await fs__default.default.promises.readdir(dir, {
155
+ const entries = await fsp__default.default.readdir(dir, {
156
156
  withFileTypes: true
157
157
  });
158
158
  let matchedFiles = [];
@@ -254,7 +254,8 @@ async function findNewestFile(dirPath, recursive = false) {
254
254
  path: file,
255
255
  mtime: (await fsp__default.default.stat(file)).mtime
256
256
  })));
257
- return stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())[0].path;
257
+ const sorted = stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
258
+ return sorted[0].path;
258
259
  }
259
260
  __name(findNewestFile, "findNewestFile");
260
261
  async function findOldestFile(dirPath, recursive = false) {
package/dir/index.d.ts CHANGED
@@ -22,4 +22,198 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- export * from './dir.utils';
25
+ import fs from 'node:fs';
26
+
27
+ /**
28
+ * Ensures that a directory exists, creating parent directories if needed (like `mkdir -p`).
29
+ *
30
+ * @param {string} dirPath - The directory path to ensure.
31
+ * @returns {Promise<void>} Resolves when the directory exists.
32
+ * @throws {Error} If directory cannot be created.
33
+ */
34
+ declare function ensureDir(dirPath: string): Promise<void>;
35
+ /**
36
+ * Recursively lists all files in a directory.
37
+ *
38
+ * @param {string} dirPath - The base directory.
39
+ * @param {boolean} [recursive=false] - Whether to recurse into subdirectories.
40
+ * @returns {Promise<string[]>} Array of absolute file paths.
41
+ * @throws {Error} If the directory cannot be read.
42
+ */
43
+ declare function listFiles(dirPath: string, recursive?: boolean): Promise<string[]>;
44
+ /**
45
+ * Deletes a directory and all its contents recursively (like `rm -rf`).
46
+ *
47
+ * @param {string} dirPath - Directory to delete.
48
+ * @returns {Promise<void>} Resolves when deletion is complete.
49
+ * @throws {Error} If deletion fails.
50
+ */
51
+ declare function deleteDirRecursive(dirPath: string): Promise<void>;
52
+ /**
53
+ * Checks whether a given path is a directory.
54
+ *
55
+ * @param {string} pathStr - Path to check.
56
+ * @returns {Promise<boolean>} True if the path is a directory, else false.
57
+ */
58
+ declare function isDirectory(pathStr: string): Promise<boolean>;
59
+ /**
60
+ * Recursively copies a directory and all its contents to a destination.
61
+ *
62
+ * @param {string} src - Source directory path.
63
+ * @param {string} dest - Destination directory path.
64
+ * @returns {Promise<void>} Resolves when copy is complete.
65
+ * @throws {Error} If source does not exist or copy fails.
66
+ */
67
+ declare function copyDir(src: string, dest: string): Promise<void>;
68
+ /**
69
+ * Moves a directory to a new location by copying and deleting the original.
70
+ *
71
+ * @param {string} src - Source directory path.
72
+ * @param {string} dest - Destination directory path.
73
+ * @returns {Promise<void>} Resolves when move is complete.
74
+ * @throws {Error} If copy or deletion fails.
75
+ */
76
+ declare function moveDir(src: string, dest: string): Promise<void>;
77
+ /**
78
+ * Empties a directory by deleting all files and subdirectories inside it.
79
+ *
80
+ * @param {string} dirPath - Path to the directory to empty.
81
+ * @returns {Promise<void>} Resolves when the directory has been emptied.
82
+ * @throws {Error} If files or subdirectories cannot be removed.
83
+ */
84
+ declare function emptyDir(dirPath: string): Promise<void>;
85
+ /**
86
+ * Calculates the total size (in bytes) of all files in a directory (recursive).
87
+ *
88
+ * @param {string} dirPath - Path to the directory.
89
+ * @returns {Promise<number>} Total size in bytes.
90
+ * @throws {Error} If any file stats cannot be read.
91
+ */
92
+ declare function getDirSize(dirPath: string): Promise<number>;
93
+ /**
94
+ * Watches a directory for file changes and calls a callback on each event.
95
+ *
96
+ * @param {string} dirPath - Directory path to watch.
97
+ * @param {(eventType: "rename" | "change", filename: string | null) => void} callback - Callback for each change event.
98
+ * @returns {() => void} A function to stop watching the directory.
99
+ */
100
+ declare function watchDir(dirPath: string, callback: (eventType: 'rename' | 'change', filename: string | null) => void): () => void;
101
+ /**
102
+ * Recursively finds files matching a simple pattern (supports '*' and '?').
103
+ *
104
+ * @param {string} pattern - Simple pattern to match files (e.g., '*.ts', 'src/*.js').
105
+ * @param {object} [options] - Options for matching files.
106
+ * @param {string} [options.cwd=process.cwd()] - Base directory to start searching from.
107
+ * @param {boolean} [options.dot=false] - Include dotfiles in matches.
108
+ * @returns {Promise<string[]>} Array of matched file paths.
109
+ */
110
+ declare function findFilesByPattern(pattern: string, options?: {
111
+ cwd?: string;
112
+ dot?: boolean;
113
+ }): Promise<string[]>;
114
+ /**
115
+ * Gets all subdirectories in a directory.
116
+ *
117
+ * @param {string} dirPath - The directory to search in.
118
+ * @param {boolean} [recursive=false] - Whether to include subdirectories recursively.
119
+ * @returns {Promise<string[]>} Array of absolute subdirectory paths.
120
+ * @throws {Error} If directory cannot be read.
121
+ */
122
+ declare function getSubdirectories(dirPath: string, recursive?: boolean): Promise<string[]>;
123
+ /**
124
+ * Ensures a directory exists and is empty.
125
+ *
126
+ * @param {string} dirPath - Path to the directory.
127
+ * @returns {Promise<void>} Resolves when the directory exists and is empty.
128
+ * @throws {Error} If directory cannot be created or emptied.
129
+ */
130
+ declare function ensureEmptyDir(dirPath: string): Promise<void>;
131
+ /**
132
+ * Creates a temporary directory with optional auto-cleanup.
133
+ *
134
+ * @param {object} [options] - Options for the temporary directory.
135
+ * @param {string} [options.prefix='tmp-'] - Prefix for the directory name.
136
+ * @param {string} [options.parentDir=os.tmpdir()] - Parent directory.
137
+ * @param {boolean} [options.cleanup=false] - Whether to register cleanup on process exit.
138
+ * @returns {Promise<{ path: string, cleanup: () => Promise<void> }>} Object with directory path and cleanup function.
139
+ * @throws {Error} If directory cannot be created.
140
+ */
141
+ declare function createTempDir(options?: {
142
+ prefix?: string;
143
+ parentDir?: string;
144
+ cleanup?: boolean;
145
+ }): Promise<{
146
+ path: string;
147
+ cleanup: () => Promise<void>;
148
+ }>;
149
+ /**
150
+ * Finds the newest file in a directory.
151
+ *
152
+ * @param {string} dirPath - Directory to search.
153
+ * @param {boolean} [recursive=false] - Whether to search subdirectories.
154
+ * @returns {Promise<string | null>} Path to the newest file or null if no files.
155
+ * @throws {Error} If directory cannot be read.
156
+ */
157
+ declare function findNewestFile(dirPath: string, recursive?: boolean): Promise<string | null>;
158
+ /**
159
+ * Finds the oldest file in a directory.
160
+ *
161
+ * @param {string} dirPath - Directory to search.
162
+ * @param {boolean} [recursive=false] - Whether to search subdirectories.
163
+ * @returns {Promise<string | null>} Path to the oldest file or null if no files.
164
+ * @throws {Error} If directory cannot be read.
165
+ */
166
+ declare function findOldestFile(dirPath: string, recursive?: boolean): Promise<string | null>;
167
+ /**
168
+ * Finds files or directories in a directory matching a predicate function.
169
+ *
170
+ * @param {string} dirPath - Directory to search.
171
+ * @param {(path: string, stat: fs.Stats) => boolean | Promise<boolean>} predicate - Function to test each path.
172
+ * @param {boolean} [recursive=false] - Whether to search subdirectories.
173
+ * @returns {Promise<string[]>} Array of matching paths.
174
+ * @throws {Error} If directory cannot be read.
175
+ */
176
+ declare function findInDir(dirPath: string, predicate: (path: string, stat: fs.Stats) => boolean | Promise<boolean>, recursive?: boolean): Promise<string[]>;
177
+ /**
178
+ * Watches a directory recursively for file changes.
179
+ *
180
+ * @param {string} dirPath - Base directory path to watch.
181
+ * @param {(eventType: "rename" | "change", filename: string) => void} callback - Callback for each change event.
182
+ * @param {boolean} [includeSubdirs=true] - Whether to watch subdirectories.
183
+ * @returns {Promise<() => void>} A function to stop watching the directory.
184
+ * @throws {Error} If directory cannot be watched.
185
+ */
186
+ declare function watchDirRecursive(dirPath: string, callback: (eventType: 'rename' | 'change', filename: string) => void, includeSubdirs?: boolean): Promise<() => void>;
187
+ /**
188
+ * Gets detailed directory statistics including file count, directory count, and size.
189
+ *
190
+ * @param {string} dirPath - Path to the directory.
191
+ * @returns {Promise<{ fileCount: number, dirCount: number, totalSize: number }>} Directory statistics.
192
+ * @throws {Error} If directory cannot be read.
193
+ */
194
+ declare function getDirStats(dirPath: string): Promise<{
195
+ fileCount: number;
196
+ dirCount: number;
197
+ totalSize: number;
198
+ }>;
199
+ /**
200
+ * Walks through a directory hierarchy, calling a visitor function for each entry.
201
+ *
202
+ * @param {string} dirPath - Starting directory path.
203
+ * @param {object} options - Options for walking the directory.
204
+ * @param {(entry: { path: string, name: string, isDirectory: boolean, stats: fs.Stats }) => boolean | void | Promise<boolean | void>} options.visitorFn -
205
+ * Function called for each file/directory. Return false to skip a directory.
206
+ * @param {'pre' | 'post'} [options.traversalOrder='pre'] - Whether to visit directories before or after their contents.
207
+ * @throws {Error} If directory cannot be read.
208
+ */
209
+ declare function walkDir(dirPath: string, options: {
210
+ visitorFn: (entry: {
211
+ path: string;
212
+ name: string;
213
+ isDirectory: boolean;
214
+ stats: fs.Stats;
215
+ }) => boolean | void | Promise<boolean | void>;
216
+ traversalOrder?: 'pre' | 'post';
217
+ }): Promise<void>;
218
+
219
+ export { copyDir, createTempDir, deleteDirRecursive, emptyDir, ensureDir, ensureEmptyDir, findFilesByPattern, findInDir, findNewestFile, findOldestFile, getDirSize, getDirStats, getSubdirectories, isDirectory, listFiles, moveDir, walkDir, watchDir, watchDirRecursive };
package/dir/index.mjs CHANGED
@@ -133,7 +133,7 @@ function watchDir(dirPath, callback) {
133
133
  __name(watchDir, "watchDir");
134
134
  async function findFilesByPattern(pattern, options = {}) {
135
135
  const matchPattern = /* @__PURE__ */ __name((name, pattern2) => {
136
- let escaped = pattern2.replaceAll(/[.+^${}()|[\]\\]/g, "\\$&");
136
+ let escaped = pattern2.replaceAll(/[.+^${}()|[\]\\]/g, String.raw`\$&`);
137
137
  escaped = escaped.replaceAll("*", ".*").replaceAll("?", ".");
138
138
  const regex = new RegExp(`^${escaped}$`);
139
139
  return regex.test(name);
@@ -143,7 +143,7 @@ async function findFilesByPattern(pattern, options = {}) {
143
143
  async function walk(dir, segIndex) {
144
144
  if (segIndex >= segments.length) return [];
145
145
  const segment = segments[segIndex];
146
- const entries = await fs.promises.readdir(dir, {
146
+ const entries = await fsp.readdir(dir, {
147
147
  withFileTypes: true
148
148
  });
149
149
  let matchedFiles = [];
@@ -245,7 +245,8 @@ async function findNewestFile(dirPath, recursive = false) {
245
245
  path: file,
246
246
  mtime: (await fsp.stat(file)).mtime
247
247
  })));
248
- return stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())[0].path;
248
+ const sorted = stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
249
+ return sorted[0].path;
249
250
  }
250
251
  __name(findNewestFile, "findNewestFile");
251
252
  async function findOldestFile(dirPath, recursive = false) {
package/env/index.cjs CHANGED
@@ -26,6 +26,8 @@
26
26
 
27
27
  var fs = require('fs');
28
28
  var path = require('path');
29
+ var date = require('@catbee/utils/date');
30
+ var validation = require('@catbee/utils/validation');
29
31
 
30
32
  var __defProp = Object.defineProperty;
31
33
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -114,7 +116,7 @@ var Env = class _Env {
114
116
  */
115
117
  static get(key, defaultValue) {
116
118
  let value = process.env[key] ?? defaultValue;
117
- if (value && value.includes("${")) {
119
+ if (value?.includes("${")) {
118
120
  value = value.replace(/\${([A-Za-z0-9_]+)}/g, (_, varName) => {
119
121
  return process.env[varName] ?? "";
120
122
  });
@@ -172,7 +174,7 @@ var Env = class _Env {
172
174
  return defaultValue;
173
175
  }
174
176
  const numberValue = Number(value);
175
- if (isNaN(numberValue)) {
177
+ if (Number.isNaN(numberValue)) {
176
178
  throw new Error(`Environment variable '${key}' is not a valid number, got: "${value}"`);
177
179
  }
178
180
  this.cache.set(`number:${key}`, numberValue);
@@ -363,7 +365,7 @@ var Env = class _Env {
363
365
  static getNumberArray(key, defaultValue = [], splitter = ",") {
364
366
  return _Env.getArray(key, defaultValue, splitter, (item) => {
365
367
  const num = Number(item);
366
- if (isNaN(num)) {
368
+ if (Number.isNaN(num)) {
367
369
  throw new Error(`Value "${item}" in array '${key}' is not a valid number`);
368
370
  }
369
371
  return num;
@@ -490,8 +492,7 @@ var Env = class _Env {
490
492
  }
491
493
  return defaultValue;
492
494
  }
493
- const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
494
- if (!emailRegex.test(value)) {
495
+ if (!validation.isEmail(value)) {
495
496
  throw new Error(`Environment variable '${key}' is not a valid email address: "${value}"`);
496
497
  }
497
498
  this.cache.set(`email:${key}`, value);
@@ -579,7 +580,7 @@ var Env = class _Env {
579
580
  return defaultValue instanceof Date ? defaultValue : /* @__PURE__ */ new Date();
580
581
  }
581
582
  const date = new Date(value);
582
- if (isNaN(date.getTime())) {
583
+ if (Number.isNaN(date.getTime())) {
583
584
  throw new Error(`Environment variable '${key}' is not a valid date: "${value}"`);
584
585
  }
585
586
  return date;
@@ -603,26 +604,9 @@ var Env = class _Env {
603
604
  if (this.cache.has(cacheKey)) {
604
605
  return this.cache.get(cacheKey);
605
606
  }
606
- const value = _Env.get(key, String(defaultValue));
607
- if (!value) return 0;
608
- if (/^\d+$/.test(value)) {
609
- const ms2 = parseInt(value, 10);
610
- this.cache.set(cacheKey, ms2);
611
- return ms2;
612
- }
613
- const durationRegex = /^(?:(\d+)y)?(?:(\d+)w)?(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?(?:(\d+)ms)?$/;
614
- const matches = value.match(durationRegex);
615
- if (!matches || matches[0] === "") {
616
- throw new Error(`Environment variable '${key}' has invalid duration format: "${value}". Use formats like 1y, 2w, 3d, 4h, 5m, 6s, or 7ms.`);
617
- }
618
- let ms = 0;
619
- if (matches[1]) ms += parseInt(matches[1], 10) * 31536e6;
620
- if (matches[2]) ms += parseInt(matches[2], 10) * 6048e5;
621
- if (matches[3]) ms += parseInt(matches[3], 10) * 864e5;
622
- if (matches[4]) ms += parseInt(matches[4], 10) * 36e5;
623
- if (matches[5]) ms += parseInt(matches[5], 10) * 6e4;
624
- if (matches[6]) ms += parseInt(matches[6], 10) * 1e3;
625
- if (matches[7]) ms += parseInt(matches[7], 10);
607
+ const raw = _Env.get(key, String(defaultValue));
608
+ if (!raw) return 0;
609
+ const ms = date.parseDuration(raw);
626
610
  this.cache.set(cacheKey, ms);
627
611
  return ms;
628
612
  }