EdgeAIG's picture
download
raw
12.8 kB
/**
* 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.
*
* @since 4.0.0
*/
import * as Arr from "../../Array.ts";
import * as Cause from "../../Cause.ts";
import * as Channel from "../../Channel.ts";
import * as Context from "../../Context.ts";
import * as Data from "../../Data.ts";
import * as Effect from "../../Effect.ts";
import * as FileSystem from "../../FileSystem.ts";
import * as Inspectable from "../../Inspectable.ts";
import * as Path from "../../Path.ts";
import * as Schema from "../../Schema.ts";
import type { ParseOptions } from "../../SchemaAST.ts";
import type * as Scope from "../../Scope.ts";
import * as Stream from "../../Stream.ts";
import * as MP from "./Multipasta.ts";
/**
* Type identifier used to brand multipart part values.
*
* @category type IDs
* @since 4.0.0
*/
export declare const TypeId = "~effect/http/Multipart";
/**
* A parsed multipart part.
*
* **Details**
*
* A part is either a text `Field` or a streamed `File`.
*
* @category models
* @since 4.0.0
*/
export type Part = Field | File;
/**
* Namespace containing shared multipart part model types.
*
* @since 4.0.0
*/
export declare namespace Part {
/**
* Common protocol implemented by multipart part values.
*
* **Details**
*
* It provides the multipart type identifier, tag, and inspectable behavior shared
* by fields, files, and persisted files.
*
* @category models
* @since 4.0.0
*/
interface Proto extends Inspectable.Inspectable {
readonly [TypeId]: typeof TypeId;
readonly _tag: string;
}
}
/**
* 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.
*
* @category models
* @since 4.0.0
*/
export interface Field extends Part.Proto {
readonly _tag: "Field";
readonly key: string;
readonly contentType: string;
readonly value: string;
}
/**
* Returns `true` when a value is a multipart `Part`.
*
* @category guards
* @since 4.0.0
*/
export declare const isPart: (u: unknown) => u is Part;
/**
* Returns `true` when a value is a multipart text `Field`.
*
* @category guards
* @since 4.0.0
*/
export declare const isField: (u: unknown) => u is Field;
/**
* 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.
*
* @category models
* @since 4.0.0
*/
export interface File extends Part.Proto {
readonly _tag: "File";
readonly key: string;
readonly name: string;
readonly contentType: string;
readonly content: Stream.Stream<Uint8Array, MultipartError>;
readonly contentEffect: Effect.Effect<Uint8Array, MultipartError>;
}
/**
* Returns `true` when a value is a multipart `File`.
*
* @category guards
* @since 4.0.0
*/
export declare const isFile: (u: unknown) => u is File;
/**
* 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.
*
* @category models
* @since 4.0.0
*/
export interface PersistedFile extends Part.Proto {
readonly _tag: "PersistedFile";
readonly key: string;
readonly name: string;
readonly contentType: string;
readonly path: string;
}
/**
* Returns `true` when a value is a persisted multipart file.
*
* @category guards
* @since 4.0.0
*/
export declare const isPersistedFile: (u: unknown) => u is PersistedFile;
/**
* Record representation of persisted multipart data.
*
* **Details**
*
* Field names map to text values, arrays of text values, or arrays of
* `PersistedFile` values.
*
* @category models
* @since 4.0.0
*/
export interface Persisted {
readonly [key: string]: ReadonlyArray<PersistedFile> | ReadonlyArray<string> | string;
}
declare const MultipartErrorTypeId = "~effect/http/Multipart/MultipartError";
/**
* 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.
*
* @category errors
* @since 4.0.0
*/
export declare class MultipartErrorReason extends Data.Error<{
readonly _tag: "FileTooLarge" | "FieldTooLarge" | "BodyTooLarge" | "TooManyParts" | "InternalError" | "Parse";
readonly cause?: unknown;
}> {
}
declare const MultipartError_base: new <A extends Record<string, any> = {}>(args: import("../../Types.ts").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
readonly _tag: "MultipartError";
} & Readonly<A>;
/**
* Error raised while parsing, streaming, or persisting multipart form data.
*
* **Details**
*
* The `reason` field contains the concrete `MultipartErrorReason`.
*
* @category errors
* @since 4.0.0
*/
export declare class MultipartError extends MultipartError_base<{
readonly reason: MultipartErrorReason;
}> {
/**
* Creates a multipart error from a reason tag and optional cause.
*
* @since 4.0.0
*/
static fromReason(reason: MultipartErrorReason["_tag"], cause?: unknown): MultipartError;
/**
* Marks this value as a multipart error for runtime guards.
*
* @since 4.0.0
*/
readonly [MultipartErrorTypeId] = "~effect/http/Multipart/MultipartError";
/**
* Uses the concrete multipart error reason as the public message.
*
* @since 4.0.0
*/
get message(): string;
}
/**
* Schema type for persisted multipart files.
*
* @category schemas
* @since 4.0.0
*/
export interface PersistedFileSchema extends Schema.declare<PersistedFile> {
}
/**
* Schema for persisted multipart files.
*
* **Details**
*
* The encoded form contains the field key, original file name, content type, and
* filesystem path.
*
* @category schemas
* @since 4.0.0
*/
export declare const PersistedFileSchema: PersistedFileSchema;
/**
* Schema for an array of persisted multipart files.
*
* @category schemas
* @since 4.0.0
*/
export declare const FilesSchema: Schema.$Array<PersistedFileSchema>;
/**
* 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`.
*
* @category schemas
* @since 4.0.0
*/
export declare const SingleFileSchema: Schema.decodeTo<PersistedFileSchema, Schema.$Array<PersistedFileSchema>>;
/**
* 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.
*
* @category schemas
* @since 4.0.0
*/
export declare const schemaPersisted: <A, I extends Partial<Persisted>, RD, RE>(schema: Schema.Codec<A, I, RD, RE>) => (input: unknown, options?: ParseOptions) => Effect.Effect<A, Schema.SchemaError, RD>;
/**
* 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.
*
* @category schemas
* @since 4.0.0
*/
export declare const schemaJson: <A, I, RD, RE>(schema: Schema.Codec<A, I, RD, RE>, options?: ParseOptions | undefined) => {
(field: string): (persisted: Persisted) => Effect.Effect<A, Schema.SchemaError, RD>;
(persisted: Persisted, field: string): Effect.Effect<A, Schema.SchemaError, RD>;
};
/**
* 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.
*
* @category configuration
* @since 4.0.0
*/
export declare const makeConfig: (headers: Record<string, string>) => Effect.Effect<MP.BaseConfig>;
/**
* 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.
*
* @category Parsers
* @since 4.0.0
*/
export declare const makeChannel: <IE>(headers: Record<string, string>) => Channel.Channel<Arr.NonEmptyReadonlyArray<Part>, MultipartError | IE, void, Arr.NonEmptyReadonlyArray<Uint8Array>, IE, unknown>;
/**
* Runs a channel of byte chunks and collects all output into a single
* `Uint8Array`.
*
* **Gotchas**
*
* This materializes the full content in memory.
*
* @category converting
* @since 4.0.0
*/
export declare const collectUint8Array: <OE, OD, R>(self: Channel.Channel<Arr.NonEmptyReadonlyArray<Uint8Array>, OE, OD, unknown, unknown, unknown, R>) => Effect.Effect<Uint8Array<ArrayBuffer>, OE, R>;
/**
* 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.
*
* @category converting
* @since 4.0.0
*/
export declare const toPersisted: (stream: Stream.Stream<Part, MultipartError>, writeFile?: (path: string, file: File) => Effect.Effect<void, MultipartError, FileSystem.FileSystem>) => Effect.Effect<Persisted, MultipartError, FileSystem.FileSystem | Path.Path | Scope.Scope>;
/**
* 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.
*
* @category references
* @since 4.0.0
*/
export declare const limitsServices: (options: {
readonly maxParts?: number | undefined;
readonly maxFieldSize?: FileSystem.SizeInput | undefined;
readonly maxFileSize?: FileSystem.SizeInput | undefined;
readonly maxTotalSize?: FileSystem.SizeInput | undefined;
readonly fieldMimeTypes?: ReadonlyArray<string> | undefined;
}) => Context.Context<never>;
/**
* Namespace containing multipart parser limit option types.
*
* @since 4.0.0
*/
export declare namespace withLimits {
/**
* Options for overriding multipart parser limits.
*
* **Details**
*
* These settings control maximum part count, field size, file size, total body
* size, and MIME types that should be treated as fields instead of files.
*
* @category fiber refs
* @since 4.0.0
*/
type Options = {
readonly maxParts?: number | undefined;
readonly maxFieldSize?: FileSystem.SizeInput | undefined;
readonly maxFileSize?: FileSystem.SizeInput | undefined;
readonly maxTotalSize?: FileSystem.SizeInput | undefined;
readonly fieldMimeTypes?: ReadonlyArray<string> | undefined;
};
}
/**
* Context reference for the maximum number of multipart parts allowed.
*
* **Details**
*
* The default is `undefined`, meaning no explicit part-count limit.
*
* @category references
* @since 4.0.0
*/
export declare const MaxParts: Context.Reference<number | undefined>;
/**
* Context reference for the maximum size of a multipart field value.
*
* **Details**
*
* The default limit is 10 MiB.
*
* @category references
* @since 4.0.0
*/
export declare const MaxFieldSize: Context.Reference<FileSystem.SizeInput>;
/**
* Context reference for the maximum size of a multipart file part.
*
* **Details**
*
* The default is `undefined`, meaning no explicit per-file limit.
*
* @category references
* @since 4.0.0
*/
export declare const MaxFileSize: Context.Reference<FileSystem.SizeInput | undefined>;
/**
* 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.
*
* @category references
* @since 4.0.0
*/
export declare const FieldMimeTypes: Context.Reference<readonly string[]>;
export {};
//# sourceMappingURL=Multipart.d.ts.map

Xet Storage Details

Size:
12.8 kB
·
Xet hash:
c914b765e9267f47427b66b1aba426595bf287e883a7d045b2a529ff933974f1

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.