@distilled.cloud/auth0 1.0.0-rc.11 → 1.0.0-rc.13

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 ADDED
@@ -0,0 +1,34 @@
1
+ # @distilled.cloud/auth0
2
+
3
+ Effect-native SDK for [auth0](https://www.npmjs.com/package/@distilled.cloud/auth0).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @distilled.cloud/auth0 effect
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```ts
14
+ import { Effect, Layer } from "effect";
15
+ import * as FetchHttpClient from "effect/http/FetchHttpClient";
16
+ import * as Auth0 from "@distilled.cloud/auth0";
17
+
18
+ const program = Effect.gen(function* () {
19
+ const result = yield* Auth0.getActions({});
20
+ return result;
21
+ });
22
+
23
+ const Live = Layer.mergeAll(
24
+ FetchHttpClient.layer,
25
+ Auth0.CredentialsFromEnv,
26
+ Auth0.Auth0Protocol,
27
+ );
28
+
29
+ program.pipe(Effect.provide(Live), Effect.runPromise);
30
+ ```
31
+
32
+ ## Auth
33
+
34
+ Required: `AUTH0_DOMAIN`, `AUTH0_MANAGEMENT_TOKEN`. Optional: `AUTH0_API_BASE_URL`. Sent as `Authorization: Bearer`.
package/lib/protocol.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  import type * as Layer from "effect/Layer";
2
- import type * as HttpClient from "effect/unstable/http/HttpClient";
3
- import type * as HttpClientError from "effect/unstable/http/HttpClientError";
2
+ import type * as HttpClient from "effect/http/HttpClient";
3
+ import type * as HttpClientError from "effect/http/HttpClientError";
4
4
  import type * as API from "@distilled.cloud/core/api";
5
5
  import type { API_ERRORS, ConfigError } from "@distilled.cloud/core/errors";
6
6
  import { Credentials } from "./credentials.ts";
7
- import { UnknownAuth0Error } from "./errors.ts";
7
+ import { UnknownAuth0Error, Auth0ParseError } from "./errors.ts";
8
8
  /**
9
9
  * Error channel shared by every generated Auth0 operation. Generated service
10
10
  * files annotate operations with `API.OperationMethod<I, O, Auth0OpError,
11
11
  * Auth0OpContext>` explicitly so the compiler never infers these back out of
12
12
  * the schema generics.
13
13
  */
14
- export type Auth0OpError = InstanceType<(typeof API_ERRORS)[number]> | UnknownAuth0Error | ConfigError | HttpClientError.HttpClientError;
14
+ export type Auth0OpError = InstanceType<(typeof API_ERRORS)[number]> | UnknownAuth0Error | ConfigError | HttpClientError.HttpClientError | Auth0ParseError;
15
15
  /** Context (requirements) shared by every generated Auth0 operation. */
16
16
  export type Auth0OpContext = Credentials | HttpClient.HttpClient;
17
17
  export declare const Auth0Protocol: Layer.Layer<API.Protocol>;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,KAAK,eAAe,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,KAAK,GAAG,MAAM,2BAA2B,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB,YAAY,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,GACzC,iBAAiB,GACjB,WAAW,GACX,eAAe,CAAC,eAAe,CAAC;AAEpC,wEAAwE;AACxE,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC;AAEjE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAyBhD,CAAC"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,KAAK,UAAU,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,KAAK,eAAe,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,KAAK,GAAG,MAAM,2BAA2B,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB,YAAY,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,GACzC,iBAAiB,GACjB,WAAW,GACX,eAAe,CAAC,eAAe,GAC/B,eAAe,CAAC;AAEpB,wEAAwE;AACxE,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC;AAEjE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CA0BhD,CAAC"}
package/lib/protocol.js CHANGED
@@ -19,7 +19,7 @@ import * as Effect from "effect/Effect";
19
19
  import * as Redacted from "effect/Redacted";
20
20
  import { makeRestProtocol } from "@distilled.cloud/core/protocol-rest";
21
21
  import { Credentials } from "./credentials.js";
22
- import { UnknownAuth0Error } from "./errors.js";
22
+ import { UnknownAuth0Error, Auth0ParseError } from "./errors.js";
23
23
  export const Auth0Protocol = makeRestProtocol({
24
24
  // The Credentials service holds an effect — resolving it here (per
25
25
  // request, on the calling fiber) picks up context-provided credentials.
@@ -42,5 +42,6 @@ export const Auth0Protocol = makeRestProtocol({
42
42
  message,
43
43
  body,
44
44
  }),
45
+ parseError: ({ body, cause }) => new Auth0ParseError({ body, cause }),
45
46
  });
