retuple 1.0.0-next.23 → 1.0.0-next.24

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/dist/index.cjs CHANGED
@@ -12,7 +12,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  };
13
13
  var _ResultAsync_inner, _a, _ResultRetry_f, _ResultRetry_promise, _ResultRetry_times, _ResultRetry_attempt, _ResultRetry_aborted, _ResultRetry_abort, _ResultRetry_getDelay, _ResultRetry_handler;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.RetupleInvalidUnionError = exports.RetupleCaughtValueError = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = void 0;
15
+ exports.RetupleCheckFailedError = exports.RetupleInvalidUnionError = exports.RetupleCaughtValueError = exports.RetupleExpectFailed = exports.RetupleUnwrapErrFailed = exports.RetupleUnwrapFailed = void 0;
16
16
  exports.Result = Result;
17
17
  exports.Ok = Ok;
18
18
  exports.Err = Err;
@@ -84,6 +84,19 @@ class RetupleInvalidUnionError extends Error {
84
84
  }
85
85
  }
86
86
  exports.RetupleInvalidUnionError = RetupleInvalidUnionError;
87
+ /**
88
+ * ## Retuple Check Failed Error
89
+ *
90
+ * This error is used as the error type of a `Result` when using $andAssert
91
+ * or $andCheck, when no custom error handler is provided.
92
+ */
93
+ class RetupleCheckFailedError extends Error {
94
+ constructor(value) {
95
+ super("Check failed");
96
+ this.value = value;
97
+ }
98
+ }
99
+ exports.RetupleCheckFailedError = RetupleCheckFailedError;
87
100
  /**
88
101
  * ## Result
89
102
  *
@@ -532,11 +545,15 @@ class ResultOk extends Array {
532
545
  $mapOrElse(_def, f) {
533
546
  return Ok(f(this[1]));
534
547
  }
535
- $andAssertOr(def, condition = isTruthy) {
536
- return condition(this[1]) ? this : asResult(def);
548
+ $andAssert(mapError = mapCheckError) {
549
+ return this[1] ? this : Err(mapError(this[1]));
537
550
  }
538
- $andAssertOrElse(def, condition = isTruthy) {
539
- return condition(this[1]) ? this : asResult(def(this[1]));
551
+ $andCheck(check, mapError = mapCheckError) {
552
+ return check(this[1]) ? this : Err(mapError(this[1]));
553
+ }
554
+ $andFirst(mapError = mapCheckError) {
555
+ const first = this[1][0];
556
+ return first ? Ok(first) : Err(mapError(this[1]));
540
557
  }
541
558
  $or() {
542
559
  return this;
@@ -675,10 +692,13 @@ class ResultErr extends Array {
675
692
  $mapOrElse(def) {
676
693
  return Ok(def(this[0]));
677
694
  }
678
- $andAssertOr() {
695
+ $andAssert() {
679
696
  return this;
680
697
  }
681
- $andAssertOrElse() {
698
+ $andCheck() {
699
+ return this;
700
+ }
701
+ $andFirst() {
682
702
  return this;
683
703
  }
684
704
  $or(or) {
@@ -849,20 +869,31 @@ class ResultAsync {
849
869
  : new ResultOk(def(res[0]));
850
870
  }));
851
871
  }
852
- $andAssertOr(def, condition = isTruthy) {
872
+ $andAssert(mapError = mapCheckError) {
853
873
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
854
- if (res instanceof ResultErr || condition(res[1])) {
874
+ if (res instanceof ResultErr) {
855
875
  return res;
856
876
  }
857
- return asResult(await def);
877
+ return res[1]
878
+ ? res
879
+ : Err(mapError(res[1]));
858
880
  }));
859
881
  }
860
- $andAssertOrElse(def, condition = isTruthy) {
882
+ $andCheck(check, mapError = mapCheckError) {
861
883
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
862
- if (res instanceof ResultErr || condition(res[1])) {
884
+ if (res instanceof ResultErr) {
885
+ return res;
886
+ }
887
+ return check(res[1]) ? res : Err(mapError(res[1]));
888
+ }));
889
+ }
890
+ $andFirst(mapError = mapCheckError) {
891
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then((res) => {
892
+ if (res instanceof ResultErr) {
863
893
  return res;
864
894
  }
865
- return asResult(await def(res[1]));
895
+ const first = res[1][0];
896
+ return first ? Ok(first) : Err(mapError(res[1]));
866
897
  }));
867
898
  }
868
899
  $or(or) {
@@ -1163,6 +1194,6 @@ function ensureError(err) {
1163
1194
  function mapTrue() {
1164
1195
  return true;
1165
1196
  }
1166
- function isTruthy(val) {
1167
- return !!val;
1197
+ function mapCheckError(value) {
1198
+ return new RetupleCheckFailedError(value);
1168
1199
  }
package/dist/index.d.cts CHANGED
@@ -59,6 +59,16 @@ export declare class RetupleInvalidUnionError extends Error {
59
59
  value: unknown;
60
60
  constructor(value: unknown);
61
61
  }
62
+ /**
63
+ * ## Retuple Check Failed Error
64
+ *
65
+ * This error is used as the error type of a `Result` when using $andAssert
66
+ * or $andCheck, when no custom error handler is provided.
67
+ */
68
+ export declare class RetupleCheckFailedError<const T = unknown> extends Error {
69
+ value: T;
70
+ constructor(value: T);
71
+ }
62
72
  /**
63
73
  * ## Result
64
74
  *
@@ -198,23 +208,33 @@ declare class ResultAsync<T, E> {
198
208
  */
