mobbdev 1.0.45 → 1.0.47

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 +228 -68
  2. package/package.json +3 -1
package/dist/index.mjs CHANGED
@@ -614,8 +614,12 @@ var GitReferenceDocument = `
614
614
  }
615
615
  `;
616
616
  var AutoPrAnalysisDocument = `
617
- mutation autoPrAnalysis($analysisId: String!, $commitDirectly: Boolean) {
618
- autoPrAnalysis(analysisId: $analysisId, sameBranchCommit: $commitDirectly) {
617
+ mutation autoPrAnalysis($analysisId: String!, $commitDirectly: Boolean, $prId: Int) {
618
+ autoPrAnalysis(
619
+ analysisId: $analysisId
620
+ sameBranchCommit: $commitDirectly
621
+ prId: $prId
622
+ ) {
619
623
  __typename
620
624
  ... on AutoPrSuccess {
621
625
  status
@@ -1569,6 +1573,7 @@ var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 30;
1569
1573
 
1570
1574
  // src/features/analysis/index.ts
1571
1575
  import fs4 from "node:fs";
1576
+ import fsPromises from "node:fs/promises";
1572
1577
  import path7 from "node:path";
1573
1578
  import { env as env2 } from "node:process";
1574
1579
  import { pipeline } from "node:stream/promises";
@@ -1684,7 +1689,7 @@ import { createSpinner as createSpinner4 } from "nanospinner";
1684
1689
  import fetch4 from "node-fetch";
1685
1690
  import open2 from "open";
1686
1691
  import tmp2 from "tmp";
1687
- import { z as z30 } from "zod";
1692
+ import { z as z31 } from "zod";
1688
1693
 
1689
1694
  // src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
1690
1695
  import Debug8 from "debug";
@@ -4302,6 +4307,26 @@ async function getAdoSdk(params) {
4302
4307
  }
4303
4308
  return parsedPullRequestStatus.data;
4304
4309
  },
4310
+ async addCommentToAdoPullRequest({
4311
+ repoUrl,
4312
+ prNumber,
4313
+ markdownComment
4314
+ }) {
4315
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
4316
+ const git = await api2.getGitApi();
4317
+ const comment = {
4318
+ comments: [
4319
+ {
4320
+ parentCommentId: 0,
4321
+ // Root comment
4322
+ content: markdownComment,
4323
+ commentType: 1
4324
+ // Default type
4325
+ }
4326
+ ]
4327
+ };
4328
+ await git.createThread(comment, repo, prNumber, projectName);
4329
+ },
4305
4330
  async getAdoIsRemoteBranch({
4306
4331
  repoUrl,
4307
4332
  branch
@@ -4617,7 +4642,8 @@ var CommitToSameBranchParamsZ = BaseSubmitToScmMessageZ.merge(
4617
4642
  branch: z19.string(),
4618
4643
  commitMessages: z19.array(z19.string()),
4619
4644
  commitDescriptions: z19.array(z19.string().nullish()),
4620
- githubCommentId: z19.number().nullish()
4645
+ githubCommentId: z19.number().nullish(),
4646
+ prId: z19.number().nullish()
4621
4647
  })
4622
4648
  );
4623
4649
  var SubmitFixesToDifferentBranchParamsZ = z19.object({
@@ -4676,7 +4702,8 @@ var GitCommitZ = z19.object({
4676
4702
  var SubmitFixesToSameBranchResponseMessageZ = z19.object({
4677
4703
  type: z19.literal(submitToScmMessageType.commitToSameBranch),
4678
4704
  githubCommentId: z19.number().nullish(),
4679
- commits: z19.array(GitCommitZ)
4705
+ commits: z19.array(GitCommitZ),
4706
+ prId: z19.number().nullish()
4680
4707
  }).merge(SubmitFixesBaseResponseMessageZ);
4681
4708
  var SubmitFixesToDifferentBranchResponseMessageZ = z19.object({
4682
4709
  type: z19.literal(submitToScmMessageType.submitFixesForDifferentBranch),
@@ -4931,16 +4958,16 @@ var AdoSCMLib = class extends SCMLib {
4931
4958
  repoUrl: this.url
4932
4959
  });
4933
4960
  }
4934
- async getPrUrl(prNumber) {
4961
+ async getSubmitRequestUrl(submitRequestIdNumber) {
4935
4962
  this._validateUrl();
4936
4963
  const adoSdk = await this.getAdoSdk();
4937
4964
  return adoSdk.getAdoPrUrl({
4938
4965
  url: this.url,
4939
- prNumber
4966
+ prNumber: submitRequestIdNumber
4940
4967
  });
4941
4968
  }
4942
- async getPrId(prUrl) {
4943
- const match = prUrl.match(/\/pullrequest\/(\d+)/);
4969
+ async getSubmitRequestId(submitRequestUrl) {
4970
+ const match = submitRequestUrl.match(/\/pullrequest\/(\d+)/);
4944
4971
  return match?.[1] || "";
4945
4972
  }
4946
4973
  async getCommitUrl(commitId) {
@@ -4951,6 +4978,15 @@ var AdoSCMLib = class extends SCMLib {
4951
4978
  commitId
4952
4979
  });
4953
4980
  }
4981
+ async addCommentToSubmitRequest(scmSubmitRequestId, comment) {
4982
+ this._validateAccessTokenAndUrl();
4983
+ const adoSdk = await this.getAdoSdk();
4984
+ await adoSdk.addCommentToAdoPullRequest({
4985
+ repoUrl: this.url,
4986
+ prNumber: Number(scmSubmitRequestId),
4987
+ markdownComment: comment
4988
+ });
4989
+ }
4954
4990
  };
4955
4991
 
4956
4992
  // src/features/analysis/scm/bitbucket/bitbucket.ts
@@ -4992,7 +5028,7 @@ function parseBitbucketOrganizationAndRepo(bitbucketUrl) {
4992
5028
  const validatedBitbucketResult = BitbucketParseResultZ.parse(parsingResult);
4993
5029
  return {
4994
5030
  workspace: validatedBitbucketResult.organization,
4995
- repoSlug: validatedBitbucketResult.repoName
5031
+ repo_slug: validatedBitbucketResult.repoName
4996
5032
  };
4997
5033
  }
4998
5034
  function getBitbucketIntance(params) {
@@ -5032,11 +5068,11 @@ function getBitbucketSdk(params) {
5032
5068
  }));
5033
5069
  },
5034
5070
  async getBranchList(params2) {
5035
- const { workspace, repoSlug } = parseBitbucketOrganizationAndRepo(
5071
+ const { workspace, repo_slug } = parseBitbucketOrganizationAndRepo(
5036
5072
  params2.repoUrl
5037
5073
  );
5038
5074
  const res = await bitbucketClient.refs.listBranches({
5039
- repo_slug: repoSlug,
5075
+ repo_slug,
5040
5076
  workspace,
5041
5077
  pagelen: 100,
5042
5078
  //It seems to not work with very large numbers like 1000 (MAX_BRANCHES_FETCH) and returns a bad request response
@@ -5049,8 +5085,8 @@ function getBitbucketSdk(params) {
5049
5085
  },
5050
5086
  async getIsUserCollaborator(params2) {
5051
5087
  const { repoUrl } = params2;
5052
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(repoUrl);
5053
- const fullRepoName = `${workspace}/${repoSlug}`;
5088
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(repoUrl);
5089
+ const fullRepoName = `${workspace}/${repo_slug}`;
5054
5090
  const res = await bitbucketClient.user.listPermissionsForRepos({
5055
5091
  q: `repository.full_name~"${fullRepoName}"`
5056
5092
  });
@@ -5059,11 +5095,11 @@ function getBitbucketSdk(params) {
5059
5095
  ) ?? false;
5060
5096
  },
5061
5097
  async createPullRequest(params2) {
5062
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
5098
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(
5063
5099
  params2.repoUrl
5064
5100
  );
5065
5101
  const res = await bitbucketClient.pullrequests.create({
5066
- repo_slug: repoSlug,
5102
+ repo_slug,
5067
5103
  workspace,
5068
5104
  _body: {
5069
5105
  type: "pullrequest",
@@ -5086,43 +5122,43 @@ function getBitbucketSdk(params) {
5086
5122
  return res.data;
5087
5123
  },
5088
5124
  async getDownloadlink(params2) {
5089
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
5125
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(
5090
5126
  params2.repoUrl
5091
5127
  );
5092
5128
  const res = await bitbucketClient.downloads.list({
5093
- repo_slug: repoSlug,
5129
+ repo_slug,
5094
5130
  workspace
5095
5131
  });
5096
5132
  return res.data;
5097
5133
  },
5098
5134
  async getBranch(params2) {
5099
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
5135
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(
5100
5136
  params2.repoUrl
5101
5137
  );
5102
5138
  const res = await bitbucketClient.refs.getBranch({
5103
5139
  name: params2.branchName,
5104
- repo_slug: repoSlug,
5140
+ repo_slug,
5105
5141
  workspace
5106
5142
  });
5107
5143
  return res.data;
5108
5144
  },
5109
5145
  async getRepo(params2) {
5110
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
5146
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(
5111
5147
  params2.repoUrl
5112
5148
  );
5113
5149
  const res = await bitbucketClient.repositories.get({
5114
- repo_slug: repoSlug,
5150
+ repo_slug,
5115
5151
  workspace
5116
5152
  });
5117
5153
  return res.data;
5118
5154
  },
5119
5155
  async getCommit(params2) {
5120
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
5156
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(
5121
5157
  params2.repoUrl
5122
5158
  );
5123
5159
  const res = await bitbucketClient.commits.get({
5124
5160
  commit: params2.commitSha,
5125
- repo_slug: repoSlug,
5161
+ repo_slug,
5126
5162
  workspace
5127
5163
  });
5128
5164
  return res.data;
@@ -5151,9 +5187,9 @@ function getBitbucketSdk(params) {
5151
5187
  },
5152
5188
  async getTagRef(params2) {
5153
5189
  const { tagName, repoUrl } = params2;
5154
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(repoUrl);
5190
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(repoUrl);
5155
5191
  const tagRes = await bitbucketClient.refs.getTag({
5156
- repo_slug: repoSlug,
5192
+ repo_slug,
5157
5193
  workspace,
5158
5194
  name: tagName
5159
5195
  });
@@ -5186,12 +5222,31 @@ function getBitbucketSdk(params) {
5186
5222
  return `${parsedRepoUrl}/get/${sha}.zip`;
5187
5223
  },
5188
5224
  async getPullRequest(params2) {
5189
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(
5225
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(
5190
5226
  params2.url
5191
5227
  );
5192
5228
  const res = await bitbucketClient.pullrequests.get({
5193
5229
  pull_request_id: params2.prNumber,
5194
- repo_slug: repoSlug,
5230
+ repo_slug,
5231
+ workspace
5232
+ });
5233
+ return res.data;
5234
+ },
5235
+ async addCommentToPullRequest({
5236
+ url,
5237
+ prNumber,
5238
+ markdownComment
5239
+ }) {
5240
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(url);
5241
+ const res = await bitbucketClient.pullrequests.createComment({
5242
+ //@ts-expect-error tyep requires _body.type, but it its uses api fails
5243
+ _body: {
5244
+ content: {
5245
+ raw: markdownComment
5246
+ }
5247
+ },
5248
+ pull_request_id: prNumber,
5249
+ repo_slug,
5195
5250
  workspace
5196
5251
  });
5197
5252
  return res.data;
@@ -5461,24 +5516,32 @@ var BitbucketSCMLib = class extends SCMLib {
5461
5516
  const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
5462
5517
  return z23.string().parse(repoRes.mainbranch?.name);
5463
5518
  }
5464
- getPrUrl(prNumber) {
5519
+ getSubmitRequestUrl(submitRequestId) {
5465
5520
  this._validateUrl();
5466
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
5521
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
5467
5522
  return Promise.resolve(
5468
- `https://bitbucket.org/${workspace}/${repoSlug}/pull-requests/${prNumber}`
5523
+ `https://bitbucket.org/${workspace}/${repo_slug}/pull-requests/${submitRequestId}`
5469
5524
  );