46
47
  //# sourceMappingURL=protocol.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAI5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAiBhD,MAAM,CAAC,MAAM,aAAa,GACxB,gBAAgB,CAAS;IACvB,mEAAmE;IACnE,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;QACnC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC;IACxB,CAAC,CAAC;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU;IACpC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACnB,aAAa,EAAE,UAAU,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;KACvD,CAAC;IACF,yEAAyE;IACzE,oDAAoD;IACpD,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CACxC,IAAI,iBAAiB,CAAC;QACpB,IAAI,EACF,OAAO,IAAI,KAAK,QAAQ;YACtB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,IAAI,KAAK,SAAS;gBAClB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBACd,CAAC,CAAC,SAAS;QACjB,OAAO;QACP,IAAI;KACL,CAAC;CACL,CAAC,CAAC"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAI5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAEvE,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAkBjE,MAAM,CAAC,MAAM,aAAa,GACxB,gBAAgB,CAAS;IACvB,mEAAmE;IACnE,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC;QACnC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC;IACxB,CAAC,CAAC;IACF,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU;IACpC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACnB,aAAa,EAAE,UAAU,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;KACvD,CAAC;IACF,yEAAyE;IACzE,oDAAoD;IACpD,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CACxC,IAAI,iBAAiB,CAAC;QACpB,IAAI,EACF,OAAO,IAAI,KAAK,QAAQ;YACtB,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,IAAI,KAAK,SAAS;gBAClB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBACd,CAAC,CAAC,SAAS;QACjB,OAAO;QACP,IAAI;KACL,CAAC;IACJ,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;CACtE,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Auth0ParseError } from "./errors.ts";
2
+ import type { Auth0OpError } from "./protocol.ts";
3
+ export declare const parseErrorIsDeclared: [Auth0ParseError] extends [Auth0OpError] ? true : false;
4
+ //# sourceMappingURL=response-validation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-validation.test.d.ts","sourceRoot":"","sources":["../src/response-validation.test.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAsClD,eAAO,MAAM,oBAAoB,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,YAAY,CAAC,GACvE,IAAI,GACJ,KAAY,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { runValidationModes } from "@distilled.cloud/core/testing";
3
+ import * as Effect from "effect/Effect";
4
+ import { fromToken } from "./credentials.js";
5
+ import { Auth0ParseError } from "./errors.js";
6
+ import * as Retry from "./retry.js";
7
+ import { getActions } from "./services/auth0.js";
8
+ // getActions declares only optional members (`total?: number`, `actions?: Action[]`, …),
9
+ // so the mismatch is a wrong primitive type.
10
+ const run = (body) => runValidationModes(getActions({}).pipe(Retry.none, Effect.provide(fromToken({ token: "test", domain: "example.auth0.com" }))), { body });
11
+ describe("Auth0 response validation", () => {
12
+ test("a matching body succeeds unchanged in both modes", async () => {
13
+ const body = { total: 0, page: 0, per_page: 50, actions: [] };
14
+ const { lenient, strict } = await run(JSON.stringify(body));
15
+ expect(lenient).toMatchObject({ _tag: "Success", success: body });
16
+ expect(strict).toMatchObject({ _tag: "Success", success: body });
17
+ });
18
+ test("a member with the wrong primitive type: lenient returns it, strict fails", async () => {
19
+ const body = { total: "zero" };
20
+ const { lenient, strict } = await run(JSON.stringify(body));
21
+ expect(lenient).toMatchObject({ _tag: "Success", success: body });
22
+ expect(strict._tag).toBe("Failure");
23
+ expect(strict.failure).toBeInstanceOf(Auth0ParseError);
24
+ });
25
+ test("a non-JSON body: lenient returns the text, strict fails", async () => {
26
+ const { lenient, strict } = await run("not json");
27
+ expect(lenient).toMatchObject({ _tag: "Success", success: "not json" });
28
+ expect(strict._tag).toBe("Failure");
29
+ expect(strict.failure).toBeInstanceOf(Auth0ParseError);
30
+ });
31
+ });
32
+ // Auth0ParseError is part of every operation's declared error type.
33
+ export const parseErrorIsDeclared = true;
34
+ //# sourceMappingURL=response-validation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-validation.test.js","sourceRoot":"","sources":["../src/response-validation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,yFAAyF;AACzF,6CAA6C;AAC7C,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAC3B,kBAAkB,CAChB,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CACjB,KAAK,CAAC,IAAI,EACV,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAC1E,EACD,EAAE,IAAI,EAAE,CACT,CAAC;AAEJ,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC9D,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAE,MAAc,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpC,MAAM,CAAE,MAAc,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,oEAAoE;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAErB,IAAI,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@distilled.cloud/auth0",
3
- "version": "1.0.0-rc.11",
3
+ "version": "1.0.0-rc.13",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/alchemy-run/distilled",
@@ -64,15 +64,15 @@
64
64
  }
65
65
  },
