@@ -991,6 +991,23 @@ impl FunctionAnalyzer<'_> {
991
991
* prop == * "get" || * prop == * "getSecret" || * prop == * "query"
992
992
}
993
993
994
+ fn resolve_jira_api_type ( url : & str ) -> Option < IntrinsicName > {
995
+ match url {
996
+ url if url. starts_with ( "/rest/servicedeskapi/" ) => {
997
+ Some ( IntrinsicName :: RequestJiraServiceManagement )
998
+ }
999
+ url if url. starts_with ( "/rest/agile/" ) => Some ( IntrinsicName :: RequestJiraSoftware ) ,
1000
+ // Accept Jira API v2.0 or v3.0
1001
+ url if url. starts_with ( "/rest/api/3/" ) || url. starts_with ( "/rest/api/2/" ) => {
1002
+ Some ( IntrinsicName :: RequestJira )
1003
+ }
1004
+ _ => {
1005
+ warn ! ( "Invalid Jira API URL format: {}" , url) ;
1006
+ None
1007
+ }
1008
+ }
1009
+ }
1010
+
994
1011
match * callee {
995
1012
[ PropPath :: Unknown ( ( ref name, ..) ) ] if * name == * "fetch" => Some ( Intrinsic :: Fetch ) ,
996
1013
[ PropPath :: Def ( def) , ref authn @ .., PropPath :: Static ( ref last) ]
@@ -1000,15 +1017,35 @@ impl FunctionAnalyzer<'_> {
1000
1017
&& Some ( & ImportKind :: Default )
1001
1018
== self . res . is_imported_from ( def, "@forge/api" ) =>
1002
1019
{
1020
+ let first_arg = first_arg?;
1021
+ let is_as_app = authn. first ( ) == Some ( & PropPath :: MemberCall ( "asApp" . into ( ) ) ) ;
1022
+
1003
1023
let function_name = if * last == "requestJira" {
1004
- IntrinsicName :: RequestJira
1024
+ // Resolve Jira API requests to either JSM/JS/Jira as all are bundled within requestJira()
1025
+ match first_arg {
1026
+ Expr :: Tpl ( template) => {
1027
+ let url = template
1028
+ . quasis
1029
+ . iter ( )
1030
+ . map ( |quasi| quasi. raw . as_str ( ) )
1031
+ . collect :: < String > ( ) ;
1032
+
1033
+ resolve_jira_api_type ( & url) . unwrap_or_else ( || {
1034
+ warn ! ( "Falling back to generic Jira request" ) ;
1035
+ IntrinsicName :: RequestJira // TODO: how should we handle this edge case?
1036
+ } )
1037
+ }
1038
+ _ => {
1039
+ warn ! ( "First parameter to requestJira() is invalid" ) ;
1040
+ IntrinsicName :: RequestJira // TODO: how should we handle this edge case?
1041
+ }
1042
+ }
1005
1043
} else if * last == "requestBitbucket" {
1006
1044
IntrinsicName :: RequestBitbucket
1007
1045
} else {
1008
1046
IntrinsicName :: RequestConfluence
1009
1047
} ;
1010
- let first_arg = first_arg?;
1011
- let is_as_app = authn. first ( ) == Some ( & PropPath :: MemberCall ( "asApp" . into ( ) ) ) ;
1048
+
1012
1049
match classify_api_call ( first_arg) {
1013
1050
ApiCallKind :: Unknown => {
1014
1051
if is_as_app {
0 commit comments