199
209
  $mapOrElse<U, V = U>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => V): ResultAsync<U | V, never>;
200
210
  /**
201
- * The same as {@link Retuple.$andAssertOr|$andAssertOr}, except it:
211
+ * The same as {@link Retuple.$andCheck|$andAssert}, except it:
202
212
  *
203
213
  * - can also accept a `PromiseLike` default value;
204
214
  * - returns {@link ResultAsync}.
205
215
  */
206
- $andAssertOr<U = T, F = E>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>): ResultAsync<Truthy<T> | U, E | F>;
207
- $andAssertOr<U = T, F = E, A extends T = T>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
208
- $andAssertOr<U = T, F = E>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
216
+ $andAssert(this: ResultAsync<T, E>): ResultAsync<Truthy<T>, E | RetupleCheckFailedError<T>>;
217
+ $andAssert<F = E>(this: ResultAsync<T, E>, mapError: (val: T) => F): ResultAsync<Truthy<T>, E | F>;
218
+ /**
219
+ * The same as {@link Retuple.$andCheck|$andCheck}, except it:
220
+ *
221
+ * - can also accept an `async` default function;
222
+ * - returns {@link ResultAsync}.
223
+ */
224
+ $andCheck<U extends T = T>(this: ResultAsync<T, E>, predicate: (val: T) => val is U): ResultAsync<U, E | RetupleCheckFailedError<T>>;
225
+ $andCheck(this: ResultAsync<T, E>, check: (val: T) => unknown): ResultAsync<T, E | RetupleCheckFailedError<T>>;
226
+ $andCheck<U extends T = T, F = E>(this: ResultAsync<T, E>, predicate: (val: T) => val is U, mapError: (val: T) => F): ResultAsync<U, E | F>;
227
+ $andCheck<F = E>(this: ResultAsync<T, E>, check: (val: T) => unknown, mapError: (val: T) => F): ResultAsync<T, E | F>;
209
228
  /**
210
- * The same as {@link Retuple.$andAssertOrElse|$andAssertOrElse}, except it:
229
+ * The same as {@link Retuple.$andCheck|$andCheck}, except it:
211
230
  *
212
231
  * - can also accept an `async` default function;
213
232
  * - returns {@link ResultAsync}.
214
233
  */
215
- $andAssertOrElse<U = T, F = E>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>): ResultAsync<Truthy<T> | U, E | F>;
216
- $andAssertOrElse<U = T, F = E, A extends T = T>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
217
- $andAssertOrElse<U = T, F = E>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
234
+ $andFirst<U>(this: ResultAsync<readonly [U?, ...any[]], E>): ResultAsync<U, E | RetupleCheckFailedError<T>>;
235
+ $andFirst(this: ResultAsync<readonly [], E>): ResultAsync<never, E | RetupleCheckFailedError<T>>;
236
+ $andFirst<U, F = E>(this: ResultAsync<readonly [U?, ...any[]], E>, mapError: (val: T) => F): ResultAsync<U, E | F>;
237
+ $andFirst<F = E>(this: ResultAsync<readonly [], E>, mapError: (val: T) => F): ResultAsync<T, E | F>;
218
238
  /**
219
239
  * The same as {@link Retuple.$or|$or}, except it:
220
240
  *
@@ -727,164 +747,118 @@ interface Retuple<T, E> extends ResultLike<T, E> {
727
747
  /**
728
748
  * Performs an assertion when this result is `Ok`:
729
749
  *
730
- * - returning `Ok` containing the current ok value when it is truthy, and
731
- * when no predicate/condition function is provided. Narrows the `T` type
732
- * to include only truthy values;
733
- * - returning `Ok` containing the current ok value when a
734
- * predicate/condition function is provided and it returns a truthy value.
735
- * Narrows the `T` type to the predicate type (if any);
736
- * - returning the default result when no predicate/condition function is
737
- * provided and the current ok value is falsey;
738
- * - returning the default result when a predicate/condition function is
739
- * provided and it returns a falsey value.
750
+ * - returning `Ok` containing the current ok value when it is truthy.
751
+ * Narrows the `T` type to include only truthy values;
752
+ * - returning `Err` containing the return value of the map error function
753
+ * when the ok value is falsey;
754
+ * - returning `Err` containing {@link RetupleCheckFailedError} when the
755
+ * ok value is falsey, and when no map error function is provided.
740
756
  *
741
757
  * Otherwise returns `Err` containing the current error value.
742
758
  *
743
759
  * @example
744
760
  *
745
761
  * ```ts
746
- * const result: Result<string | null, string> = Ok("test");
747
- * const asserted = result.$andAssertOr(Ok("ok-default"));
762
+ * const result: Result<string | null, never> = Ok("test");
763
+ * const asserted = result.$andAssert();
748
764
  *
749
- * asserted satisfies Result<string, string>;
765
+ * asserted satisfies Result<string, RetupleCheckFailedError<string | null>>;
750
766
  * assert.equal(asserted.$unwrap(), "test");
751
767
  * ```
752
768
  *
753
769
  * @example
754
770
  *
755
771
  * ```ts
756
- * const result: Result<string | null, string> = Ok("test");
757
- * const asserted = result.$andAssertOr(
758
- * Err("err-default"),
759
- * (val): val is "test" => val === "test",
772
+ * const result: Result<string | null | undefined, never> = Ok(null);
773
+ * const asserted = result.$andAssert(
774
+ * (val) => val === null ? "value was null" : "value was undefined"
760
775
  * );
761
776
  *
762
- * asserted satisfies Result<"test", string>;
763
- * assert.equal(asserted.$unwrap(), "test");
764
- * ```
765
- *
766
- * @example
767
- *
768
- * ```ts
769
- * const result: Result<string | null, string> = Ok(null);
770
- * const asserted = result.$andAssertOr(Ok("ok-default"));
771
- *
772
777
  * asserted satisfies Result<string, string>;
773
- * assert.equal(asserted.$unwrap(), "ok-default");
774
- * ```
775
- *
776
- * @example
777
- *
778
- * ```ts
779
- * const result: Result<string | null, string> = Ok("value");
780
- * const asserted = result.$andAssertOr(
781
- * Err("err-default"),
782
- * (val): val is "test" => val === "test",
783
- * );
784
- *
785
- * asserted satisfies Result<"test", string>;
786
- * assert.equal(asserted.$unwrapErr(), "err-default");
787
- * ```
788
- *
789
- * @example
790
- *
791
- * ```ts
792
- * const result: Result<string | null, string> = Err("test");
793
- * const asserted = result.$andAssertOr(
794
- * Err("err-default"),
795
- * (val): val is "test" => val === "test",
796
- * );
797
- *
798
- * asserted satisfies Result<"test", string>;
799
- * assert.equal(asserted.$unwrapErr(), "test");
778
+ * assert.equal(asserted.$unwrapErr(), "value was null");
800
779
  * ```
801
780
  */
