@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/server/index.mjs CHANGED
@@ -30,12 +30,12 @@ import { requestId, setupRequestContext, timeout, responseTime, errorHandler } f
30
30
  import { Env } from '@catbee/utils/env';
31
31
  import { getLogger } from '@catbee/utils/logger';
32
32
  import { ServiceUnavailableException, InternalServerErrorException, NotFoundException } from '@catbee/utils/exception';
33
- import fs from 'fs';
34
- import { defaultServerConfig, defaultCatbeeConfig } from '@catbee/utils/config';
35
- import { deepObjMerge } from '@catbee/utils/obj';
36
- import { fileExists } from '@catbee/utils/fs';
37
- import { isPort } from '@catbee/utils/validate';
33
+ import { getCatbeeServerGlobalConfig } from '@catbee/utils/config';
34
+ import { deepObjMerge, deepClone } from '@catbee/utils/obj';
35
+ import { fileExists, readFile, readFileSync } from '@catbee/utils/fs';
36
+ import { isPort } from '@catbee/utils/validation';
38
37
  import { optionalRequire } from '@catbee/utils/async';
38
+ import { uuid } from '@catbee/utils/id';
39
39
 
40
40
  var __defProp = Object.defineProperty;
41
41
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
@@ -498,7 +498,10 @@ var ServerConfigBuilder = class {
498
498
  * ```
499
499
  */
500
500
  withBodyParser(opts) {
501
- this.config.bodyParser = deepObjMerge({}, this.config.bodyParser ?? {}, opts);
501
+ this.config.bodyParser = {
502
+ ...this.config.bodyParser,
503
+ ...opts
504
+ };
502
505
  return this;
503
506
  }
504
507
  /**
@@ -641,7 +644,7 @@ var ServerConfigBuilder = class {
641
644
  * ```
642
645
  */
643
646
  build() {
644
- const config = deepObjMerge({}, defaultServerConfig, this.config);
647
+ const config = deepObjMerge({}, getCatbeeServerGlobalConfig(), this.config);
645
648
  if (config.openApi?.enable && !config.openApi.filePath) {
646
649
  throw new Error("OpenAPI is enabled but no filePath is specified");
647
650
  }
@@ -651,7 +654,7 @@ var ServerConfigBuilder = class {
651
654
  });
652
655
  }
653
656
  mergeConfig(key, value) {
654
- const current = typeof this.config[key] === "object" && this.config[key] !== null ? this.config[key] : {};
657
+ const current = this.config[key] && typeof this.config[key] === "object" ? deepClone(this.config[key]) : {};
655
658
  this.config[key] = deepObjMerge({}, current, value);
656
659
  }
657
660
  setEnabled(key, enable, overrides = {}) {
@@ -662,9 +665,11 @@ var ServerConfigBuilder = class {
662
665
  return this;
663
666
  }
664
667
  };
