mobbdev 1.0.53 → 1.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +1104 -862
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -25,7 +25,7 @@ import chalk10 from "chalk";
25
25
  import yargs from "yargs/yargs";
26
26
 
27
27
  // src/args/commands/analyze.ts
28
- import fs5 from "node:fs";
28
+ import fs4 from "node:fs";
29
29
 
30
30
  // src/commands/index.ts
31
31
  import crypto from "node:crypto";
@@ -123,6 +123,7 @@ var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
123
123
  IssueType_Enum2["DefaultRightsInObjDefinition"] = "DEFAULT_RIGHTS_IN_OBJ_DEFINITION";
124
124
  IssueType_Enum2["DeprecatedFunction"] = "DEPRECATED_FUNCTION";
125
125
  IssueType_Enum2["DosStringBuilder"] = "DOS_STRING_BUILDER";
126
+ IssueType_Enum2["DuplicatedStrings"] = "DUPLICATED_STRINGS";
126
127
  IssueType_Enum2["ErroneousStringCompare"] = "ERRONEOUS_STRING_COMPARE";
127
128
  IssueType_Enum2["ErrorCondtionWithoutAction"] = "ERROR_CONDTION_WITHOUT_ACTION";
128
129
  IssueType_Enum2["FrameableLoginPage"] = "FRAMEABLE_LOGIN_PAGE";
@@ -144,6 +145,7 @@ var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
144
145
  IssueType_Enum2["InsecureBinderConfiguration"] = "INSECURE_BINDER_CONFIGURATION";
145
146
  IssueType_Enum2["InsecureCookie"] = "INSECURE_COOKIE";
146
147
  IssueType_Enum2["InsecureRandomness"] = "INSECURE_RANDOMNESS";
148
+ IssueType_Enum2["InsecureUuidVersion"] = "INSECURE_UUID_VERSION";
147
149
  IssueType_Enum2["InsufficientLogging"] = "INSUFFICIENT_LOGGING";
148
150
  IssueType_Enum2["JqueryDeprecatedSymbols"] = "JQUERY_DEPRECATED_SYMBOLS";
149
151
  IssueType_Enum2["LeftoverDebugCode"] = "LEFTOVER_DEBUG_CODE";
@@ -221,19 +223,20 @@ var Vulnerability_Report_Issue_State_Enum = /* @__PURE__ */ ((Vulnerability_Repo
221
223
  Vulnerability_Report_Issue_State_Enum2["Unsupported"] = "Unsupported";
222
224
  return Vulnerability_Report_Issue_State_Enum2;
223
225
  })(Vulnerability_Report_Issue_State_Enum || {});