802
- $andAssertOr<U = T, F = E>(this: Result<T, E>, def: ResultLike<U, F>): Result<Truthy<T> | U, E | F>;
803
- $andAssertOr<U = T, F = E, A extends T = T>(this: Result<T, E>, def: ResultLike<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
804
- $andAssertOr<U = T, F = E>(this: Result<T, E>, def: ResultLike<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
781
+ $andAssert(this: Result<T, E>): Result<Truthy<T>, E | RetupleCheckFailedError<T>>;
782
+ $andAssert<F = E>(this: Result<T, E>, mapError: (val: T) => F): Result<Truthy<T>, E | F>;
805
783
  /**
806
- * Performs an assertion when this result is `Ok`:
784
+ * Performs a check when this result is `Ok`:
807
785
  *
808
- * - returning `Ok` containing the current ok value when it is truthy, and
809
- * when no predicate/condition function is provided. Narrows the `T` type
810
- * to include only truthy values;
811
- * - returning `Ok` containing the current ok value when a
812
- * predicate/condition function is provided and it returns a truthy value.
813
- * Narrows the `T` type to the predicate type (if any);
814
- * - returning the result returned by the default function when no
815
- * predicate/condition function is provided and the current ok value is
816
- * falsey;
817
- * - returning the result returned by the default function when a
818
- * predicate/condition function is provided and it returns a falsey value.
786
+ * - returning `Ok` containing the current ok value when the predicate/check
787
+ * function returns true. Narrows the `T` type based on the check function;
788
+ * - returning `Err` containing the return value of the map error function
789
+ * when the ok value fails the check;
790
+ * - returning `Err` containing {@link RetupleCheckFailedError} when the
791
+ * ok value fails the check, and when no map error function is provided.
819
792
  *
820
793
  * Otherwise returns `Err` containing the current error value.
821
794
  *
822
795
  * @example
823
796
  *
824
797
  * ```ts
825
- * const result: Result<string | null, string> = Ok("test");
826
- * const asserted = result.$andAssertOrElse(
827
- * (val) => Ok(`ok-default:${val}`),
828
- * );
798
+ * const result: Result<string, never> = Ok("test");
799
+ * const asserted = result.$andCheck((val) => val === "test");
829
800
  *
830
- * asserted satisfies Result<string, string>;
801
+ * asserted satisfies Result<string, RetupleCheckFailedError<string>>;
831
802
  * assert.equal(asserted.$unwrap(), "test");
832
803
  * ```
833
804
  *
834
805
  * @example
835
806
  *
836
807
  * ```ts
837
- * const result: Result<string | null, string> = Ok("test");
838
- * const asserted = result.$andAssertOrElse(
839
- * (val) => Err(`err-default:${val}`),
840
- * (val): val is "test" => val === "test",
808
+ * const result: Result<string, never> = Ok("test");
809
+ * const checked = result.$andCheck(
810
+ * (val) => val === "value",
811
+ * (val) => `value was ${val}`,
841
812
  * );
842
813
  *
843
- * asserted satisfies Result<"test", string>;
844
- * assert.equal(asserted.$unwrap(), "test");
814
+ * checked satisfies Result<"value", string>;
815
+ * assert.equal(checked.$unwrapErr(), "value was test");
845
816
  * ```
817
+ */
818
+ $andCheck<U extends T = T>(this: Result<T, E>, predicate: (val: T) => val is U): Result<U, E | RetupleCheckFailedError<T>>;
819
+ $andCheck(this: Result<T, E>, check: (val: T) => unknown): Result<T, E | RetupleCheckFailedError<T>>;
820
+ $andCheck<U extends T = T, F = E>(this: Result<T, E>, predicate: (val: T) => val is U, mapError: (val: T) => F): Result<U, E | F>;
821
+ $andCheck<F = E>(this: Result<T, E>, check: (val: T) => unknown, mapError: (val: T) => F): Result<T, E | F>;
822
+ /**
823
+ * Checks the first element of the contained array when when this result
824
+ * is `Ok`:
846
825
  *
847
- * @example
848
- *
849
- * ```ts
850
- * const result: Result<string | null, string> = Ok(null);
851
- * const asserted = result.$andAssertOrElse(
852
- * (val) => Ok(`ok-default:${val}`),
853
- * );
826
+ * - returning `Ok` containing the first array element when it is truthy.
827
+ * Narrows the type to include only truthy values;
828
+ * - returning `Err` containing the return value of the map error function
829
+ * when the first array element fails the check;
830
+ * - returning `Err` containing {@link RetupleCheckFailedError} when the
831
+ * first array elemnt fails the check, and when no map error function is
832
+ * provided.
854
833
  *
855
- * asserted satisfies Result<string, string>;
856
- * assert.equal(asserted.$unwrap(), "ok-default:null");
857
- * ```
834
+ * Otherwise returns `Err` containing the current error value.
858
835
  *
859
836
  * @example
860
837
  *
861
838
  * ```ts
862
- * const result: Result<string | null, string> = Ok("value");
863
- * const asserted = result.$andAssertOrElse(
864
- * (val) => Err(`err-default:${val}`),
865
- * (val): val is "test" => val === "test",
866
- * );
839
+ * const result: Result<(string | null)[], never> = Ok(["test", null]);
840
+ * const first = result.$andFirst();
867
841
  *
868
- * asserted satisfies Result<"test", string>;
869
- * assert.equal(asserted.$unwrapErr(), "err-default:value");
842
+ * first satisfies Result<string, RetupleCheckFailedError<string | null>>;
843
+ * assert.equal(first.$unwrap(), "test");
870
844
  * ```
871
845
  *
872
846
  * @example
873
847
  *
874
848
  * ```ts
875
- * const result: Result<string | null, string> = Err("test");
876
- * const asserted = result.$andAssertOrElse(
877
- * (val) => Err(`err-default:${val}`),
878
- * (val): val is "test" => val === "test",
849
+ * const result: Result<(string | null | undefined)[], never> = Ok([null, "test"]);
850
+ * const first = result.$andFirst(
851
+ * (val) => val === null ? "value was null" : "value was undefined",
879
852
  * );
880
853
  *
881
- * asserted satisfies Result<"test", string>;
882
- * assert.equal(asserted.$unwrapErr(), "test");
854
+ * first satisfies Result<string, string>;
855
+ * assert.equal(first.$unwrapErr(), "value was null");
883
856
  * ```
884
857
  */
885
- $andAssertOrElse<U = T, F = E>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>): Result<Truthy<T> | U, E | F>;
886
- $andAssertOrElse<U = T, F = E, A extends T = T>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
887
- $andAssertOrElse<U = T, F = E>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
858
+ $andFirst(this: Result<readonly [], E>): Result<never, E | RetupleCheckFailedError<[]>>;
859
+ $andFirst<U>(this: Result<readonly [U?, ...any[]], E>): Result<Truthy<U>, E | RetupleCheckFailedError<T>>;
860
+ $andFirst<F = E>(this: Result<readonly [], E>, mapError: (val: readonly []) => F): Result<never, E | F>;
861
+ $andFirst<U, F = E>(this: Result<readonly [U?, ...any[]], E>, mapError: (val: T) => F): Result<Truthy<U>, E | F>;
888
862
  /**
889
863
  * Returns `Ok` containing the return value of the map function when this
890
864
  * result is `Ok`.
@@ -911,10 +885,10 @@ interface Retuple<T, E> extends ResultLike<T, E> {
911
885
  * );
912
886
  * ```
913
887
  */
914
- $map<U>(this: Result<T, E>, f: (value: T) => U): Result<U, E>;
888
+ $map<U>(this: Result<T, E>, f: (val: T) => U): Result<U, E>;
915
889
  /**
916
- * Returns `Err` containing the return value of the map function when this
917
- * result is `Err`.
890
+ * Returns `Err` containing the return value of the map error function
891
+ * when this result is `Err`.
918
892
  *
919
893
  * Otherwise, returns `Ok` containing the current ok value.
920
894
  *
@@ -1351,10 +1325,6 @@ interface Retuple<T, E> extends ResultLike<T, E> {
1351
1325
  *
1352
1326
  * Otherwise returns `Err` containing the current error value.
1353
1327
  *
1354
- * This method should only be called when the `T` type is `Result`. This
1355
- * is enforced with a type constraint. If the ok value is not
1356
- * a result, `RetupleFlattenFailed` is thrown.
1357
- *
1358
1328
  * @example
1359
1329
  *
1360
1330
  * ```ts
package/dist/index.d.ts CHANGED
@@ -59,6 +59,16 @@ export declare class RetupleInvalidUnionError extends Error {
59
59
  value: unknown;
60
60
  constructor(value: unknown);
61
61
  }
62
+ /**
63
+ * ## Retuple Check Failed Error
64
+ *
65
+ * This error is used as the error type of a `Result` when using $andAssert
66
+ * or $andCheck, when no custom error handler is provided.
67
+ */
68
+ export declare class RetupleCheckFailedError<const T = unknown> extends Error {
69
+ value: T;
70
+ constructor(value: T);
71
+ }
62
72
  /**
63
73
  * ## Result
64
74
  *
@@ -198,23 +208,33 @@ declare class ResultAsync<T, E> {
198
208
  */
199
209
  $mapOrElse<U, V = U>(this: ResultAsync<T, E>, def: (err: E) => U, f: (val: T) => V): ResultAsync<U | V, never>;
200
210
  /**
201
- * The same as {@link Retuple.$andAssertOr|$andAssertOr}, except it:
211
+ * The same as {@link Retuple.$andCheck|$andAssert}, except it:
202
212
  *
203
213
  * - can also accept a `PromiseLike` default value;
204
214
  * - returns {@link ResultAsync}.
205
215
  */
206
- $andAssertOr<U = T, F = E>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>): ResultAsync<Truthy<T> | U, E | F>;
207
- $andAssertOr<U = T, F = E, A extends T = T>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
208
- $andAssertOr<U = T, F = E>(this: ResultAsync<T, E>, def: ResultLikeAwaitable<U, F>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
216
+ $andAssert(this: ResultAsync<T, E>): ResultAsync<Truthy<T>, E | RetupleCheckFailedError<T>>;
217
+ $andAssert<F = E>(this: ResultAsync<T, E>, mapError: (val: T) => F): ResultAsync<Truthy<T>, E | F>;
218
+ /**
219
+ * The same as {@link Retuple.$andCheck|$andCheck}, except it:
220
+ *
221
+ * - can also accept an `async` default function;
222
+ * - returns {@link ResultAsync}.
223
+ */
224
+ $andCheck<U extends T = T>(this: ResultAsync<T, E>, predicate: (val: T) => val is U): ResultAsync<U, E | RetupleCheckFailedError<T>>;
225
+ $andCheck(this: ResultAsync<T, E>, check: (val: T) => unknown): ResultAsync<T, E | RetupleCheckFailedError<T>>;
226
+ $andCheck<U extends T = T, F = E>(this: ResultAsync<T, E>, predicate: (val: T) => val is U, mapError: (val: T) => F): ResultAsync<U, E | F>;
227
+ $andCheck<F = E>(this: ResultAsync<T, E>, check: (val: T) => unknown, mapError: (val: T) => F): ResultAsync<T, E | F>;
209
228
  /**
210
- * The same as {@link Retuple.$andAssertOrElse|$andAssertOrElse}, except it:
229
+ * The same as {@link Retuple.$andCheck|$andCheck}, except it:
211
230
  *
212
231
  * - can also accept an `async` default function;
213
232
  * - returns {@link ResultAsync}.
214
233
  */
215
- $andAssertOrElse<U = T, F = E>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>): ResultAsync<Truthy<T> | U, E | F>;
216
- $andAssertOrElse<U = T, F = E, A extends T = T>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>, predicate: (val: T) => val is A): ResultAsync<U | A, E | F>;
217
- $andAssertOrElse<U = T, F = E>(this: ResultAsync<T, E>, def: (val: T) => ResultLikeAwaitable<U, F>, condition: (val: T) => unknown): ResultAsync<T | U, E | F>;
234
+ $andFirst<U>(this: ResultAsync<readonly [U?, ...any[]], E>): ResultAsync<U, E | RetupleCheckFailedError<T>>;
235
+ $andFirst(this: ResultAsync<readonly [], E>): ResultAsync<never, E | RetupleCheckFailedError<T>>;
236
+ $andFirst<U, F = E>(this: ResultAsync<readonly [U?, ...any[]], E>, mapError: (val: T) => F): ResultAsync<U, E | F>;
237
+ $andFirst<F = E>(this: ResultAsync<readonly [], E>, mapError: (val: T) => F): ResultAsync<T, E | F>;
218
238
  /**
219
239
  * The same as {@link Retuple.$or|$or}, except it:
220
240
  *
@@ -727,164 +747,118 @@ interface Retuple<T, E> extends ResultLike<T, E> {
727
747
  /**
728
748
  * Performs an assertion when this result is `Ok`:
729
749
  *
730
- * - returning `Ok` containing the current ok value when it is truthy, and
731
- * when no predicate/condition function is provided. Narrows the `T` type
732
- * to include only truthy values;
733
- * - returning `Ok` containing the current ok value when a
734
- * predicate/condition function is provided and it returns a truthy value.
735
- * Narrows the `T` type to the predicate type (if any);
736
- * - returning the default result when no predicate/condition function is
737
- * provided and the current ok value is falsey;
738
- * - returning the default result when a predicate/condition function is
739
- * provided and it returns a falsey value.
750
+ * - returning `Ok` containing the current ok value when it is truthy.
751
+ * Narrows the `T` type to include only truthy values;
752
+ * - returning `Err` containing the return value of the map error function
753
+ * when the ok value is falsey;
754
+ * - returning `Err` containing {@link RetupleCheckFailedError} when the
755
+ * ok value is falsey, and when no map error function is provided.
740
756
  *
741
757
  * Otherwise returns `Err` containing the current error value.
742
758
  *
743
759
  * @example
744
760
  *
745
761
  * ```ts
746
- * const result: Result<string | null, string> = Ok("test");
747
- * const asserted = result.$andAssertOr(Ok("ok-default"));
762
+ * const result: Result<string | null, never> = Ok("test");
763
+ * const asserted = result.$andAssert();
748
764
  *
749
- * asserted satisfies Result<string, string>;
765
+ * asserted satisfies Result<string, RetupleCheckFailedError<string | null>>;
750
766
  * assert.equal(asserted.$unwrap(), "test");
751
767
  * ```
752
768
  *
753
769
  * @example
754
770
  *
755
771
  * ```ts
756
- * const result: Result<string | null, string> = Ok("test");
757
- * const asserted = result.$andAssertOr(
758
- * Err("err-default"),
759
- * (val): val is "test" => val === "test",
772
+ * const result: Result<string | null | undefined, never> = Ok(null);
773
+ * const asserted = result.$andAssert(
774
+ * (val) => val === null ? "value was null" : "value was undefined"
760
775
  * );
761
776
  *
762
- * asserted satisfies Result<"test", string>;
763
- * assert.equal(asserted.$unwrap(), "test");
764
- * ```
765
- *
766
- * @example
767
- *
768
- * ```ts
769
- * const result: Result<string | null, string> = Ok(null);
770
- * const asserted = result.$andAssertOr(Ok("ok-default"));
771
- *
772
777
  * asserted satisfies Result<string, string>;
773
- * assert.equal(asserted.$unwrap(), "ok-default");
774
- * ```
775
- *
776
- * @example
777
- *
778
- * ```ts
779
- * const result: Result<string | null, string> = Ok("value");
780
- * const asserted = result.$andAssertOr(
781
- * Err("err-default"),
782
- * (val): val is "test" => val === "test",
783
- * );
784
- *
785
- * asserted satisfies Result<"test", string>;
786
- * assert.equal(asserted.$unwrapErr(), "err-default");
787
- * ```
788
- *
789
- * @example
790
- *
791
- * ```ts
792
- * const result: Result<string | null, string> = Err("test");
793
- * const asserted = result.$andAssertOr(
794
- * Err("err-default"),
795
- * (val): val is "test" => val === "test",
796
- * );
797
- *
798
- * asserted satisfies Result<"test", string>;
799
- * assert.equal(asserted.$unwrapErr(), "test");
778
+ * assert.equal(asserted.$unwrapErr(), "value was null");
800
779
  * ```
801
780
  */