5470
5525
  }
5471
- async getPrId(prUrl) {
5472
- const match = prUrl.match(/\/pull-requests\/(\d+)/);
5526
+ async getSubmitRequestId(submitRequestUrl) {
5527
+ const match = submitRequestUrl.match(/\/pull-requests\/(\d+)/);
5473
5528
  return match?.[1] || "";
5474
5529
  }
5475
5530
  getCommitUrl(commitId) {
5476
5531
  this._validateUrl();
5477
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
5532
+ const { repo_slug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
5478
5533
  return Promise.resolve(
5479
- `https://bitbucket.org/${workspace}/${repoSlug}/commits/${commitId}`
5534
+ `https://bitbucket.org/${workspace}/${repo_slug}/commits/${commitId}`
5480
5535
  );
5481
5536
  }
5537
+ async addCommentToSubmitRequest(submitRequestId, comment) {
5538
+ this._validateUrl();
5539
+ await this.bitbucketSdk.addCommentToPullRequest({
5540
+ prNumber: Number(submitRequestId),
5541
+ url: this.url,
5542
+ markdownComment: comment
5543
+ });
5544
+ }
5482
5545
  };
5483
5546
 
5484
5547
  // src/features/analysis/scm/github/GithubSCMLib.ts
@@ -5639,6 +5702,14 @@ var GithubSCMLib = class extends SCMLib {
5639
5702
  prNumber: Number(scmSubmitRequestId)
5640
5703
  });
