@@ -254,7 +254,7 @@ module ClientRequest {
254254 method = "request" and
255255 result = this .getOptionArgument ( 0 , "data" )
256256 or
257- method = [ "post" , "put" ] and
257+ method = [ "post" , "put" , "patch" ] and
258258 result = [ this .getArgument ( 1 ) , this .getOptionArgument ( 2 , "data" ) ]
259259 or
260260 method = [ "postForm" , "putForm" , "patchForm" ] and result = this .getArgument ( 1 )
@@ -289,6 +289,69 @@ module ClientRequest {
289289 }
290290 }
291291
292+ /**
293+ * A model of a `axios` instance request.
294+ */
295+ class AxiosInstanceRequest extends ClientRequest:: Range , API:: CallNode {
296+ string method ;
297+ API:: CallNode instance ;
298+
299+ // Instances of axios, e.g. `axios.create({ ... })`
300+ AxiosInstanceRequest ( ) {
301+ instance = axios ( ) .getMember ( [ "create" , "createInstance" ] ) .getACall ( ) and
302+ method = [ httpMethodName ( ) , "request" , "postForm" , "putForm" , "patchForm" , "getUri" ] and
303+ this = instance .getReturn ( ) .getMember ( method ) .getACall ( )
304+ }
305+
306+ private int getOptionsArgIndex ( ) {
307+ ( method = "get" or method = "delete" or method = "head" ) and
308+ result = 0
309+ or
310+ ( method = "post" or method = "put" or method = "patch" ) and
311+ result = 1
312+ }
313+
314+ private DataFlow:: Node getOptionArgument ( string name ) {
315+ result = this .getOptionArgument ( this .getOptionsArgIndex ( ) , name )
316+ }
317+
318+ override DataFlow:: Node getUrl ( ) {
319+ result = this .getArgument ( 0 ) or
320+ result = this .getOptionArgument ( urlPropertyName ( ) )
321+ }
322+
323+ override DataFlow:: Node getHost ( ) { result = instance .getOptionArgument ( 0 , "baseURL" ) }
324+
325+ override DataFlow:: Node getADataNode ( ) {
326+ method = [ "post" , "put" , "patch" ] and
327+ result = [ this .getArgument ( 1 ) , this .getOptionArgument ( 2 , "data" ) ]
328+ or
329+ method = [ "postForm" , "putForm" , "patchForm" ] and result = this .getArgument ( 1 )
330+ or
331+ result = this .getOptionArgument ( [ 0 .. 2 ] , [ "headers" , "params" ] )
332+ }
333+
334+ /** Gets the response type from the options passed in. */
335+ string getResponseType ( ) {
336+ exists ( DataFlow:: Node option | option = instance .getOptionArgument ( 0 , "responseType" ) |
337+ option .mayHaveStringValue ( result )
338+ )
339+ or
340+ not exists ( this .getOptionArgument ( "responseType" ) ) and
341+ result = "json"
342+ }
343+
344+ override DataFlow:: Node getAResponseDataNode ( string responseType , boolean promise ) {
345+ responseType = this .getResponseType ( ) and
346+ promise = true and
347+ result = this
348+ or
349+ responseType = this .getResponseType ( ) and
350+ promise = false and
351+ result = this .getReturn ( ) .getPromisedError ( ) .getMember ( "response" ) .asSource ( )
352+ }
353+ }
354+
292355 /** An expression that is used as a credential in a request. */
293356 private class AuthorizationHeader extends CredentialsNode {
294357 AuthorizationHeader ( ) {
0 commit comments