802
- $andAssertOr<U = T, F = E>(this: Result<T, E>, def: ResultLike<U, F>): Result<Truthy<T> | U, E | F>;
803
- $andAssertOr<U = T, F = E, A extends T = T>(this: Result<T, E>, def: ResultLike<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
804
- $andAssertOr<U = T, F = E>(this: Result<T, E>, def: ResultLike<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
781
+ $andAssert(this: Result<T, E>): Result<Truthy<T>, E | RetupleCheckFailedError<T>>;
782
+ $andAssert<F = E>(this: Result<T, E>, mapError: (val: T) => F): Result<Truthy<T>, E | F>;
805
783
  /**
806
- * Performs an assertion when this result is `Ok`:
784
+ * Performs a check when this result is `Ok`:
807
785
  *
808
- * - returning `Ok` containing the current ok value when it is truthy, and
809
- * when no predicate/condition function is provided. Narrows the `T` type
810
- * to include only truthy values;
811
- * - returning `Ok` containing the current ok value when a
812
- * predicate/condition function is provided and it returns a truthy value.
813
- * Narrows the `T` type to the predicate type (if any);
814
- * - returning the result returned by the default function when no
815
- * predicate/condition function is provided and the current ok value is
816
- * falsey;
817
- * - returning the result returned by the default function when a
818
- * predicate/condition function is provided and it returns a falsey value.
786
+ * - returning `Ok` containing the current ok value when the predicate/check
787
+ * function returns true. Narrows the `T` type based on the check function;
788
+ * - returning `Err` containing the return value of the map error function
789
+ * when the ok value fails the check;
790
+ * - returning `Err` containing {@link RetupleCheckFailedError} when the
791
+ * ok value fails the check, and when no map error function is provided.
819
792
  *
820
793
  * Otherwise returns `Err` containing the current error value.
821
794
  *
822
795
  * @example
823
796
  *
824
797
  * ```ts
825
- * const result: Result<string | null, string> = Ok("test");
826
- * const asserted = result.$andAssertOrElse(
827
- * (val) => Ok(`ok-default:${val}`),
828
- * );
798
+ * const result: Result<string, never> = Ok("test");
799
+ * const asserted = result.$andCheck((val) => val === "test");
829
800
  *
830
- * asserted satisfies Result<string, string>;
801
+ * asserted satisfies Result<string, RetupleCheckFailedError<string>>;
831
802
  * assert.equal(asserted.$unwrap(), "test");
832
803
  * ```
833
804
  *
834
805
  * @example
835
806
  *
836
807
  * ```ts
837
- * const result: Result<string | null, string> = Ok("test");
838
- * const asserted = result.$andAssertOrElse(
839
- * (val) => Err(`err-default:${val}`),
840
- * (val): val is "test" => val === "test",
808
+ * const result: Result<string, never> = Ok("test");
809
+ * const checked = result.$andCheck(
810
+ * (val) => val === "value",
811
+ * (val) => `value was ${val}`,
841
812
  * );
842
813
  *
843
- * asserted satisfies Result<"test", string>;
844
- * assert.equal(asserted.$unwrap(), "test");
814
+ * checked satisfies Result<"value", string>;
815
+ * assert.equal(checked.$unwrapErr(), "value was test");
845
816
  * ```
817
+ */
818
+ $andCheck<U extends T = T>(this: Result<T, E>, predicate: (val: T) => val is U): Result<U, E | RetupleCheckFailedError<T>>;
819
+ $andCheck(this: Result<T, E>, check: (val: T) => unknown): Result<T, E | RetupleCheckFailedError<T>>;
820
+ $andCheck<U extends T = T, F = E>(this: Result<T, E>, predicate: (val: T) => val is U, mapError: (val: T) => F): Result<U, E | F>;
821
+ $andCheck<F = E>(this: Result<T, E>, check: (val: T) => unknown, mapError: (val: T) => F): Result<T, E | F>;
822
+ /**
823
+ * Checks the first element of the contained array when when this result
824
+ * is `Ok`:
846
825
  *
847
- * @example
848
- *
849
- * ```ts
850
- * const result: Result<string | null, string> = Ok(null);
851
- * const asserted = result.$andAssertOrElse(
852
- * (val) => Ok(`ok-default:${val}`),
853
- * );
826
+ * - returning `Ok` containing the first array element when it is truthy.
827
+ * Narrows the type to include only truthy values;
828
+ * - returning `Err` containing the return value of the map error function
829
+ * when the first array element fails the check;
830
+ * - returning `Err` containing {@link RetupleCheckFailedError} when the
831
+ * first array elemnt fails the check, and when no map error function is
832
+ * provided.
854
833
  *
855
- * asserted satisfies Result<string, string>;
856
- * assert.equal(asserted.$unwrap(), "ok-default:null");
857
- * ```
834
+ * Otherwise returns `Err` containing the current error value.
858
835
  *
859
836
  * @example
860
837
  *
861
838
  * ```ts
862
- * const result: Result<string | null, string> = Ok("value");
863
- * const asserted = result.$andAssertOrElse(
864
- * (val) => Err(`err-default:${val}`),
865
- * (val): val is "test" => val === "test",
866
- * );
839
+ * const result: Result<(string | null)[], never> = Ok(["test", null]);
840
+ * const first = result.$andFirst();
867
841
  *
868
- * asserted satisfies Result<"test", string>;
869
- * assert.equal(asserted.$unwrapErr(), "err-default:value");
842
+ * first satisfies Result<string, RetupleCheckFailedError<string | null>>;
843
+ * assert.equal(first.$unwrap(), "test");
870
844
  * ```
871
845
  *
872
846
  * @example
873
847
  *
874
848
  * ```ts
875
- * const result: Result<string | null, string> = Err("test");
876
- * const asserted = result.$andAssertOrElse(
877
- * (val) => Err(`err-default:${val}`),
878
- * (val): val is "test" => val === "test",
849
+ * const result: Result<(string | null | undefined)[], never> = Ok([null, "test"]);
850
+ * const first = result.$andFirst(
851
+ * (val) => val === null ? "value was null" : "value was undefined",
879
852
  * );
880
853
  *
881
- * asserted satisfies Result<"test", string>;
882
- * assert.equal(asserted.$unwrapErr(), "test");
854
+ * first satisfies Result<string, string>;
855
+ * assert.equal(first.$unwrapErr(), "value was null");
883
856
  * ```
884
857
  */
885
- $andAssertOrElse<U = T, F = E>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>): Result<Truthy<T> | U, E | F>;
886
- $andAssertOrElse<U = T, F = E, A extends T = T>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>, predicate: (val: T) => val is A): Result<U | A, E | F>;
887
- $andAssertOrElse<U = T, F = E>(this: Result<T, E>, def: (val: T) => ResultLike<U, F>, condition: (val: T) => unknown): Result<T | U, E | F>;
858
+ $andFirst(this: Result<readonly [], E>): Result<never, E | RetupleCheckFailedError<[]>>;
859
+ $andFirst<U>(this: Result<readonly [U?, ...any[]], E>): Result<Truthy<U>, E | RetupleCheckFailedError<T>>;
860
+ $andFirst<F = E>(this: Result<readonly [], E>, mapError: (val: readonly []) => F): Result<never, E | F>;
861
+ $andFirst<U, F = E>(this: Result<readonly [U?, ...any[]], E>, mapError: (val: T) => F): Result<Truthy<U>, E | F>;
888
862
  /**
889
863
  * Returns `Ok` containing the return value of the map function when this
890
864
  * result is `Ok`.
@@ -911,10 +885,10 @@ interface Retuple<T, E> extends ResultLike<T, E> {
911
885
  * );
912
886
  * ```
913
887
  */
