@j2blasco/ts-result 0.0.9 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./result"), exports);
18
18
  __exportStar(require("./result-functions"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,qDAAmC"}
@@ -8,3 +8,4 @@ function andThen(callback) {
8
8
  function andThenAsync(callback) {
9
9
  return (result) => result.andThenAsync(callback);
10
10
  }
11
+ //# sourceMappingURL=result-functions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-functions.js","sourceRoot":"","sources":["../../src/result-functions.ts"],"names":[],"mappings":";;AAEA,0BAMC;AAED,oCAUC;AAlBD,SAAgB,OAAO,CACrB,QAAsC;IAItC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,SAAgB,YAAY,CAK1B,QAA+C;IAI/C,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AACnD,CAAC"}
@@ -93,3 +93,4 @@ function makeSafePromise(promise) {
93
93
  .then((value) => resultSuccess(value))
94
94
  .catch((error) => resultError.unknown(error.message));
95
95
  }
96
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/result.ts"],"names":[],"mappings":"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"}
@@ -6,3 +6,4 @@ function assertType(_value) { }
6
6
  function expectToCompile() {
7
7
  expect(true).toBe(true);
8
8
  }
9
+ //# sourceMappingURL=assert-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-type.js","sourceRoot":"","sources":["../../../../src/utils/test/assert-type.ts"],"names":[],"mappings":";;AAAA,gCAEU;AAEV,0CAEC;AAND,SAAgB,UAAU,CACxB,MAAgD,IACzC,CAAC;AAEV,SAAgB,eAAe;IAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
package/dist/esm/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from './result';
2
2
  export * from './result-functions';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC"}
@@ -4,3 +4,4 @@ export function andThen(callback) {
4
4
  export function andThenAsync(callback) {
5
5
  return (result) => result.andThenAsync(callback);
6
6
  }
7
+ //# sourceMappingURL=result-functions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-functions.js","sourceRoot":"","sources":["../../src/result-functions.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,OAAO,CACrB,QAAsC;IAItC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,YAAY,CAK1B,QAA+C;IAI/C,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AACnD,CAAC"}
@@ -83,3 +83,4 @@ export function makeSafePromise(promise) {
83
83
  .then((value) => resultSuccess(value))
84
84
  .catch((error) => resultError.unknown(error.message));
85
85
  }
86
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/result.ts"],"names":[],"mappings":"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"}
@@ -2,3 +2,4 @@ export function assertType(_value) { }
2
2
  export function expectToCompile() {
3
3
  expect(true).toBe(true);
4
4
  }
5
+ //# sourceMappingURL=assert-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-type.js","sourceRoot":"","sources":["../../../../src/utils/test/assert-type.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CACxB,MAAgD,IACzC,CAAC;AAEV,MAAM,UAAU,eAAe;IAC7B,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@j2blasco/ts-result",
3
- "version": "0.0.9",
3
+ "version": "0.1.1",
4
4
  "description": "Result Monad for TypeScript", "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "repository": {
@@ -18,6 +18,7 @@
18
18
  "dist/cjs",
19
19
  "dist/esm",
20
20
  "types",
21
+ "src",
21
22
  "README.md",
22
23
  "LICENSE"
23
24
  ], "scripts": {
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './result';
2
+ export * from './result-functions';
@@ -0,0 +1,34 @@
1
+ import { asyncPipe, pipe } from "@j2blasco/ts-pipe";
2
+ import { andThen, andThenAsync } from "./result-functions";
3
+ import { resultSuccess } from "./result";
4
+ import { assertType } from "./utils/test/assert-type";
5
+
6
+ function doSomething() {
7
+ return resultSuccess("5");
8
+ }
9
+
10
+ describe("Result integration with ts-pipe", () => {
11
+ test("asyncPipe", async () => {
12
+ var result = await asyncPipe(
13
+ doSomething(),
14
+ andThenAsync(async (_e) => resultSuccess(new Date())),
15
+ andThen((r) => {
16
+ assertType<typeof r, Date>(true);
17
+ return resultSuccess("test");
18
+ })
19
+ );
20
+ expect(result.unwrapOrThrow()).toBe("test");
21
+ });
22
+
23
+ test("pipe", async () => {
24
+ var result = pipe(
25
+ doSomething(),
26
+ andThen((_e) => resultSuccess(new Date())),
27
+ andThen((r) => {
28
+ assertType<typeof r, Date>(true);
29
+ return resultSuccess("test");
30
+ })
31
+ );
32
+ expect(result.unwrapOrThrow()).toBe("test");
33
+ });
34
+ });
@@ -0,0 +1,21 @@
1
+ import { ErrorType, Result, SuccessType } from "./result";
2
+
3
+ export function andThen<TSuccess, TError, TResult extends Result<any, any>>(
4
+ callback: (value: TSuccess) => TResult
5
+ ): (
6
+ result: Result<TSuccess, TError>
7
+ ) => Result<SuccessType<TResult>, TError | ErrorType<TResult>> {
8
+ return (result) => result.andThen(callback);
9
+ }
10
+
11
+ export function andThenAsync<
12
+ TSuccess,
13
+ TError,
14
+ TResult extends Result<any, any>
15
+ >(
16
+ callback: (value: TSuccess) => Promise<TResult>
17
+ ): (
18
+ result: Result<TSuccess, TError>
19
+ ) => Promise<Result<SuccessType<TResult>, TError | ErrorType<TResult>>> {
20
+ return (result) => result.andThenAsync(callback);
21
+ }
@@ -0,0 +1,79 @@
1
+ import {
2
+ resultSuccess,
3
+ resultError,
4
+ unwrapSuccessResult,
5
+ Result,
6
+ ErrorWithCode,
7
+ resultSuccessVoid,
8
+ } from "./result";
9
+ import { assertType, expectToCompile } from "./utils/test/assert-type";
10
+
11
+ function createResult<TSuccess, TError>(): Result<TSuccess, TError> {
12
+ return resultSuccessVoid() as object as Result<TSuccess, TError>;
13
+ }
14
+
15
+ describe("Result Monad", () => {
16
+ test("resultSuccess should create a success result", () => {
17
+ const success = resultSuccess("test");
18
+ expect(unwrapSuccessResult(success)).toBe("test");
19
+ });
20
+
21
+ test("resultError.unknown should create an unknown error result", () => {
22
+ const error = resultError.unknown("An error occurred");
23
+ try {
24
+ error.unwrapOrThrow();
25
+ } catch (e) {
26
+ expect(e).toMatchObject({
27
+ code: "unknown",
28
+ data: { message: "An error occurred" },
29
+ });
30
+ }
31
+ });
32
+
33
+ test("resultError.withCode should create a coded error result", () => {
34
+ const error = resultError.withCode("test-code" as const, {
35
+ detail: "Some details",
36
+ });
37
+ try {
38
+ error.unwrapOrThrow();
39
+ } catch (e) {
40
+ expect(e).toMatchObject({
41
+ code: "test-code" as const,
42
+ data: { detail: "Some details" },
43
+ });
44
+ }
45
+ });
46
+
47
+ test("Result Monad success should be chainable with inferred types - string -> int", () => {
48
+ const resultString = createResult<string, ErrorWithCode<"test">>();
49
+
50
+ const resultInt = resultString.andThen((value) => {
51
+ type Expected = string;
52
+ assertType<typeof value, Expected>(true);
53
+ return resultSuccess(42);
54
+ });
55
+
56
+ type Expected = Result<number, ErrorWithCode<"test">>;
57
+ assertType<typeof resultInt, Expected>(true);
58
+
59
+ expectToCompile();
60
+ });
61
+
62
+ test("Result Monad success should be chainable with inferred types - obj -> obj", () => {
63
+ const resultString = createResult<
64
+ { test: string },
65
+ ErrorWithCode<"test">
66
+ >();
67
+
68
+ const resultInt = resultString.andThen((value) => {
69
+ type Expected = { test: string };
70
+ assertType<typeof value, Expected>(true);
71
+ return resultSuccess({ test2: "test" });
72
+ });
73
+
74
+ type Expected = Result<{ test2: string }, ErrorWithCode<"test">>;
75
+ assertType<typeof resultInt, Expected>(true);
76
+
77
+ expectToCompile();
78
+ });
79
+ });
package/src/result.ts ADDED
@@ -0,0 +1,159 @@
1
+ export interface Result<TSuccess1, TError1> {
2
+ andThen<TResult extends Result<any, any>>(
3
+ f: (value: TSuccess1) => TResult,
4
+ ): Result<SuccessType<TResult>, TError1 | ErrorType<TResult>>;
5
+ andThenAsync<TResult extends Result<any, any>>(
6
+ f: (value: TSuccess1) => Promise<TResult>,
7
+ ): Promise<Result<SuccessType<TResult>, TError1 | ErrorType<TResult>>>;
8
+ catchError<TResult extends Result<any, any>>(
9
+ f: (error: TError1) => TResult,
10
+ ): Result<TSuccess1 | SuccessType<TResult>, ErrorType<TResult>>;
11
+ catchErrorAsync<TResult extends Result<any, any>>(
12
+ f: (error: TError1) => Promise<TResult>,
13
+ ): Promise<Result<TSuccess1 | SuccessType<TResult>, ErrorType<TResult>>>;
14
+ unwrapOrThrow(errorCallback?: (e: TError1) => void): TSuccess1;
15
+ }
16
+
17
+ export function unwrapSuccessResult<T>(result: Result<T, never>): T {
18
+ if (result instanceof ResultSuccessImp) {
19
+ return result['value'];
20
+ }
21
+ throw new Error('Unreachable code. Result is an error');
22
+ }
23
+
24
+ export type ErrorWithCode<TCode, TData = object> = { code: TCode; data: TData };
25
+ export function errorWithCode<TCode, TData>(
26
+ code: TCode,
27
+ data: TData,
28
+ ): ErrorWithCode<TCode, TData> {
29
+ return {
30
+ code,
31
+ data,
32
+ };
33
+ }
34
+
35
+ export type ErrorUnknown = {
36
+ code: 'unknown';
37
+ data: { message: string };
38
+ };
39
+ export function errorUnkown(message: string): ErrorUnknown {
40
+ return {
41
+ code: 'unknown',
42
+ data: { message },
43
+ };
44
+ }
45
+
46
+ export type SuccessType<T> = T extends Result<infer S, any> ? S : never;
47
+ export type ErrorType<T> = T extends Result<any, infer E> ? E : never;
48
+
49
+ export type SuccessVoid = never;
50
+
51
+ export function resultSuccessVoid(): Result<SuccessVoid, never> {
52
+ return new ResultSuccessImp<SuccessVoid>(undefined as never);
53
+ }
54
+
55
+ export function resultSuccess<TSuccess1>(
56
+ value: TSuccess1,
57
+ ): Result<TSuccess1, never> {
58
+ return new ResultSuccessImp<TSuccess1>(value);
59
+ }
60
+
61
+ type EnforceLiteral<T> = string extends T ? never : T;
62
+
63
+ export class resultError {
64
+ public static unknown(message: string): Result<never, ErrorUnknown> {
65
+ return new ResultErrorImp<ErrorUnknown>(errorUnkown(message));
66
+ }
67
+ public static withCode<TCode, TData = object>(
68
+ code: EnforceLiteral<TCode>,
69
+ data: TData = {} as TData,
70
+ ): Result<never, ErrorWithCode<TCode, TData>> {
71
+ return new ResultErrorImp<ErrorWithCode<TCode, TData>>(
72
+ errorWithCode(code, data),
73
+ );
74
+ }
75
+ public static fromError<
76
+ TSuccess1,
77
+ TError1 extends ErrorWithCode<any, object>,
78
+ >(error: TError1): Result<TSuccess1, TError1> {
79
+ return new ResultErrorImp<TError1>(error);
80
+ }
81
+ }
82
+
83
+ class ResultSuccessImp<TSuccess1> implements Result<TSuccess1, never> {
84
+ constructor(private value: TSuccess1) {}
85
+
86
+ public andThen<TSuccess2, TError2>(
87
+ f: (value: TSuccess1) => Result<TSuccess2, TError2>,
88
+ ): Result<TSuccess2, TError2> {
89
+ return f(this.value);
90
+ }
91
+
92
+ public async andThenAsync<TSuccess2, TError2>(
93
+ f: (value: TSuccess1) => Promise<Result<TSuccess2, TError2>>,
94
+ ): Promise<Result<TSuccess2, TError2>> {
95
+ return await f(this.value);
96
+ }
97
+
98
+ public catchError<TSuccess2, TError2>(
99
+ _f: (error: never) => Result<TSuccess2, TError2>,
100
+ ): Result<TSuccess1 | TSuccess2, TError2> {
101
+ return this;
102
+ }
103
+
104
+ public async catchErrorAsync<TSuccess2, TError2>(
105
+ _f: (error: never) => Promise<Result<TSuccess2, TError2>>,
106
+ ): Promise<Result<TSuccess1 | TSuccess2, TError2>> {
107
+ return this;
108
+ }
109
+
110
+ public unwrapOrThrow(_errorCallback?: (e: never) => void): TSuccess1 {
111
+ return this.value;
112
+ }
113
+ }
114
+
115
+ class ResultErrorImp<TError1> implements Result<never, TError1> {
116
+ constructor(private error: TError1) {}
117
+
118
+ public andThen<TSuccess2, TError2>(
119
+ _f: (value: never) => Result<TSuccess2, TError2>,
120
+ ): Result<TSuccess2, TError1 | TError2> {
121
+ return this;
122
+ }
123
+
124
+ public async andThenAsync<TSuccess2, TError2>(
125
+ _f: (value: never) => Promise<Result<TSuccess2, TError2>>,
126
+ ): Promise<Result<TSuccess2, TError1 | TError2>> {
127
+ return this;
128
+ }
129
+
130
+ public catchError<TSuccess2, TError2>(
131
+ f: (error: TError1) => Result<TSuccess2, TError2>,
132
+ ): Result<TSuccess2, TError2> {
133
+ return f(this.error);
134
+ }
135
+
136
+ public async catchErrorAsync<TSuccess2, TError2>(
137
+ f: (error: TError1) => Promise<Result<TSuccess2, TError2>>,
138
+ ): Promise<Result<TSuccess2, TError2>> {
139
+ return await f(this.error);
140
+ }
141
+
142
+ public unwrapOrThrow(errorCallback?: (e: TError1) => void): never {
143
+ if (errorCallback !== undefined) {
144
+ errorCallback(this.error);
145
+ }
146
+ throw this.error;
147
+ }
148
+ }
149
+
150
+ export type UnwrapErrorFromResult<T> =
151
+ T extends Result<any, infer U> ? U : never;
152
+
153
+ export function makeSafePromise<T>(
154
+ promise: Promise<T>,
155
+ ): Promise<Result<T, ErrorUnknown>> {
156
+ return promise
157
+ .then((value) => resultSuccess(value))
158
+ .catch((error) => resultError.unknown(error.message));
159
+ }
@@ -0,0 +1,7 @@
1
+ export function assertType<TActual, TExpected>(
2
+ _value: TActual extends TExpected ? true : false
3
+ ): void {}
4
+
5
+ export function expectToCompile() {
6
+ expect(true).toBe(true);
7
+ }