@@ -10,6 +10,7 @@ import ApiActionInfo from './elements/ApiActionInfo'
1010import ApiActionSQL from './elements/ApiActionSQL'
1111import ApiActionLog from './elements/ApiActionLog'
1212import ApiActionEvents from './elements/ApiActionEvents'
13+ import { objectToFormData } from '../libs/object' ;
1314
1415interface Props {
1516 lrdDocsItem : IAPIInfo ,
@@ -29,7 +30,7 @@ export default function ApiAction(props: Props) {
2930 const [ sendingRequest , setSendingRequest ] = useState ( false ) ;
3031 const [ queryParams , setQueryParams ] = useState ( '' ) ;
3132 const [ bodyParams , setBodyParams ] = useState ( '' ) ;
32- const [ fileParams , setFileParams ] = useState ( null ) ;
33+ const [ fileParams , setFileParams ] = useState < FormData > ( ) ;
3334 const [ responseData , setResponseData ] = useState ( "" ) ;
3435 const [ sqlQueriesCount , setSqlQueriesCount ] = useState ( 0 ) ;
3536 const [ sqlData , setSqlData ] = useState ( "" ) ;
@@ -43,15 +44,21 @@ export default function ApiAction(props: Props) {
4344 const [ responseHeaders , setResponseHeaders ] = useState ( "" ) ;
4445 const [ activeTab , setActiveTab ] = useState ( 'info' ) ;
4546
46- const handleFileChange = ( files : any , file : any ) => {
47- const formData : any = new FormData ( )
48- if ( file . includes ( '.*' ) ) {
49- const fileParam = file . replace ( '.*' , '' )
47+ const handleFileChange = ( files : any , key : any ) => {
48+ const formData = fileParams || new FormData ( ) ;
49+ const parts = key . split ( '.' ) ;
50+ const fileKey = key . split ( "." ) . reduce ( ( current : string , part : string , index : number ) => {
51+ if ( index === parts . length - 1 && ( part === '*' || ! isNaN ( Number ( part ) ) ) ) {
52+ return current
53+ }
54+ return ! current ? part : `${ current } [${ part } ]`
55+ } , '' )
56+ if ( key . includes ( '.*' ) ) {
5057 for ( let i = 0 ; i < files . length ; i ++ ) {
51- formData . append ( `${ fileParam } [${ i } ]` , files [ i ] ) ;
58+ formData . append ( `${ fileKey } [${ i } ]` , files [ i ] ) ;
5259 }
5360 } else {
54- formData . append ( file , files [ 0 ] )
61+ formData . append ( fileKey , files [ 0 ] )
5562 }
5663 setFileParams ( formData )
5764 }
@@ -79,7 +86,7 @@ export default function ApiAction(props: Props) {
7986 }
8087 const headers = JSON . parse ( requestHeaders )
8188 headers [ 'X-Request-LRD' ] = true
82- if ( fileParams != null ) {
89+ if ( fileParams ) {
8390 delete headers [ 'Content-Type' ]
8491 headers [ 'Accept' ] = 'multipart/form-data'
8592 }
@@ -90,13 +97,11 @@ export default function ApiAction(props: Props) {
9097 headers : headers ,
9198 }
9299
100+
93101 if ( method == 'POST' || method == 'PUT' || method == 'PATCH' ) {
94102 try {
95- JSON . parse ( bodyParams )
96103 if ( fileParams != null ) {
97- for ( const [ key , value ] of Object . entries ( JSON . parse ( bodyParams ) ) ) {
98- fileParams . append ( key , value )
99- }
104+ objectToFormData ( JSON . parse ( bodyParams ) , fileParams as FormData )
100105 }
101106
102107 } catch ( error : any ) {
@@ -201,10 +206,14 @@ export default function ApiAction(props: Props) {
201206 let index = 0
202207 for ( const [ key ] of Object . entries ( lrdDocsItem . rules ) ) {
203208 index ++
209+ const parts = key . split ( '.' ) ;
210+ const queryKey = parts . reduce ( ( current : string , part : string ) => {
211+ return current ? `${ current } [${ part !== '*' ? part : 0 } ]` : part
212+ } , '' )
204213 if ( index == 1 ) {
205- queries += `?${ key } =\n`
214+ queries += `?${ queryKey } =\n`
206215 } else {
207- queries += `&${ key } =\n`
216+ queries += `&${ queryKey } =\n`
208217 }
209218 }
210219 setQueryParams ( queries )
@@ -217,30 +226,39 @@ export default function ApiAction(props: Props) {
217226 setCurlCommand ( makeCurlCommand ( host , lrdDocsItem . uri , method , cached , requestHeaders ) )
218227 return
219228 }
220- const body : any = { }
221- for ( const [ key , rule ] of Object . entries ( lrdDocsItem . rules ) ) {
229+ const body : any = Object . entries ( lrdDocsItem . rules ) . reduce ( ( acc , [ key , rule ] ) => {
222230 if ( rule . length == 0 ) {
223- continue
231+ return acc
224232 }
225- const theRule = rule [ 0 ] . split ( "|" )
226- if ( theRule . includes ( 'file' ) || theRule . includes ( 'image' ) ) {
227- continue
228- }
229- if ( key . includes ( ".*" ) ) {
230- body [ key ] = [ ]
231- continue
233+
234+ const ruleObj = rule [ 0 ] . split ( '|' ) ;
235+
236+ if ( ruleObj . includes ( 'file' ) || ruleObj . includes ( 'image' ) ) {
237+ return acc
232238 }
233- if ( key . includes ( "." ) ) {
234- const keys = key . split ( "." )
235- if ( keys . length == 2 ) {
236- body [ keys [ 0 ] ] = { }
237- body [ keys [ 0 ] ] [ keys [ 1 ] ] = ""
239+
240+ const keys = key . split ( '.' ) ;
241+ keys . reduce ( ( current : any , key , index ) => {
242+ key = key === "*" ? "0" : key ;
243+ if ( index === keys . length - 1 ) {
244+ if ( ! isNaN ( Number ( key ) ) ) {
245+ current = ! Array . isArray ( current ) ? [ ] : current ;
246+ return current
247+ }
248+ current [ key ] = ruleObj . includes ( 'array' ) ? [ ] : "" ;
249+ } else {
250+ if ( ruleObj . includes ( 'array' ) || keys [ index + 1 ] === "*" || ! isNaN ( Number ( keys [ index + 1 ] ) ) ) {
251+ current [ key ] = current [ key ] || [ ] ;
252+ } else {
253+ current [ key ] = current [ key ] || { } ;
254+ }
238255 }
239- continue
240- }
256+ return current [ key ] ;
257+ } , acc ) ;
258+
259+ return acc ;
260+ } , { } )
241261
242- body [ key ] = ""
243- }
244262 const jsonBody = JSON . stringify ( body , null , 2 )
245263 setBodyParams ( jsonBody )
246264 setCurlCommand ( makeCurlCommand ( host , lrdDocsItem . uri , method , jsonBody , requestHeaders ) )
0 commit comments