@effect/platform 0.40.2 → 0.40.3

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 (33) hide show
  1. package/Http/Multiplex/package.json +6 -0
  2. package/dist/cjs/Http/IncomingMessage.js +3 -3
  3. package/dist/cjs/Http/IncomingMessage.js.map +1 -1
  4. package/dist/cjs/Http/Multiplex.js +93 -0
  5. package/dist/cjs/Http/Multiplex.js.map +1 -0
  6. package/dist/cjs/HttpServer.js +3 -1
  7. package/dist/cjs/HttpServer.js.map +1 -1
  8. package/dist/cjs/internal/http/multiplex.js +85 -0
  9. package/dist/cjs/internal/http/multiplex.js.map +1 -0
  10. package/dist/cjs/internal/http/router.js +1 -3
  11. package/dist/cjs/internal/http/router.js.map +1 -1
  12. package/dist/dts/Http/Multiplex.d.ts +111 -0
  13. package/dist/dts/Http/Multiplex.d.ts.map +1 -0
  14. package/dist/dts/HttpServer.d.ts +18 -10
  15. package/dist/dts/HttpServer.d.ts.map +1 -1
  16. package/dist/dts/internal/http/multiplex.d.ts +2 -0
  17. package/dist/dts/internal/http/multiplex.d.ts.map +1 -0
  18. package/dist/esm/Http/IncomingMessage.js +3 -3
  19. package/dist/esm/Http/IncomingMessage.js.map +1 -1
  20. package/dist/esm/Http/Multiplex.js +62 -0
  21. package/dist/esm/Http/Multiplex.js.map +1 -0
  22. package/dist/esm/HttpServer.js +18 -10
  23. package/dist/esm/HttpServer.js.map +1 -1
  24. package/dist/esm/internal/http/multiplex.js +53 -0
  25. package/dist/esm/internal/http/multiplex.js.map +1 -0
  26. package/dist/esm/internal/http/router.js +1 -3
  27. package/dist/esm/internal/http/router.js.map +1 -1
  28. package/package.json +10 -2
  29. package/src/Http/IncomingMessage.ts +3 -3
  30. package/src/Http/Multiplex.ts +174 -0
  31. package/src/HttpServer.ts +18 -10
  32. package/src/internal/http/multiplex.ts +222 -0
  33. package/src/internal/http/router.ts +7 -7
package/src/HttpServer.ts CHANGED
@@ -6,6 +6,7 @@ import * as body from "./Http/Body.js"
6
6
  import * as headers from "./Http/Headers.js"
7
7
  import * as middleware from "./Http/Middleware.js"
8
8
  import * as multipart from "./Http/Multipart.js"
9
+ import * as multiplex from "./Http/Multiplex.js"
9
10
  import * as router from "./Http/Router.js"
10
11
  import * as error from "./Http/ServerError.js"
11
12
  import * as request from "./Http/ServerRequest.js"
