ts-data-forge 4.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/dist/entry-point.mjs +2 -0
  2. package/dist/entry-point.mjs.map +1 -1
  3. package/dist/functional/index.d.mts +1 -0
  4. package/dist/functional/index.d.mts.map +1 -1
  5. package/dist/functional/index.mjs +2 -0
  6. package/dist/functional/index.mjs.map +1 -1
  7. package/dist/functional/ternary-result/impl/index.d.mts +29 -0
  8. package/dist/functional/ternary-result/impl/index.d.mts.map +1 -0
  9. package/dist/functional/ternary-result/impl/index.mjs +28 -0
  10. package/dist/functional/ternary-result/impl/index.mjs.map +1 -0
  11. package/dist/functional/ternary-result/impl/tag.d.mts +7 -0
  12. package/dist/functional/ternary-result/impl/tag.d.mts.map +1 -0
  13. package/dist/functional/ternary-result/impl/tag.mjs +9 -0
  14. package/dist/functional/ternary-result/impl/tag.mjs.map +1 -0
  15. package/dist/functional/ternary-result/impl/ternary-result-err.d.mts +14 -0
  16. package/dist/functional/ternary-result/impl/ternary-result-err.d.mts.map +1 -0
  17. package/dist/functional/ternary-result/impl/ternary-result-err.mjs +21 -0
  18. package/dist/functional/ternary-result/impl/ternary-result-err.mjs.map +1 -0
  19. package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.d.mts +18 -0
  20. package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.d.mts.map +1 -0
  21. package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.mjs +24 -0
  22. package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.mjs.map +1 -0
  23. package/dist/functional/ternary-result/impl/ternary-result-flat-map.d.mts +29 -0
  24. package/dist/functional/ternary-result/impl/ternary-result-flat-map.d.mts.map +1 -0
  25. package/dist/functional/ternary-result/impl/ternary-result-flat-map.mjs +41 -0
  26. package/dist/functional/ternary-result/impl/ternary-result-flat-map.mjs.map +1 -0
  27. package/dist/functional/ternary-result/impl/ternary-result-fold.d.mts +27 -0
  28. package/dist/functional/ternary-result/impl/ternary-result-fold.d.mts.map +1 -0
  29. package/dist/functional/ternary-result/impl/ternary-result-fold.mjs +36 -0
  30. package/dist/functional/ternary-result/impl/ternary-result-fold.mjs.map +1 -0
  31. package/dist/functional/ternary-result/impl/ternary-result-from-promise.d.mts +20 -0
  32. package/dist/functional/ternary-result/impl/ternary-result-from-promise.d.mts.map +1 -0
  33. package/dist/functional/ternary-result/impl/ternary-result-from-promise.mjs +24 -0
  34. package/dist/functional/ternary-result/impl/ternary-result-from-promise.mjs.map +1 -0
  35. package/dist/functional/ternary-result/impl/ternary-result-from-throwable.d.mts +17 -0
  36. package/dist/functional/ternary-result/impl/ternary-result-from-throwable.d.mts.map +1 -0
  37. package/dist/functional/ternary-result/impl/ternary-result-from-throwable.mjs +33 -0
  38. package/dist/functional/ternary-result/impl/ternary-result-from-throwable.mjs.map +1 -0
  39. package/dist/functional/ternary-result/impl/ternary-result-is-err.d.mts +20 -0
  40. package/dist/functional/ternary-result/impl/ternary-result-is-err.d.mts.map +1 -0
  41. package/dist/functional/ternary-result/impl/ternary-result-is-err.mjs +23 -0
  42. package/dist/functional/ternary-result/impl/ternary-result-is-err.mjs.map +1 -0
  43. package/dist/functional/ternary-result/impl/ternary-result-is-ok.d.mts +21 -0
  44. package/dist/functional/ternary-result/impl/ternary-result-is-ok.d.mts.map +1 -0
  45. package/dist/functional/ternary-result/impl/ternary-result-is-ok.mjs +24 -0
  46. package/dist/functional/ternary-result/impl/ternary-result-is-ok.mjs.map +1 -0
  47. package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.d.mts +17 -0
  48. package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.d.mts.map +1 -0
  49. package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.mjs +28 -0
  50. package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.mjs.map +1 -0
  51. package/dist/functional/ternary-result/impl/ternary-result-is-warn.d.mts +21 -0
  52. package/dist/functional/ternary-result/impl/ternary-result-is-warn.d.mts.map +1 -0
  53. package/dist/functional/ternary-result/impl/ternary-result-is-warn.mjs +24 -0
  54. package/dist/functional/ternary-result/impl/ternary-result-is-warn.mjs.map +1 -0
  55. package/dist/functional/ternary-result/impl/ternary-result-map-err.d.mts +23 -0
  56. package/dist/functional/ternary-result/impl/ternary-result-map-err.d.mts.map +1 -0
  57. package/dist/functional/ternary-result/impl/ternary-result-map-err.mjs +26 -0
  58. package/dist/functional/ternary-result/impl/ternary-result-map-err.mjs.map +1 -0
  59. package/dist/functional/ternary-result/impl/ternary-result-map-warn.d.mts +21 -0
  60. package/dist/functional/ternary-result/impl/ternary-result-map-warn.d.mts.map +1 -0
  61. package/dist/functional/ternary-result/impl/ternary-result-map-warn.mjs +29 -0
  62. package/dist/functional/ternary-result/impl/ternary-result-map-warn.mjs.map +1 -0
  63. package/dist/functional/ternary-result/impl/ternary-result-map.d.mts +29 -0
  64. package/dist/functional/ternary-result/impl/ternary-result-map.d.mts.map +1 -0
  65. package/dist/functional/ternary-result/impl/ternary-result-map.mjs +35 -0
  66. package/dist/functional/ternary-result/impl/ternary-result-map.mjs.map +1 -0
  67. package/dist/functional/ternary-result/impl/ternary-result-ok.d.mts +16 -0
  68. package/dist/functional/ternary-result/impl/ternary-result-ok.d.mts.map +1 -0
  69. package/dist/functional/ternary-result/impl/ternary-result-ok.mjs +23 -0
  70. package/dist/functional/ternary-result/impl/ternary-result-ok.mjs.map +1 -0
  71. package/dist/functional/ternary-result/impl/ternary-result-or-else.d.mts +26 -0
  72. package/dist/functional/ternary-result/impl/ternary-result-or-else.d.mts.map +1 -0
  73. package/dist/functional/ternary-result/impl/ternary-result-or-else.mjs +19 -0
  74. package/dist/functional/ternary-result/impl/ternary-result-or-else.mjs.map +1 -0
  75. package/dist/functional/ternary-result/impl/ternary-result-to-optional.d.mts +16 -0
  76. package/dist/functional/ternary-result/impl/ternary-result-to-optional.d.mts.map +1 -0
  77. package/dist/functional/ternary-result/impl/ternary-result-to-optional.mjs +25 -0
  78. package/dist/functional/ternary-result/impl/ternary-result-to-optional.mjs.map +1 -0
  79. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.d.mts +22 -0
  80. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.d.mts.map +1 -0
  81. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.mjs +17 -0
  82. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.mjs.map +1 -0
  83. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.d.mts +18 -0
  84. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.d.mts.map +1 -0
  85. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mjs +36 -0
  86. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mjs.map +1 -0
  87. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.d.mts +17 -0
  88. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.d.mts.map +1 -0
  89. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.mjs +22 -0
  90. package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.mjs.map +1 -0
  91. package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.d.mts +22 -0
  92. package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.d.mts.map +1 -0
  93. package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.mjs +17 -0
  94. package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.mjs.map +1 -0
  95. package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.d.mts +17 -0
  96. package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.d.mts.map +1 -0
  97. package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.mjs +13 -0
  98. package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.mjs.map +1 -0
  99. package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.d.mts +18 -0
  100. package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.d.mts.map +1 -0
  101. package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.mjs +36 -0
  102. package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.mjs.map +1 -0
  103. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.d.mts +19 -0
  104. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.d.mts.map +1 -0
  105. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.mjs +17 -0
  106. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.mjs.map +1 -0
  107. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.d.mts +18 -0
  108. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.d.mts.map +1 -0
  109. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mjs +32 -0
  110. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mjs.map +1 -0
  111. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.d.mts +17 -0
  112. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.d.mts.map +1 -0
  113. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.mjs +22 -0
  114. package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.mjs.map +1 -0
  115. package/dist/functional/ternary-result/impl/ternary-result-warn.d.mts +18 -0
  116. package/dist/functional/ternary-result/impl/ternary-result-warn.d.mts.map +1 -0
  117. package/dist/functional/ternary-result/impl/ternary-result-warn.mjs +26 -0
  118. package/dist/functional/ternary-result/impl/ternary-result-warn.mjs.map +1 -0
  119. package/dist/functional/ternary-result/impl/ternary-result-zip.d.mts +26 -0
  120. package/dist/functional/ternary-result/impl/ternary-result-zip.d.mts.map +1 -0
  121. package/dist/functional/ternary-result/impl/ternary-result-zip.mjs +48 -0
  122. package/dist/functional/ternary-result/impl/ternary-result-zip.mjs.map +1 -0
  123. package/dist/functional/ternary-result/impl/types.d.mts +25 -0
  124. package/dist/functional/ternary-result/impl/types.d.mts.map +1 -0
  125. package/dist/functional/ternary-result/impl/types.mjs +2 -0
  126. package/dist/functional/ternary-result/impl/types.mjs.map +1 -0
  127. package/dist/functional/ternary-result/impl/variant-name.d.mts +3 -0
  128. package/dist/functional/ternary-result/impl/variant-name.d.mts.map +1 -0
  129. package/dist/functional/ternary-result/impl/variant-name.mjs +16 -0
  130. package/dist/functional/ternary-result/impl/variant-name.mjs.map +1 -0
  131. package/dist/functional/ternary-result/index.d.mts +2 -0
  132. package/dist/functional/ternary-result/index.d.mts.map +1 -0
  133. package/dist/functional/ternary-result/index.mjs +3 -0
  134. package/dist/functional/ternary-result/index.mjs.map +1 -0
  135. package/dist/globals.d.mts +55 -2
  136. package/package.json +1 -1
  137. package/src/functional/index.mts +1 -0
  138. package/src/functional/ternary-result/impl/index.mts +28 -0
  139. package/src/functional/ternary-result/impl/tag.mts +11 -0
  140. package/src/functional/ternary-result/impl/ternary-result-err.mts +18 -0
  141. package/src/functional/ternary-result/impl/ternary-result-expect-to-be.mts +53 -0
  142. package/src/functional/ternary-result/impl/ternary-result-flat-map.mts +95 -0
  143. package/src/functional/ternary-result/impl/ternary-result-fold.mts +93 -0
  144. package/src/functional/ternary-result/impl/ternary-result-from-promise.mts +27 -0
  145. package/src/functional/ternary-result/impl/ternary-result-from-throwable.mts +31 -0
  146. package/src/functional/ternary-result/impl/ternary-result-is-err.mts +23 -0
  147. package/src/functional/ternary-result/impl/ternary-result-is-ok.mts +24 -0
  148. package/src/functional/ternary-result/impl/ternary-result-is-ternary-result.mts +27 -0
  149. package/src/functional/ternary-result/impl/ternary-result-is-warn.mts +24 -0
  150. package/src/functional/ternary-result/impl/ternary-result-map-err.mts +64 -0
  151. package/src/functional/ternary-result/impl/ternary-result-map-warn.mts +66 -0
  152. package/src/functional/ternary-result/impl/ternary-result-map.mts +81 -0
  153. package/src/functional/ternary-result/impl/ternary-result-ok.mts +20 -0
  154. package/src/functional/ternary-result/impl/ternary-result-or-else.mts +66 -0
  155. package/src/functional/ternary-result/impl/ternary-result-to-optional.mts +25 -0
  156. package/src/functional/ternary-result/impl/ternary-result-unwrap-err-or.mts +45 -0
  157. package/src/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mts +40 -0
  158. package/src/functional/ternary-result/impl/ternary-result-unwrap-err.mts +22 -0
  159. package/src/functional/ternary-result/impl/ternary-result-unwrap-ok-or.mts +45 -0
  160. package/src/functional/ternary-result/impl/ternary-result-unwrap-ok.mts +32 -0
  161. package/src/functional/ternary-result/impl/ternary-result-unwrap-throw.mts +45 -0
  162. package/src/functional/ternary-result/impl/ternary-result-unwrap-warn-or.mts +42 -0
  163. package/src/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mts +38 -0
  164. package/src/functional/ternary-result/impl/ternary-result-unwrap-warn.mts +22 -0
  165. package/src/functional/ternary-result/impl/ternary-result-warn.mts +23 -0
  166. package/src/functional/ternary-result/impl/ternary-result-zip.mts +53 -0
  167. package/src/functional/ternary-result/impl/types.mts +39 -0
  168. package/src/functional/ternary-result/impl/variant-name.mts +17 -0
  169. package/src/functional/ternary-result/index.mts +1 -0
  170. package/src/functional/ternary-result.test.mts +198 -0
  171. package/src/globals.d.mts +55 -2