914
- $map<U>(this: Result<T, E>, f: (value: T) => U): Result<U, E>;
888
+ $map<U>(this: Result<T, E>, f: (val: T) => U): Result<U, E>;
915
889
  /**
916
- * Returns `Err` containing the return value of the map function when this
917
- * result is `Err`.
890
+ * Returns `Err` containing the return value of the map error function
891
+ * when this result is `Err`.
918
892
  *
919
893
  * Otherwise, returns `Ok` containing the current ok value.
920
894
  *
@@ -1351,10 +1325,6 @@ interface Retuple<T, E> extends ResultLike<T, E> {
1351
1325
  *
1352
1326
  * Otherwise returns `Err` containing the current error value.
1353
1327
  *
1354
- * This method should only be called when the `T` type is `Result`. This
1355
- * is enforced with a type constraint. If the ok value is not
1356
- * a result, `RetupleFlattenFailed` is thrown.
1357
- *
1358
1328
  * @example
1359
1329
  *
1360
1330
  * ```ts
package/dist/index.js CHANGED
@@ -73,6 +73,18 @@ export class RetupleInvalidUnionError extends Error {
73
73
  this.value = value;
74
74
  }
75
75
  }
76
+ /**
77
+ * ## Retuple Check Failed Error
78
+ *
79
+ * This error is used as the error type of a `Result` when using $andAssert
80
+ * or $andCheck, when no custom error handler is provided.
81
+ */
82
+ export class RetupleCheckFailedError extends Error {
83
+ constructor(value) {
84
+ super("Check failed");
85
+ this.value = value;
86
+ }
87
+ }
76
88
  /**
77
89
  * ## Result
78
90
  *
@@ -521,11 +533,15 @@ class ResultOk extends Array {
521
533
  $mapOrElse(_def, f) {
522
534
  return Ok(f(this[1]));
523
535
  }
524
- $andAssertOr(def, condition = isTruthy) {
525
- return condition(this[1]) ? this : asResult(def);
536
+ $andAssert(mapError = mapCheckError) {
537
+ return this[1] ? this : Err(mapError(this[1]));
526
538
  }
527
- $andAssertOrElse(def, condition = isTruthy) {
528
- return condition(this[1]) ? this : asResult(def(this[1]));
539
+ $andCheck(check, mapError = mapCheckError) {
540
+ return check(this[1]) ? this : Err(mapError(this[1]));
541
+ }
542
+ $andFirst(mapError = mapCheckError) {
543
+ const first = this[1][0];
544
+ return first ? Ok(first) : Err(mapError(this[1]));
529
545
  }
530
546
  $or() {
531
547
  return this;
@@ -664,10 +680,13 @@ class ResultErr extends Array {
664
680
  $mapOrElse(def) {
665
681
  return Ok(def(this[0]));
666
682
  }
667
- $andAssertOr() {
683
+ $andAssert() {
668
684
  return this;
669
685
  }
670
- $andAssertOrElse() {
686
+ $andCheck() {
687
+ return this;
688
+ }
689
+ $andFirst() {
671
690
  return this;
672
691
  }
673
692
  $or(or) {
@@ -838,20 +857,31 @@ class ResultAsync {
838
857
  : new ResultOk(def(res[0]));
839
858
  }));
840
859
  }
841
- $andAssertOr(def, condition = isTruthy) {
860
+ $andAssert(mapError = mapCheckError) {
842
861
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
843
- if (res instanceof ResultErr || condition(res[1])) {
862
+ if (res instanceof ResultErr) {
844
863
  return res;
845
864
  }
846
- return asResult(await def);
865
+ return res[1]
866
+ ? res
867
+ : Err(mapError(res[1]));
847
868
  }));
848
869
  }
849
- $andAssertOrElse(def, condition = isTruthy) {
870
+ $andCheck(check, mapError = mapCheckError) {
850
871
  return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then(async (res) => {
851
- if (res instanceof ResultErr || condition(res[1])) {
872
+ if (res instanceof ResultErr) {
873
+ return res;
874
+ }
875
+ return check(res[1]) ? res : Err(mapError(res[1]));
876
+ }));
877
+ }
878
+ $andFirst(mapError = mapCheckError) {
879
+ return new ResultAsync(__classPrivateFieldGet(this, _ResultAsync_inner, "f").then((res) => {
880
+ if (res instanceof ResultErr) {
852
881
  return res;
853
882
  }
854
- return asResult(await def(res[1]));
883
+ const first = res[1][0];
884
+ return first ? Ok(first) : Err(mapError(res[1]));
855
885
  }));
856
886
  }
857
887
  $or(or) {
@@ -1152,6 +1182,6 @@ function ensureError(err) {
1152
1182
  function mapTrue() {
1153
1183
  return true;
1154
1184
  }
1155
- function isTruthy(val) {
1156
- return !!val;
1185
+ function mapCheckError(value) {
1186
+ return new RetupleCheckFailedError(value);
1157
1187
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "retuple",
3
- "version": "1.0.0-next.23",
3
+ "version": "1.0.0-next.24",
4
4
  "scripts": {
5
5
  "test": "vitest",
6
6
  "lint": "eslint . --ext .ts -c eslint.config.mjs --fix",