@@ -16,70 +17,77 @@ export {
16
17
  /**
17
18
  * @since 1.0.0
18
19
  *
19
- * - Docs: [Http/App](https://effect-ts.github.io/effect/platform/Http/App.html)
20
+ * - Docs: [Http/App](https://effect-ts.github.io/effect/platform/Http/App.ts.html)
20
21
  * - Module: `@effect/platform/Http/App`
21
22
  */
22
23
  app,
23
24
  /**
24
25
  * @since 1.0.0
25
26
  *
26
- * - Docs: [Http/Body](https://effect-ts.github.io/effect/platform/Http/Body.html)
27
+ * - Docs: [Http/Body](https://effect-ts.github.io/effect/platform/Http/Body.ts.html)
27
28
  * - Module: `@effect/platform/Http/Body`
28
29
  */
29
30
  body,
30
31
  /**
31
32
  * @since 1.0.0
32
33
  *
33
- * - Docs: [Http/ServerError](https://effect-ts.github.io/effect/platform/Http/ServerError.html)
34
+ * - Docs: [Http/ServerError](https://effect-ts.github.io/effect/platform/Http/ServerError.ts.html)
34
35
  * - Module: `@effect/platform/Http/ServerError`
35
36
  */
36
37
  error,
37
38
  /**
38
39
  * @since 1.0.0
39
40
  *
40
- * - Docs: [Http/Headers](https://effect-ts.github.io/effect/platform/Http/Headers.html)
41
+ * - Docs: [Http/Headers](https://effect-ts.github.io/effect/platform/Http/Headers.ts.html)
41
42
  * - Module: `@effect/platform/Http/Headers`
42
43
  */
43
44
  headers,
44
45
  /**
45
46
  * @since 1.0.0
46
47
  *
47
- * - Docs: [Http/Middleware](https://effect-ts.github.io/effect/platform/Http/Middleware.html)
48
+ * - Docs: [Http/Middleware](https://effect-ts.github.io/effect/platform/Http/Middleware.ts.html)
48
49
  * - Module: `@effect/platform/Http/Middleware`
49
50
  */
50
51
  middleware,
51
52
  /**
52
53
  * @since 1.0.0
53
54
  *
54
- * - Docs: [Http/Multipart](https://effect-ts.github.io/effect/platform/Http/Multipart.html)
55
+ * - Docs: [Http/Multipart](https://effect-ts.github.io/effect/platform/Http/Multipart.ts.html)
55
56
  * - Module: `@effect/platform/Http/Multipart`
56
57
  */
57
58
  multipart,
58
59
  /**
59
60
  * @since 1.0.0
60
61
  *
61
- * - Docs: [Http/ServerRequest](https://effect-ts.github.io/effect/platform/Http/ServerRequest.html)
62
+ * - Docs: [Http/Multiplex](https://effect-ts.github.io/effect/platform/Http/Multiplex.ts.html)
63
+ * - Module: `@effect/platform/Http/Multiplex`
64
+ */
65
+ multiplex,
66
+ /**
67
+ * @since 1.0.0
68
+ *
69
+ * - Docs: [Http/ServerRequest](https://effect-ts.github.io/effect/platform/Http/ServerRequest.ts.html)
62
70
  * - Module: `@effect/platform/Http/ServerRequest`
63
71
  */
64
72
  request,
65
73
  /**
66
74
  * @since 1.0.0
67
75
  *
68
- * - Docs: [Http/ServerResponse](https://effect-ts.github.io/effect/platform/Http/ServerResponse.html)
76
+ * - Docs: [Http/ServerResponse](https://effect-ts.github.io/effect/platform/Http/ServerResponse.ts.html)
69
77
  * - Module: `@effect/platform/Http/ServerResponse`
70
78
  */
71
79
  response,
72
80
  /**
73
81
  * @since 1.0.0
74
82
  *
75
- * - Docs: [Http/Router](https://effect-ts.github.io/effect/platform/Http/Router.html)
83
+ * - Docs: [Http/Router](https://effect-ts.github.io/effect/platform/Http/Router.ts.html)
76
84
  * - Module: `@effect/platform/Http/Router`
77
85
  */
78
86
  router,
79
87
  /**
80
88
  * @since 1.0.0
81
89
  *
82
- * - Docs: [Http/UrlParams](https://effect-ts.github.io/effect/platform/Http/UrlParams.html)
90
+ * - Docs: [Http/UrlParams](https://effect-ts.github.io/effect/platform/Http/UrlParams.ts.html)
83
91
  * - Module: `@effect/platform/Http/UrlParams`
84
92
  */
85
93
  urlParams
@@ -0,0 +1,222 @@
1
+ import * as Effect from "effect/Effect"
2
+ import * as Effectable from "effect/Effectable"
3
+ import { dual } from "effect/Function"
4
+ import * as ReadonlyArray from "effect/ReadonlyArray"
5
+ import type * as App from "../../Http/App.js"
6
+ import type * as Multiplex from "../../Http/Multiplex.js"
7
+ import * as Error from "../../Http/ServerError.js"
8
+ import * as ServerRequest from "../../Http/ServerRequest.js"
9
+ import type * as ServerResponse from "../../Http/ServerResponse.js"
10
+
11
+ /** @internal */
12
+ export const TypeId: Multiplex.TypeId = Symbol.for("@effect/platform/Http/Multiplex") as Multiplex.TypeId
13
+
14
+ class MultiplexImpl<R, E>
15
+ extends Effectable.Class<R | ServerRequest.ServerRequest, E | Error.RouteNotFound, ServerResponse.ServerResponse>
16
+ implements Multiplex.Multiplex<R, E>
17
+ {
18
+ readonly [TypeId]: Multiplex.TypeId
19
+
20
+ constructor(
21
+ readonly apps: ReadonlyArray<
22
+ readonly [
23
+ predicate: (request: ServerRequest.ServerRequest) => Effect.Effect<R, E, boolean>,
24
+ app: App.Default<R, E>
25
+ ]
26
+ >
27
+ ) {
28
+ super()
29
+ this[TypeId] = TypeId
30
+
31
+ let execute: (request: ServerRequest.ServerRequest) => App.Default<R, E | Error.RouteNotFound> = (request) =>
32
+ Effect.fail(Error.RouteNotFound({ request }))
33
+
34
+ for (let i = apps.length - 1; i >= 0; i--) {
35
+ const [predicate, app] = apps[i]
36
+ const previous = execute
37
+ execute = (request) =>
38
+ Effect.flatMap(
39
+ predicate(request),
40
+ (match) => match ? app : previous(request)
41
+ )
42
+ }
43
+
44
+ this.execute = Effect.flatMap(ServerRequest.ServerRequest, execute)
45
+ }
46
+
47
+ execute: App.Default<R, E | Error.RouteNotFound>
48
+
49
+ commit() {
50
+ return this.execute
51
+ }
52
+ }
53
+
54
+ /** @internal */
55
+ export const empty: Multiplex.Multiplex<never, never> = new MultiplexImpl([])
56
+
57
+ /** @internal */
58
+ export const make = <R, E>(
59
+ apps: Iterable<
60
+ readonly [predicate: (request: ServerRequest.ServerRequest) => Effect.Effect<R, E, boolean>, app: App.Default<R, E>]
61
+ >
62
+ ): Multiplex.Multiplex<R, E> => new MultiplexImpl(ReadonlyArray.fromIterable(apps))
63
+
64
+ /** @internal */
65
+ export const add = dual<
66
+ <R2, E2, R3, E3>(
67
+ predicate: (request: ServerRequest.ServerRequest) => Effect.Effect<R2, E2, boolean>,
68
+ app: App.Default<R3, E3>
69
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2 | R3, E | E2 | E3>,
70
+ <R, E, R2, E2, R3, E3>(
71
+ self: Multiplex.Multiplex<R, E>,
72
+ predicate: (request: ServerRequest.ServerRequest) => Effect.Effect<R2, E2, boolean>,
73
+ app: App.Default<R3, E3>
74
+ ) => Multiplex.Multiplex<R | R2 | R3, E | E2 | E3>
75
+ >(
76
+ 3,
77
+ (self, predicate, app) =>
78
+ make([
79
+ ...self.apps,
80
+ [predicate, app]
81
+ ] as any)
82
+ )
83
+
84
+ /** @internal */
85
+ export const headerExact = dual<
86
+ <R2, E2>(
87
+ header: string,
88
+ value: string,
89
+ app: App.Default<R2, E2>
90
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2, E | E2>,
91
+ <R, E, R2, E2>(
92
+ self: Multiplex.Multiplex<R, E>,
93
+ header: string,
94
+ value: string,
95
+ app: App.Default<R2, E2>
96
+ ) => Multiplex.Multiplex<R | R2, E | E2>
97
+ >(
98
+ 4,
99
+ (self, header, value, app) =>
100
+ add(self, (req) =>
101
+ req.headers[header] !== undefined
102
+ ? Effect.succeed(req.headers[header] === value)
103
+ : Effect.succeed(false), app)
104
+ )
105
+
106
+ /** @internal */
107
+ export const headerRegex = dual<
108
+ <R2, E2>(
109
+ header: string,
110
+ regex: RegExp,
111
+ app: App.Default<R2, E2>
112
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2, E | E2>,
113
+ <R, E, R2, E2>(
114
+ self: Multiplex.Multiplex<R, E>,
115
+ header: string,
116
+ regex: RegExp,
117
+ app: App.Default<R2, E2>
118
+ ) => Multiplex.Multiplex<R | R2, E | E2>
119
+ >(
120
+ 4,
121
+ (self, header, regex, app) =>
122
+ add(self, (req) =>
123
+ req.headers[header] !== undefined
124
+ ? Effect.succeed(regex.test(req.headers[header]))
125
+ : Effect.succeed(false), app)
126
+ )
127
+
128
+ /** @internal */
129
+ export const headerStartsWith = dual<
130
+ <R2, E2>(
131
+ header: string,
132
+ prefix: string,
133
+ app: App.Default<R2, E2>
134
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2, E | E2>,
135
+ <R, E, R2, E2>(
136
+ self: Multiplex.Multiplex<R, E>,
137
+ header: string,
138
+ prefix: string,
139
+ app: App.Default<R2, E2>
140
+ ) => Multiplex.Multiplex<R | R2, E | E2>
141
+ >(
142
+ 4,
143
+ (self, header, prefix, app) =>
144
+ add(self, (req) =>
145
+ req.headers[header] !== undefined
146
+ ? Effect.succeed(req.headers[header].startsWith(prefix))
147
+ : Effect.succeed(false), app)
148
+ )
149
+
150
+ /** @internal */
151
+ export const headerEndsWith = dual<
152
+ <R2, E2>(
153
+ header: string,
154
+ suffix: string,
155
+ app: App.Default<R2, E2>
156
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2, E | E2>,
157
+ <R, E, R2, E2>(
158
+ self: Multiplex.Multiplex<R, E>,
159
+ header: string,
160
+ suffix: string,
161
+ app: App.Default<R2, E2>
162
+ ) => Multiplex.Multiplex<R | R2, E | E2>
163
+ >(
164
+ 4,
165
+ (self, header, suffix, app) =>
166
+ add(self, (req) =>
167
+ req.headers[header] !== undefined
168
+ ? Effect.succeed(req.headers[header].endsWith(suffix))
169
+ : Effect.succeed(false), app)
170
+ )
171
+
172
+ /** @internal */
173
+ export const hostRegex = dual<
174
+ <R2, E2>(
175
+ regex: RegExp,
176
+ app: App.Default<R2, E2>
177
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2, E | E2>,
178
+ <R, E, R2, E2>(
179
+ self: Multiplex.Multiplex<R, E>,
180
+ regex: RegExp,
181
+ app: App.Default<R2, E2>
182
+ ) => Multiplex.Multiplex<R | R2, E | E2>
183
+ >(3, (self, regex, app) => headerRegex(self, "host", regex, app))
184
+
185
+ /** @internal */
186
+ export const hostStartsWith = dual<
187
+ <R2, E2>(
188
+ prefix: string,
189
+ app: App.Default<R2, E2>
190
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2, E | E2>,
191
+ <R, E, R2, E2>(
192
+ self: Multiplex.Multiplex<R, E>,
193
+ prefix: string,
194
+ app: App.Default<R2, E2>
195
+ ) => Multiplex.Multiplex<R | R2, E | E2>
196
+ >(3, (self, prefix, app) => headerStartsWith(self, "host", prefix, app))
197
+
198
+ /** @internal */
199
+ export const hostEndsWith = dual<
200
+ <R2, E2>(
201
+ suffix: string,
202
+ app: App.Default<R2, E2>
203
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2, E | E2>,
204
+ <R, E, R2, E2>(
205
+ self: Multiplex.Multiplex<R, E>,
206
+ suffix: string,
207
+ app: App.Default<R2, E2>
208
+ ) => Multiplex.Multiplex<R | R2, E | E2>
209
+ >(3, (self, suffix, app) => headerEndsWith(self, "host", suffix, app))
210
+
211
+ /** @internal */
212
+ export const hostExact = dual<
213
+ <R2, E2>(
214
+ host: string,
215
+ app: App.Default<R2, E2>
216
+ ) => <R, E>(self: Multiplex.Multiplex<R, E>) => Multiplex.Multiplex<R | R2, E | E2>,
217
+ <R, E, R2, E2>(
218
+ self: Multiplex.Multiplex<R, E>,
219
+ host: string,
220
+ app: App.Default<R2, E2>
221
+ ) => Multiplex.Multiplex<R | R2, E | E2>
222
+ >(3, (self, host, app) => headerExact(self, "host", host, app))
@@ -65,15 +65,15 @@ class RouterImpl<R, E> extends Effectable.StructuralClass<
65
65
  ) {
66
66
  super()
67
67
  this[TypeId] = TypeId
68
+ this.httpApp = toHttpApp(this) as any
68
69
  }
69
- private httpApp:
70
- | Effect.Effect<Exclude<R, Router.RouteContext>, E | Error.RouteNotFound, ServerResponse.ServerResponse>
71
- | undefined
70
+ private httpApp: Effect.Effect<
71
+ Exclude<R, Router.RouteContext>,
72
+ E | Error.RouteNotFound,
73
+ ServerResponse.ServerResponse
74
+ >
72
75
  commit() {
73
- if (this.httpApp === undefined) {
74
- this.httpApp = toHttpApp(this) as any
75
- }
76
- return this.httpApp!
76
+ return this.httpApp
77
77
  }
78
78
  toJSON() {
79
79
  return {