@effect/platform 0.37.8 → 0.39.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.
Files changed (80) hide show
  1. package/Http/Multipart/package.json +6 -0
  2. package/dist/cjs/Http/Body.js +6 -1
  3. package/dist/cjs/Http/Body.js.map +1 -1
  4. package/dist/cjs/Http/IncomingMessage.js +3 -1
  5. package/dist/cjs/Http/IncomingMessage.js.map +1 -1
  6. package/dist/cjs/Http/{FormData.js → Multipart.js} +5 -5
  7. package/dist/cjs/Http/Multipart.js.map +1 -0
  8. package/dist/cjs/Http/ServerRequest.js +9 -4
  9. package/dist/cjs/Http/ServerRequest.js.map +1 -1
  10. package/dist/cjs/Http/UrlParams.js +32 -5
  11. package/dist/cjs/Http/UrlParams.js.map +1 -1
  12. package/dist/cjs/HttpServer.js +3 -3
  13. package/dist/cjs/HttpServer.js.map +1 -1
  14. package/dist/cjs/internal/http/body.js +9 -4
  15. package/dist/cjs/internal/http/body.js.map +1 -1
  16. package/dist/cjs/internal/http/client.js +4 -5
  17. package/dist/cjs/internal/http/client.js.map +1 -1
  18. package/dist/cjs/internal/http/{formData.js → multipart.js} +42 -35
  19. package/dist/cjs/internal/http/multipart.js.map +1 -0
  20. package/dist/cjs/internal/http/serverRequest.js +43 -24
  21. package/dist/cjs/internal/http/serverRequest.js.map +1 -1
  22. package/dist/cjs/internal/http/serverResponse.js.map +1 -1
  23. package/dist/cjs/internal/keyValueStore.js +1 -1
  24. package/dist/cjs/internal/keyValueStore.js.map +1 -1
  25. package/dist/dts/Http/Body.d.ts +6 -0
  26. package/dist/dts/Http/Body.d.ts.map +1 -1
  27. package/dist/dts/Http/{FormData.d.ts → Multipart.d.ts} +11 -11
  28. package/dist/dts/Http/Multipart.d.ts.map +1 -0
  29. package/dist/dts/Http/ServerRequest.d.ts +11 -6
  30. package/dist/dts/Http/ServerRequest.d.ts.map +1 -1
  31. package/dist/dts/Http/UrlParams.d.ts +35 -0
  32. package/dist/dts/Http/UrlParams.d.ts.map +1 -1
  33. package/dist/dts/HttpServer.d.ts +8 -8
  34. package/dist/dts/HttpServer.d.ts.map +1 -1
  35. package/dist/dts/internal/http/multipart.d.ts +2 -0
  36. package/dist/dts/internal/http/multipart.d.ts.map +1 -0
  37. package/dist/esm/Http/Body.js +5 -0
  38. package/dist/esm/Http/Body.js.map +1 -1
  39. package/dist/esm/Http/IncomingMessage.js +3 -1
  40. package/dist/esm/Http/IncomingMessage.js.map +1 -1
  41. package/dist/esm/Http/{FormData.js → Multipart.js} +4 -4
  42. package/dist/esm/Http/Multipart.js.map +1 -0
  43. package/dist/esm/Http/ServerRequest.js +8 -3
  44. package/dist/esm/Http/ServerRequest.js.map +1 -1
  45. package/dist/esm/Http/UrlParams.js +30 -3
  46. package/dist/esm/Http/UrlParams.js.map +1 -1
  47. package/dist/esm/HttpServer.js +8 -8
  48. package/dist/esm/HttpServer.js.map +1 -1
  49. package/dist/esm/internal/http/body.js +6 -2
  50. package/dist/esm/internal/http/body.js.map +1 -1
  51. package/dist/esm/internal/http/client.js +4 -5
  52. package/dist/esm/internal/http/client.js.map +1 -1
  53. package/dist/esm/internal/http/{formData.js → multipart.js} +39 -32
  54. package/dist/esm/internal/http/multipart.js.map +1 -0
  55. package/dist/esm/internal/http/serverRequest.js +38 -20
  56. package/dist/esm/internal/http/serverRequest.js.map +1 -1
  57. package/dist/esm/internal/http/serverResponse.js.map +1 -1
  58. package/dist/esm/internal/keyValueStore.js +1 -1
  59. package/dist/esm/internal/keyValueStore.js.map +1 -1
  60. package/package.json +13 -13
  61. package/src/Http/Body.ts +7 -0
  62. package/src/Http/IncomingMessage.ts +1 -1
  63. package/src/Http/{FormData.ts → Multipart.ts} +17 -18
  64. package/src/Http/ServerRequest.ts +26 -14
  65. package/src/Http/UrlParams.ts +79 -0
  66. package/src/HttpServer.ts +8 -8
  67. package/src/internal/http/body.ts +9 -3
  68. package/src/internal/http/client.ts +11 -15
  69. package/src/internal/http/{formData.ts → multipart.ts} +79 -80
  70. package/src/internal/http/serverRequest.ts +66 -37
  71. package/src/internal/http/serverResponse.ts +4 -1
  72. package/src/internal/keyValueStore.ts +1 -1
  73. package/Http/FormData/package.json +0 -6
  74. package/dist/cjs/Http/FormData.js.map +0 -1
  75. package/dist/cjs/internal/http/formData.js.map +0 -1
  76. package/dist/dts/Http/FormData.d.ts.map +0 -1
  77. package/dist/dts/internal/http/formData.d.ts +0 -2
  78. package/dist/dts/internal/http/formData.d.ts.map +0 -1
  79. package/dist/esm/Http/FormData.js.map +0 -1
  80. package/dist/esm/internal/http/formData.js.map +0 -1