66
66
  "dependencies": {
67
- "@distilled.cloud/core": "1.0.0-rc.11"
67
+ "@distilled.cloud/core": "1.0.0-rc.13"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@types/bun": "1.3.14",
71
71
  "@types/node": "26.2.0",
72
- "@effect/platform-bun": ">=4.0.0-rc.115 || >=4.0.0"
72
+ "@effect/platform-bun": "^4.0.0"
73
73
  },
74
74
  "peerDependencies": {
75
- "effect": ">=4.0.0-rc.115 || >=4.0.0"
75
+ "effect": "^4.0.0"
76
76
  },
77
77
  "scripts": {
78
78
  "build": "tsc -b",
package/src/protocol.ts CHANGED
@@ -18,13 +18,13 @@
18
18
  import * as Effect from "effect/Effect";
19
19
  import type * as Layer from "effect/Layer";
20
20
  import * as Redacted from "effect/Redacted";
21
- import type * as HttpClient from "effect/unstable/http/HttpClient";
22
- import type * as HttpClientError from "effect/unstable/http/HttpClientError";
21
+ import type * as HttpClient from "effect/http/HttpClient";
22
+ import type * as HttpClientError from "effect/http/HttpClientError";
23
23
  import type * as API from "@distilled.cloud/core/api";
24
24
  import { makeRestProtocol } from "@distilled.cloud/core/protocol-rest";
25
25
  import type { API_ERRORS, ConfigError } from "@distilled.cloud/core/errors";
26
26
  import { Credentials, type Config } from "./credentials.ts";
27
- import { UnknownAuth0Error } from "./errors.ts";
27
+ import { UnknownAuth0Error, Auth0ParseError } from "./errors.ts";
28
28
 
29
29
  /**
30
30
  * Error channel shared by every generated Auth0 operation. Generated service
@@ -36,7 +36,8 @@ export type Auth0OpError =
36
36
  | InstanceType<(typeof API_ERRORS)[number]>
37
37
  | UnknownAuth0Error
38
38
  | ConfigError
39
- | HttpClientError.HttpClientError;
39
+ | HttpClientError.HttpClientError
40
+ | Auth0ParseError;
40
41
 
41
42
  /** Context (requirements) shared by every generated Auth0 operation. */
42
43
  export type Auth0OpContext = Credentials | HttpClient.HttpClient;
@@ -66,4 +67,5 @@ export const Auth0Protocol: Layer.Layer<API.Protocol> =
66
67
  message,
67
68
  body,
68
69
  }),
70
+ parseError: ({ body, cause }) => new Auth0ParseError({ body, cause }),
69
71
  });
@@ -0,0 +1,48 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { runValidationModes } from "@distilled.cloud/core/testing";
3
+ import * as Effect from "effect/Effect";
4
+ import { fromToken } from "./credentials.ts";
5
+ import { Auth0ParseError } from "./errors.ts";
6
+ import * as Retry from "./retry.ts";
7
+ import { getActions } from "./services/auth0.ts";
8
+ import type { Auth0OpError } from "./protocol.ts";
9
+
10
+ // getActions declares only optional members (`total?: number`, `actions?: Action[]`, …),
11
+ // so the mismatch is a wrong primitive type.
12
+ const run = (body: string) =>
13
+ runValidationModes(
14
+ getActions({}).pipe(
15
+ Retry.none,
16
+ Effect.provide(fromToken({ token: "test", domain: "example.auth0.com" })),
17
+ ),
18
+ { body },
19
+ );
20
+
21
+ describe("Auth0 response validation", () => {
22
+ test("a matching body succeeds unchanged in both modes", async () => {
23
+ const body = { total: 0, page: 0, per_page: 50, actions: [] };
24
+ const { lenient, strict } = await run(JSON.stringify(body));
25
+ expect(lenient).toMatchObject({ _tag: "Success", success: body });
26
+ expect(strict).toMatchObject({ _tag: "Success", success: body });
27
+ });
28
+
29
+ test("a member with the wrong primitive type: lenient returns it, strict fails", async () => {
30
+ const body = { total: "zero" };
31
+ const { lenient, strict } = await run(JSON.stringify(body));
32
+ expect(lenient).toMatchObject({ _tag: "Success", success: body });
33
+ expect(strict._tag).toBe("Failure");
34
+ expect((strict as any).failure).toBeInstanceOf(Auth0ParseError);
35
+ });
36
+
37
+ test("a non-JSON body: lenient returns the text, strict fails", async () => {
38
+ const { lenient, strict } = await run("not json");
39
+ expect(lenient).toMatchObject({ _tag: "Success", success: "not json" });
40
+ expect(strict._tag).toBe("Failure");
41
+ expect((strict as any).failure).toBeInstanceOf(Auth0ParseError);
42
+ });
43
+ });
44
+
45
+ // Auth0ParseError is part of every operation's declared error type.
46
+ export const parseErrorIsDeclared: [Auth0ParseError] extends [Auth0OpError]
47
+ ? true
48
+ : false = true;