ts-data-forge 1.0.0 → 1.0.2
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.
- package/README.md +1 -1
- package/dist/array/array-utils.d.mts +2617 -0
- package/dist/array/array-utils.d.mts.map +1 -0
- package/dist/array/array-utils.mjs +2915 -0
- package/dist/array/array-utils.mjs.map +1 -0
- package/dist/array/index.d.mts +3 -0
- package/dist/array/index.d.mts.map +1 -0
- package/dist/array/index.mjs +3 -0
- package/dist/array/index.mjs.map +1 -0
- package/dist/array/tuple-utils.d.mts +421 -0
- package/dist/array/tuple-utils.d.mts.map +1 -0
- package/dist/array/tuple-utils.mjs +391 -0
- package/dist/array/tuple-utils.mjs.map +1 -0
- package/dist/collections/imap-mapped.d.mts +445 -0
- package/dist/collections/imap-mapped.d.mts.map +1 -0
- package/dist/collections/imap-mapped.mjs +424 -0
- package/dist/collections/imap-mapped.mjs.map +1 -0
- package/dist/collections/imap.d.mts +359 -0
- package/dist/collections/imap.d.mts.map +1 -0
- package/dist/collections/imap.mjs +338 -0
- package/dist/collections/imap.mjs.map +1 -0
- package/dist/collections/index.d.mts +7 -0
- package/dist/collections/index.d.mts.map +1 -0
- package/dist/collections/index.mjs +7 -0
- package/dist/collections/index.mjs.map +1 -0
- package/dist/collections/iset-mapped.d.mts +576 -0
- package/dist/collections/iset-mapped.d.mts.map +1 -0
- package/dist/collections/iset-mapped.mjs +522 -0
- package/dist/collections/iset-mapped.mjs.map +1 -0
- package/dist/collections/iset.d.mts +426 -0
- package/dist/collections/iset.d.mts.map +1 -0
- package/dist/collections/iset.mjs +437 -0
- package/dist/collections/iset.mjs.map +1 -0
- package/dist/collections/queue.d.mts +190 -0
- package/dist/collections/queue.d.mts.map +1 -0
- package/dist/collections/queue.mjs +317 -0
- package/dist/collections/queue.mjs.map +1 -0
- package/dist/collections/stack.d.mts +210 -0
- package/dist/collections/stack.d.mts.map +1 -0
- package/dist/collections/stack.mjs +353 -0
- package/dist/collections/stack.mjs.map +1 -0
- package/dist/expect-type.d.mts +199 -0
- package/dist/expect-type.d.mts.map +1 -0
- package/dist/expect-type.mjs +201 -0
- package/dist/expect-type.mjs.map +1 -0
- package/dist/functional/index.d.mts +5 -0
- package/dist/functional/index.d.mts.map +1 -0
- package/dist/functional/index.mjs +5 -0
- package/dist/functional/index.mjs.map +1 -0
- package/dist/functional/match.d.mts +215 -0
- package/dist/functional/match.d.mts.map +1 -0
- package/dist/functional/match.mjs +139 -0
- package/dist/functional/match.mjs.map +1 -0
- package/dist/functional/optional.d.mts +517 -0
- package/dist/functional/optional.d.mts.map +1 -0
- package/dist/functional/optional.mjs +532 -0
- package/dist/functional/optional.mjs.map +1 -0
- package/dist/functional/pipe.d.mts +185 -0
- package/dist/functional/pipe.d.mts.map +1 -0
- package/dist/functional/pipe.mjs +129 -0
- package/dist/functional/pipe.mjs.map +1 -0
- package/dist/functional/result.d.mts +796 -0
- package/dist/functional/result.d.mts.map +1 -0
- package/dist/functional/result.mjs +844 -0
- package/dist/functional/result.mjs.map +1 -0
- package/dist/globals.d.mts +38 -0
- package/dist/guard/has-key.d.mts +100 -0
- package/dist/guard/has-key.d.mts.map +1 -0
- package/dist/guard/has-key.mjs +94 -0
- package/dist/guard/has-key.mjs.map +1 -0
- package/dist/guard/index.d.mts +8 -0
- package/dist/guard/index.d.mts.map +1 -0
- package/dist/guard/index.mjs +8 -0
- package/dist/guard/index.mjs.map +1 -0
- package/dist/guard/is-non-empty-string.d.mts +106 -0
- package/dist/guard/is-non-empty-string.d.mts.map +1 -0
- package/dist/guard/is-non-empty-string.mjs +108 -0
- package/dist/guard/is-non-empty-string.mjs.map +1 -0
- package/dist/guard/is-non-null-object.d.mts +105 -0
- package/dist/guard/is-non-null-object.d.mts.map +1 -0
- package/dist/guard/is-non-null-object.mjs +108 -0
- package/dist/guard/is-non-null-object.mjs.map +1 -0
- package/dist/guard/is-primitive.d.mts +146 -0
- package/dist/guard/is-primitive.d.mts.map +1 -0
- package/dist/guard/is-primitive.mjs +161 -0
- package/dist/guard/is-primitive.mjs.map +1 -0
- package/dist/guard/is-record.d.mts +151 -0
- package/dist/guard/is-record.d.mts.map +1 -0
- package/dist/guard/is-record.mjs +155 -0
- package/dist/guard/is-record.mjs.map +1 -0
- package/dist/guard/is-type.d.mts +430 -0
- package/dist/guard/is-type.d.mts.map +1 -0
- package/dist/guard/is-type.mjs +432 -0
- package/dist/guard/is-type.mjs.map +1 -0
- package/dist/guard/key-is-in.d.mts +158 -0
- package/dist/guard/key-is-in.d.mts.map +1 -0
- package/dist/guard/key-is-in.mjs +160 -0
- package/dist/guard/key-is-in.mjs.map +1 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +61 -0
- package/dist/index.mjs.map +1 -0
- package/dist/iterator/index.d.mts +2 -0
- package/dist/iterator/index.d.mts.map +1 -0
- package/dist/iterator/index.mjs +2 -0
- package/dist/iterator/index.mjs.map +1 -0
- package/dist/iterator/range.d.mts +97 -0
- package/dist/iterator/range.d.mts.map +1 -0
- package/dist/iterator/range.mjs +130 -0
- package/dist/iterator/range.mjs.map +1 -0
- package/dist/json/index.d.mts +2 -0
- package/dist/json/index.d.mts.map +1 -0
- package/dist/json/index.mjs +2 -0
- package/dist/json/index.mjs.map +1 -0
- package/dist/json/json.d.mts +597 -0
- package/dist/json/json.d.mts.map +1 -0
- package/dist/json/json.mjs +687 -0
- package/dist/json/json.mjs.map +1 -0
- package/dist/number/branded-types/finite-number.d.mts +291 -0
- package/dist/number/branded-types/finite-number.d.mts.map +1 -0
- package/dist/number/branded-types/finite-number.mjs +296 -0
- package/dist/number/branded-types/finite-number.mjs.map +1 -0
- package/dist/number/branded-types/index.d.mts +27 -0
- package/dist/number/branded-types/index.d.mts.map +1 -0
- package/dist/number/branded-types/index.mjs +27 -0
- package/dist/number/branded-types/index.mjs.map +1 -0
- package/dist/number/branded-types/int.d.mts +242 -0
- package/dist/number/branded-types/int.d.mts.map +1 -0
- package/dist/number/branded-types/int.mjs +239 -0
- package/dist/number/branded-types/int.mjs.map +1 -0
- package/dist/number/branded-types/int16.d.mts +162 -0
- package/dist/number/branded-types/int16.d.mts.map +1 -0
- package/dist/number/branded-types/int16.mjs +141 -0
- package/dist/number/branded-types/int16.mjs.map +1 -0
- package/dist/number/branded-types/int32.d.mts +155 -0
- package/dist/number/branded-types/int32.d.mts.map +1 -0
- package/dist/number/branded-types/int32.mjs +142 -0
- package/dist/number/branded-types/int32.mjs.map +1 -0
- package/dist/number/branded-types/non-negative-finite-number.d.mts +165 -0
- package/dist/number/branded-types/non-negative-finite-number.d.mts.map +1 -0
- package/dist/number/branded-types/non-negative-finite-number.mjs +160 -0
- package/dist/number/branded-types/non-negative-finite-number.mjs.map +1 -0
- package/dist/number/branded-types/non-negative-int16.d.mts +160 -0
- package/dist/number/branded-types/non-negative-int16.d.mts.map +1 -0
- package/dist/number/branded-types/non-negative-int16.mjs +138 -0
- package/dist/number/branded-types/non-negative-int16.mjs.map +1 -0
- package/dist/number/branded-types/non-negative-int32.d.mts +156 -0
- package/dist/number/branded-types/non-negative-int32.d.mts.map +1 -0
- package/dist/number/branded-types/non-negative-int32.mjs +138 -0
- package/dist/number/branded-types/non-negative-int32.mjs.map +1 -0
- package/dist/number/branded-types/non-zero-finite-number.d.mts +154 -0
- package/dist/number/branded-types/non-zero-finite-number.d.mts.map +1 -0
- package/dist/number/branded-types/non-zero-finite-number.mjs +160 -0
- package/dist/number/branded-types/non-zero-finite-number.mjs.map +1 -0
- package/dist/number/branded-types/non-zero-int.d.mts +131 -0
- package/dist/number/branded-types/non-zero-int.d.mts.map +1 -0
- package/dist/number/branded-types/non-zero-int.mjs +128 -0
- package/dist/number/branded-types/non-zero-int.mjs.map +1 -0
- package/dist/number/branded-types/non-zero-int16.d.mts +166 -0
- package/dist/number/branded-types/non-zero-int16.d.mts.map +1 -0
- package/dist/number/branded-types/non-zero-int16.mjs +145 -0
- package/dist/number/branded-types/non-zero-int16.mjs.map +1 -0
- package/dist/number/branded-types/non-zero-int32.d.mts +158 -0
- package/dist/number/branded-types/non-zero-int32.d.mts.map +1 -0
- package/dist/number/branded-types/non-zero-int32.mjs +145 -0
- package/dist/number/branded-types/non-zero-int32.mjs.map +1 -0
- package/dist/number/branded-types/non-zero-safe-int.d.mts +148 -0
- package/dist/number/branded-types/non-zero-safe-int.d.mts.map +1 -0
- package/dist/number/branded-types/non-zero-safe-int.mjs +145 -0
- package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -0
- package/dist/number/branded-types/non-zero-uint16.d.mts +160 -0
- package/dist/number/branded-types/non-zero-uint16.d.mts.map +1 -0
- package/dist/number/branded-types/non-zero-uint16.mjs +140 -0
- package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -0
- package/dist/number/branded-types/non-zero-uint32.d.mts +156 -0
- package/dist/number/branded-types/non-zero-uint32.d.mts.map +1 -0
- package/dist/number/branded-types/non-zero-uint32.mjs +140 -0
- package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -0
- package/dist/number/branded-types/positive-finite-number.d.mts +171 -0
- package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -0
- package/dist/number/branded-types/positive-finite-number.mjs +165 -0
- package/dist/number/branded-types/positive-finite-number.mjs.map +1 -0
- package/dist/number/branded-types/positive-int.d.mts +270 -0
- package/dist/number/branded-types/positive-int.d.mts.map +1 -0
- package/dist/number/branded-types/positive-int.mjs +257 -0
- package/dist/number/branded-types/positive-int.mjs.map +1 -0
- package/dist/number/branded-types/positive-int16.d.mts +162 -0
- package/dist/number/branded-types/positive-int16.d.mts.map +1 -0
- package/dist/number/branded-types/positive-int16.mjs +139 -0
- package/dist/number/branded-types/positive-int16.mjs.map +1 -0
- package/dist/number/branded-types/positive-int32.d.mts +158 -0
- package/dist/number/branded-types/positive-int32.d.mts.map +1 -0
- package/dist/number/branded-types/positive-int32.mjs +139 -0
- package/dist/number/branded-types/positive-int32.mjs.map +1 -0
- package/dist/number/branded-types/positive-safe-int.d.mts +152 -0
- package/dist/number/branded-types/positive-safe-int.d.mts.map +1 -0
- package/dist/number/branded-types/positive-safe-int.mjs +138 -0
- package/dist/number/branded-types/positive-safe-int.mjs.map +1 -0
- package/dist/number/branded-types/positive-uint16.d.mts +160 -0
- package/dist/number/branded-types/positive-uint16.d.mts.map +1 -0
- package/dist/number/branded-types/positive-uint16.mjs +139 -0
- package/dist/number/branded-types/positive-uint16.mjs.map +1 -0
- package/dist/number/branded-types/positive-uint32.d.mts +156 -0
- package/dist/number/branded-types/positive-uint32.d.mts.map +1 -0
- package/dist/number/branded-types/positive-uint32.mjs +139 -0
- package/dist/number/branded-types/positive-uint32.mjs.map +1 -0
- package/dist/number/branded-types/safe-int.d.mts +243 -0
- package/dist/number/branded-types/safe-int.d.mts.map +1 -0
- package/dist/number/branded-types/safe-int.mjs +240 -0
- package/dist/number/branded-types/safe-int.mjs.map +1 -0
- package/dist/number/branded-types/safe-uint.d.mts +151 -0
- package/dist/number/branded-types/safe-uint.d.mts.map +1 -0
- package/dist/number/branded-types/safe-uint.mjs +138 -0
- package/dist/number/branded-types/safe-uint.mjs.map +1 -0
- package/dist/number/branded-types/uint.d.mts +144 -0
- package/dist/number/branded-types/uint.d.mts.map +1 -0
- package/dist/number/branded-types/uint.mjs +132 -0
- package/dist/number/branded-types/uint.mjs.map +1 -0
- package/dist/number/branded-types/uint16.d.mts +157 -0
- package/dist/number/branded-types/uint16.d.mts.map +1 -0
- package/dist/number/branded-types/uint16.mjs +137 -0
- package/dist/number/branded-types/uint16.mjs.map +1 -0
- package/dist/number/branded-types/uint32.d.mts +185 -0
- package/dist/number/branded-types/uint32.d.mts.map +1 -0
- package/dist/number/branded-types/uint32.mjs +169 -0
- package/dist/number/branded-types/uint32.mjs.map +1 -0
- package/dist/number/enum/index.d.mts +3 -0
- package/dist/number/enum/index.d.mts.map +1 -0
- package/dist/number/enum/index.mjs +3 -0
- package/dist/number/enum/index.mjs.map +1 -0
- package/dist/number/enum/int8.d.mts +202 -0
- package/dist/number/enum/int8.d.mts.map +1 -0
- package/dist/number/enum/int8.mjs +296 -0
- package/dist/number/enum/int8.mjs.map +1 -0
- package/dist/number/enum/uint8.d.mts +128 -0
- package/dist/number/enum/uint8.d.mts.map +1 -0
- package/dist/number/enum/uint8.mjs +251 -0
- package/dist/number/enum/uint8.mjs.map +1 -0
- package/dist/number/index.d.mts +5 -0
- package/dist/number/index.d.mts.map +1 -0
- package/dist/number/index.mjs +31 -0
- package/dist/number/index.mjs.map +1 -0
- package/dist/number/num.d.mts +515 -0
- package/dist/number/num.d.mts.map +1 -0
- package/dist/number/num.mjs +513 -0
- package/dist/number/num.mjs.map +1 -0
- package/dist/number/refined-number-utils.d.mts +191 -0
- package/dist/number/refined-number-utils.d.mts.map +1 -0
- package/dist/number/refined-number-utils.mjs +179 -0
- package/dist/number/refined-number-utils.mjs.map +1 -0
- package/dist/object/index.d.mts +2 -0
- package/dist/object/index.d.mts.map +1 -0
- package/dist/object/index.mjs +2 -0
- package/dist/object/index.mjs.map +1 -0
- package/dist/object/object.d.mts +296 -0
- package/dist/object/object.d.mts.map +1 -0
- package/dist/object/object.mjs +295 -0
- package/dist/object/object.mjs.map +1 -0
- package/dist/others/cast-mutable.d.mts +110 -0
- package/dist/others/cast-mutable.d.mts.map +1 -0
- package/dist/others/cast-mutable.mjs +114 -0
- package/dist/others/cast-mutable.mjs.map +1 -0
- package/dist/others/cast-readonly.d.mts +189 -0
- package/dist/others/cast-readonly.d.mts.map +1 -0
- package/dist/others/cast-readonly.mjs +193 -0
- package/dist/others/cast-readonly.mjs.map +1 -0
- package/dist/others/if-then.d.mts +98 -0
- package/dist/others/if-then.d.mts.map +1 -0
- package/dist/others/if-then.mjs +100 -0
- package/dist/others/if-then.mjs.map +1 -0
- package/dist/others/index.d.mts +8 -0
- package/dist/others/index.d.mts.map +1 -0
- package/dist/others/index.mjs +8 -0
- package/dist/others/index.mjs.map +1 -0
- package/dist/others/map-nullable.d.mts +151 -0
- package/dist/others/map-nullable.d.mts.map +1 -0
- package/dist/others/map-nullable.mjs +159 -0
- package/dist/others/map-nullable.mjs.map +1 -0
- package/dist/others/memoize-function.d.mts +173 -0
- package/dist/others/memoize-function.d.mts.map +1 -0
- package/dist/others/memoize-function.mjs +189 -0
- package/dist/others/memoize-function.mjs.map +1 -0
- package/dist/others/tuple.d.mts +159 -0
- package/dist/others/tuple.d.mts.map +1 -0
- package/dist/others/tuple.mjs +161 -0
- package/dist/others/tuple.mjs.map +1 -0
- package/dist/others/unknown-to-string.d.mts +180 -0
- package/dist/others/unknown-to-string.d.mts.map +1 -0
- package/dist/others/unknown-to-string.mjs +211 -0
- package/dist/others/unknown-to-string.mjs.map +1 -0
- package/dist/tsconfig.json +1 -0
- package/package.json +18 -16
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Result } from '../functional/index.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Converts an unknown value to its string representation in a type-safe manner.
|
|
4
|
+
*
|
|
5
|
+
* This function handles all JavaScript types and provides consistent string conversion
|
|
6
|
+
* with proper error handling for edge cases like circular references. Unlike naive
|
|
7
|
+
* toString() calls, this function never throws and handles all value types gracefully.
|
|
8
|
+
*
|
|
9
|
+
* **Type conversion rules:**
|
|
10
|
+
* - Strings: returned as-is
|
|
11
|
+
* - Numbers, booleans, bigints: converted via toString()
|
|
12
|
+
* - Symbols: converted to their description string
|
|
13
|
+
* - Functions: converted to their string representation
|
|
14
|
+
* - null: returns "null" (not "null" from JSON)
|
|
15
|
+
* - undefined: returns "undefined"
|
|
16
|
+
* - Objects: JSON stringified (with optional pretty printing)
|
|
17
|
+
*
|
|
18
|
+
* @param value - The unknown value to convert to string
|
|
19
|
+
* @param options - Optional configuration for the conversion
|
|
20
|
+
* @param options.prettyPrintObject - If true, objects are formatted with 2-space indentation
|
|
21
|
+
* @returns A Result containing either the string representation or an Error for failures
|
|
22
|
+
*
|
|
23
|
+
* @example Basic type conversions
|
|
24
|
+
* ```typescript
|
|
25
|
+
* // Primitive types
|
|
26
|
+
* unknownToString('hello'); // Ok('hello')
|
|
27
|
+
* unknownToString(123); // Ok('123')
|
|
28
|
+
* unknownToString(true); // Ok('true')
|
|
29
|
+
* unknownToString(null); // Ok('null')
|
|
30
|
+
* unknownToString(undefined); // Ok('undefined')
|
|
31
|
+
* unknownToString(Symbol('test')); // Ok('Symbol(test)')
|
|
32
|
+
* unknownToString(123n); // Ok('123')
|
|
33
|
+
*
|
|
34
|
+
* // Function conversion
|
|
35
|
+
* const fn = () => 'test';
|
|
36
|
+
* unknownToString(fn); // Ok('() => 'test'')
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example Object stringification
|
|
40
|
+
* ```typescript
|
|
41
|
+
* // Simple object
|
|
42
|
+
* const obj = { a: 1, b: 'hello', c: [1, 2, 3] };
|
|
43
|
+
* const result = unknownToString(obj);
|
|
44
|
+
* if (Result.isOk(result)) {
|
|
45
|
+
* console.log(result.value); // '{"a":1,"b":"hello","c":[1,2,3]}'
|
|
46
|
+
* }
|
|
47
|
+
*
|
|
48
|
+
* // Pretty printing
|
|
49
|
+
* const prettyResult = unknownToString(obj, { prettyPrintObject: true });
|
|
50
|
+
* if (Result.isOk(prettyResult)) {
|
|
51
|
+
* console.log(prettyResult.value);
|
|
52
|
+
* // {
|
|
53
|
+
* // "a": 1,
|
|
54
|
+
* // "b": "hello",
|
|
55
|
+
* // "c": [
|
|
56
|
+
* // 1,
|
|
57
|
+
* // 2,
|
|
58
|
+
* // 3
|
|
59
|
+
* // ]
|
|
60
|
+
* // }
|
|
61
|
+
* }
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @example Error handling for circular references
|
|
65
|
+
* ```typescript
|
|
66
|
+
* // Circular reference
|
|
67
|
+
* const circular: any = { name: 'parent' };
|
|
68
|
+
* circular.self = circular;
|
|
69
|
+
*
|
|
70
|
+
* const result = unknownToString(circular);
|
|
71
|
+
* if (Result.isErr(result)) {
|
|
72
|
+
* console.log(result.value.message);
|
|
73
|
+
* // "Converting circular structure to JSON"
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* // Handle with custom serialization
|
|
77
|
+
* const safeStringify = (value: unknown): string => {
|
|
78
|
+
* const result = unknownToString(value);
|
|
79
|
+
* return Result.isOk(result)
|
|
80
|
+
* ? result.value
|
|
81
|
+
* : `[Error: ${result.value.message}]`;
|
|
82
|
+
* };
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @example Logging and debugging utilities
|
|
86
|
+
* ```typescript
|
|
87
|
+
* // Type-safe logger
|
|
88
|
+
* class Logger {
|
|
89
|
+
* log(message: string, data?: unknown): void {
|
|
90
|
+
* const timestamp = new Date().toISOString();
|
|
91
|
+
* const dataStr = data !== undefined
|
|
92
|
+
* ? unknownToString(data, { prettyPrintObject: true })
|
|
93
|
+
* : Result.ok('');
|
|
94
|
+
*
|
|
95
|
+
* if (Result.isOk(dataStr)) {
|
|
96
|
+
* console.log(`[${timestamp}] ${message}`, dataStr.value);
|
|
97
|
+
* } else {
|
|
98
|
+
* console.log(`[${timestamp}] ${message} [Unstringifiable data]`);
|
|
99
|
+
* }
|
|
100
|
+
* }
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* const logger = new Logger();
|
|
104
|
+
* logger.log('User data:', { id: 123, name: 'John' });
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @example API response formatting
|
|
108
|
+
* ```typescript
|
|
109
|
+
* // Safe error response formatting
|
|
110
|
+
* function formatErrorResponse(error: unknown): string {
|
|
111
|
+
* const result = unknownToString(error, { prettyPrintObject: true });
|
|
112
|
+
*
|
|
113
|
+
* if (Result.isOk(result)) {
|
|
114
|
+
* return JSON.stringify({
|
|
115
|
+
* success: false,
|
|
116
|
+
* error: result.value
|
|
117
|
+
* });
|
|
118
|
+
* }
|
|
119
|
+
*
|
|
120
|
+
* // Fallback for unstringifiable errors
|
|
121
|
+
* return JSON.stringify({
|
|
122
|
+
* success: false,
|
|
123
|
+
* error: 'An unknown error occurred'
|
|
124
|
+
* });
|
|
125
|
+
* }
|
|
126
|
+
*
|
|
127
|
+
* try {
|
|
128
|
+
* // some operation
|
|
129
|
+
* } catch (error) {
|
|
130
|
+
* const response = formatErrorResponse(error);
|
|
131
|
+
* res.status(500).send(response);
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
* @example Working with special objects
|
|
136
|
+
* ```typescript
|
|
137
|
+
* // Date objects
|
|
138
|
+
* unknownToString(new Date('2023-01-01'));
|
|
139
|
+
* // Ok('"2023-01-01T00:00:00.000Z"') - JSON stringified
|
|
140
|
+
*
|
|
141
|
+
* // Regular expressions
|
|
142
|
+
* unknownToString(/test/gi);
|
|
143
|
+
* // Ok('{}') - RegExp has no enumerable properties
|
|
144
|
+
*
|
|
145
|
+
* // Arrays
|
|
146
|
+
* unknownToString([1, 'two', { three: 3 }]);
|
|
147
|
+
* // Ok('[1,"two",{"three":3}]')
|
|
148
|
+
*
|
|
149
|
+
* // Map and Set (converted to empty objects by JSON.stringify)
|
|
150
|
+
* unknownToString(new Map([['a', 1]])); // Ok('{}')
|
|
151
|
+
* unknownToString(new Set([1, 2, 3])); // Ok('{}')
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @example Integration with Result type
|
|
155
|
+
* ```typescript
|
|
156
|
+
* import { Result, pipe } from '../functional';
|
|
157
|
+
*
|
|
158
|
+
* // Chain with other Result operations
|
|
159
|
+
* function processUserInput(input: unknown): Result<string, Error> {
|
|
160
|
+
* return pipe(input)
|
|
161
|
+
* .map(val => unknownToString(val))
|
|
162
|
+
* .map(Result.flatten) // Flatten Result<Result<string, Error>, never>
|
|
163
|
+
* .map(str => Result.map(str, s => s.trim()))
|
|
164
|
+
* .map(Result.flatten)
|
|
165
|
+
* .map(str => Result.flatMap(str, s =>
|
|
166
|
+
* s.length > 0
|
|
167
|
+
* ? Result.ok(s)
|
|
168
|
+
* : Result.err(new Error('Empty string'))
|
|
169
|
+
* ))
|
|
170
|
+
* .value;
|
|
171
|
+
* }
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
174
|
+
* @see Result - For error handling pattern used by this function
|
|
175
|
+
* @see JSON.stringify - Underlying serialization for objects
|
|
176
|
+
*/
|
|
177
|
+
export declare const unknownToString: (value: unknown, options?: Partial<Readonly<{
|
|
178
|
+
prettyPrintObject: boolean;
|
|
179
|
+
}>>) => Result<string, Error>;
|
|
180
|
+
//# sourceMappingURL=unknown-to-string.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unknown-to-string.d.mts","sourceRoot":"","sources":["../../src/others/unknown-to-string.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8KG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,OAAO,EACd,UAAU,OAAO,CAAC,QAAQ,CAAC;IAAE,iBAAiB,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,KAC1D,MAAM,CAAC,MAAM,EAAE,KAAK,CAiCtB,CAAC"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { isNonNullish } from '../guard/is-type.mjs';
|
|
2
|
+
import '../functional/optional.mjs';
|
|
3
|
+
import { Result } from '../functional/result.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Converts an unknown value to its string representation in a type-safe manner.
|
|
7
|
+
*
|
|
8
|
+
* This function handles all JavaScript types and provides consistent string conversion
|
|
9
|
+
* with proper error handling for edge cases like circular references. Unlike naive
|
|
10
|
+
* toString() calls, this function never throws and handles all value types gracefully.
|
|
11
|
+
*
|
|
12
|
+
* **Type conversion rules:**
|
|
13
|
+
* - Strings: returned as-is
|
|
14
|
+
* - Numbers, booleans, bigints: converted via toString()
|
|
15
|
+
* - Symbols: converted to their description string
|
|
16
|
+
* - Functions: converted to their string representation
|
|
17
|
+
* - null: returns "null" (not "null" from JSON)
|
|
18
|
+
* - undefined: returns "undefined"
|
|
19
|
+
* - Objects: JSON stringified (with optional pretty printing)
|
|
20
|
+
*
|
|
21
|
+
* @param value - The unknown value to convert to string
|
|
22
|
+
* @param options - Optional configuration for the conversion
|
|
23
|
+
* @param options.prettyPrintObject - If true, objects are formatted with 2-space indentation
|
|
24
|
+
* @returns A Result containing either the string representation or an Error for failures
|
|
25
|
+
*
|
|
26
|
+
* @example Basic type conversions
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Primitive types
|
|
29
|
+
* unknownToString('hello'); // Ok('hello')
|
|
30
|
+
* unknownToString(123); // Ok('123')
|
|
31
|
+
* unknownToString(true); // Ok('true')
|
|
32
|
+
* unknownToString(null); // Ok('null')
|
|
33
|
+
* unknownToString(undefined); // Ok('undefined')
|
|
34
|
+
* unknownToString(Symbol('test')); // Ok('Symbol(test)')
|
|
35
|
+
* unknownToString(123n); // Ok('123')
|
|
36
|
+
*
|
|
37
|
+
* // Function conversion
|
|
38
|
+
* const fn = () => 'test';
|
|
39
|
+
* unknownToString(fn); // Ok('() => 'test'')
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example Object stringification
|
|
43
|
+
* ```typescript
|
|
44
|
+
* // Simple object
|
|
45
|
+
* const obj = { a: 1, b: 'hello', c: [1, 2, 3] };
|
|
46
|
+
* const result = unknownToString(obj);
|
|
47
|
+
* if (Result.isOk(result)) {
|
|
48
|
+
* console.log(result.value); // '{"a":1,"b":"hello","c":[1,2,3]}'
|
|
49
|
+
* }
|
|
50
|
+
*
|
|
51
|
+
* // Pretty printing
|
|
52
|
+
* const prettyResult = unknownToString(obj, { prettyPrintObject: true });
|
|
53
|
+
* if (Result.isOk(prettyResult)) {
|
|
54
|
+
* console.log(prettyResult.value);
|
|
55
|
+
* // {
|
|
56
|
+
* // "a": 1,
|
|
57
|
+
* // "b": "hello",
|
|
58
|
+
* // "c": [
|
|
59
|
+
* // 1,
|
|
60
|
+
* // 2,
|
|
61
|
+
* // 3
|
|
62
|
+
* // ]
|
|
63
|
+
* // }
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @example Error handling for circular references
|
|
68
|
+
* ```typescript
|
|
69
|
+
* // Circular reference
|
|
70
|
+
* const circular: any = { name: 'parent' };
|
|
71
|
+
* circular.self = circular;
|
|
72
|
+
*
|
|
73
|
+
* const result = unknownToString(circular);
|
|
74
|
+
* if (Result.isErr(result)) {
|
|
75
|
+
* console.log(result.value.message);
|
|
76
|
+
* // "Converting circular structure to JSON"
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* // Handle with custom serialization
|
|
80
|
+
* const safeStringify = (value: unknown): string => {
|
|
81
|
+
* const result = unknownToString(value);
|
|
82
|
+
* return Result.isOk(result)
|
|
83
|
+
* ? result.value
|
|
84
|
+
* : `[Error: ${result.value.message}]`;
|
|
85
|
+
* };
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @example Logging and debugging utilities
|
|
89
|
+
* ```typescript
|
|
90
|
+
* // Type-safe logger
|
|
91
|
+
* class Logger {
|
|
92
|
+
* log(message: string, data?: unknown): void {
|
|
93
|
+
* const timestamp = new Date().toISOString();
|
|
94
|
+
* const dataStr = data !== undefined
|
|
95
|
+
* ? unknownToString(data, { prettyPrintObject: true })
|
|
96
|
+
* : Result.ok('');
|
|
97
|
+
*
|
|
98
|
+
* if (Result.isOk(dataStr)) {
|
|
99
|
+
* console.log(`[${timestamp}] ${message}`, dataStr.value);
|
|
100
|
+
* } else {
|
|
101
|
+
* console.log(`[${timestamp}] ${message} [Unstringifiable data]`);
|
|
102
|
+
* }
|
|
103
|
+
* }
|
|
104
|
+
* }
|
|
105
|
+
*
|
|
106
|
+
* const logger = new Logger();
|
|
107
|
+
* logger.log('User data:', { id: 123, name: 'John' });
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @example API response formatting
|
|
111
|
+
* ```typescript
|
|
112
|
+
* // Safe error response formatting
|
|
113
|
+
* function formatErrorResponse(error: unknown): string {
|
|
114
|
+
* const result = unknownToString(error, { prettyPrintObject: true });
|
|
115
|
+
*
|
|
116
|
+
* if (Result.isOk(result)) {
|
|
117
|
+
* return JSON.stringify({
|
|
118
|
+
* success: false,
|
|
119
|
+
* error: result.value
|
|
120
|
+
* });
|
|
121
|
+
* }
|
|
122
|
+
*
|
|
123
|
+
* // Fallback for unstringifiable errors
|
|
124
|
+
* return JSON.stringify({
|
|
125
|
+
* success: false,
|
|
126
|
+
* error: 'An unknown error occurred'
|
|
127
|
+
* });
|
|
128
|
+
* }
|
|
129
|
+
*
|
|
130
|
+
* try {
|
|
131
|
+
* // some operation
|
|
132
|
+
* } catch (error) {
|
|
133
|
+
* const response = formatErrorResponse(error);
|
|
134
|
+
* res.status(500).send(response);
|
|
135
|
+
* }
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @example Working with special objects
|
|
139
|
+
* ```typescript
|
|
140
|
+
* // Date objects
|
|
141
|
+
* unknownToString(new Date('2023-01-01'));
|
|
142
|
+
* // Ok('"2023-01-01T00:00:00.000Z"') - JSON stringified
|
|
143
|
+
*
|
|
144
|
+
* // Regular expressions
|
|
145
|
+
* unknownToString(/test/gi);
|
|
146
|
+
* // Ok('{}') - RegExp has no enumerable properties
|
|
147
|
+
*
|
|
148
|
+
* // Arrays
|
|
149
|
+
* unknownToString([1, 'two', { three: 3 }]);
|
|
150
|
+
* // Ok('[1,"two",{"three":3}]')
|
|
151
|
+
*
|
|
152
|
+
* // Map and Set (converted to empty objects by JSON.stringify)
|
|
153
|
+
* unknownToString(new Map([['a', 1]])); // Ok('{}')
|
|
154
|
+
* unknownToString(new Set([1, 2, 3])); // Ok('{}')
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* @example Integration with Result type
|
|
158
|
+
* ```typescript
|
|
159
|
+
* import { Result, pipe } from '../functional';
|
|
160
|
+
*
|
|
161
|
+
* // Chain with other Result operations
|
|
162
|
+
* function processUserInput(input: unknown): Result<string, Error> {
|
|
163
|
+
* return pipe(input)
|
|
164
|
+
* .map(val => unknownToString(val))
|
|
165
|
+
* .map(Result.flatten) // Flatten Result<Result<string, Error>, never>
|
|
166
|
+
* .map(str => Result.map(str, s => s.trim()))
|
|
167
|
+
* .map(Result.flatten)
|
|
168
|
+
* .map(str => Result.flatMap(str, s =>
|
|
169
|
+
* s.length > 0
|
|
170
|
+
* ? Result.ok(s)
|
|
171
|
+
* : Result.err(new Error('Empty string'))
|
|
172
|
+
* ))
|
|
173
|
+
* .value;
|
|
174
|
+
* }
|
|
175
|
+
* ```
|
|
176
|
+
*
|
|
177
|
+
* @see Result - For error handling pattern used by this function
|
|
178
|
+
* @see JSON.stringify - Underlying serialization for objects
|
|
179
|
+
*/
|
|
180
|
+
const unknownToString = (value, options) => {
|
|
181
|
+
switch (typeof value) {
|
|
182
|
+
case 'string':
|
|
183
|
+
return Result.ok(value);
|
|
184
|
+
case 'number':
|
|
185
|
+
case 'bigint':
|
|
186
|
+
case 'boolean':
|
|
187
|
+
case 'symbol':
|
|
188
|
+
case 'function':
|
|
189
|
+
return Result.ok(value.toString());
|
|
190
|
+
case 'object':
|
|
191
|
+
if (!isNonNullish(value)) {
|
|
192
|
+
return Result.ok('null');
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
const stringified = options?.prettyPrintObject === true
|
|
196
|
+
? JSON.stringify(value, undefined, 2)
|
|
197
|
+
: JSON.stringify(value);
|
|
198
|
+
return Result.ok(stringified);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
return Result.err(error instanceof Error
|
|
202
|
+
? error
|
|
203
|
+
: new Error('Failed to stringify object'));
|
|
204
|
+
}
|
|
205
|
+
case 'undefined':
|
|
206
|
+
return Result.ok('undefined');
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export { unknownToString };
|
|
211
|
+
//# sourceMappingURL=unknown-to-string.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unknown-to-string.mjs","sources":["../../src/others/unknown-to-string.mts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8KG;MACU,eAAe,GAAG,CAC7B,KAAc,EACd,OAA2D,KAClC;IACzB,QAAQ,OAAO,KAAK;AAClB,QAAA,KAAK,QAAQ;AACX,YAAA,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC;AAEzB,QAAA,KAAK,QAAQ;AACb,QAAA,KAAK,QAAQ;AACb,QAAA,KAAK,SAAS;AACd,QAAA,KAAK,QAAQ;AACb,QAAA,KAAK,UAAU;YACb,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;AAEpC,QAAA,KAAK,QAAQ;AACX,YAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;AACxB,gBAAA,OAAO,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;;AAE1B,YAAA,IAAI;AACF,gBAAA,MAAM,WAAW,GACf,OAAO,EAAE,iBAAiB,KAAK;sBAC3B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC;AACpC,sBAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;AAC3B,gBAAA,OAAO,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC;;YAC7B,OAAO,KAAK,EAAE;AACd,gBAAA,OAAO,MAAM,CAAC,GAAG,CACf,KAAK,YAAY;AACf,sBAAE;AACF,sBAAE,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAC5C;;AAGL,QAAA,KAAK,WAAW;AACd,YAAA,OAAO,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC;;AAEnC;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"include":["."]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-data-forge",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -35,13 +35,14 @@
|
|
|
35
35
|
"LICENSE"
|
|
36
36
|
],
|
|
37
37
|
"scripts": {
|
|
38
|
-
"build": "npm run z:node-
|
|
39
|
-
"check-all": "npm run z:node-
|
|
40
|
-
"check:ext": "npm run z:node-
|
|
38
|
+
"build": "npm run z:node-esm -- ./scripts/cmd/build.mjs",
|
|
39
|
+
"check-all": "npm run z:node-esm -- ./scripts/cmd/check-all.mjs",
|
|
40
|
+
"check:ext": "npm run z:node-esm -- ./scripts/cmd/check-ext.mjs",
|
|
41
41
|
"cspell": "cspell \"**\" --gitignore --gitignore-root ./ --no-progress",
|
|
42
|
-
"doc": "npm run z:node-
|
|
43
|
-
"fmt": "
|
|
44
|
-
"
|
|
42
|
+
"doc": "npm run z:node-esm -- ./scripts/cmd/gen-docs.mjs",
|
|
43
|
+
"fmt": "npm run z:node-esm -- ./scripts/cmd/fmt-diff.mjs",
|
|
44
|
+
"fmt:full": "prettier --write .",
|
|
45
|
+
"gi": "npm run z:node-esm -- ./scripts/cmd/gi.mjs",
|
|
45
46
|
"lint": "eslint .",
|
|
46
47
|
"lint:fix": "eslint . --fix",
|
|
47
48
|
"md": "markdownlint-cli2",
|
|
@@ -54,11 +55,11 @@
|
|
|
54
55
|
"tscw": "tsc --noEmit --watch",
|
|
55
56
|
"type-check": "tsc --noEmit",
|
|
56
57
|
"update-packages": "npx npm-check-updates -u --install always --reject @types/node",
|
|
57
|
-
"z:node-
|
|
58
|
+
"z:node-esm": "node --import tsx/esm",
|
|
58
59
|
"z:vitest": "vitest --config ./configs/vitest.config.ts"
|
|
59
60
|
},
|
|
60
61
|
"dependencies": {
|
|
61
|
-
"ts-type-forge": "^2.0.
|
|
62
|
+
"ts-type-forge": "^2.0.3"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
64
65
|
"@eslint/js": "^9.29.0",
|
|
@@ -72,9 +73,9 @@
|
|
|
72
73
|
"@semantic-release/github": "^11.0.3",
|
|
73
74
|
"@semantic-release/npm": "^12.0.1",
|
|
74
75
|
"@semantic-release/release-notes-generator": "^14.0.3",
|
|
75
|
-
"@types/node": "^20.19.
|
|
76
|
-
"@vitest/coverage-v8": "^3.2.
|
|
77
|
-
"@vitest/ui": "^3.2.
|
|
76
|
+
"@types/node": "^20.19.1",
|
|
77
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
78
|
+
"@vitest/ui": "^3.2.4",
|
|
78
79
|
"conventional-changelog-conventionalcommits": "^9.0.0",
|
|
79
80
|
"cspell": "^9.1.1",
|
|
80
81
|
"eslint": "^9.29.0",
|
|
@@ -83,14 +84,15 @@
|
|
|
83
84
|
"prettier": "^3.5.3",
|
|
84
85
|
"prettier-plugin-organize-imports": "^4.1.0",
|
|
85
86
|
"prettier-plugin-packagejson": "^2.5.15",
|
|
86
|
-
"rollup": "^4.
|
|
87
|
+
"rollup": "^4.44.0",
|
|
87
88
|
"semantic-release": "^24.2.5",
|
|
89
|
+
"ts-repo-utils": "^1.2.0",
|
|
88
90
|
"tsx": "^4.20.3",
|
|
89
91
|
"typedoc": "^0.28.5",
|
|
90
|
-
"typedoc-plugin-markdown": "^4.
|
|
92
|
+
"typedoc-plugin-markdown": "^4.7.0",
|
|
91
93
|
"typescript": "^5.8.3",
|
|
92
|
-
"typescript-eslint": "^8.34.
|
|
93
|
-
"vitest": "^3.2.
|
|
94
|
+
"typescript-eslint": "^8.34.1",
|
|
95
|
+
"vitest": "^3.2.4"
|
|
94
96
|
},
|
|
95
97
|
"peerDependencies": {
|
|
96
98
|
"typescript": ">=4.8"
|