@effect/platform 0.65.3 → 0.65.5
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 +276 -62
- package/dist/cjs/HttpClient.js +38 -0
- package/dist/cjs/HttpClient.js.map +1 -1
- package/dist/cjs/internal/httpMiddleware.js +2 -2
- package/dist/cjs/internal/httpMiddleware.js.map +1 -1
- package/dist/dts/HttpClient.d.ts +38 -0
- package/dist/dts/HttpClient.d.ts.map +1 -1
- package/dist/esm/HttpClient.js +38 -0
- package/dist/esm/HttpClient.js.map +1 -1
- package/dist/esm/internal/httpMiddleware.js +2 -2
- package/dist/esm/internal/httpMiddleware.js.map +1 -1
- package/package.json +3 -3
- package/src/HttpClient.ts +38 -0
- package/src/internal/httpMiddleware.ts +2 -2
package/README.md
CHANGED
|
@@ -569,26 +569,25 @@ handle responses, and abstract over the differences between platforms.
|
|
|
569
569
|
|
|
570
570
|
The `HttpClient` interface has a set of methods for sending requests:
|
|
571
571
|
|
|
572
|
-
- `.execute` - takes a
|
|
573
|
-
- `.{get, post,
|
|
572
|
+
- `.execute` - takes a [HttpClientRequest](#httpclientrequest) and returns a `HttpClientResponse`
|
|
573
|
+
- `.{get, del, head, options, patch, post, put}` - convenience methods for creating a request and
|
|
574
574
|
executing it in one step
|
|
575
575
|
|
|
576
|
-
To access the `HttpClient`, you can use the `HttpClient.HttpClient`
|
|
576
|
+
To access the `HttpClient`, you can use the `HttpClient.HttpClient` [tag](https://effect.website/docs/guides/context-management/services).
|
|
577
577
|
This will give you access to a `HttpClient.Service` instance, which is the default
|
|
578
|
-
|
|
578
|
+
instance of the `HttpClient` interface.
|
|
579
579
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
Here's a simple example demonstrating how to retrieve JSON data using `HttpClient` from `@effect/platform`.
|
|
580
|
+
**Example: Retrieving JSON Data (GET)**
|
|
583
581
|
|
|
584
582
|
```ts
|
|
585
583
|
import { FetchHttpClient, HttpClient } from "@effect/platform"
|
|
586
584
|
import { Effect } from "effect"
|
|
587
585
|
|
|
588
586
|
const program = Effect.gen(function* () {
|
|
589
|
-
//
|
|
587
|
+
// Access HttpClient
|
|
590
588
|
const client = yield* HttpClient.HttpClient
|
|
591
589
|
|
|
590
|
+
// Create and execute a GET request
|
|
592
591
|
const response = yield* client.get(
|
|
593
592
|
"https://jsonplaceholder.typicode.com/posts/1"
|
|
594
593
|
)
|
|
@@ -597,9 +596,9 @@ const program = Effect.gen(function* () {
|
|
|
597
596
|
|
|
598
597
|
console.log(json)
|
|
599
598
|
}).pipe(
|
|
600
|
-
//
|
|
599
|
+
// Ensure request is aborted if the program is interrupted
|
|
601
600
|
Effect.scoped,
|
|
602
|
-
//
|
|
601
|
+
// Provide the HttpClient
|
|
603
602
|
Effect.provide(FetchHttpClient.layer)
|
|
604
603
|
)
|
|
605
604
|
|
|
@@ -618,33 +617,62 @@ Output:
|
|
|
618
617
|
*/
|
|
619
618
|
```
|
|
620
619
|
|
|
621
|
-
|
|
620
|
+
**Example: Creating and Executing a Custom Request**
|
|
622
621
|
|
|
623
|
-
|
|
622
|
+
Using [HttpClientRequest](#httpclientrequest), you can create and then execute a request. This is useful for customizing the request further.
|
|
624
623
|
|
|
625
624
|
```ts
|
|
626
|
-
import {
|
|
625
|
+
import {
|
|
626
|
+
FetchHttpClient,
|
|
627
|
+
HttpClient,
|
|
628
|
+
HttpClientRequest
|
|
629
|
+
} from "@effect/platform"
|
|
627
630
|
import { Effect } from "effect"
|
|
628
631
|
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
userId: 1,
|
|
637
|
-
id: 1,
|
|
638
|
-
title: "title...",
|
|
639
|
-
body: "body..."
|
|
640
|
-
})
|
|
641
|
-
)
|
|
642
|
-
)
|
|
632
|
+
const program = Effect.gen(function* () {
|
|
633
|
+
// Access HttpClient
|
|
634
|
+
const client = yield* HttpClient.HttpClient
|
|
635
|
+
|
|
636
|
+
// Create a GET request
|
|
637
|
+
const req = HttpClientRequest.get(
|
|
638
|
+
"https://jsonplaceholder.typicode.com/posts/1"
|
|
643
639
|
)
|
|
640
|
+
|
|
641
|
+
// Optionally customize the request
|
|
642
|
+
|
|
643
|
+
// Execute the request and get the response
|
|
644
|
+
const response = yield* client.execute(req)
|
|
645
|
+
|
|
646
|
+
const json = yield* response.json
|
|
647
|
+
|
|
648
|
+
console.log(json)
|
|
649
|
+
}).pipe(
|
|
650
|
+
// Ensure request is aborted if the program is interrupted
|
|
651
|
+
Effect.scoped,
|
|
652
|
+
// Provide the HttpClient
|
|
653
|
+
Effect.provide(FetchHttpClient.layer)
|
|
644
654
|
)
|
|
655
|
+
|
|
656
|
+
Effect.runPromise(program)
|
|
657
|
+
/*
|
|
658
|
+
Output:
|
|
659
|
+
{
|
|
660
|
+
userId: 1,
|
|
661
|
+
id: 1,
|
|
662
|
+
title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
|
|
663
|
+
body: 'quia et suscipit\n' +
|
|
664
|
+
'suscipit recusandae consequuntur expedita et cum\n' +
|
|
665
|
+
'reprehenderit molestiae ut ut quas totam\n' +
|
|
666
|
+
'nostrum rerum est autem sunt rem eveniet architecto'
|
|
667
|
+
}
|
|
668
|
+
*/
|
|
645
669
|
```
|
|
646
670
|
|
|
647
|
-
##
|
|
671
|
+
## Customize a HttpClient
|
|
672
|
+
|
|
673
|
+
The `HttpClient` module allows you to customize the client in various ways. For instance, you can log details of a request before execution using the `tapRequest` function.
|
|
674
|
+
|
|
675
|
+
**Example: Tapping**
|
|
648
676
|
|
|
649
677
|
```ts
|
|
650
678
|
import { FetchHttpClient, HttpClient } from "@effect/platform"
|
|
@@ -689,6 +717,199 @@ Output:
|
|
|
689
717
|
*/
|
|
690
718
|
```
|
|
691
719
|
|
|
720
|
+
**Operations Summary**
|
|
721
|
+
|
|
722
|
+
| Operation | Description |
|
|
723
|
+
| ------------------------ | --------------------------------------------------------------------------------------- |
|
|
724
|
+
| `filterOrElse` | Filters the result of a response, or runs an alternative effect if the predicate fails. |
|
|
725
|
+
| `filterOrFail` | Filters the result of a response, or throws an error if the predicate fails. |
|
|
726
|
+
| `filterStatus` | Filters responses by HTTP status code. |
|
|
727
|
+
| `filterStatusOk` | Filters responses that return a 2xx status code. |
|
|
728
|
+
| `followRedirects` | Follows HTTP redirects up to a specified number of times. |
|
|
729
|
+
| `map` | Transforms the result of a request. |
|
|
730
|
+
| `mapEffect` | Transforms the result of a request using an effectful function. |
|
|
731
|
+
| `mapRequest` | Appends a transformation of the request object before sending it. |
|
|
732
|
+
| `mapRequestEffect` | Appends an effectful transformation of the request object before sending it. |
|
|
733
|
+
| `mapRequestInput` | Prepends a transformation of the request object before sending it. |
|
|
734
|
+
| `mapRequestInputEffect` | Prepends an effectful transformation of the request object before sending it. |
|
|
735
|
+
| `retry` | Retries the request based on a provided schedule or policy. |
|
|
736
|
+
| `schemaFunction` | Creates a function that validates request data against a schema before sending it. |
|
|
737
|
+
| `scoped` | Ensures resources are properly scoped and released after execution. |
|
|
738
|
+
| `tap` | Performs an additional effect after a successful request. |
|
|
739
|
+
| `tapRequest` | Performs an additional effect on the request before sending it. |
|
|
740
|
+
| `withCookiesRef` | Associates a `Ref` of cookies with the client for handling cookies across requests. |
|
|
741
|
+
| `withTracerDisabledWhen` | Disables tracing for specific requests based on a provided predicate. |
|
|
742
|
+
| `withTracerPropagation` | Enables or disables tracing propagation for the request. |
|
|
743
|
+
|
|
744
|
+
### Mapping Requests
|
|
745
|
+
|
|
746
|
+
Note that `mapRequest` and `mapRequestEffect` add transformations at the end of the request chain, while `mapRequestInput` and `mapRequestInputEffect` apply transformations at the start:
|
|
747
|
+
|
|
748
|
+
```ts
|
|
749
|
+
import { FetchHttpClient, HttpClient } from "@effect/platform"
|
|
750
|
+
import { Effect } from "effect"
|
|
751
|
+
|
|
752
|
+
const program = Effect.gen(function* () {
|
|
753
|
+
const client = (yield* HttpClient.HttpClient).pipe(
|
|
754
|
+
// Append transformation
|
|
755
|
+
HttpClient.mapRequest((req) => {
|
|
756
|
+
console.log(1)
|
|
757
|
+
return req
|
|
758
|
+
}),
|
|
759
|
+
// Another append transformation
|
|
760
|
+
HttpClient.mapRequest((req) => {
|
|
761
|
+
console.log(2)
|
|
762
|
+
return req
|
|
763
|
+
}),
|
|
764
|
+
// Prepend transformation, this executes first
|
|
765
|
+
HttpClient.mapRequestInput((req) => {
|
|
766
|
+
console.log(3)
|
|
767
|
+
return req
|
|
768
|
+
})
|
|
769
|
+
)
|
|
770
|
+
|
|
771
|
+
const response = yield* client.get(
|
|
772
|
+
"https://jsonplaceholder.typicode.com/posts/1"
|
|
773
|
+
)
|
|
774
|
+
|
|
775
|
+
const json = yield* response.json
|
|
776
|
+
|
|
777
|
+
console.log(json)
|
|
778
|
+
}).pipe(Effect.scoped, Effect.provide(FetchHttpClient.layer))
|
|
779
|
+
|
|
780
|
+
Effect.runPromise(program)
|
|
781
|
+
/*
|
|
782
|
+
Output:
|
|
783
|
+
3
|
|
784
|
+
1
|
|
785
|
+
2
|
|
786
|
+
{
|
|
787
|
+
userId: 1,
|
|
788
|
+
id: 1,
|
|
789
|
+
title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
|
|
790
|
+
body: 'quia et suscipit\n' +
|
|
791
|
+
'suscipit recusandae consequuntur expedita et cum\n' +
|
|
792
|
+
'reprehenderit molestiae ut ut quas totam\n' +
|
|
793
|
+
'nostrum rerum est autem sunt rem eveniet architecto'
|
|
794
|
+
}
|
|
795
|
+
*/
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
### Integration with Schema
|
|
799
|
+
|
|
800
|
+
The `HttpClient.schemaFunction` allows you to integrate schemas into your HTTP client requests. This function ensures that the data you send conforms to a specified schema, enhancing type safety and validation.
|
|
801
|
+
|
|
802
|
+
```ts
|
|
803
|
+
import {
|
|
804
|
+
FetchHttpClient,
|
|
805
|
+
HttpClient,
|
|
806
|
+
HttpClientRequest
|
|
807
|
+
} from "@effect/platform"
|
|
808
|
+
import { Schema } from "@effect/schema"
|
|
809
|
+
import { Effect } from "effect"
|
|
810
|
+
|
|
811
|
+
const program = Effect.gen(function* () {
|
|
812
|
+
const client = yield* HttpClient.HttpClient
|
|
813
|
+
const addTodo = HttpClient.schemaFunction(
|
|
814
|
+
client,
|
|
815
|
+
Schema.Struct({
|
|
816
|
+
title: Schema.String,
|
|
817
|
+
body: Schema.String,
|
|
818
|
+
userId: Schema.Number
|
|
819
|
+
})
|
|
820
|
+
)(HttpClientRequest.post("https://jsonplaceholder.typicode.com/posts"))
|
|
821
|
+
|
|
822
|
+
const response = yield* addTodo({
|
|
823
|
+
title: "foo",
|
|
824
|
+
body: "bar",
|
|
825
|
+
userId: 1
|
|
826
|
+
})
|
|
827
|
+
|
|
828
|
+
const json = yield* response.json
|
|
829
|
+
|
|
830
|
+
console.log(json)
|
|
831
|
+
}).pipe(Effect.scoped, Effect.provide(FetchHttpClient.layer))
|
|
832
|
+
|
|
833
|
+
Effect.runPromise(program)
|
|
834
|
+
/*
|
|
835
|
+
Output:
|
|
836
|
+
{ title: 'foo', body: 'bar', userId: 1, id: 101 }
|
|
837
|
+
*/
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
## RequestInit Options
|
|
841
|
+
|
|
842
|
+
You can customize the `HttpClient` by passing `RequestInit` options to configure aspects of the HTTP requests, such as credentials, headers, and more.
|
|
843
|
+
|
|
844
|
+
In this example, we customize the `HttpClient` to include credentials with every request:
|
|
845
|
+
|
|
846
|
+
```ts
|
|
847
|
+
import { FetchHttpClient, HttpClient } from "@effect/platform"
|
|
848
|
+
import { Effect, Layer } from "effect"
|
|
849
|
+
|
|
850
|
+
const CustomFetchLive = FetchHttpClient.layer.pipe(
|
|
851
|
+
Layer.provide(
|
|
852
|
+
Layer.succeed(FetchHttpClient.RequestInit, {
|
|
853
|
+
credentials: "include"
|
|
854
|
+
})
|
|
855
|
+
)
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
const program = Effect.gen(function* () {
|
|
859
|
+
const client = yield* HttpClient.HttpClient
|
|
860
|
+
const response = yield* client.get(
|
|
861
|
+
"https://jsonplaceholder.typicode.com/posts/1"
|
|
862
|
+
)
|
|
863
|
+
const json = yield* response.json
|
|
864
|
+
console.log(json)
|
|
865
|
+
}).pipe(Effect.scoped, Effect.provide(CustomFetchLive))
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
## Create a Custom HttpClient
|
|
869
|
+
|
|
870
|
+
You can create a custom `HttpClient.Service` using the `HttpClient.makeService` function. This allows you to simulate or mock server responses within your application.
|
|
871
|
+
|
|
872
|
+
```ts
|
|
873
|
+
import { HttpClient, HttpClientResponse } from "@effect/platform"
|
|
874
|
+
import { Effect, Layer } from "effect"
|
|
875
|
+
|
|
876
|
+
const myClient = HttpClient.makeService((req) =>
|
|
877
|
+
Effect.succeed(
|
|
878
|
+
HttpClientResponse.fromWeb(
|
|
879
|
+
req,
|
|
880
|
+
// Simulate a response from a server
|
|
881
|
+
new Response(
|
|
882
|
+
JSON.stringify({
|
|
883
|
+
userId: 1,
|
|
884
|
+
id: 1,
|
|
885
|
+
title: "title...",
|
|
886
|
+
body: "body..."
|
|
887
|
+
})
|
|
888
|
+
)
|
|
889
|
+
)
|
|
890
|
+
)
|
|
891
|
+
)
|
|
892
|
+
|
|
893
|
+
const program = Effect.gen(function* () {
|
|
894
|
+
const client = yield* HttpClient.HttpClient
|
|
895
|
+
const response = yield* client.get(
|
|
896
|
+
"https://jsonplaceholder.typicode.com/posts/1"
|
|
897
|
+
)
|
|
898
|
+
const json = yield* response.json
|
|
899
|
+
console.log(json)
|
|
900
|
+
}).pipe(
|
|
901
|
+
Effect.scoped,
|
|
902
|
+
// Provide the HttpClient
|
|
903
|
+
Effect.provide(Layer.succeed(HttpClient.HttpClient, myClient))
|
|
904
|
+
)
|
|
905
|
+
|
|
906
|
+
Effect.runPromise(program)
|
|
907
|
+
/*
|
|
908
|
+
Output:
|
|
909
|
+
{ userId: 1, id: 1, title: 'title...', body: 'body...' }
|
|
910
|
+
*/
|
|
911
|
+
```
|
|
912
|
+
|
|
692
913
|
## HttpClientRequest
|
|
693
914
|
|
|
694
915
|
### Overview
|
|
@@ -697,13 +918,13 @@ You can create a `HttpClientRequest` using the following provided constructors:
|
|
|
697
918
|
|
|
698
919
|
| Constructor | Description |
|
|
699
920
|
| --------------------------- | ------------------------- |
|
|
700
|
-
| `HttpClientRequest.get` | Create a GET request |
|
|
701
|
-
| `HttpClientRequest.post` | Create a POST request |
|
|
702
|
-
| `HttpClientRequest.patch` | Create a PATCH request |
|
|
703
|
-
| `HttpClientRequest.put` | Create a PUT request |
|
|
704
921
|
| `HttpClientRequest.del` | Create a DELETE request |
|
|
922
|
+
| `HttpClientRequest.get` | Create a GET request |
|
|
705
923
|
| `HttpClientRequest.head` | Create a HEAD request |
|
|
706
924
|
| `HttpClientRequest.options` | Create an OPTIONS request |
|
|
925
|
+
| `HttpClientRequest.patch` | Create a PATCH request |
|
|
926
|
+
| `HttpClientRequest.post` | Create a POST request |
|
|
927
|
+
| `HttpClientRequest.put` | Create a PUT request |
|
|
707
928
|
|
|
708
929
|
### Setting Headers
|
|
709
930
|
|
|
@@ -815,9 +1036,11 @@ Output:
|
|
|
815
1036
|
|
|
816
1037
|
## GET
|
|
817
1038
|
|
|
818
|
-
### Converting
|
|
1039
|
+
### Converting the Response
|
|
1040
|
+
|
|
1041
|
+
The `HttpClientResponse` provides several methods to convert a response into different formats.
|
|
819
1042
|
|
|
820
|
-
|
|
1043
|
+
**Example: Converting to JSON**
|
|
821
1044
|
|
|
822
1045
|
```ts
|
|
823
1046
|
import { FetchHttpClient, HttpClient } from "@effect/platform"
|
|
@@ -850,16 +1073,14 @@ object {
|
|
|
850
1073
|
*/
|
|
851
1074
|
```
|
|
852
1075
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
To convert a GET response to text:
|
|
1076
|
+
**Example: Converting to Text**
|
|
856
1077
|
|
|
857
1078
|
```ts
|
|
858
1079
|
import { FetchHttpClient, HttpClient } from "@effect/platform"
|
|
859
1080
|
import { NodeRuntime } from "@effect/platform-node"
|
|
860
1081
|
import { Console, Effect } from "effect"
|
|
861
1082
|
|
|
862
|
-
const
|
|
1083
|
+
const getPostAsText = Effect.gen(function* () {
|
|
863
1084
|
const client = yield* HttpClient.HttpClient
|
|
864
1085
|
const response = yield* client.get(
|
|
865
1086
|
"https://jsonplaceholder.typicode.com/posts/1"
|
|
@@ -867,7 +1088,7 @@ const getPostAsJson = Effect.gen(function* () {
|
|
|
867
1088
|
return yield* response.text
|
|
868
1089
|
}).pipe(Effect.scoped, Effect.provide(FetchHttpClient.layer))
|
|
869
1090
|
|
|
870
|
-
|
|
1091
|
+
getPostAsText.pipe(
|
|
871
1092
|
Effect.andThen((post) => Console.log(typeof post, post)),
|
|
872
1093
|
NodeRuntime.runMain
|
|
873
1094
|
)
|
|
@@ -885,22 +1106,20 @@ string {
|
|
|
885
1106
|
*/
|
|
886
1107
|
```
|
|
887
1108
|
|
|
888
|
-
|
|
1109
|
+
**Methods Summary**
|
|
889
1110
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
|
893
|
-
|
|
|
894
|
-
| `
|
|
895
|
-
| `
|
|
896
|
-
| `
|
|
897
|
-
| `
|
|
898
|
-
| `response.text` | Convert to text |
|
|
899
|
-
| `response.urlParamsBody` | Convert to `UrlParams` |
|
|
1111
|
+
| Method | Description |
|
|
1112
|
+
| --------------- | ------------------------------------- |
|
|
1113
|
+
| `arrayBuffer` | Convert to `ArrayBuffer` |
|
|
1114
|
+
| `formData` | Convert to `FormData` |
|
|
1115
|
+
| `json` | Convert to JSON |
|
|
1116
|
+
| `stream` | Convert to a `Stream` of `Uint8Array` |
|
|
1117
|
+
| `text` | Convert to text |
|
|
1118
|
+
| `urlParamsBody` | Convert to `UrlParams` |
|
|
900
1119
|
|
|
901
1120
|
### Decoding Data with Schemas
|
|
902
1121
|
|
|
903
|
-
A common use case when fetching data is to validate the received format. For this purpose, the `
|
|
1122
|
+
A common use case when fetching data is to validate the received format. For this purpose, the `HttpClientResponse` module is integrated with `@effect/schema`.
|
|
904
1123
|
|
|
905
1124
|
```ts
|
|
906
1125
|
import {
|
|
@@ -917,12 +1136,6 @@ const Post = Schema.Struct({
|
|
|
917
1136
|
title: Schema.String
|
|
918
1137
|
})
|
|
919
1138
|
|
|
920
|
-
/*
|
|
921
|
-
const getPostAndValidate: Effect.Effect<{
|
|
922
|
-
readonly id: number;
|
|
923
|
-
readonly title: string;
|
|
924
|
-
}, HttpClientError | ParseError, never>
|
|
925
|
-
*/
|
|
926
1139
|
const getPostAndValidate = Effect.gen(function* () {
|
|
927
1140
|
const client = yield* HttpClient.HttpClient
|
|
928
1141
|
const response = yield* client.get(
|
|
@@ -947,9 +1160,9 @@ Note that we use `Effect.scoped` after consuming the response. This ensures that
|
|
|
947
1160
|
|
|
948
1161
|
### Filtering And Error Handling
|
|
949
1162
|
|
|
950
|
-
It's important to note that `HttpClient.
|
|
1163
|
+
It's important to note that `HttpClient.get` doesn't consider non-`200` status codes as errors by default. This design choice allows for flexibility in handling different response scenarios. For instance, you might have a schema union where the status code serves as the discriminator, enabling you to define a schema that encompasses all possible response cases.
|
|
951
1164
|
|
|
952
|
-
You can use `HttpClient.filterStatusOk
|
|
1165
|
+
You can use `HttpClient.filterStatusOk` to ensure only `2xx` responses are treated as successes.
|
|
953
1166
|
|
|
954
1167
|
In this example, we attempt to fetch a non-existent page and don't receive any error:
|
|
955
1168
|
|
|
@@ -991,8 +1204,9 @@ const getText = Effect.gen(function* () {
|
|
|
991
1204
|
getText.pipe(Effect.andThen(Console.log), NodeRuntime.runMain)
|
|
992
1205
|
/*
|
|
993
1206
|
Output:
|
|
994
|
-
|
|
995
|
-
|
|
1207
|
+
[17:37:59.923] ERROR (#0):
|
|
1208
|
+
ResponseError: StatusCode: non 2xx status code (404 GET https://jsonplaceholder.typicode.com/non-existing-page)
|
|
1209
|
+
... stack trace ...
|
|
996
1210
|
*/
|
|
997
1211
|
```
|
|
998
1212
|
|
|
@@ -1073,7 +1287,7 @@ Output:
|
|
|
1073
1287
|
|
|
1074
1288
|
### Decoding Data with Schemas
|
|
1075
1289
|
|
|
1076
|
-
A common use case when fetching data is to validate the received format. For this purpose, the `
|
|
1290
|
+
A common use case when fetching data is to validate the received format. For this purpose, the `HttpClientResponse` module is integrated with `@effect/schema`.
|
|
1077
1291
|
|
|
1078
1292
|
```ts
|
|
1079
1293
|
import {
|
package/dist/cjs/HttpClient.js
CHANGED
|
@@ -33,21 +33,29 @@ const catchTag = exports.catchTag = internal.catchTag;
|
|
|
33
33
|
*/
|
|
34
34
|
const catchTags = exports.catchTags = internal.catchTags;
|
|
35
35
|
/**
|
|
36
|
+
* Filters the result of a response, or runs an alternative effect if the predicate fails.
|
|
37
|
+
*
|
|
36
38
|
* @since 1.0.0
|
|
37
39
|
* @category filters
|
|
38
40
|
*/
|
|
39
41
|
const filterOrElse = exports.filterOrElse = internal.filterOrElse;
|
|
40
42
|
/**
|
|
43
|
+
* Filters the result of a response, or throws an error if the predicate fails.
|
|
44
|
+
*
|
|
41
45
|
* @since 1.0.0
|
|
42
46
|
* @category filters
|
|
43
47
|
*/
|
|
44
48
|
const filterOrFail = exports.filterOrFail = internal.filterOrFail;
|
|
45
49
|
/**
|
|
50
|
+
* Filters responses by HTTP status code.
|
|
51
|
+
*
|
|
46
52
|
* @since 1.0.0
|
|
47
53
|
* @category filters
|
|
48
54
|
*/
|
|
49
55
|
const filterStatus = exports.filterStatus = internal.filterStatus;
|
|
50
56
|
/**
|
|
57
|
+
* Filters responses that return a 2xx status code.
|
|
58
|
+
*
|
|
51
59
|
* @since 1.0.0
|
|
52
60
|
* @category filters
|
|
53
61
|
*/
|
|
@@ -73,66 +81,92 @@ const transform = exports.transform = internal.transform;
|
|
|
73
81
|
*/
|
|
74
82
|
const transformResponse = exports.transformResponse = internal.transformResponse;
|
|
75
83
|
/**
|
|
84
|
+
* Transforms the result of a request.
|
|
85
|
+
*
|
|
76
86
|
* @since 1.0.0
|
|
77
87
|
* @category mapping & sequencing
|
|
78
88
|
*/
|
|
79
89
|
const map = exports.map = internal.map;
|
|
80
90
|
/**
|
|
91
|
+
* Transforms the result of a request using an effectful function.
|
|
92
|
+
*
|
|
81
93
|
* @since 1.0.0
|
|
82
94
|
* @category mapping & sequencing
|
|
83
95
|
*/
|
|
84
96
|
const mapEffect = exports.mapEffect = internal.mapEffect;
|
|
85
97
|
/**
|
|
98
|
+
* Appends a transformation of the request object before sending it.
|
|
99
|
+
*
|
|
86
100
|
* @since 1.0.0
|
|
87
101
|
* @category mapping & sequencing
|
|
88
102
|
*/
|
|
89
103
|
const mapRequest = exports.mapRequest = internal.mapRequest;
|
|
90
104
|
/**
|
|
105
|
+
* Appends an effectful transformation of the request object before sending it.
|
|
106
|
+
*
|
|
91
107
|
* @since 1.0.0
|
|
92
108
|
* @category mapping & sequencing
|
|
93
109
|
*/
|
|
94
110
|
const mapRequestEffect = exports.mapRequestEffect = internal.mapRequestEffect;
|
|
95
111
|
/**
|
|
112
|
+
* Prepends a transformation of the request object before sending it.
|
|
113
|
+
*
|
|
96
114
|
* @since 1.0.0
|
|
97
115
|
* @category mapping & sequencing
|
|
98
116
|
*/
|
|
99
117
|
const mapRequestInput = exports.mapRequestInput = internal.mapRequestInput;
|
|
100
118
|
/**
|
|
119
|
+
* Prepends an effectful transformation of the request object before sending it.
|
|
120
|
+
*
|
|
101
121
|
* @since 1.0.0
|
|
102
122
|
* @category mapping & sequencing
|
|
103
123
|
*/
|
|
104
124
|
const mapRequestInputEffect = exports.mapRequestInputEffect = internal.mapRequestInputEffect;
|
|
105
125
|
/**
|
|
126
|
+
* Retries the request based on a provided schedule or policy.
|
|
127
|
+
*
|
|
106
128
|
* @since 1.0.0
|
|
107
129
|
* @category error handling
|
|
108
130
|
*/
|
|
109
131
|
const retry = exports.retry = internal.retry;
|
|
110
132
|
/**
|
|
133
|
+
* Ensures resources are properly scoped and released after execution.
|
|
134
|
+
*
|
|
111
135
|
* @since 1.0.0
|
|
112
136
|
* @category resources & finalizers
|
|
113
137
|
*/
|
|
114
138
|
const scoped = exports.scoped = internal.scoped;
|
|
115
139
|
/**
|
|
140
|
+
* Creates a function that validates request data against a schema before sending it.
|
|
141
|
+
*
|
|
116
142
|
* @since 1.0.0
|
|
117
143
|
* @category schema
|
|
118
144
|
*/
|
|
119
145
|
const schemaFunction = exports.schemaFunction = internal.schemaFunction;
|
|
120
146
|
/**
|
|
147
|
+
* Performs an additional effect after a successful request.
|
|
148
|
+
*
|
|
121
149
|
* @since 1.0.0
|
|
122
150
|
* @category mapping & sequencing
|
|
123
151
|
*/
|
|
124
152
|
const tap = exports.tap = internal.tap;
|
|
125
153
|
/**
|
|
154
|
+
* Performs an additional effect on the request before sending it.
|
|
155
|
+
*
|
|
126
156
|
* @since 1.0.0
|
|
127
157
|
* @category mapping & sequencing
|
|
128
158
|
*/
|
|
129
159
|
const tapRequest = exports.tapRequest = internal.tapRequest;
|
|
130
160
|
/**
|
|
161
|
+
* Associates a `Ref` of cookies with the client for handling cookies across requests.
|
|
162
|
+
*
|
|
131
163
|
* @since 1.0.0
|
|
132
164
|
* @category cookies
|
|
133
165
|
*/
|
|
134
166
|
const withCookiesRef = exports.withCookiesRef = internal.withCookiesRef;
|
|
135
167
|
/**
|
|
168
|
+
* Follows HTTP redirects up to a specified number of times.
|
|
169
|
+
*
|
|
136
170
|
* @since 1.0.0
|
|
137
171
|
* @category redirects
|
|
138
172
|
*/
|
|
@@ -143,6 +177,8 @@ const followRedirects = exports.followRedirects = internal.followRedirects;
|
|
|
143
177
|
*/
|
|
144
178
|
const currentTracerDisabledWhen = exports.currentTracerDisabledWhen = internal.currentTracerDisabledWhen;
|
|
145
179
|
/**
|
|
180
|
+
* Disables tracing for specific requests based on a provided predicate.
|
|
181
|
+
*
|
|
146
182
|
* @since 1.0.0
|
|
147
183
|
* @category fiber refs
|
|
148
184
|
*/
|
|
@@ -153,6 +189,8 @@ const withTracerDisabledWhen = exports.withTracerDisabledWhen = internal.withTra
|
|
|
153
189
|
*/
|
|
154
190
|
const currentTracerPropagation = exports.currentTracerPropagation = internal.currentTracerPropagation;
|
|
155
191
|
/**
|
|
192
|
+
* Enables or disables tracing propagation for the request.
|
|
193
|
+
*
|
|
156
194
|
* @since 1.0.0
|
|
157
195
|
* @category fiber refs
|
|
158
196
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpClient.js","names":["internal","_interopRequireWildcard","require","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","TypeId","exports","HttpClient","tag","catchAll","catchTag","catchTags","filterOrElse","filterOrFail","filterStatus","filterStatusOk","make","makeService","transform","transformResponse","map","mapEffect","mapRequest","mapRequestEffect","mapRequestInput","mapRequestInputEffect","retry","scoped","schemaFunction","tap","tapRequest","withCookiesRef","followRedirects","currentTracerDisabledWhen","withTracerDisabledWhen","currentTracerPropagation","withTracerPropagation","layerMergedContext"],"sources":["../../src/HttpClient.ts"],"sourcesContent":[null],"mappings":";;;;;;AAqBA,IAAAA,QAAA,GAAAC,uBAAA,CAAAC,OAAA;AAAoD,SAAAC,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAH,wBAAAG,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,OAAAC,cAAA,CAAAC,IAAA,CAAAhB,CAAA,EAAAc,CAAA,SAAAG,CAAA,GAAAP,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAG,CAAA,KAAAA,CAAA,CAAAV,GAAA,IAAAU,CAAA,CAAAC,GAAA,IAAAP,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAG,CAAA,IAAAT,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAe,GAAA,CAAAlB,CAAA,EAAAQ,CAAA,GAAAA,CAAA;AAEpD;;;;AAIO,MAAMW,MAAM,GAAAC,OAAA,CAAAD,MAAA,GAAkBvB,QAAQ,CAACuB,MAAM;AA0DpD;;;;AAIO,MAAME,UAAU,GAAAD,OAAA,CAAAC,UAAA,GAAwDzB,QAAQ,CAAC0B,GAAG;AAE3F;;;;AAIO,MAAMC,QAAQ,GAAAH,OAAA,CAAAG,QAAA,GAQjB3B,QAAQ,CAAC2B,QAAQ;AAErB;;;;AAIO,MAAMC,QAAQ,GAAAJ,OAAA,CAAAI,QAAA,GAUjB5B,QAAQ,CAAC4B,QAAQ;AAErB;;;;AAIO,MAAMC,SAAS,GAAAL,OAAA,CAAAK,SAAA,GA4ClB7B,QAAQ,CAAC6B,SAAS;AAEtB
|
|
1
|
+
{"version":3,"file":"HttpClient.js","names":["internal","_interopRequireWildcard","require","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","TypeId","exports","HttpClient","tag","catchAll","catchTag","catchTags","filterOrElse","filterOrFail","filterStatus","filterStatusOk","make","makeService","transform","transformResponse","map","mapEffect","mapRequest","mapRequestEffect","mapRequestInput","mapRequestInputEffect","retry","scoped","schemaFunction","tap","tapRequest","withCookiesRef","followRedirects","currentTracerDisabledWhen","withTracerDisabledWhen","currentTracerPropagation","withTracerPropagation","layerMergedContext"],"sources":["../../src/HttpClient.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -116,9 +116,9 @@ const xForwardedHeaders = exports.xForwardedHeaders = /*#__PURE__*/make(httpApp
|
|
|
116
116
|
}) : request));
|
|
117
117
|
/** @internal */
|
|
118
118
|
const searchParamsParser = httpApp => Effect.withFiberRuntime(fiber => {
|
|
119
|
-
const context = fiber.
|
|
119
|
+
const context = fiber.currentContext;
|
|
120
120
|
const request = Context.unsafeGet(context, ServerRequest.HttpServerRequest);
|
|
121
|
-
const params = ServerRequest.searchParamsFromURL(new URL(request.
|
|
121
|
+
const params = ServerRequest.searchParamsFromURL(new URL(request.originalUrl));
|
|
122
122
|
return Effect.locally(httpApp, FiberRef.currentContext, Context.add(context, ServerRequest.ParsedSearchParams, params));
|
|
123
123
|
});
|
|
124
124
|
/** @internal */
|