224
- var Vulnerability_Report_Issue_Tag_Enum = /* @__PURE__ */ ((Vulnerability_Report_Issue_Tag_Enum2) => {
225
- Vulnerability_Report_Issue_Tag_Enum2["AutogeneratedCode"] = "AUTOGENERATED_CODE";
226
- Vulnerability_Report_Issue_Tag_Enum2["AuxiliaryCode"] = "AUXILIARY_CODE";
227
- Vulnerability_Report_Issue_Tag_Enum2["FalsePositive"] = "FALSE_POSITIVE";
228
- Vulnerability_Report_Issue_Tag_Enum2["TestCode"] = "TEST_CODE";
229
- Vulnerability_Report_Issue_Tag_Enum2["VendorCode"] = "VENDOR_CODE";
230
- return Vulnerability_Report_Issue_Tag_Enum2;
226
+ var Vulnerability_Report_Issue_Tag_Enum = /* @__PURE__ */ ((Vulnerability_Report_Issue_Tag_Enum3) => {
227
+ Vulnerability_Report_Issue_Tag_Enum3["AutogeneratedCode"] = "AUTOGENERATED_CODE";
228
+ Vulnerability_Report_Issue_Tag_Enum3["AuxiliaryCode"] = "AUXILIARY_CODE";
229
+ Vulnerability_Report_Issue_Tag_Enum3["FalsePositive"] = "FALSE_POSITIVE";
230
+ Vulnerability_Report_Issue_Tag_Enum3["TestCode"] = "TEST_CODE";
231
+ Vulnerability_Report_Issue_Tag_Enum3["VendorCode"] = "VENDOR_CODE";
232
+ return Vulnerability_Report_Issue_Tag_Enum3;
231
233
  })(Vulnerability_Report_Issue_Tag_Enum || {});
232
234
  var Vulnerability_Report_Vendor_Enum = /* @__PURE__ */ ((Vulnerability_Report_Vendor_Enum3) => {
233
235
  Vulnerability_Report_Vendor_Enum3["Checkmarx"] = "checkmarx";
234
236
  Vulnerability_Report_Vendor_Enum3["CheckmarxXml"] = "checkmarxXml";
235
237
  Vulnerability_Report_Vendor_Enum3["Codeql"] = "codeql";
236
238
  Vulnerability_Report_Vendor_Enum3["Fortify"] = "fortify";
239
+ Vulnerability_Report_Vendor_Enum3["Opengrep"] = "opengrep";
237
240
  Vulnerability_Report_Vendor_Enum3["Semgrep"] = "semgrep";
238
241
  Vulnerability_Report_Vendor_Enum3["Snyk"] = "snyk";
239
242
  Vulnerability_Report_Vendor_Enum3["Sonarqube"] = "sonarqube";
@@ -411,8 +414,12 @@ var GetVulByNodesMetadataDocument = `
411
414
  path
412
415
  startLine
413
416
  vulnerabilityReportIssue {
414
- issueType
417
+ parsedIssueType
415
418
  fixId
419
+ category
420
+ vulnerabilityReportIssueTags {
421
+ tag: vulnerability_report_issue_tag_value
422
+ }
416
423
  }
417
424
  }
418
425
  fixablePrVuls: vulnerability_report_issue_aggregate(
@@ -436,6 +443,25 @@ var GetVulByNodesMetadataDocument = `
436
443
  count
437
444
  }
438
445
  }
446
+ irrelevantVulnerabilityReportIssue: vulnerability_report(
447
+ where: {id: {_eq: $vulnerabilityReportId}}
448
+ ) {
449
+ vulnerabilityReportIssues(
450
+ where: {fixId: {_is_null: true}, _or: [{category: {_eq: "Irrelevant"}}, {category: {_eq: "FalsePositive"}}]}
451
+ ) {
452
+ id
453
+ parsedIssueType
454
+ fixId
455
+ category
456
+ vulnerabilityReportIssueTags {
457
+ tag: vulnerability_report_issue_tag_value
458
+ }
459
+ codeNodes(order_by: {index: desc}, where: {_or: $filters}) {
460
+ path
461
+ startLine
462
+ }
463
+ }
464
+ }
439
465
  }
440
466
  `;
441
467
  var UpdateScmTokenDocument = `
@@ -898,7 +924,7 @@ var FixPageFixReportZ = z3.object({
898
924
 
899
925
  // src/features/analysis/scm/shared/src/types/issue.ts
900
926
  var MAX_SOURCE_CODE_FILE_SIZE_IN_BYTES = 1e5;
901
- var category = {
927
+ var CATEGORY = {
902
928
  NoFix: "NoFix",
903
929
  Unsupported: "Unsupported",
904
930
  Irrelevant: "Irrelevant",
@@ -906,11 +932,11 @@ var category = {
906
932
  Fixable: "Fixable"
907
933
  };
908
934
  var ValidCategoriesZ = z4.union([
909
- z4.literal(category.NoFix),
910
- z4.literal(category.Unsupported),
911
- z4.literal(category.Irrelevant),
912
- z4.literal(category.FalsePositive),
913
- z4.literal(category.Fixable)
935
+ z4.literal(CATEGORY.NoFix),
936
+ z4.literal(CATEGORY.Unsupported),
937
+ z4.literal(CATEGORY.Irrelevant),
938
+ z4.literal(CATEGORY.FalsePositive),
939
+ z4.literal(CATEGORY.Fixable)
914
940
  ]);
915
941
  var BaseIssuePartsZ = z4.object({
916
942
  id: z4.string().uuid(),
@@ -919,6 +945,10 @@ var BaseIssuePartsZ = z4.object({
919
945
  createdAt: z4.string(),
920
946
  parsedSeverity: ParsedSeverityZ,
921
947
  category: ValidCategoriesZ,
948
+ extraData: z4.object({
949
+ missing_files: z4.string().array().nullish(),
950
+ error_files: z4.string().array().nullish()
951
+ }),
922
952
  vulnerabilityReportIssueTags: z4.array(
923
953
  z4.object({
924
954
  tag: z4.nativeEnum(Vulnerability_Report_Issue_Tag_Enum)
@@ -967,13 +997,13 @@ var FalsePositivePartsZ = z4.object({
967
997
  });
968
998
  var IssuePartsWithFixZ = BaseIssuePartsZ.merge(
969
999
  z4.object({
970
- category: z4.literal(category.Irrelevant),
1000
+ category: z4.literal(CATEGORY.Irrelevant),
971
1001
  fix: FixPartsForFixScreenZ.nullish()
972
1002
  })
973
1003
  );
974
1004
  var IssuePartsFpZ = BaseIssuePartsZ.merge(
975
1005
  z4.object({
976
- category: z4.literal(category.FalsePositive),
1006
+ category: z4.literal(CATEGORY.FalsePositive),
977
1007
  fpId: z4.string().uuid(),
978
1008
  getFalsePositive: FalsePositivePartsZ
979
1009
  })
@@ -981,9 +1011,9 @@ var IssuePartsFpZ = BaseIssuePartsZ.merge(
981
1011
  var GeneralIssueZ = BaseIssuePartsZ.merge(
982
1012
  z4.object({
983
1013
  category: z4.union([
984
- z4.literal(category.NoFix),
985
- z4.literal(category.Unsupported),
986
- z4.literal(category.Fixable)
1014
+ z4.literal(CATEGORY.NoFix),
1015
+ z4.literal(CATEGORY.Unsupported),
1016
+ z4.literal(CATEGORY.Fixable)
987
1017
  ])
988
1018
  })
989
1019
  );
@@ -1008,6 +1038,13 @@ var GetIssueScreenDataZ = z4.object({
1008
1038
  issueIndexes: GetIssueIndexesZ
1009
1039
  });
1010
1040
  var IssueBucketZ = z4.enum(["fixable", "irrelevant", "remaining"]);
1041
+ var mapCategoryToBucket = {
1042
+ FalsePositive: "irrelevant",
1043
+ Irrelevant: "irrelevant",
1044
+ NoFix: "remaining",
1045
+ Unsupported: "remaining",
1046
+ Fixable: "fixable"
1047
+ };
1011
1048
 
1012
1049
  // src/features/analysis/scm/shared/src/types/types.ts
1013
1050
  import { z as z7 } from "zod";
@@ -1102,7 +1139,9 @@ var issueTypeMap = {
1102
1139
  ["FRAMEABLE_LOGIN_PAGE" /* FrameableLoginPage */]: "Frameable Login Page",
1103
1140
  ["USE_OF_HARD_CODED_CRYPTOGRAPHIC_KEY" /* UseOfHardCodedCryptographicKey */]: "Use of Hardcoded Cryptographic Key",
1104
1141
  ["MISSING_SSL_MINVERSION" /* MissingSslMinversion */]: "Missing SSL MinVersion",
1105
- ["WEBSOCKET_MISSING_ORIGIN_CHECK" /* WebsocketMissingOriginCheck */]: "Missing Websocket Origin Check"
1142
+ ["WEBSOCKET_MISSING_ORIGIN_CHECK" /* WebsocketMissingOriginCheck */]: "Missing Websocket Origin Check",
1143
+ ["DUPLICATED_STRINGS" /* DuplicatedStrings */]: "String Literals Should not Be Duplicated",
1144
+ ["INSECURE_UUID_VERSION" /* InsecureUuidVersion */]: "Insecure UUID Version"
1106
1145
  };
1107
1146
  var issueTypeZ = z5.nativeEnum(IssueType_Enum);
1108
1147
  var getIssueTypeFriendlyString = (issueType) => {
@@ -1112,6 +1151,29 @@ var getIssueTypeFriendlyString = (issueType) => {
1112
1151
  }
1113
1152
  return issueTypeMap[issueTypeZParseRes.data];
1114
1153
  };
1154
+ function getTagTooltip(tag) {
1155
+ switch (tag) {
1156
+ case "FALSE_POSITIVE":
1157
+ return "Issue was found to be a false positive";
1158
+ case "TEST_CODE":
1159
+ return "Issue found in test files, not production code";
1160
+ case "VENDOR_CODE":
1161
+ return "Issue is in external libraries or dependencies not owned or maintained by your team";
1162
+ case "AUTOGENERATED_CODE":
1163
+ return "Code created by tools or frameworks, not manually written";
1164
+ case "AUXILIARY_CODE":
1165
+ return "Issue found in supporting files that don\u2019t impact core functionality";
1166
+ default:
1167
+ return tag;
1168
+ }
1169
+ }
1170
+ var issueDescription = {
1171
+ ["AUTOGENERATED_CODE" /* AutogeneratedCode */]: "The flagged code is generated automatically by tools or frameworks as part of the build or runtime process. This categorization highlights that **the issue resides in non-manual code**, which often requires tool-specific solutions or exemptions.",
1172
+ ["AUXILIARY_CODE" /* AuxiliaryCode */]: "The flagged code is auxiliary or supporting code, such as configuration files, build scripts, or other non-application logic. This categorization indicates that the issue is not directly related to the application\u2019s core functionality.",
1173
+ ["FALSE_POSITIVE" /* FalsePositive */]: "The flagged code **does not represent an actual vulnerability within the application\u2019s context.** This categorization indicates that the issue is either misidentified by the scanner or deemed irrelevant to the application\u2019s functionality.",
1174
+ ["TEST_CODE" /* TestCode */]: "The flagged code resides in a test-specific path or context. This categorization indicates that **it supports testing scenarios and is isolated from production use**.",
1175
+ ["VENDOR_CODE" /* VendorCode */]: "The flagged code originates from a third-party library or dependency maintained externally. This categorization suggests that **the issue lies outside the application\u2019s direct control** and should be addressed by the vendor if necessary."
1176
+ };
1115
1177
 
1116
1178
  // src/features/analysis/scm/shared/src/validations.ts
1117
1179
  var IssueTypeSettingZ = z6.object({
@@ -1605,9 +1667,9 @@ var progressMassages = {
1605
1667
  var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 30;
1606
1668
 
1607
1669
  // src/features/analysis/index.ts
1608
- import fs4 from "node:fs";
1670
+ import fs3 from "node:fs";
1609
1671
  import fsPromises from "node:fs/promises";
1610
- import path7 from "node:path";
1672
+ import path6 from "node:path";
1611
1673
  import { env as env2 } from "node:process";
1612
1674
  import { pipeline } from "node:stream/promises";
1613
1675
 
@@ -1721,18 +1783,14 @@ import extract from "extract-zip";
1721
1783
  import { createSpinner as createSpinner4 } from "nanospinner";
1722
1784
  import fetch4 from "node-fetch";
1723
1785
  import open2 from "open";
1724
- import tmp2 from "tmp";
1725
- import { z as z31 } from "zod";
1786
+ import tmp from "tmp";
1787
+ import { z as z29 } from "zod";
1726
1788
 
1727
1789
  // src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
1728
1790
  import Debug8 from "debug";
1729
1791
 
1730
- // src/features/analysis/scm/github/github.ts
1731
- import { RequestError } from "@octokit/request-error";
1732
-
1733
- // src/features/analysis/scm/constants.ts
1734
- var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
1735
- var MAX_BRANCHES_FETCH = 1e3;
1792
+ // src/features/analysis/scm/github/GithubSCMLib.ts
1793
+ import { z as z24 } from "zod";
1736
1794
 
1737
1795
  // src/features/analysis/scm/errors.ts
1738
1796
  var InvalidRepoUrlError = class extends Error {
@@ -1762,6 +1820,21 @@ var RepoNoTokenAccessError = class extends Error {
1762
1820
  }
1763
1821
  };
1764
1822
 
1823
+ // src/features/analysis/scm/scmSubmit/index.ts
1824
+ import { simpleGit } from "simple-git";
1825
+ var isValidBranchName = async (branchName) => {
1826
+ const git = simpleGit();
1827
+ try {
1828
+ const res = await git.raw(["check-ref-format", "--branch", branchName]);
1829
+ if (res) {
1830
+ return true;
1831
+ }
1832
+ return false;
1833
+ } catch (e) {
1834
+ return false;
1835
+ }
1836
+ };
1837
+
1765
1838
  // src/features/analysis/scm/types.ts
1766
1839
  import { z as z14 } from "zod";
1767
1840
 
@@ -2007,13 +2080,20 @@ var fixDetailsData = {
2007
2080
  ["FRAMEABLE_LOGIN_PAGE" /* FrameableLoginPage */]: void 0,
2008
2081
  ["USE_OF_HARD_CODED_CRYPTOGRAPHIC_KEY" /* UseOfHardCodedCryptographicKey */]: void 0,
2009
2082
  ["MISSING_SSL_MINVERSION" /* MissingSslMinversion */]: void 0,
2010
- ["WEBSOCKET_MISSING_ORIGIN_CHECK" /* WebsocketMissingOriginCheck */]: void 0
2083
+ ["WEBSOCKET_MISSING_ORIGIN_CHECK" /* WebsocketMissingOriginCheck */]: void 0,
2084
+ ["DUPLICATED_STRINGS" /* DuplicatedStrings */]: void 0,
2085
+ ["INSECURE_UUID_VERSION" /* InsecureUuidVersion */]: void 0
2011
2086
  };
2012
2087
 
2013
2088
  // src/features/analysis/scm/shared/src/commitDescriptionMarkup.ts
2014
2089
  function capitalizeFirstLetter(str) {
2015
2090
  return str?.length ? str[0].toUpperCase() + str.slice(1) : "";
2016
2091
  }
2092
+ function lowercaseFirstLetter(str) {
2093
+ if (!str)
2094
+ return str;
2095
+ return `${str.charAt(0).toLowerCase()}${str.slice(1)}`;
2096
+ }
2017
2097
  var severityToEmoji = {
2018
2098
  ["critical" /* Critical */]: "\u{1F6A8}",
2019
2099
  ["high" /* High */]: "\u{1F6A9}",
@@ -2025,7 +2105,8 @@ var getCommitDescription = ({
2025
2105
  issueType,
2026
2106
  severity,
2027
2107
  guidances,
2028
- fixUrl
2108
+ fixUrl,
2109
+ irrelevantIssueWithTags
2029
2110
  }) => {
2030
2111
  const issueTypeString = getIssueTypeFriendlyString(issueType);
2031
2112
  let description = `This change fixes a **${severity} severity** (${severityToEmoji[severity]}) **${issueTypeString}** issue reported by **${capitalizeFirstLetter(
@@ -2035,6 +2116,17 @@ var getCommitDescription = ({
2035
2116
  `;
2036
2117
  const parseIssueTypeRes = z9.nativeEnum(IssueType_Enum).safeParse(issueType);
2037
2118
  if (issueType && parseIssueTypeRes.success) {
2119
+ if (irrelevantIssueWithTags?.[0]?.tag) {
2120
+ description += `
2121
+ > [!tip]
2122
+ > This issue was found to be irrelevant to your project - ${lowercaseFirstLetter(getTagTooltip(irrelevantIssueWithTags[0].tag))}.
2123
+ > Mobb recommends to ignore this issue, however fix is available if you think differently.
2124
+
2125
+
2126
+ ## Justification
2127
+ ${issueDescription[irrelevantIssueWithTags[0].tag]}
2128
+ `;
2129
+ }
2038
2130
  const staticData = fixDetailsData[parseIssueTypeRes.data];
2039
2131
  if (staticData) {
2040
2132
  description += `## Issue description
@@ -2056,6 +2148,36 @@ ${guidances.map(({ guidance }) => `## Additional actions required
2056
2148
  }
2057
2149
  return description;
2058
2150
  };
2151
+ var getCommitIssueDescription = ({
2152
+ vendor,
2153
+ issueType,
2154
+ irrelevantIssueWithTags
2155
+ }) => {
2156
+ const issueTypeString = getIssueTypeFriendlyString(issueType);
2157
+ let description = `The following issues reported by ${capitalizeFirstLetter(vendor)} on this PR were found to be irrelevant to your project:
2158
+ `;
2159
+ const parseIssueTypeRes = z9.nativeEnum(IssueType_Enum).safeParse(issueType);
2160
+ if (issueType && parseIssueTypeRes.success) {
2161
+ if (irrelevantIssueWithTags?.[0]?.tag) {
2162
+ description += `
2163
+ > [!tip]
2164
+ > ${issueTypeString} - ${lowercaseFirstLetter(getTagTooltip(irrelevantIssueWithTags[0].tag))}.
2165
+ > Mobb recommends to ignore this issue, however fix is available if you think differently.
2166
+
2167
+
2168
+ ## Justification
2169
+ ${issueDescription[irrelevantIssueWithTags[0].tag]}
2170
+ `;
2171
+ }
2172
+ const staticData = fixDetailsData[parseIssueTypeRes.data];
2173
+ if (staticData) {
2174
+ description += `## Issue description
2175
+ ${staticData.issueDescription}
2176
+ `;
2177
+ }
2178
+ }
2179
+ return description;
2180
+ };
2059
2181
 
2060
2182
  // src/features/analysis/scm/shared/src/guidances.ts
2061
2183
  import { z as z12 } from "zod";
@@ -2655,6 +2777,15 @@ var confusingNaming = {
2655
2777
  }
2656
2778
  };
2657
2779
 
2780
+ // src/features/analysis/scm/shared/src/storedQuestionData/java/duplicatedStrings.ts
2781
+ var duplicatedStrings = {
2782
+ constantName: {
2783
+ content: () => "New constant name",
2784
+ description: () => "",
2785
+ guidance: () => ""
2786
+ }
2787
+ };
2788
+
2658
2789
  // src/features/analysis/scm/shared/src/storedQuestionData/java/erroneousStringCompare.ts
2659
2790
  var erroneousStringCompare = {
2660
2791
  javaVersionGreaterOrEqual17: {
@@ -3051,7 +3182,8 @@ var vulnerabilities11 = {
3051
3182
  ["INSECURE_COOKIE" /* InsecureCookie */]: insecureCookie2,
3052
3183
  ["TRUST_BOUNDARY_VIOLATION" /* TrustBoundaryViolation */]: trustBoundaryViolation2,
3053
3184
  ["LEFTOVER_DEBUG_CODE" /* LeftoverDebugCode */]: leftoverDebugCode,
3054
- ["ERRONEOUS_STRING_COMPARE" /* ErroneousStringCompare */]: erroneousStringCompare
3185
+ ["ERRONEOUS_STRING_COMPARE" /* ErroneousStringCompare */]: erroneousStringCompare,
3186
+ ["DUPLICATED_STRINGS" /* DuplicatedStrings */]: duplicatedStrings
3055
3187
  };
3056
3188
  var java_default2 = vulnerabilities11;
3057
3189
 
@@ -3749,6 +3881,15 @@ function getFixUrl({
3749
3881
  }) {
3750
3882
  return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
3751
3883
  }
3884
+ function getIssueUrl({
3885
+ appBaseUrl,
3886
+ issueId,
3887
+ projectId,
3888
+ organizationId,
3889
+ analysisId
3890
+ }) {
3891
+ return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/issue/${issueId}`;
3892
+ }
3752
3893
 
3753
3894
  // src/features/analysis/scm/types.ts
3754
3895
  var ReferenceType = /* @__PURE__ */ ((ReferenceType2) => {
@@ -3788,100 +3929,8 @@ var GetRefererenceResultZ = z14.object({
3788
3929
  type: z14.nativeEnum(ReferenceType)
3789
3930
  });
3790
3931
 
3791
- // src/features/analysis/scm/github/consts.ts
3792
- var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
3793
- var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
3794
- var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
3795
- var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
3796
- var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
3797
- var REPLY_TO_CODE_REVIEW_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies";
3798
- var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
3799
- var POST_GENERAL_PR_COMMENT = "POST /repos/{owner}/{repo}/issues/{issue_number}/comments";
3800
- var GET_GENERAL_PR_COMMENTS = "GET /repos/{owner}/{repo}/issues/{issue_number}/comments";
3801
- var DELETE_GENERAL_PR_COMMENT = "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}";
3802
- var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
3803
- var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
3804
- var GET_USER = "GET /user";
3805
- var GET_USER_REPOS = "GET /user/repos";
3806
- var GET_REPO_BRANCHES = "GET /repos/{owner}/{repo}/branches";
3807
- var GET_BLAME_DOCUMENT = `
3808
- query GetBlame(
3809
- $owner: String!
3810
- $repo: String!
3811
- $ref: String!
3812
- $path: String!
3813
- ) {
3814
- repository(name: $repo, owner: $owner) {
3815
- # branch name
3816
- object(expression: $ref) {
3817
- # cast Target to a Commit
3818
- ... on Commit {
3819
- # full repo-relative path to blame file
3820
- blame(path: $path) {
3821
- ranges {
3822
- commit {
3823
- author {
3824
- user {
3825
- name
3826
- login
3827
- }
3828
- }
3829
- authoredDate
3830
- }
3831
- startingLine
3832
- endingLine
3833
- age
3834
- }
3835
- }
3836
- }
3837
-
3838
- }
3839
- }
3840
- }
3841
- `;
3842
-
3843
- // src/features/analysis/scm/github/utils/encrypt_secret.ts
3844
- import sodium from "libsodium-wrappers";
3845
- async function encryptSecret(secret, key) {
3846
- await sodium.ready;
3847
- const binkey = sodium.from_base64(key, sodium.base64_variants.ORIGINAL);
3848
- const binsec = sodium.from_string(secret);
3849
- const encBytes = sodium.crypto_box_seal(binsec, binkey);
3850
- return sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL);
3851
- }
3852
-
3853
- // src/features/analysis/scm/github/utils/utils.ts
3854
- import { Octokit } from "octokit";
3855
- import { fetch as fetch2, ProxyAgent as ProxyAgent2 } from "undici";
3856
-
3857
- // src/features/analysis/scm/ado/constants.ts
3858
- var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
3859
-
3860
- // src/features/analysis/scm/ado/utils.ts
3861
- import querystring from "node:querystring";
3862
- import * as api from "azure-devops-node-api";
3863
- import Debug2 from "debug";
3864
- import { z as z18 } from "zod";
3865
-
3866
- // src/features/analysis/scm/env.ts
3867
- import { z as z15 } from "zod";
3868
- var EnvVariablesZod = z15.object({
3869
- GITLAB_API_TOKEN: z15.string().optional(),
3870
- GITHUB_API_TOKEN: z15.string().optional(),
3871
- GIT_COMMITTER_EMAIL: z15.string().optional(),
3872
- GIT_COMMITTER_NAME: z15.string().optional(),
3873
- GIT_PROXY_HOST: z15.string()
3874
- });
3875
- var {
3876
- GITLAB_API_TOKEN,
3877
- GITHUB_API_TOKEN,
3878
- GIT_PROXY_HOST,
3879
- GIT_COMMITTER_EMAIL,
3880
- GIT_COMMITTER_NAME
3881
- } = EnvVariablesZod.parse(process.env);
3882
-
3883
3932
  // src/features/analysis/scm/utils/index.ts
3884
- import { z as z16 } from "zod";
3933
+ import { z as z15 } from "zod";
3885
3934
  function getFixUrlWithRedirect(params) {
3886
3935
  const {
3887
3936
  fixId,
@@ -3903,6 +3952,27 @@ function getFixUrlWithRedirect(params) {
3903
3952
  analysisId
3904
3953
  })}?${searchParams.toString()}`;
3905
3954
  }
3955
+ function getIssueUrlWithRedirect(params) {
3956
+ const {
3957
+ issueId,
3958
+ projectId,
3959
+ organizationId,
3960
+ analysisId,
3961
+ redirectUrl,
3962
+ appBaseUrl,
3963
+ commentId
3964
+ } = params;
3965
+ const searchParams = new URLSearchParams();
3966
+ searchParams.append("commit_redirect_url", redirectUrl);
3967
+ searchParams.append("comment_id", commentId.toString());
3968
+ return `${getIssueUrl({
3969
+ appBaseUrl,
3970
+ issueId,
3971
+ projectId,
3972
+ organizationId,
3973
+ analysisId
3974
+ })}?${searchParams.toString()}`;
3975
+ }
3906
3976
  function getCommitUrl(params) {
3907
3977
  const {
3908
3978
  fixId,
@@ -3924,6 +3994,27 @@ function getCommitUrl(params) {
3924
3994
  analysisId
3925
3995
  })}/commit?${searchParams.toString()}`;
3926
3996
  }
3997
+ function getCommitIssueUrl(params) {
3998
+ const {
3999
+ issueId,
4000
+ projectId,
4001
+ organizationId,
4002
+ analysisId,
4003
+ redirectUrl,
4004
+ appBaseUrl,
4005
+ commentId
4006
+ } = params;
4007
+ const searchParams = new URLSearchParams();
4008
+ searchParams.append("redirect_url", redirectUrl);
4009
+ searchParams.append("comment_id", commentId.toString());
4010
+ return `${getIssueUrl({
4011
+ appBaseUrl,
4012
+ issueId,
4013
+ projectId,
4014
+ organizationId,
4015
+ analysisId
4016
+ })}/commit?${searchParams.toString()}`;
4017
+ }
3927
4018
  var userNamePattern = /^(https?:\/\/)([^@]+@)?([^/]+\/.+)$/;
3928
4019
  var sshPattern = /^git@([\w.-]+):([\w./-]+)$/;
3929
4020
  function normalizeUrl(repoUrl) {
@@ -3950,7 +4041,7 @@ function shouldValidateUrl(repoUrl) {
3950
4041
  return repoUrl && isUrlHasPath(repoUrl);
3951
4042
  }
3952
4043
  function isBrokerUrl(url) {
3953
- return z16.string().uuid().safeParse(new URL(url).host).success;
4044
+ return z15.string().uuid().safeParse(new URL(url).host).success;
3954
4045
  }
3955
4046
  function buildAuthorizedRepoUrl(args) {
3956
4047
  const { url, username, password } = args;
@@ -3986,7 +4077,7 @@ function getCloudScmLibTypeFromUrl(url) {
3986
4077
  return void 0;
3987
4078
  }
3988
4079
  function getScmLibTypeFromScmType(scmType) {
3989
- const parsedScmType = z16.nativeEnum(ScmType).parse(scmType);
4080
+ const parsedScmType = z15.nativeEnum(ScmType).parse(scmType);
3990
4081
  return scmTypeToScmLibScmType[parsedScmType];
3991
4082
  }
3992
4083
  function getScmConfig({
@@ -4052,67 +4143,223 @@ function getScmConfig({
4052
4143
  };
4053
4144
  }
4054
4145
 
4055
- // src/features/analysis/scm/ado/validation.ts
4056
- import { z as z17 } from "zod";
4057
- var ValidPullRequestStatusZ = z17.union([
4058
- z17.literal(1 /* Active */),
4059
- z17.literal(2 /* Abandoned */),
4060
- z17.literal(3 /* Completed */)
4061
- ]);
4062
- var AdoAuthResultZ = z17.object({
4063
- access_token: z17.string().min(1),
4064
- token_type: z17.string().min(1),
4065
- refresh_token: z17.string().min(1)
4066
- });
4067
- var AdoAuthResultWithOrgsZ = AdoAuthResultZ.extend({
4068
- scmOrgs: z17.array(z17.string())
4069
- });
4070
- var profileZ = z17.object({
4071
- displayName: z17.string(),
4072
- publicAlias: z17.string().min(1),
4073
- emailAddress: z17.string(),
4074
- coreRevision: z17.number(),
4075
- timeStamp: z17.string(),
4076
- id: z17.string(),
4077
- revision: z17.number()
4078
- });
4079
- var accountsZ = z17.object({
4080
- count: z17.number(),
4081
- value: z17.array(
4082
- z17.object({
4083
- accountId: z17.string(),
4084
- accountUri: z17.string(),
4085
- accountName: z17.string()
4086
- })
4087
- )
4088
- });
4089
-
4090
- // src/features/analysis/scm/ado/utils.ts
4091
- var debug2 = Debug2("mobbdev:scm:ado");
4092
- function _getPublicAdoClient({
4093
- orgName,
4094
- origin: origin2
4095
- }) {
4096
- const orgUrl = `${origin2}/${orgName}`;
4097
- const authHandler = api.getPersonalAccessTokenHandler("");
4098
- authHandler.canHandleAuthentication = () => false;
4099
- authHandler.prepareRequest = (_options) => {
4100
- return;
4101
- };
4102
- const connection = new api.WebApi(orgUrl, authHandler);
4103
- return connection;
4104
- }
4105
- function removeTrailingSlash(str) {
4106
- return str.trim().replace(/\/+$/, "");
4107
- }
4108
- function parseAdoOwnerAndRepo(adoUrl) {
4109
- adoUrl = removeTrailingSlash(adoUrl);
4110
- const parsingResult = parseScmURL(adoUrl, "Ado" /* Ado */);
4111
- if (!parsingResult || parsingResult.scmType !== "Ado" /* Ado */) {
4112
- throw new InvalidUrlPatternError(`
4113
- : ${adoUrl}`);
4114
- }
4115
- const {
4146
+ // src/features/analysis/scm/scm.ts
4147
+ var SCMLib = class {
4148
+ constructor(url, accessToken, scmOrg) {
4149
+ __publicField(this, "url");
4150
+ __publicField(this, "accessToken");
4151
+ __publicField(this, "scmOrg");
4152
+ this.accessToken = accessToken;
4153
+ this.url = url;
4154
+ this.scmOrg = scmOrg;
4155
+ }
4156
+ async getUrlWithCredentials() {
4157
+ if (!this.url) {
4158
+ console.error("no url for getUrlWithCredentials()");
4159
+ throw new Error("no url");
4160
+ }
4161
+ const trimmedUrl = this.url.trim().replace(/\/$/, "");
4162
+ const accessToken = this.getAccessToken();
4163
+ if (!accessToken) {
4164
+ return trimmedUrl;
4165
+ }
4166
+ if (this.scmLibType === "ADO" /* ADO */) {
4167
+ const { host, protocol, pathname } = new URL(trimmedUrl);
4168
+ return `${protocol}//${accessToken}@${host}${pathname}`;
4169
+ }
4170
+ const finalUrl = this.scmLibType === "GITLAB" /* GITLAB */ ? `${trimmedUrl}.git` : trimmedUrl;
4171
+ const username = await this._getUsernameForAuthUrl();
4172
+ return buildAuthorizedRepoUrl({
4173
+ url: finalUrl,
4174
+ username,
4175
+ password: accessToken
4176
+ });
4177
+ }
4178
+ getAccessToken() {
4179
+ return this.accessToken || "";
4180
+ }
4181
+ getUrl() {
4182
+ return this.url;
4183
+ }
4184
+ getName() {
4185
+ if (!this.url) {
4186
+ return "";
4187
+ }
4188
+ return this.url.split("/").at(-1) || "";
4189
+ }
4190
+ _validateAccessToken() {
4191
+ if (!this.accessToken) {
4192
+ console.error("no access token");
4193
+ throw new Error("no access token");
4194
+ }
4195
+ }
4196
+ static async getIsValidBranchName(branchName) {
4197
+ return isValidBranchName(branchName);
4198
+ }
4199
+ _validateAccessTokenAndUrl() {
4200
+ this._validateAccessToken();
4201
+ this._validateUrl();
4202
+ }
4203
+ _validateUrl() {
4204
+ if (!this.url) {
4205
+ console.error("no url");
4206
+ throw new InvalidRepoUrlError("no url");
4207
+ }
4208
+ }
4209
+ };
4210
+
4211
+ // src/features/analysis/scm/github/github.ts
4212
+ import { RequestError } from "@octokit/request-error";
4213
+
4214
+ // src/features/analysis/scm/constants.ts
4215
+ var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
4216
+ var MAX_BRANCHES_FETCH = 1e3;
4217
+
4218
+ // src/features/analysis/scm/github/consts.ts
4219
+ var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
4220
+ var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
4221
+ var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
4222
+ var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
4223
+ var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
4224
+ var REPLY_TO_CODE_REVIEW_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies";
4225
+ var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
4226
+ var POST_GENERAL_PR_COMMENT = "POST /repos/{owner}/{repo}/issues/{issue_number}/comments";
4227
+ var GET_GENERAL_PR_COMMENTS = "GET /repos/{owner}/{repo}/issues/{issue_number}/comments";
4228
+ var DELETE_GENERAL_PR_COMMENT = "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}";
4229
+ var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
4230
+ var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
4231
+ var GET_USER = "GET /user";
4232
+ var GET_USER_REPOS = "GET /user/repos";
4233
+ var GET_REPO_BRANCHES = "GET /repos/{owner}/{repo}/branches";
4234
+ var GET_BLAME_DOCUMENT = `
4235
+ query GetBlame(
4236
+ $owner: String!
4237
+ $repo: String!
4238
+ $ref: String!
4239
+ $path: String!
4240
+ ) {
4241
+ repository(name: $repo, owner: $owner) {
4242
+ # branch name
4243
+ object(expression: $ref) {
4244
+ # cast Target to a Commit
4245
+ ... on Commit {
4246
+ # full repo-relative path to blame file
4247
+ blame(path: $path) {
4248
+ ranges {
4249
+ commit {
4250
+ author {
4251
+ user {
4252
+ name
4253
+ login
4254
+ }
4255
+ }
4256
+ authoredDate
4257
+ }
4258
+ startingLine
4259
+ endingLine
4260
+ age
4261
+ }
4262
+ }
4263
+ }
4264
+
4265
+ }
4266
+ }
4267
+ }
4268
+ `;
4269
+
4270
+ // src/features/analysis/scm/github/utils/encrypt_secret.ts
4271
+ import sodium from "libsodium-wrappers";
4272
+ async function encryptSecret(secret, key) {
4273
+ await sodium.ready;
4274
+ const binkey = sodium.from_base64(key, sodium.base64_variants.ORIGINAL);
4275
+ const binsec = sodium.from_string(secret);
4276
+ const encBytes = sodium.crypto_box_seal(binsec, binkey);
4277
+ return sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL);
4278
+ }
4279
+
4280
+ // src/features/analysis/scm/github/utils/utils.ts
4281
+ import { Octokit } from "octokit";
4282
+ import { fetch as fetch2, ProxyAgent as ProxyAgent2 } from "undici";
4283
+
4284
+ // src/features/analysis/scm/ado/constants.ts
4285
+ var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
4286
+
4287
+ // src/features/analysis/scm/ado/utils.ts
4288
+ import querystring from "node:querystring";
4289
+ import * as api from "azure-devops-node-api";
4290
+ import Debug2 from "debug";
4291
+ import { z as z18 } from "zod";
4292
+
4293
+ // src/features/analysis/scm/env.ts
4294
+ import { z as z16 } from "zod";
4295
+ var EnvVariablesZod = z16.object({
4296
+ GITLAB_API_TOKEN: z16.string().optional(),
4297
+ GITHUB_API_TOKEN: z16.string().optional(),
4298
+ GIT_PROXY_HOST: z16.string()
4299
+ });
4300
+ var { GITLAB_API_TOKEN, GITHUB_API_TOKEN, GIT_PROXY_HOST } = EnvVariablesZod.parse(process.env);
4301
+
4302
+ // src/features/analysis/scm/ado/validation.ts
4303
+ import { z as z17 } from "zod";
4304
+ var ValidPullRequestStatusZ = z17.union([
4305
+ z17.literal(1 /* Active */),
4306
+ z17.literal(2 /* Abandoned */),
4307
+ z17.literal(3 /* Completed */)
4308
+ ]);
4309
+ var AdoAuthResultZ = z17.object({
4310
+ access_token: z17.string().min(1),
4311
+ token_type: z17.string().min(1),
4312
+ refresh_token: z17.string().min(1)
4313
+ });
4314
+ var AdoAuthResultWithOrgsZ = AdoAuthResultZ.extend({
4315
+ scmOrgs: z17.array(z17.string())
4316
+ });
4317
+ var profileZ = z17.object({
4318
+ displayName: z17.string(),
4319
+ publicAlias: z17.string().min(1),
4320
+ emailAddress: z17.string(),
4321
+ coreRevision: z17.number(),
4322
+ timeStamp: z17.string(),
4323
+ id: z17.string(),
4324
+ revision: z17.number()
4325
+ });
4326
+ var accountsZ = z17.object({
4327
+ count: z17.number(),
4328
+ value: z17.array(
4329
+ z17.object({
4330
+ accountId: z17.string(),
4331
+ accountUri: z17.string(),
4332
+ accountName: z17.string()
4333
+ })
4334
+ )
4335
+ });
4336
+
4337
+ // src/features/analysis/scm/ado/utils.ts
4338
+ var debug2 = Debug2("mobbdev:scm:ado");
4339
+ function _getPublicAdoClient({
4340
+ orgName,
4341
+ origin: origin2
4342
+ }) {
4343
+ const orgUrl = `${origin2}/${orgName}`;
4344
+ const authHandler = api.getPersonalAccessTokenHandler("");
4345
+ authHandler.canHandleAuthentication = () => false;
4346
+ authHandler.prepareRequest = (_options) => {
4347
+ return;
4348
+ };
4349
+ const connection = new api.WebApi(orgUrl, authHandler);
4350
+ return connection;
4351
+ }
4352
+ function removeTrailingSlash(str) {
4353
+ return str.trim().replace(/\/+$/, "");
4354
+ }
4355
+ function parseAdoOwnerAndRepo(adoUrl) {
4356
+ adoUrl = removeTrailingSlash(adoUrl);
4357
+ const parsingResult = parseScmURL(adoUrl, "Ado" /* Ado */);
4358
+ if (!parsingResult || parsingResult.scmType !== "Ado" /* Ado */) {
4359
+ throw new InvalidUrlPatternError(`
4360
+ : ${adoUrl}`);
4361
+ }
4362
+ const {
4116
4363
  organization,
4117
4364
  repoName,
4118
4365
  projectName,
@@ -4429,7 +4676,7 @@ async function getAdoSdk(params) {
4429
4676
  const url = new URL(repoUrl);
4430
4677
  const origin2 = url.origin.toLowerCase().endsWith(".visualstudio.com") ? DEFUALT_ADO_ORIGIN : url.origin.toLowerCase();
4431
4678
  const params2 = `path=/&versionDescriptor[versionOptions]=0&versionDescriptor[versionType]=commit&versionDescriptor[version]=${branch}&resolveLfs=true&$format=zip&api-version=5.0&download=true`;
4432
- const path9 = [
4679
+ const path8 = [
4433
4680
  prefixPath,
4434
4681
  owner,
4435
4682
  projectName,
@@ -4440,7 +4687,7 @@ async function getAdoSdk(params) {
4440
4687
  "items",
4441
4688
  "items"
4442
4689
  ].filter(Boolean).join("/");
4443
- return new URL(`${path9}?${params2}`, origin2).toString();
4690
+ return new URL(`${path8}?${params2}`, origin2).toString();
4444
4691
  },
4445
4692
  async getAdoBranchList({ repoUrl }) {
4446
4693
  try {
@@ -4615,246 +4862,53 @@ async function getAdoRepoList({
4615
4862
  ...await getAdoClientParams({
4616
4863
  accessToken,
4617
4864
  tokenOrg: tokenOrg || org,
4618
- url: void 0
4619
- }),
4620
- orgName: org
4621
- });
4622
- const gitOrg = await orgApi.getGitApi();
4623
- const orgRepos = await gitOrg.getRepositories();
4624
- const repoInfoList = (await Promise.allSettled(
4625
- orgRepos.map(async (repo) => {
4626
- if (!repo.name || !repo.remoteUrl || !repo.defaultBranch) {
4627
- throw new InvalidRepoUrlError("bad repo");
4628
- }
4629
- const branch = await gitOrg.getBranch(
4630
- repo.name,
4631
- repo.defaultBranch.replace(/^refs\/heads\//, ""),
4632
- repo.project?.name
4633
- );
4634
- return {
4635
- repoName: repo.name,
4636
- repoUrl: repo.remoteUrl.replace(
4637
- /^[hH][tT][tT][pP][sS]:\/\/[^/]+@/,
4638
- "https://"
4639
- ),
4640
- repoOwner: org,
4641
- repoIsPublic: repo.project?.visibility === 2 /* Public */,
4642
- repoLanguages: [],
4643
- repoUpdatedAt: branch.commit?.committer?.date?.toDateString() || repo.project?.lastUpdateTime?.toDateString() || (/* @__PURE__ */ new Date()).toDateString()
4644
- };
4645
- })
4646
- )).reduce((acc, res) => {
4647
- if (res.status === "fulfilled") {
4648
- acc.push(res.value);
4649
- }
4650
- return acc;
4651
- }, []);
4652
- return repoInfoList;
4653
- })
4654
- )).reduce((acc, res) => {
4655
- if (res.status === "fulfilled") {
4656
- return acc.concat(res.value);
4657
- }
4658
- return acc;
4659
- }, []);
4660
- return repos;
4661
- }
4662
-
4663
- // src/features/analysis/scm/ado/AdoSCMLib.ts
4664
- import { setTimeout as setTimeout2 } from "node:timers/promises";
4665
-
4666
- // src/features/analysis/scm/scmSubmit/index.ts
4667
- import fs2 from "node:fs/promises";
4668
- import parseDiff from "parse-diff";
4669
- import path4 from "path";
4670
- import { simpleGit } from "simple-git";
4671
- import tmp from "tmp";
4672
- import { z as z20 } from "zod";
4673
-
4674
- // src/features/analysis/scm/scmSubmit/types.ts
4675
- import { z as z19 } from "zod";
4676
- var BaseSubmitToScmMessageZ = z19.object({
4677
- submitFixRequestId: z19.string().uuid(),
4678
- fixes: z19.array(
4679
- z19.object({
4680
- fixId: z19.string().uuid(),
4681
- patchesOriginalEncodingBase64: z19.array(z19.string()),
4682
- patches: z19.array(z19.string())
4683
- })
4684
- ),
4685
- commitHash: z19.string(),
4686
- repoUrl: z19.string(),
4687
- mobbUserEmail: z19.string(),
4688
- extraHeaders: z19.record(z19.string(), z19.string()).default({})
4689
- });
4690
- var submitToScmMessageType = {
4691
- commitToSameBranch: "commitToSameBranch",
4692
- submitFixesForDifferentBranch: "submitFixesForDifferentBranch"
4693
- };
4694
- var CommitToSameBranchParamsZ = BaseSubmitToScmMessageZ.merge(
4695
- z19.object({
4696
- type: z19.literal(submitToScmMessageType.commitToSameBranch),
4697
- branch: z19.string(),
4698
- commitMessages: z19.array(z19.string()),
4699
- commitDescriptions: z19.array(z19.string().nullish()),
4700
- githubCommentId: z19.number().nullish(),
4701
- prId: z19.number().nullish()
4702
- })
4703
- );
4704
- var SubmitFixesToDifferentBranchParamsZ = z19.object({
4705
- type: z19.literal(submitToScmMessageType.submitFixesForDifferentBranch),
4706
- submitBranch: z19.string(),
4707
- baseBranch: z19.string()
4708
- }).merge(BaseSubmitToScmMessageZ);
4709
- var SubmitFixesMessageZ = z19.union([
4710
- CommitToSameBranchParamsZ,
4711
- SubmitFixesToDifferentBranchParamsZ
4712
- ]);
4713
- var FixResponseArrayZ = z19.array(
4714
- z19.object({
4715
- fixId: z19.string().uuid()
4716
- })
4717
- );
4718
- var SubmitFixesBaseResponseMessageZ = z19.object({
4719
- mobbUserEmail: z19.string(),
4720
- submitFixRequestId: z19.string().uuid(),
4721
- submitBranches: z19.array(
4722
- z19.object({
4723
- branchName: z19.string(),
4724
- fixes: FixResponseArrayZ
4725
- })
4726
- ),
4727
- error: z19.object({
4728
- type: z19.enum([
4729
- "InitialRepoAccessError",
4730
- "PushBranchError",
4731
- "AllFixesConflictWithTargetBranchError",
4732
- "InternalFixConflictError",
4733
- "UnknownError"
4734
- ]),
4735
- info: z19.object({
4736
- message: z19.string(),
4737
- pushBranchName: z19.string().optional()
4738
- })
4739
- }).optional()
4740
- });
4741
- var authorSchemaZ = z19.object({
4742
- email: z19.string(),
4743
- name: z19.string()
4744
- }).nullable();
4745
- var summarySchemaZ = z19.object({
4746
- changes: z19.number(),
4747
- insertions: z19.number(),
4748
- deletions: z19.number()
4749
- });
4750
- var GitCommitZ = z19.object({
4751
- author: authorSchemaZ,
4752
- branch: z19.string(),
4753
- commit: z19.string(),
4754
- root: z19.boolean(),
4755
- summary: summarySchemaZ
4756
- });
4757
- var SubmitFixesToSameBranchResponseMessageZ = z19.object({
4758
- type: z19.literal(submitToScmMessageType.commitToSameBranch),
4759
- githubCommentId: z19.number().nullish(),
4760
- commits: z19.array(GitCommitZ),
4761
- prId: z19.number().nullish()
4762
- }).merge(SubmitFixesBaseResponseMessageZ);
4763
- var SubmitFixesToDifferentBranchResponseMessageZ = z19.object({
4764
- type: z19.literal(submitToScmMessageType.submitFixesForDifferentBranch),
4765
- githubCommentId: z19.number().optional()
4766
- }).merge(SubmitFixesBaseResponseMessageZ);
4767
- var SubmitFixesResponseMessageZ = z19.discriminatedUnion("type", [
4768
- SubmitFixesToSameBranchResponseMessageZ,
4769
- SubmitFixesToDifferentBranchResponseMessageZ
4770
- ]);
4771
-
4772
- // src/features/analysis/scm/scmSubmit/index.ts
4773
- var isValidBranchName = async (branchName) => {
4774
- const git = simpleGit();
4775
- try {
4776
- const res = await git.raw(["check-ref-format", "--branch", branchName]);
4777
- if (res) {
4778
- return true;
4779
- }
4780
- return false;
4781
- } catch (e) {
4782
- return false;
4783
- }
4784
- };
4785
- var FixesZ = z20.array(
4786
- z20.object({
4787
- fixId: z20.string(),
4788
- patchesOriginalEncodingBase64: z20.array(z20.string())
4789
- })
4790
- ).nonempty();
4791
-
4792
- // src/features/analysis/scm/scm.ts
4793
- var SCMLib = class {
4794
- constructor(url, accessToken, scmOrg) {
4795
- __publicField(this, "url");
4796
- __publicField(this, "accessToken");
4797
- __publicField(this, "scmOrg");
4798
- this.accessToken = accessToken;
4799
- this.url = url;
4800
- this.scmOrg = scmOrg;
4801
- }
4802
- async getUrlWithCredentials() {
4803
- if (!this.url) {
4804
- console.error("no url for getUrlWithCredentials()");
4805
- throw new Error("no url");
4806
- }
4807
- const trimmedUrl = this.url.trim().replace(/\/$/, "");
4808
- const accessToken = this.getAccessToken();
4809
- if (!accessToken) {
4810
- return trimmedUrl;
4811
- }
4812
- if (this.scmLibType === "ADO" /* ADO */) {
4813
- const { host, protocol, pathname } = new URL(trimmedUrl);
4814
- return `${protocol}//${accessToken}@${host}${pathname}`;
4815
- }
4816
- const finalUrl = this.scmLibType === "GITLAB" /* GITLAB */ ? `${trimmedUrl}.git` : trimmedUrl;
4817
- const username = await this._getUsernameForAuthUrl();
4818
- return buildAuthorizedRepoUrl({
4819
- url: finalUrl,
4820
- username,
4821
- password: accessToken
4822
- });
4823
- }
4824
- getAccessToken() {
4825
- return this.accessToken || "";
4826
- }
4827
- getUrl() {
4828
- return this.url;
4829
- }
4830
- getName() {
4831
- if (!this.url) {
4832
- return "";
4833
- }
4834
- return this.url.split("/").at(-1) || "";
4835
- }
4836
- _validateAccessToken() {
4837
- if (!this.accessToken) {
4838
- console.error("no access token");
4839
- throw new Error("no access token");
4840
- }
4841
- }
4842
- static async getIsValidBranchName(branchName) {
4843
- return isValidBranchName(branchName);
4844
- }
4845
- _validateAccessTokenAndUrl() {
4846
- this._validateAccessToken();
4847
- this._validateUrl();
4848
- }
4849
- _validateUrl() {
4850
- if (!this.url) {
4851
- console.error("no url");
4852
- throw new InvalidRepoUrlError("no url");
4865
+ url: void 0
4866
+ }),
4867
+ orgName: org
4868
+ });
4869
+ const gitOrg = await orgApi.getGitApi();
4870
+ const orgRepos = await gitOrg.getRepositories();
4871
+ const repoInfoList = (await Promise.allSettled(
4872
+ orgRepos.map(async (repo) => {
4873
+ if (!repo.name || !repo.remoteUrl || !repo.defaultBranch) {
4874
+ throw new InvalidRepoUrlError("bad repo");
4875
+ }
4876
+ const branch = await gitOrg.getBranch(
4877
+ repo.name,
4878
+ repo.defaultBranch.replace(/^refs\/heads\//, ""),
4879
+ repo.project?.name
4880
+ );
4881
+ return {
4882
+ repoName: repo.name,
4883
+ repoUrl: repo.remoteUrl.replace(
4884
+ /^[hH][tT][tT][pP][sS]:\/\/[^/]+@/,
4885
+ "https://"
4886
+ ),
4887
+ repoOwner: org,
4888
+ repoIsPublic: repo.project?.visibility === 2 /* Public */,
4889
+ repoLanguages: [],
4890
+ repoUpdatedAt: branch.commit?.committer?.date?.toDateString() || repo.project?.lastUpdateTime?.toDateString() || (/* @__PURE__ */ new Date()).toDateString()
4891
+ };
4892
+ })
4893
+ )).reduce((acc, res) => {
4894
+ if (res.status === "fulfilled") {
4895
+ acc.push(res.value);
4896
+ }
4897
+ return acc;
4898
+ }, []);
4899
+ return repoInfoList;
4900
+ })
4901
+ )).reduce((acc, res) => {
4902
+ if (res.status === "fulfilled") {
4903
+ return acc.concat(res.value);
4853
4904
  }
4854
- }
4855
- };
4905
+ return acc;
4906
+ }, []);
4907
+ return repos;
4908
+ }
4856
4909
 
4857
4910
  // src/features/analysis/scm/ado/AdoSCMLib.ts
4911
+ import { setTimeout as setTimeout2 } from "node:timers/promises";
4858
4912
  async function initAdoSdk(params) {
4859
4913
  const { url, accessToken, scmOrg } = params;
4860
4914
  const adoClientParams = await getAdoClientParams({
@@ -5049,33 +5103,33 @@ import querystring2 from "node:querystring";
5049
5103
  import * as bitbucketPkgNode from "bitbucket";
5050
5104
  import bitbucketPkg from "bitbucket";
5051
5105
  import Debug3 from "debug";
5052
- import { z as z22 } from "zod";
5106
+ import { z as z20 } from "zod";
5053
5107
 
5054
5108
  // src/features/analysis/scm/bitbucket/validation.ts
5055
- import { z as z21 } from "zod";
5056
- var BitbucketAuthResultZ = z21.object({
5057
- access_token: z21.string(),
5058
- token_type: z21.string(),
5059
- refresh_token: z21.string()
5109
+ import { z as z19 } from "zod";
5110
+ var BitbucketAuthResultZ = z19.object({
5111
+ access_token: z19.string(),
5112
+ token_type: z19.string(),
5113
+ refresh_token: z19.string()
5060
5114
  });
5061
5115
 
5062
5116
  // src/features/analysis/scm/bitbucket/bitbucket.ts
5063
5117
  var debug3 = Debug3("scm:bitbucket");
5064
5118
  var BITBUCKET_HOSTNAME = "bitbucket.org";
5065
- var TokenExpiredErrorZ = z22.object({
5066
- status: z22.number(),
5067
- error: z22.object({
5068
- type: z22.string(),
5069
- error: z22.object({
5070
- message: z22.string()
5119
+ var TokenExpiredErrorZ = z20.object({
5120
+ status: z20.number(),
5121
+ error: z20.object({
5122
+ type: z20.string(),
5123
+ error: z20.object({
5124
+ message: z20.string()
5071
5125
  })
5072
5126
  })
5073
5127
  });
5074
5128
  var BITBUCKET_ACCESS_TOKEN_URL = `https://${BITBUCKET_HOSTNAME}/site/oauth2/access_token`;
5075
- var BitbucketParseResultZ = z22.object({
5076
- organization: z22.string(),
5077
- repoName: z22.string(),
5078
- hostname: z22.literal(BITBUCKET_HOSTNAME)
5129
+ var BitbucketParseResultZ = z20.object({
5130
+ organization: z20.string(),
5131
+ repoName: z20.string(),
5132
+ hostname: z20.literal(BITBUCKET_HOSTNAME)
5079
5133
  });
5080
5134
  function parseBitbucketOrganizationAndRepo(bitbucketUrl) {
5081
5135
  const parsedGitHubUrl = normalizeUrl(bitbucketUrl);
@@ -5136,7 +5190,7 @@ function getBitbucketSdk(params) {
5136
5190
  if (!res.data.values) {
5137
5191
  return [];
5138
5192
  }
5139
- return res.data.values.filter((branch) => !!branch.name).map((branch) => z22.string().parse(branch.name));
5193
+ return res.data.values.filter((branch) => !!branch.name).map((branch) => z20.string().parse(branch.name));
5140
5194
  },
5141
5195
  async getIsUserCollaborator(params2) {
5142
5196
  const { repoUrl } = params2;
@@ -5251,7 +5305,7 @@ function getBitbucketSdk(params) {
5251
5305
  return GetRefererenceResultZ.parse({
5252
5306
  sha: tagRes.data.target?.hash,
5253
5307
  type: "TAG" /* TAG */,
5254
- date: new Date(z22.string().parse(tagRes.data.target?.date))
5308
+ date: new Date(z20.string().parse(tagRes.data.target?.date))
5255
5309
  });
5256
5310
  },
5257
5311
  async getBranchRef(params2) {
@@ -5259,7 +5313,7 @@ function getBitbucketSdk(params) {
5259
5313
  return GetRefererenceResultZ.parse({
5260
5314
  sha: getBranchRes.target?.hash,
5261
5315
  type: "BRANCH" /* BRANCH */,
5262
- date: new Date(z22.string().parse(getBranchRes.target?.date))
5316
+ date: new Date(z20.string().parse(getBranchRes.target?.date))
5263
5317
  });
5264
5318
  },
5265
5319
  async getCommitRef(params2) {
@@ -5267,13 +5321,13 @@ function getBitbucketSdk(params) {
5267
5321
  return GetRefererenceResultZ.parse({
5268
5322
  sha: getCommitRes.hash,
5269
5323
  type: "COMMIT" /* COMMIT */,
5270
- date: new Date(z22.string().parse(getCommitRes.date))
5324
+ date: new Date(z20.string().parse(getCommitRes.date))
5271
5325
  });
5272
5326
  },
5273
5327
  async getDownloadUrl({ url, sha }) {
5274
5328
  this.getReferenceData({ ref: sha, url });
5275
5329
  const repoRes = await this.getRepo({ repoUrl: url });
5276
- const parsedRepoUrl = z22.string().url().parse(repoRes.links?.html?.href);
5330
+ const parsedRepoUrl = z20.string().url().parse(repoRes.links?.html?.href);
5277
5331
  return `${parsedRepoUrl}/get/${sha}.zip`;
5278
5332
  },
5279
5333
  async getPullRequest(params2) {
@@ -5338,7 +5392,7 @@ async function validateBitbucketParams(params) {
5338
5392
  }
5339
5393
  async function getUsersworkspacesSlugs(bitbucketClient) {
5340
5394
  const res = await bitbucketClient.workspaces.getWorkspaces({});
5341
- return res.data.values?.map((v) => z22.string().parse(v.slug));
5395
+ return res.data.values?.map((v) => z20.string().parse(v.slug));
5342
5396
  }
5343
5397
  async function getllUsersrepositories(bitbucketClient) {
5344
5398
  const userWorspacesSlugs = await getUsersworkspacesSlugs(bitbucketClient);
@@ -5366,10 +5420,10 @@ async function getRepositoriesByWorkspace(bitbucketClient, { workspaceSlug }) {
5366
5420
 
5367
5421
  // src/features/analysis/scm/bitbucket/BitbucketSCMLib.ts
5368
5422
  import { setTimeout as setTimeout3 } from "node:timers/promises";
5369
- import { z as z23 } from "zod";
5423
+ import { z as z21 } from "zod";
5370
5424
  function getUserAndPassword(token) {
5371
5425
  const [username, password] = token.split(":");
5372
- const safePasswordAndUsername = z23.object({ username: z23.string(), password: z23.string() }).parse({ username, password });
5426
+ const safePasswordAndUsername = z21.object({ username: z21.string(), password: z21.string() }).parse({ username, password });
5373
5427
  return {
5374
5428
  username: safePasswordAndUsername.username,
5375
5429
  password: safePasswordAndUsername.password
@@ -5441,7 +5495,7 @@ var BitbucketSCMLib = class extends SCMLib {
5441
5495
  return { username, password, authType };
5442
5496
  }
5443
5497
  case "token": {
5444
- return { authType, token: z23.string().parse(this.accessToken) };
5498
+ return { authType, token: z21.string().parse(this.accessToken) };
5445
5499
  }
5446
5500
  case "public":
5447
5501
  return { authType };
@@ -5455,7 +5509,7 @@ var BitbucketSCMLib = class extends SCMLib {
5455
5509
  ...params,
5456
5510
  repoUrl: this.url
5457
5511
  });
5458
- return String(z23.number().parse(pullRequestRes.id));
5512
+ return String(z21.number().parse(pullRequestRes.id));
5459
5513
  } catch (e) {
5460
5514
  console.warn(
5461
5515
  `error creating pull request for BB. Try number ${i + 1}`,
@@ -5531,319 +5585,70 @@ var BitbucketSCMLib = class extends SCMLib {
5531
5585
  return res.name === branch;
5532
5586
  } catch (e) {
5533
5587
  return false;
5534
- }
5535
- }
5536
- async getUserHasAccessToRepo() {
5537
- this._validateAccessTokenAndUrl();
5538
- return this.bitbucketSdk.getIsUserCollaborator({ repoUrl: this.url });
5539
- }
5540
- async getUsername() {
5541
- this._validateAccessToken();
5542
- const res = await this.bitbucketSdk.getUser();
5543
- return z23.string().parse(res.username);
5544
- }
5545
- async getSubmitRequestStatus(_scmSubmitRequestId) {
5546
- this._validateAccessTokenAndUrl();
5547
- const pullRequestRes = await this.bitbucketSdk.getPullRequest({
5548
- prNumber: Number(_scmSubmitRequestId),
5549
- url: this.url
5550
- });
5551
- switch (pullRequestRes.state) {
5552
- case "OPEN":
5553
- return "open";
5554
- case "MERGED":
5555
- return "merged";
5556
- case "DECLINED":
5557
- return "closed";
5558
- default:
5559
- throw new Error(`unknown state ${pullRequestRes.state} `);
5560
- }
5561
- }
5562
- async getRepoBlameRanges(_ref, _path) {
5563
- return [];
5564
- }
5565
- async getReferenceData(ref) {
5566
- this._validateUrl();
5567
- return this.bitbucketSdk.getReferenceData({ url: this.url, ref });
5568
- }
5569
- async getRepoDefaultBranch() {
5570
- this._validateUrl();
5571
- const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
5572
- return z23.string().parse(repoRes.mainbranch?.name);
5573
- }
5574
- getSubmitRequestUrl(submitRequestId) {
5575
- this._validateUrl();
5576
- const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
5577
- return Promise.resolve(
5578
- `https://bitbucket.org/${workspace}/${repo_slug}/pull-requests/${submitRequestId}`
5579
- );
5580
- }
5581
- async getSubmitRequestId(submitRequestUrl) {
5582
- const match = submitRequestUrl.match(/\/pull-requests\/(\d+)/);
5583
- return match?.[1] || "";
5584
- }
5585
- getCommitUrl(commitId) {
5586
- this._validateUrl();
5587
- const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
5588
- return Promise.resolve(
5589
- `https://bitbucket.org/${workspace}/${repo_slug}/commits/${commitId}`
5590
- );
5591
- }
5592
- async addCommentToSubmitRequest(submitRequestId, comment) {
5593
- this._validateUrl();
5594
- await this.bitbucketSdk.addCommentToPullRequest({
5595
- prNumber: Number(submitRequestId),
5596
- url: this.url,
5597
- markdownComment: comment
5598
- });
5599
- }
5600
- };
5601
-
5602
- // src/features/analysis/scm/github/GithubSCMLib.ts
5603
- import { z as z24 } from "zod";
5604
- var GithubSCMLib = class extends SCMLib {
5605
- // we don't always need a url, what's important is that we have an access token
5606
- constructor(url, accessToken, scmOrg) {
5607
- super(url, accessToken, scmOrg);
5608
- __publicField(this, "githubSdk");
5609
- this.githubSdk = getGithubSdk({
5610
- auth: accessToken,
5611
- url
5612
- });
5613
- }
5614
- async createSubmitRequest(params) {
5615
- this._validateAccessTokenAndUrl();
5616
- const { targetBranchName, sourceBranchName, title, body } = params;
5617
- const pullRequestResult = await this.githubSdk.createPullRequest({
5618
- title,
5619
- body,
5620
- targetBranchName,
5621
- sourceBranchName,
5622
- repoUrl: this.url
5623
- });
5624
- return String(pullRequestResult.data.number);
5625
- }
5626
- async forkRepo(repoUrl) {
5627
- this._validateAccessToken();
5628
- return this.githubSdk.forkRepo({
5629
- repoUrl
5630
- });
5631
- }
5632
- async createOrUpdateRepositorySecret(params) {
5633
- this._validateAccessTokenAndUrl();
5634
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5635
- const { data: repositoryPublicKeyResponse } = await this.githubSdk.getRepositoryPublicKey({ owner, repo });
5636
- const { key_id, key } = repositoryPublicKeyResponse;
5637
- const encryptedValue = await encryptSecret(params.value, key);
5638
- return this.githubSdk.createOrUpdateRepositorySecret({
5639
- encrypted_value: encryptedValue,
5640
- secret_name: params.name,
5641
- key_id,
5642
- owner,
5643
- repo
5644
- });
5645
- }
5646
- async createPullRequestWithNewFile(sourceRepoUrl, filesPaths, userRepoUrl, title, body) {
5647
- const { pull_request_url } = await this.githubSdk.createPr({
5648
- sourceRepoUrl,
5649
- filesPaths,
5650
- userRepoUrl,
5651
- title,
5652
- body
5653
- });
5654
- return { pull_request_url };
5655
- }
5656
- async validateParams() {
5657
- return githubValidateParams(this.url, this.accessToken);
5658
- }
5659
- async postPrComment(params) {
5660
- this._validateAccessTokenAndUrl();
5661
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5662
- return this.githubSdk.postPrComment({
5663
- ...params,
5664
- owner,
5665
- repo
5666
- });
5667
- }
5668
- async updatePrComment(params) {
5669
- this._validateAccessTokenAndUrl();
5670
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5671
- return this.githubSdk.updatePrComment({
5672
- ...params,
5673
- owner,
5674
- repo
5675
- });
5676
- }
5677
- async deleteComment(params) {
5678
- this._validateAccessTokenAndUrl();
5679
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5680
- return this.githubSdk.deleteComment({
5681
- ...params,
5682
- owner,
5683
- repo
5684
- });
5685
- }
5686
- async getPrComments(params) {
5687
- this._validateAccessTokenAndUrl();
5688
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5689
- return this.githubSdk.getPrComments({
5690
- per_page: 100,
5691
- ...params,
5692
- owner,
5693
- repo
5694
- });
5695
- }
5696
- async getPrDiff(params) {
5697
- this._validateAccessTokenAndUrl();
5698
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5699
- const prRes = await this.githubSdk.getPrDiff({
5700
- ...params,
5701
- owner,
5702
- repo
5703
- });
5704
- return z24.string().parse(prRes.data);
5705
- }
5706
- async getRepoList(_scmOrg) {
5707
- this._validateAccessToken();
5708
- return this.githubSdk.getGithubRepoList();
5709
- }
5710
- async getBranchList() {
5711
- this._validateAccessTokenAndUrl();
5712
- const branches = await this.githubSdk.getGithubBranchList(this.url);
5713
- return branches.data.map((branch) => branch.name);
5714
- }
5715
- get scmLibType() {
5716
- return "GITHUB" /* GITHUB */;
5717
- }
5718
- getAuthHeaders() {
5719
- if (this.accessToken) {
5720
- return { authorization: `Bearer ${this.accessToken}` };
5721
- }
5722
- return {};
5723
- }
5724
- getDownloadUrl(sha) {
5725
- this._validateUrl();
5726
- const res = parseScmURL(this.url, "GitHub" /* GitHub */);
5727
- if (!res) {
5728
- throw new InvalidRepoUrlError("invalid repo url");
5729
- }
5730
- const { protocol, hostname, organization, repoName } = res;
5731
- const downloadUrl = isGithubOnPrem(this.url) ? `${protocol}//${hostname}/api/v3/repos/${organization}/${repoName}/zipball/${sha}` : `https://api.${hostname}/repos/${organization}/${repoName}/zipball/${sha}`;
5732
- return Promise.resolve(downloadUrl);
5733
- }
5734
- async _getUsernameForAuthUrl() {
5735
- return this.getUsername();
5736
- }
5737
- async getIsRemoteBranch(branch) {
5738
- this._validateUrl();
5739
- return this.githubSdk.getGithubIsRemoteBranch({ branch, repoUrl: this.url });
5588
+ }
5740
5589
  }
5741
5590
  async getUserHasAccessToRepo() {
5742
5591
  this._validateAccessTokenAndUrl();
5743
- const username = await this.getUsername();
5744
- return this.githubSdk.getGithubIsUserCollaborator({
5745
- repoUrl: this.url,
5746
- username
5747
- });
5592
+ return this.bitbucketSdk.getIsUserCollaborator({ repoUrl: this.url });
5748
5593
  }
5749
5594
  async getUsername() {
5750
5595
  this._validateAccessToken();
5751
- return this.githubSdk.getGithubUsername();
5752
- }
5753
- async getSubmitRequestStatus(scmSubmitRequestId) {
5754
- this._validateAccessTokenAndUrl();
5755
- return this.githubSdk.getGithubPullRequestStatus({
5756
- repoUrl: this.url,
5757
- prNumber: Number(scmSubmitRequestId)
5758
- });
5596
+ const res = await this.bitbucketSdk.getUser();
5597
+ return z21.string().parse(res.username);
5759
5598
  }
5760
- async addCommentToSubmitRequest(submitRequestId, comment) {
5599
+ async getSubmitRequestStatus(_scmSubmitRequestId) {
5761
5600
  this._validateAccessTokenAndUrl();
5762
- await this.githubSdk.createMarkdownCommentOnPullRequest({
5763
- repoUrl: this.url,
5764
- prNumber: Number(submitRequestId),
5765
- markdownComment: comment
5601
+ const pullRequestRes = await this.bitbucketSdk.getPullRequest({
5602
+ prNumber: Number(_scmSubmitRequestId),
5603
+ url: this.url
5766
5604
  });
5605
+ switch (pullRequestRes.state) {
5606
+ case "OPEN":
5607
+ return "open";
5608
+ case "MERGED":
5609
+ return "merged";
5610
+ case "DECLINED":
5611
+ return "closed";
5612
+ default:
5613
+ throw new Error(`unknown state ${pullRequestRes.state} `);
5614
+ }
5767
5615
  }
5768
- async getRepoBlameRanges(ref, path9) {
5769
- this._validateUrl();
5770
- return await this.githubSdk.getGithubBlameRanges({
5771
- ref,
5772
- path: path9,
5773
- gitHubUrl: this.url
5774
- });
5616
+ async getRepoBlameRanges(_ref, _path) {
5617
+ return [];
5775
5618
  }
5776
5619
  async getReferenceData(ref) {
5777
5620
  this._validateUrl();
5778
- return this.githubSdk.getGithubReferenceData({ ref, gitHubUrl: this.url });
5779
- }
5780
- async getPrComment(commentId) {
5781
- this._validateUrl();
5782
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5783
- return await this.githubSdk.getPrComment({
5784
- repo,
5785
- owner,
5786
- comment_id: commentId
5787
- });
5621
+ return this.bitbucketSdk.getReferenceData({ url: this.url, ref });
5788
5622
  }
5789
5623
  async getRepoDefaultBranch() {
5790
5624
  this._validateUrl();
5791
- return await this.githubSdk.getGithubRepoDefaultBranch(this.url);
5625
+ const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
5626
+ return z21.string().parse(repoRes.mainbranch?.name);
5792
5627
  }
5793
- async getSubmitRequestUrl(submitRequestUrl) {
5794
- this._validateAccessTokenAndUrl();
5795
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5796
- const getPrRes = await this.githubSdk.getPr({
5797
- owner,
5798
- repo,
5799
- pull_number: submitRequestUrl
5800
- });
5801
- return getPrRes.data.html_url;
5628
+ getSubmitRequestUrl(submitRequestId) {
5629
+ this._validateUrl();
5630
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
5631
+ return Promise.resolve(
5632
+ `https://bitbucket.org/${workspace}/${repo_slug}/pull-requests/${submitRequestId}`
5633
+ );
5802
5634
  }
5803
5635
  async getSubmitRequestId(submitRequestUrl) {
5804
- const match = submitRequestUrl.match(/\/pull\/(\d+)/);
5636
+ const match = submitRequestUrl.match(/\/pull-requests\/(\d+)/);
5805
5637
  return match?.[1] || "";
5806
5638
  }
5807
- async getCommitUrl(commitId) {
5808
- this._validateAccessTokenAndUrl();
5809
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5810
- const getCommitRes = await this.githubSdk.getCommit({
5811
- owner,
5812
- repo,
5813
- commitSha: commitId
5814
- });
5815
- return getCommitRes.data.html_url;
5816
- }
5817
- async postGeneralPrComment(params) {
5818
- const { prNumber, body } = params;
5819
- this._validateAccessTokenAndUrl();
5820
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5821
- return await this.githubSdk.postGeneralPrComment({
5822
- issue_number: prNumber,
5823
- owner,
5824
- repo,
5825
- body
5826
- });
5827
- }
5828
- async getGeneralPrComments(params) {
5829
- const { prNumber } = params;
5830
- this._validateAccessTokenAndUrl();
5831
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5832
- return await this.githubSdk.getGeneralPrComments({
5833
- issue_number: prNumber,
5834
- owner,
5835
- repo
5836
- });
5639
+ getCommitUrl(commitId) {
5640
+ this._validateUrl();
5641
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
5642
+ return Promise.resolve(
5643
+ `https://bitbucket.org/${workspace}/${repo_slug}/commits/${commitId}`
5644
+ );
5837
5645
  }
5838
- async deleteGeneralPrComment({
5839
- commentId
5840
- }) {
5841
- this._validateAccessTokenAndUrl();
5842
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5843
- return this.githubSdk.deleteGeneralPrComment({
5844
- owner,
5845
- repo,
5846
- comment_id: commentId
5646
+ async addCommentToSubmitRequest(submitRequestId, comment) {
5647
+ this._validateUrl();
5648
+ await this.bitbucketSdk.addCommentToPullRequest({
5649
+ prNumber: Number(submitRequestId),
5650
+ url: this.url,
5651
+ markdownComment: comment
5847
5652
  });
5848
5653
  }
5849
5654
  };
@@ -5863,11 +5668,11 @@ import {
5863
5668
  } from "undici";
5864
5669
 
5865
5670
  // src/features/analysis/scm/gitlab/types.ts
5866
- import { z as z25 } from "zod";
5867
- var GitlabAuthResultZ = z25.object({
5868
- access_token: z25.string(),
5869
- token_type: z25.string(),
5870
- refresh_token: z25.string()
5671
+ import { z as z22 } from "zod";
5672
+ var GitlabAuthResultZ = z22.object({
5673
+ access_token: z22.string(),
5674
+ token_type: z22.string(),
5675
+ refresh_token: z22.string()
5871
5676
  });
5872
5677
 
5873
5678
  // src/features/analysis/scm/gitlab/gitlab.ts
@@ -6165,13 +5970,13 @@ function parseGitlabOwnerAndRepo(gitlabUrl) {
6165
5970
  const { organization, repoName, projectPath } = parsingResult;
6166
5971
  return { owner: organization, repo: repoName, projectPath };
6167
5972
  }
6168
- async function getGitlabBlameRanges({ ref, gitlabUrl, path: path9 }, options) {
5973
+ async function getGitlabBlameRanges({ ref, gitlabUrl, path: path8 }, options) {
6169
5974
  const { projectPath } = parseGitlabOwnerAndRepo(gitlabUrl);
6170
5975
  const api2 = getGitBeaker({
6171
5976
  url: gitlabUrl,
6172
5977
  gitlabAuthToken: options?.gitlabAuthToken
6173
5978
  });
6174
- const resp = await api2.RepositoryFiles.allFileBlames(projectPath, path9, ref);
5979
+ const resp = await api2.RepositoryFiles.allFileBlames(projectPath, path8, ref);
6175
5980
  let lineNumber = 1;
6176
5981
  return resp.filter((range) => range.lines).map((range) => {
6177
5982
  const oldLineNumber = lineNumber;
@@ -6357,10 +6162,10 @@ var GitlabSCMLib = class extends SCMLib {
6357
6162
  markdownComment: comment
6358
6163
  });
6359
6164
  }
6360
- async getRepoBlameRanges(ref, path9) {
6165
+ async getRepoBlameRanges(ref, path8) {
6361
6166
  this._validateUrl();
6362
6167
  return await getGitlabBlameRanges(
6363
- { ref, path: path9, gitlabUrl: this.url },
6168
+ { ref, path: path8, gitlabUrl: this.url },
6364
6169
  {
6365
6170
  url: this.url,
6366
6171
  gitlabAuthToken: this.accessToken
@@ -6409,7 +6214,7 @@ var GitlabSCMLib = class extends SCMLib {
6409
6214
  };
6410
6215
 
6411
6216
  // src/features/analysis/scm/scmFactory.ts
6412
- import { z as z26 } from "zod";
6217
+ import { z as z23 } from "zod";
6413
6218
 
6414
6219
  // src/features/analysis/scm/StubSCMLib.ts
6415
6220
  var StubSCMLib = class extends SCMLib {
@@ -6531,7 +6336,7 @@ async function createScmLib({ url, accessToken, scmType, scmOrg }, { propagateEx
6531
6336
  if (e instanceof InvalidRepoUrlError && url) {
6532
6337
  throw new RepoNoTokenAccessError(
6533
6338
  "no access to repo",
6534
- scmLibScmTypeToScmType[z26.nativeEnum(ScmLibScmType).parse(scmType)]
6339
+ scmLibScmTypeToScmType[z23.nativeEnum(ScmLibScmType).parse(scmType)]
6535
6340
  );
6536
6341
  }
6537
6342
  console.error(`error validating scm: ${scmType} `, e);
@@ -6862,14 +6667,14 @@ function getGithubSdk(params = {}) {
6862
6667
  };
6863
6668
  },
6864
6669
  async getGithubBlameRanges(params2) {
6865
- const { ref, gitHubUrl, path: path9 } = params2;
6670
+ const { ref, gitHubUrl, path: path8 } = params2;
6866
6671
  const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
6867
6672
  const res = await octokit.graphql(
6868
6673
  GET_BLAME_DOCUMENT,
6869
6674
  {
6870
6675
  owner,
6871
6676
  repo,
6872
- path: path9,
6677
+ path: path8,
6873
6678
  ref
6874
6679
  }
6875
6680
  );
@@ -7010,10 +6815,258 @@ function getGithubSdk(params = {}) {
7010
6815
  };
7011
6816
  }
7012
6817
 
6818
+ // src/features/analysis/scm/github/GithubSCMLib.ts
6819
+ var GithubSCMLib = class extends SCMLib {
6820
+ // we don't always need a url, what's important is that we have an access token
6821
+ constructor(url, accessToken, scmOrg) {
6822
+ super(url, accessToken, scmOrg);
6823
+ __publicField(this, "githubSdk");
6824
+ this.githubSdk = getGithubSdk({
6825
+ auth: accessToken,
6826
+ url
6827
+ });
6828
+ }
6829
+ async createSubmitRequest(params) {
6830
+ this._validateAccessTokenAndUrl();
6831
+ const { targetBranchName, sourceBranchName, title, body } = params;
6832
+ const pullRequestResult = await this.githubSdk.createPullRequest({
6833
+ title,
6834
+ body,
6835
+ targetBranchName,
6836
+ sourceBranchName,
6837
+ repoUrl: this.url
6838
+ });
6839
+ return String(pullRequestResult.data.number);
6840
+ }
6841
+ async forkRepo(repoUrl) {
6842
+ this._validateAccessToken();
6843
+ return this.githubSdk.forkRepo({
6844
+ repoUrl
6845
+ });
6846
+ }
6847
+ async createOrUpdateRepositorySecret(params) {
6848
+ this._validateAccessTokenAndUrl();
6849
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
6850
+ const { data: repositoryPublicKeyResponse } = await this.githubSdk.getRepositoryPublicKey({ owner, repo });
6851
+ const { key_id, key } = repositoryPublicKeyResponse;
6852
+ const encryptedValue = await encryptSecret(params.value, key);
6853
+ return this.githubSdk.createOrUpdateRepositorySecret({
6854
+ encrypted_value: encryptedValue,
6855
+ secret_name: params.name,
6856
+ key_id,
6857
+ owner,
6858
+ repo
6859
+ });
6860
+ }
6861
+ async createPullRequestWithNewFile(sourceRepoUrl, filesPaths, userRepoUrl, title, body) {
6862
+ const { pull_request_url } = await this.githubSdk.createPr({
6863
+ sourceRepoUrl,
6864
+ filesPaths,
6865
+ userRepoUrl,
6866
+ title,
6867
+ body
6868
+ });
6869
+ return { pull_request_url };
6870
+ }
6871
+ async validateParams() {
6872
+ return githubValidateParams(this.url, this.accessToken);
6873
+ }
6874
+ async postPrComment(params) {
6875
+ this._validateAccessTokenAndUrl();
6876
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
6877
+ return this.githubSdk.postPrComment({
6878
+ ...params,
6879
+ owner,
6880
+ repo
6881
+ });
6882
+ }
6883
+ async updatePrComment(params) {
6884
+ this._validateAccessTokenAndUrl();
6885
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
6886
+ return this.githubSdk.updatePrComment({
6887
+ ...params,
6888
+ owner,
6889
+ repo
6890
+ });
6891
+ }
6892
+ async deleteComment(params) {
6893
+ this._validateAccessTokenAndUrl();
6894
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
6895
+ return this.githubSdk.deleteComment({
6896
+ ...params,
6897
+ owner,
6898
+ repo
6899
+ });
6900
+ }
6901
+ async getPrComments(params) {
6902
+ this._validateAccessTokenAndUrl();
6903
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
6904
+ return this.githubSdk.getPrComments({
6905
+ per_page: 100,
6906
+ ...params,
6907
+ owner,
6908
+ repo
6909
+ });
6910
+ }
6911
+ async getPrDiff(params) {
6912
+ this._validateAccessTokenAndUrl();
6913
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
6914
+ const prRes = await this.githubSdk.getPrDiff({
6915
+ ...params,
6916
+ owner,
6917
+ repo
6918
+ });
6919
+ return z24.string().parse(prRes.data);
6920
+ }
6921
+ async getRepoList(_scmOrg) {
6922
+ this._validateAccessToken();
6923
+ return this.githubSdk.getGithubRepoList();
6924
+ }
6925
+ async getBranchList() {
6926
+ this._validateAccessTokenAndUrl();
6927
+ const branches = await this.githubSdk.getGithubBranchList(this.url);
6928
+ return branches.data.map((branch) => branch.name);
6929
+ }
6930
+ get scmLibType() {
6931
+ return "GITHUB" /* GITHUB */;
6932
+ }
6933
+ getAuthHeaders() {
6934
+ if (this.accessToken) {
6935
+ return { authorization: `Bearer ${this.accessToken}` };
6936
+ }
6937
+ return {};
6938
+ }
6939
+ getDownloadUrl(sha) {
6940
+ this._validateUrl();
6941
+ const res = parseScmURL(this.url, "GitHub" /* GitHub */);
6942
+ if (!res) {
6943
+ throw new InvalidRepoUrlError("invalid repo url");
6944
+ }
6945
+ const { protocol, hostname, organization, repoName } = res;
6946
+ const downloadUrl = isGithubOnPrem(this.url) ? `${protocol}//${hostname}/api/v3/repos/${organization}/${repoName}/zipball/${sha}` : `https://api.${hostname}/repos/${organization}/${repoName}/zipball/${sha}`;
6947
+ return Promise.resolve(downloadUrl);
6948
+ }
6949
+ async _getUsernameForAuthUrl() {
6950
+ return this.getUsername();
6951
+ }
6952
+ async getIsRemoteBranch(branch) {
6953
+ this._validateUrl();
6954
+ return this.githubSdk.getGithubIsRemoteBranch({ branch, repoUrl: this.url });
6955
+ }
6956
+ async getUserHasAccessToRepo() {
6957
+ this._validateAccessTokenAndUrl();
6958
+ const username = await this.getUsername();
6959
+ return this.githubSdk.getGithubIsUserCollaborator({
6960
+ repoUrl: this.url,
6961
+ username
6962
+ });
6963
+ }
6964
+ async getUsername() {
6965
+ this._validateAccessToken();
6966
+ return this.githubSdk.getGithubUsername();
6967
+ }
6968
+ async getSubmitRequestStatus(scmSubmitRequestId) {
6969
+ this._validateAccessTokenAndUrl();
6970
+ return this.githubSdk.getGithubPullRequestStatus({
6971
+ repoUrl: this.url,
6972
+ prNumber: Number(scmSubmitRequestId)
6973
+ });
6974
+ }
6975
+ async addCommentToSubmitRequest(submitRequestId, comment) {
6976
+ this._validateAccessTokenAndUrl();
6977
+ await this.githubSdk.createMarkdownCommentOnPullRequest({
6978
+ repoUrl: this.url,
6979
+ prNumber: Number(submitRequestId),
6980
+ markdownComment: comment
6981
+ });
6982
+ }
6983
+ async getRepoBlameRanges(ref, path8) {
6984
+ this._validateUrl();
6985
+ return await this.githubSdk.getGithubBlameRanges({
6986
+ ref,
6987
+ path: path8,
6988
+ gitHubUrl: this.url
6989
+ });
6990
+ }
6991
+ async getReferenceData(ref) {
6992
+ this._validateUrl();
6993
+ return this.githubSdk.getGithubReferenceData({ ref, gitHubUrl: this.url });
6994
+ }
6995
+ async getPrComment(commentId) {
6996
+ this._validateUrl();
6997
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
6998
+ return await this.githubSdk.getPrComment({
6999
+ repo,
7000
+ owner,
7001
+ comment_id: commentId
7002
+ });
7003
+ }
7004
+ async getRepoDefaultBranch() {
7005
+ this._validateUrl();
7006
+ return await this.githubSdk.getGithubRepoDefaultBranch(this.url);
7007
+ }
7008
+ async getSubmitRequestUrl(submitRequestUrl) {
7009
+ this._validateAccessTokenAndUrl();
7010
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
7011
+ const getPrRes = await this.githubSdk.getPr({
7012
+ owner,
7013
+ repo,
7014
+ pull_number: submitRequestUrl
7015
+ });
7016
+ return getPrRes.data.html_url;
7017
+ }
7018
+ async getSubmitRequestId(submitRequestUrl) {
7019
+ const match = submitRequestUrl.match(/\/pull\/(\d+)/);
7020
+ return match?.[1] || "";
7021
+ }
7022
+ async getCommitUrl(commitId) {
7023
+ this._validateAccessTokenAndUrl();
7024
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
7025
+ const getCommitRes = await this.githubSdk.getCommit({
7026
+ owner,
7027
+ repo,
7028
+ commitSha: commitId
7029
+ });
7030
+ return getCommitRes.data.html_url;
7031
+ }
7032
+ async postGeneralPrComment(params) {
7033
+ const { prNumber, body } = params;
7034
+ this._validateAccessTokenAndUrl();
7035
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
7036
+ return await this.githubSdk.postGeneralPrComment({
7037
+ issue_number: prNumber,
7038
+ owner,
7039
+ repo,
7040
+ body
7041
+ });
7042
+ }
7043
+ async getGeneralPrComments(params) {
7044
+ const { prNumber } = params;
7045
+ this._validateAccessTokenAndUrl();
7046
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
7047
+ return await this.githubSdk.getGeneralPrComments({
7048
+ issue_number: prNumber,
7049
+ owner,
7050
+ repo
7051
+ });
7052
+ }
7053
+ async deleteGeneralPrComment({
7054
+ commentId
7055
+ }) {
7056
+ this._validateAccessTokenAndUrl();
7057
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
7058
+ return this.githubSdk.deleteGeneralPrComment({
7059
+ owner,
7060
+ repo,
7061
+ comment_id: commentId
7062
+ });
7063
+ }
7064
+ };
7065
+
7013
7066
  // src/features/analysis/add_fix_comments_for_pr/utils/utils.ts
7014
7067
  import Debug7 from "debug";
7015
- import parseDiff2 from "parse-diff";
7016
- import { z as z28 } from "zod";
7068
+ import parseDiff from "parse-diff";
7069
+ import { z as z26 } from "zod";
7017
7070
 
7018
7071
  // src/features/analysis/utils/by_key.ts
7019
7072
  function keyBy(array, keyBy2) {
@@ -7085,11 +7138,12 @@ var scannerToFriendlyString = {
7085
7138
 
7086
7139
  // src/features/analysis/add_fix_comments_for_pr/utils/buildCommentBody.ts
7087
7140
  import Debug6 from "debug";
7088
- import { z as z27 } from "zod";
7141
+ import { z as z25 } from "zod";
7089
7142
  var debug6 = Debug6("mobbdev:handle-finished-analysis");
7090
7143
  var getCommitFixButton = (commitUrl) => `<a href="${commitUrl}"><img src=${COMMIT_FIX_SVG}></a>`;
7091
- function buildCommentBody({
7144
+ function buildFixCommentBody({
7092
7145
  fix,
7146
+ issueId,
7093
7147
  commentId,
7094
7148
  commentUrl,
7095
7149
  scanner,
@@ -7097,9 +7151,19 @@ function buildCommentBody({
7097
7151
  projectId,
7098
7152
  analysisId,
7099
7153
  organizationId,
7100
- patch
7154
+ patch,
7155
+ irrelevantIssueWithTags
7101
7156
  }) {
7102
- const commitUrl = getCommitUrl({
7157
+ const isIrrelevantIssueWithTags = irrelevantIssueWithTags?.[0]?.tag;
7158
+ const commitUrl = isIrrelevantIssueWithTags ? getCommitIssueUrl({
7159
+ appBaseUrl: WEB_APP_URL,
7160
+ issueId,
7161
+ projectId,
7162
+ analysisId,
7163
+ organizationId,
7164
+ redirectUrl: commentUrl,
7165
+ commentId
7166
+ }) : getCommitUrl({
7103
7167
  appBaseUrl: WEB_APP_URL,
7104
7168
  fixId,
7105
7169
  projectId,
@@ -7108,7 +7172,15 @@ function buildCommentBody({
7108
7172
  redirectUrl: commentUrl,
7109
7173
  commentId
7110
7174
  });
7111
- const fixUrl = getFixUrlWithRedirect({
7175
+ const fixUrl = isIrrelevantIssueWithTags ? getIssueUrlWithRedirect({
7176
+ appBaseUrl: WEB_APP_URL,
7177
+ issueId,
7178
+ projectId,
7179
+ analysisId,
7180
+ organizationId,
7181
+ redirectUrl: commentUrl,
7182
+ commentId
7183
+ }) : getFixUrlWithRedirect({
7112
7184
  appBaseUrl: WEB_APP_URL,
7113
7185
  fixId,
7114
7186
  projectId,
@@ -7119,11 +7191,11 @@ function buildCommentBody({
7119
7191
  });
7120
7192
  const issueType = getIssueTypeFriendlyString(fix.safeIssueType);
7121
7193
  const title = `# ${MobbIconMarkdown} ${issueType} fix is ready`;
7122
- const validFixParseRes = z27.object({
7194
+ const validFixParseRes = z25.object({
7123
7195
  patchAndQuestions: PatchAndQuestionsZ,
7124
- safeIssueLanguage: z27.nativeEnum(IssueLanguage_Enum),
7125
- severityText: z27.nativeEnum(Vulnerability_Severity_Enum),
7126
- safeIssueType: z27.nativeEnum(IssueType_Enum)
7196
+ safeIssueLanguage: z25.nativeEnum(IssueLanguage_Enum),
7197
+ severityText: z25.nativeEnum(Vulnerability_Severity_Enum),
7198
+ safeIssueType: z25.nativeEnum(IssueType_Enum)
7127
7199
  }).safeParse(fix);
7128
7200
  if (!validFixParseRes.success) {
7129
7201
  debug6(
@@ -7140,7 +7212,8 @@ function buildCommentBody({
7140
7212
  issueType: validFixParseRes.data.safeIssueType,
7141
7213
  issueLanguage: validFixParseRes.data.safeIssueLanguage,
7142
7214
  fixExtraContext: validFixParseRes.data.patchAndQuestions.extraContext
7143
- })
7215
+ }),
7216
+ irrelevantIssueWithTags
7144
7217
  }) : "";
7145
7218
  const diff = `\`\`\`diff
7146
7219
  ${patch}
@@ -7154,6 +7227,37 @@ ${getCommitFixButton(
7154
7227
  )}
7155
7228
  ${fixPageLink}`;
7156
7229
  }
7230
+ function buildIssueCommentBody({
7231
+ issueId,
7232
+ commentId,
7233
+ commentUrl,
7234
+ scanner,
7235
+ issueType,
7236
+ projectId,
7237
+ analysisId,
7238
+ organizationId,
7239
+ irrelevantIssueWithTags
7240
+ }) {
7241
+ const issueUrl = getIssueUrlWithRedirect({
7242
+ appBaseUrl: WEB_APP_URL,
7243
+ issueId,
7244
+ projectId,
7245
+ analysisId,
7246
+ organizationId,
7247
+ redirectUrl: commentUrl,
7248
+ commentId
7249
+ });
7250
+ const title = `# ${MobbIconMarkdown} Irrelevant issues were spotted - no action required \u{1F9F9}`;
7251
+ const subTitle = getCommitIssueDescription({
7252
+ issueType,
7253
+ vendor: scannerToVulnerability_Report_Vendor_Enum[scanner],
7254
+ irrelevantIssueWithTags
7255
+ });
7256
+ const issuePageLink = `[Learn more and fine tune the issue](${issueUrl})`;
7257
+ return `${title}
7258
+ ${subTitle}
7259
+ ${issuePageLink}`;
7260
+ }
7157
7261
 
7158
7262
  // src/features/analysis/add_fix_comments_for_pr/utils/utils.ts
7159
7263
  var debug7 = Debug7("mobbdev:handle-finished-analysis");
@@ -7211,6 +7315,53 @@ function deleteAllPreviousGeneralPrComments(params) {
7211
7315
  }
7212
7316
  });
7213
7317
  }
7318
+ async function postIssueComment(params) {
7319
+ const {
7320
+ vulnerabilityReportIssueCodeNode,
7321
+ projectId,
7322
+ analysisId,
7323
+ organizationId,
7324
+ scm,
7325
+ commitSha,
7326
+ pullRequest,
7327
+ scanner
7328
+ } = params;
7329
+ const {
7330
+ path: path8,
7331
+ startLine,
7332
+ vulnerabilityReportIssue: {
7333
+ vulnerabilityReportIssueTags,
7334
+ category,
7335
+ parsedIssueType
7336
+ },
7337
+ vulnerabilityReportIssueId
7338
+ } = vulnerabilityReportIssueCodeNode;
7339
+ const irrelevantIssueWithTags = mapCategoryToBucket[category] === "irrelevant" && vulnerabilityReportIssueTags?.length > 0 ? vulnerabilityReportIssueTags : [];
7340
+ const commentRes = await scm.postPrComment({
7341
+ body: `# ${MobbIconMarkdown} Your fix is ready!
7342
+ Refresh the page in order to see the changes.`,
7343
+ pull_number: pullRequest,
7344
+ commit_id: commitSha,
7345
+ path: path8,
7346
+ line: startLine
7347
+ });
7348
+ const commentId = commentRes.data.id;
7349
+ const commentBody = buildIssueCommentBody({
7350
+ issueId: vulnerabilityReportIssueId,
7351
+ issueType: parsedIssueType,
7352
+ irrelevantIssueWithTags,
7353
+ commentId,
7354
+ commentUrl: commentRes.data.html_url,
7355
+ scanner,
7356
+ projectId,
7357
+ analysisId,
7358
+ organizationId
7359
+ });
7360
+ return await scm.updatePrComment({
7361
+ body: commentBody,
7362
+ comment_id: commentId
7363
+ });
7364
+ }
7214
7365
  async function postFixComment(params) {
7215
7366
  const {
7216
7367
  vulnerabilityReportIssueCodeNode,
@@ -7224,10 +7375,12 @@ async function postFixComment(params) {
7224
7375
  scanner
7225
7376
  } = params;
7226
7377
  const {
7227
- path: path9,
7378
+ path: path8,
7228
7379
  startLine,
7229
- vulnerabilityReportIssue: { fixId }
7380
+ vulnerabilityReportIssue: { fixId, vulnerabilityReportIssueTags, category },
7381
+ vulnerabilityReportIssueId
7230
7382
  } = vulnerabilityReportIssueCodeNode;
7383
+ const irrelevantIssueWithTags = mapCategoryToBucket[category] === "irrelevant" && vulnerabilityReportIssueTags?.length > 0 ? vulnerabilityReportIssueTags : [];
7231
7384
  const fix = fixesById[fixId];
7232
7385
  if (!fix || fix.patchAndQuestions.__typename !== "FixData") {
7233
7386
  throw new Error(`fix ${fixId} not found`);
@@ -7240,12 +7393,14 @@ async function postFixComment(params) {
7240
7393
  Refresh the page in order to see the changes.`,
7241
7394
  pull_number: pullRequest,
7242
7395
  commit_id: commitSha,
7243
- path: path9,
7396
+ path: path8,
7244
7397
  line: startLine
7245
7398
  });
7246
7399
  const commentId = commentRes.data.id;
7247
- const commentBody = buildCommentBody({
7400
+ const commentBody = buildFixCommentBody({
7248
7401
  fix,
7402
+ issueId: vulnerabilityReportIssueId,
7403
+ irrelevantIssueWithTags,
7249
7404
  commentId,
7250
7405
  commentUrl: commentRes.data.html_url,
7251
7406
  scanner,
@@ -7288,7 +7443,7 @@ ${summary.join("\n")}`;
7288
7443
  }
7289
7444
  async function getRelevantVulenrabilitiesFromDiff(params) {
7290
7445
  const { gqlClient, diff, vulnerabilityReportId } = params;
7291
- const parsedDiff = parseDiff2(diff);
7446
+ const parsedDiff = parseDiff(diff);
7292
7447
  const fileHunks = parsedDiff.map((file) => {
7293
7448
  const fileNumbers = file.chunks.flatMap((chunk) => chunk.changes).filter((change) => change.type === "add").map((_change) => {
7294
7449
  const change = _change;
@@ -7296,7 +7451,7 @@ async function getRelevantVulenrabilitiesFromDiff(params) {
7296
7451
  });
7297
7452
  const lineAddedRanges = calculateRanges(fileNumbers);
7298
7453
  const fileFilter = {
7299
- path: z28.string().parse(file.to),
7454
+ path: z26.string().parse(file.to),
7300
7455
  ranges: lineAddedRanges.map(([startLine, endLine]) => ({
7301
7456
  endLine,
7302
7457
  startLine
@@ -7399,7 +7554,7 @@ async function addFixCommentsForPr({
7399
7554
  gqlClient,
7400
7555
  scanner
7401
7556
  }) {
7402
- if (_scm instanceof GithubSCMLib === false) {
7557
+ if (!(_scm instanceof GithubSCMLib)) {
7403
7558
  return;
7404
7559
  }
7405
7560
  const scm = _scm;
@@ -7421,7 +7576,10 @@ async function addFixCommentsForPr({
7421
7576
  gqlClient,
7422
7577
  vulnerabilityReportId: getAnalysisRes.vulnerabilityReportId
7423
7578
  });
7424
- const { vulnerabilityReportIssueCodeNodes } = prVulenrabilities;
7579
+ const {
7580
+ vulnerabilityReportIssueCodeNodes,
7581
+ irrelevantVulnerabilityReportIssues
7582
+ } = prVulenrabilities;
7425
7583
  const fixesId = vulnerabilityReportIssueCodeNodes.map(
7426
7584
  ({ vulnerabilityReportIssue: { fixId } }) => fixId
7427
7585
  );
@@ -7450,6 +7608,33 @@ async function addFixCommentsForPr({
7450
7608
  });
7451
7609
  }
7452
7610
  ),
7611
+ ...irrelevantVulnerabilityReportIssues.map((vulnerabilityReportIssue) => {
7612
+ return vulnerabilityReportIssue.codeNodes.map(
7613
+ (vulnerabilityReportIssueCodeNode) => {
7614
+ return postIssueComment({
7615
+ vulnerabilityReportIssueCodeNode: {
7616
+ path: vulnerabilityReportIssueCodeNode.path,
7617
+ startLine: vulnerabilityReportIssueCodeNode.startLine,
7618
+ vulnerabilityReportIssue: {
7619
+ fixId: "",
7620
+ parsedIssueType: vulnerabilityReportIssue.parsedIssueType,
7621
+ vulnerabilityReportIssueTags: vulnerabilityReportIssue.vulnerabilityReportIssueTags,
7622
+ category: vulnerabilityReportIssue.category
7623
+ },
7624
+ vulnerabilityReportIssueId: vulnerabilityReportIssue.id
7625
+ },
7626
+ projectId,
7627
+ analysisId,
7628
+ organizationId,
7629
+ fixesById,
7630
+ scm,
7631
+ pullRequest,
7632
+ scanner,
7633
+ commitSha
7634
+ });
7635
+ }
7636
+ );
7637
+ }),
7453
7638
  postAnalysisInsightComment({
7454
7639
  prVulenrabilities,
7455
7640
  pullRequest,
@@ -7648,32 +7833,63 @@ function subscribe(query, variables, callback, wsClientOptions) {
7648
7833
  }
7649
7834
 
7650
7835
  // src/features/analysis/graphql/types.ts
7651
- import { z as z29 } from "zod";
7652
- var VulnerabilityReportIssueCodeNodeZ = z29.object({
7653
- vulnerabilityReportIssueId: z29.string(),
7654
- path: z29.string(),
7655
- startLine: z29.number(),
7656
- vulnerabilityReportIssue: z29.object({
7657
- fixId: z29.string()
7836
+ import { z as z27 } from "zod";
7837
+ var VulnerabilityReportIssueCodeNodeZ = z27.object({
7838
+ vulnerabilityReportIssueId: z27.string(),
7839
+ path: z27.string(),
7840
+ startLine: z27.number(),
7841
+ vulnerabilityReportIssue: z27.object({
7842
+ fixId: z27.string(),
7843
+ category: ValidCategoriesZ,
7844
+ parsedIssueType: z27.string(),
7845
+ vulnerabilityReportIssueTags: z27.array(
7846
+ z27.object({
7847
+ tag: z27.nativeEnum(Vulnerability_Report_Issue_Tag_Enum)
7848
+ })
7849
+ )
7658
7850
  })
7659
7851
  });
7660
- var GetVulByNodesMetadataZ = z29.object({
7661
- vulnerabilityReportIssueCodeNodes: z29.array(VulnerabilityReportIssueCodeNodeZ),
7662
- nonFixablePrVuls: z29.object({
7663
- aggregate: z29.object({
7664
- count: z29.number()
7852
+ var VulnerabilityReportIssueNoFixCodeNodeZ = z27.object({
7853
+ vulnerabilityReportIssues: z27.array(
7854
+ z27.object({
7855
+ id: z27.string(),
7856
+ fixId: z27.string().nullable(),
7857
+ category: ValidCategoriesZ,
7858
+ parsedIssueType: z27.string(),
7859
+ codeNodes: z27.array(
7860
+ z27.object({
7861
+ path: z27.string(),
7862
+ startLine: z27.number()
7863
+ })
7864
+ ),
7865
+ vulnerabilityReportIssueTags: z27.array(
7866
+ z27.object({
7867
+ tag: z27.nativeEnum(Vulnerability_Report_Issue_Tag_Enum)
7868
+ })
7869
+ )
7870
+ })
7871
+ )
7872
+ });
7873
+ var GetVulByNodesMetadataZ = z27.object({
7874
+ vulnerabilityReportIssueCodeNodes: z27.array(VulnerabilityReportIssueCodeNodeZ),
7875
+ nonFixablePrVuls: z27.object({
7876
+ aggregate: z27.object({
7877
+ count: z27.number()
7665
7878
  })
7666
7879
  }),
7667
- fixablePrVuls: z29.object({
7668
- aggregate: z29.object({
7669
- count: z29.number()
7880
+ fixablePrVuls: z27.object({
7881
+ aggregate: z27.object({
7882
+ count: z27.number()
7670
7883
  })
7671
7884
  }),
7672
- totalScanVulnerabilities: z29.object({
7673
- aggregate: z29.object({
7674
- count: z29.number()
7885
+ totalScanVulnerabilities: z27.object({
7886
+ aggregate: z27.object({
7887
+ count: z27.number()
7675
7888
  })
7676
- })
7889
+ }),
7890
+ irrelevantVulnerabilityReportIssue: z27.array(
7891
+ VulnerabilityReportIssueNoFixCodeNodeZ
7892
+ )
7677
7893
  });
7678
7894
 
7679
7895
  // src/features/analysis/graphql/gql.ts
@@ -7825,6 +8041,7 @@ var GQLClient = class {
7825
8041
  const totalScanVulnerabilities = parsedGetVulByNodesMetadataRes.totalScanVulnerabilities.aggregate.count;
7826
8042
  const vulnerabilitiesOutsidePr = totalScanVulnerabilities - nonFixablePrVuls - fixablePrVuls;
7827
8043
  const totalPrVulnerabilities = nonFixablePrVuls + fixablePrVuls;
8044
+ const irrelevantVulnerabilityReportIssues = parsedGetVulByNodesMetadataRes.irrelevantVulnerabilityReportIssue?.[0]?.vulnerabilityReportIssues ?? [];
7828
8045
  return {
7829
8046
  vulnerabilityReportIssueCodeNodes: Object.values(
7830
8047
  uniqueVulByNodesMetadata
@@ -7833,7 +8050,8 @@ var GQLClient = class {
7833
8050
  fixablePrVuls,
7834
8051
  totalScanVulnerabilities,
7835
8052
  vulnerabilitiesOutsidePr,
7836
- totalPrVulnerabilities
8053
+ totalPrVulnerabilities,
8054
+ irrelevantVulnerabilityReportIssues
7837
8055
  };
7838
8056
  }
7839
8057
  async digestVulnerabilityReport({
@@ -7961,24 +8179,24 @@ var GQLClient = class {
7961
8179
  };
7962
8180
 
7963
8181
  // src/features/analysis/pack.ts
7964
- import fs3 from "node:fs";
7965
- import path5 from "node:path";
8182
+ import fs2 from "node:fs";
8183
+ import path4 from "node:path";
7966
8184
  import AdmZip from "adm-zip";
7967
8185
  import Debug12 from "debug";
7968
8186
  import { globby } from "globby";
7969
8187
  import { isBinary } from "istextorbinary";
7970
8188
  import { simpleGit as simpleGit3 } from "simple-git";
7971
8189
  import { parseStringPromise } from "xml2js";
7972
- import { z as z30 } from "zod";
8190
+ import { z as z28 } from "zod";
7973
8191
  var debug12 = Debug12("mobbdev:pack");
7974
8192
  var MAX_FILE_SIZE = 1024 * 1024 * 5;
7975
- var FPR_SOURCE_CODE_FILE_MAPPING_SCHEMA = z30.object({
7976
- properties: z30.object({
7977
- entry: z30.array(
7978
- z30.object({
7979
- _: z30.string(),
7980
- $: z30.object({
7981
- key: z30.string()
8193
+ var FPR_SOURCE_CODE_FILE_MAPPING_SCHEMA = z28.object({
8194
+ properties: z28.object({
8195
+ entry: z28.array(
8196
+ z28.object({
8197
+ _: z28.string(),
8198
+ $: z28.object({
8199
+ key: z28.string()
7982
8200
  })
7983
8201
  })
7984
8202
  )
@@ -8028,20 +8246,20 @@ async function pack(srcDirPath, vulnFiles) {
8028
8246
  const zip = new AdmZip();
8029
8247
  debug12("compressing files");
8030
8248
  for (const filepath of filepaths) {
8031
- const absFilepath = path5.join(srcDirPath, filepath.toString());
8249
+ const absFilepath = path4.join(srcDirPath, filepath.toString());
8032
8250
  vulnFiles = vulnFiles.concat(_get_manifest_files_suffixes());
8033
8251
  if (!endsWithAny(
8034
- absFilepath.toString().replaceAll(path5.win32.sep, path5.posix.sep),
8252
+ absFilepath.toString().replaceAll(path4.win32.sep, path4.posix.sep),
8035
8253
  vulnFiles
8036
8254
  )) {
8037
8255
  debug12("ignoring %s because it is not a vulnerability file", filepath);
8038
8256
  continue;
8039
8257
  }
8040
- if (fs3.lstatSync(absFilepath).size > MAX_FILE_SIZE) {
8258
+ if (fs2.lstatSync(absFilepath).size > MAX_FILE_SIZE) {
8041
8259
  debug12("ignoring %s because the size is > 5MB", filepath);
8042
8260
  continue;
8043
8261
  }
8044
- const data = git ? await git.showBuffer([`HEAD:./${filepath}`]) : fs3.readFileSync(absFilepath);
8262
+ const data = git ? await git.showBuffer([`HEAD:./${filepath}`]) : fs2.readFileSync(absFilepath);
8045
8263
  if (isBinary(null, data)) {
8046
8264
  debug12("ignoring %s because is seems to be a binary file", filepath);
8047
8265
  continue;
@@ -8198,7 +8416,7 @@ import Debug14 from "debug";
8198
8416
  import { existsSync } from "fs";
8199
8417
  import { createSpinner as createSpinner2 } from "nanospinner";
8200
8418
  import { type } from "os";
8201
- import path6 from "path";
8419
+ import path5 from "path";
8202
8420
  var debug13 = Debug14("mobbdev:checkmarx");
8203
8421
  var require2 = createRequire(import.meta.url);
8204
8422
  var getCheckmarxPath = () => {
@@ -8258,9 +8476,9 @@ async function getCheckmarxReport({ reportPath, repositoryRoot, branch, projectN
8258
8476
  await startCheckmarxConfigationPrompt();
8259
8477
  await validateCheckamxCredentials();
8260
8478
  }
8261
- const extension = path6.extname(reportPath);
8262
- const filePath = path6.dirname(reportPath);
8263
- const fileName = path6.basename(reportPath, extension);
8479
+ const extension = path5.extname(reportPath);
8480
+ const filePath = path5.dirname(reportPath);
8481
+ const fileName = path5.basename(reportPath, extension);
8264
8482
  const checkmarxCommandArgs = getCheckmarxCommandArgs({
8265
8483
  repoPath: repositoryRoot,
8266
8484
  branch,
@@ -8442,7 +8660,7 @@ async function downloadRepo({
8442
8660
  const { createSpinner: createSpinner5 } = Spinner2({ ci });
8443
8661
  const repoSpinner = createSpinner5("\u{1F4BE} Downloading Repo").start();
8444
8662
  debug16("download repo %s %s %s", repoUrl, dirname);
8445
- const zipFilePath = path7.join(dirname, "repo.zip");
8663
+ const zipFilePath = path6.join(dirname, "repo.zip");
8446
8664
  debug16("download URL: %s auth headers: %o", downloadUrl, authHeaders);
8447
8665
  const response = await fetch4(downloadUrl, {
8448
8666
  method: "GET",
@@ -8455,19 +8673,19 @@ async function downloadRepo({
8455
8673
  repoSpinner.error({ text: "\u{1F4BE} Repo download failed" });
8456
8674
  throw new Error(`Can't access ${chalk4.bold(repoUrl)}`);
8457
8675
  }
8458
- const fileWriterStream = fs4.createWriteStream(zipFilePath);
8676
+ const fileWriterStream = fs3.createWriteStream(zipFilePath);
8459
8677
  if (!response.body) {
8460
8678
  throw new Error("Response body is empty");
8461
8679
  }
8462
8680
  await pipeline(response.body, fileWriterStream);
8463
8681
  await extract(zipFilePath, { dir: dirname });
8464
- const repoRoot = fs4.readdirSync(dirname, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name)[0];
8682
+ const repoRoot = fs3.readdirSync(dirname, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name)[0];
8465
8683
  if (!repoRoot) {
8466
8684
  throw new Error("Repo root not found");
8467
8685
  }
8468
8686
  debug16("repo root %s", repoRoot);
8469
8687
  repoSpinner.success({ text: "\u{1F4BE} Repo downloaded successfully" });
8470
- return path7.join(dirname, repoRoot);
8688
+ return path6.join(dirname, repoRoot);
8471
8689
  }
8472
8690
  var getReportUrl = ({
8473
8691
  organizationId,
@@ -8478,7 +8696,7 @@ var debug16 = Debug17("mobbdev:index");
8478
8696
  var config2 = new Configstore(packageJson.name, { apiToken: "" });
8479
8697
  debug16("config %o", config2);
8480
8698
  async function runAnalysis(params, options) {
8481
- const tmpObj = tmp2.dirSync({
8699
+ const tmpObj = tmp.dirSync({
8482
8700
  unsafeCleanup: true
8483
8701
  });
8484
8702
  try {
@@ -8577,7 +8795,7 @@ async function getReport(params, { skipPrompts }) {
8577
8795
  authHeaders: scm.getAuthHeaders(),
8578
8796
  downloadUrl
8579
8797
  });
8580
- const reportPath = path7.join(dirname, "report.json");
8798
+ const reportPath = path6.join(dirname, "report.json");
8581
8799
  switch (scanner) {
8582
8800
  case "snyk":
8583
8801
  await getSnykReport(reportPath, repositoryRoot, { skipPrompts });
@@ -8737,7 +8955,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
8737
8955
  spinner: mobbSpinner,
8738
8956
  submitVulnerabilityReportVariables: {
8739
8957
  fixReportId: reportUploadInfo.fixReportId,
8740
- repoUrl: z31.string().parse(repo),
8958
+ repoUrl: z29.string().parse(repo),
8741
8959
  reference,
8742
8960
  projectId,
8743
8961
  vulnerabilityReportFileName: "report.json",
@@ -8764,6 +8982,15 @@ async function _scan(params, { skipPrompts = false } = {}) {
8764
8982
  });
8765
8983
  }
8766
8984
  await askToOpenAnalysis();
8985
+ if (command === "review") {
8986
+ await waitForAnaysisAndReviewPr({
8987
+ repo,
8988
+ githubActionToken,
8989
+ analysisId: reportUploadInfo.fixReportId,
8990
+ scanner,
8991
+ gqlClient
8992
+ });
8993
+ }
8767
8994
  return reportUploadInfo.fixReportId;
8768
8995
  async function askToOpenAnalysis() {
8769
8996
  if (!repoUploadInfo || !reportUploadInfo) {
@@ -8856,7 +9083,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
8856
9083
  const zippingSpinner = createSpinner5("\u{1F4E6} Zipping repo").start();
8857
9084
  let zipBuffer;
8858
9085
  let gitInfo = { success: false };
8859
- if (srcFileStatus.isFile() && path7.extname(srcPath).toLowerCase() === ".fpr") {
9086
+ if (srcFileStatus.isFile() && path6.extname(srcPath).toLowerCase() === ".fpr") {
8860
9087
  zipBuffer = await repackFpr(srcPath);
8861
9088
  } else {
8862
9089
  gitInfo = await getGitInfo(srcPath);
@@ -8892,34 +9119,12 @@ async function _scan(params, { skipPrompts = false } = {}) {
8892
9119
  }
8893
9120
  });
8894
9121
  if (command === "review") {
8895
- const params2 = z31.object({
8896
- repo: z31.string().url(),
8897
- githubActionToken: z31.string()
8898
- }).parse({ repo, githubActionToken });
8899
- const scm = await createScmLib(
8900
- {
8901
- url: params2.repo,
8902
- accessToken: params2.githubActionToken,
8903
- scmOrg: "",
8904
- scmType: "GITHUB" /* GITHUB */
8905
- },
8906
- {
8907
- propagateExceptions: true
8908
- }
8909
- );
8910
- await gqlClient.subscribeToAnalysis({
8911
- subscribeToAnalysisParams: {
8912
- analysisId: reportUploadInfo.fixReportId
8913
- },
8914
- callback: (analysisId) => {
8915
- return addFixCommentsForPr({
8916
- analysisId,
8917
- gqlClient,
8918
- scm,
8919
- scanner: z31.nativeEnum(SCANNERS).parse(scanner)
8920
- });
8921
- },
8922
- callbackStates: ["Finished" /* Finished */]
9122
+ await waitForAnaysisAndReviewPr({
9123
+ repo,
9124
+ githubActionToken,
9125
+ analysisId: reportUploadInfo.fixReportId,
9126
+ scanner,
9127
+ gqlClient
8923
9128
  });
8924
9129
  }
8925
9130
  } catch (e) {
@@ -8991,6 +9196,43 @@ async function _digestReport({
8991
9196
  throw e;
8992
9197
  }
8993
9198
  }
9199
+ async function waitForAnaysisAndReviewPr({
9200
+ repo,
9201
+ githubActionToken,
9202
+ analysisId,
9203
+ scanner,
9204
+ gqlClient
9205
+ }) {
9206
+ const params = z29.object({
9207
+ repo: z29.string().url(),
9208
+ githubActionToken: z29.string()
9209
+ }).parse({ repo, githubActionToken });
9210
+ const scm = await createScmLib(
9211
+ {
9212
+ url: params.repo,
9213
+ accessToken: params.githubActionToken,
9214
+ scmOrg: "",
9215
+ scmType: "GITHUB" /* GITHUB */
9216
+ },
9217
+ {
9218
+ propagateExceptions: true
9219
+ }
9220
+ );
9221
+ await gqlClient.subscribeToAnalysis({
9222
+ subscribeToAnalysisParams: {
9223
+ analysisId
9224
+ },
9225
+ callback: (analysisId2) => {
9226
+ return addFixCommentsForPr({
9227
+ analysisId: analysisId2,
9228
+ gqlClient,
9229
+ scm,
9230
+ scanner: z29.nativeEnum(SCANNERS).parse(scanner)
9231
+ });
9232
+ },
9233
+ callbackStates: ["Finished" /* Finished */]
9234
+ });
9235
+ }
8994
9236
 
8995
9237
  // src/commands/index.ts
8996
9238
  import chalk5 from "chalk";
@@ -9302,8 +9544,8 @@ var scmTokenOption = {
9302
9544
 
9303
9545
  // src/args/validation.ts
9304
9546
  import chalk7 from "chalk";
9305
- import path8 from "path";
9306
- import { z as z32 } from "zod";
9547
+ import path7 from "path";
9548
+ import { z as z30 } from "zod";
9307
9549
  function throwRepoUrlErrorMessage({
9308
9550
  error,
9309
9551
  repoUrl,
@@ -9320,11 +9562,11 @@ Example:
9320
9562
  )}`;
9321
9563
  throw new CliError(formattedErrorMessage);
9322
9564
  }
9323
- var UrlZ = z32.string({
9565
+ var UrlZ = z30.string({
9324
9566
  invalid_type_error: `is not a valid ${Object.values(ScmType).join("/ ")} URL`
9325
9567
  });
9326
9568
  function validateOrganizationId(organizationId) {
9327
- const orgIdValidation = z32.string().uuid().nullish().safeParse(organizationId);
9569
+ const orgIdValidation = z30.string().uuid().nullish().safeParse(organizationId);
9328
9570
  if (!orgIdValidation.success) {
9329
9571
  throw new CliError(`organizationId: ${organizationId} is not a valid UUID`);
9330
9572
  }
@@ -9346,7 +9588,7 @@ function validateRepoUrl(args) {
9346
9588
  }
9347
9589
  var supportExtensions = [".json", ".xml", ".fpr", ".sarif"];
9348
9590
  function validateReportFileFormat(reportFile) {
9349
- if (!supportExtensions.includes(path8.extname(reportFile))) {
9591
+ if (!supportExtensions.includes(path7.extname(reportFile))) {
9350
9592
  throw new CliError(
9351
9593
  `
9352
9594
  ${chalk7.bold(
@@ -9389,7 +9631,7 @@ function analyzeBuilder(yargs2) {
9389
9631
  ).help();
9390
9632
  }
9391
9633
  function validateAnalyzeOptions(argv) {
9392
- if (!fs5.existsSync(argv.f)) {
9634
+ if (!fs4.existsSync(argv.f)) {
9393
9635
  throw new CliError(`
9394
9636
  Can't access ${chalk8.bold(argv.f)}`);
9395
9637
  }
@@ -9421,7 +9663,7 @@ async function analyzeHandler(args) {
9421
9663
  }
9422
9664
 
9423
9665
  // src/args/commands/review.ts
9424
- import fs6 from "node:fs";
9666
+ import fs5 from "node:fs";
9425
9667
  import chalk9 from "chalk";
9426
9668
  function reviewBuilder(yargs2) {
9427
9669
  return yargs2.option("f", {
@@ -9451,14 +9693,14 @@ function reviewBuilder(yargs2) {
9451
9693
  "Path to the repository folder with the source code"
9452
9694
  ),
9453
9695
  type: "string",
9454
- demandOption: true
9696
+ demandOption: false
9455
9697
  }).example(
9456
9698
  "npx mobbdev@latest review -r https://github.com/WebGoat/WebGoat -f <your_vulnerability_report_path> --ch <pr_last_commit> --pr <pr_number> --ref <pr_branch_name> --api-key <api_key> --src-path <your_repo_path>",
9457
9699
  "add fixes to your pr"
9458
9700
  ).help();
9459
9701
  }
9460
9702
  function validateReviewOptions(argv) {
9461
- if (!fs6.existsSync(argv.f)) {
9703
+ if (!fs5.existsSync(argv.f)) {
9462
9704
  throw new CliError(`
9463
9705
  Can't access ${chalk9.bold(argv.f)}`);
9464
9706
  }