diff --git a/.changeset/funny-beans-peel.md b/.changeset/funny-beans-peel.md
new file mode 100644
index 00000000..aa153891
--- /dev/null
+++ b/.changeset/funny-beans-peel.md
@@ -0,0 +1,7 @@
+---
+"@effect/platform-node": minor
+"@effect/platform-bun": minor
+"@effect/platform": minor
+---
+
+rename server FormData module to Multipart
diff --git a/docs/platform-bun/HttpServer.ts.md b/docs/platform-bun/HttpServer.ts.md
index 02df2eb6..7a9accdb 100644
--- a/docs/platform-bun/HttpServer.ts.md
+++ b/docs/platform-bun/HttpServer.ts.md
@@ -17,9 +17,9 @@ Added in v1.0.0
- [body](#body)
- [error](#error)
- [etag](#etag)
- - [formData](#formdata)
- [headers](#headers)
- [middleware](#middleware)
+ - [multipart](#multipart)
- [request](#request)
- [response](#response)
- [router](#router)
@@ -82,44 +82,44 @@ Added in v1.0.0
- Docs: [Http/Etag](https://effect-ts.github.io/platform/platform-node/Http/Etag.ts.html)
- Module: `@effect/platform-node/Http/Etag`
-## formData
+## headers
**Signature**
```ts
-export declare const formData: typeof formData
+export declare const headers: typeof headers
```
Added in v1.0.0
-- Docs: [Http/FormData](https://effect-ts.github.io/platform/platform-node/Http/FormData.ts.html)
-- Module: `@effect/platform-node/Http/FormData`
+- Docs: [Http/Headers](https://effect-ts.github.io/platform/platform/Http/Headers.ts.html)
+- Module: `@effect/platform/Http/Headers`
-## headers
+## middleware
**Signature**
```ts
-export declare const headers: typeof headers
+export declare const middleware: typeof middleware
```
Added in v1.0.0
-- Docs: [Http/Headers](https://effect-ts.github.io/platform/platform/Http/Headers.ts.html)
-- Module: `@effect/platform/Http/Headers`
+- Docs: [Http/Middleware](https://effect-ts.github.io/platform/platform/Http/Middleware.ts.html)
+- Module: `@effect/platform/Http/Middleware`
-## middleware
+## multipart
**Signature**
```ts
-export declare const middleware: typeof middleware
+export declare const multipart: typeof multipart
```
Added in v1.0.0
-- Docs: [Http/Middleware](https://effect-ts.github.io/platform/platform/Http/Middleware.ts.html)
-- Module: `@effect/platform/Http/Middleware`
+- Docs: [Http/Multipart](https://effect-ts.github.io/platform/platform-node/Http/Multipart.ts.html)
+- Module: `@effect/platform-node/Http/Multipart`
## request
diff --git a/docs/platform-node/Http/FormData.ts.md b/docs/platform-node/Http/Multipart.ts.md
similarity index 50%
rename from docs/platform-node/Http/FormData.ts.md
rename to docs/platform-node/Http/Multipart.ts.md
index 61f456ea..48b97182 100644
--- a/docs/platform-node/Http/FormData.ts.md
+++ b/docs/platform-node/Http/Multipart.ts.md
@@ -1,40 +1,40 @@
---
-title: Http/FormData.ts
+title: Http/Multipart.ts
nav_order: 7
parent: "@effect/platform-node"
---
-## FormData overview
+## Multipart overview
Added in v1.0.0
-Also includes exports from [`@effect/platform/Http/FormData`](https://effect-ts.github.io/platform/platform/Http/FormData.ts.html).
+Also includes exports from [`@effect/platform/Http/Multipart`](https://effect-ts.github.io/platform/platform/Http/Multipart.ts.html).
---
Table of contents
- [constructors](#constructors)
- - [formData](#formdata)
+ - [persisted](#persisted)
- [stream](#stream)
- [conversions](#conversions)
- [fileToReadable](#filetoreadable)
- [exports](#exports)
- - [From "@effect/platform/Http/FormData"](#from-effectplatformhttpformdata)
+ - [From "@effect/platform/Http/Multipart"](#from-effectplatformhttpmultipart)
---
# constructors
-## formData
+## persisted
**Signature**
```ts
-export declare const formData: (
+export declare const persisted: (
source: Readable,
headers: IncomingHttpHeaders
-) => Effect.Effect
+) => Effect.Effect
```
Added in v1.0.0
@@ -47,7 +47,7 @@ Added in v1.0.0
export declare const stream: (
source: Readable,
headers: IncomingHttpHeaders
-) => Stream.Stream
+) => Stream.Stream
```
Added in v1.0.0
@@ -59,21 +59,21 @@ Added in v1.0.0
**Signature**
```ts
-export declare const fileToReadable: (file: FormData.File) => Readable
+export declare const fileToReadable: (file: Multipart.File) => Readable
```
Added in v1.0.0
# exports
-## From "@effect/platform/Http/FormData"
+## From "@effect/platform/Http/Multipart"
-Re-exports all named exports from the "@effect/platform/Http/FormData" module.
+Re-exports all named exports from the "@effect/platform/Http/Multipart" module.
**Signature**
```ts
-export * from "@effect/platform/Http/FormData"
+export * from "@effect/platform/Http/Multipart"
```
Added in v1.0.0
diff --git a/docs/platform-node/HttpServer.ts.md b/docs/platform-node/HttpServer.ts.md
index 9fdca599..9c96a0cc 100644
--- a/docs/platform-node/HttpServer.ts.md
+++ b/docs/platform-node/HttpServer.ts.md
@@ -17,9 +17,9 @@ Added in v1.0.0
- [body](#body)
- [error](#error)
- [etag](#etag)
- - [formData](#formdata)
- [headers](#headers)
- [middleware](#middleware)
+ - [multipart](#multipart)
- [request](#request)
- [response](#response)
- [router](#router)
@@ -82,44 +82,44 @@ Added in v1.0.0
- Docs: [Http/Etag](https://effect-ts.github.io/platform/platform-node/Http/Etag.ts.html)
- Module: `@effect/platform-node/Http/Etag`
-## formData
+## headers
**Signature**
```ts
-export declare const formData: typeof formData
+export declare const headers: typeof headers
```
Added in v1.0.0
-- Docs: [Http/FormData](https://effect-ts.github.io/platform/platform-node/Http/FormData.ts.html)
-- Module: `@effect/platform-node/Http/FormData`
+- Docs: [Http/Headers](https://effect-ts.github.io/platform/platform/Http/Headers.ts.html)
+- Module: `@effect/platform/Http/Headers`
-## headers
+## middleware
**Signature**
```ts
-export declare const headers: typeof headers
+export declare const middleware: typeof middleware
```
Added in v1.0.0
-- Docs: [Http/Headers](https://effect-ts.github.io/platform/platform/Http/Headers.ts.html)
-- Module: `@effect/platform/Http/Headers`
+- Docs: [Http/Middleware](https://effect-ts.github.io/platform/platform/Http/Middleware.ts.html)
+- Module: `@effect/platform/Http/Middleware`
-## middleware
+## multipart
**Signature**
```ts
-export declare const middleware: typeof middleware
+export declare const multipart: typeof multipart
```
Added in v1.0.0
-- Docs: [Http/Middleware](https://effect-ts.github.io/platform/platform/Http/Middleware.ts.html)
-- Module: `@effect/platform/Http/Middleware`
+- Docs: [Http/Multipart](https://effect-ts.github.io/platform/platform-node/Http/Multipart.ts.html)
+- Module: `@effect/platform-node/Http/Multipart`
## request
diff --git a/docs/platform/Http/Headers.ts.md b/docs/platform/Http/Headers.ts.md
index b38814e3..181b0be0 100644
--- a/docs/platform/Http/Headers.ts.md
+++ b/docs/platform/Http/Headers.ts.md
@@ -1,6 +1,6 @@
---
title: Http/Headers.ts
-nav_order: 14
+nav_order: 13
parent: "@effect/platform"
---
diff --git a/docs/platform/Http/IncomingMessage.ts.md b/docs/platform/Http/IncomingMessage.ts.md
index 220a7647..9c03d4b0 100644
--- a/docs/platform/Http/IncomingMessage.ts.md
+++ b/docs/platform/Http/IncomingMessage.ts.md
@@ -1,6 +1,6 @@
---
title: Http/IncomingMessage.ts
-nav_order: 15
+nav_order: 14
parent: "@effect/platform"
---
diff --git a/docs/platform/Http/Method.ts.md b/docs/platform/Http/Method.ts.md
index d754b858..e1fa3445 100644
--- a/docs/platform/Http/Method.ts.md
+++ b/docs/platform/Http/Method.ts.md
@@ -1,6 +1,6 @@
---
title: Http/Method.ts
-nav_order: 16
+nav_order: 15
parent: "@effect/platform"
---
diff --git a/docs/platform/Http/Middleware.ts.md b/docs/platform/Http/Middleware.ts.md
index ca3b9805..f02fa0ad 100644
--- a/docs/platform/Http/Middleware.ts.md
+++ b/docs/platform/Http/Middleware.ts.md
@@ -1,6 +1,6 @@
---
title: Http/Middleware.ts
-nav_order: 17
+nav_order: 16
parent: "@effect/platform"
---
diff --git a/docs/platform/Http/FormData.ts.md b/docs/platform/Http/Multipart.ts.md
similarity index 82%
rename from docs/platform/Http/FormData.ts.md
rename to docs/platform/Http/Multipart.ts.md
index d2db0057..da0e72dd 100644
--- a/docs/platform/Http/FormData.ts.md
+++ b/docs/platform/Http/Multipart.ts.md
@@ -1,10 +1,10 @@
---
-title: Http/FormData.ts
-nav_order: 13
+title: Http/Multipart.ts
+nav_order: 17
parent: "@effect/platform"
---
-## FormData overview
+## Multipart overview
Added in v1.0.0
@@ -13,12 +13,12 @@ Added in v1.0.0
Table of contents
- [constructors](#constructors)
- - [formData](#formdata)
- [makeChannel](#makechannel)
- [makeConfig](#makeconfig)
+ - [toPersisted](#topersisted)
- [errors](#errors)
- - [FormDataError](#formdataerror)
- - [FormDataError (interface)](#formdataerror-interface)
+ - [MultipartError](#multiparterror)
+ - [MultipartError (interface)](#multiparterror-interface)
- [fiber refs](#fiber-refs)
- [fieldMimeTypes](#fieldmimetypes)
- [maxFieldSize](#maxfieldsize)
@@ -32,8 +32,8 @@ Added in v1.0.0
- [Field (interface)](#field-interface)
- [File (interface)](#file-interface)
- [Part (type alias)](#part-type-alias)
+ - [Persisted (interface)](#persisted-interface)
- [PersistedFile (interface)](#persistedfile-interface)
- - [PersistedFormData (interface)](#persistedformdata-interface)
- [refinements](#refinements)
- [isField](#isfield)
- [schema](#schema)
@@ -53,62 +53,62 @@ Added in v1.0.0
# constructors
-## formData
+## makeChannel
**Signature**
```ts
-export declare const formData: (
- stream: Stream.Stream,
- writeFile?: ((path: string, file: File) => Effect.Effect) | undefined
-) => Effect.Effect
+export declare const makeChannel: (
+ headers: Record,
+ bufferSize?: number
+) => Channel.Channel, unknown, MultipartError | IE, Chunk.Chunk, unknown>
```
Added in v1.0.0
-## makeChannel
+## makeConfig
**Signature**
```ts
-export declare const makeChannel: (
- headers: Record,
- bufferSize?: number
-) => Channel.Channel, unknown, FormDataError | IE, Chunk.Chunk, unknown>
+export declare const makeConfig: (headers: Record) => Effect.Effect
```
Added in v1.0.0
-## makeConfig
+## toPersisted
**Signature**
```ts
-export declare const makeConfig: (headers: Record) => Effect.Effect
+export declare const toPersisted: (
+ stream: Stream.Stream,
+ writeFile?: ((path: string, file: File) => Effect.Effect) | undefined
+) => Effect.Effect
```
Added in v1.0.0
# errors
-## FormDataError
+## MultipartError
**Signature**
```ts
-export declare const FormDataError: (reason: FormDataError["reason"], error: unknown) => FormDataError
+export declare const MultipartError: (reason: MultipartError["reason"], error: unknown) => MultipartError
```
Added in v1.0.0
-## FormDataError (interface)
+## MultipartError (interface)
**Signature**
```ts
-export interface FormDataError extends Data.Case {
+export interface MultipartError extends Data.Case {
readonly [ErrorTypeId]: ErrorTypeId
- readonly _tag: "FormDataError"
+ readonly _tag: "MultipartError"
readonly reason: "FileTooLarge" | "FieldTooLarge" | "BodyTooLarge" | "TooManyParts" | "InternalError" | "Parse"
readonly error: unknown
}
@@ -237,7 +237,7 @@ export interface File extends Part.Proto {
readonly key: string
readonly name: string
readonly contentType: string
- readonly content: Stream.Stream
+ readonly content: Stream.Stream
}
```
@@ -253,29 +253,29 @@ export type Part = Field | File
Added in v1.0.0
-## PersistedFile (interface)
+## Persisted (interface)
**Signature**
```ts
-export interface PersistedFile extends Part.Proto {
- readonly _tag: "PersistedFile"
- readonly key: string
- readonly name: string
- readonly contentType: string
- readonly path: string
+export interface Persisted {
+ readonly [key: string]: ReadonlyArray | string
}
```
Added in v1.0.0
-## PersistedFormData (interface)
+## PersistedFile (interface)
**Signature**
```ts
-export interface PersistedFormData {
- readonly [key: string]: ReadonlyArray | string
+export interface PersistedFile extends Part.Proto {
+ readonly _tag: "PersistedFile"
+ readonly key: string
+ readonly name: string
+ readonly contentType: string
+ readonly path: string
}
```
@@ -313,8 +313,8 @@ Added in v1.0.0
export declare const schemaJson: (
schema: Schema.Schema
) => {
- (field: string): (formData: PersistedFormData) => Effect.Effect
- (formData: PersistedFormData, field: string): Effect.Effect
+ (field: string): (persisted: Persisted) => Effect.Effect
+ (persisted: Persisted, field: string): Effect.Effect
}
```
@@ -325,9 +325,9 @@ Added in v1.0.0
**Signature**
```ts
-export declare const schemaPersisted: (
+export declare const schemaPersisted: (
schema: Schema.Schema
-) => (formData: PersistedFormData) => Effect.Effect
+) => (persisted: Persisted) => Effect.Effect
```
Added in v1.0.0
diff --git a/docs/platform/Http/ServerRequest.ts.md b/docs/platform/Http/ServerRequest.ts.md
index ee2e8b28..78d8f17f 100644
--- a/docs/platform/Http/ServerRequest.ts.md
+++ b/docs/platform/Http/ServerRequest.ts.md
@@ -13,7 +13,7 @@ Added in v1.0.0
Table of contents
- [accessors](#accessors)
- - [persistedFormData](#persistedformdata)
+ - [persistedMultipart](#persistedmultipart)
- [context](#context)
- [ServerRequest](#serverrequest)
- [conversions](#conversions)
@@ -23,10 +23,11 @@ Added in v1.0.0
- [models](#models)
- [ServerRequest (interface)](#serverrequest-interface)
- [schema](#schema)
+ - [schemaBodyForm](#schemabodyform)
- [schemaBodyJson](#schemabodyjson)
+ - [schemaBodyMultipart](#schemabodymultipart)
+ - [schemaBodyMultipartJson](#schemabodymultipartjson)
- [schemaBodyUrlParams](#schemabodyurlparams)
- - [schemaFormData](#schemaformdata)
- - [schemaFormDataJson](#schemaformdatajson)
- [schemaHeaders](#schemaheaders)
- [type ids](#type-ids)
- [TypeId](#typeid)
@@ -36,14 +37,14 @@ Added in v1.0.0
# accessors
-## persistedFormData
+## persistedMultipart
**Signature**
```ts
-export declare const persistedFormData: Effect.Effect<
+export declare const persistedMultipart: Effect.Effect<
Scope.Scope | Path.Path | FileSystem.FileSystem | ServerRequest,
- FormData.FormDataError,
+ Multipart.MultipartError,
unknown
>
```
@@ -100,12 +101,12 @@ export interface ServerRequest extends IncomingMessage.IncomingMessage
- readonly formDataStream: Stream.Stream
+ readonly multipartStream: Stream.Stream
readonly modify: (options: {
readonly url?: string
@@ -119,64 +120,80 @@ Added in v1.0.0
# schema
-## schemaBodyJson
+## schemaBodyForm
**Signature**
```ts
-export declare const schemaBodyJson: (
+export declare const schemaBodyForm: (
schema: Schema.Schema
-) => Effect.Effect
+) => Effect.Effect<
+ Scope.Scope | Path.Path | FileSystem.FileSystem | ServerRequest,
+ Multipart.MultipartError | ParseResult.ParseError | Error.RequestError,
+ A
+>
```
Added in v1.0.0
-## schemaBodyUrlParams
+## schemaBodyJson
**Signature**
```ts
-export declare const schemaBodyUrlParams: >, A>(
+export declare const schemaBodyJson: (
schema: Schema.Schema
) => Effect.Effect
```
Added in v1.0.0
-## schemaFormData
+## schemaBodyMultipart
**Signature**
```ts
-export declare const schemaFormData: (
+export declare const schemaBodyMultipart: (
schema: Schema.Schema
) => Effect.Effect<
Scope.Scope | Path.Path | FileSystem.FileSystem | ServerRequest,
- FormData.FormDataError | ParseResult.ParseError,
+ Multipart.MultipartError | ParseResult.ParseError,
A
>
```
Added in v1.0.0
-## schemaFormDataJson
+## schemaBodyMultipartJson
**Signature**
```ts
-export declare const schemaFormDataJson: (
+export declare const schemaBodyMultipartJson: (
schema: Schema.Schema
) => (
field: string
) => Effect.Effect<
Scope.Scope | Path.Path | FileSystem.FileSystem | ServerRequest,
- FormData.FormDataError | ParseResult.ParseError | Error.RequestError,
+ Multipart.MultipartError | ParseResult.ParseError | Error.RequestError,
A
>
```
Added in v1.0.0
+## schemaBodyUrlParams
+
+**Signature**
+
+```ts
+export declare const schemaBodyUrlParams: >, A>(
+ schema: Schema.Schema
+) => Effect.Effect
+```
+
+Added in v1.0.0
+
## schemaHeaders
**Signature**
diff --git a/docs/platform/HttpServer.ts.md b/docs/platform/HttpServer.ts.md
index 1f925319..3759aedf 100644
--- a/docs/platform/HttpServer.ts.md
+++ b/docs/platform/HttpServer.ts.md
@@ -16,9 +16,9 @@ Added in v1.0.0
- [app](#app)
- [body](#body)
- [error](#error)
- - [formData](#formdata)
- [headers](#headers)
- [middleware](#middleware)
+ - [multipart](#multipart)
- [request](#request)
- [response](#response)
- [router](#router)
@@ -67,44 +67,44 @@ Added in v1.0.0
- Docs: [Http/ServerError](https://effect-ts.github.io/platform/platform/Http/ServerError.html)
- Module: `@effect/platform/Http/ServerError`
-## formData
+## headers
**Signature**
```ts
-export declare const formData: typeof formData
+export declare const headers: typeof headers
```
Added in v1.0.0
-- Docs: [Http/FormData](https://effect-ts.github.io/platform/platform/Http/FormData.html)
-- Module: `@effect/platform/Http/FormData`
+- Docs: [Http/Headers](https://effect-ts.github.io/platform/platform/Http/Headers.html)
+- Module: `@effect/platform/Http/Headers`
-## headers
+## middleware
**Signature**
```ts
-export declare const headers: typeof headers
+export declare const middleware: typeof middleware
```
Added in v1.0.0
-- Docs: [Http/Headers](https://effect-ts.github.io/platform/platform/Http/Headers.html)
-- Module: `@effect/platform/Http/Headers`
+- Docs: [Http/Middleware](https://effect-ts.github.io/platform/platform/Http/Middleware.html)
+- Module: `@effect/platform/Http/Middleware`
-## middleware
+## multipart
**Signature**
```ts
-export declare const middleware: typeof middleware
+export declare const multipart: typeof multipart
```
Added in v1.0.0
-- Docs: [Http/Middleware](https://effect-ts.github.io/platform/platform/Http/Middleware.html)
-- Module: `@effect/platform/Http/Middleware`
+- Docs: [Http/Multipart](https://effect-ts.github.io/platform/platform/Http/Multipart.html)
+- Module: `@effect/platform/Http/Multipart`
## request
diff --git a/packages/platform-bun/examples/http-router.ts b/packages/platform-bun/examples/http-router.ts
index c46f8a95..f3556b9f 100644
--- a/packages/platform-bun/examples/http-router.ts
+++ b/packages/platform-bun/examples/http-router.ts
@@ -20,8 +20,8 @@ const HttpLive = Http.router.empty.pipe(
Http.router.post(
"/upload",
Effect.gen(function*(_) {
- const data = yield* _(Http.request.schemaFormData(Schema.struct({
- files: Http.formData.filesSchema
+ const data = yield* _(Http.request.schemaBodyForm(Schema.struct({
+ files: Http.multipart.filesSchema
})))
console.log("got files", data.files)
return Http.response.empty()
diff --git a/packages/platform-bun/src/HttpServer.ts b/packages/platform-bun/src/HttpServer.ts
index 82444d53..e5420e2b 100644
--- a/packages/platform-bun/src/HttpServer.ts
+++ b/packages/platform-bun/src/HttpServer.ts
@@ -2,7 +2,7 @@
* @since 1.0.0
*/
import * as etag from "@effect/platform-node/Http/Etag"
-import * as formData from "@effect/platform-node/Http/FormData"
+import * as multipart from "@effect/platform-node/Http/Multipart"
import * as app from "@effect/platform/Http/App"
import * as body from "@effect/platform/Http/Body"
import * as headers from "@effect/platform/Http/Headers"
@@ -43,13 +43,6 @@ export {
* - Module: `@effect/platform-node/Http/Etag`
*/
etag,
- /**
- * @since 1.0.0
- *
- * - Docs: [Http/FormData](https://effect-ts.github.io/platform/platform-node/Http/FormData.ts.html)
- * - Module: `@effect/platform-node/Http/FormData`
- */
- formData,
/**
* @since 1.0.0
*
@@ -64,6 +57,13 @@ export {
* - Module: `@effect/platform/Http/Middleware`
*/
middleware,
+ /**
+ * @since 1.0.0
+ *
+ * - Docs: [Http/Multipart](https://effect-ts.github.io/platform/platform-node/Http/Multipart.ts.html)
+ * - Module: `@effect/platform-node/Http/Multipart`
+ */
+ multipart,
/**
* @since 1.0.0
*
diff --git a/packages/platform-bun/src/internal/http/server.ts b/packages/platform-bun/src/internal/http/server.ts
index 88e61ac1..f7143b34 100644
--- a/packages/platform-bun/src/internal/http/server.ts
+++ b/packages/platform-bun/src/internal/http/server.ts
@@ -1,5 +1,5 @@
///
-import * as FormData from "@effect/platform-node/Http/FormData"
+import * as Multipart from "@effect/platform-node/Http/Multipart"
import type * as FileSystem from "@effect/platform/FileSystem"
import * as App from "@effect/platform/Http/App"
import * as Headers from "@effect/platform/Http/Headers"
@@ -278,29 +278,29 @@ class ServerRequestImpl implements ServerRequest.ServerRequest {
}))
}
- private formDataEffect:
+ private multipartEffect:
| Effect.Effect<
Scope.Scope | FileSystem.FileSystem | Path.Path,
- FormData.FormDataError,
- FormData.PersistedFormData
+ Multipart.MultipartError,
+ Multipart.Persisted
>
| undefined
- get formData(): Effect.Effect<
+ get multipart(): Effect.Effect<
Scope.Scope | FileSystem.FileSystem | Path.Path,
- FormData.FormDataError,
- FormData.PersistedFormData
+ Multipart.MultipartError,
+ Multipart.Persisted
> {
- if (this.formDataEffect) {
- return this.formDataEffect
+ if (this.multipartEffect) {
+ return this.multipartEffect
}
- this.formDataEffect = Effect.runSync(Effect.cached(
- FormData.formData(Readable.fromWeb(this.source.body! as any), this.headers)
+ this.multipartEffect = Effect.runSync(Effect.cached(
+ Multipart.persisted(Readable.fromWeb(this.source.body! as any), this.headers)
))
- return this.formDataEffect
+ return this.multipartEffect
}
- get formDataStream(): Stream.Stream {
- return FormData.stream(Readable.fromWeb(this.source.body! as any), this.headers)
+ get multipartStream(): Stream.Stream {
+ return Multipart.stream(Readable.fromWeb(this.source.body! as any), this.headers)
}
private arrayBufferEffect: Effect.Effect | undefined
diff --git a/packages/platform-node/examples/http-router.ts b/packages/platform-node/examples/http-router.ts
index df01bbdc..b4bd8053 100644
--- a/packages/platform-node/examples/http-router.ts
+++ b/packages/platform-node/examples/http-router.ts
@@ -25,8 +25,8 @@ const HttpLive = Http.router.empty.pipe(
Http.router.post(
"/upload",
Effect.gen(function*(_) {
- const data = yield* _(Http.request.schemaFormData(Schema.struct({
- files: Http.formData.filesSchema
+ const data = yield* _(Http.request.schemaBodyForm(Schema.struct({
+ files: Http.multipart.filesSchema
})))
console.log("got files", data.files)
return Http.response.empty()
diff --git a/packages/platform-node/src/Http/FormData.ts b/packages/platform-node/src/Http/Multipart.ts
similarity index 56%
rename from packages/platform-node/src/Http/FormData.ts
rename to packages/platform-node/src/Http/Multipart.ts
index b021db7b..57d8b7e6 100644
--- a/packages/platform-node/src/Http/FormData.ts
+++ b/packages/platform-node/src/Http/Multipart.ts
@@ -1,22 +1,22 @@
/**
* @since 1.0.0
*
- * Also includes exports from [`@effect/platform/Http/FormData`](https://effect-ts.github.io/platform/platform/Http/FormData.ts.html).
+ * Also includes exports from [`@effect/platform/Http/Multipart`](https://effect-ts.github.io/platform/platform/Http/Multipart.ts.html).
*/
import type * as FileSystem from "@effect/platform/FileSystem"
-import type * as FormData from "@effect/platform/Http/FormData"
+import type * as Multipart from "@effect/platform/Http/Multipart"
import type * as Path from "@effect/platform/Path"
import type * as Effect from "effect/Effect"
import type * as Scope from "effect/Scope"
import type * as Stream from "effect/Stream"
import type { IncomingHttpHeaders } from "node:http"
import type { Readable } from "node:stream"
-import * as internal from "../internal/http/formData.js"
+import * as internal from "../internal/http/multipart.js"
/**
* @since 1.0.0
*/
-export * from "@effect/platform/Http/FormData"
+export * from "@effect/platform/Http/Multipart"
/**
* @since 1.0.0
@@ -25,23 +25,23 @@ export * from "@effect/platform/Http/FormData"
export const stream: (
source: Readable,
headers: IncomingHttpHeaders
-) => Stream.Stream = internal.stream
+) => Stream.Stream = internal.stream
/**
* @since 1.0.0
* @category constructors
*/
-export const formData: (
+export const persisted: (
source: Readable,
headers: IncomingHttpHeaders
) => Effect.Effect<
FileSystem.FileSystem | Path.Path | Scope.Scope,
- FormData.FormDataError,
- FormData.PersistedFormData
-> = internal.formData
+ Multipart.MultipartError,
+ Multipart.Persisted
+> = internal.persisted
/**
* @since 1.0.0
* @category conversions
*/
-export const fileToReadable: (file: FormData.File) => Readable = internal.fileToReadable
+export const fileToReadable: (file: Multipart.File) => Readable = internal.fileToReadable
diff --git a/packages/platform-node/src/HttpServer.ts b/packages/platform-node/src/HttpServer.ts
index c5e099ff..ef4edf15 100644
--- a/packages/platform-node/src/HttpServer.ts
+++ b/packages/platform-node/src/HttpServer.ts
@@ -10,7 +10,7 @@ import * as error from "@effect/platform/Http/ServerError"
import * as response from "@effect/platform/Http/ServerResponse"
import * as urlParams from "@effect/platform/Http/UrlParams"
import * as etag from "./Http/Etag.js"
-import * as formData from "./Http/FormData.js"
+import * as multipart from "./Http/Multipart.js"
import * as server from "./Http/Server.js"
import * as request from "./Http/ServerRequest.js"
@@ -43,13 +43,6 @@ export {
* - Module: `@effect/platform-node/Http/Etag`
*/
etag,
- /**
- * @since 1.0.0
- *
- * - Docs: [Http/FormData](https://effect-ts.github.io/platform/platform-node/Http/FormData.ts.html)
- * - Module: `@effect/platform-node/Http/FormData`
- */
- formData,
/**
* @since 1.0.0
*
@@ -64,6 +57,13 @@ export {
* - Module: `@effect/platform/Http/Middleware`
*/
middleware,
+ /**
+ * @since 1.0.0
+ *
+ * - Docs: [Http/Multipart](https://effect-ts.github.io/platform/platform-node/Http/Multipart.ts.html)
+ * - Module: `@effect/platform-node/Http/Multipart`
+ */
+ multipart,
/**
* @since 1.0.0
*
diff --git a/packages/platform-node/src/internal/http/formData.ts b/packages/platform-node/src/internal/http/multipart.ts
similarity index 60%
rename from packages/platform-node/src/internal/http/formData.ts
rename to packages/platform-node/src/internal/http/multipart.ts
index e398f146..bf159987 100644
--- a/packages/platform-node/src/internal/http/formData.ts
+++ b/packages/platform-node/src/internal/http/multipart.ts
@@ -1,4 +1,4 @@
-import * as FormData from "@effect/platform/Http/FormData"
+import * as Multipart from "@effect/platform/Http/Multipart"
import * as Effect from "effect/Effect"
import { pipe } from "effect/Function"
import * as Stream from "effect/Stream"
@@ -15,12 +15,12 @@ import * as NodeStream from "../stream.js"
export const stream = (
source: Readable,
headers: IncomingHttpHeaders
-): Stream.Stream =>
+): Stream.Stream =>
pipe(
- FormData.makeConfig(headers as any),
+ Multipart.makeConfig(headers as any),
Effect.map(
(config) =>
- NodeStream.fromReadable(() => {
+ NodeStream.fromReadable(() => {
const parser = MP.make(config)
source.pipe(parser)
return parser
@@ -31,21 +31,21 @@ export const stream = (
)
/** @internal */
-export const formData = (
+export const persisted = (
source: Readable,
headers: IncomingHttpHeaders
) =>
- FormData.formData(stream(source, headers), (path, file) =>
+ Multipart.toPersisted(stream(source, headers), (path, file) =>
Effect.tryPromise({
try: (signal) => NodeStreamP.pipeline((file as FileImpl).file, NFS.createWriteStream(path), { signal }),
- catch: (error) => FormData.FormDataError("InternalError", error)
+ catch: (error) => Multipart.MultipartError("InternalError", error)
}))
-const convertPart = (part: MP.Part): FormData.Part =>
+const convertPart = (part: MP.Part): Multipart.Part =>
part._tag === "Field" ? new FieldImpl(part.info, part.value) : new FileImpl(part)
-class FieldImpl implements FormData.Field {
- readonly [FormData.TypeId]: FormData.TypeId
+class FieldImpl implements Multipart.Field {
+ readonly [Multipart.TypeId]: Multipart.TypeId
readonly _tag = "Field"
readonly key: string
readonly contentType: string
@@ -55,53 +55,53 @@ class FieldImpl implements FormData.Field {
info: PartInfo,
value: Uint8Array
) {
- this[FormData.TypeId] = FormData.TypeId
+ this[Multipart.TypeId] = Multipart.TypeId
this.key = info.name
this.contentType = info.contentType
this.value = decodeField(info, value)
}
}
-class FileImpl implements FormData.File {
+class FileImpl implements Multipart.File {
readonly _tag = "File"
- readonly [FormData.TypeId]: FormData.TypeId
+ readonly [Multipart.TypeId]: Multipart.TypeId
readonly key: string
readonly name: string
readonly contentType: string
- readonly content: Stream.Stream
+ readonly content: Stream.Stream
constructor(readonly file: MP.FileStream) {
- this[FormData.TypeId] = FormData.TypeId
+ this[Multipart.TypeId] = Multipart.TypeId
this.key = file.info.name
this.name = file.filename ?? file.info.name
this.contentType = file.info.contentType
- this.content = NodeStream.fromReadable(() => file, (error) => FormData.FormDataError("InternalError", error))
+ this.content = NodeStream.fromReadable(() => file, (error) => Multipart.MultipartError("InternalError", error))
}
}
/** @internal */
-export const fileToReadable = (file: FormData.File): Readable => (file as FileImpl).file
+export const fileToReadable = (file: Multipart.File): Readable => (file as FileImpl).file
-function convertError(error: MultipartError): FormData.FormDataError {
+function convertError(error: MultipartError): Multipart.MultipartError {
switch (error._tag) {
case "ReachedLimit": {
switch (error.limit) {
case "MaxParts": {
- return FormData.FormDataError("TooManyParts", error)
+ return Multipart.MultipartError("TooManyParts", error)
}
case "MaxFieldSize": {
- return FormData.FormDataError("FieldTooLarge", error)
+ return Multipart.MultipartError("FieldTooLarge", error)
}
case "MaxPartSize": {
- return FormData.FormDataError("FileTooLarge", error)
+ return Multipart.MultipartError("FileTooLarge", error)
}
case "MaxTotalSize": {
- return FormData.FormDataError("BodyTooLarge", error)
+ return Multipart.MultipartError("BodyTooLarge", error)
}
}
}
default: {
- return FormData.FormDataError("Parse", error)
+ return Multipart.MultipartError("Parse", error)
}
}
}
diff --git a/packages/platform-node/src/internal/http/server.ts b/packages/platform-node/src/internal/http/server.ts
index d6bce70d..7a11b0d1 100644
--- a/packages/platform-node/src/internal/http/server.ts
+++ b/packages/platform-node/src/internal/http/server.ts
@@ -1,10 +1,10 @@
import * as FileSystem from "@effect/platform/FileSystem"
import * as App from "@effect/platform/Http/App"
-import type * as FormData from "@effect/platform/Http/FormData"
import type * as Headers from "@effect/platform/Http/Headers"
import * as IncomingMessage from "@effect/platform/Http/IncomingMessage"
import type { Method } from "@effect/platform/Http/Method"
import * as Middleware from "@effect/platform/Http/Middleware"
+import type * as Multipart from "@effect/platform/Http/Multipart"
import * as Server from "@effect/platform/Http/Server"
import * as Error from "@effect/platform/Http/ServerError"
import * as ServerRequest from "@effect/platform/Http/ServerRequest"
@@ -24,8 +24,8 @@ import type * as Net from "node:net"
import { Readable } from "node:stream"
import { pipeline } from "node:stream/promises"
import * as NodeSink from "../../Sink.js"
-import * as internalFormData from "./formData.js"
import { IncomingMessageImpl } from "./incomingMessage.js"
+import * as internalMultipart from "./multipart.js"
import * as internalPlatform from "./platform.js"
/** @internal */
@@ -207,29 +207,29 @@ class ServerRequestImpl extends IncomingMessageImpl implemen
return this.headersOverride
}
- private formDataEffect:
+ private multipartEffect:
| Effect.Effect<
Scope.Scope | FileSystem.FileSystem | Path.Path,
- FormData.FormDataError,
- FormData.PersistedFormData
+ Multipart.MultipartError,
+ Multipart.Persisted
>
| undefined
- get formData(): Effect.Effect<
+ get multipart(): Effect.Effect<
Scope.Scope | FileSystem.FileSystem | Path.Path,
- FormData.FormDataError,
- FormData.PersistedFormData
+ Multipart.MultipartError,
+ Multipart.Persisted
> {
- if (this.formDataEffect) {
- return this.formDataEffect
+ if (this.multipartEffect) {
+ return this.multipartEffect
}
- this.formDataEffect = Effect.runSync(Effect.cached(
- internalFormData.formData(this.source, this.source.headers)
+ this.multipartEffect = Effect.runSync(Effect.cached(
+ internalMultipart.persisted(this.source, this.source.headers)
))
- return this.formDataEffect
+ return this.multipartEffect
}
- get formDataStream(): Stream.Stream {
- return internalFormData.stream(this.source, this.source.headers)
+ get multipartStream(): Stream.Stream {
+ return internalMultipart.stream(this.source, this.source.headers)
}
toString(): string {
diff --git a/packages/platform-node/test/HttpServer.test.ts b/packages/platform-node/test/HttpServer.test.ts
index 2b4b3560..adc57217 100644
--- a/packages/platform-node/test/HttpServer.test.ts
+++ b/packages/platform-node/test/HttpServer.test.ts
@@ -82,7 +82,7 @@ describe("HttpServer", () => {
"/upload",
Effect.gen(function*(_) {
const request = yield* _(Http.request.ServerRequest)
- const formData = yield* _(request.formData)
+ const formData = yield* _(request.multipart)
const part = formData.file
assert(typeof part !== "string")
const file = part[0]
@@ -103,15 +103,15 @@ describe("HttpServer", () => {
expect(result).toEqual({ ok: true })
}).pipe(Effect.scoped, runPromise))
- it("schemaFormData", () =>
+ it("schemaBodyForm", () =>
Effect.gen(function*(_) {
yield* _(
Http.router.empty,
Http.router.post(
"/upload",
Effect.gen(function*(_) {
- const files = yield* _(Http.request.schemaFormData(Schema.struct({
- file: Http.formData.filesSchema,
+ const files = yield* _(Http.request.schemaBodyForm(Schema.struct({
+ file: Http.multipart.filesSchema,
test: Schema.string
})))
expect(files).toHaveProperty("file")
@@ -140,16 +140,16 @@ describe("HttpServer", () => {
"/upload",
Effect.gen(function*(_) {
const request = yield* _(Http.request.ServerRequest)
- yield* _(request.formData)
+ yield* _(request.multipart)
return Http.response.empty()
}).pipe(Effect.scoped)
),
- Effect.catchTag("FormDataError", (error) =>
+ Effect.catchTag("MultipartError", (error) =>
error.reason === "FileTooLarge" ?
Http.response.empty({ status: 413 }) :
Effect.fail(error)),
Http.server.serveEffect(),
- Http.formData.withMaxFileSize(Option.some(100))
+ Http.multipart.withMaxFileSize(Option.some(100))
)
const client = yield* _(makeClient)
const formData = new FormData()
@@ -169,16 +169,16 @@ describe("HttpServer", () => {
"/upload",
Effect.gen(function*(_) {
const request = yield* _(Http.request.ServerRequest)
- yield* _(request.formData)
+ yield* _(request.multipart)
return Http.response.empty()
}).pipe(Effect.scoped)
),
- Effect.catchTag("FormDataError", (error) =>
+ Effect.catchTag("MultipartError", (error) =>
error.reason === "FieldTooLarge" ?
Http.response.empty({ status: 413 }) :
Effect.fail(error)),
Http.server.serveEffect(),
- Http.formData.withMaxFieldSize(100)
+ Http.multipart.withMaxFieldSize(100)
)
const client = yield* _(makeClient)
const formData = new FormData()
diff --git a/packages/platform/src/Http/FormData.ts b/packages/platform/src/Http/Multipart.ts
similarity index 84%
rename from packages/platform/src/Http/FormData.ts
rename to packages/platform/src/Http/Multipart.ts
index 978a2805..802eecae 100644
--- a/packages/platform/src/Http/FormData.ts
+++ b/packages/platform/src/Http/Multipart.ts
@@ -13,7 +13,7 @@ import type * as Scope from "effect/Scope"
import type * as Stream from "effect/Stream"
import type * as Multipasta from "multipasta"
import type * as FileSystem from "../FileSystem.js"
-import * as internal from "../internal/http/formData.js"
+import * as internal from "../internal/http/multipart.js"
import type * as Path from "../Path.js"
/**
@@ -68,7 +68,7 @@ export interface File extends Part.Proto {
readonly key: string
readonly name: string
readonly contentType: string
- readonly content: Stream.Stream
+ readonly content: Stream.Stream
}
/**
@@ -87,7 +87,7 @@ export interface PersistedFile extends Part.Proto {
* @since 1.0.0
* @category models
*/
-export interface PersistedFormData {
+export interface Persisted {
readonly [key: string]: ReadonlyArray | string
}
@@ -107,9 +107,9 @@ export type ErrorTypeId = typeof ErrorTypeId
* @since 1.0.0
* @category errors
*/
-export interface FormDataError extends Data.Case {
+export interface MultipartError extends Data.Case {
readonly [ErrorTypeId]: ErrorTypeId
- readonly _tag: "FormDataError"
+ readonly _tag: "MultipartError"
readonly reason: "FileTooLarge" | "FieldTooLarge" | "BodyTooLarge" | "TooManyParts" | "InternalError" | "Parse"
readonly error: unknown
}
@@ -118,10 +118,10 @@ export interface FormDataError extends Data.Case {
* @since 1.0.0
* @category errors
*/
-export const FormDataError: (
- reason: FormDataError["reason"],
+export const MultipartError: (
+ reason: MultipartError["reason"],
error: unknown
-) => FormDataError = internal.FormDataError
+) => MultipartError = internal.MultipartError
/**
* @since 1.0.0
@@ -203,17 +203,17 @@ export const filesSchema: Schema.Schema, ReadonlyAr
export const schemaJson: (
schema: Schema.Schema
) => {
- (field: string): (formData: PersistedFormData) => Effect.Effect
- (formData: PersistedFormData, field: string): Effect.Effect
+ (field: string): (persisted: Persisted) => Effect.Effect
+ (persisted: Persisted, field: string): Effect.Effect
} = internal.schemaJson
/**
* @since 1.0.0
* @category schema
*/
-export const schemaPersisted: (
+export const schemaPersisted: (
schema: Schema.Schema
-) => (formData: PersistedFormData) => Effect.Effect = internal.schemaPersisted
+) => (persisted: Persisted) => Effect.Effect = internal.schemaPersisted
/**
* @since 1.0.0
@@ -222,7 +222,7 @@ export const schemaPersisted: (
export const makeChannel: (
headers: Record,
bufferSize?: number
-) => Channel.Channel, unknown, FormDataError | IE, Chunk.Chunk, unknown> =
+) => Channel.Channel, unknown, MultipartError | IE, Chunk.Chunk, unknown> =
internal.makeChannel
/**
@@ -236,8 +236,7 @@ export const makeConfig: (headers: Record) => Effect.Effect,
- writeFile?: (path: string, file: File) => Effect.Effect
-) => Effect.Effect =
- internal.formData
+export const toPersisted: (
+ stream: Stream.Stream,
+ writeFile?: (path: string, file: File) => Effect.Effect
+) => Effect.Effect = internal.toPersisted
diff --git a/packages/platform/src/Http/ServerRequest.ts b/packages/platform/src/Http/ServerRequest.ts
index c936e149..d747c2da 100644
--- a/packages/platform/src/Http/ServerRequest.ts
+++ b/packages/platform/src/Http/ServerRequest.ts
@@ -10,10 +10,10 @@ import type * as Stream from "effect/Stream"
import type * as FileSystem from "../FileSystem.js"
import * as internal from "../internal/http/serverRequest.js"
import type * as Path from "../Path.js"
-import type * as FormData from "./FormData.js"
import type * as Headers from "./Headers.js"
import type * as IncomingMessage from "./IncomingMessage.js"
import type { Method } from "./Method.js"
+import type * as Multipart from "./Multipart.js"
import type * as Error from "./ServerError.js"
export {
@@ -47,12 +47,12 @@ export interface ServerRequest extends IncomingMessage.IncomingMessage
- readonly formDataStream: Stream.Stream
+ readonly multipartStream: Stream.Stream
readonly modify: (
options: {
@@ -73,11 +73,11 @@ export const ServerRequest: Context.Tag = internal
* @since 1.0.0
* @category accessors
*/
-export const persistedFormData: Effect.Effect<
+export const persistedMultipart: Effect.Effect<
Scope.Scope | FileSystem.FileSystem | Path.Path | ServerRequest,
- FormData.FormDataError,
+ Multipart.MultipartError,
unknown
-> = internal.persistedFormData
+> = internal.multipartPersisted
/**
* @since 1.0.0
@@ -95,6 +95,18 @@ export const schemaBodyJson: (
schema: Schema.Schema
) => Effect.Effect = internal.schemaBodyJson
+/**
+ * @since 1.0.0
+ * @category schema
+ */
+export const schemaBodyForm: (
+ schema: Schema.Schema
+) => Effect.Effect<
+ ServerRequest | Scope.Scope | FileSystem.FileSystem | Path.Path,
+ Multipart.MultipartError | Error.RequestError | ParseResult.ParseError,
+ A
+> = internal.schemaBodyForm
+
/**
* @since 1.0.0
* @category schema
@@ -107,27 +119,27 @@ export const schemaBodyUrlParams: >, A
* @since 1.0.0
* @category schema
*/
-export const schemaFormData: (
+export const schemaBodyMultipart: (
schema: Schema.Schema
) => Effect.Effect<
ServerRequest | Scope.Scope | FileSystem.FileSystem | Path.Path,
- FormData.FormDataError | ParseResult.ParseError,
+ Multipart.MultipartError | ParseResult.ParseError,
A
-> = internal.schemaFormData
+> = internal.schemaBodyMultipart
/**
* @since 1.0.0
* @category schema
*/
-export const schemaFormDataJson: (
+export const schemaBodyMultipartJson: (
schema: Schema.Schema
) => (
field: string
) => Effect.Effect<
ServerRequest | Scope.Scope | FileSystem.FileSystem | Path.Path,
- Error.RequestError | FormData.FormDataError | ParseResult.ParseError,
+ Error.RequestError | Multipart.MultipartError | ParseResult.ParseError,
A
-> = internal.schemaFormDataJson
+> = internal.schemaBodyMultipartJson
/**
* @since 1.0.0
diff --git a/packages/platform/src/HttpServer.ts b/packages/platform/src/HttpServer.ts
index 1fc55198..989489c9 100644
--- a/packages/platform/src/HttpServer.ts
+++ b/packages/platform/src/HttpServer.ts
@@ -3,9 +3,9 @@
*/
import * as app from "./Http/App.js"
import * as body from "./Http/Body.js"
-import * as formData from "./Http/FormData.js"
import * as headers from "./Http/Headers.js"
import * as middleware from "./Http/Middleware.js"
+import * as multipart from "./Http/Multipart.js"
import * as router from "./Http/Router.js"
import * as error from "./Http/ServerError.js"
import * as request from "./Http/ServerRequest.js"
@@ -34,13 +34,6 @@ export {
* - Module: `@effect/platform/Http/ServerError`
*/
error,
- /**
- * @since 1.0.0
- *
- * - Docs: [Http/FormData](https://effect-ts.github.io/platform/platform/Http/FormData.html)
- * - Module: `@effect/platform/Http/FormData`
- */
- formData,
/**
* @since 1.0.0
*
@@ -55,6 +48,13 @@ export {
* - Module: `@effect/platform/Http/Middleware`
*/
middleware,
+ /**
+ * @since 1.0.0
+ *
+ * - Docs: [Http/Multipart](https://effect-ts.github.io/platform/platform/Http/Multipart.html)
+ * - Module: `@effect/platform/Http/Multipart`
+ */
+ multipart,
/**
* @since 1.0.0
*
diff --git a/packages/platform/src/internal/http/formData.ts b/packages/platform/src/internal/http/multipart.ts
similarity index 72%
rename from packages/platform/src/internal/http/formData.ts
rename to packages/platform/src/internal/http/multipart.ts
index f98efc6a..a2a059a9 100644
--- a/packages/platform/src/internal/http/formData.ts
+++ b/packages/platform/src/internal/http/multipart.ts
@@ -16,34 +16,34 @@ import type * as AsyncInput from "effect/SingleProducerAsyncInput"
import * as Stream from "effect/Stream"
import * as MP from "multipasta"
import * as FileSystem from "../../FileSystem.js"
-import type * as FormData from "../../Http/FormData.js"
import * as IncomingMessage from "../../Http/IncomingMessage.js"
+import type * as Multipart from "../../Http/Multipart.js"
import * as Path from "../../Path.js"
/** @internal */
-export const TypeId: FormData.TypeId = Symbol.for("@effect/platform/Http/FormData") as FormData.TypeId
+export const TypeId: Multipart.TypeId = Symbol.for("@effect/platform/Http/Multipart") as Multipart.TypeId
/** @internal */
-export const ErrorTypeId: FormData.ErrorTypeId = Symbol.for(
- "@effect/platform/Http/FormData/FormDataError"
-) as FormData.ErrorTypeId
+export const ErrorTypeId: Multipart.ErrorTypeId = Symbol.for(
+ "@effect/platform/Http/Multipart/MultipartError"
+) as Multipart.ErrorTypeId
/** @internal */
-export const FormDataError = (reason: FormData.FormDataError["reason"], error: unknown): FormData.FormDataError =>
+export const MultipartError = (reason: Multipart.MultipartError["reason"], error: unknown): Multipart.MultipartError =>
Data.struct({
[ErrorTypeId]: ErrorTypeId,
- _tag: "FormDataError",
+ _tag: "MultipartError",
reason,
error
})
/** @internal */
-export const isField = (u: unknown): u is FormData.Field =>
+export const isField = (u: unknown): u is Multipart.Field =>
Predicate.hasProperty(u, TypeId) && Predicate.isTagged(u, "Field")
/** @internal */
export const maxParts: FiberRef.FiberRef> = globalValue(
- "@effect/platform/Http/FormData/maxParts",
+ "@effect/platform/Http/Multipart/maxParts",
() => FiberRef.unsafeMake(Option.none())
)
@@ -55,7 +55,7 @@ export const withMaxParts = dual<
/** @internal */
export const maxFieldSize: FiberRef.FiberRef = globalValue(
- "@effect/platform/Http/FormData/maxFieldSize",
+ "@effect/platform/Http/Multipart/maxFieldSize",
() => FiberRef.unsafeMake(FileSystem.Size(10 * 1024 * 1024))
)
@@ -67,7 +67,7 @@ export const withMaxFieldSize = dual<
/** @internal */
export const maxFileSize: FiberRef.FiberRef> = globalValue(
- "@effect/platform/Http/FormData/maxFileSize",
+ "@effect/platform/Http/Multipart/maxFileSize",
() => FiberRef.unsafeMake(Option.none())
)
@@ -79,7 +79,7 @@ export const withMaxFileSize = dual<
/** @internal */
export const fieldMimeTypes: FiberRef.FiberRef> = globalValue(
- "@effect/platform/Http/FormData/fieldMimeTypes",
+ "@effect/platform/Http/Multipart/fieldMimeTypes",
() => FiberRef.unsafeMake>(Chunk.make("application/json"))
)
@@ -90,56 +90,58 @@ export const withFieldMimeTypes = dual<
>(2, (effect, mimeTypes) => Effect.locally(effect, fieldMimeTypes, Chunk.fromIterable(mimeTypes)))
/** @internal */
-export const filesSchema: Schema.Schema, ReadonlyArray> =
- Schema
- .array(
- pipe(
- Schema.object,
- Schema.filter(
- (file): file is FormData.PersistedFile => TypeId in file && "_tag" in file && file._tag === "PersistedFile"
- )
- ) as any as Schema.Schema
- )
+export const filesSchema: Schema.Schema<
+ ReadonlyArray,
+ ReadonlyArray
+> = Schema
+ .array(
+ pipe(
+ Schema.object,
+ Schema.filter(
+ (file): file is Multipart.PersistedFile => TypeId in file && "_tag" in file && file._tag === "PersistedFile"
+ )
+ ) as any as Schema.Schema
+ )
/** @internal */
-export const schemaPersisted = (
+export const schemaPersisted = (
schema: Schema.Schema
) => {
const parse = Schema.parse(schema)
- return (formData: FormData.PersistedFormData) => parse(formData)
+ return (persisted: Multipart.Persisted) => parse(persisted)
}
/** @internal */
export const schemaJson = (schema: Schema.Schema): {
(
field: string
- ): (formData: FormData.PersistedFormData) => Effect.Effect
+ ): (persisted: Multipart.Persisted) => Effect.Effect
(
- formData: FormData.PersistedFormData,
+ persisted: Multipart.Persisted,
field: string
- ): Effect.Effect
+ ): Effect.Effect
} => {
const parse = Schema.parse(schema)
return dual<
(
field: string
) => (
- formData: FormData.PersistedFormData
- ) => Effect.Effect,
+ persisted: Multipart.Persisted
+ ) => Effect.Effect,
(
- formData: FormData.PersistedFormData,
+ persisted: Multipart.Persisted,
field: string
- ) => Effect.Effect
- >(2, (formData, field) =>
+ ) => Effect.Effect
+ >(2, (persisted, field) =>
pipe(
- Effect.succeed(formData[field]),
+ Effect.succeed(persisted[field]),
Effect.filterOrFail(
isField,
- () => FormDataError("Parse", `schemaJson: was not a field`)
+ () => MultipartError("Parse", `schemaJson: was not a field`)
),
Effect.tryMap({
try: (field) => JSON.parse(field.value),
- catch: (error) => FormDataError("Parse", `schemaJson: field was not valid json: ${error}`)
+ catch: (error) => MultipartError("Parse", `schemaJson: field was not valid json: ${error}`)
}),
Effect.flatMap(parse)
))
@@ -181,8 +183,8 @@ export const makeChannel = (
IE,
Chunk.Chunk,
unknown,
- FormData.FormDataError | IE,
- Chunk.Chunk,
+ Multipart.MultipartError | IE,
+ Chunk.Chunk,
unknown
> =>
Channel.acquireUseRelease(
@@ -202,13 +204,13 @@ const makeFromQueue = (
IE,
Chunk.Chunk,
unknown,
- IE | FormData.FormDataError,
- Chunk.Chunk,
+ IE | Multipart.MultipartError,
+ Chunk.Chunk,
unknown
> =>
Channel.suspend(() => {
- let error = Option.none>()
- let partsBuffer: Array = []
+ let error = Option.none>()
+ let partsBuffer: Array = []
let partsFinished = false
const input: AsyncInput.AsyncInputProducer, unknown> = {
@@ -293,8 +295,8 @@ const makeFromQueue = (
unknown,
unknown,
unknown,
- IE | FormData.FormDataError,
- Chunk.Chunk,
+ IE | Multipart.MultipartError,
+ Chunk.Chunk,
void
> = Channel.suspend(() => {
if (error._tag === "Some") {
@@ -308,32 +310,32 @@ const makeFromQueue = (
return Channel.embedInput(partsChannel, input)
})
-function convertError(error: MP.MultipartError): FormData.FormDataError {
+function convertError(error: MP.MultipartError): Multipart.MultipartError {
switch (error._tag) {
case "ReachedLimit": {
switch (error.limit) {
case "MaxParts": {
- return FormDataError("TooManyParts", error)
+ return MultipartError("TooManyParts", error)
}
case "MaxFieldSize": {
- return FormDataError("FieldTooLarge", error)
+ return MultipartError("FieldTooLarge", error)
}
case "MaxPartSize": {
- return FormDataError("FileTooLarge", error)
+ return MultipartError("FileTooLarge", error)
}
case "MaxTotalSize": {
- return FormDataError("BodyTooLarge", error)
+ return MultipartError("BodyTooLarge", error)
}
}
}
default: {
- return FormDataError("Parse", error)
+ return MultipartError("Parse", error)
}
}
}
-class FieldImpl implements FormData.Field {
- readonly [TypeId]: FormData.TypeId
+class FieldImpl implements Multipart.Field {
+ readonly [TypeId]: Multipart.TypeId
readonly _tag = "Field"
constructor(
@@ -345,13 +347,13 @@ class FieldImpl implements FormData.Field {
}
}
-class FileImpl implements FormData.File {
+class FileImpl implements Multipart.File {
readonly _tag = "File"
- readonly [TypeId]: FormData.TypeId
+ readonly [TypeId]: Multipart.TypeId
readonly key: string
readonly name: string
readonly contentType: string
- readonly content: Stream.Stream
+ readonly content: Stream.Stream
constructor(
info: MP.PartInfo,
@@ -365,21 +367,21 @@ class FileImpl implements FormData.File {
}
}
-const defaultWriteFile = (path: string, file: FormData.File) =>
+const defaultWriteFile = (path: string, file: Multipart.File) =>
Effect.flatMap(
FileSystem.FileSystem,
(fs) =>
Effect.mapError(
Stream.run(file.content, fs.sink(path)),
- (error) => FormDataError("InternalError", error)
+ (error) => MultipartError("InternalError", error)
)
)
/** @internal */
-export const formData = (
- stream: Stream.Stream,
+export const toPersisted = (
+ stream: Stream.Stream,
writeFile = defaultWriteFile
-): Effect.Effect =>
+): Effect.Effect =>
pipe(
Effect.Do,
Effect.bind("fs", () => FileSystem.FileSystem),
@@ -388,18 +390,18 @@ export const formData = (
Effect.flatMap(({ dir, path: path_ }) =>
Stream.runFoldEffect(
stream,
- Object.create(null) as Record | string>,
- (formData, part) => {
+ Object.create(null) as Record | string>,
+ (persisted, part) => {
if (part._tag === "Field") {
- formData[part.key] = part.value
- return Effect.succeed(formData)
+ persisted[part.key] = part.value
+ return Effect.succeed(persisted)
}
const file = part
const path = path_.join(dir, path_.basename(file.name).slice(-128))
- if (!Array.isArray(formData[part.key])) {
- formData[part.key] = []
+ if (!Array.isArray(persisted[part.key])) {
+ persisted[part.key] = []
}
- ;(formData[part.key] as Array).push(
+ ;(persisted[part.key] as Array).push(
new PersistedFileImpl(
file.key,
file.name,
@@ -407,18 +409,18 @@ export const formData = (
path
)
)
- return Effect.as(writeFile(path, file), formData)
+ return Effect.as(writeFile(path, file), persisted)
}
)
),
Effect.catchTags({
- SystemError: (err) => Effect.fail(FormDataError("InternalError", err)),
- BadArgument: (err) => Effect.fail(FormDataError("InternalError", err))
+ SystemError: (err) => Effect.fail(MultipartError("InternalError", err)),
+ BadArgument: (err) => Effect.fail(MultipartError("InternalError", err))
})
)
-class PersistedFileImpl implements FormData.PersistedFile {
- readonly [TypeId]: FormData.TypeId
+class PersistedFileImpl implements Multipart.PersistedFile {
+ readonly [TypeId]: Multipart.TypeId
readonly _tag = "PersistedFile"
constructor(
diff --git a/packages/platform/src/internal/http/serverRequest.ts b/packages/platform/src/internal/http/serverRequest.ts
index e256912c..ca408f82 100644
--- a/packages/platform/src/internal/http/serverRequest.ts
+++ b/packages/platform/src/internal/http/serverRequest.ts
@@ -1,3 +1,4 @@
+import type * as ParseResult from "@effect/schema/ParseResult"
import type * as Schema from "@effect/schema/Schema"
import * as Context from "effect/Context"
import * as Effect from "effect/Effect"
@@ -5,10 +6,10 @@ import * as Option from "effect/Option"
import type * as Scope from "effect/Scope"
import * as Stream from "effect/Stream"
import type * as FileSystem from "../../FileSystem.js"
-import * as FormData from "../../Http/FormData.js"
import * as Headers from "../../Http/Headers.js"
import * as IncomingMessage from "../../Http/IncomingMessage.js"
import type { Method } from "../../Http/Method.js"
+import * as Multipart from "../../Http/Multipart.js"
import * as Error from "../../Http/ServerError.js"
import type * as ServerRequest from "../../Http/ServerRequest.js"
import * as UrlParams from "../../Http/UrlParams.js"
@@ -21,7 +22,7 @@ export const TypeId: ServerRequest.TypeId = Symbol.for("@effect/platform/Http/Se
export const serverRequestTag = Context.Tag(TypeId)
/** @internal */
-export const persistedFormData = Effect.flatMap(serverRequestTag, (request) => request.formData)
+export const multipartPersisted = Effect.flatMap(serverRequestTag, (request) => request.multipart)
/** @internal */
export const schemaHeaders = >, A>(schema: Schema.Schema) => {
@@ -35,6 +36,24 @@ export const schemaBodyJson = (schema: Schema.Schema) => {
return Effect.flatMap(serverRequestTag, parse)
}
+/** @internal */
+export const schemaBodyForm = (
+ schema: Schema.Schema
+) => {
+ const parseMultipart = Multipart.schemaPersisted(schema)
+ const parseUrlParams = IncomingMessage.schemaBodyUrlParams(schema as Schema.Schema)
+ return Effect.flatMap(serverRequestTag, (request): Effect.Effect<
+ ServerRequest.ServerRequest | Scope.Scope | FileSystem.FileSystem | Path.Path,
+ Multipart.MultipartError | ParseResult.ParseError | Error.RequestError,
+ A
+ > => {
+ if (request.headers["content-type"]?.trim().toLowerCase().startsWith("multipart/form-data")) {
+ return Effect.flatMap(request.multipart, parseMultipart)
+ }
+ return parseUrlParams(request)
+ })
+}
+
/** @internal */
export const schemaBodyUrlParams = >, A>(schema: Schema.Schema) => {
const parse = IncomingMessage.schemaBodyUrlParams(schema)
@@ -42,24 +61,24 @@ export const schemaBodyUrlParams = >,
}
/** @internal */
-export const schemaFormData = (
+export const schemaBodyMultipart = (
schema: Schema.Schema
) => {
- const parse = FormData.schemaPersisted(schema)
- return Effect.flatMap(persistedFormData, parse)
+ const parse = Multipart.schemaPersisted(schema)
+ return Effect.flatMap(multipartPersisted, parse)
}
/** @internal */
-export const schemaFormDataJson = (schema: Schema.Schema) => {
- const parse = FormData.schemaJson(schema)
+export const schemaBodyMultipartJson = (schema: Schema.Schema) => {
+ const parse = Multipart.schemaJson(schema)
return (field: string) =>
Effect.flatMap(serverRequestTag, (request) =>
Effect.flatMap(
- request.formData,
- (formData) =>
+ request.multipart,
+ (persisted) =>
Effect.catchTag(
- parse(formData, field),
- "FormDataError",
+ parse(persisted, field),
+ "MultipartError",
(error) =>
Effect.fail(
Error.RequestError({
@@ -175,31 +194,31 @@ class ServerRequestImpl implements ServerRequest.ServerRequest {
}))
}
- private formDataEffect:
+ private multipartEffect:
| Effect.Effect<
Scope.Scope | FileSystem.FileSystem | Path.Path,
- FormData.FormDataError,
- FormData.PersistedFormData
+ Multipart.MultipartError,
+ Multipart.Persisted
>
| undefined
- get formData(): Effect.Effect<
+ get multipart(): Effect.Effect<
Scope.Scope | FileSystem.FileSystem | Path.Path,
- FormData.FormDataError,
- FormData.PersistedFormData
+ Multipart.MultipartError,
+ Multipart.Persisted
> {
- if (this.formDataEffect) {
- return this.formDataEffect
+ if (this.multipartEffect) {
+ return this.multipartEffect
}
- this.formDataEffect = Effect.runSync(Effect.cached(
- FormData.formData(this.formDataStream)
+ this.multipartEffect = Effect.runSync(Effect.cached(
+ Multipart.toPersisted(this.multipartStream)
))
- return this.formDataEffect
+ return this.multipartEffect
}
- get formDataStream(): Stream.Stream {
+ get multipartStream(): Stream.Stream {
return Stream.pipeThroughChannel(
- Stream.mapError(this.stream, (error) => FormData.FormDataError("InternalError", error)),
- FormData.makeChannel(this.headers)
+ Stream.mapError(this.stream, (error) => Multipart.MultipartError("InternalError", error)),
+ Multipart.makeChannel(this.headers)
)
}
diff --git a/packages/platform/src/internal/http/serverResponse.ts b/packages/platform/src/internal/http/serverResponse.ts
index aa4b81db..86530470 100644
--- a/packages/platform/src/internal/http/serverResponse.ts
+++ b/packages/platform/src/internal/http/serverResponse.ts
@@ -176,7 +176,10 @@ export const raw = (body: unknown, options?: ServerResponse.Options): ServerResp
)
/** @internal */
-export const formData = (body: FormData, options?: ServerResponse.Options.WithContent): ServerResponse.ServerResponse =>
+export const formData = (
+ body: FormData,
+ options?: ServerResponse.Options.WithContent
+): ServerResponse.ServerResponse =>
new ServerResponseImpl(
options?.status ?? 200,
options?.statusText,
diff --git a/packages/platform/test/Http/FormData.test.ts b/packages/platform/test/Http/Multipart.test.ts
similarity index 85%
rename from packages/platform/test/Http/FormData.test.ts
rename to packages/platform/test/Http/Multipart.test.ts
index 0b35efb3..ea3aacae 100644
--- a/packages/platform/test/Http/FormData.test.ts
+++ b/packages/platform/test/Http/Multipart.test.ts
@@ -1,8 +1,8 @@
-import * as FormData from "@effect/platform/Http/FormData"
+import * as Multipart from "@effect/platform/Http/Multipart"
import { Chunk, Effect, identity, Stream } from "effect"
import { assert, describe, test } from "vitest"
-describe("FormData", () => {
+describe("Multipart", () => {
test("it parses", () =>
Effect.gen(function*(_) {
const data = new globalThis.FormData()
@@ -13,7 +13,7 @@ describe("FormData", () => {
const parts = yield* _(
Stream.fromReadableStream(() => response.body!, identity),
- Stream.pipeThroughChannel(FormData.makeChannel(Object.fromEntries(response.headers))),
+ Stream.pipeThroughChannel(Multipart.makeChannel(Object.fromEntries(response.headers))),
Stream.mapEffect((part) => {
return Effect.unified(
part._tag === "File" ?