@effect/platform 0.48.15 → 0.48.17

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 (134) hide show
  1. package/Http/Cookies/package.json +6 -0
  2. package/README.md +235 -46
  3. package/dist/cjs/Http/Client.js +6 -1
  4. package/dist/cjs/Http/Client.js.map +1 -1
  5. package/dist/cjs/Http/ClientRequest.js.map +1 -1
  6. package/dist/cjs/Http/ClientResponse.js.map +1 -1
  7. package/dist/cjs/Http/Cookies.js +566 -0
  8. package/dist/cjs/Http/Cookies.js.map +1 -0
  9. package/dist/cjs/Http/Headers.js +2 -2
  10. package/dist/cjs/Http/Headers.js.map +1 -1
  11. package/dist/cjs/Http/IncomingMessage.js +12 -16
  12. package/dist/cjs/Http/IncomingMessage.js.map +1 -1
  13. package/dist/cjs/Http/Multipart.js.map +1 -1
  14. package/dist/cjs/Http/Router.js +11 -1
  15. package/dist/cjs/Http/Router.js.map +1 -1
  16. package/dist/cjs/Http/ServerRequest.js +6 -1
  17. package/dist/cjs/Http/ServerRequest.js.map +1 -1
  18. package/dist/cjs/Http/ServerResponse.js +36 -1
  19. package/dist/cjs/Http/ServerResponse.js.map +1 -1
  20. package/dist/cjs/Http/UrlParams.js +2 -2
  21. package/dist/cjs/Http/UrlParams.js.map +1 -1
  22. package/dist/cjs/HttpClient.js +3 -1
  23. package/dist/cjs/HttpClient.js.map +1 -1
  24. package/dist/cjs/HttpServer.js +3 -1
  25. package/dist/cjs/HttpServer.js.map +1 -1
  26. package/dist/cjs/internal/http/body.js +2 -2
  27. package/dist/cjs/internal/http/body.js.map +1 -1
  28. package/dist/cjs/internal/http/client.js +9 -3
  29. package/dist/cjs/internal/http/client.js.map +1 -1
  30. package/dist/cjs/internal/http/clientRequest.js +2 -2
  31. package/dist/cjs/internal/http/clientRequest.js.map +1 -1
  32. package/dist/cjs/internal/http/clientResponse.js +16 -8
  33. package/dist/cjs/internal/http/clientResponse.js.map +1 -1
  34. package/dist/cjs/internal/http/multipart.js +4 -4
  35. package/dist/cjs/internal/http/multipart.js.map +1 -1
  36. package/dist/cjs/internal/http/router.js +34 -7
  37. package/dist/cjs/internal/http/router.js.map +1 -1
  38. package/dist/cjs/internal/http/serverRequest.js +30 -15
  39. package/dist/cjs/internal/http/serverRequest.js.map +1 -1
  40. package/dist/cjs/internal/http/serverResponse.js +48 -23
  41. package/dist/cjs/internal/http/serverResponse.js.map +1 -1
  42. package/dist/dts/Error.d.ts.map +1 -1
  43. package/dist/dts/Http/App.d.ts +1 -1
  44. package/dist/dts/Http/App.d.ts.map +1 -1
  45. package/dist/dts/Http/Client.d.ts +13 -2
  46. package/dist/dts/Http/Client.d.ts.map +1 -1
  47. package/dist/dts/Http/ClientRequest.d.ts +2 -1
  48. package/dist/dts/Http/ClientRequest.d.ts.map +1 -1
  49. package/dist/dts/Http/ClientResponse.d.ts +7 -4
  50. package/dist/dts/Http/ClientResponse.d.ts.map +1 -1
  51. package/dist/dts/Http/Cookies.d.ts +253 -0
  52. package/dist/dts/Http/Cookies.d.ts.map +1 -0
  53. package/dist/dts/Http/Headers.d.ts +2 -2
  54. package/dist/dts/Http/Headers.d.ts.map +1 -1
  55. package/dist/dts/Http/IncomingMessage.d.ts +7 -6
  56. package/dist/dts/Http/IncomingMessage.d.ts.map +1 -1
  57. package/dist/dts/Http/Multipart.d.ts +3 -2
  58. package/dist/dts/Http/Multipart.d.ts.map +1 -1
  59. package/dist/dts/Http/Router.d.ts +29 -3
  60. package/dist/dts/Http/Router.d.ts.map +1 -1
  61. package/dist/dts/Http/ServerRequest.d.ts +14 -6
  62. package/dist/dts/Http/ServerRequest.d.ts.map +1 -1
  63. package/dist/dts/Http/ServerResponse.d.ts +89 -13
  64. package/dist/dts/Http/ServerResponse.d.ts.map +1 -1
  65. package/dist/dts/Http/UrlParams.d.ts +3 -2
  66. package/dist/dts/Http/UrlParams.d.ts.map +1 -1
  67. package/dist/dts/HttpClient.d.ts +8 -0
  68. package/dist/dts/HttpClient.d.ts.map +1 -1
  69. package/dist/dts/HttpServer.d.ts +8 -0
  70. package/dist/dts/HttpServer.d.ts.map +1 -1
  71. package/dist/dts/Socket.d.ts +3 -3
  72. package/dist/dts/Socket.d.ts.map +1 -1
  73. package/dist/dts/internal/http/router.d.ts.map +1 -1
  74. package/dist/esm/Http/Client.js +5 -0
  75. package/dist/esm/Http/Client.js.map +1 -1
  76. package/dist/esm/Http/ClientRequest.js.map +1 -1
  77. package/dist/esm/Http/ClientResponse.js.map +1 -1
  78. package/dist/esm/Http/Cookies.js +518 -0
  79. package/dist/esm/Http/Cookies.js.map +1 -0
  80. package/dist/esm/Http/Headers.js +2 -2
  81. package/dist/esm/Http/Headers.js.map +1 -1
  82. package/dist/esm/Http/IncomingMessage.js +12 -15
  83. package/dist/esm/Http/IncomingMessage.js.map +1 -1
  84. package/dist/esm/Http/Multipart.js.map +1 -1
  85. package/dist/esm/Http/Router.js +10 -0
  86. package/dist/esm/Http/Router.js.map +1 -1
  87. package/dist/esm/Http/ServerRequest.js +5 -0
  88. package/dist/esm/Http/ServerRequest.js.map +1 -1
  89. package/dist/esm/Http/ServerResponse.js +35 -0
  90. package/dist/esm/Http/ServerResponse.js.map +1 -1
  91. package/dist/esm/Http/UrlParams.js +2 -2
  92. package/dist/esm/Http/UrlParams.js.map +1 -1
  93. package/dist/esm/HttpClient.js +8 -0
  94. package/dist/esm/HttpClient.js.map +1 -1
  95. package/dist/esm/HttpServer.js +8 -0
  96. package/dist/esm/HttpServer.js.map +1 -1
  97. package/dist/esm/internal/http/body.js +2 -2
  98. package/dist/esm/internal/http/body.js.map +1 -1
  99. package/dist/esm/internal/http/client.js +8 -2
  100. package/dist/esm/internal/http/client.js.map +1 -1
  101. package/dist/esm/internal/http/clientRequest.js +2 -2
  102. package/dist/esm/internal/http/clientRequest.js.map +1 -1
  103. package/dist/esm/internal/http/clientResponse.js +16 -8
  104. package/dist/esm/internal/http/clientResponse.js.map +1 -1
  105. package/dist/esm/internal/http/multipart.js +4 -4
  106. package/dist/esm/internal/http/multipart.js.map +1 -1
  107. package/dist/esm/internal/http/router.js +31 -6
  108. package/dist/esm/internal/http/router.js.map +1 -1
  109. package/dist/esm/internal/http/serverRequest.js +28 -14
  110. package/dist/esm/internal/http/serverRequest.js.map +1 -1
  111. package/dist/esm/internal/http/serverResponse.js +47 -22
  112. package/dist/esm/internal/http/serverResponse.js.map +1 -1
  113. package/package.json +12 -4
  114. package/src/Http/Client.ts +16 -2
  115. package/src/Http/ClientRequest.ts +3 -1
  116. package/src/Http/ClientResponse.ts +18 -7
  117. package/src/Http/Cookies.ts +718 -0
  118. package/src/Http/Headers.ts +16 -8
  119. package/src/Http/IncomingMessage.ts +17 -12
  120. package/src/Http/Multipart.ts +5 -2
  121. package/src/Http/Router.ts +50 -3
  122. package/src/Http/ServerRequest.ts +25 -7
  123. package/src/Http/ServerResponse.ts +145 -13
  124. package/src/Http/UrlParams.ts +3 -2
  125. package/src/HttpClient.ts +8 -0
  126. package/src/HttpServer.ts +8 -0
  127. package/src/internal/http/body.ts +3 -2
  128. package/src/internal/http/client.ts +45 -5
  129. package/src/internal/http/clientRequest.ts +3 -2
  130. package/src/internal/http/clientResponse.ts +18 -8
  131. package/src/internal/http/multipart.ts +7 -4
  132. package/src/internal/http/router.ts +80 -6
  133. package/src/internal/http/serverRequest.ts +41 -15
  134. package/src/internal/http/serverResponse.ts +190 -18
