@@ -85,6 +85,50 @@ interface FilePart<T> {
8585
8686type Part = string | Uint8Array | FilePart < Uint8Array >
8787
88+ type FormInput = Record < string , Part > | FormData
89+ type FormBody = Record < string , string | number [ ] | FilePart < number [ ] > >
90+
91+ async function formBody ( data : FormInput ) : Promise < FormBody > {
92+ const form : FormBody = { }
93+
94+ const append = async (
95+ key : string ,
96+ v : string | Uint8Array | FilePart < Uint8Array > | File
97+ ) : Promise < void > => {
98+ if ( v !== null ) {
99+ let r
100+ if ( typeof v === 'string' ) {
101+ r = v
102+ } else if ( v instanceof Uint8Array || Array . isArray ( v ) ) {
103+ r = Array . from ( v )
104+ } else if ( v instanceof File ) {
105+ r = {
106+ file : Array . from ( new Uint8Array ( await v . arrayBuffer ( ) ) ) ,
107+ mime : v . type ,
108+ fileName : v . name
109+ }
110+ } else if ( typeof v . file === 'string' ) {
111+ r = { file : v . file , mime : v . mime , fileName : v . fileName }
112+ } else {
113+ r = { file : Array . from ( v . file ) , mime : v . mime , fileName : v . fileName }
114+ }
115+ form [ String ( key ) ] = r
116+ }
117+ }
118+
119+ if ( data instanceof FormData ) {
120+ for ( const [ key , value ] of data ) {
121+ await append ( key , value )
122+ }
123+ } else {
124+ for ( const [ key , value ] of Object . entries ( data ) ) {
125+ await append ( key , value )
126+ }
127+ }
128+
129+ return form
130+ }
131+
88132/**
89133 * The body object to be used on POST and PUT requests.
90134 *
@@ -108,6 +152,7 @@ class Body {
108152 * but you can set it to `multipart/form-data` if the Cargo feature `http-multipart` is enabled.
109153 *
110154 * Note that a file path must be allowed in the `fs` allowlist scope.
155+ *
111156 * @example
112157 * ```typescript
113158 * import { Body } from "@tauri-apps/api/http"
@@ -131,40 +176,8 @@ class Body {
131176 *
132177 * @returns The body object ready to be used on the POST and PUT requests.
133178 */
134- static form ( data : Record < string , Part > | FormData ) : Body {
135- const form : Record < string , string | number [ ] | FilePart < number [ ] > > = { }
136-
137- const append = (
138- key : string ,
139- v : string | Uint8Array | FilePart < Uint8Array > | File
140- ) : void => {
141- if ( v !== null ) {
142- let r
143- if ( typeof v === 'string' ) {
144- r = v
145- } else if ( v instanceof Uint8Array || Array . isArray ( v ) ) {
146- r = Array . from ( v )
147- } else if ( v instanceof File ) {
148- r = { file : v . name , mime : v . type , fileName : v . name }
149- } else if ( typeof v . file === 'string' ) {
150- r = { file : v . file , mime : v . mime , fileName : v . fileName }
151- } else {
152- r = { file : Array . from ( v . file ) , mime : v . mime , fileName : v . fileName }
153- }
154- form [ String ( key ) ] = r
155- }
156- }
157-
158- if ( data instanceof FormData ) {
159- for ( const [ key , value ] of data ) {
160- append ( key , value )
161- }
162- } else {
163- for ( const [ key , value ] of Object . entries ( data ) ) {
164- append ( key , value )
165- }
166- }
167- return new Body ( 'Form' , form )
179+ static form ( data : FormInput ) : Body {
180+ return new Body ( 'Form' , data )
168181 }
169182
170183 /**
@@ -343,6 +356,11 @@ class Client {
343356 if ( jsonResponse ) {
344357 options . responseType = ResponseType . Text
345358 }
359+
360+ if ( options . body ?. type === 'Form' ) {
361+ options . body . payload = await formBody ( options . body . payload as FormInput )
362+ }
363+
346364 return invokeTauriCommand < IResponse < T > > ( {
347365 __tauriModule : 'Http' ,
348366 message : {
@@ -546,6 +564,7 @@ export type {
546564 Duration ,
547565 ClientOptions ,
548566 Part ,
567+ FormInput ,
549568 HttpVerb ,
550569 HttpOptions ,
551570 RequestOptions ,
0 commit comments