5641
5704
  }
5705
+ async addCommentToSubmitRequest(submitRequestId, comment) {
5706
+ this._validateAccessTokenAndUrl();
5707
+ await this.githubSdk.createMarkdownCommentOnPullRequest({
5708
+ repoUrl: this.url,
5709
+ prNumber: Number(submitRequestId),
5710
+ markdownComment: comment
5711
+ });
5712
+ }
5642
5713
  async getRepoBlameRanges(ref, path9) {
5643
5714
  this._validateUrl();
5644
5715
  return await this.githubSdk.getGithubBlameRanges({
@@ -5664,18 +5735,18 @@ var GithubSCMLib = class extends SCMLib {
5664
5735
  this._validateUrl();
5665
5736
  return await this.githubSdk.getGithubRepoDefaultBranch(this.url);
5666
5737
  }
5667
- async getPrUrl(prNumber) {
5738
+ async getSubmitRequestUrl(submitRequestUrl) {
5668
5739
  this._validateAccessTokenAndUrl();
5669
5740
  const { owner, repo } = parseGithubOwnerAndRepo(this.url);
5670
5741
  const getPrRes = await this.githubSdk.getPr({
5671
5742
  owner,
5672
5743
  repo,
5673
- pull_number: prNumber
5744
+ pull_number: submitRequestUrl
5674
5745
  });
5675
5746
  return getPrRes.data.html_url;
5676
5747
  }
5677
- async getPrId(prUrl) {
5678
- const match = prUrl.match(/\/pull\/(\d+)/);
5748
+ async getSubmitRequestId(submitRequestUrl) {
5749
+ const match = submitRequestUrl.match(/\/pull\/(\d+)/);
5679
5750
  return match?.[1] || "";
5680
5751
  }
5681
5752
  async getCommitUrl(commitId) {
@@ -5852,6 +5923,16 @@ async function getGitlabMergeRequestStatus({
5852
5923
  throw new Error(`unknown merge request state ${res.state}`);
5853
5924
  }
5854
5925
  }
5926
+ async function createMarkdownCommentOnPullRequest({
5927
+ markdownComment,
5928
+ accessToken,
5929
+ repoUrl,
5930
+ mrNumber
5931
+ }) {
5932
+ const { projectPath } = parseGitlabOwnerAndRepo(repoUrl);
5933
+ const api2 = getGitBeaker({ url: repoUrl, gitlabAuthToken: accessToken });
5934
+ return api2.MergeRequestNotes.create(projectPath, mrNumber, markdownComment);
5935
+ }
5855
5936
  async function getGitlabIsRemoteBranch({
5856
5937
  accessToken,
5857
5938
  repoUrl,
@@ -6202,6 +6283,15 @@ var GitlabSCMLib = class extends SCMLib {
6202
6283
  throw new Error(`unknown state ${state}`);
6203
6284
  }
6204
6285
  }
6286
+ async addCommentToSubmitRequest(submitRequestId, comment) {
6287
+ this._validateAccessTokenAndUrl();
6288
+ await createMarkdownCommentOnPullRequest({
6289
+ accessToken: this.accessToken,
6290
+ repoUrl: this.url,
6291
+ mrNumber: Number(submitRequestId),
6292
+ markdownComment: comment
6293
+ });
6294
+ }
6205
6295
  async getRepoBlameRanges(ref, path9) {
6206
6296
  this._validateUrl();
6207
6297
  return await getGitlabBlameRanges(
@@ -6229,17 +6319,17 @@ var GitlabSCMLib = class extends SCMLib {
6229
6319
  gitlabAuthToken: this.accessToken
6230
6320
  });
6231
6321
  }
6232
- async getPrUrl(prNumber) {
6322
+ async getSubmitRequestUrl(submitRequestUrl) {
6233
6323
  this._validateAccessTokenAndUrl();
6234
6324
  const res = await getGitlabMergeRequest({
6235
6325
  url: this.url,
6236
- prNumber,
6326
+ prNumber: submitRequestUrl,
6237
6327
  accessToken: this.accessToken
6238
6328
  });
6239
6329
  return res.web_url;
6240
6330
  }
6241
- async getPrId(prUrl) {
6242
- const match = prUrl.match(/\/merge_requests\/(\d+)/);
6331
+ async getSubmitRequestId(submitRequestUrl) {
6332
+ const match = submitRequestUrl.match(/\/merge_requests\/(\d+)/);
6243
6333
  return match?.[1] || "";
6244
6334
  }
6245
6335
  async getCommitUrl(commitId) {
@@ -6324,12 +6414,12 @@ var StubSCMLib = class extends SCMLib {
6324
6414
  console.warn("getRepoDefaultBranch() returning empty string");
6325
6415
  return "";
6326
6416
  }
6327
- async getPrUrl(_prNumber) {
6328
- console.warn("getPrUrl() returning empty string");
6417
+ async getSubmitRequestUrl(_submitRequestIdNumber) {
6418
+ console.warn("getSubmitRequestUrl() returning empty string");
6329
6419
  return "";
6330
6420
  }
6331
- async getPrId(_prUrl) {
6332
- console.warn("getPrId() returning empty string");
6421
+ async getSubmitRequestId(_submitRequestUrl) {
6422
+ console.warn("getSubmitRequestId() returning empty string");
6333
6423
  return "";
6334
6424
  }
6335
6425
  async getCommitUrl(_commitId) {
@@ -6340,6 +6430,9 @@ var StubSCMLib = class extends SCMLib {
6340
6430
  console.warn("_getUsernameForAuthUrl() returning empty string");
6341
6431
  return "";
6342
6432
  }
6433
+ async addCommentToSubmitRequest(_submitRequestId, _comment) {
6434
+ console.warn("addCommentToSubmitRequest() no-op");
6435
+ }
6343
6436
  };
6344
6437
 
6345
6438
  // src/features/analysis/scm/scmFactory.ts
@@ -6565,6 +6658,16 @@ function getGithubSdk(params = {}) {
6565
6658
  }
6566
6659
  return res.data.state;
6567
6660
  },
6661
+ async createMarkdownCommentOnPullRequest(params2) {
6662
+ const { repoUrl, prNumber, markdownComment } = params2;
6663
+ const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
6664
+ return octokit.rest.issues.createComment({
6665
+ owner,
6666
+ repo,
6667
+ issue_number: prNumber,
6668
+ body: markdownComment
6669
+ });
6670
+ },
6568
6671
  async getGithubIsRemoteBranch(params2) {
6569
6672
  const { repoUrl, branch } = params2;
6570
6673
  const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
@@ -7301,7 +7404,7 @@ async function addFixCommentsForPr({
7301
7404
  import Debug9 from "debug";
7302
7405
  var debug9 = Debug9("mobbdev:handleAutoPr");
7303
7406
  async function handleAutoPr(params) {
7304
- const { gqlClient, analysisId, commitDirectly, createSpinner: createSpinner5 } = params;
7407
+ const { gqlClient, analysisId, commitDirectly, prId, createSpinner: createSpinner5 } = params;
7305
7408
  const createAutoPrSpinner = createSpinner5(
7306
7409
  "\u{1F504} Waiting for the analysis to finish before initiating automatic pull request creation"
7307
7410
  ).start();
@@ -7312,7 +7415,8 @@ async function handleAutoPr(params) {
7312
7415
  callback: async (analysisId2) => {
7313
7416
  const autoPrAnalysisRes = await gqlClient.autoPrAnalysis(
7314
7417
  analysisId2,
7315
- commitDirectly
7418
+ commitDirectly,
7419
+ prId
7316
7420
  );
7317
7421
  debug9("auto pr analysis res %o", autoPrAnalysisRes);
7318
7422
  if (autoPrAnalysisRes.autoPrAnalysis?.__typename === "AutoPrError") {
@@ -7770,10 +7874,11 @@ var GQLClient = class {
7770
7874
  }
7771
7875
  return res.analysis;
7772
7876
  }
7773
- async autoPrAnalysis(analysisId, commitDirectly) {
7877
+ async autoPrAnalysis(analysisId, commitDirectly, prId) {
7774
7878
  return this._clientSdk.autoPrAnalysis({
7775
7879
  analysisId,
7776
- commitDirectly
7880
+ commitDirectly,
7881
+ prId
7777
7882
  });
7778
7883
  }
7779
7884
  async getFixes(fixIds) {
@@ -7798,15 +7903,29 @@ import Debug12 from "debug";
7798
7903
  import { globby } from "globby";
7799
7904
  import { isBinary } from "istextorbinary";
7800
7905
  import { simpleGit as simpleGit3 } from "simple-git";
7906
+ import { parseStringPromise } from "xml2js";
7907
+ import { z as z30 } from "zod";
7801
7908
  var debug12 = Debug12("mobbdev:pack");
7802
7909
  var MAX_FILE_SIZE = 1024 * 1024 * 5;
7910
+ var FPR_SOURCE_CODE_FILE_MAPPING_SCHEMA = z30.object({
7911
+ properties: z30.object({
7912
+ entry: z30.array(
7913
+ z30.object({
7914
+ _: z30.string(),
7915
+ $: z30.object({
7916
+ key: z30.string()
7917
+ })
7918
+ })
7919
+ )
7920
+ })
7921
+ });
7803
7922
  function endsWithAny(str, suffixes) {
7804
7923
  return suffixes.some(function(suffix) {
7805
7924
  return str.endsWith(suffix);
7806
7925
  });
7807
7926
  }
7808
7927
  function _get_manifest_files_suffixes() {
7809
- return ["package.json"];
7928
+ return ["package.json", "pom.xml"];
7810
7929
  }
7811
7930
  async function pack(srcDirPath, vulnFiles) {
7812
7931
  debug12("pack folder %s", srcDirPath);
@@ -7867,6 +7986,25 @@ async function pack(srcDirPath, vulnFiles) {
7867
7986
  debug12("get zip file buffer");
7868
7987
  return zip.toBuffer();
7869
7988
  }
7989
+ async function repackFpr(fprPath) {
7990
+ debug12("repack fpr file %s", fprPath);
7991
+ const zipIn = new AdmZip(fprPath);
7992
+ const zipOut = new AdmZip();
7993
+ const mappingXML = zipIn.readAsText("src-archive/index.xml", "utf-8");
7994
+ const filesMapping = FPR_SOURCE_CODE_FILE_MAPPING_SCHEMA.parse(
7995
+ await parseStringPromise(mappingXML)
7996
+ );
7997
+ for (const fileMapping of filesMapping.properties.entry) {
7998
+ const zipPath = fileMapping._;
7999
+ const realPath = fileMapping.$.key;
8000
+ const buf = zipIn.readFile(zipPath);
8001
+ if (buf) {
8002
+ zipOut.addFile(realPath, buf);
8003
+ }
8004
+ }
8005
+ debug12("get repacked zip file buffer");
8006
+ return zipOut.toBuffer();
8007
+ }
7870
8008
 
7871
8009
  // src/features/analysis/prompts.ts
7872
8010
  import inquirer from "inquirer";
@@ -8411,7 +8549,8 @@ async function _scan(params, { skipPrompts = false } = {}) {
8411
8549
  command,
8412
8550
  organizationId: userOrganizationId,
8413
8551
  autoPr,
8414
- commitDirectly
8552
+ commitDirectly,
8553
+ pullRequest
8415
8554
  } = params;
8416
8555
  debug16("start %s %s", dirname, repo);
8417
8556
  const { createSpinner: createSpinner5 } = Spinner2({ ci });
@@ -8529,7 +8668,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
8529
8668
  spinner: mobbSpinner,
8530
8669
  submitVulnerabilityReportVariables: {
8531
8670
  fixReportId: reportUploadInfo.fixReportId,
8532
- repoUrl: z30.string().parse(repo),
8671
+ repoUrl: z31.string().parse(repo),
8533
8672
  reference,
8534
8673
  projectId,
8535
8674
  vulnerabilityReportFileName: "report.json",
@@ -8551,6 +8690,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
8551
8690
  gqlClient,
8552
8691
  analysisId: reportUploadInfo.fixReportId,
8553
8692
  commitDirectly,
8693
+ prId: pullRequest,
8554
8694
  createSpinner: createSpinner5
8555
8695
  });
8556
8696
  }
@@ -8642,9 +8782,16 @@ async function _scan(params, { skipPrompts = false } = {}) {
8642
8782
  projectId,
8643
8783
  command
8644
8784
  });
8645
- const gitInfo = await getGitInfo(srcPath);
8785
+ const srcFileStatus = await fsPromises.lstat(srcPath);
8646
8786
  const zippingSpinner = createSpinner5("\u{1F4E6} Zipping repo").start();
8647
- const zipBuffer = await pack(srcPath, vulnFiles);
8787
+ let zipBuffer;
8788
+ let gitInfo = { success: false };
8789
+ if (srcFileStatus.isFile() && path7.extname(srcPath).toLowerCase() === ".fpr") {
8790
+ zipBuffer = await repackFpr(srcPath);
8791
+ } else {
8792
+ gitInfo = await getGitInfo(srcPath);
8793
+ zipBuffer = await pack(srcPath, vulnFiles);
8794
+ }
8648
8795
  zippingSpinner.success({ text: "\u{1F4E6} Zipping repo successful!" });
8649
8796
  const uploadRepoSpinner = createSpinner5("\u{1F4C1} Uploading Repo").start();
8650
8797
  try {
@@ -8675,9 +8822,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
8675
8822
  }
8676
8823
  });
8677
8824
  if (command === "review") {
8678
- const params2 = z30.object({
8679
- repo: z30.string().url(),
8680
- githubActionToken: z30.string()
8825
+ const params2 = z31.object({
8826
+ repo: z31.string().url(),
8827
+ githubActionToken: z31.string()
8681
8828
  }).parse({ repo, githubActionToken });
8682
8829
  const scm = await createScmLib(
8683
8830
  {
@@ -8699,7 +8846,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
8699
8846
  analysisId,
8700
8847
  gqlClient,
8701
8848
  scm,
8702
- scanner: z30.nativeEnum(SCANNERS).parse(scanner)
8849
+ scanner: z31.nativeEnum(SCANNERS).parse(scanner)
8703
8850
  });
8704
8851
  },
8705
8852
  callbackStates: ["Finished" /* Finished */]
@@ -8717,6 +8864,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
8717
8864
  gqlClient,
8718
8865
  analysisId: reportUploadInfo.fixReportId,
8719
8866
  commitDirectly,
8867
+ prId: pullRequest,
8720
8868
  createSpinner: createSpinner5
8721
8869
  });
8722
8870
  }
@@ -8823,7 +8971,8 @@ async function analyze({
8823
8971
  mobbProjectName,
8824
8972
  organizationId,
8825
8973
  autoPr,
8826
- commitDirectly
8974
+ commitDirectly,
8975
+ pullRequest
8827
8976
  }, { skipPrompts = false } = {}) {
8828
8977
  !ci && await showWelcomeMessage(skipPrompts);
8829
8978
  await runAnalysis(
@@ -8839,7 +8988,8 @@ async function analyze({
8839
8988
  organizationId,
8840
8989
  command: "analyze",
8841
8990
  autoPr,
8842
- commitDirectly
8991
+ commitDirectly,
8992
+ pullRequest
8843
8993
  },
8844
8994
  { skipPrompts }
8845
8995
  );
@@ -9082,7 +9232,7 @@ var scmTokenOption = {
9082
9232
  // src/args/validation.ts
9083
9233
  import chalk7 from "chalk";
9084
9234
  import path8 from "path";
9085
- import { z as z31 } from "zod";
9235
+ import { z as z32 } from "zod";
9086
9236
  function throwRepoUrlErrorMessage({
9087
9237
  error,
9088
9238
  repoUrl,
@@ -9099,11 +9249,11 @@ Example:
9099
9249
  )}`;
9100
9250
  throw new CliError(formattedErrorMessage);
9101
9251
  }
9102
- var UrlZ = z31.string({
9252
+ var UrlZ = z32.string({
9103
9253
  invalid_type_error: `is not a valid ${Object.values(ScmType).join("/ ")} URL`
9104
9254
  });
9105
9255
  function validateOrganizationId(organizationId) {
9106
- const orgIdValidation = z31.string().uuid().nullish().safeParse(organizationId);
9256
+ const orgIdValidation = z32.string().uuid().nullish().safeParse(organizationId);
9107
9257
  if (!orgIdValidation.success) {
9108
9258
  throw new CliError(`organizationId: ${organizationId} is not a valid UUID`);
9109
9259
  }
@@ -9150,14 +9300,19 @@ function analyzeBuilder(yargs2) {
9150
9300
  }).option("repo", repoOption).option("p", {
9151
9301
  alias: "src-path",
9152
9302
  describe: chalk8.bold(
9153
- "Path to the repository folder with the source code"
9303
+ "Path to the repository folder with the source code; alternatively, you can specify the Fortify FPR file to extract source code out of it"
9154
9304
  ),
9155
9305
  type: "string"
9156
9306
  }).option("ref", refOption).option("ch", {
9157
9307
  alias: "commit-hash",
9158
9308
  describe: chalk8.bold("Hash of the commit"),
9159
9309
  type: "string"
9160
- }).option("mobb-project-name", mobbProjectNameOption).option("y", yesOption).option("ci", ciOption).option("org", organizationIdOptions).option("api-key", apiKeyOption).option("commit-hash", commitHashOption).option("auto-pr", autoPrOption).option("commit-directly", commitDirectlyOption).example(
9310
+ }).option("mobb-project-name", mobbProjectNameOption).option("y", yesOption).option("ci", ciOption).option("org", organizationIdOptions).option("api-key", apiKeyOption).option("commit-hash", commitHashOption).option("auto-pr", autoPrOption).option("commit-directly", commitDirectlyOption).option("pull-request", {
9311
+ alias: ["pr", "pr-number", "pr-id"],
9312
+ describe: chalk8.bold("Number of the pull request"),
9313
+ type: "number",
9314
+ demandOption: false
9315
+ }).example(
9161
9316
  "npx mobbdev@latest analyze -r https://github.com/WebGoat/WebGoat -f <your_vulnerability_report_path>",
9162
9317
  "analyze an existing repository"
9163
9318
  ).help();
@@ -9182,6 +9337,11 @@ Can't access ${chalk8.bold(argv.f)}`);
9182
9337
  "--commit-directly flag requires --auto-pr to be provided as well"
9183
9338
  );
9184
9339
  }
9340
+ if (argv.pullRequest && !argv["commit-directly"]) {
9341
+ throw new CliError(
9342
+ "--pull-request flag requires --commit-directly to be provided as well"
9343
+ );
9344
+ }
9185
9345
  validateReportFileFormat(argv.f);
9186
9346
  }
9187
9347
  async function analyzeHandler(args) {
@@ -9210,7 +9370,7 @@ function reviewBuilder(yargs2) {
9210
9370
  type: "string",
9211
9371
  demandOption: true
9212
9372
  }).option("pull-request", {
9213
- alias: "pr",
9373
+ alias: ["pr", "pr-number", "pr-id"],
9214
9374
  describe: chalk9.bold("Number of the pull request"),
9215
9375
  type: "number",
9216
9376
  demandOption: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobbdev",
3
- "version": "1.0.45",
3
+ "version": "1.0.47",
4
4
  "description": "Automated secure code remediation tool",
5
5
  "repository": "git+https://github.com/mobb-dev/bugsy.git",
6
6
  "main": "dist/index.js",
@@ -70,6 +70,7 @@
70
70
  "undici": "6.21.1",
71
71
  "uuid": "11.1.0",
72
72
  "ws": "8.18.0",
73
+ "xml2js": "0.6.2",
73
74
  "yargs": "17.7.2",
74
75
  "zod": "3.24.2"
75
76
  },
@@ -89,6 +90,7 @@
89
90
  "@types/tmp": "0.2.6",
90
91
  "@types/uuid": "10.0.0",
91
92
  "@types/ws": "8.5.14",
93
+ "@types/xml2js": "0.4.14",
92
94
  "@types/yargs": "17.0.33",
93
95
  "@typescript-eslint/eslint-plugin": "7.17.0",
94
96
  "@typescript-eslint/parser": "7.17.0",