@effect/platform 0.11.5 → 0.12.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.
Files changed (193) hide show
  1. package/FileSystem.d.ts +43 -11
  2. package/FileSystem.d.ts.map +1 -1
  3. package/FileSystem.js +33 -3
  4. package/FileSystem.js.map +1 -1
  5. package/Http/App.d.ts +18 -0
  6. package/Http/App.d.ts.map +1 -0
  7. package/Http/App.js +6 -0
  8. package/Http/App.js.map +1 -0
  9. package/Http/Body.d.ts +37 -14
  10. package/Http/Body.d.ts.map +1 -1
  11. package/Http/Body.js +17 -5
  12. package/Http/Body.js.map +1 -1
  13. package/Http/Client.d.ts +2 -2
  14. package/Http/Client.d.ts.map +1 -1
  15. package/Http/Client.js +3 -3
  16. package/Http/Client.js.map +1 -1
  17. package/Http/ClientRequest.d.ts +44 -1
  18. package/Http/ClientRequest.d.ts.map +1 -1
  19. package/Http/ClientRequest.js +21 -3
  20. package/Http/ClientRequest.js.map +1 -1
  21. package/Http/ClientResponse.d.ts +13 -1
  22. package/Http/ClientResponse.d.ts.map +1 -1
  23. package/Http/ClientResponse.js +14 -2
  24. package/Http/ClientResponse.js.map +1 -1
  25. package/Http/FormData.d.ts +97 -4
  26. package/Http/FormData.d.ts.map +1 -1
  27. package/Http/FormData.js +77 -2
  28. package/Http/FormData.js.map +1 -1
  29. package/Http/Headers.d.ts +29 -3
  30. package/Http/Headers.d.ts.map +1 -1
  31. package/Http/Headers.js +13 -1
  32. package/Http/Headers.js.map +1 -1
  33. package/Http/IncomingMessage.d.ts +26 -5
  34. package/Http/IncomingMessage.d.ts.map +1 -1
  35. package/Http/IncomingMessage.js +38 -3
  36. package/Http/IncomingMessage.js.map +1 -1
  37. package/Http/Middleware.d.ts +56 -0
  38. package/Http/Middleware.d.ts.map +1 -0
  39. package/Http/Middleware.js +46 -0
  40. package/Http/Middleware.js.map +1 -0
  41. package/Http/Router.d.ts +221 -0
  42. package/Http/Router.d.ts.map +1 -0
  43. package/Http/Router.js +148 -0
  44. package/Http/Router.js.map +1 -0
  45. package/Http/Server.d.ts +85 -0
  46. package/Http/Server.d.ts.map +1 -0
  47. package/Http/Server.js +34 -0
  48. package/Http/Server.js.map +1 -0
  49. package/Http/ServerError.d.ts +96 -0
  50. package/Http/ServerError.d.ts.map +1 -0
  51. package/Http/ServerError.js +40 -0
  52. package/Http/ServerError.js.map +1 -0
  53. package/Http/ServerRequest.d.ts +82 -0
  54. package/Http/ServerRequest.d.ts.map +1 -0
  55. package/Http/ServerRequest.js +66 -0
  56. package/Http/ServerRequest.js.map +1 -0
  57. package/Http/ServerResponse.d.ts +168 -0
  58. package/Http/ServerResponse.d.ts.map +1 -0
  59. package/Http/ServerResponse.js +116 -0
  60. package/Http/ServerResponse.js.map +1 -0
  61. package/Http/UrlParams.d.ts +20 -5
  62. package/Http/UrlParams.d.ts.map +1 -1
  63. package/Http/UrlParams.js.map +1 -1
  64. package/HttpServer.d.ts +44 -0
  65. package/HttpServer.d.ts.map +1 -0
  66. package/HttpServer.js +29 -0
  67. package/HttpServer.js.map +1 -0
  68. package/internal/fileSystem.js +33 -12
  69. package/internal/fileSystem.js.map +1 -1
  70. package/internal/http/body.js +28 -28
  71. package/internal/http/body.js.map +1 -1
  72. package/internal/http/client.d.ts.map +1 -1
  73. package/internal/http/client.js +32 -26
  74. package/internal/http/client.js.map +1 -1
  75. package/internal/http/clientRequest.js +22 -6
  76. package/internal/http/clientRequest.js.map +1 -1
  77. package/internal/http/clientResponse.js +15 -12
  78. package/internal/http/clientResponse.js.map +1 -1
  79. package/internal/http/formData.d.ts +8 -0
  80. package/internal/http/formData.d.ts.map +1 -0
  81. package/internal/http/formData.js +88 -0
  82. package/internal/http/formData.js.map +1 -0
  83. package/internal/http/middleware.d.ts +2 -0
  84. package/internal/http/middleware.d.ts.map +1 -0
  85. package/internal/http/middleware.js +43 -0
  86. package/internal/http/middleware.js.map +1 -0
  87. package/internal/http/router.d.ts +2 -0
  88. package/internal/http/router.d.ts.map +1 -0
  89. package/internal/http/router.js +187 -0
  90. package/internal/http/router.js.map +1 -0
  91. package/internal/http/server.d.ts +2 -0
  92. package/internal/http/server.d.ts.map +1 -0
  93. package/internal/http/server.js +30 -0
  94. package/internal/http/server.js.map +1 -0
  95. package/internal/http/serverError.d.ts +2 -0
  96. package/internal/http/serverError.d.ts.map +1 -0
  97. package/internal/http/serverError.js +30 -0
  98. package/internal/http/serverError.js.map +1 -0
  99. package/internal/http/serverRequest.d.ts +2 -0
  100. package/internal/http/serverRequest.d.ts.map +1 -0
  101. package/internal/http/serverRequest.js +57 -0
  102. package/internal/http/serverRequest.js.map +1 -0
  103. package/internal/http/serverResponse.d.ts +2 -0
  104. package/internal/http/serverResponse.d.ts.map +1 -0
  105. package/internal/http/serverResponse.js +109 -0
  106. package/internal/http/serverResponse.js.map +1 -0
  107. package/mjs/FileSystem.mjs +26 -1
  108. package/mjs/FileSystem.mjs.map +1 -1
  109. package/mjs/Http/App.mjs +2 -0
  110. package/mjs/Http/App.mjs.map +1 -0
  111. package/mjs/Http/Body.mjs +12 -2
  112. package/mjs/Http/Body.mjs.map +1 -1
  113. package/mjs/Http/Client.mjs +1 -1
  114. package/mjs/Http/Client.mjs.map +1 -1
  115. package/mjs/Http/ClientRequest.mjs +16 -1
  116. package/mjs/Http/ClientRequest.mjs.map +1 -1
  117. package/mjs/Http/ClientResponse.mjs +11 -1
  118. package/mjs/Http/ClientResponse.mjs.map +1 -1
  119. package/mjs/Http/FormData.mjs +62 -1
  120. package/mjs/Http/FormData.mjs.map +1 -1
  121. package/mjs/Http/Headers.mjs +10 -0
  122. package/mjs/Http/Headers.mjs.map +1 -1
  123. package/mjs/Http/IncomingMessage.mjs +32 -1
  124. package/mjs/Http/IncomingMessage.mjs.map +1 -1
  125. package/mjs/Http/Middleware.mjs +32 -0
  126. package/mjs/Http/Middleware.mjs.map +1 -0
  127. package/mjs/Http/Router.mjs +117 -0
  128. package/mjs/Http/Router.mjs.map +1 -0
  129. package/mjs/Http/Server.mjs +22 -0
  130. package/mjs/Http/Server.mjs.map +1 -0
  131. package/mjs/Http/ServerError.mjs +27 -0
  132. package/mjs/Http/ServerError.mjs.map +1 -0
  133. package/mjs/Http/ServerRequest.mjs +48 -0
  134. package/mjs/Http/ServerRequest.mjs.map +1 -0
  135. package/mjs/Http/ServerResponse.mjs +90 -0
  136. package/mjs/Http/ServerResponse.mjs.map +1 -0
  137. package/mjs/Http/UrlParams.mjs.map +1 -1
  138. package/mjs/HttpServer.mjs +24 -0
  139. package/mjs/HttpServer.mjs.map +1 -0
  140. package/mjs/internal/fileSystem.mjs +27 -11
  141. package/mjs/internal/fileSystem.mjs.map +1 -1
  142. package/mjs/internal/http/body.mjs +23 -25
  143. package/mjs/internal/http/body.mjs.map +1 -1
  144. package/mjs/internal/http/client.mjs +30 -24
  145. package/mjs/internal/http/client.mjs.map +1 -1
  146. package/mjs/internal/http/clientRequest.mjs +16 -4
  147. package/mjs/internal/http/clientRequest.mjs.map +1 -1
  148. package/mjs/internal/http/clientResponse.mjs +15 -12
  149. package/mjs/internal/http/clientResponse.mjs.map +1 -1
  150. package/mjs/internal/http/formData.mjs +67 -0
  151. package/mjs/internal/http/formData.mjs.map +1 -0
  152. package/mjs/internal/http/middleware.mjs +29 -0
  153. package/mjs/internal/http/middleware.mjs.map +1 -0
  154. package/mjs/internal/http/router.mjs +155 -0
  155. package/mjs/internal/http/router.mjs.map +1 -0
  156. package/mjs/internal/http/server.mjs +17 -0
  157. package/mjs/internal/http/server.mjs.map +1 -0
  158. package/mjs/internal/http/serverError.mjs +17 -0
  159. package/mjs/internal/http/serverError.mjs.map +1 -0
  160. package/mjs/internal/http/serverRequest.mjs +41 -0
  161. package/mjs/internal/http/serverRequest.mjs.map +1 -0
  162. package/mjs/internal/http/serverResponse.mjs +82 -0
  163. package/mjs/internal/http/serverResponse.mjs.map +1 -0
  164. package/package.json +2 -1
  165. package/src/FileSystem.ts +52 -27
  166. package/src/Http/App.ts +19 -0
  167. package/src/Http/Body.ts +41 -14
  168. package/src/Http/Client.ts +6 -3
  169. package/src/Http/ClientRequest.ts +52 -2
  170. package/src/Http/ClientResponse.ts +13 -1
  171. package/src/Http/FormData.ts +121 -5
  172. package/src/Http/Headers.ts +37 -3
  173. package/src/Http/IncomingMessage.ts +46 -3
  174. package/src/Http/Middleware.ts +69 -0
  175. package/src/Http/Router.ts +342 -0
  176. package/src/Http/Server.ts +134 -0
  177. package/src/Http/ServerError.ts +111 -0
  178. package/src/Http/ServerRequest.ts +120 -0
  179. package/src/Http/ServerResponse.ts +202 -0
  180. package/src/Http/UrlParams.ts +20 -5
  181. package/src/HttpServer.ts +44 -0
  182. package/src/internal/fileSystem.ts +28 -7
  183. package/src/internal/http/body.ts +65 -39
  184. package/src/internal/http/client.ts +45 -36
  185. package/src/internal/http/clientRequest.ts +64 -4
  186. package/src/internal/http/clientResponse.ts +21 -13
  187. package/src/internal/http/formData.ts +140 -0
  188. package/src/internal/http/middleware.ts +72 -0
  189. package/src/internal/http/router.ts +298 -0
  190. package/src/internal/http/server.ts +80 -0
  191. package/src/internal/http/serverError.ts +26 -0
  192. package/src/internal/http/serverRequest.ts +71 -0
  193. package/src/internal/http/serverResponse.ts +255 -0
