Multipart
Parses and persists HTTP multipart/form-data request bodies.
Multipart turns incoming byte streams into typed form parts. Text parts become decoded fields, while upload parts stay as streamed files until they are collected or written to scoped temporary files. The persisted representation can then be decoded with schemas for handlers that receive fields and uploaded files together. This module also includes multipart error types, schema helpers for persisted files, and parser limit settings.
Configuration
makeConfig
Signature
declare function makeConfig(headers: Record<string, string>): Effect<BaseConfig>;Converting
collectUint8Array
Runs a channel of byte chunks and collects all output into a single Uint8Array.
Gotchas
This materializes the full content in memory.
Signature
declare function collectUint8Array<OE, OD, R>(
self: Channel<
readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>],
OE,
OD,
unknown,
unknown,
unknown,
R
>,
): Effect<Uint8Array<ArrayBuffer>, OE, R>;toPersisted
Persists a stream of multipart parts into a record.
Details
Text fields are collected as strings, and file parts are written to files in a scoped temporary directory.
Gotchas
Persisted file paths remain valid for the lifetime of the scope.
Signature
declare function toPersisted(
stream: Stream<Part, MultipartError>,
writeFile: (path: string, file: File) => Effect<void, MultipartError, FileSystem>,
): Effect<Persisted, MultipartError, Scope | FileSystem | Path>;Errors
MultipartError
Error raised while parsing, streaming, or persisting multipart form data.
Details
The reason field contains the concrete MultipartErrorReason. When used as a server response, parse errors render as 400, limit errors as 413, and internal errors as 500. Multipart errors are ignored by the error reporter.
Signature
declare class MultipartError extends YieldableError<this> & {
readonly _tag: "MultipartError";
} & Readonly<{
readonly reason: MultipartErrorReason;
}> implements Respondable {
constructor(args: {
readonly reason: MultipartErrorReason;
});
readonly "~effect/ErrorReporter/ignore": true;
readonly "~effect/http/Multipart/MultipartError": "~effect/http/Multipart/MultipartError";
message: string;
"~effect/http/HttpServerRespondable"(): Effect<HttpServerResponse, never, never>;
static fromReason(reason: "InternalError" | "FileTooLarge" | "FieldTooLarge" | "BodyTooLarge" | "TooManyParts" | "Parse", cause?: unknown): MultipartError;
}MultipartErrorReason
Error reason carried by a MultipartError.
Details
It identifies parser and limit failures such as oversized files or fields, too many parts, total body size limits, parse errors, and internal errors.
Signature
declare class MultipartErrorReason extends Error<{
readonly _tag:
| "FileTooLarge"
| "FieldTooLarge"
| "BodyTooLarge"
| "TooManyParts"
| "InternalError"
| "Parse";
readonly cause?: unknown;
}> {
constructor(args: {
readonly _tag:
| "InternalError"
| "FileTooLarge"
| "FieldTooLarge"
| "BodyTooLarge"
| "TooManyParts"
| "Parse";
readonly cause?: unknown;
});
}Guards
Returns true when a value is a multipart text Field.
Signature
declare function isField(u: unknown): u is Field;Returns true when a value is a multipart File.
Signature
declare function isFile(u: unknown): u is File;Returns true when a value is a multipart Part.
Signature
declare function isPart(u: unknown): u is Part;isPersistedFile
Returns true when a value is a persisted multipart file.
Signature
declare function isPersistedFile(u: unknown): u is PersistedFile;Models
Multipart form field containing a decoded text value.
Details
The key is the field name, contentType is the part media type, and value is the decoded field content.
Signature
interface Field extends Proto {
readonly _tag: "Field";
readonly contentType: string;
readonly key: string;
readonly value: string;
}Multipart file part.
Gotchas
The file content is exposed as a byte stream. contentEffect collects the full file into memory and should be used only when the file size is acceptable.
Signature
interface File extends Proto {
readonly _tag: "File";
readonly content: Stream<Uint8Array<ArrayBufferLike>, MultipartError>;
readonly contentEffect: Effect<Uint8Array<ArrayBufferLike>, MultipartError>;
readonly contentType: string;
readonly key: string;
readonly name: string;
}A parsed multipart part.
Details
A part is either a text Field or a streamed File.
Signature
type Part = Field | File;Record representation of persisted multipart data.
Details
Field names map to text values, arrays of text values, or arrays of PersistedFile values.
Signature
interface Persisted {
[key: string]: string | readonly Array<string> | readonly Array<PersistedFile>;
}PersistedFile interface
Multipart file part that has been written to the filesystem.
Details
The path points to the persisted file while the scope used to persist the multipart data remains open.
Signature
interface PersistedFile extends Proto {
readonly _tag: "PersistedFile";
readonly contentType: string;
readonly key: string;
readonly name: string;
readonly path: string;
}Other
Namespace containing shared multipart part model types.
withLimits
Namespace containing multipart parser limit option types.
Parsing
makeChannel
Creates a channel that parses multipart byte chunks into multipart parts.
Details
The channel consumes non-empty batches of Uint8Array chunks and emits non-empty batches of parsed Part values, failing with MultipartError for parser and limit failures.
Signature
declare function makeChannel<IE>(
headers: Record<string, string>,
): Channel<
readonly [Part, Part],
MultipartError | IE,
void,
readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>],
IE,
unknown
>;References
limitsServices
Creates a context containing multipart parser limit settings.
Details
The context can provide maximum part count, field size, file size, total body size, and MIME types that should be parsed as fields.
Signature
declare function limitsServices(options: {
readonly fieldMimeTypes?: readonly Array<string>;
readonly maxFieldSize?: SizeInput;
readonly maxFileSize?: SizeInput;
readonly maxParts?: number;
readonly maxTotalSize?: SizeInput;
}): Context<never>Schemas
FilesSchema
Schema for an array of persisted multipart files.
Signature
declare const FilesSchema: Schema.$Array<PersistedFileSchema>;PersistedFileSchema
Schema for persisted multipart files.
Details
The encoded form contains the field key, original file name, content type, and filesystem path.
Signature
declare const PersistedFileSchema: PersistedFileSchema;PersistedFileSchema interface
Schema type for persisted multipart files.
Signature
interface PersistedFileSchema extends declare<PersistedFile> {
constructor(_: never);
}schemaJson
Creates a decoder for a JSON-encoded field in persisted multipart data.
Details
The selected field is parsed from a JSON string and decoded with the supplied schema.
Signature
declare function schemaJson<A, RD>(
schema: ConstraintDecoder<A, RD>,
options?: ParseOptions,
): {
(field: string): (persisted: Persisted) => Effect<A, SchemaError, RD>;
(persisted: Persisted, field: string): Effect<A, SchemaError, RD>;
};schemaPersisted
Creates a decoder for persisted multipart data using the supplied schema.
Details
The returned function decodes an unknown input into the schema output and fails with SchemaError when validation fails.
Signature
declare function schemaPersisted<A, I extends Partial<Persisted>, RD>(
schema: ConstraintCodec<A, I, RD, unknown>,
): (input: unknown, options?: ParseOptions) => Effect<A, SchemaError, RD>;SingleFileSchema
Schema for exactly one persisted multipart file.
Details
The encoded form is a one-element file array, while the decoded value is the single PersistedFile.
Signature
declare const SingleFileSchema: Schema.decodeTo<
PersistedFileSchema,
Schema.$Array<PersistedFileSchema>
>;Services
FieldMimeTypes
Context reference for MIME type fragments that should be parsed as multipart fields instead of files.
Details
The default treats application/json parts as fields.
Signature
declare const FieldMimeTypes: Reference<readonly Array<string>>MaxFieldSize
Context reference for the maximum size of a multipart field value.
Details
The default limit is 10 MiB.
Signature
declare const MaxFieldSize: Reference<SizeInput>;MaxFileSize
Context reference for the maximum size of a multipart file part.
Details
The default is undefined, meaning no explicit per-file limit.
Signature
declare const MaxFileSize: Reference<SizeInput | undefined>;Context reference for the maximum number of multipart parts allowed.
Details
The default is undefined, meaning no explicit part-count limit.
Signature
declare const MaxParts: Reference<number | undefined>;
Builds the low-level multipart parser configuration from request headers and the current fiber context.
Details
Parser limits are read from the multipart references, including maximum parts, field size, file size, total body size, and field MIME type overrides.