@@ -0,0 +1,66 @@
1
+ import { isOk } from './ternary-result-is-ok.mjs';
2
+ import { isWarn } from './ternary-result-is-warn.mjs';
3
+ import { type NarrowToOk, type NarrowToWarn } from './types.mjs';
4
+
5
+ /**
6
+ * Returns the original result if it is Ok, otherwise the provided fallback.
7
+ *
8
+ * @example
9
+ *
10
+ * ```ts
11
+ * const fallback = TernaryResult.ok('fallback');
12
+ *
13
+ * assert.deepStrictEqual(
14
+ * TernaryResult.orElse(TernaryResult.ok('value'), fallback),
15
+ * TernaryResult.ok('value'),
16
+ * );
17
+ * assert.deepStrictEqual(
18
+ * TernaryResult.orElse(TernaryResult.warn('value', 'warn'), fallback),
19
+ * TernaryResult.warn('value', 'warn'),
20
+ * );
21
+ * assert.deepStrictEqual(
22
+ * TernaryResult.orElse(TernaryResult.err('err'), fallback),
23
+ * fallback,
24
+ * );
25
+ * ```
26
+ */
27
+ export function orElse<
28
+ R extends UnknownTernaryResult,
29
+ R2 extends UnknownTernaryResult,
30
+ >(result: R, alternative: R2): NarrowToOk<R> | NarrowToWarn<R> | R2;
31
+
32
+ // Curried version
33
+ export function orElse<S, W, E, S2, W2, E2>(
34
+ alternative: TernaryResult<S2, E2, W2>,
35
+ ): (
36
+ result: TernaryResult<S, E, W>,
37
+ ) => TernaryResult<S, E, W> | TernaryResult<S2, E2, W2>;
38
+
39
+ export function orElse<
40
+ R extends UnknownTernaryResult,
41
+ R2 extends UnknownTernaryResult,
42
+ >(
43
+ ...args: readonly [result: R, alternative: R2] | readonly [alternative: R2]
44
+ ):
45
+ | (NarrowToOk<R> | NarrowToWarn<R> | R2)
46
+ | ((result: R) => NarrowToOk<R> | NarrowToWarn<R> | R2) {
47
+ switch (args.length) {
48
+ case 2: {
49
+ const [result, alternative] = args;
50
+ return orElseImpl(result, alternative);
51
+ }
52
+ case 1: {
53
+ const [alternative] = args;
54
+ return (result: R) => orElseImpl(result, alternative);
55
+ }
56
+ }
57
+ }
58
+
59
+ const orElseImpl = <
60
+ R extends UnknownTernaryResult,
61
+ R2 extends UnknownTernaryResult,
62
+ >(
63
+ result: R,
64
+ alternative: R2,
65
+ ): NarrowToOk<R> | NarrowToWarn<R> | R2 =>
66
+ isOk(result) || isWarn(result) ? result : alternative;
@@ -0,0 +1,25 @@
1
+ import { Optional } from '../../optional/index.mjs';
2
+ import { isOk } from './ternary-result-is-ok.mjs';
3
+ import { isWarn } from './ternary-result-is-warn.mjs';
4
+ import { type UnwrapOk } from './types.mjs';
5
+
6
+ /**
7
+ * Converts a `TernaryResult` into an `Optional` by keeping only Ok values.
8
+ *
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * const okValue = TernaryResult.ok(7);
13
+ * const warnValue = TernaryResult.warn(7, 'warn');
14
+ *
15
+ * assert.deepStrictEqual(TernaryResult.toOptional(okValue), Optional.some(7));
16
+ * assert.deepStrictEqual(TernaryResult.toOptional(warnValue), Optional.some(7));
17
+ * ```
18
+ */
19
+ export const toOptional = <R extends UnknownTernaryResult>(
20
+ result: R,
21
+ ): Optional<UnwrapOk<R>> =>
22
+ isOk(result) || isWarn(result)
23
+ ? // eslint-disable-next-line total-functions/no-unsafe-type-assertion
24
+ Optional.some(result.value as UnwrapOk<R>)
25
+ : Optional.none;
@@ -0,0 +1,45 @@
1
+ import { unwrapErr } from './ternary-result-unwrap-err.mjs';
2
+ import { type UnwrapErr } from './types.mjs';
3
+
4
+ /**
5
+ * Returns the Err value or the provided default.
6
+ *
7
+ * @example
8
+ *
9
+ * ```ts
10
+ * const okValue = TernaryResult.ok('value');
11
+ *
12
+ * assert.strictEqual(TernaryResult.unwrapErrOr(okValue, 'default'), 'default');
13
+ * const unwrapErr = TernaryResult.unwrapErrOr('fallback error');
14
+ *
15
+ * assert.strictEqual(unwrapErr(TernaryResult.err('boom')), 'boom');
16
+ * assert.strictEqual(
17
+ * unwrapErr(TernaryResult.warn('value', 'warn')),
18
+ * 'fallback error',
19
+ * );
20
+ * ```
21
+ */
22
+ export function unwrapErrOr<R extends UnknownTernaryResult, D>(
23
+ result: R,
24
+ defaultValue: D,
25
+ ): D | UnwrapErr<R>;
26
+
27
+ // Curried version
28
+ export function unwrapErrOr<E, D>(
29
+ defaultValue: D,
30
+ ): <S, W>(result: TernaryResult<S, E, W>) => D | E;
31
+
32
+ export function unwrapErrOr<R extends UnknownTernaryResult, D>(
33
+ ...args: readonly [result: R, defaultValue: D] | readonly [defaultValue: D]
34
+ ): D | UnwrapErr<R> | ((result: R) => D | UnwrapErr<R>) {
35
+ switch (args.length) {
36
+ case 2: {
37
+ const [result, defaultValue] = args;
38
+ return unwrapErr(result) ?? defaultValue;
39
+ }
40
+ case 1: {
41
+ const [defaultValue] = args;
42
+ return (result: R) => unwrapErr(result) ?? defaultValue;
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,40 @@
1
+ import { unknownToString } from '../../../others/index.mjs';
2
+ import { isErr } from './ternary-result-is-err.mjs';
3
+ import { isWarn } from './ternary-result-is-warn.mjs';
4
+ import { type UnwrapErr, type UnwrapOk, type UnwrapWarn } from './types.mjs';
5
+ import { variantName } from './variant-name.mjs';
6
+
7
+ /**
8
+ * Returns the Err value or throws if the result is not Err.
9
+ *
10
+ * @example
11
+ *
12
+ * ```ts
13
+ * const errValue = TernaryResult.err('boom');
14
+ *
15
+ * assert.strictEqual(TernaryResult.unwrapErrThrow(errValue), 'boom');
16
+ * assert.throws(
17
+ * () => TernaryResult.unwrapErrThrow(TernaryResult.ok('value')),
18
+ * /Expected Err/u,
19
+ * );
20
+ * ```
21
+ */
22
+ export const unwrapErrThrow = <R extends UnknownTernaryResult>(
23
+ result: R,
24
+ toStr: (value: UnwrapOk<R> | UnwrapWarn<R>) => string = unknownToString,
25
+ ): UnwrapErr<R> => {
26
+ if (isErr(result)) {
27
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
28
+ return result.value as UnwrapErr<R>;
29
+ }
30
+
31
+ const variant = variantName(result.$$tag);
32
+
33
+ const payload = isWarn(result)
34
+ ? // eslint-disable-next-line total-functions/no-unsafe-type-assertion
35
+ (result.warning as UnwrapWarn<R> as UnwrapOk<R> | UnwrapWarn<R>)
36
+ : // eslint-disable-next-line total-functions/no-unsafe-type-assertion
37
+ (result.value as UnwrapOk<R> as UnwrapOk<R> | UnwrapWarn<R>);
38
+
39
+ throw new Error(`Expected Err but got ${variant}: ${toStr(payload)}`);
40
+ };
@@ -0,0 +1,22 @@
1
+ import { isErr } from './ternary-result-is-err.mjs';
2
+ import { type UnwrapErr } from './types.mjs';
3
+
4
+ /**
5
+ * Safely unwraps the Err value.
6
+ *
7
+ * @example
8
+ *
9
+ * ```ts
10
+ * const errValue = TernaryResult.err('fail');
11
+ * const okValue = TernaryResult.ok('value');
12
+ *
13
+ * assert.strictEqual(TernaryResult.unwrapErr(errValue), 'fail');
14
+ * // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
15
+ * assert.strictEqual(TernaryResult.unwrapErr(okValue), undefined);
16
+ * ```
17
+ */
18
+ export const unwrapErr = <R extends UnknownTernaryResult>(
19
+ result: R,
20
+ ): UnwrapErr<R> | undefined =>
21
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
22
+ isErr(result) ? (result.value as UnwrapErr<R>) : undefined;
@@ -0,0 +1,45 @@
1
+ import { unwrapOk } from './ternary-result-unwrap-ok.mjs';
2
+ import { type UnwrapOk } from './types.mjs';
3
+
4
+ /**
5
+ * Returns the Ok value or the provided default.
6
+ *
7
+ * @example
8
+ *
9
+ * ```ts
10
+ * const errValue = TernaryResult.err('err');
11
+ *
12
+ * assert.strictEqual(TernaryResult.unwrapOkOr(errValue, 0), 0);
13
+ * const unwrapWithDefault = TernaryResult.unwrapOkOr('fallback');
14
+ *
15
+ * assert.strictEqual(unwrapWithDefault(TernaryResult.ok(5)), 5);
16
+ * assert.strictEqual(
17
+ * unwrapWithDefault(TernaryResult.warn('warn-value', 'warn')),
18
+ * 'warn-value',
19
+ * );
20
+ * ```
21
+ */
22
+ export function unwrapOkOr<R extends UnknownTernaryResult, D>(
23
+ result: R,
24
+ defaultValue: D,
25
+ ): D | UnwrapOk<R>;
26
+
27
+ // Curried version
28
+ export function unwrapOkOr<S, D>(
29
+ defaultValue: D,
30
+ ): <W, E>(result: TernaryResult<S, E, W>) => D | S;
31
+
32
+ export function unwrapOkOr<R extends UnknownTernaryResult, D>(
33
+ ...args: readonly [result: R, defaultValue: D] | readonly [defaultValue: D]
34
+ ): D | UnwrapOk<R> | ((result: R) => D | UnwrapOk<R>) {
35
+ switch (args.length) {
36
+ case 2: {
37
+ const [result, defaultValue] = args;
38
+ return unwrapOk(result) ?? defaultValue;
39
+ }
40
+ case 1: {
41
+ const [defaultValue] = args;
42
+ return (result: R) => unwrapOk(result) ?? defaultValue;
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,32 @@
1
+ import { isOk } from './ternary-result-is-ok.mjs';
2
+ import { isWarn } from './ternary-result-is-warn.mjs';
3
+ import { type UnwrapOk } from './types.mjs';
4
+
5
+ /**
6
+ * Safely unwraps the Ok value.
7
+ *
8
+ * @example
9
+ *
10
+ * ```ts
11
+ * const okValue = TernaryResult.ok(3);
12
+ * const warnValue = TernaryResult.warn(4, 'warn');
13
+ *
14
+ * assert.strictEqual(TernaryResult.unwrapOk(okValue), 3);
15
+ * assert.strictEqual(TernaryResult.unwrapOk(warnValue), 4);
16
+ * ```
17
+ */
18
+ export function unwrapOk<R extends TernaryOk<unknown>>(result: R): UnwrapOk<R>;
19
+ export function unwrapOk<R extends UnknownTernaryResult>(
20
+ result: R,
21
+ ): UnwrapOk<R> | undefined;
22
+
23
+ export function unwrapOk<R extends UnknownTernaryResult>(
24
+ result: R,
25
+ ): UnwrapOk<R> | undefined {
26
+ if (isOk(result) || isWarn(result)) {
27
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
28
+ return result.value as UnwrapOk<R>;
29
+ }
30
+
31
+ return undefined;
32
+ }
@@ -0,0 +1,45 @@
1
+ import { unknownToString } from '../../../others/index.mjs';
2
+ import { isErr } from './ternary-result-is-err.mjs';
3
+ import { isWarn } from './ternary-result-is-warn.mjs';
4
+ import { type UnwrapErr, type UnwrapOk, type UnwrapWarn } from './types.mjs';
5
+
6
+ /**
7
+ * Returns the Ok value or throws if the result is Warn or Err.
8
+ *
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * const okValue = TernaryResult.ok('ready');
13
+ *
14
+ * assert.strictEqual(TernaryResult.unwrapThrow(okValue), 'ready');
15
+ * assert.throws(
16
+ * () => TernaryResult.unwrapThrow(TernaryResult.warn('warn', 'warned')),
17
+ * /Expected Ok/u,
18
+ * );
19
+ * ```
20
+ */
21
+ export const unwrapThrow = <R extends UnknownTernaryResult>(
22
+ result: R,
23
+ toStr: (value: UnwrapWarn<R> | UnwrapErr<R>) => string = unknownToString,
24
+ ): UnwrapOk<R> => {
25
+ if (isErr(result)) {
26
+ throw new Error(
27
+ `Expected Ok but got Err: ${toStr(
28
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
29
+ result.value as UnwrapErr<R>,
30
+ )}`,
31
+ );
32
+ }
33
+
34
+ if (isWarn(result)) {
35
+ throw new Error(
36
+ `Expected Ok but got Warn: ${toStr(
37
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
38
+ result.warning as UnwrapWarn<R>,
39
+ )}`,
40
+ );
41
+ }
42
+
43
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
44
+ return result.value as UnwrapOk<R>;
45
+ };
@@ -0,0 +1,42 @@
1
+ import { unwrapWarn } from './ternary-result-unwrap-warn.mjs';
2
+ import { type UnwrapWarn } from './types.mjs';
3
+
4
+ /**
5
+ * Returns the Warn value or the provided default.
6
+ *
7
+ * @example
8
+ *
9
+ * ```ts
10
+ * const okValue = TernaryResult.ok('value');
11
+ *
12
+ * assert.strictEqual(TernaryResult.unwrapWarnOr(okValue, 'warn'), 'warn');
13
+ * const unwrapWarn = TernaryResult.unwrapWarnOr('fallback warn');
14
+ *
15
+ * assert.strictEqual(unwrapWarn(TernaryResult.warn('value', 'slow')), 'slow');
16
+ * assert.strictEqual(unwrapWarn(TernaryResult.err('err')), 'fallback warn');
17
+ * ```
18
+ */
19
+ export function unwrapWarnOr<R extends UnknownTernaryResult, D>(
20
+ result: R,
21
+ defaultValue: D,
22
+ ): D | UnwrapWarn<R>;
23
+
24
+ // Curried version
25
+ export function unwrapWarnOr<W, D>(
26
+ defaultValue: D,
27
+ ): <S, E>(result: TernaryResult<S, E, W>) => D | W;
28
+
29
+ export function unwrapWarnOr<R extends UnknownTernaryResult, D>(
30
+ ...args: readonly [result: R, defaultValue: D] | readonly [defaultValue: D]
31
+ ): D | UnwrapWarn<R> | ((result: R) => D | UnwrapWarn<R>) {
32
+ switch (args.length) {
33
+ case 2: {
34
+ const [result, defaultValue] = args;
35
+ return unwrapWarn(result) ?? defaultValue;
36
+ }
37
+ case 1: {
38
+ const [defaultValue] = args;
39
+ return (result: R) => unwrapWarn(result) ?? defaultValue;
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,38 @@
1
+ import { unknownToString } from '../../../others/index.mjs';
2
+ import { isWarn } from './ternary-result-is-warn.mjs';
3
+ import { type UnwrapErr, type UnwrapOk, type UnwrapWarn } from './types.mjs';
4
+ import { variantName } from './variant-name.mjs';
5
+
6
+ /**
7
+ * Returns the Warn value or throws if the result is not Warn.
8
+ *
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * const warnValue = TernaryResult.warn('pending', 'check logs');
13
+ *
14
+ * assert.strictEqual(TernaryResult.unwrapWarnThrow(warnValue), 'check logs');
15
+ * assert.throws(
16
+ * () => TernaryResult.unwrapWarnThrow(TernaryResult.err('err')),
17
+ * /Expected Warn/u,
18
+ * );
19
+ * ```
20
+ */
21
+ export const unwrapWarnThrow = <R extends UnknownTernaryResult>(
22
+ result: R,
23
+ toStr: (value: UnwrapOk<R> | UnwrapErr<R>) => string = unknownToString,
24
+ ): UnwrapWarn<R> => {
25
+ if (isWarn(result)) {
26
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
27
+ return result.warning as UnwrapWarn<R>;
28
+ }
29
+
30
+ const variant = variantName(result.$$tag);
31
+
32
+ throw new Error(
33
+ `Expected Warn but got ${variant}: ${toStr(
34
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
35
+ result.value as UnwrapOk<R> | UnwrapErr<R>,
36
+ )}`,
37
+ );
38
+ };
@@ -0,0 +1,22 @@
1
+ import { isWarn } from './ternary-result-is-warn.mjs';
2
+ import { type UnwrapWarn } from './types.mjs';
3
+
4
+ /**
5
+ * Safely unwraps the Warn value.
6
+ *
7
+ * @example
8
+ *
9
+ * ```ts
10
+ * const warnValue = TernaryResult.warn('ok', 'careful');
11
+ * const okValue = TernaryResult.ok('ok');
12
+ *
13
+ * assert.strictEqual(TernaryResult.unwrapWarn(warnValue), 'careful');
14
+ * // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
15
+ * assert.strictEqual(TernaryResult.unwrapWarn(okValue), undefined);
16
+ * ```
17
+ */
18
+ export const unwrapWarn = <R extends UnknownTernaryResult>(
19
+ result: R,
20
+ ): UnwrapWarn<R> | undefined =>
21
+ // eslint-disable-next-line total-functions/no-unsafe-type-assertion
22
+ isWarn(result) ? (result.warning as UnwrapWarn<R>) : undefined;
@@ -0,0 +1,23 @@
1
+ import { WarnTypeTagName } from './tag.mjs';
2
+
3
+ /**
4
+ * Creates a `TernaryResult.Warn` containing the provided success value and
5
+ * warning.
6
+ *
7
+ * @example
8
+ *
9
+ * ```ts
10
+ * const caution = TernaryResult.warn({ id: 1 }, 'Needs review');
11
+ *
12
+ * assert.deepStrictEqual(caution, {
13
+ * $$tag: 'ts-data-forge::Result.warn',
14
+ * value: { id: 1 },
15
+ * warning: 'Needs review',
16
+ * });
17
+ * ```
18
+ */
19
+ export const warn = <S, W>(value: S, warning: W): TernaryWarn<S, W> => ({
20
+ $$tag: WarnTypeTagName,
21
+ value,
22
+ warning,
23
+ });
@@ -0,0 +1,53 @@
1
+ import { isErr } from './ternary-result-is-err.mjs';
2
+ import { isWarn } from './ternary-result-is-warn.mjs';
3
+ import { ok } from './ternary-result-ok.mjs';
4
+ import { warn } from './ternary-result-warn.mjs';
5
+
6
+ /**
7
+ * Combines two `TernaryResult`s, prioritising Err over Warn over Ok.
8
+ *
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * const okPair = TernaryResult.zip(TernaryResult.ok('left'), TernaryResult.ok(1));
13
+ * const warnPair = TernaryResult.zip(
14
+ * TernaryResult.warn('left', 'warn'),
15
+ * TernaryResult.ok(1),
16
+ * );
17
+ * const errPair = TernaryResult.zip(
18
+ * TernaryResult.ok('left'),
19
+ * TernaryResult.err('err'),
20
+ * );
21
+ *
22
+ * assert.deepStrictEqual(okPair, TernaryResult.ok(['left', 1] as const));
23
+ * assert.deepStrictEqual(
24
+ * warnPair,
25
+ * TernaryResult.warn(['left', 1] as const, 'warn'),
26
+ * );
27
+ * assert.deepStrictEqual(errPair, TernaryResult.err('err'));
28
+ * ```
29
+ */
30
+ export const zip = <S1, W1, E1, S2, W2, E2>(
31
+ resultA: TernaryResult<S1, E1, W1>,
32
+ resultB: TernaryResult<S2, E2, W2>,
33
+ ): TernaryResult<readonly [S1, S2], E1 | E2, W1 | W2> => {
34
+ if (isErr(resultA)) {
35
+ return resultA;
36
+ }
37
+
38
+ if (isErr(resultB)) {
39
+ return resultB;
40
+ }
41
+
42
+ const pair = [resultA.value, resultB.value] as const;
43
+
44
+ if (isWarn(resultA)) {
45
+ return warn(pair, resultA.warning);
46
+ }
47
+
48
+ if (isWarn(resultB)) {
49
+ return warn(pair, resultB.warning);
50
+ }
51
+
52
+ return ok(pair);
53
+ };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Extracts the success value type `S` from a `TernaryResult.Ok<S>`.
3
+ */
4
+ export type UnwrapOk<R extends UnknownTernaryResult> =
5
+ R extends TernaryOk<infer S>
6
+ ? S
7
+ : R extends TernaryWarn<infer S, unknown>
8
+ ? S
9
+ : never;
10
+
11
+ /**
12
+ * Extracts the warning value type `W` from a `TernaryResult.Warn<W>`.
13
+ */
14
+ export type UnwrapWarn<R extends UnknownTernaryResult> =
15
+ R extends TernaryWarn<unknown, infer E> ? E : never;
16
+
17
+ /**
18
+ * Extracts the error value type `E` from a `TernaryResult.Err<E>`.
19
+ */
20
+ export type UnwrapErr<R extends UnknownTernaryResult> =
21
+ R extends TernaryErr<infer E> ? E : never;
22
+
23
+ /**
24
+ * Narrows the provided `UnknownTernaryResult` to its Ok variant.
25
+ */
26
+ export type NarrowToOk<R extends UnknownTernaryResult> =
27
+ R extends TernaryOk<unknown> ? R : never;
28
+
29
+ /**
30
+ * Narrows the provided `UnknownTernaryResult` to its Warn variant.
31
+ */
32
+ export type NarrowToWarn<R extends UnknownTernaryResult> =
33
+ R extends TernaryWarn<unknown, unknown> ? R : never;
34
+
35
+ /**
36
+ * Narrows the provided `UnknownTernaryResult` to its Err variant.
37
+ */
38
+ export type NarrowToErr<R extends UnknownTernaryResult> =
39
+ R extends TernaryErr<unknown> ? R : never;
@@ -0,0 +1,17 @@
1
+ import { ErrTypeTagName, OkTypeTagName, WarnTypeTagName } from './tag.mjs';
2
+
3
+ /** @internal Returns the human readable variant label for the given tag. */
4
+ export const variantName = (
5
+ tag: UnknownTernaryResult['$$tag'],
6
+ ): 'Ok' | 'Warn' | 'Err' => {
7
+ switch (tag) {
8
+ case OkTypeTagName:
9
+ return 'Ok';
10
+
11
+ case WarnTypeTagName:
12
+ return 'Warn';
13
+
14
+ case ErrTypeTagName:
15
+ return 'Err';
16
+ }
17
+ };
@@ -0,0 +1 @@
1
+ export * as TernaryResult from './impl/index.mjs';