@@ -0,0 +1,298 @@
1
+ import * as Chunk from "@effect/data/Chunk"
2
+ import * as Context from "@effect/data/Context"
3
+ import * as Equal from "@effect/data/Equal"
4
+ import { dual } from "@effect/data/Function"
5
+ import * as Hash from "@effect/data/Hash"
6
+ import * as Option from "@effect/data/Option"
7
+ import { pipeArguments } from "@effect/data/Pipeable"
8
+ import * as Effect from "@effect/io/Effect"
9
+ import type * as App from "@effect/platform/Http/App"
10
+ import type * as Method from "@effect/platform/Http/Method"
11
+ import type * as Router from "@effect/platform/Http/Router"
12
+ import * as Error from "@effect/platform/Http/ServerError"
13
+ import * as ServerRequest from "@effect/platform/Http/ServerRequest"
14
+ import * as Schema from "@effect/schema/Schema"
15
+ import * as Channel from "@effect/stream/Channel"
16
+ import * as Sink from "@effect/stream/Sink"
17
+ import * as Stream from "@effect/stream/Stream"
18
+ import type { HTTPMethod } from "find-my-way"
19
+ import FindMyWay from "find-my-way"
20
+
21
+ /** @internal */
22
+ export const TypeId: Router.TypeId = Symbol.for("@effect/platform/Http/Router") as Router.TypeId
23
+
24
+ /** @internal */
25
+ export const RouteTypeId: Router.RouteTypeId = Symbol.for("@effect/platform/Http/Router/Route") as Router.RouteTypeId
26
+
27
+ /** @internal */
28
+ export const RouteContextTypeId: Router.RouteContextTypeId = Symbol.for(
29
+ "@effect/platform/Http/Router/RouteContext"
30
+ ) as Router.RouteContextTypeId
31
+
32
+ /** @internal */
33
+ export const RouteContext = Context.Tag<Router.RouteContext>("@effect/platform/Http/Router/RouteContext")
34
+
35
+ /** @internal */
36
+ export const params = Effect.map(RouteContext, (_) => _.params)
37
+
38
+ /** @internal */
39
+ export const searchParams = Effect.map(RouteContext, (_) => _.searchParams)
40
+
41
+ /** @internal */
42
+ export const schemaParams = <I extends Readonly<Record<string, string>>, A>(schema: Schema.Schema<I, A>) => {
43
+ const parse = Schema.parse(schema)
44
+ return Effect.flatMap(
45
+ RouteContext,
46
+ (_) =>
47
+ parse({
48
+ ..._.searchParams,
49
+ ..._.params
50
+ })
51
+ )
52
+ }
53
+
54
+ class RouterImpl<R, E> implements Router.Router<R, E> {
55
+ readonly [TypeId]: Router.TypeId
56
+ constructor(
57
+ readonly routes: Chunk.Chunk<Router.Route<R, E>>,
58
+ readonly mounts: Chunk.Chunk<readonly [string, App.Default<R, E>]>
59
+ ) {
60
+ this[TypeId] = TypeId
61
+ this[Effect.EffectTypeId] = undefined
62
+ this[Stream.StreamTypeId] = undefined
63
+ this[Sink.SinkTypeId] = undefined
64
+ this[Channel.ChannelTypeId] = undefined
65
+ }
66
+ pipe() {
67
+ return pipeArguments(this, arguments)
68
+ }
69
+ private httpApp: App.Default<Exclude<R, Router.RouteContext>, E | Error.RouteNotFound> | undefined
70
+ commit() {
71
+ if (this.httpApp === undefined) {
72
+ this.httpApp = toHttpApp(this)
73
+ }
74
+ return this.httpApp
75
+ }
76
+
77
+ // implements HttpApp/Effect
78
+ public _tag = "Commit" // OP_COMMIT
79
+ readonly [Effect.EffectTypeId]: any
80
+ readonly [Stream.StreamTypeId]: any
81
+ readonly [Sink.SinkTypeId]: any
82
+ readonly [Channel.ChannelTypeId]: any;
83
+ [Equal.symbol](
84
+ this: RouterImpl<R, E>,
85
+ that: RouterImpl<R, E>
86
+ ): boolean {
87
+ return this === that
88
+ }
89
+ [Hash.symbol](this: RouterImpl<R, E>): number {
90
+ return Hash.random(this)
91
+ }
92
+ }
93
+
94
+ const toHttpApp = <R, E>(
95
+ self: Router.Router<R, E>
96
+ ): App.Default<Exclude<R, Router.RouteContext>, E | Error.RouteNotFound> => {
97
+ const router = FindMyWay()
98
+ Chunk.forEach(self.mounts, ([path, app]) => {
99
+ const fn = () => {}
100
+ fn.handler = Effect.updateService(app, ServerRequest.ServerRequest, (request) => sliceRequestUrl(request, path))
101
+ router.all(path, fn)
102
+ router.all(path + "/*", fn)
103
+ })
104
+ Chunk.forEach(self.routes, (route) => {
105
+ const fn = () => {}
106
+ fn.handler = route
107
+ if (route.method === "*") {
108
+ router.all(route.path, fn)
109
+ } else {
110
+ router.on(route.method, route.path, fn)
111
+ }
112
+ })
113
+ return Effect.flatMap(
114
+ ServerRequest.ServerRequest,
115
+ (request): App.Default<Exclude<R, Router.RouteContext>, E | Error.RouteNotFound> => {
116
+ const result = router.find(request.method as HTTPMethod, request.url)
117
+ if (result === null) {
118
+ return Effect.fail(Error.RouteNotFound({ request }))
119
+ }
120
+ const handler = (result.handler as any).handler
121
+ if (RouteTypeId in handler) {
122
+ const route = handler as Router.Route<R, E>
123
+ if (route.prefix._tag === "Some") {
124
+ request = sliceRequestUrl(request, route.prefix.value)
125
+ }
126
+ return Effect.mapInputContext(
127
+ route.handler,
128
+ (context) =>
129
+ Context.add(
130
+ Context.add(context, ServerRequest.ServerRequest, request),
131
+ RouteContext,
132
+ new RouteContextImpl(result.params, result.searchParams)
133
+ ) as Context.Context<R>
134
+ )
135
+ }
136
+ return (handler as App.Default<Exclude<R, Router.RouteContext>, E>)
137
+ }
138
+ )
139
+ }
140
+
141
+ function sliceRequestUrl(request: ServerRequest.ServerRequest, prefix: string) {
142
+ const prefexLen = prefix.length
143
+ return request.setUrl(request.url.length <= prefexLen ? "/" : request.url.slice(prefexLen))
144
+ }
145
+
146
+ class RouteImpl<R, E> implements Router.Route<R, E> {
147
+ readonly [RouteTypeId]: Router.RouteTypeId
148
+ constructor(
149
+ readonly method: Method.Method | "*",
150
+ readonly path: string,
151
+ readonly handler: Router.Route.Handler<R, E>,
152
+ readonly prefix = Option.none<string>()
153
+ ) {
154
+ this[RouteTypeId] = RouteTypeId
155
+ }
156
+ }
157
+
158
+ class RouteContextImpl implements Router.RouteContext {
159
+ readonly [RouteContextTypeId]: Router.RouteContextTypeId
160
+ constructor(
161
+ readonly params: Readonly<Record<string, string | undefined>>,
162
+ readonly searchParams: Readonly<Record<string, string>>
163
+ ) {
164
+ this[RouteContextTypeId] = RouteContextTypeId
165
+ }
166
+ }
167
+
168
+ /** @internal */
169
+ export const empty: Router.Router<never, never> = new RouterImpl(Chunk.empty(), Chunk.empty())
170
+
171
+ /** @internal */
172
+ export const fromIterable = <R, E>(
173
+ routes: Iterable<Router.Route<R, E>>
174
+ ): Router.Router<R, E> => new RouterImpl(Chunk.fromIterable(routes), Chunk.empty())
175
+
176
+ /** @internal */
177
+ export const makeRoute = <R, E>(
178
+ method: Method.Method,
179
+ path: string,
180
+ handler: Router.Route.Handler<R, E>,
181
+ prefix: Option.Option<string> = Option.none()
182
+ ): Router.Route<R, E> => new RouteImpl(method, path, handler, prefix)
183
+
184
+ /** @internal */
185
+ export const concat = dual<
186
+ <R1, E1>(that: Router.Router<R1, E1>) => <R, E>(self: Router.Router<R, E>) => Router.Router<R | R1, E | E1>,
187
+ <R, E, R1, E1>(self: Router.Router<R, E>, that: Router.Router<R1, E1>) => Router.Router<R | R1, E | E1>
188
+ >(2, (self, that) => new RouterImpl(Chunk.appendAll(self.routes, that.routes) as any, self.mounts))
189
+
190
+ const removeTrailingSlash = (path: string) => (path.endsWith("/") ? path.slice(0, -1) : path)
191
+
192
+ /** @internal */
193
+ export const prefixAll = dual<
194
+ (prefix: string) => <R, E>(self: Router.Router<R, E>) => Router.Router<R, E>,
195
+ <R, E>(self: Router.Router<R, E>, prefix: string) => Router.Router<R, E>
196
+ >(
197
+ 2,
198
+ (self, prefix) => {
199
+ prefix = removeTrailingSlash(prefix)
200
+ return new RouterImpl(
201
+ Chunk.map(self.routes, (route) =>
202
+ new RouteImpl(
203
+ route.method,
204
+ route.path === "/" ? prefix : prefix + route.path,
205
+ route.handler,
206
+ Option.orElse(
207
+ Option.map(route.prefix, (_) => prefix + _),
208
+ () => Option.some(prefix)
209
+ )
210
+ )),
211
+ Chunk.map(self.mounts, ([path, app]) => [path === "/" ? prefix : prefix + path, app])
212
+ )
213
+ }
214
+ )
215
+
216
+ /** @internal */
217
+ export const mount = dual<
218
+ <R1, E1>(
219
+ path: string,
220
+ that: Router.Router<R1, E1>
221
+ ) => <R, E>(self: Router.Router<R, E>) => Router.Router<R | R1, E | E1>,
222
+ <R, E, R1, E1>(
223
+ self: Router.Router<R, E>,
224
+ path: string,
225
+ that: Router.Router<R1, E1>
226
+ ) => Router.Router<R | R1, E | E1>
227
+ >(
228
+ 3,
229
+ (self, path, that) => concat(self, prefixAll(that, path))
230
+ )
231
+
232
+ /** @internal */
233
+ export const mountApp = dual<
234
+ <R1, E1>(
235
+ path: string,
236
+ that: App.Default<R1, E1>
237
+ ) => <R, E>(self: Router.Router<R, E>) => Router.Router<R | R1, E | E1>,
238
+ <R, E, R1, E1>(
239
+ self: Router.Router<R, E>,
240
+ path: string,
241
+ that: App.Default<R1, E1>
242
+ ) => Router.Router<R | R1, E | E1>
243
+ >(
244
+ 3,
245
+ (self, path, that) => new RouterImpl(self.routes, Chunk.append(self.mounts, [removeTrailingSlash(path), that]) as any)
246
+ )
247
+
248
+ /** @internal */
249
+ export const route = (method: Method.Method | "*"): {
250
+ <R1, E1>(
251
+ path: string,
252
+ handler: Router.Route.Handler<R1, E1>
253
+ ): <R, E>(self: Router.Router<R, E>) => Router.Router<R | Exclude<R1, Router.RouteContext>, E1 | E>
254
+ <R, E, R1, E1>(
255
+ self: Router.Router<R, E>,
256
+ path: string,
257
+ handler: Router.Route.Handler<R1, E1>
258
+ ): Router.Router<R | Exclude<R1, Router.RouteContext>, E | E1>
259
+ } =>
260
+ dual<
261
+ <R1, E1>(
262
+ path: string,
263
+ handler: Router.Route.Handler<R1, E1>
264
+ ) => <R, E>(self: Router.Router<R, E>) => Router.Router<R | Exclude<R1, Router.RouteContext>, E | E1>,
265
+ <R, E, R1, E1>(
266
+ self: Router.Router<R, E>,
267
+ path: string,
268
+ handler: Router.Route.Handler<R1, E1>
269
+ ) => Router.Router<R | Exclude<R1, Router.RouteContext>, E | E1>
270
+ >(3, (self, path, handler) =>
271
+ new RouterImpl(
272
+ Chunk.append(self.routes, new RouteImpl(method, path, handler)) as any,
273
+ self.mounts
274
+ ))
275
+
276
+ /** @internal */
277
+ export const all = route("*")
278
+
279
+ /** @internal */
280
+ export const get = route("GET")
281
+
282
+ /** @internal */
283
+ export const post = route("POST")
284
+
285
+ /** @internal */
286
+ export const put = route("PUT")
287
+
288
+ /** @internal */
289
+ export const patch = route("PATCH")
290
+
291
+ /** @internal */
292
+ export const del = route("DELETE")
293
+
294
+ /** @internal */
295
+ export const head = route("HEAD")
296
+
297
+ /** @internal */
298
+ export const options = route("OPTIONS")
@@ -0,0 +1,80 @@
1
+ import * as Context from "@effect/data/Context"
2
+ import { dual } from "@effect/data/Function"
3
+ import * as Effect from "@effect/io/Effect"
4
+ import type * as Scope from "@effect/io/Scope"
5
+ import type * as App from "@effect/platform/Http/App"
6
+ import type * as Middleware from "@effect/platform/Http/Middleware"
7
+ import type * as Server from "@effect/platform/Http/Server"
8
+ import type * as Error from "@effect/platform/Http/ServerError"
9
+ import type * as ServerRequest from "@effect/platform/Http/ServerRequest"
10
+
11
+ /** @internal */
12
+ export const TypeId: Server.TypeId = Symbol.for("@effect/platform/Http/Server") as Server.TypeId
13
+
14
+ /** @internal */
15
+ export const serverTag = Context.Tag<Server.Server>("@effect/platform/Http/Server")
16
+
17
+ const serverProto = {
18
+ [TypeId]: TypeId
19
+ }
20
+
21
+ /** @internal */
22
+ export const isServer = (u: unknown): u is Server.Server => typeof u === "object" && u !== null && TypeId in u
23
+
24
+ /** @internal */
25
+ export const make = (
26
+ options: {
27
+ readonly serve: (
28
+ httpApp: App.Default<never, unknown>,
29
+ middleware?: Middleware.Middleware
30
+ ) => Effect.Effect<Scope.Scope, Error.ServeError, never>
31
+ readonly address: Server.Address
32
+ }
33
+ ): Server.Server => Object.assign(Object.create(serverProto), options)
34
+
35
+ /** @internal */
36
+ export const serve = dual<
37
+ {
38
+ (): <R, E>(
39
+ httpApp: App.Default<R, E>
40
+ ) => Effect.Effect<
41
+ Server.Server | Scope.Scope | Exclude<R, ServerRequest.ServerRequest>,
42
+ Error.ServeError,
43
+ never
44
+ >
45
+ <R, E, App extends App.Default<any, any>>(middleware: Middleware.Middleware.Applied<R, E, App>): (
46
+ httpApp: App.Default<R, E>
47
+ ) => Effect.Effect<
48
+ Server.Server | Scope.Scope | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest>,
49
+ Error.ServeError,
50
+ never
51
+ >
52
+ },
53
+ {
54
+ <R, E>(
55
+ httpApp: App.Default<R, E>
56
+ ): Effect.Effect<Server.Server | Scope.Scope | Exclude<R, ServerRequest.ServerRequest>, Error.ServeError, never>
57
+ <R, E, App extends App.Default<any, any>>(
58
+ httpApp: App.Default<R, E>,
59
+ middleware: Middleware.Middleware.Applied<R, E, App>
60
+ ): Effect.Effect<
61
+ Server.Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest> | Scope.Scope,
62
+ Error.ServeError,
63
+ never
64
+ >
65
+ }
66
+ >(
67
+ (args) => Effect.isEffect(args[0]),
68
+ (<R, E, App extends App.Default<any, any>>(
69
+ httpApp: App.Default<R, E>,
70
+ middleware: Middleware.Middleware.Applied<R, E, App>
71
+ ): Effect.Effect<
72
+ Server.Server | Exclude<Effect.Effect.Context<App>, ServerRequest.ServerRequest> | Scope.Scope,
73
+ Error.ServeError,
74
+ never
75
+ > =>
76
+ Effect.flatMap(
77
+ serverTag,
78
+ (server) => server.serve(httpApp, middleware)
79
+ )) as any
80
+ )
@@ -0,0 +1,26 @@
1
+ import * as Data from "@effect/data/Data"
2
+ import type * as Error from "@effect/platform/Http/ServerError"
3
+
4
+ /** @internal */
5
+ export const TypeId: Error.TypeId = Symbol.for(
6
+ "@effect/platform/Http/Error"
7
+ ) as Error.TypeId
8
+
9
+ const make = <A extends Error.HttpServerError>(tag: A["_tag"]) => (props: Omit<A, Error.HttpError.ProvidedFields>): A =>
10
+ Data.struct({
11
+ [TypeId]: TypeId,
12
+ _tag: tag,
13
+ ...props
14
+ } as A)
15
+
16
+ /** @internal */
17
+ export const requestError = make<Error.RequestError>("RequestError")
18
+
19
+ /** @internal */
20
+ export const responseError = make<Error.ResponseError>("ResponseError")
21
+
22
+ /** @internal */
23
+ export const routeNotFound = make<Error.RouteNotFound>("RouteNotFound")
24
+
25
+ /** @internal */
26
+ export const serveError = make<Error.ServeError>("ServeError")
@@ -0,0 +1,71 @@
1
+ import * as Context from "@effect/data/Context"
2
+ import * as Effect from "@effect/io/Effect"
3
+ import * as FormData from "@effect/platform/Http/FormData"
4
+ import * as IncomingMessage from "@effect/platform/Http/IncomingMessage"
5
+ import * as Error from "@effect/platform/Http/ServerError"
6
+ import type * as ServerRequest from "@effect/platform/Http/ServerRequest"
7
+ import type * as Schema from "@effect/schema/Schema"
8
+
9
+ /** @internal */
10
+ export const TypeId: ServerRequest.TypeId = Symbol.for("@effect/platform/Http/ServerRequest") as ServerRequest.TypeId
11
+
12
+ /** @internal */
13
+ export const serverRequestTag = Context.Tag<ServerRequest.ServerRequest>(TypeId)
14
+
15
+ /** @internal */
16
+ export const formDataRecord = Effect.map(
17
+ Effect.flatMap(serverRequestTag, (request) => request.formData),
18
+ FormData.toRecord
19
+ )
20
+
21
+ /** @internal */
22
+ export const schemaHeaders = <I extends Readonly<Record<string, string>>, A>(schema: Schema.Schema<I, A>) => {
23
+ const parse = IncomingMessage.schemaHeaders(schema)
24
+ return Effect.flatMap(serverRequestTag, parse)
25
+ }
26
+
27
+ /** @internal */
28
+ export const schemaBodyJson = <I, A>(schema: Schema.Schema<I, A>) => {
29
+ const parse = IncomingMessage.schemaBodyJson(schema)
30
+ return Effect.flatMap(serverRequestTag, parse)
31
+ }
32
+
33
+ /** @internal */
34
+ export const schemaBodyUrlParams = <I extends Readonly<Record<string, string>>, A>(schema: Schema.Schema<I, A>) => {
35
+ const parse = IncomingMessage.schemaBodyUrlParams(schema)
36
+ return Effect.flatMap(serverRequestTag, parse)
37
+ }
38
+
39
+ /** @internal */
40
+ export const schemaFormData = <I extends Readonly<Record<string, string | ReadonlyArray<globalThis.File>>>, A>(
41
+ schema: Schema.Schema<I, A>
42
+ ) => {
43
+ const parse = FormData.schemaRecord(schema)
44
+ return Effect.flatMap(
45
+ Effect.flatMap(serverRequestTag, (request) => request.formData),
46
+ parse
47
+ )
48
+ }
49
+
50
+ /** @internal */
51
+ export const schemaFormDataJson = <I, A>(schema: Schema.Schema<I, A>) => {
52
+ const parse = FormData.schemaJson(schema)
53
+ return (field: string) =>
54
+ Effect.flatMap(serverRequestTag, (request) =>
55
+ Effect.flatMap(
56
+ request.formData,
57
+ (formData) =>
58
+ Effect.catchTag(
59
+ parse(formData, field),
60
+ "FormDataError",
61
+ (error) =>
62
+ Effect.fail(
63
+ Error.RequestError({
64
+ reason: "Decode",
65
+ request,
66
+ error: error.error
67
+ })
68
+ )
69
+ )
70
+ ))
71
+ }