1/**
2 * Low-level parser for HTTP `multipart/form-data` bodies.
3 *
4 * @stability unstable
5 * @since 4.0.0
6 */
7import type * as ByteSize from "../ByteSize.ts"
8import type * as HeadersParser from "./MultipartParser/HeadersParser.ts"
9import * as internal from "./MultipartParser/internal/multipart.ts"
10
11/**
12 * Metadata describing a multipart form part.
13 *
14 * @stability unstable
15 * @category models
16 * @since 4.0.0
17 */
18export interface PartInfo {
19 readonly name: string
20 readonly filename?: string | undefined
21 readonly contentType: string
22 readonly contentTypeParameters: Record<string, string>
23 readonly contentDisposition: string
24 readonly contentDispositionParameters: Record<string, string>
25 readonly headers: Record<string, string | Array<string>>
26}
27
28/**
29 * An error produced while parsing a multipart body.
30 *
31 * @stability unstable
32 * @category errors
33 * @since 4.0.0
34 */
35export type MultipartError =
36 | {
37 readonly _tag: "InvalidBoundary"
38 }
39 | {
40 readonly _tag: "BadHeaders"
41 readonly error: HeadersParser.Failure
42 }
43 | {
44 readonly _tag: "InvalidDisposition"
45 }
46 | {
47 readonly _tag: "ReachedLimit"
48 readonly limit:
49 | "MaxParts"
50 | "MaxTotalSize"
51 | "MaxPartSize"
52 | "MaxFieldSize"
53 }
54 | {
55 readonly _tag: "EndNotReached"
56 }
57
58/**
59 * Shared multipart parser configuration.
60 *
61 * @stability unstable
62 * @category models
63 * @since 4.0.0
64 */
65export type BaseConfig = {
66 readonly headers: Record<string, string>
67 readonly isFile?: ((info: PartInfo) => boolean) | undefined
68 readonly maxParts?: number | undefined
69 readonly maxTotalSize?: ByteSize.Input | undefined
70 readonly maxPartSize?: ByteSize.Input | undefined
71 readonly maxFieldSize?: ByteSize.Input | undefined
72}
73
74/**
75 * Multipart parser configuration with event callbacks.
76 *
77 * @stability unstable
78 * @category models
79 * @since 4.0.0
80 */
81export type Config = BaseConfig & {
82 readonly onField: (info: PartInfo, value: Uint8Array) => void
83 readonly onFile: (info: PartInfo) => (chunk: Uint8Array | null) => void
84 readonly onError: (error: MultipartError) => void
85 readonly onDone: () => void
86}
87
88/**
89 * A streaming multipart parser.
90 *
91 * @stability unstable
92 * @category models
93 * @since 4.0.0
94 */
95export interface Parser {
96 readonly write: (chunk: Uint8Array) => void
97 readonly end: () => void
98}
99
100/**
101 * Creates a streaming multipart parser.
102 *
103 * @stability unstable
104 * @category constructors
105 * @since 4.0.0
106 */
107export const make: (options: Config) => Parser = internal.make
108
109/**
110 * Determines whether a multipart part should be treated as a file.
111 *
112 * @stability unstable
113 * @category utilities
114 * @since 4.0.0
115 */
116export const defaultIsFile: (info: PartInfo) => boolean = internal.defaultIsFile
117
118/**
119 * Decodes a multipart field using its declared character set.
120 *
121 * @stability unstable
122 * @category utilities
123 * @since 4.0.0
124 */
125export const decodeField: (info: PartInfo, value: Uint8Array) => string = internal.decodeField