@@ -50,18 +50,21 @@ export const schemaFromSelf: Schema.Schema<Headers> = Schema.declare(isHeaders,
50
50
  * @since 1.0.0
51
51
  * @category schemas
52
52
  */
53
- export const schema: Schema.Schema<Headers, ReadonlyRecord.ReadonlyRecord<string, string>> = Schema.transform(
54
- Schema.record(Schema.string, Schema.string),
55
- schemaFromSelf,
56
- (record) => fromInput(record),
57
- identity
58
- )
53
+ export const schema: Schema.Schema<Headers, ReadonlyRecord.ReadonlyRecord<string, string | ReadonlyArray<string>>> =
54
+ Schema.transform(
55
+ Schema.record(Schema.string, Schema.union(Schema.string, Schema.array(Schema.string))),
56
+ schemaFromSelf,
57
+ (record) => fromInput(record),
58
+ identity
59
+ )
59
60
 
60
61
  /**
61
62
  * @since 1.0.0
62
63
  * @category models
63
64
  */
64
- export type Input = ReadonlyRecord.ReadonlyRecord<string, string> | Iterable<readonly [string, string]>
65
+ export type Input =
66
+ | ReadonlyRecord.ReadonlyRecord<string, string | ReadonlyArray<string>>
67
+ | Iterable<readonly [string, string]>
65
68
 
66
69
  /**
67
70
  * @since 1.0.0
@@ -83,7 +86,12 @@ export const fromInput: (input?: Input) => Headers = (input) => {
83
86
  )) as Headers
84
87
  }
85
88
  return ReadonlyRecord.fromEntries(
86
- Object.entries(input).map(([k, v]) => [k.toLowerCase(), v])
89
+ Object.entries(input).map(([k, v]) =>
90
+ [
91
+ k.toLowerCase(),
92
+ Array.isArray(v) ? v.join(", ") : v
93
+ ] as const
94
+ )
87
95
  ) as Headers
88
96
  }
89
97
 
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type { ParseOptions } from "@effect/schema/AST"
4
5
  import * as ParseResult from "@effect/schema/ParseResult"
5
6
  import * as Schema from "@effect/schema/Schema"
6
7
  import * as Effect from "effect/Effect"
@@ -47,8 +48,8 @@ export interface IncomingMessage<E> extends Inspectable {
47
48
  * @since 1.0.0
48
49
  * @category schema
49
50
  */
50
- export const schemaBodyJson = <A, I, R>(schema: Schema.Schema<A, I, R>) => {
51
- const parse = Schema.decodeUnknown(schema)
51
+ export const schemaBodyJson = <A, I, R>(schema: Schema.Schema<A, I, R>, options?: ParseOptions | undefined) => {
52
+ const parse = Schema.decodeUnknown(schema, options)
52
53
  return <E>(self: IncomingMessage<E>): Effect.Effect<A, E | ParseResult.ParseError, R> =>
53
54
  Effect.flatMap(self.json, parse)
54
55
  }
@@ -57,8 +58,8 @@ export const schemaBodyJson = <A, I, R>(schema: Schema.Schema<A, I, R>) => {
57
58
  * @since 1.0.0
58
59
  * @category schema
59
60
  */
60
- export const schemaBodyJsonEffect = <A, I, R>(schema: Schema.Schema<A, I, R>) => {
61
- const decode = schemaBodyJson(schema)
61
+ export const schemaBodyJsonEffect = <A, I, R>(schema: Schema.Schema<A, I, R>, options?: ParseOptions | undefined) => {
62
+ const decode = schemaBodyJson(schema, options)
62
63
  return <E, E2, R2>(effect: Effect.Effect<IncomingMessage<E>, E2, R2>) => Effect.scoped(Effect.flatMap(effect, decode))
63
64
  }
64
65
 
@@ -67,9 +68,10 @@ export const schemaBodyJsonEffect = <A, I, R>(schema: Schema.Schema<A, I, R>) =>
67
68
  * @category schema
68
69
  */
69
70
  export const schemaBodyUrlParams = <R, I extends Readonly<Record<string, string>>, A>(
70
- schema: Schema.Schema<A, I, R>
71
+ schema: Schema.Schema<A, I, R>,
72
+ options?: ParseOptions | undefined
71
73
  ) => {
72
- const parse = Schema.decodeUnknown(schema)
74
+ const parse = Schema.decodeUnknown(schema, options)
73
75
  return <E>(self: IncomingMessage<E>): Effect.Effect<A, E | ParseResult.ParseError, R> =>
74
76
  Effect.flatMap(self.urlParamsBody, (_) => parse(Object.fromEntries(_)))
75
77
  }
@@ -79,9 +81,10 @@ export const schemaBodyUrlParams = <R, I extends Readonly<Record<string, string>
79
81
  * @category schema
80
82
  */
81
83
  export const schemaBodyUrlParamsEffect = <R, I extends Readonly<Record<string, string>>, A>(
82
- schema: Schema.Schema<A, I, R>
84
+ schema: Schema.Schema<A, I, R>,
85
+ options?: ParseOptions | undefined
83
86
  ) => {
84
- const decode = schemaBodyUrlParams(schema)
87
+ const decode = schemaBodyUrlParams(schema, options)
85
88
  return <E, E2, R2>(effect: Effect.Effect<IncomingMessage<E>, E2, R2>) => Effect.scoped(Effect.flatMap(effect, decode))
86
89
  }
87
90
 
@@ -90,9 +93,10 @@ export const schemaBodyUrlParamsEffect = <R, I extends Readonly<Record<string, s
90
93
  * @category schema
91
94
  */
92
95
  export const schemaHeaders = <R, I extends Readonly<Record<string, string | undefined>>, A>(
93
- schema: Schema.Schema<A, I, R>
96
+ schema: Schema.Schema<A, I, R>,
97
+ options?: ParseOptions | undefined
94
98
  ) => {
95
- const parse = Schema.decodeUnknown(schema)
99
+ const parse = Schema.decodeUnknown(schema, options)
96
100
  return <E>(self: IncomingMessage<E>): Effect.Effect<A, ParseResult.ParseError, R> => parse(self.headers)
97
101
  }
98
102
 
@@ -101,9 +105,10 @@ export const schemaHeaders = <R, I extends Readonly<Record<string, string | unde
101
105
  * @category schema
102
106
  */
103
107
  export const schemaHeadersEffect = <R, I extends Readonly<Record<string, string>>, A>(
104
- schema: Schema.Schema<A, I, R>
108
+ schema: Schema.Schema<A, I, R>,
109
+ options?: ParseOptions | undefined
105
110
  ) => {
106
- const decode = schemaHeaders(schema)
111
+ const decode = schemaHeaders(schema, options)
107
112
  return <E, E2, R2>(effect: Effect.Effect<IncomingMessage<E>, E2, R2>) => Effect.scoped(Effect.flatMap(effect, decode))
108
113
  }
109
114
 
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type { ParseOptions } from "@effect/schema/AST"
4
5
  import type * as ParseResult from "@effect/schema/ParseResult"
5
6
  import type * as Schema from "@effect/schema/Schema"
6
7
  import type { YieldableError } from "effect/Cause"
@@ -221,7 +222,8 @@ export const filesSchema: Schema.Schema<ReadonlyArray<PersistedFile>> = internal
221
222
  * @category schema
222
223
  */
223
224
  export const schemaJson: <A, I, R>(
224
- schema: Schema.Schema<A, I, R>
225
+ schema: Schema.Schema<A, I, R>,
226
+ options?: ParseOptions | undefined
225
227
  ) => {
226
228
  (field: string): (persisted: Persisted) => Effect.Effect<A, ParseResult.ParseError, R>
227
229
  (persisted: Persisted, field: string): Effect.Effect<A, ParseResult.ParseError, R>
@@ -232,7 +234,8 @@ export const schemaJson: <A, I, R>(
232
234
  * @category schema
233
235
  */
234
236
  export const schemaPersisted: <R, I extends Partial<Persisted>, A>(
235
- schema: Schema.Schema<A, I, R>
237
+ schema: Schema.Schema<A, I, R>,
238
+ options?: ParseOptions | undefined
236
239
  ) => (persisted: Persisted) => Effect.Effect<A, ParseResult.ParseError, R> = internal.schemaPersisted
237
240
 
238
241
  /**
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type { ParseOptions } from "@effect/schema/AST"
4
5
  import type * as ParseResult from "@effect/schema/ParseResult"
5
6
  import type * as Schema from "@effect/schema/Schema"
6
7
  import type * as Cause from "effect/Cause"
@@ -148,12 +149,56 @@ export const searchParams: Effect.Effect<
148
149
  RouteContext
149
150
  > = internal.searchParams
150
151
 
152
+ /**
153
+ * @since 1.0.0
154
+ * @category route context
155
+ */
156
+ export const schemaJson: <
157
+ R,
158
+ I extends {
159
+ readonly method?: Method.Method | undefined
160
+ readonly url?: string | undefined
161
+ readonly cookies?: Readonly<Record<string, string>> | undefined
162
+ readonly headers?: Readonly<Record<string, string>> | undefined
163
+ readonly pathParams?: Readonly<Record<string, string>> | undefined
164
+ readonly searchParams?: Readonly<Record<string, string>> | undefined
165
+ readonly body?: any
166
+ },
167
+ A
168
+ >(
169
+ schema: Schema.Schema<A, I, R>,
170
+ options?: ParseOptions | undefined
171
+ ) => Effect.Effect<A, ParseResult.ParseError | Error.RequestError, RouteContext | R | ServerRequest.ServerRequest> =
172
+ internal.schemaJson
173
+
174
+ /**
175
+ * @since 1.0.0
176
+ * @category route context
177
+ */
178
+ export const schemaNoBody: <
179
+ R,
180
+ I extends {
181
+ readonly method?: Method.Method | undefined
182
+ readonly url?: string | undefined
183
+ readonly cookies?: Readonly<Record<string, string>> | undefined
184
+ readonly headers?: Readonly<Record<string, string>> | undefined
185
+ readonly pathParams?: Readonly<Record<string, string>> | undefined
186
+ readonly searchParams?: Readonly<Record<string, string>> | undefined
187
+ },
188
+ A
189
+ >(
190
+ schema: Schema.Schema<A, I, R>,
191
+ options?: ParseOptions | undefined
192
+ ) => Effect.Effect<A, ParseResult.ParseError | Error.RequestError, RouteContext | R | ServerRequest.ServerRequest> =
193
+ internal.schemaNoBody
194
+
151
195
  /**
152
196
  * @since 1.0.0
153
197
  * @category route context
154
198
  */
155
199
  export const schemaParams: <R, I extends Readonly<Record<string, string>>, A>(
156
- schema: Schema.Schema<A, I, R>
200
+ schema: Schema.Schema<A, I, R>,
201
+ options?: ParseOptions | undefined
157
202
  ) => Effect.Effect<A, ParseResult.ParseError, RouteContext | R> = internal.schemaParams
158
203
 
159
204
  /**
@@ -161,7 +206,8 @@ export const schemaParams: <R, I extends Readonly<Record<string, string>>, A>(
161
206
  * @category route context
162
207
  */
163
208
  export const schemaPathParams: <R, I extends Readonly<Record<string, string>>, A>(
164
- schema: Schema.Schema<A, I, R>
209
+ schema: Schema.Schema<A, I, R>,
210
+ options?: ParseOptions | undefined
165
211
  ) => Effect.Effect<A, ParseResult.ParseError, RouteContext | R> = internal.schemaPathParams
166
212
 
167
213
  /**
@@ -169,7 +215,8 @@ export const schemaPathParams: <R, I extends Readonly<Record<string, string>>, A
169
215
  * @category route context
170
216
  */
171
217
  export const schemaSearchParams: <R, I extends Readonly<Record<string, string>>, A>(
172
- schema: Schema.Schema<A, I, R>
218
+ schema: Schema.Schema<A, I, R>,
219
+ options?: ParseOptions | undefined
173
220
  ) => Effect.Effect<A, ParseResult.ParseError, RouteContext | R> = internal.schemaSearchParams
174
221
 
175
222
  /**
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type { ParseOptions } from "@effect/schema/AST"
4
5
  import type * as ParseResult from "@effect/schema/ParseResult"
5
6
  import type * as Schema from "@effect/schema/Schema"
6
7
  import type { Channel } from "effect/Channel"
7
8
  import type { Chunk } from "effect/Chunk"
8
9
  import type * as Context from "effect/Context"
9
10
  import type * as Effect from "effect/Effect"
11
+ import type { ReadonlyRecord } from "effect/ReadonlyRecord"
10
12
  import type * as Scope from "effect/Scope"
11
13
  import type * as Stream from "effect/Stream"
12
14
  import type * as FileSystem from "../FileSystem.js"
@@ -49,6 +51,7 @@ export interface ServerRequest extends IncomingMessage.IncomingMessage<Error.Req
49
51
  readonly url: string
50
52
  readonly originalUrl: string
51
53
  readonly method: Method
54
+ readonly cookies: ReadonlyRecord<string, string>
52
55
 
53
56
  readonly multipart: Effect.Effect<
54
57
  Multipart.Persisted,
@@ -104,12 +107,22 @@ export const upgradeChannel: <IE = never>() => Channel<
104
107
  ServerRequest
105
108
  > = internal.upgradeChannel
106
109
 
110
+ /**
111
+ * @since 1.0.0
112
+ * @category schema
113
+ */
114
+ export const schemaCookies: <R, I extends Readonly<Record<string, string>>, A>(
115
+ schema: Schema.Schema<A, I, R>,
116
+ options?: ParseOptions | undefined
117
+ ) => Effect.Effect<A, ParseResult.ParseError, ServerRequest | R> = internal.schemaCookies
118
+
107
119
  /**
108
120
  * @since 1.0.0
109
121
  * @category schema
110
122
  */
111
123
  export const schemaHeaders: <R, I extends Readonly<Record<string, string>>, A>(
112
- schema: Schema.Schema<A, I, R>
124
+ schema: Schema.Schema<A, I, R>,
125
+ options?: ParseOptions | undefined
113
126
  ) => Effect.Effect<A, ParseResult.ParseError, ServerRequest | R> = internal.schemaHeaders
114
127
 
115
128
  /**
@@ -117,7 +130,8 @@ export const schemaHeaders: <R, I extends Readonly<Record<string, string>>, A>(
117
130
  * @category schema
118
131
  */
119
132
  export const schemaBodyJson: <A, I, R>(
120
- schema: Schema.Schema<A, I, R>
133
+ schema: Schema.Schema<A, I, R>,
134
+ options?: ParseOptions | undefined
121
135
  ) => Effect.Effect<A, Error.RequestError | ParseResult.ParseError, ServerRequest | R> = internal.schemaBodyJson
122
136
 
123
137
  /**
@@ -125,7 +139,8 @@ export const schemaBodyJson: <A, I, R>(
125
139
  * @category schema
126
140
  */
127
141
  export const schemaBodyForm: <R, I extends Partial<Multipart.Persisted>, A>(
128
- schema: Schema.Schema<A, I, R>
142
+ schema: Schema.Schema<A, I, R>,
143
+ options?: ParseOptions | undefined
129
144
  ) => Effect.Effect<
130
145
  A,
131
146
  Multipart.MultipartError | ParseResult.ParseError | Error.RequestError,
@@ -137,15 +152,17 @@ export const schemaBodyForm: <R, I extends Partial<Multipart.Persisted>, A>(
137
152
  * @category schema
138
153
  */
139
154
  export const schemaBodyUrlParams: <R, I extends Readonly<Record<string, string>>, A>(
140
- schema: Schema.Schema<A, I, R>
141
- ) => Effect.Effect<A, Error.RequestError | ParseResult.ParseError, ServerRequest | R> = internal.schemaBodyUrlParams
155
+ schema: Schema.Schema<A, I, R>,
156
+ options?: ParseOptions | undefined
157
+ ) => Effect.Effect<A, ParseResult.ParseError | Error.RequestError, R | ServerRequest> = internal.schemaBodyUrlParams
142
158
 
143
159
  /**
144
160
  * @since 1.0.0
145
161
  * @category schema
146
162
  */
147
163
  export const schemaBodyMultipart: <R, I extends Partial<Multipart.Persisted>, A>(
148
- schema: Schema.Schema<A, I, R>
164
+ schema: Schema.Schema<A, I, R>,
165
+ options?: ParseOptions | undefined
149
166
  ) => Effect.Effect<
150
167
  A,
151
168
  Multipart.MultipartError | ParseResult.ParseError,
@@ -157,7 +174,8 @@ export const schemaBodyMultipart: <R, I extends Partial<Multipart.Persisted>, A>
157
174
  * @category schema
158
175
  */
159
176
  export const schemaBodyFormJson: <A, I, R>(
160
- schema: Schema.Schema<A, I, R>
177
+ schema: Schema.Schema<A, I, R>,
178
+ options?: ParseOptions | undefined
161
179
  ) => (
162
180
  field: string
163
181
  ) => Effect.Effect<
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type { ParseOptions } from "@effect/schema/AST"
4
5
  import type * as Schema from "@effect/schema/Schema"
5
6
  import type * as Effect from "effect/Effect"
6
7
  import type { Inspectable } from "effect/Inspectable"
@@ -10,6 +11,7 @@ import type * as FileSystem from "../FileSystem.js"
10
11
  import * as internal from "../internal/http/serverResponse.js"
11
12
  import type * as Template from "../Template.js"
12
13
  import type * as Body from "./Body.js"
14
+ import type { Cookie, Cookies, CookiesError } from "./Cookies.js"
13
15
  import type * as Headers from "./Headers.js"
14
16
  import type * as Platform from "./Platform.js"
15
17
  import type * as UrlParams from "./UrlParams.js"
@@ -35,6 +37,7 @@ export interface ServerResponse extends Effect.Effect<ServerResponse>, Inspectab
35
37
  readonly status: number
36
38
  readonly statusText?: string | undefined
37
39
  readonly headers: Headers.Headers
40
+ readonly cookies: Cookies
38
41
  readonly body: Body.Body
39
42
  }
40
43
 
@@ -46,6 +49,7 @@ export interface Options {
46
49
  readonly status?: number | undefined
47
50
  readonly statusText?: string | undefined
48
51
  readonly headers?: Headers.Headers | undefined
52
+ readonly cookies?: Cookies | undefined
49
53
  readonly contentType?: string | undefined
50
54
  readonly contentLength?: number | undefined
51
55
  }
@@ -76,19 +80,20 @@ export const isServerResponse: (u: unknown) => u is ServerResponse = internal.is
76
80
  * @since 1.0.0
77
81
  * @category constructors
78
82
  */
79
- export const empty: (options?: Options.WithContent) => ServerResponse = internal.empty
83
+ export const empty: (options?: Options.WithContent | undefined) => ServerResponse = internal.empty
80
84
 
81
85
  /**
82
86
  * @since 1.0.0
83
87
  * @category constructors
84
88
  */
85
- export const uint8Array: (body: Uint8Array, options?: Options.WithContentType) => ServerResponse = internal.uint8Array
89
+ export const uint8Array: (body: Uint8Array, options?: Options.WithContentType | undefined) => ServerResponse =
90
+ internal.uint8Array
86
91
 
87
92
  /**
88
93
  * @since 1.0.0
89
94
  * @category constructors
90
95
  */
91
- export const text: (body: string, options?: Options.WithContentType) => ServerResponse = internal.text
96
+ export const text: (body: string, options?: Options.WithContentType | undefined) => ServerResponse = internal.text
92
97
 
93
98
  /**
94
99
  * @since 1.0.0
@@ -117,7 +122,7 @@ export const htmlStream: <A extends ReadonlyArray<Template.InterpolatedWithStrea
117
122
  */
118
123
  export const json: (
119
124
  body: unknown,
120
- options?: Options.WithContent
125
+ options?: Options.WithContent | undefined
121
126
  ) => Effect.Effect<ServerResponse, Body.BodyError> = internal.json
122
127
 
123
128
  /**
@@ -125,7 +130,8 @@ export const json: (
125
130
  * @category constructors
126
131
  */
127
132
  export const schemaJson: <A, I, R>(
128
- schema: Schema.Schema<A, I, R>
133
+ schema: Schema.Schema<A, I, R>,
134
+ options?: ParseOptions | undefined
129
135
  ) => (body: A, options?: Options.WithContent | undefined) => Effect.Effect<ServerResponse, Body.BodyError, R> =
130
136
  internal.schemaJson
131
137
 
@@ -133,31 +139,34 @@ export const schemaJson: <A, I, R>(
133
139
  * @since 1.0.0
134
140
  * @category constructors
135
141
  */
136
- export const unsafeJson: (body: unknown, options?: Options.WithContent) => ServerResponse = internal.unsafeJson
142
+ export const unsafeJson: (body: unknown, options?: Options.WithContent | undefined) => ServerResponse =
143
+ internal.unsafeJson
137
144
 
138
145
  /**
139
146
  * @since 1.0.0
140
147
  * @category constructors
141
148
  */
142
- export const urlParams: (body: UrlParams.Input, options?: Options.WithContent) => ServerResponse = internal.urlParams
149
+ export const urlParams: (body: UrlParams.Input, options?: Options.WithContent | undefined) => ServerResponse =
150
+ internal.urlParams
143
151
 
144
152
  /**
145
153
  * @since 1.0.0
146
154
  * @category constructors
147
155
  */
148
- export const raw: (body: unknown, options?: Options) => ServerResponse = internal.raw
156
+ export const raw: (body: unknown, options?: Options | undefined) => ServerResponse = internal.raw
149
157
 
150
158
  /**
151
159
  * @since 1.0.0
152
160
  * @category constructors
153
161
  */
154
- export const formData: (body: FormData, options?: Options.WithContent) => ServerResponse = internal.formData
162
+ export const formData: (body: FormData, options?: Options.WithContent | undefined) => ServerResponse = internal.formData
155
163
 
156
164
  /**
157
165
  * @since 1.0.0
158
166
  * @category constructors
159
167
  */
160
- export const stream: (body: Stream.Stream<Uint8Array, unknown>, options?: Options) => ServerResponse = internal.stream
168
+ export const stream: (body: Stream.Stream<Uint8Array, unknown>, options?: Options | undefined) => ServerResponse =
169
+ internal.stream
161
170
 
162
171
  /**
163
172
  * @since 1.0.0
@@ -165,7 +174,7 @@ export const stream: (body: Stream.Stream<Uint8Array, unknown>, options?: Option
165
174
  */
166
175
  export const file: (
167
176
  path: string,
168
- options?: Options & FileSystem.StreamOptions
177
+ options?: (Options & FileSystem.StreamOptions) | undefined
169
178
  ) => Effect.Effect<ServerResponse, PlatformError.PlatformError, Platform.Platform> = internal.file
170
179
 
171
180
  /**
@@ -174,7 +183,7 @@ export const file: (
174
183
  */
175
184
  export const fileWeb: (
176
185
  file: Body.Body.FileLike,
177
- options?: Options.WithContent & FileSystem.StreamOptions
186
+ options?: (Options.WithContent & FileSystem.StreamOptions) | undefined
178
187
  ) => Effect.Effect<ServerResponse, never, Platform.Platform> = internal.fileWeb
179
188
 
180
189
  /**
@@ -195,6 +204,129 @@ export const setHeaders: {
195
204
  (self: ServerResponse, input: Headers.Input): ServerResponse
196
205
  } = internal.setHeaders
197
206
 
207
+ /**
208
+ * @since 1.0.0
209
+ * @category combinators
210
+ */
211
+ export const removeCookie: {
212
+ (name: string): (self: ServerResponse) => ServerResponse
213
+ (self: ServerResponse, name: string): ServerResponse
214
+ } = internal.removeCookie
215
+
216
+ /**
217
+ * @since 1.0.0
218
+ * @category combinators
219
+ */
220
+ export const replaceCookies: {
221
+ (cookies: Cookies): (self: ServerResponse) => ServerResponse
222
+ (self: ServerResponse, cookies: Cookies): ServerResponse
223
+ } = internal.replaceCookies
224
+
225
+ /**
226
+ * @since 1.0.0
227
+ * @category combinators
228
+ */
229
+ export const setCookie: {
230
+ (
231
+ name: string,
232
+ value: string,
233
+ options?: Cookie["options"]
234
+ ): (
235
+ self: ServerResponse
236
+ ) => Effect.Effect<
237
+ ServerResponse,
238
+ CookiesError
239
+ >
240
+ (
241
+ self: ServerResponse,
242
+ name: string,
243
+ value: string,
244
+ options?: Cookie["options"]
245
+ ): Effect.Effect<
246
+ ServerResponse,
247
+ CookiesError
248
+ >
249
+ } = internal.setCookie
250
+
251
+ /**
252
+ * @since 1.0.0
253
+ * @category combinators
254
+ */
255
+ export const unsafeSetCookie: {
256
+ (
257
+ name: string,
258
+ value: string,
259
+ options?: Cookie["options"]
260
+ ): (self: ServerResponse) => ServerResponse
261
+ (
262
+ self: ServerResponse,
263
+ name: string,
264
+ value: string,
265
+ options?: Cookie["options"]
266
+ ): ServerResponse
267
+ } = internal.unsafeSetCookie
268
+
269
+ /**
270
+ * @since 1.0.0
271
+ * @category combinators
272
+ */
273
+ export const updateCookies: {
274
+ (f: (cookies: Cookies) => Cookies): (self: ServerResponse) => ServerResponse
275
+ (self: ServerResponse, f: (cookies: Cookies) => Cookies): ServerResponse
276
+ } = internal.updateCookies
277
+
278
+ /**
279
+ * @since 1.0.0
280
+ * @category combinators
281
+ */
282
+ export const setCookies: {
283
+ (
284
+ cookies: Iterable<
285
+ readonly [
286
+ name: string,
287
+ value: string,
288
+ options?: Cookie["options"]
289
+ ]
290
+ >
291
+ ): (self: ServerResponse) => Effect.Effect<ServerResponse, CookiesError, never>
292
+ (
293
+ self: ServerResponse,
294
+ cookies: Iterable<
295
+ readonly [
296
+ name: string,
297
+ value: string,
298
+ options?: Cookie["options"]
299
+ ]
300
+ >
301
+ ): Effect.Effect<ServerResponse, CookiesError, never>
302
+ } = internal.setCookies
303
+
304
+ /**
305
+ * @since 1.0.0
306
+ * @category combinators
307
+ */
308
+ export const unsafeSetCookies: {
309
+ (
310
+ cookies: Iterable<
311
+ readonly [
312
+ name: string,
313
+ value: string,
314
+ options?: Cookie["options"]
315
+ ]
316
+ >
317
+ ): (self: ServerResponse) => ServerResponse
318
+ (
319
+ self: ServerResponse,
320
+ cookies: Iterable<
321
+ readonly [
322
+ name: string,
323
+ value: string,
324
+ options?: Cookie["options"]
325
+ ]
326
+ >
327
+ ): ServerResponse
328
+ } = internal.unsafeSetCookies
329
+
198
330
  /**
199
331
  * @since 1.0.0
200
332
  * @category combinators
@@ -217,4 +349,4 @@ export const setStatus: {
217
349
  * @since 1.0.0
218
350
  * @category conversions
219
351
  */
220
- export const toWeb: (response: ServerResponse, withoutBody?: boolean) => Response = internal.toWeb
352
+ export const toWeb: (response: ServerResponse, withoutBody?: boolean | undefined) => Response = internal.toWeb
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type { ParseOptions } from "@effect/schema/AST"
4
5
  import type * as ParseResult from "@effect/schema/ParseResult"
5
6
  import * as Schema from "@effect/schema/Schema"
6
7
  import * as Effect from "effect/Effect"
@@ -217,7 +218,7 @@ const baseUrl = (): string | undefined => {
217
218
  * @since 1.0.0
218
219
  * @category schema
219
220
  */
220
- export const schemaJson = <A, I, R>(schema: Schema.Schema<A, I, R>): {
221
+ export const schemaJson = <A, I, R>(schema: Schema.Schema<A, I, R>, options?: ParseOptions | undefined): {
221
222
  (
222
223
  field: string
223
224
  ): (self: UrlParams) => Effect.Effect<A, ParseResult.ParseError, R>
@@ -226,7 +227,7 @@ export const schemaJson = <A, I, R>(schema: Schema.Schema<A, I, R>): {
226
227
  field: string
227
228
  ): Effect.Effect<A, ParseResult.ParseError, R>
228
229
  } => {
229
- const parse = Schema.decodeUnknown(Schema.parseJson(schema))
230
+ const parse = Schema.decodeUnknown(Schema.parseJson(schema), options)
230
231
  return dual<
231
232
  (field: string) => (self: UrlParams) => Effect.Effect<A, ParseResult.ParseError, R>,
232
233
  (self: UrlParams, field: string) => Effect.Effect<A, ParseResult.ParseError, R>
package/src/HttpClient.ts CHANGED
@@ -6,6 +6,7 @@ import * as client from "./Http/Client.js"
6
6
  import * as error from "./Http/ClientError.js"
7
7
  import * as request from "./Http/ClientRequest.js"
8
8
  import * as response from "./Http/ClientResponse.js"
9
+ import * as cookies from "./Http/Cookies.js"
9
10
  import * as headers from "./Http/Headers.js"
10
11
  import * as urlParams from "./Http/UrlParams.js"
11
12
 
@@ -24,6 +25,13 @@ export {
24
25
  * - Module: `@effect/platform/Http/Client`
25
26
  */
26
27
  client,
28
+ /**
29
+ * @since 1.0.0
30
+ *
31
+ * - Docs: [Http/Cookies](https://effect-ts.github.io/effect/platform/Http/Cookies.ts.html)
32
+ * - Module: `@effect/platform/Http/Cookies`
33
+ */
34
+ cookies,
27
35
  /**
28
36
  * @since 1.0.0
29
37
  *
package/src/HttpServer.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import * as app from "./Http/App.js"
5
5
  import * as body from "./Http/Body.js"
6
+ import * as cookies from "./Http/Cookies.js"
6
7
  import * as etag from "./Http/Etag.js"
7
8
  import * as headers from "./Http/Headers.js"
8
9
  import * as middleware from "./Http/Middleware.js"
@@ -31,6 +32,13 @@ export {
31
32
  * - Module: `@effect/platform/Http/Body`
32
33
  */
33
34
  body,
35
+ /**
36
+ * @since 1.0.0
37
+ *
38
+ * - Docs: [Http/Cookies](https://effect-ts.github.io/effect/platform/Http/Cookies.ts.html)
39
+ * - Module: `@effect/platform/Http/Cookies`
40
+ */
41
+ cookies,
34
42
  /**
35
43
  * @since 1.0.0
36
44
  *
@@ -1,3 +1,4 @@
1
+ import type { ParseOptions } from "@effect/schema/AST"
1
2
  import * as Schema from "@effect/schema/Schema"
2
3
  import * as Data from "effect/Data"
3
4
  import * as Effect from "effect/Effect"
@@ -127,8 +128,8 @@ export const urlParams = (urlParams: UrlParams.UrlParams): Body.Uint8Array =>
127
128
  text(UrlParams.toString(urlParams), "application/x-www-form-urlencoded")
128
129
 
129
130
  /** @internal */
130
- export const jsonSchema = <A, I, R>(schema: Schema.Schema<A, I, R>) => {
131
- const encode = Schema.encode(schema)
131
+ export const jsonSchema = <A, I, R>(schema: Schema.Schema<A, I, R>, options?: ParseOptions) => {
132
+ const encode = Schema.encode(schema, options)
132
133
  return (body: A): Effect.Effect<Body.Uint8Array, Body.BodyError, R> =>
133
134
  Effect.flatMap(
134
135
  Effect.mapError(encode(body), (error) => BodyError({ _tag: "SchemaError", error })),