@effect/platform 0.44.7 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Http/Client.js +11 -1
- package/dist/cjs/Http/Client.js.map +1 -1
- package/dist/cjs/Http/ClientResponse.js +60 -2
- package/dist/cjs/Http/ClientResponse.js.map +1 -1
- package/dist/cjs/Http/IncomingMessage.js +28 -1
- package/dist/cjs/Http/IncomingMessage.js.map +1 -1
- package/dist/cjs/internal/http/client.js +12 -7
- package/dist/cjs/internal/http/client.js.map +1 -1
- package/dist/cjs/internal/http/clientResponse.js +31 -1
- package/dist/cjs/internal/http/clientResponse.js.map +1 -1
- package/dist/dts/Http/Client.d.ts +18 -4
- package/dist/dts/Http/Client.d.ts.map +1 -1
- package/dist/dts/Http/ClientResponse.d.ts +66 -1
- package/dist/dts/Http/ClientResponse.d.ts.map +1 -1
- package/dist/dts/Http/IncomingMessage.d.ts +15 -0
- package/dist/dts/Http/IncomingMessage.d.ts.map +1 -1
- package/dist/esm/Http/Client.js +10 -0
- package/dist/esm/Http/Client.js.map +1 -1
- package/dist/esm/Http/ClientResponse.js +56 -1
- package/dist/esm/Http/ClientResponse.js.map +1 -1
- package/dist/esm/Http/IncomingMessage.js +24 -0
- package/dist/esm/Http/IncomingMessage.js.map +1 -1
- package/dist/esm/internal/http/client.js +11 -7
- package/dist/esm/internal/http/client.js.map +1 -1
- package/dist/esm/internal/http/clientResponse.js +22 -0
- package/dist/esm/internal/http/clientResponse.js.map +1 -1
- package/package.json +3 -3
- package/src/Http/Client.ts +37 -4
- package/src/Http/ClientResponse.ts +104 -1
- package/src/Http/IncomingMessage.ts +31 -0
- package/src/internal/http/client.ts +64 -39
- package/src/internal/http/clientResponse.ts +53 -0
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
import type * as ParseResult from "@effect/schema/ParseResult"
|
|
5
5
|
import type * as Schema from "@effect/schema/Schema"
|
|
6
6
|
import type * as Effect from "effect/Effect"
|
|
7
|
+
import type * as Scope from "effect/Scope"
|
|
8
|
+
import type * as Stream from "effect/Stream"
|
|
7
9
|
import * as internal from "../internal/http/clientResponse.js"
|
|
8
10
|
import type * as Error from "./ClientError.js"
|
|
9
11
|
import type * as ClientRequest from "./ClientRequest.js"
|
|
10
12
|
import type * as IncomingMessage from "./IncomingMessage.js"
|
|
13
|
+
import type * as UrlParams from "./UrlParams.js"
|
|
11
14
|
|
|
12
15
|
export {
|
|
13
16
|
/**
|
|
@@ -15,6 +18,11 @@ export {
|
|
|
15
18
|
* @category schema
|
|
16
19
|
*/
|
|
17
20
|
schemaBodyJson,
|
|
21
|
+
/**
|
|
22
|
+
* @since 1.0.0
|
|
23
|
+
* @category schema
|
|
24
|
+
*/
|
|
25
|
+
schemaBodyJsonEffect,
|
|
18
26
|
/**
|
|
19
27
|
* @since 1.0.0
|
|
20
28
|
* @category schema
|
|
@@ -24,7 +32,17 @@ export {
|
|
|
24
32
|
* @since 1.0.0
|
|
25
33
|
* @category schema
|
|
26
34
|
*/
|
|
27
|
-
|
|
35
|
+
schemaBodyUrlParamsEffect,
|
|
36
|
+
/**
|
|
37
|
+
* @since 1.0.0
|
|
38
|
+
* @category schema
|
|
39
|
+
*/
|
|
40
|
+
schemaHeaders,
|
|
41
|
+
/**
|
|
42
|
+
* @since 1.0.0
|
|
43
|
+
* @category schema
|
|
44
|
+
*/
|
|
45
|
+
schemaHeadersEffect
|
|
28
46
|
} from "./IncomingMessage.js"
|
|
29
47
|
|
|
30
48
|
/**
|
|
@@ -84,3 +102,88 @@ export const schemaNoBody: <
|
|
|
84
102
|
A
|
|
85
103
|
>(schema: Schema.Schema<A, I, R>) => (self: ClientResponse) => Effect.Effect<A, ParseResult.ParseError, R> =
|
|
86
104
|
internal.schemaNoBody
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @since 1.0.0
|
|
108
|
+
* @category accessors
|
|
109
|
+
*/
|
|
110
|
+
export const arrayBuffer: <E, R>(
|
|
111
|
+
effect: Effect.Effect<ClientResponse, E, R>
|
|
112
|
+
) => Effect.Effect<ArrayBuffer, Error.ResponseError | E, Exclude<R, Scope.Scope>> = internal.arrayBuffer
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @since 1.0.0
|
|
116
|
+
* @category accessors
|
|
117
|
+
*/
|
|
118
|
+
export const formData: <E, R>(
|
|
119
|
+
effect: Effect.Effect<ClientResponse, E, R>
|
|
120
|
+
) => Effect.Effect<FormData, Error.ResponseError | E, Exclude<R, Scope.Scope>> = internal.formData
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @since 1.0.0
|
|
124
|
+
* @category accessors
|
|
125
|
+
*/
|
|
126
|
+
export const json: <E, R>(
|
|
127
|
+
effect: Effect.Effect<ClientResponse, E, R>
|
|
128
|
+
) => Effect.Effect<unknown, Error.ResponseError | E, Exclude<R, Scope.Scope>> = internal.json
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @since 1.0.0
|
|
132
|
+
* @category accessors
|
|
133
|
+
*/
|
|
134
|
+
export const stream: <E, R>(
|
|
135
|
+
effect: Effect.Effect<ClientResponse, E, R>
|
|
136
|
+
) => Stream.Stream<Uint8Array, Error.ResponseError | E, Exclude<R, Scope.Scope>> = internal.stream
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @since 1.0.0
|
|
140
|
+
* @category accessors
|
|
141
|
+
*/
|
|
142
|
+
export const text: <E, R>(
|
|
143
|
+
effect: Effect.Effect<ClientResponse, E, R>
|
|
144
|
+
) => Effect.Effect<string, Error.ResponseError | E, Exclude<R, Scope.Scope>> = internal.text
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @since 1.0.0
|
|
148
|
+
* @category accessors
|
|
149
|
+
*/
|
|
150
|
+
export const urlParamsBody: <E, R>(
|
|
151
|
+
effect: Effect.Effect<ClientResponse, E, R>
|
|
152
|
+
) => Effect.Effect<UrlParams.UrlParams, Error.ResponseError | E, Exclude<R, Scope.Scope>> = internal.urlParamsBody
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @since 1.0.0
|
|
156
|
+
* @category schema
|
|
157
|
+
*/
|
|
158
|
+
export const schemaJsonEffect: <
|
|
159
|
+
R,
|
|
160
|
+
I extends {
|
|
161
|
+
readonly status?: number | undefined
|
|
162
|
+
readonly headers?: Readonly<Record<string, string>> | undefined
|
|
163
|
+
readonly body?: unknown
|
|
164
|
+
},
|
|
165
|
+
A
|
|
166
|
+
>(
|
|
167
|
+
schema: Schema.Schema<A, I, R>
|
|
168
|
+
) => <E, R2>(
|
|
169
|
+
effect: Effect.Effect<ClientResponse, E, R2>
|
|
170
|
+
) => Effect.Effect<
|
|
171
|
+
A,
|
|
172
|
+
Error.ResponseError | E | ParseResult.ParseError,
|
|
173
|
+
Exclude<R, Scope.Scope> | Exclude<R2, Scope.Scope>
|
|
174
|
+
> = internal.schemaJsonEffect
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @since 1.0.0
|
|
178
|
+
* @category schema
|
|
179
|
+
*/
|
|
180
|
+
export const schemaNoBodyEffect: <
|
|
181
|
+
R,
|
|
182
|
+
I extends { readonly status?: number | undefined; readonly headers?: Readonly<Record<string, string>> | undefined },
|
|
183
|
+
A
|
|
184
|
+
>(
|
|
185
|
+
schema: Schema.Schema<A, I, R>
|
|
186
|
+
) => <E, R2>(
|
|
187
|
+
effect: Effect.Effect<ClientResponse, E, R2>
|
|
188
|
+
) => Effect.Effect<A, E | ParseResult.ParseError, Exclude<R, Scope.Scope> | Exclude<R2, Scope.Scope>> =
|
|
189
|
+
internal.schemaNoBodyEffect
|
|
@@ -52,6 +52,15 @@ export const schemaBodyJson = <A, I, R>(schema: Schema.Schema<A, I, R>) => {
|
|
|
52
52
|
Effect.flatMap(self.json, parse)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* @since 1.0.0
|
|
57
|
+
* @category schema
|
|
58
|
+
*/
|
|
59
|
+
export const schemaBodyJsonEffect = <A, I, R>(schema: Schema.Schema<A, I, R>) => {
|
|
60
|
+
const decode = schemaBodyJson(schema)
|
|
61
|
+
return <E, E2, R2>(effect: Effect.Effect<IncomingMessage<E>, E2, R2>) => Effect.scoped(Effect.flatMap(effect, decode))
|
|
62
|
+
}
|
|
63
|
+
|
|
55
64
|
/**
|
|
56
65
|
* @since 1.0.0
|
|
57
66
|
* @category schema
|
|
@@ -64,6 +73,17 @@ export const schemaBodyUrlParams = <R, I extends Readonly<Record<string, string>
|
|
|
64
73
|
Effect.flatMap(self.urlParamsBody, (_) => parse(Object.fromEntries(_)))
|
|
65
74
|
}
|
|
66
75
|
|
|
76
|
+
/**
|
|
77
|
+
* @since 1.0.0
|
|
78
|
+
* @category schema
|
|
79
|
+
*/
|
|
80
|
+
export const schemaBodyUrlParamsEffect = <R, I extends Readonly<Record<string, string>>, A>(
|
|
81
|
+
schema: Schema.Schema<A, I, R>
|
|
82
|
+
) => {
|
|
83
|
+
const decode = schemaBodyUrlParams(schema)
|
|
84
|
+
return <E, E2, R2>(effect: Effect.Effect<IncomingMessage<E>, E2, R2>) => Effect.scoped(Effect.flatMap(effect, decode))
|
|
85
|
+
}
|
|
86
|
+
|
|
67
87
|
/**
|
|
68
88
|
* @since 1.0.0
|
|
69
89
|
* @category schema
|
|
@@ -73,6 +93,17 @@ export const schemaHeaders = <R, I extends Readonly<Record<string, string>>, A>(
|
|
|
73
93
|
return <E>(self: IncomingMessage<E>): Effect.Effect<A, ParseResult.ParseError, R> => parse(self.headers)
|
|
74
94
|
}
|
|
75
95
|
|
|
96
|
+
/**
|
|
97
|
+
* @since 1.0.0
|
|
98
|
+
* @category schema
|
|
99
|
+
*/
|
|
100
|
+
export const schemaHeadersEffect = <R, I extends Readonly<Record<string, string>>, A>(
|
|
101
|
+
schema: Schema.Schema<A, I, R>
|
|
102
|
+
) => {
|
|
103
|
+
const decode = schemaHeaders(schema)
|
|
104
|
+
return <E, E2, R2>(effect: Effect.Effect<IncomingMessage<E>, E2, R2>) => Effect.scoped(Effect.flatMap(effect, decode))
|
|
105
|
+
}
|
|
106
|
+
|
|
76
107
|
const SpanSchema = Schema.struct({
|
|
77
108
|
traceId: Schema.string,
|
|
78
109
|
spanId: Schema.string,
|
|
@@ -2,11 +2,12 @@ import type * as ParseResult from "@effect/schema/ParseResult"
|
|
|
2
2
|
import * as Schema from "@effect/schema/Schema"
|
|
3
3
|
import * as Context from "effect/Context"
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
|
-
import { dual } from "effect/Function"
|
|
5
|
+
import { dual, pipe } from "effect/Function"
|
|
6
6
|
import * as Layer from "effect/Layer"
|
|
7
7
|
import { pipeArguments } from "effect/Pipeable"
|
|
8
8
|
import type * as Predicate from "effect/Predicate"
|
|
9
9
|
import type * as Schedule from "effect/Schedule"
|
|
10
|
+
import type * as Scope from "effect/Scope"
|
|
10
11
|
import * as Stream from "effect/Stream"
|
|
11
12
|
import type * as Body from "../../Http/Body.js"
|
|
12
13
|
import type * as Client from "../../Http/Client.js"
|
|
@@ -68,7 +69,7 @@ const addB3Headers = (req: ClientRequest.ClientRequest) =>
|
|
|
68
69
|
export const makeDefault = (
|
|
69
70
|
f: (
|
|
70
71
|
request: ClientRequest.ClientRequest
|
|
71
|
-
) => Effect.Effect<ClientResponse.ClientResponse, Error.HttpClientError>
|
|
72
|
+
) => Effect.Effect<ClientResponse.ClientResponse, Error.HttpClientError, Scope.Scope>
|
|
72
73
|
): Client.Client.Default => make(Effect.flatMap(f), addB3Headers)
|
|
73
74
|
|
|
74
75
|
/** @internal */
|
|
@@ -91,25 +92,31 @@ export const fetch = (options?: RequestInit): Client.Client.Default =>
|
|
|
91
92
|
const fetch = fetch_._tag === "Some" ? fetch_.value : globalThis.fetch
|
|
92
93
|
const headers = new Headers(request.headers)
|
|
93
94
|
const send = (body: BodyInit | undefined) =>
|
|
94
|
-
|
|
95
|
-
Effect.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
95
|
+
pipe(
|
|
96
|
+
Effect.acquireRelease(
|
|
97
|
+
Effect.sync(() => new AbortController()),
|
|
98
|
+
(controller) => Effect.sync(() => controller.abort())
|
|
99
|
+
),
|
|
100
|
+
Effect.flatMap((controller) =>
|
|
101
|
+
Effect.tryPromise({
|
|
102
|
+
try: () =>
|
|
103
|
+
fetch(url, {
|
|
104
|
+
...options,
|
|
105
|
+
method: request.method,
|
|
106
|
+
headers,
|
|
107
|
+
body,
|
|
108
|
+
duplex: request.body._tag === "Stream" ? "half" : undefined,
|
|
109
|
+
signal: controller.signal
|
|
110
|
+
} as any),
|
|
111
|
+
catch: (_) =>
|
|
112
|
+
internalError.requestError({
|
|
113
|
+
request,
|
|
114
|
+
reason: "Transport",
|
|
115
|
+
error: _
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
),
|
|
119
|
+
Effect.map((_) => internalResponse.fromWeb(request, _))
|
|
113
120
|
)
|
|
114
121
|
if (Method.hasBody(request.method)) {
|
|
115
122
|
return send(convertBody(request.body))
|
|
@@ -449,6 +456,22 @@ export const mapEffect = dual<
|
|
|
449
456
|
) => Client.Client<R | R2, E | E2, B>
|
|
450
457
|
>(2, (self, f) => transformResponse(self, Effect.flatMap(f)))
|
|
451
458
|
|
|
459
|
+
/** @internal */
|
|
460
|
+
export const scoped = <R, E, A>(
|
|
461
|
+
self: Client.Client<R, E, A>
|
|
462
|
+
): Client.Client<Exclude<R, Scope.Scope>, E, A> => transformResponse(self, Effect.scoped)
|
|
463
|
+
|
|
464
|
+
/** @internal */
|
|
465
|
+
export const mapEffectScoped = dual<
|
|
466
|
+
<A, R2, E2, B>(
|
|
467
|
+
f: (a: A) => Effect.Effect<B, E2, R2>
|
|
468
|
+
) => <R, E>(self: Client.Client<R, E, A>) => Client.Client<Exclude<R | R2, Scope.Scope>, E | E2, B>,
|
|
469
|
+
<R, E, A, R2, E2, B>(
|
|
470
|
+
self: Client.Client<R, E, A>,
|
|
471
|
+
f: (a: A) => Effect.Effect<B, E2, R2>
|
|
472
|
+
) => Client.Client<Exclude<R | R2, Scope.Scope>, E | E2, B>
|
|
473
|
+
>(2, (self, f) => scoped(mapEffect(self, f)))
|
|
474
|
+
|
|
452
475
|
/** @internal */
|
|
453
476
|
export const mapRequest = dual<
|
|
454
477
|
(
|
|
@@ -532,7 +555,7 @@ export const schemaFunction = dual<
|
|
|
532
555
|
request: ClientRequest.ClientRequest
|
|
533
556
|
) => (
|
|
534
557
|
a: SA
|
|
535
|
-
) => Effect.Effect<A, E | ParseResult.ParseError | Error.RequestError, SR | R
|
|
558
|
+
) => Effect.Effect<A, E | ParseResult.ParseError | Error.RequestError, Exclude<SR | R, Scope.Scope>>,
|
|
536
559
|
<R, E, A, SA, SI, SR>(
|
|
537
560
|
self: Client.Client<R, E, A>,
|
|
538
561
|
schema: Schema.Schema<SA, SI, SR>
|
|
@@ -540,27 +563,29 @@ export const schemaFunction = dual<
|
|
|
540
563
|
request: ClientRequest.ClientRequest
|
|
541
564
|
) => (
|
|
542
565
|
a: SA
|
|
543
|
-
) => Effect.Effect<A, E | ParseResult.ParseError | Error.RequestError, SR | R
|
|
566
|
+
) => Effect.Effect<A, E | ParseResult.ParseError | Error.RequestError, Exclude<SR | R, Scope.Scope>>
|
|
544
567
|
>(2, (self, schema) => {
|
|
545
568
|
const encode = Schema.encode(schema)
|
|
546
569
|
return (request) => (a) =>
|
|
547
|
-
Effect.
|
|
548
|
-
Effect.
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
570
|
+
Effect.scoped(
|
|
571
|
+
Effect.flatMap(
|
|
572
|
+
Effect.tryMap(encode(a), {
|
|
573
|
+
try: (body) => new TextEncoder().encode(JSON.stringify(body)),
|
|
574
|
+
catch: (error) =>
|
|
575
|
+
internalError.requestError({
|
|
576
|
+
request,
|
|
577
|
+
reason: "Encode",
|
|
578
|
+
error
|
|
579
|
+
})
|
|
580
|
+
}),
|
|
581
|
+
(body) =>
|
|
582
|
+
self(
|
|
583
|
+
internalRequest.setBody(
|
|
584
|
+
request,
|
|
585
|
+
internalBody.uint8Array(body, "application/json")
|
|
586
|
+
)
|
|
562
587
|
)
|
|
563
|
-
|
|
588
|
+
)
|
|
564
589
|
)
|
|
565
590
|
})
|
|
566
591
|
|
|
@@ -170,3 +170,56 @@ export const schemaNoBody = <
|
|
|
170
170
|
headers: self.headers
|
|
171
171
|
})
|
|
172
172
|
}
|
|
173
|
+
|
|
174
|
+
/** @internal */
|
|
175
|
+
export const arrayBuffer = <E, R>(effect: Effect.Effect<ClientResponse.ClientResponse, E, R>) =>
|
|
176
|
+
Effect.scoped(Effect.flatMap(effect, (_) => _.arrayBuffer))
|
|
177
|
+
|
|
178
|
+
/** @internal */
|
|
179
|
+
export const text = <E, R>(effect: Effect.Effect<ClientResponse.ClientResponse, E, R>) =>
|
|
180
|
+
Effect.scoped(Effect.flatMap(effect, (_) => _.text))
|
|
181
|
+
|
|
182
|
+
/** @internal */
|
|
183
|
+
export const json = <E, R>(effect: Effect.Effect<ClientResponse.ClientResponse, E, R>) =>
|
|
184
|
+
Effect.scoped(Effect.flatMap(effect, (_) => _.json))
|
|
185
|
+
|
|
186
|
+
/** @internal */
|
|
187
|
+
export const urlParamsBody = <E, R>(effect: Effect.Effect<ClientResponse.ClientResponse, E, R>) =>
|
|
188
|
+
Effect.scoped(Effect.flatMap(effect, (_) => _.urlParamsBody))
|
|
189
|
+
|
|
190
|
+
/** @internal */
|
|
191
|
+
export const formData = <E, R>(effect: Effect.Effect<ClientResponse.ClientResponse, E, R>) =>
|
|
192
|
+
Effect.scoped(Effect.flatMap(effect, (_) => _.formData))
|
|
193
|
+
|
|
194
|
+
/** @internal */
|
|
195
|
+
export const stream = <E, R>(effect: Effect.Effect<ClientResponse.ClientResponse, E, R>) =>
|
|
196
|
+
Stream.unwrapScoped(Effect.map(effect, (_) => _.stream))
|
|
197
|
+
|
|
198
|
+
/** @internal */
|
|
199
|
+
export const schemaJsonEffect = <
|
|
200
|
+
R,
|
|
201
|
+
I extends {
|
|
202
|
+
readonly status?: number | undefined
|
|
203
|
+
readonly headers?: Readonly<Record<string, string>> | undefined
|
|
204
|
+
readonly body?: unknown | undefined
|
|
205
|
+
},
|
|
206
|
+
A
|
|
207
|
+
>(schema: Schema.Schema<A, I, R>) => {
|
|
208
|
+
const decode = schemaJson(schema)
|
|
209
|
+
return <E, R2>(effect: Effect.Effect<ClientResponse.ClientResponse, E, R2>) =>
|
|
210
|
+
Effect.scoped(Effect.flatMap(effect, decode))
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** @internal */
|
|
214
|
+
export const schemaNoBodyEffect = <
|
|
215
|
+
R,
|
|
216
|
+
I extends {
|
|
217
|
+
readonly status?: number | undefined
|
|
218
|
+
readonly headers?: Readonly<Record<string, string>> | undefined
|
|
219
|
+
},
|
|
220
|
+
A
|
|
221
|
+
>(schema: Schema.Schema<A, I, R>) => {
|
|
222
|
+
const decode = schemaNoBody(schema)
|
|
223
|
+
return <E, R2>(effect: Effect.Effect<ClientResponse.ClientResponse, E, R2>) =>
|
|
224
|
+
Effect.scoped(Effect.flatMap(effect, decode))
|
|
225
|
+
}
|