effect 4.0.0-beta.62 → 4.0.0-beta.63
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/Effect.d.ts +38 -0
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +38 -0
- package/dist/Effect.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/effect.js +2 -0
- package/dist/internal/effect.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.js +11 -7
- package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiClient.js +2 -1
- package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiTest.d.ts +20 -0
- package/dist/unstable/httpapi/HttpApiTest.d.ts.map +1 -0
- package/dist/unstable/httpapi/HttpApiTest.js +54 -0
- package/dist/unstable/httpapi/HttpApiTest.js.map +1 -0
- package/dist/unstable/httpapi/index.d.ts +4 -0
- package/dist/unstable/httpapi/index.d.ts.map +1 -1
- package/dist/unstable/httpapi/index.js +4 -0
- package/dist/unstable/httpapi/index.js.map +1 -1
- package/package.json +1 -1
- package/src/Effect.ts +41 -0
- package/src/index.ts +1 -1
- package/src/internal/effect.ts +9 -0
- package/src/unstable/httpapi/HttpApiBuilder.ts +14 -8
- package/src/unstable/httpapi/HttpApiClient.ts +4 -3
- package/src/unstable/httpapi/HttpApiTest.ts +95 -0
- package/src/unstable/httpapi/index.ts +5 -0
|
@@ -77,7 +77,7 @@ export const layer = <Id extends string, Groups extends HttpApiGroup.Any>(
|
|
|
77
77
|
key.startsWith("effect/httpapi/HttpApiGroup/")
|
|
78
78
|
)
|
|
79
79
|
for (const group of Object.values(api.groups)) {
|
|
80
|
-
const groupRoutes = services.mapUnsafe.get(group.key) as Array<HttpRouter.Route<any, any>>
|
|
80
|
+
const groupRoutes = services.mapUnsafe.get(group.key)?.routes as Array<HttpRouter.Route<any, any>>
|
|
81
81
|
if (groupRoutes === undefined) {
|
|
82
82
|
const available = availableGroups.length === 0 ? "none" : availableGroups.join(", ")
|
|
83
83
|
return yield* Effect.die(
|
|
@@ -130,10 +130,15 @@ export const group = <
|
|
|
130
130
|
? (yield* result as Effect.Effect<any, any, any>)
|
|
131
131
|
: result
|
|
132
132
|
const routes: Array<HttpRouter.Route<any, any>> = []
|
|
133
|
-
for (const item of handlers.handlers) {
|
|
133
|
+
for (const item of handlers.handlers.values()) {
|
|
134
134
|
routes.push(handlerToRoute(group as any, item, services))
|
|
135
135
|
}
|
|
136
|
-
return Context.makeUnsafe(
|
|
136
|
+
return Context.makeUnsafe(
|
|
137
|
+
new Map([[group.key, {
|
|
138
|
+
routes,
|
|
139
|
+
handlers: handlers.handlers
|
|
140
|
+
}]])
|
|
141
|
+
)
|
|
137
142
|
})) as any
|
|
138
143
|
|
|
139
144
|
/**
|
|
@@ -162,7 +167,7 @@ export interface Handlers<
|
|
|
162
167
|
_Endpoints: Covariant<Endpoints>
|
|
163
168
|
}
|
|
164
169
|
readonly group: HttpApiGroup.AnyWithProps
|
|
165
|
-
readonly handlers:
|
|
170
|
+
readonly handlers: Map<string, Handlers.Item<R>>
|
|
166
171
|
|
|
167
172
|
/**
|
|
168
173
|
* Add the implementation for an `HttpApiEndpoint` to a `Handlers` group.
|
|
@@ -449,7 +454,7 @@ const HandlersProto = {
|
|
|
449
454
|
options?: { readonly uninterruptible?: boolean | undefined } | undefined
|
|
450
455
|
) {
|
|
451
456
|
const endpoint = this.group.endpoints[name]
|
|
452
|
-
this.handlers.
|
|
457
|
+
this.handlers.set(name, {
|
|
453
458
|
endpoint,
|
|
454
459
|
handler,
|
|
455
460
|
isRaw: false,
|
|
@@ -464,7 +469,7 @@ const HandlersProto = {
|
|
|
464
469
|
options?: { readonly uninterruptible?: boolean | undefined } | undefined
|
|
465
470
|
) {
|
|
466
471
|
const endpoint = this.group.endpoints[name]
|
|
467
|
-
this.handlers.
|
|
472
|
+
this.handlers.set(name, {
|
|
468
473
|
endpoint,
|
|
469
474
|
handler,
|
|
470
475
|
isRaw: true,
|
|
@@ -479,7 +484,7 @@ const makeHandlers = <R, Endpoints extends HttpApiEndpoint.Any>(
|
|
|
479
484
|
): Handlers<R, Endpoints> => {
|
|
480
485
|
const self = Object.create(HandlersProto)
|
|
481
486
|
self.group = group
|
|
482
|
-
self.handlers = new
|
|
487
|
+
self.handlers = new Map<string, Handlers.Item<R>>()
|
|
483
488
|
return self
|
|
484
489
|
}
|
|
485
490
|
|
|
@@ -632,7 +637,8 @@ function handlerToHttpEffect(
|
|
|
632
637
|
)
|
|
633
638
|
}
|
|
634
639
|
|
|
635
|
-
|
|
640
|
+
/** @internal */
|
|
641
|
+
export function handlerToRoute(
|
|
636
642
|
group: HttpApiGroup.AnyWithProps,
|
|
637
643
|
handler: Handlers.Item<any>,
|
|
638
644
|
context: Context.Context<any>
|
|
@@ -175,7 +175,8 @@ type UrlBuilderTopLevelMethods<Groups extends HttpApiGroup.Any> = Extract<Groups
|
|
|
175
175
|
: never :
|
|
176
176
|
never
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
/** @internal */
|
|
179
|
+
export const makeClient = <ApiId extends string, Groups extends HttpApiGroup.Any, E, R>(
|
|
179
180
|
api: HttpApi.HttpApi<ApiId, Groups>,
|
|
180
181
|
options: {
|
|
181
182
|
readonly httpClient: HttpClient.HttpClient.With<E, R>
|
|
@@ -201,9 +202,9 @@ const makeClient = <ApiId extends string, Groups extends HttpApiGroup.Any, E, R>
|
|
|
201
202
|
| undefined
|
|
202
203
|
readonly baseUrl?: URL | string | undefined
|
|
203
204
|
}
|
|
204
|
-
): Effect.Effect<void
|
|
205
|
+
): Effect.Effect<void> =>
|
|
205
206
|
Effect.gen(function*() {
|
|
206
|
-
const services = yield* Effect.context
|
|
207
|
+
const services = yield* Effect.context()
|
|
207
208
|
|
|
208
209
|
const httpClient = options.httpClient.pipe(
|
|
209
210
|
options?.baseUrl === undefined
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 4.0.0
|
|
3
|
+
*/
|
|
4
|
+
import * as Context from "../../Context.ts"
|
|
5
|
+
import * as Effect from "../../Effect.ts"
|
|
6
|
+
import type { FileSystem } from "../../FileSystem.ts"
|
|
7
|
+
import * as Layer from "../../Layer.ts"
|
|
8
|
+
import type { Path } from "../../Path.ts"
|
|
9
|
+
import type { Scope } from "../../Scope.ts"
|
|
10
|
+
import type { Generator } from "../http/Etag.ts"
|
|
11
|
+
import * as HttpClient from "../http/HttpClient.ts"
|
|
12
|
+
import type { HttpPlatform } from "../http/HttpPlatform.ts"
|
|
13
|
+
import * as HttpRouter from "../http/HttpRouter.ts"
|
|
14
|
+
import * as HttpServerRequest from "../http/HttpServerRequest.ts"
|
|
15
|
+
import * as HttpServerResponse from "../http/HttpServerResponse.ts"
|
|
16
|
+
import type * as HttpApi from "./HttpApi.ts"
|
|
17
|
+
import type { Handlers } from "./HttpApiBuilder.ts"
|
|
18
|
+
import * as HttpApiBuilder from "./HttpApiBuilder.ts"
|
|
19
|
+
import * as HttpApiClient from "./HttpApiClient.ts"
|
|
20
|
+
import type * as HttpApiEndpoint from "./HttpApiEndpoint.ts"
|
|
21
|
+
import type * as HttpApiGroup from "./HttpApiGroup.ts"
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @since 4.0.0
|
|
25
|
+
* @category Testing
|
|
26
|
+
*/
|
|
27
|
+
export const groups = Effect.fnUntraced(function*<
|
|
28
|
+
ApiId extends string,
|
|
29
|
+
Groups extends HttpApiGroup.Any,
|
|
30
|
+
const Names extends ReadonlyArray<HttpApiGroup.Name<Groups>>,
|
|
31
|
+
SelectedGroups = HttpApiGroup.WithName<Groups, Names[number]>
|
|
32
|
+
>(
|
|
33
|
+
api: HttpApi.HttpApi<ApiId, Groups>,
|
|
34
|
+
groupNames: Names
|
|
35
|
+
): Effect.fn.Return<
|
|
36
|
+
HttpApiClient.Client<Groups>,
|
|
37
|
+
never,
|
|
38
|
+
| HttpApiGroup.ToService<ApiId, SelectedGroups>
|
|
39
|
+
| HttpApiGroup.MiddlewareClient<Groups>
|
|
40
|
+
| HttpApiEndpoint.Middleware<HttpApiGroup.Endpoints<Groups>>
|
|
41
|
+
| FileSystem
|
|
42
|
+
| Generator
|
|
43
|
+
| HttpPlatform
|
|
44
|
+
| Path
|
|
45
|
+
| Scope
|
|
46
|
+
> {
|
|
47
|
+
let context = yield* Effect.context<HttpApiGroup.ToService<ApiId, SelectedGroups>>()
|
|
48
|
+
|
|
49
|
+
for (const name in api.groups) {
|
|
50
|
+
const group = api.groups[name]
|
|
51
|
+
if (groupNames.includes(name as any)) {
|
|
52
|
+
continue
|
|
53
|
+
}
|
|
54
|
+
const handlers = new Map<string, Handlers.Item<never>>()
|
|
55
|
+
const routes: Array<HttpRouter.Route<any, any>> = []
|
|
56
|
+
for (const endpointName in group.endpoints) {
|
|
57
|
+
const endpoint = group.endpoints[endpointName]
|
|
58
|
+
const handler: Handlers.Item<never> = {
|
|
59
|
+
endpoint: endpoint as any,
|
|
60
|
+
handler: () => Effect.die(new Error(`Unhandled endpoint: ${endpointName}`)),
|
|
61
|
+
isRaw: false,
|
|
62
|
+
uninterruptible: false
|
|
63
|
+
}
|
|
64
|
+
handlers.set(endpointName, handler)
|
|
65
|
+
routes.push(HttpApiBuilder.handlerToRoute(group as any, handler, context))
|
|
66
|
+
}
|
|
67
|
+
context = Context.add(context, group as any, { handlers, routes })
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const layer: Layer.Layer<
|
|
71
|
+
never,
|
|
72
|
+
never,
|
|
73
|
+
| FileSystem
|
|
74
|
+
| Generator
|
|
75
|
+
| HttpPlatform
|
|
76
|
+
| HttpRouter.HttpRouter
|
|
77
|
+
| Path
|
|
78
|
+
> = HttpApiBuilder.layer(api).pipe(
|
|
79
|
+
Layer.provide(Layer.succeedContext(context))
|
|
80
|
+
) as any
|
|
81
|
+
const handler = yield* HttpRouter.toHttpEffect(layer)
|
|
82
|
+
const httpClient = HttpClient.make(Effect.fnUntraced(function*(request) {
|
|
83
|
+
const serverRequest = HttpServerRequest.fromClientRequest(request)
|
|
84
|
+
const response = yield* handler.pipe(
|
|
85
|
+
Effect.provideService(HttpServerRequest.HttpServerRequest, serverRequest),
|
|
86
|
+
Effect.orDie
|
|
87
|
+
)
|
|
88
|
+
return HttpServerResponse.toClientResponse(response)
|
|
89
|
+
}, Effect.scoped))
|
|
90
|
+
|
|
91
|
+
return yield* HttpApiClient.makeWith(api, {
|
|
92
|
+
httpClient,
|
|
93
|
+
baseUrl: "http://localhost:3000"
|
|
94
|
+
})
|
|
95
|
+
})
|