@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/obj/index.mjs CHANGED
@@ -26,8 +26,12 @@ var __defProp = Object.defineProperty;
26
26
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
27
27
 
28
28
  // src/obj/obj.utils.ts
29
+ function isObject(value) {
30
+ return value !== null && typeof value === "object" && !Array.isArray(value);
31
+ }
32
+ __name(isObject, "isObject");
29
33
  function isObjEmpty(obj) {
30
- return !!obj && typeof obj === "object" && Object.keys(obj).length === 0;
34
+ return isObject(obj) && Object.keys(obj).length === 0;
31
35
  }
32
36
  __name(isObjEmpty, "isObjEmpty");
33
37
  function pick(obj, keys) {
@@ -42,117 +46,38 @@ function omit(obj, keys) {
42
46
  }
43
47
  __name(omit, "omit");
44
48
  function deepObjMerge(target, ...sources) {
45
- if (!sources.length) return target;
46
49
  const seen = /* @__PURE__ */ new WeakMap();
47
- seen.set(target, target);
48
- for (const s of sources) {
49
- if (s && typeof s === "object") {
50
- seen.set(s, target);
51
- }
52
- }
53
- function deepClone2(value) {
54
- if (value === null || typeof value !== "object") return value;
55
- if (seen.has(value)) return seen.get(value);
56
- if (value instanceof Date) {
57
- return new Date(value.getTime());
58
- }
59
- if (Array.isArray(value)) {
60
- const clone2 = [];
61
- seen.set(value, clone2);
62
- value.forEach((item, i) => clone2[i] = deepClone2(item));
63
- return clone2;
64
- }
65
- if (value instanceof Set) {
66
- const clone2 = /* @__PURE__ */ new Set();
67
- seen.set(value, clone2);
68
- value.forEach((item) => clone2.add(deepClone2(item)));
69
- return clone2;
70
- }
71
- if (value instanceof Map) {
72
- const clone2 = /* @__PURE__ */ new Map();
73
- seen.set(value, clone2);
74
- value.forEach((val, key) => clone2.set(key, deepClone2(val)));
75
- return clone2;
76
- }
77
- if (value instanceof RegExp) {
78
- return new RegExp(value.source, value.flags);
50
+ const mergeInto = /* @__PURE__ */ __name((t, s) => {
51
+ if (s === void 0) return t;
52
+ if (typeof s === "function" || typeof s === "symbol") return s;
53
+ if (Array.isArray(s)) {
54
+ const cloned = deepClone(s);
55
+ seen.set(s, cloned);
56
+ return cloned;
79
57
  }
80
- if (value instanceof ArrayBuffer) {
81
- return value.slice(0);
82
- }
83
- if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {
84
- const typed = value;
85
- const ctor = typed.constructor;
86
- const typedArrayCtors = [
87
- Int8Array,
88
- Uint8Array,
89
- Uint8ClampedArray,
90
- Int16Array,
91
- Uint16Array,
92
- Int32Array,
93
- Uint32Array,
94
- Float32Array,
95
- Float64Array,
96
- BigInt64Array,
97
- BigUint64Array
98
- ].filter(Boolean);
99
- const typedArrayCtorSet = new Set(typedArrayCtors);
100
- if (typeof ctor === "function" && typedArrayCtorSet.has(ctor)) {
101
- const buffer = typed.buffer && typeof typed.buffer.slice === "function" ? typed.buffer.slice(0) : typed.buffer;
102
- const clone2 = new ctor(buffer, typed.byteOffset, typed.length);
103
- seen.set(value, clone2);
104
- return clone2;
105
- } else if (typeof typed.slice === "function") {
106
- const clone2 = typed.slice();
107
- seen.set(value, clone2);
108
- return clone2;
109
- } else {
110
- throw new Error("Cannot deep clone unknown TypedArray type: " + (typed && typed.constructor && typed.constructor.name));
58
+ if (s && typeof s === "object") {
59
+ if (seen.has(s)) return seen.get(s);
60
+ if (s instanceof Date || s instanceof Map || s instanceof Set || s instanceof RegExp || s instanceof ArrayBuffer || ArrayBuffer.isView(s)) {
61
+ const cloned = deepClone(s);
62
+ seen.set(s, cloned);
63
+ return cloned;
111
64
  }
112
- }
113
- const clone = Object.create(Object.getPrototypeOf(value));
114
- seen.set(value, clone);
115
- Reflect.ownKeys(value).forEach((key) => {
116
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
117
- if (descriptor.get || descriptor.set) {
118
- Object.defineProperty(clone, key, descriptor);
119
- } else {
120
- clone[key] = deepClone2(value[key]);
65
+ if (!t || typeof t !== "object") {
66
+ t = Object.create(Object.getPrototypeOf(s));
121
67
  }
122
- });
123
- return clone;
124
- }
125
- __name(deepClone2, "deepClone");
126
- function mergeProp(target2, source, key) {
127
- const targetValue = target2[key];
128
- const sourceValue = source[key];
129
- if (sourceValue === void 0) return;
130
- if (sourceValue === null || typeof sourceValue !== "object") {
131
- target2[key] = sourceValue;
132
- return;
133
- }
134
- if (Array.isArray(sourceValue)) {
135
- target2[key] = deepClone2(sourceValue);
136
- return;
137
- }
138
- if (sourceValue instanceof Date || sourceValue instanceof RegExp || sourceValue instanceof Set || sourceValue instanceof Map || sourceValue instanceof ArrayBuffer || ArrayBuffer.isView(sourceValue) && !(sourceValue instanceof DataView)) {
139
- target2[key] = deepClone2(sourceValue);
140
- return;
141
- }
142
- if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
143
- for (const k of Reflect.ownKeys(sourceValue)) {
144
- mergeProp(targetValue, sourceValue, k);
68
+ seen.set(s, t);
69
+ for (const key of Reflect.ownKeys(s)) {
70
+ if (key === "__proto__") continue;
71
+ const sv = s[key];
72
+ if (sv === void 0) continue;
73
+ t[key] = mergeInto(t[key], sv);
145
74
  }
146
- return;
147
- }
148
- target2[key] = deepClone2(sourceValue);
149
- }
150
- __name(mergeProp, "mergeProp");
151
- for (const source of sources) {
152
- if (source == null) continue;
153
- for (const key of Reflect.ownKeys(source)) {
154
- mergeProp(target, source, key);
75
+ return t;
155
76
  }
77
+ return s;
78
+ }, "mergeInto");
79
+ for (const s of sources) {
80
+ target = mergeInto(target, s);
156
81
  }
157
82
  return target;
158
83
  }
@@ -167,6 +92,7 @@ __name(isPlainObject, "isPlainObject");
167
92
  function flattenObject(obj, prefix = "") {
168
93
  return Object.entries(obj).reduce((acc, [key, value]) => {
169
94
  const newKey = prefix ? `${prefix}.${key}` : key;
95
+ if (key === "__proto__") return acc;
170
96
  if (value && typeof value === "object" && !Array.isArray(value)) {
171
97
  Object.assign(acc, flattenObject(value, newKey));
172
98
  } else {
@@ -182,63 +108,52 @@ function getValueByPath(obj, path) {
182
108
  return parts.reduce((acc, key) => acc?.[key], obj);
183
109
  }
184
110
  __name(getValueByPath, "getValueByPath");
111
+ function ensureNextContainer(curr, nextIsIndex) {
112
+ if (curr === void 0 || typeof curr !== "object" || curr === null) {
113
+ return nextIsIndex ? [] : /* @__PURE__ */ Object.create(null);
114
+ }
115
+ return curr;
116
+ }
117
+ __name(ensureNextContainer, "ensureNextContainer");
185
118
  function setValueByPath(obj, path, value) {
186
119
  if (!obj || typeof obj !== "object") return obj;
120
+ const clone = deepClone(obj);
187
121
  const parts = path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
188
- if (parts.length === 0) return obj;
122
+ if (parts.length === 0) return clone;
189
123
  const forbiddenKeys = /* @__PURE__ */ new Set([
190
124
  "__proto__",
191
125
  "prototype",
192
126
  "constructor"
193
127
  ]);
194
- let current = obj;
128
+ let current = clone;
195
129
  for (let i = 0; i < parts.length - 1; i++) {
196
130
  const key = parts[i];
197
- if (forbiddenKeys.has(key)) {
198
- return obj;
199
- }
131
+ if (forbiddenKeys.has(key)) return clone;
200
132
  const nextKey = parts[i + 1];
201
- const isArrayIndex = !isNaN(Number(nextKey));
202
- if (current[key] === void 0) {
203
- current[key] = isArrayIndex ? [] : /* @__PURE__ */ Object.create(null);
204
- } else if (typeof current[key] !== "object" || current[key] === null) {
205
- current[key] = isArrayIndex ? [] : /* @__PURE__ */ Object.create(null);
206
- }
133
+ const nextIsIndex = !Number.isNaN(Number(nextKey));
134
+ current[key] = ensureNextContainer(current[key], nextIsIndex);
207
135
  current = current[key];
208
136
  }
209
- const finalKey = parts[parts.length - 1];
210
- if (forbiddenKeys.has(finalKey)) {
211
- return obj;
212
- }
137
+ const finalKey = parts.at(-1);
138
+ if (forbiddenKeys.has(finalKey)) return clone;
213
139
  current[finalKey] = value;
214
- return obj;
140
+ return clone;
215
141
  }
216
142
  __name(setValueByPath, "setValueByPath");
217
143
  function isEqual(a, b) {
218
144
  if (a === b) return true;
219
- if (a == null || b == null || typeof a !== "object" || typeof b !== "object") {
220
- return false;
221
- }
222
- if (a instanceof Date && b instanceof Date) {
223
- return a.getTime() === b.getTime();
224
- }
225
- if (a instanceof Date || b instanceof Date) {
226
- return false;
227
- }
228
- if (Array.isArray(a) && Array.isArray(b)) {
229
- if (a.length !== b.length) return false;
230
- for (let i = 0; i < a.length; i++) {
231
- if (!isEqual(a[i], b[i])) return false;
232
- }
233
- return true;
234
- }
235
- if (Array.isArray(a) || Array.isArray(b)) {
236
- return false;
237
- }
238
- const keysA = Object.keys(a);
239
- const keysB = Object.keys(b);
240
- if (keysA.length !== keysB.length) return false;
241
- return keysA.every((key) => Object.prototype.hasOwnProperty.call(b, key) && isEqual(a[key], b[key]));
145
+ if (a == null || b == null || typeof a !== "object" || typeof b !== "object") return false;
146
+ if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
147
+ if (a instanceof RegExp && b instanceof RegExp) return a.source === b.source && a.flags === b.flags;
148
+ if (a instanceof Set && b instanceof Set) return a.size === b.size && [
149
+ ...a
150
+ ].every((v) => b.has(v));
151
+ if (a instanceof Map && b instanceof Map) return a.size === b.size && [
152
+ ...a
153
+ ].every(([k, v]) => isEqual(v, b.get(k)));
154
+ if (a instanceof ArrayBuffer && b instanceof ArrayBuffer) return isEqual(new Uint8Array(a), new Uint8Array(b));
155
+ if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((v, i) => isEqual(v, b[i]));
156
+ return Object.keys(a).length === Object.keys(b).length && Object.keys(a).every((key) => isEqual(a[key], b[key]));
242
157
  }
243
158
  __name(isEqual, "isEqual");
244
159
  function filterObject(obj, predicate) {
@@ -252,35 +167,108 @@ function mapObject(obj, mapFn) {
252
167
  ]));
253
168
  }
254
169
  __name(mapObject, "mapObject");
255
- function deepClone(value) {
256
- try {
257
- if (typeof globalThis.structuredClone === "function") {
258
- return globalThis.structuredClone(value);
259
- }
260
- } catch (_) {
170
+ function _deepClone(value, seen) {
171
+ if (typeof value === "function" || typeof value === "symbol") {
172
+ return value;
261
173
  }
262
- try {
263
- return JSON.parse(JSON.stringify(value));
264
- } catch (_) {
174
+ if (value === null || typeof value !== "object") {
265
175
  return value;
266
176
  }
177
+ if (seen.has(value)) {
178
+ return seen.get(value);
179
+ }
180
+ let result;
181
+ if (Array.isArray(value)) {
182
+ result = [];
183
+ seen.set(value, result);
184
+ for (const item of value) {
185
+ result.push(_deepClone(item, seen));
186
+ }
187
+ return result;
188
+ }
189
+ if (value instanceof Date) {
190
+ result = new Date(value.getTime());
191
+ seen.set(value, result);
192
+ return result;
193
+ }
194
+ if (value instanceof Map) {
195
+ result = /* @__PURE__ */ new Map();
196
+ seen.set(value, result);
197
+ for (const [k, v] of value) {
198
+ result.set(_deepClone(k, seen), _deepClone(v, seen));
199
+ }
200
+ return result;
201
+ }
202
+ if (value instanceof Set) {
203
+ result = /* @__PURE__ */ new Set();
204
+ seen.set(value, result);
205
+ for (const v of value) {
206
+ result.add(_deepClone(v, seen));
207
+ }
208
+ return result;
209
+ }
210
+ if (value instanceof RegExp) {
211
+ result = new RegExp(value.source, value.flags);
212
+ seen.set(value, result);
213
+ return result;
214
+ }
215
+ if (ArrayBuffer.isView(value)) {
216
+ if (value instanceof DataView) {
217
+ const buf2 = _deepClone(value.buffer, seen);
218
+ const clone2 = new DataView(buf2, value.byteOffset, value.byteLength);
219
+ seen.set(value, clone2);
220
+ return clone2;
221
+ }
222
+ const typed = value;
223
+ const buf = _deepClone(typed.buffer, seen);
224
+ const clone = new typed.constructor(buf, typed.byteOffset, typed.length);
225
+ seen.set(value, clone);
226
+ return clone;
227
+ }
228
+ if (value instanceof ArrayBuffer) {
229
+ result = value.slice(0);
230
+ seen.set(value, result);
231
+ return result;
232
+ }
233
+ result = Object.create(Object.getPrototypeOf(value));
234
+ seen.set(value, result);
235
+ for (const key of Reflect.ownKeys(value)) {
236
+ const desc = Object.getOwnPropertyDescriptor(value, key);
237
+ if (desc?.get || desc?.set) {
238
+ Object.defineProperty(result, key, {
239
+ get: desc.get,
240
+ set: desc.set,
241
+ enumerable: desc.enumerable,
242
+ configurable: desc.configurable
243
+ });
244
+ } else {
245
+ Object.defineProperty(result, key, {
246
+ value: _deepClone(value[key], seen),
247
+ writable: desc?.writable ?? true,
248
+ enumerable: desc?.enumerable ?? true,
249
+ configurable: desc?.configurable ?? true
250
+ });
251
+ }
252
+ }
253
+ return result;
254
+ }
255
+ __name(_deepClone, "_deepClone");
256
+ function deepClone(value) {
257
+ const seen = /* @__PURE__ */ new WeakMap();
258
+ return _deepClone(value, seen);
267
259
  }
268
260
  __name(deepClone, "deepClone");
269
261
  function deepFreeze(obj) {
270
262
  Object.freeze(obj);
271
- for (const prop of Object.getOwnPropertyNames(obj)) {
272
- const value = obj[prop];
273
- if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
274
- deepFreeze(value);
263
+ for (const key of Reflect.ownKeys(obj)) {
264
+ const val = obj[key];
265
+ if (isObject(val) && !Object.isFrozen(val)) {
266
+ deepFreeze(val);
275
267
  }
276
268
  }
277
269
  return obj;
278
270
  }
279
271
  __name(deepFreeze, "deepFreeze");
280
- function isObject(value) {
281
- return value !== null && typeof value === "object" && !Array.isArray(value);
282
- }
283
- __name(isObject, "isObject");
284
272
  function getAllPaths(obj, parentPath = "") {
285
273
  if (!isObject(obj)) return [];
286
274
  return Object.entries(obj).flatMap(([key, value]) => {
package/package.json CHANGED
@@ -1,13 +1,10 @@
1
1
  {
2
2
  "name": "@catbee/utils",
3
- "version": "2.0.0-next.0",
3
+ "version": "2.0.0-next.1",
4
4
  "description": "A modular, production-grade utility toolkit for Node.js and TypeScript, designed for robust, scalable applications (including Express-based services). All utilities are tree-shakable and can be imported independently.",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
- "main": "index.cjs",
9
- "module": "index.mjs",
10
- "types": "index.d.ts",
11
8
  "author": "Hari G <harig@catbee.in>",
12
9
  "maintainers": [
13
10
  "Hari G <harig@catbee.in>",
@@ -23,8 +20,7 @@
23
20
  },
24
21
  "license": "MIT",
25
22
  "dependencies": {
26
- "pino": "^10.1.0",
27
- "reflect-metadata": "^0.2.2"
23
+ "pino": "^10.1.0"
28
24
  },
29
25
  "optionalDependencies": {
30
26
  "@scalar/express-api-reference": "^0.8.30",
@@ -36,7 +32,8 @@
36
32
  "express-rate-limit": "^8.2.1",
37
33
  "helmet": "^8.1.0",
38
34
  "pino-pretty": "^13.1.3",
39
- "prom-client": "^15.1.3"
35
+ "prom-client": "^15.1.3",
36
+ "reflect-metadata": "^0.2.2"
40
37
  },
41
38
  "peerDependencies": {
42
39
  "express": "^5.1.0"
@@ -49,6 +46,9 @@
49
46
  "engines": {
50
47
  "node": ">=18.4"
51
48
  },
49
+ "main": "index.cjs",
50
+ "module": "index.mjs",
51
+ "types": "index.d.ts",
52
52
  "files": [
53
53
  "**/*.mjs",
54
54
  "**/*.cjs",
@@ -193,10 +193,10 @@
193
193
  "require": "./url/index.cjs",
194
194
  "types": "./url/index.d.ts"
195
195
  },
196
- "./validate": {
197
- "import": "./validate/index.mjs",
198
- "require": "./validate/index.cjs",
199
- "types": "./validate/index.d.ts"
196
+ "./validation": {
197
+ "import": "./validation/index.mjs",
198
+ "require": "./validation/index.cjs",
199
+ "types": "./validation/index.d.ts"
200
200
  }
201
201
  }
202
202
  }
@@ -193,8 +193,8 @@ function memoize(fn, options = {}) {
193
193
  __name(memoize, "memoize");
194
194
  function trackMemoryUsage(fn, options = {}) {
195
195
  const { log = false, label = fn.name || "anonymous function" } = options;
196
- if (global.gc) {
197
- global.gc();
196
+ if (globalThis.gc) {
197
+ globalThis.gc();
198
198
  }
199
199
  const beforeMemory = process.memoryUsage();
200
200
  const result = fn();
@@ -22,4 +22,141 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- export * from './performance.utils';
25
+ /**
26
+ * Options for timing function execution.
27
+ */
28
+ interface TimingOptions {
29
+ /** Optional label for the timing (defaults to function name) */
30
+ label?: string;
31
+ /** Whether to log the timing (default: false) */
32
+ log?: boolean;
33
+ /** Log level to use if logging is enabled (default: 'debug') */
34
+ logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error';
35
+ }
36
+ /**
37
+ * Result of a timing operation.
38
+ */
39
+ interface TimingResult {
40
+ /** Duration in milliseconds */
41
+ durationMs: number;
42
+ /** Duration in seconds */
43
+ durationSec: number;
44
+ /** Start timestamp */
45
+ startTime: number;
46
+ /** End timestamp */
47
+ endTime: number;
48
+ /** Label used for the timing */
49
+ label: string;
50
+ }
51
+ /**
52
+ * Measure the execution time of a synchronous function.
53
+ *
54
+ * @param fn - Function to measure
55
+ * @param options - Timing options
56
+ * @returns Result containing the return value and timing information
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const { result, timing } = timeSync(() => {
61
+ * // Some expensive operation
62
+ * return computeResult();
63
+ * }, { label: 'Computation', log: true });
64
+ *
65
+ * console.log(`Result: ${result}, took ${timing.durationMs}ms`);
66
+ * ```
67
+ */
68
+ declare function timeSync<T>(fn: () => T, options?: TimingOptions): {
69
+ result: T;
70
+ timing: TimingResult;
71
+ };
72
+ /**
73
+ * Measure the execution time of an asynchronous function.
74
+ *
75
+ * @param fn - Async function to measure
76
+ * @param options - Timing options
77
+ * @returns Promise resolving to result and timing information
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const { result, timing } = await timeAsync(async () => {
82
+ * // Some expensive async operation
83
+ * const data = await fetchData();
84
+ * return processData(data);
85
+ * }, { label: 'API Request', log: true });
86
+ *
87
+ * console.log(`Fetched ${result.length} items in ${timing.durationSec.toFixed(2)}s`);
88
+ * ```
89
+ */
90
+ declare function timeAsync<T>(fn: () => Promise<T>, options?: TimingOptions): Promise<{
91
+ result: T;
92
+ timing: TimingResult;
93
+ }>;
94
+ /**
95
+ * Create a timing decorator for class methods.
96
+ *
97
+ * @param options - Timing options
98
+ * @returns Method decorator
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * class DataService {
103
+ * @timed({ log: true, logLevel: 'info' })
104
+ * async fetchData() {
105
+ * // ...implementation
106
+ * }
107
+ * }
108
+ * ```
109
+ */
110
+ declare function timed(options?: TimingOptions): (target: any, propertyKeyOrContext: string | symbol | any, descriptor?: PropertyDescriptor) => void;
111
+ /**
112
+ * Memoize function results with optional TTL and max cache size.
113
+ *
114
+ * @param fn - Function to memoize
115
+ * @param options - Memoization options
116
+ * @returns Memoized function
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * // Cache results for 30 seconds, with a maximum of 100 entries
121
+ * const cachedFetch = memoize(
122
+ * async (url) => {
123
+ * const response = await fetch(url);
124
+ * return response.json();
125
+ * },
126
+ * { ttl: 30000, maxSize: 100, cacheKey: (url) => url }
127
+ * );
128
+ * ```
129
+ */
130
+ declare function memoize<T, Args extends any[]>(fn: (...args: Args) => T, options?: {
131
+ /** Time-to-live in milliseconds (default: indefinite) */
132
+ ttl?: number;
133
+ /** Maximum cache size (default: unlimited) */
134
+ maxSize?: number;
135
+ /** Function to generate a cache key from arguments */
136
+ cacheKey?: (...args: Args) => string;
137
+ /** Auto-cleanup interval in milliseconds (default: disabled) */
138
+ autoCleanupMs?: number;
139
+ }): (...args: Args) => T;
140
+ /**
141
+ * Track memory usage for a function execution.
142
+ *
143
+ * @param fn - Function to track
144
+ * @param options - Memory tracking options
145
+ * @returns Result and memory usage information
146
+ */
147
+ declare function trackMemoryUsage<T>(fn: () => T, options?: {
148
+ /** Whether to log the memory usage (default: false) */
149
+ log?: boolean;
150
+ /** Label for the memory tracking (default: function name) */
151
+ label?: string;
152
+ }): {
153
+ result: T;
154
+ memoryUsage: {
155
+ before: NodeJS.MemoryUsage;
156
+ after: NodeJS.MemoryUsage;
157
+ diff: Record<string, number>;
158
+ };
159
+ };
160
+
161
+ export { memoize, timeAsync, timeSync, timed, trackMemoryUsage };
162
+ export type { TimingOptions, TimingResult };
@@ -191,8 +191,8 @@ function memoize(fn, options = {}) {
191
191
  __name(memoize, "memoize");
192
192
  function trackMemoryUsage(fn, options = {}) {
193
193
  const { log = false, label = fn.name || "anonymous function" } = options;
194
- if (global.gc) {
195
- global.gc();
194
+ if (globalThis.gc) {
195
+ globalThis.gc();
196
196
  }
197
197
  const beforeMemory = process.memoryUsage();
198
198
  const result = fn();
package/request/index.cjs CHANGED
@@ -61,7 +61,7 @@ function parseNumberParam(value, options = {}) {
61
61
  };
62
62
  }
63
63
  const num = Number(value);
64
- if (isNaN(num)) {
64
+ if (Number.isNaN(num)) {
65
65
  if (throwOnError) throw new exception.BadRequestException(errorMessage);
66
66
  return {
67
67
  isValid: false,