@@ -10,10 +10,10 @@ import type * as Stream from "effect/Stream"
10
10
  import type * as FileSystem from "../FileSystem.js"
11
11
  import * as internal from "../internal/http/serverRequest.js"
12
12
  import type * as Path from "../Path.js"
13
- import type * as FormData from "./FormData.js"
14
13
  import type * as Headers from "./Headers.js"
15
14
  import type * as IncomingMessage from "./IncomingMessage.js"
16
15
  import type { Method } from "./Method.js"
16
+ import type * as Multipart from "./Multipart.js"
17
17
  import type * as Error from "./ServerError.js"
18
18
 
19
19
  export {
@@ -47,12 +47,12 @@ export interface ServerRequest extends IncomingMessage.IncomingMessage<Error.Req
47
47
  readonly originalUrl: string
48
48
  readonly method: Method
49
49
 
50
- readonly formData: Effect.Effect<
50
+ readonly multipart: Effect.Effect<
51
51
  Scope.Scope | FileSystem.FileSystem | Path.Path,
52
- FormData.FormDataError,
53
- FormData.PersistedFormData
52
+ Multipart.MultipartError,
53
+ Multipart.Persisted
54
54
  >
55
- readonly formDataStream: Stream.Stream<never, FormData.FormDataError, FormData.Part>
55
+ readonly multipartStream: Stream.Stream<never, Multipart.MultipartError, Multipart.Part>
56
56
 
57
57
  readonly modify: (
58
58
  options: {
@@ -73,11 +73,11 @@ export const ServerRequest: Context.Tag<ServerRequest, ServerRequest> = internal
73
73
  * @since 1.0.0
74
74
  * @category accessors
75
75
  */
76
- export const persistedFormData: Effect.Effect<
76
+ export const persistedMultipart: Effect.Effect<
77
77
  Scope.Scope | FileSystem.FileSystem | Path.Path | ServerRequest,
78
- FormData.FormDataError,
78
+ Multipart.MultipartError,
79
79
  unknown
80
- > = internal.persistedFormData
80
+ > = internal.multipartPersisted
81
81
 
82
82
  /**
83
83
  * @since 1.0.0
@@ -95,6 +95,18 @@ export const schemaBodyJson: <I, A>(
95
95
  schema: Schema.Schema<I, A>
96
96
  ) => Effect.Effect<ServerRequest, Error.RequestError | ParseResult.ParseError, A> = internal.schemaBodyJson
97
97
 
98
+ /**
99
+ * @since 1.0.0
100
+ * @category schema
101
+ */
102
+ export const schemaBodyForm: <I extends Multipart.Persisted, A>(
103
+ schema: Schema.Schema<I, A>
104
+ ) => Effect.Effect<
105
+ ServerRequest | Scope.Scope | FileSystem.FileSystem | Path.Path,
106
+ Multipart.MultipartError | Error.RequestError | ParseResult.ParseError,
107
+ A
108
+ > = internal.schemaBodyForm
109
+
98
110
  /**
99
111
  * @since 1.0.0
100
112
  * @category schema
@@ -107,27 +119,27 @@ export const schemaBodyUrlParams: <I extends Readonly<Record<string, string>>, A
107
119
  * @since 1.0.0
108
120
  * @category schema
109
121
  */
110
- export const schemaFormData: <I extends FormData.PersistedFormData, A>(
122
+ export const schemaBodyMultipart: <I extends Multipart.Persisted, A>(
111
123
  schema: Schema.Schema<I, A>
112
124
  ) => Effect.Effect<
113
125
  ServerRequest | Scope.Scope | FileSystem.FileSystem | Path.Path,
114
- FormData.FormDataError | ParseResult.ParseError,
126
+ Multipart.MultipartError | ParseResult.ParseError,
115
127
  A
116
- > = internal.schemaFormData
128
+ > = internal.schemaBodyMultipart
117
129
 
118
130
  /**
119
131
  * @since 1.0.0
120
132
  * @category schema
121
133
  */
122
- export const schemaFormDataJson: <I, A>(
134
+ export const schemaBodyFormJson: <I, A>(
123
135
  schema: Schema.Schema<I, A>
124
136
  ) => (
125
137
  field: string
126
138
  ) => Effect.Effect<
127
139
  ServerRequest | Scope.Scope | FileSystem.FileSystem | Path.Path,
128
- Error.RequestError | FormData.FormDataError | ParseResult.ParseError,
140
+ Error.RequestError | ParseResult.ParseError,
129
141
  A
130
- > = internal.schemaFormDataJson
142
+ > = internal.schemaBodyFormJson
131
143
 
132
144
  /**
133
145
  * @since 1.0.0
@@ -1,8 +1,11 @@
1
1
  /**
2
2
  * @since 1.0.0
3
3
  */
4
+ import type * as ParseResult from "@effect/schema/ParseResult"
5
+ import * as Schema from "@effect/schema/Schema"
4
6
  import * as Effect from "effect/Effect"
5
7
  import { dual } from "effect/Function"
8
+ import * as Option from "effect/Option"
6
9
  import * as ReadonlyArray from "effect/ReadonlyArray"
7
10
 
8
11
  /**
@@ -34,6 +37,62 @@ export const fromInput = (input: Input): UrlParams => {
34
37
  */
35
38
  export const empty: UrlParams = []
36
39
 
40
+ /**
41
+ * @since 1.0.0
42
+ * @category combinators
43
+ */
44
+ export const getAll: {
45
+ (key: string): (self: UrlParams) => ReadonlyArray<string>
46
+ (self: UrlParams, key: string): ReadonlyArray<string>
47
+ } = dual<
48
+ (key: string) => (self: UrlParams) => ReadonlyArray<string>,
49
+ (self: UrlParams, key: string) => ReadonlyArray<string>
50
+ >(2, (self, key) =>
51
+ ReadonlyArray.reduce(self, [] as Array<string>, (acc, [k, value]) => {
52
+ if (k === key) {
53
+ acc.push(value)
54
+ }
55
+ return acc
56
+ }))
57
+
58
+ /**
59
+ * @since 1.0.0
60
+ * @category combinators
61
+ */
62
+ export const getFirst: {
63
+ (key: string): (self: UrlParams) => Option.Option<string>
64
+ (self: UrlParams, key: string): Option.Option<string>
65
+ } = dual<
66
+ (key: string) => (self: UrlParams) => Option.Option<string>,
67
+ (self: UrlParams, key: string) => Option.Option<string>
68
+ >(2, (self, key) =>
69
+ Option.map(
70
+ ReadonlyArray.findFirst(
71
+ self,
72
+ ([k]) => k === key
73
+ ),
74
+ ([, value]) => value
75
+ ))
76
+
77
+ /**
78
+ * @since 1.0.0
79
+ * @category combinators
80
+ */
81
+ export const getLast: {
82
+ (key: string): (self: UrlParams) => Option.Option<string>
83
+ (self: UrlParams, key: string): Option.Option<string>
84
+ } = dual<
85
+ (key: string) => (self: UrlParams) => Option.Option<string>,
86
+ (self: UrlParams, key: string) => Option.Option<string>
87
+ >(2, (self, key) =>
88
+ Option.map(
89
+ ReadonlyArray.findLast(
90
+ self,
91
+ ([k]) => k === key
92
+ ),
93
+ ([, value]) => value
94
+ ))
95
+
37
96
  /**
38
97
  * @since 1.0.0
39
98
  * @category combinators
@@ -143,3 +202,23 @@ const baseUrl = (): string | undefined => {
143
202
  }
144
203
  return undefined
145
204
  }
205
+
206
+ /**
207
+ * @since 1.0.0
208
+ * @category schema
209
+ */
210
+ export const schemaJson = <I, A>(schema: Schema.Schema<I, A>): {
211
+ (
212
+ field: string
213
+ ): (self: UrlParams) => Effect.Effect<never, ParseResult.ParseError, A>
214
+ (
215
+ self: UrlParams,
216
+ field: string
217
+ ): Effect.Effect<never, ParseResult.ParseError, A>
218
+ } => {
219
+ const parse = Schema.parse(Schema.parseJson(schema))
220
+ return dual<
221
+ (field: string) => (self: UrlParams) => Effect.Effect<never, ParseResult.ParseError, A>,
222
+ (self: UrlParams, field: string) => Effect.Effect<never, ParseResult.ParseError, A>
223
+ >(2, (self, field) => parse(Option.getOrElse(getLast(self, field), () => "")))
224
+ }
package/src/HttpServer.ts CHANGED
@@ -3,9 +3,9 @@
3
3
  */
4
4
  import * as app from "./Http/App.js"
5
5
  import * as body from "./Http/Body.js"
6
- import * as formData from "./Http/FormData.js"
7
6
  import * as headers from "./Http/Headers.js"
8
7
  import * as middleware from "./Http/Middleware.js"
8
+ import * as multipart from "./Http/Multipart.js"
9
9
  import * as router from "./Http/Router.js"
10
10
  import * as error from "./Http/ServerError.js"
11
11
  import * as request from "./Http/ServerRequest.js"
@@ -34,13 +34,6 @@ export {
34
34
  * - Module: `@effect/platform/Http/ServerError`
35
35
  */
36
36
  error,
37
- /**
38
- * @since 1.0.0
39
- *
40
- * - Docs: [Http/FormData](https://effect-ts.github.io/platform/platform/Http/FormData.html)
41
- * - Module: `@effect/platform/Http/FormData`
42
- */
43
- formData,
44
37
  /**
45
38
  * @since 1.0.0
46
39
  *
@@ -55,6 +48,13 @@ export {
55
48
  * - Module: `@effect/platform/Http/Middleware`
56
49
  */
57
50
  middleware,
51
+ /**
52
+ * @since 1.0.0
53
+ *
54
+ * - Docs: [Http/Multipart](https://effect-ts.github.io/platform/platform/Http/Multipart.html)
55
+ * - Module: `@effect/platform/Http/Multipart`
56
+ */
57
+ multipart,
58
58
  /**
59
59
  * @since 1.0.0
60
60
  *
@@ -6,6 +6,7 @@ import * as Stream_ from "effect/Stream"
6
6
  import type * as PlatformError from "../../Error.js"
7
7
  import * as FileSystem from "../../FileSystem.js"
8
8
  import type * as Body from "../../Http/Body.js"
9
+ import * as UrlParams from "../../Http/UrlParams.js"
9
10
 
10
11
  /** @internal */
11
12
  export const TypeId: Body.TypeId = Symbol.for(
@@ -68,13 +69,14 @@ class Uint8ArrayImpl implements Body.Uint8Array {
68
69
  export const uint8Array = (body: Uint8Array, contentType?: string): Body.Uint8Array =>
69
70
  new Uint8ArrayImpl(body, contentType ?? "application/octet-stream")
70
71
 
72
+ const encoder = new TextEncoder()
73
+
71
74
  /** @internal */
72
75
  export const text = (body: string, contentType?: string): Body.Uint8Array =>
73
- uint8Array(new TextEncoder().encode(body), contentType ?? "text/plain")
76
+ uint8Array(encoder.encode(body), contentType ?? "text/plain")
74
77
 
75
78
  /** @internal */
76
- export const unsafeJson = (body: unknown): Body.Uint8Array =>
77
- uint8Array(new TextEncoder().encode(JSON.stringify(body)), "application/json")
79
+ export const unsafeJson = (body: unknown): Body.Uint8Array => text(JSON.stringify(body), "application/json")
78
80
 
79
81
  /** @internal */
80
82
  export const json = (body: unknown): Effect.Effect<never, Body.BodyError, Body.Uint8Array> =>
@@ -83,6 +85,10 @@ export const json = (body: unknown): Effect.Effect<never, Body.BodyError, Body.U
83
85
  catch: (error) => BodyError({ _tag: "JsonError", error })
84
86
  })
85
87
 
88
+ /** @internal */
89
+ export const urlParams = (urlParams: UrlParams.UrlParams): Body.Uint8Array =>
90
+ text(UrlParams.toString(urlParams), "application/x-www-form-urlencoded")
91
+
86
92
  /** @internal */
87
93
  export const jsonSchema = <I, A>(schema: Schema.Schema<I, A>) => {
88
94
  const encode = Schema.encode(schema)
@@ -4,7 +4,6 @@ import * as Context from "effect/Context"
4
4
  import * as Effect from "effect/Effect"
5
5
  import { dual } from "effect/Function"
6
6
  import * as Layer from "effect/Layer"
7
- import * as Option from "effect/Option"
8
7
  import { pipeArguments } from "effect/Pipeable"
9
8
  import type * as Predicate from "effect/Predicate"
10
9
  import type * as Schedule from "effect/Schedule"
@@ -53,20 +52,17 @@ export const make = <R, E, A, R2, E2>(
53
52
  }
54
53
 
55
54
  const addB3Headers = (req: ClientRequest.ClientRequest) =>
56
- Effect.map(
57
- Effect.currentSpan,
58
- Option.match({
59
- onNone: () => req,
60
- onSome: (span) =>
61
- internalRequest.setHeader(
62
- req,
63
- "b3",
64
- `${span.traceId}-${span.spanId}-${span.sampled ? "1" : "0"}${
65
- span.parent._tag === "Some" ? `-${span.parent.value.spanId}` : ""
66
- }`
67
- )
68
- })
69
- )
55
+ Effect.match(Effect.currentSpan, {
56
+ onFailure: () => req,
57
+ onSuccess: (span) =>
58
+ internalRequest.setHeader(
59
+ req,
60
+ "b3",
61
+ `${span.traceId}-${span.spanId}-${span.sampled ? "1" : "0"}${
62
+ span.parent._tag === "Some" ? `-${span.parent.value.spanId}` : ""
63
+ }`
64
+ )
65
+ })
70
66
 
71
67
  /** @internal */
72
68
  export const makeDefault = (
@@ -16,34 +16,34 @@ import type * as AsyncInput from "effect/SingleProducerAsyncInput"
16
16
  import * as Stream from "effect/Stream"
17
17
  import * as MP from "multipasta"
18
18
  import * as FileSystem from "../../FileSystem.js"
19
- import type * as FormData from "../../Http/FormData.js"
20
19
  import * as IncomingMessage from "../../Http/IncomingMessage.js"
20
+ import type * as Multipart from "../../Http/Multipart.js"
21
21
  import * as Path from "../../Path.js"
22
22
 
23
23
  /** @internal */
24
- export const TypeId: FormData.TypeId = Symbol.for("@effect/platform/Http/FormData") as FormData.TypeId
24
+ export const TypeId: Multipart.TypeId = Symbol.for("@effect/platform/Http/Multipart") as Multipart.TypeId
25
25
 
26
26
  /** @internal */
27
- export const ErrorTypeId: FormData.ErrorTypeId = Symbol.for(
28
- "@effect/platform/Http/FormData/FormDataError"
29
- ) as FormData.ErrorTypeId
27
+ export const ErrorTypeId: Multipart.ErrorTypeId = Symbol.for(
28
+ "@effect/platform/Http/Multipart/MultipartError"
29
+ ) as Multipart.ErrorTypeId
30
30
 
31
31
  /** @internal */
32
- export const FormDataError = (reason: FormData.FormDataError["reason"], error: unknown): FormData.FormDataError =>
32
+ export const MultipartError = (reason: Multipart.MultipartError["reason"], error: unknown): Multipart.MultipartError =>
33
33
  Data.struct({
34
34
  [ErrorTypeId]: ErrorTypeId,
35
- _tag: "FormDataError",
35
+ _tag: "MultipartError",
36
36
  reason,
37
37
  error
38
38
  })
39
39
 
40
40
  /** @internal */
41
- export const isField = (u: unknown): u is FormData.Field =>
41
+ export const isField = (u: unknown): u is Multipart.Field =>
42
42
  Predicate.hasProperty(u, TypeId) && Predicate.isTagged(u, "Field")
43
43
 
44
44
  /** @internal */
45
45
  export const maxParts: FiberRef.FiberRef<Option.Option<number>> = globalValue(
46
- "@effect/platform/Http/FormData/maxParts",
46
+ "@effect/platform/Http/Multipart/maxParts",
47
47
  () => FiberRef.unsafeMake(Option.none<number>())
48
48
  )
49
49
 
@@ -55,7 +55,7 @@ export const withMaxParts = dual<
55
55
 
56
56
  /** @internal */
57
57
  export const maxFieldSize: FiberRef.FiberRef<FileSystem.Size> = globalValue(
58
- "@effect/platform/Http/FormData/maxFieldSize",
58
+ "@effect/platform/Http/Multipart/maxFieldSize",
59
59
  () => FiberRef.unsafeMake(FileSystem.Size(10 * 1024 * 1024))
60
60
  )
61
61
 
@@ -67,7 +67,7 @@ export const withMaxFieldSize = dual<
67
67
 
68
68
  /** @internal */
69
69
  export const maxFileSize: FiberRef.FiberRef<Option.Option<FileSystem.Size>> = globalValue(
70
- "@effect/platform/Http/FormData/maxFileSize",
70
+ "@effect/platform/Http/Multipart/maxFileSize",
71
71
  () => FiberRef.unsafeMake(Option.none<FileSystem.Size>())
72
72
  )
73
73
 
@@ -79,7 +79,7 @@ export const withMaxFileSize = dual<
79
79
 
80
80
  /** @internal */
81
81
  export const fieldMimeTypes: FiberRef.FiberRef<Chunk.Chunk<string>> = globalValue(
82
- "@effect/platform/Http/FormData/fieldMimeTypes",
82
+ "@effect/platform/Http/Multipart/fieldMimeTypes",
83
83
  () => FiberRef.unsafeMake<Chunk.Chunk<string>>(Chunk.make("application/json"))
84
84
  )
85
85
 
@@ -89,59 +89,58 @@ export const withFieldMimeTypes = dual<
89
89
  <R, E, A>(effect: Effect.Effect<R, E, A>, mimeTypes: ReadonlyArray<string>) => Effect.Effect<R, E, A>
90
90
  >(2, (effect, mimeTypes) => Effect.locally(effect, fieldMimeTypes, Chunk.fromIterable(mimeTypes)))
91
91
 
92
+ const fileSchema: Schema.Schema<Multipart.PersistedFile, Multipart.PersistedFile> = Schema.struct({
93
+ [TypeId]: Schema.uniqueSymbol(TypeId),
94
+ _tag: Schema.literal("PersistedFile"),
95
+ key: Schema.string,
96
+ name: Schema.string,
97
+ contentType: Schema.string,
98
+ path: Schema.string
99
+ })
100
+
92
101
  /** @internal */
93
- export const filesSchema: Schema.Schema<ReadonlyArray<FormData.PersistedFile>, ReadonlyArray<FormData.PersistedFile>> =
94
- Schema
95
- .array(
96
- pipe(
97
- Schema.object,
98
- Schema.filter(
99
- (file): file is FormData.PersistedFile => TypeId in file && "_tag" in file && file._tag === "PersistedFile"
100
- )
101
- ) as any as Schema.Schema<FormData.PersistedFile, FormData.PersistedFile>
102
- )
102
+ export const filesSchema: Schema.Schema<
103
+ ReadonlyArray<Multipart.PersistedFile>,
104
+ ReadonlyArray<Multipart.PersistedFile>
105
+ > = Schema.array(fileSchema)
103
106
 
104
107
  /** @internal */
105
- export const schemaPersisted = <I extends FormData.PersistedFormData, A>(
108
+ export const schemaPersisted = <I extends Multipart.Persisted, A>(
106
109
  schema: Schema.Schema<I, A>
107
110
  ) => {
108
111
  const parse = Schema.parse(schema)
109
- return (formData: FormData.PersistedFormData) => parse(formData)
112
+ return (persisted: Multipart.Persisted) => parse(persisted)
110
113
  }
111
114
 
112
115
  /** @internal */
113
116
  export const schemaJson = <I, A>(schema: Schema.Schema<I, A>): {
114
117
  (
115
118
  field: string
116
- ): (formData: FormData.PersistedFormData) => Effect.Effect<never, FormData.FormDataError | ParseResult.ParseError, A>
119
+ ): (persisted: Multipart.Persisted) => Effect.Effect<never, ParseResult.ParseError, A>
117
120
  (
118
- formData: FormData.PersistedFormData,
121
+ persisted: Multipart.Persisted,
119
122
  field: string
120
- ): Effect.Effect<never, FormData.FormDataError | ParseResult.ParseError, A>
123
+ ): Effect.Effect<never, ParseResult.ParseError, A>
121
124
  } => {
122
- const parse = Schema.parse(schema)
125
+ const fromJson = Schema.parseJson(schema)
123
126
  return dual<
124
127
  (
125
128
  field: string
126
129
  ) => (
127
- formData: FormData.PersistedFormData
128
- ) => Effect.Effect<never, FormData.FormDataError | ParseResult.ParseError, A>,
130
+ persisted: Multipart.Persisted
131
+ ) => Effect.Effect<never, ParseResult.ParseError, A>,
129
132
  (
130
- formData: FormData.PersistedFormData,
133
+ persisted: Multipart.Persisted,
131
134
  field: string
132
- ) => Effect.Effect<never, FormData.FormDataError | ParseResult.ParseError, A>
133
- >(2, (formData, field) =>
134
- pipe(
135
- Effect.succeed(formData[field]),
136
- Effect.filterOrFail(
137
- isField,
138
- () => FormDataError("Parse", `schemaJson: was not a field`)
139
- ),
140
- Effect.tryMap({
141
- try: (field) => JSON.parse(field.value),
142
- catch: (error) => FormDataError("Parse", `schemaJson: field was not valid json: ${error}`)
143
- }),
144
- Effect.flatMap(parse)
135
+ ) => Effect.Effect<never, ParseResult.ParseError, A>
136
+ >(2, (persisted, field) =>
137
+ Effect.map(
138
+ Schema.parse(
139
+ Schema.struct({
140
+ [field]: fromJson
141
+ })
142
+ )(persisted),
143
+ (_) => _[field]
145
144
  ))
146
145
  }
147
146
 
@@ -181,8 +180,8 @@ export const makeChannel = <IE>(
181
180
  IE,
182
181
  Chunk.Chunk<Uint8Array>,
183
182
  unknown,
184
- FormData.FormDataError | IE,
185
- Chunk.Chunk<FormData.Part>,
183
+ Multipart.MultipartError | IE,
184
+ Chunk.Chunk<Multipart.Part>,
186
185
  unknown
187
186
  > =>
188
187
  Channel.acquireUseRelease(
@@ -202,13 +201,13 @@ const makeFromQueue = <IE>(
202
201
  IE,
203
202
  Chunk.Chunk<Uint8Array>,
204
203
  unknown,
205
- IE | FormData.FormDataError,
206
- Chunk.Chunk<FormData.Part>,
204
+ IE | Multipart.MultipartError,
205
+ Chunk.Chunk<Multipart.Part>,
207
206
  unknown
208
207
  > =>
209
208
  Channel.suspend(() => {
210
- let error = Option.none<Cause.Cause<IE | FormData.FormDataError>>()
211
- let partsBuffer: Array<FormData.Part> = []
209
+ let error = Option.none<Cause.Cause<IE | Multipart.MultipartError>>()
210
+ let partsBuffer: Array<Multipart.Part> = []
212
211
  let partsFinished = false
213
212
 
214
213
  const input: AsyncInput.AsyncInputProducer<IE, Chunk.Chunk<Uint8Array>, unknown> = {
@@ -293,8 +292,8 @@ const makeFromQueue = <IE>(
293
292
  unknown,
294
293
  unknown,
295
294
  unknown,
296
- IE | FormData.FormDataError,
297
- Chunk.Chunk<FormData.Part>,
295
+ IE | Multipart.MultipartError,
296
+ Chunk.Chunk<Multipart.Part>,
298
297
  void
299
298
  > = Channel.suspend(() => {
300
299
  if (error._tag === "Some") {
@@ -308,32 +307,32 @@ const makeFromQueue = <IE>(
308
307
  return Channel.embedInput(partsChannel, input)
309
308
  })
310
309
 
311
- function convertError(error: MP.MultipartError): FormData.FormDataError {
310
+ function convertError(error: MP.MultipartError): Multipart.MultipartError {
312
311
  switch (error._tag) {
313
312
  case "ReachedLimit": {
314
313
  switch (error.limit) {
315
314
  case "MaxParts": {
316
- return FormDataError("TooManyParts", error)
315
+ return MultipartError("TooManyParts", error)
317
316
  }
318
317
  case "MaxFieldSize": {
319
- return FormDataError("FieldTooLarge", error)
318
+ return MultipartError("FieldTooLarge", error)
320
319
  }
321
320
  case "MaxPartSize": {
322
- return FormDataError("FileTooLarge", error)
321
+ return MultipartError("FileTooLarge", error)
323
322
  }
324
323
  case "MaxTotalSize": {
325
- return FormDataError("BodyTooLarge", error)
324
+ return MultipartError("BodyTooLarge", error)
326
325
  }
327
326
  }
328
327
  }
329
328
  default: {
330
- return FormDataError("Parse", error)
329
+ return MultipartError("Parse", error)
331
330
  }
332
331
  }
333
332
  }
334
333
 
335
- class FieldImpl implements FormData.Field {
336
- readonly [TypeId]: FormData.TypeId
334
+ class FieldImpl implements Multipart.Field {
335
+ readonly [TypeId]: Multipart.TypeId
337
336
  readonly _tag = "Field"
338
337
 
339
338
  constructor(
@@ -345,13 +344,13 @@ class FieldImpl implements FormData.Field {
345
344
  }
346
345
  }
347
346
 
348
- class FileImpl implements FormData.File {
347
+ class FileImpl implements Multipart.File {
349
348
  readonly _tag = "File"
350
- readonly [TypeId]: FormData.TypeId
349
+ readonly [TypeId]: Multipart.TypeId
351
350
  readonly key: string
352
351
  readonly name: string
353
352
  readonly contentType: string
354
- readonly content: Stream.Stream<never, FormData.FormDataError, Uint8Array>
353
+ readonly content: Stream.Stream<never, Multipart.MultipartError, Uint8Array>
355
354
 
356
355
  constructor(
357
356
  info: MP.PartInfo,
@@ -365,21 +364,21 @@ class FileImpl implements FormData.File {
365
364
  }
366
365
  }
367
366
 
368
- const defaultWriteFile = (path: string, file: FormData.File) =>
367
+ const defaultWriteFile = (path: string, file: Multipart.File) =>
369
368
  Effect.flatMap(
370
369
  FileSystem.FileSystem,
371
370
  (fs) =>
372
371
  Effect.mapError(
373
372
  Stream.run(file.content, fs.sink(path)),
374
- (error) => FormDataError("InternalError", error)
373
+ (error) => MultipartError("InternalError", error)
375
374
  )
376
375
  )
377
376
 
378
377
  /** @internal */
379
- export const formData = (
380
- stream: Stream.Stream<never, FormData.FormDataError, FormData.Part>,
378
+ export const toPersisted = (
379
+ stream: Stream.Stream<never, Multipart.MultipartError, Multipart.Part>,
381
380
  writeFile = defaultWriteFile
382
- ): Effect.Effect<FileSystem.FileSystem | Path.Path | Scope.Scope, FormData.FormDataError, FormData.PersistedFormData> =>
381
+ ): Effect.Effect<FileSystem.FileSystem | Path.Path | Scope.Scope, Multipart.MultipartError, Multipart.Persisted> =>
383
382
  pipe(
384
383
  Effect.Do,
385
384
  Effect.bind("fs", () => FileSystem.FileSystem),
@@ -388,18 +387,18 @@ export const formData = (
388
387
  Effect.flatMap(({ dir, path: path_ }) =>
389
388
  Stream.runFoldEffect(
390
389
  stream,
391
- Object.create(null) as Record<string, Array<FormData.PersistedFile> | string>,
392
- (formData, part) => {
390
+ Object.create(null) as Record<string, Array<Multipart.PersistedFile> | string>,
391
+ (persisted, part) => {
393
392
  if (part._tag === "Field") {
394
- formData[part.key] = part.value
395
- return Effect.succeed(formData)
393
+ persisted[part.key] = part.value
394
+ return Effect.succeed(persisted)
396
395
  }
397
396
  const file = part
398
397
  const path = path_.join(dir, path_.basename(file.name).slice(-128))
399
- if (!Array.isArray(formData[part.key])) {
400
- formData[part.key] = []
398
+ if (!Array.isArray(persisted[part.key])) {
399
+ persisted[part.key] = []
401
400
  }
402
- ;(formData[part.key] as Array<FormData.PersistedFile>).push(
401
+ ;(persisted[part.key] as Array<Multipart.PersistedFile>).push(
403
402
  new PersistedFileImpl(
404
403
  file.key,
405
404
  file.name,
@@ -407,18 +406,18 @@ export const formData = (
407
406
  path
408
407
  )
409
408
  )
410
- return Effect.as(writeFile(path, file), formData)
409
+ return Effect.as(writeFile(path, file), persisted)
411
410
  }
412
411
  )
413
412
  ),
414
413
  Effect.catchTags({
415
- SystemError: (err) => Effect.fail(FormDataError("InternalError", err)),
416
- BadArgument: (err) => Effect.fail(FormDataError("InternalError", err))
414
+ SystemError: (err) => Effect.fail(MultipartError("InternalError", err)),
415
+ BadArgument: (err) => Effect.fail(MultipartError("InternalError", err))
417
416
  })
418
417
  )
419
418
 
420
- class PersistedFileImpl implements FormData.PersistedFile {
421
- readonly [TypeId]: FormData.TypeId
419
+ class PersistedFileImpl implements Multipart.PersistedFile {
420
+ readonly [TypeId]: Multipart.TypeId
422
421
  readonly _tag = "PersistedFile"
423
422
 
424
423
  constructor(