665
-
666
- // src/server/server.ts
667
- var getDependencyErrorMessage = /* @__PURE__ */ __name((packageName, x) => `Missing required dependency ${x ? `for ${x}` : ""}: ${packageName}. Please install it to proceed.`, "getDependencyErrorMessage");
668
+ var getDependencyErrorMessage = /* @__PURE__ */ __name((packageName, context) => {
669
+ const ctxPart = context ? `for ${context}` : "";
670
+ const spacer = ctxPart ? ` ${ctxPart}` : "";
671
+ return `Missing required dependency${spacer}: ${packageName}. Please install it to proceed.`;
672
+ }, "getDependencyErrorMessage");
668
673
  var DependencyErrors = {
669
674
  express: getDependencyErrorMessage("express"),
670
675
  helmet: getDependencyErrorMessage("helmet"),
@@ -729,10 +734,10 @@ var ExpressServer = class {
729
734
  * - Request tracing
730
735
  */
731
736
  constructor(config, hooks = {}) {
732
- if (this.isBuiltServerConfig(config)) {
737
+ if (this.hasBuildMarker(config)) {
733
738
  this.config = config;
734
739
  } else {
735
- this.config = deepObjMerge({}, defaultServerConfig, config);
740
+ this.config = deepObjMerge({}, getCatbeeServerGlobalConfig(), config);
736
741
  }
737
742
  if (!isPort(this.config.port)) {
738
743
  const msg = `Port must be a valid number between 1 and 65535, got: ${this.config.port}`;
@@ -834,7 +839,7 @@ var ExpressServer = class {
834
839
  async runHook(hook, ...args) {
835
840
  try {
836
841
  const fn = this.hooks[hook];
837
- if (fn) await fn.apply(null, args);
842
+ if (fn) await fn(...args);
838
843
  } catch (err) {
839
844
  getLogger().error({
840
845
  err,
@@ -881,7 +886,7 @@ var ExpressServer = class {
881
886
  this.app.use(requestId({
882
887
  headerName: this.config.requestId?.headerName,
883
888
  exposeHeader: this.config.requestId?.exposeHeader,
884
- generator: this.config.requestId?.generator
889
+ generator: this.config.requestId?.generator || uuid
885
890
  }));
886
891
  this.app.use(setupRequestContext({
887
892
  headerName: this.config.requestId?.headerName,
@@ -1045,7 +1050,7 @@ var ExpressServer = class {
1045
1050
  }
1046
1051
  this.app.use(openApiMountPath, apiReference({
1047
1052
  spec: {
1048
- content: await fs.promises.readFile(openApiFilePath, "utf8")
1053
+ content: await readFile(openApiFilePath, "utf8")
1049
1054
  }
1050
1055
  }));
1051
1056
  if (this.config.openApi?.verbose) {
@@ -1109,7 +1114,7 @@ var ExpressServer = class {
1109
1114
  const healthCheckPath = this.normalizePath(this.config.healthCheck?.path || "/healthz", this.config.healthCheck?.withGlobalPrefix);
1110
1115
  this.app.get(healthCheckPath, async (_req, res) => {
1111
1116
  try {
1112
- if (!this.healthChecks.length || defaultCatbeeConfig.server.skipHealthz) {
1117
+ if (!this.healthChecks.length || getCatbeeServerGlobalConfig().skipHealthz) {
1113
1118
  return res.status(HttpStatusCodes.OK).json(new SuccessResponse("OK"));
1114
1119
  }
1115
1120
  const checkResults = await Promise.allSettled(this.healthChecks.map(async ({ name, check }) => {
@@ -1208,7 +1213,7 @@ var ExpressServer = class {
1208
1213
  */
1209
1214
  async ready() {
1210
1215
  try {
1211
- if (!this.healthChecks.length || defaultCatbeeConfig.server.skipHealthz) return true;
1216
+ if (!this.healthChecks.length || getCatbeeServerGlobalConfig().skipHealthz) return true;
1212
1217
  const checkResults = await Promise.allSettled(this.healthChecks.map(async ({ name, check }) => {
1213
1218
  try {
1214
1219
  const status = await Promise.resolve(check());
@@ -1297,11 +1302,11 @@ var ExpressServer = class {
1297
1302
  if (this.config.https) {
1298
1303
  const httpsOptions = {
1299
1304
  ...this.config.https,
1300
- key: fs.readFileSync(this.config.https.key),
1301
- cert: fs.readFileSync(this.config.https.cert)
1305
+ key: readFileSync(this.config.https.key),
1306
+ cert: readFileSync(this.config.https.cert)
1302
1307
  };
1303
1308
  if (this.config.https.ca) {
1304
- httpsOptions.ca = fs.readFileSync(this.config.https.ca);
1309
+ httpsOptions.ca = readFileSync(this.config.https.ca);
1305
1310
  }
1306
1311
  if (this.config.https.passphrase) {
1307
1312
  httpsOptions.passphrase = this.config.https.passphrase;
@@ -1526,7 +1531,7 @@ var ExpressServer = class {
1526
1531
  /**
1527
1532
  * Get server configuration
1528
1533
  *
1529
- * @return {*} {ServerConfig}
1534
+ * @return {*} {CatbeeServerConfig}
1530
1535
  */
1531
1536
  getConfig() {
1532
1537
  return this.config;
@@ -1600,7 +1605,7 @@ var ExpressServer = class {
1600
1605
  throw new Error(msg);
1601
1606
  }
1602
1607
  }
1603
- isBuiltServerConfig(config) {
1608
+ hasBuildMarker(config) {
1604
1609
  if (config?.[BUILD_MARKER]) {
1605
1610
  return true;
1606
1611
  }
package/stream/index.d.ts CHANGED
@@ -22,4 +22,93 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- export * from './stream.utils';
25
+ import { Readable, Transform } from 'node:stream';
26
+ import { BufferEncoding } from '@catbee/utils/crypto';
27
+
28
+ /**
29
+ * Convert a buffer or string to a readable stream.
30
+ *
31
+ * @param data - Buffer or string to convert
32
+ * @returns Readable stream containing the data
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const stream = bufferToStream(Buffer.from('Hello world'));
37
+ * // or
38
+ * const stream = bufferToStream('Hello world');
39
+ * ```
40
+ */
41
+ declare function bufferToStream(data: Buffer | string): Readable;
42
+ /**
43
+ * Convert a readable stream to a buffer.
44
+ *
45
+ * @param stream - Readable stream to convert
46
+ * @returns Promise resolving to a buffer containing all stream data
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const buffer = await streamToBuffer(fs.createReadStream('file.txt'));
51
+ * console.log(buffer.toString()); // Contents of file.txt
52
+ * ```
53
+ */
54
+ declare function streamToBuffer(stream: Readable): Promise<Buffer>;
55
+ /**
56
+ * Convert a readable stream to a string.
57
+ *
58
+ * @param stream - Readable stream to convert
59
+ * @param encoding - Character encoding (default: 'utf8')
60
+ * @returns Promise resolving to a string containing all stream data
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const content = await streamToString(fs.createReadStream('file.txt'));
65
+ * console.log(content); // Contents of file.txt as string
66
+ * ```
67
+ */
68
+ declare function streamToString(stream: Readable, encoding?: BufferEncoding): Promise<string>;
69
+ /**
70
+ * Create a transform stream that limits the rate of data flow.
71
+ *
72
+ * @param bytesPerSecond - Maximum bytes per second
73
+ * @returns Transform stream that throttles data flow
74
+ */
75
+ declare function createThrottleStream(bytesPerSecond: number): Transform;
76
+ /**
77
+ * Create a transform stream that batches data into chunks of specified size.
78
+ *
79
+ * @param size - Size of each batch (items for object mode, bytes for binary mode)
80
+ * @param options - Stream options
81
+ * @returns Transform stream that batches data
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * // Batch lines from a file into arrays of 100 lines each
86
+ * createReadStream('large-file.txt')
87
+ * .pipe(createLineStream())
88
+ * .pipe(createBatchStream(100))
89
+ * .on('data', batch => console.log(`Processing batch of ${batch.length} lines`));
90
+ * ```
91
+ */
92
+ declare function createBatchStream(size: number, options?: {
93
+ objectMode?: boolean;
94
+ }): Transform;
95
+ /**
96
+ * Create a transform stream that splits text data by newlines.
97
+ *
98
+ * @param options - Options for the line stream
99
+ * @returns Transform stream that emits lines
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * // Process a file line by line
104
+ * createReadStream('file.txt')
105
+ * .pipe(createLineStream())
106
+ * .on('data', line => console.log(`Line: ${line}`));
107
+ * ```
108
+ */
109
+ declare function createLineStream(options?: {
110
+ encoding?: BufferEncoding;
111
+ includeNewlines?: boolean;
112
+ }): Transform;
113
+
114
+ export { bufferToStream, createBatchStream, createLineStream, createThrottleStream, streamToBuffer, streamToString };
package/string/index.d.ts CHANGED
@@ -22,4 +22,105 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- export * from './string.utils';
25
+ /**
26
+ * Capitalizes the first character of a string.
27
+ *
28
+ * @param {string} str - The input string.
29
+ * @returns {string} The string with the first character in uppercase.
30
+ */
31
+ declare function capitalize(str: string): string;
32
+ /**
33
+ * Converts a string to kebab-case (e.g., "FooBar test" -> "foo-bar-test").
34
+ *
35
+ * @param {string} str - The input string.
36
+ * @returns {string} The kebab-cased string.
37
+ */
38
+ declare function toKebabCase(str: string): string;
39
+ /**
40
+ * Converts a kebab-case or snake_case string to camelCase.
41
+ *
42
+ * @param {string} str - The input string.
43
+ * @returns {string} The camelCased string.
44
+ */
45
+ declare function toCamelCase(str: string): string;
46
+ /**
47
+ * Converts a string to a URL-friendly slug (lowercase, dashes, alphanumeric).
48
+ *
49
+ * @param {string} str - The input string.
50
+ * @returns {string} The slugified string.
51
+ */
52
+ declare function slugify(str: string): string;
53
+ /**
54
+ * Truncates a string to a specific length, appending '...' if truncated.
55
+ *
56
+ * @param {string} str - The input string.
57
+ * @param {number} len - The maximum length.
58
+ * @returns {string} The truncated string.
59
+ */
60
+ declare function truncate(str: string, len: number): string;
61
+ /**
62
+ * Converts a string to PascalCase (e.g., "foo-bar" -> "FooBar").
63
+ *
64
+ * @param {string} str - The input string.
65
+ * @returns {string} The PascalCased string.
66
+ */
67
+ declare function toPascalCase(str: string): string;
68
+ /**
69
+ * Converts a string to snake_case (e.g., "FooBar test" -> "foo_bar_test").
70
+ *
71
+ * @param {string} str - The input string.
72
+ * @returns {string} The snake_cased string.
73
+ */
74
+ declare function toSnakeCase(str: string): string;
75
+ /**
76
+ * Masks a string by replacing characters with a mask character.
77
+ * Useful for hiding sensitive information like credit cards or passwords.
78
+ *
79
+ * @param {string} str - The string to mask.
80
+ * @param {number} [visibleStart=0] - Number of characters to show at start.
81
+ * @param {number} [visibleEnd=0] - Number of characters to show at end.
82
+ * @param {string} [maskChar="*"] - Character to use for masking.
83
+ * @returns {string} The masked string.
84
+ */
85
+ declare function mask(str: string, visibleStart?: number, visibleEnd?: number, maskChar?: string): string;
86
+ /**
87
+ * Removes all HTML tags from a string.
88
+ *
89
+ * @param {string} str - The HTML string to process.
90
+ * @returns {string} The string with HTML tags removed.
91
+ */
92
+ declare function stripHtml(str: string): string;
93
+ /**
94
+ * Performs case-insensitive string comparison.
95
+ *
96
+ * @param {string} a - First string.
97
+ * @param {string} b - Second string.
98
+ * @returns {boolean} True if the strings are equal ignoring case.
99
+ */
100
+ declare function equalsIgnoreCase(a: string, b: string): boolean;
101
+ /**
102
+ * Reverses a string.
103
+ *
104
+ * @param {string} str - The string to reverse.
105
+ * @returns {string} The reversed string.
106
+ */
107
+ declare function reverse(str: string): string;
108
+ /**
109
+ * Counts occurrences of a substring within a string.
110
+ *
111
+ * @param {string} str - The source string.
112
+ * @param {string} substring - The substring to count.
113
+ * @param {boolean} [caseSensitive=true] - Whether to perform case-sensitive counting.
114
+ * @returns {number} Number of occurrences.
115
+ */
116
+ declare function countOccurrences(str: string, substring: string, caseSensitive?: boolean): number;
117
+ /**
118
+ * Convert a string to Title Case (each word capitalized).
119
+ * Preserves existing spacing and punctuation between words.
120
+ *
121
+ * @param str - Input string
122
+ * @returns Title-cased string
123
+ */
124
+ declare function toTitleCase(str: string): string;
125
+
126
+ export { capitalize, countOccurrences, equalsIgnoreCase, mask, reverse, slugify, stripHtml, toCamelCase, toKebabCase, toPascalCase, toSnakeCase, toTitleCase, truncate };
package/type/index.cjs CHANGED
@@ -73,7 +73,7 @@ function toNum(value, defaultValue = 0) {
73
73
  if (typeof value === "number") return value;
74
74
  try {
75
75
  const num = Number(value);
76
- return isNaN(num) ? defaultValue : num;
76
+ return Number.isNaN(num) ? defaultValue : num;
77
77
  } catch {
78
78
  return defaultValue;
79
79
  }
package/type/index.d.ts CHANGED
@@ -22,4 +22,110 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- export * from './type.utils';
25
+ /**
26
+ * Check if a value is of a specific primitive type.
27
+ *
28
+ * @param value - Value to check
29
+ * @param type - Type to check against
30
+ * @returns Whether the value is of the specified type
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * isPrimitiveType('hello', 'string'); // true
35
+ * isPrimitiveType(42, 'number'); // true
36
+ * isPrimitiveType(true, 'boolean'); // true
37
+ * isPrimitiveType(null, 'null'); // true
38
+ * isPrimitiveType(undefined, 'undefined'); // true
39
+ * isPrimitiveType({}, 'object'); // true
40
+ * isPrimitiveType([], 'array'); // true
41
+ * ```
42
+ */
43
+ declare function isPrimitiveType(value: unknown, type: 'string' | 'number' | 'boolean' | 'symbol' | 'bigint' | 'function' | 'object' | 'array' | 'null' | 'undefined'): boolean;
44
+ /**
45
+ * Get the primitive type of a value as a string.
46
+ *
47
+ * @param value - Value to get the type of
48
+ * @returns String representing the type
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * getTypeOf('hello'); // 'string'
53
+ * getTypeOf(42); // 'number'
54
+ * getTypeOf([]); // 'array'
55
+ * getTypeOf(null); // 'null'
56
+ * ```
57
+ */
58
+ declare function getTypeOf(value: unknown): string;
59
+ /**
60
+ * Type guard for checking if a value is an array of a specific type.
61
+ *
62
+ * @param value - Value to check
63
+ * @param itemTypeGuard - Function that checks if items are of the expected type
64
+ * @returns True if the value is an array with items of the expected type
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * isArrayOf([1, 2, 3], (item): item is number => typeof item === 'number'); // true
69
+ * isArrayOf(['a', 'b', 'c'], (item): item is string => typeof item === 'string'); // true
70
+ * isArrayOf([1, '2', 3], (item): item is number => typeof item === 'number'); // false
71
+ * ```
72
+ */
73
+ declare function isArrayOf<T>(value: unknown, itemTypeGuard: (item: unknown) => item is T): value is T[];
74
+ /**
75
+ * Convert a value to a string.
76
+ *
77
+ * @param value - Value to convert
78
+ * @param defaultValue - Default value if conversion fails
79
+ * @returns String representation of the value
80
+ */
81
+ declare function toStr(value: unknown, defaultValue?: string): string;
82
+ /**
83
+ * Convert a value to a number.
84
+ *
85
+ * @param value - Value to convert
86
+ * @param defaultValue - Default value if conversion fails
87
+ * @returns Numeric representation of the value
88
+ */
89
+ declare function toNum(value: unknown, defaultValue?: number): number;
90
+ /**
91
+ * Convert a value to a boolean.
92
+ *
93
+ * @param value - Value to convert
94
+ * @param defaultValue - Default value if conversion fails
95
+ * @returns Boolean representation of the value
96
+ */
97
+ declare function toBool(value: unknown, defaultValue?: boolean): boolean;
98
+ /**
99
+ * Ensure a value matches the expected type, or provide a default.
100
+ *
101
+ * @param value - Value to check
102
+ * @param expectedType - Expected primitive type
103
+ * @param defaultValue - Default value to use if type doesn't match
104
+ * @returns The value if it matches the type, otherwise the default
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * ensureType(42, 'number', 0); // 42
109
+ * ensureType('42', 'number', 0); // 0
110
+ * ensureType(undefined, 'string', 'default'); // 'default'
111
+ * ```
112
+ */
113
+ declare function ensureType<T>(value: unknown, expectedType: string, defaultValue: T): T;
114
+ /**
115
+ * Check whether a value is neither null nor undefined.
116
+ * Useful in filter chains and guards.
117
+ *
118
+ * @param value - Value to check
119
+ * @returns True when value !== null && value !== undefined
120
+ */
121
+ declare function isDefined<T>(value: T | null | undefined): value is T;
122
+ /**
123
+ * Check whether a value is empty.
124
+ * Supports strings, arrays, maps, sets and plain objects.
125
+ *
126
+ * @param value - Value to inspect
127
+ * @returns True when value is considered empty
128
+ */
129
+ declare function isEmpty(value: any): boolean;
130
+
131
+ export { ensureType, getTypeOf, isArrayOf, isDefined, isEmpty, isPrimitiveType, toBool, toNum, toStr };
package/type/index.mjs CHANGED
@@ -71,7 +71,7 @@ function toNum(value, defaultValue = 0) {
71
71
  if (typeof value === "number") return value;
72
72
  try {
73
73
  const num = Number(value);
74
- return isNaN(num) ? defaultValue : num;
74
+ return Number.isNaN(num) ? defaultValue : num;
75
75
  } catch {
76
76
  return defaultValue;
77
77
  }