mobbdev 1.2.22 → 1.2.27
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.
- package/dist/args/commands/upload_ai_blame.mjs +19 -9
- package/dist/index.mjs +201 -510
- package/package.json +1 -1
|
@@ -237,6 +237,7 @@ var init_client_generates = __esm({
|
|
|
237
237
|
IssueType_Enum2["DuplicatedStrings"] = "DUPLICATED_STRINGS";
|
|
238
238
|
IssueType_Enum2["ErroneousStringCompare"] = "ERRONEOUS_STRING_COMPARE";
|
|
239
239
|
IssueType_Enum2["ErrorCondtionWithoutAction"] = "ERROR_CONDTION_WITHOUT_ACTION";
|
|
240
|
+
IssueType_Enum2["ExcessiveSecretsExposure"] = "EXCESSIVE_SECRETS_EXPOSURE";
|
|
240
241
|
IssueType_Enum2["FrameableLoginPage"] = "FRAMEABLE_LOGIN_PAGE";
|
|
241
242
|
IssueType_Enum2["FunctionCallWithoutParentheses"] = "FUNCTION_CALL_WITHOUT_PARENTHESES";
|
|
242
243
|
IssueType_Enum2["GhActionsShellInjection"] = "GH_ACTIONS_SHELL_INJECTION";
|
|
@@ -881,6 +882,7 @@ var init_client_generates = __esm({
|
|
|
881
882
|
... on ProcessAIBlameRequestedResult {
|
|
882
883
|
status
|
|
883
884
|
requestIds
|
|
885
|
+
commitBlameRequestIds
|
|
884
886
|
}
|
|
885
887
|
}
|
|
886
888
|
}
|
|
@@ -1711,7 +1713,8 @@ var init_getIssueType = __esm({
|
|
|
1711
1713
|
["ACTION_NOT_PINNED_TO_COMMIT_SHA" /* ActionNotPinnedToCommitSha */]: "Action Not Pinned to Commit Sha",
|
|
1712
1714
|
["DJANGO_BLANK_FIELD_NEEDS_NULL_OR_DEFAULT" /* DjangoBlankFieldNeedsNullOrDefault */]: "Django Blank Field Needs Null or Default",
|
|
1713
1715
|
["REDUNDANT_NIL_ERROR_CHECK" /* RedundantNilErrorCheck */]: "Redundant Nil Error Check",
|
|
1714
|
-
["MISSING_WORKFLOW_PERMISSIONS" /* MissingWorkflowPermissions */]: "Missing Workflow Permissions"
|
|
1716
|
+
["MISSING_WORKFLOW_PERMISSIONS" /* MissingWorkflowPermissions */]: "Missing Workflow Permissions",
|
|
1717
|
+
["EXCESSIVE_SECRETS_EXPOSURE" /* ExcessiveSecretsExposure */]: "Excessive Secrets Exposure"
|
|
1715
1718
|
};
|
|
1716
1719
|
issueTypeZ = z5.nativeEnum(IssueType_Enum);
|
|
1717
1720
|
getIssueTypeFriendlyString = (issueType) => {
|
|
@@ -2571,11 +2574,20 @@ var init_urlParser = __esm({
|
|
|
2571
2574
|
}
|
|
2572
2575
|
});
|
|
2573
2576
|
|
|
2577
|
+
// src/features/analysis/scm/shared/src/urlParser/repoSlug.ts
|
|
2578
|
+
var init_repoSlug = __esm({
|
|
2579
|
+
"src/features/analysis/scm/shared/src/urlParser/repoSlug.ts"() {
|
|
2580
|
+
"use strict";
|
|
2581
|
+
init_urlParser();
|
|
2582
|
+
}
|
|
2583
|
+
});
|
|
2584
|
+
|
|
2574
2585
|
// src/features/analysis/scm/shared/src/urlParser/index.ts
|
|
2575
2586
|
var init_urlParser2 = __esm({
|
|
2576
2587
|
"src/features/analysis/scm/shared/src/urlParser/index.ts"() {
|
|
2577
2588
|
"use strict";
|
|
2578
2589
|
init_types2();
|
|
2590
|
+
init_repoSlug();
|
|
2579
2591
|
init_urlParser();
|
|
2580
2592
|
}
|
|
2581
2593
|
});
|
|
@@ -4210,7 +4222,9 @@ function subscribeStream(query, variables, handlers, wsClientOptions) {
|
|
|
4210
4222
|
finalizeError(error);
|
|
4211
4223
|
},
|
|
4212
4224
|
complete: () => {
|
|
4213
|
-
|
|
4225
|
+
finalizeError(
|
|
4226
|
+
new Error("Subscription completed by server before resolving")
|
|
4227
|
+
);
|
|
4214
4228
|
}
|
|
4215
4229
|
}
|
|
4216
4230
|
);
|
|
@@ -4544,7 +4558,8 @@ var fixDetailsData = {
|
|
|
4544
4558
|
["ACTION_NOT_PINNED_TO_COMMIT_SHA" /* ActionNotPinnedToCommitSha */]: void 0,
|
|
4545
4559
|
["DJANGO_BLANK_FIELD_NEEDS_NULL_OR_DEFAULT" /* DjangoBlankFieldNeedsNullOrDefault */]: void 0,
|
|
4546
4560
|
["REDUNDANT_NIL_ERROR_CHECK" /* RedundantNilErrorCheck */]: void 0,
|
|
4547
|
-
["MISSING_WORKFLOW_PERMISSIONS" /* MissingWorkflowPermissions */]: void 0
|
|
4561
|
+
["MISSING_WORKFLOW_PERMISSIONS" /* MissingWorkflowPermissions */]: void 0,
|
|
4562
|
+
["EXCESSIVE_SECRETS_EXPOSURE" /* ExcessiveSecretsExposure */]: void 0
|
|
4548
4563
|
};
|
|
4549
4564
|
|
|
4550
4565
|
// src/features/analysis/scm/shared/src/commitDescriptionMarkup.ts
|
|
@@ -6146,9 +6161,6 @@ var GetReferenceResultZ = z14.object({
|
|
|
6146
6161
|
type: z14.nativeEnum(ReferenceType)
|
|
6147
6162
|
});
|
|
6148
6163
|
|
|
6149
|
-
// src/features/analysis/scm/utils/diffUtils.ts
|
|
6150
|
-
import parseDiff from "parse-diff";
|
|
6151
|
-
|
|
6152
6164
|
// src/features/analysis/scm/ado/constants.ts
|
|
6153
6165
|
init_types2();
|
|
6154
6166
|
var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
|
|
@@ -6249,8 +6261,6 @@ var REPORT_DEFAULT_FILE_NAME = "report.json";
|
|
|
6249
6261
|
init_env();
|
|
6250
6262
|
|
|
6251
6263
|
// src/features/analysis/scm/github/GithubSCMLib.ts
|
|
6252
|
-
init_env();
|
|
6253
|
-
import pLimit from "p-limit";
|
|
6254
6264
|
import { z as z22 } from "zod";
|
|
6255
6265
|
init_client_generates();
|
|
6256
6266
|
|
|
@@ -6274,7 +6284,7 @@ import {
|
|
|
6274
6284
|
Gitlab
|
|
6275
6285
|
} from "@gitbeaker/rest";
|
|
6276
6286
|
import Debug4 from "debug";
|
|
6277
|
-
import
|
|
6287
|
+
import pLimit from "p-limit";
|
|
6278
6288
|
import {
|
|
6279
6289
|
Agent,
|
|
6280
6290
|
fetch as undiciFetch,
|
package/dist/index.mjs
CHANGED
|
@@ -237,6 +237,7 @@ var init_client_generates = __esm({
|
|
|
237
237
|
IssueType_Enum2["DuplicatedStrings"] = "DUPLICATED_STRINGS";
|
|
238
238
|
IssueType_Enum2["ErroneousStringCompare"] = "ERRONEOUS_STRING_COMPARE";
|
|
239
239
|
IssueType_Enum2["ErrorCondtionWithoutAction"] = "ERROR_CONDTION_WITHOUT_ACTION";
|
|
240
|
+
IssueType_Enum2["ExcessiveSecretsExposure"] = "EXCESSIVE_SECRETS_EXPOSURE";
|
|
240
241
|
IssueType_Enum2["FrameableLoginPage"] = "FRAMEABLE_LOGIN_PAGE";
|
|
241
242
|
IssueType_Enum2["FunctionCallWithoutParentheses"] = "FUNCTION_CALL_WITHOUT_PARENTHESES";
|
|
242
243
|
IssueType_Enum2["GhActionsShellInjection"] = "GH_ACTIONS_SHELL_INJECTION";
|
|
@@ -881,6 +882,7 @@ var init_client_generates = __esm({
|
|
|
881
882
|
... on ProcessAIBlameRequestedResult {
|
|
882
883
|
status
|
|
883
884
|
requestIds
|
|
885
|
+
commitBlameRequestIds
|
|
884
886
|
}
|
|
885
887
|
}
|
|
886
888
|
}
|
|
@@ -1411,7 +1413,8 @@ var init_getIssueType = __esm({
|
|
|
1411
1413
|
["ACTION_NOT_PINNED_TO_COMMIT_SHA" /* ActionNotPinnedToCommitSha */]: "Action Not Pinned to Commit Sha",
|
|
1412
1414
|
["DJANGO_BLANK_FIELD_NEEDS_NULL_OR_DEFAULT" /* DjangoBlankFieldNeedsNullOrDefault */]: "Django Blank Field Needs Null or Default",
|
|
1413
1415
|
["REDUNDANT_NIL_ERROR_CHECK" /* RedundantNilErrorCheck */]: "Redundant Nil Error Check",
|
|
1414
|
-
["MISSING_WORKFLOW_PERMISSIONS" /* MissingWorkflowPermissions */]: "Missing Workflow Permissions"
|
|
1416
|
+
["MISSING_WORKFLOW_PERMISSIONS" /* MissingWorkflowPermissions */]: "Missing Workflow Permissions",
|
|
1417
|
+
["EXCESSIVE_SECRETS_EXPOSURE" /* ExcessiveSecretsExposure */]: "Excessive Secrets Exposure"
|
|
1415
1418
|
};
|
|
1416
1419
|
issueTypeZ = z.nativeEnum(IssueType_Enum);
|
|
1417
1420
|
getIssueTypeFriendlyString = (issueType) => {
|
|
@@ -2620,11 +2623,20 @@ var init_urlParser = __esm({
|
|
|
2620
2623
|
}
|
|
2621
2624
|
});
|
|
2622
2625
|
|
|
2626
|
+
// src/features/analysis/scm/shared/src/urlParser/repoSlug.ts
|
|
2627
|
+
var init_repoSlug = __esm({
|
|
2628
|
+
"src/features/analysis/scm/shared/src/urlParser/repoSlug.ts"() {
|
|
2629
|
+
"use strict";
|
|
2630
|
+
init_urlParser();
|
|
2631
|
+
}
|
|
2632
|
+
});
|
|
2633
|
+
|
|
2623
2634
|
// src/features/analysis/scm/shared/src/urlParser/index.ts
|
|
2624
2635
|
var init_urlParser2 = __esm({
|
|
2625
2636
|
"src/features/analysis/scm/shared/src/urlParser/index.ts"() {
|
|
2626
2637
|
"use strict";
|
|
2627
2638
|
init_types2();
|
|
2639
|
+
init_repoSlug();
|
|
2628
2640
|
init_urlParser();
|
|
2629
2641
|
}
|
|
2630
2642
|
});
|
|
@@ -4274,7 +4286,8 @@ var fixDetailsData = {
|
|
|
4274
4286
|
["ACTION_NOT_PINNED_TO_COMMIT_SHA" /* ActionNotPinnedToCommitSha */]: void 0,
|
|
4275
4287
|
["DJANGO_BLANK_FIELD_NEEDS_NULL_OR_DEFAULT" /* DjangoBlankFieldNeedsNullOrDefault */]: void 0,
|
|
4276
4288
|
["REDUNDANT_NIL_ERROR_CHECK" /* RedundantNilErrorCheck */]: void 0,
|
|
4277
|
-
["MISSING_WORKFLOW_PERMISSIONS" /* MissingWorkflowPermissions */]: void 0
|
|
4289
|
+
["MISSING_WORKFLOW_PERMISSIONS" /* MissingWorkflowPermissions */]: void 0,
|
|
4290
|
+
["EXCESSIVE_SECRETS_EXPOSURE" /* ExcessiveSecretsExposure */]: void 0
|
|
4278
4291
|
};
|
|
4279
4292
|
|
|
4280
4293
|
// src/features/analysis/scm/shared/src/commitDescriptionMarkup.ts
|
|
@@ -6109,34 +6122,6 @@ var GetReferenceResultZ = z13.object({
|
|
|
6109
6122
|
type: z13.nativeEnum(ReferenceType)
|
|
6110
6123
|
});
|
|
6111
6124
|
|
|
6112
|
-
// src/features/analysis/scm/utils/diffUtils.ts
|
|
6113
|
-
import parseDiff from "parse-diff";
|
|
6114
|
-
function parseAddedLinesByFile(diff) {
|
|
6115
|
-
const result = /* @__PURE__ */ new Map();
|
|
6116
|
-
const parsedDiff = parseDiff(diff);
|
|
6117
|
-
for (const file of parsedDiff) {
|
|
6118
|
-
if (!file.to || file.to === "/dev/null") {
|
|
6119
|
-
continue;
|
|
6120
|
-
}
|
|
6121
|
-
const filePath = file.to;
|
|
6122
|
-
const addedLines = [];
|
|
6123
|
-
if (file.chunks) {
|
|
6124
|
-
for (const chunk of file.chunks) {
|
|
6125
|
-
for (const change of chunk.changes) {
|
|
6126
|
-
if (change.type === "add") {
|
|
6127
|
-
const addChange = change;
|
|
6128
|
-
addedLines.push(addChange.ln);
|
|
6129
|
-
}
|
|
6130
|
-
}
|
|
6131
|
-
}
|
|
6132
|
-
}
|
|
6133
|
-
if (addedLines.length > 0) {
|
|
6134
|
-
result.set(filePath, addedLines);
|
|
6135
|
-
}
|
|
6136
|
-
}
|
|
6137
|
-
return result;
|
|
6138
|
-
}
|
|
6139
|
-
|
|
6140
6125
|
// src/features/analysis/scm/utils/scm.ts
|
|
6141
6126
|
var safeBody = (body, maxBodyLength) => {
|
|
6142
6127
|
const truncationNotice = "\n\n... Message was cut here because it is too long";
|
|
@@ -7101,28 +7086,16 @@ var SCMLib = class {
|
|
|
7101
7086
|
*
|
|
7102
7087
|
* @param repoUrl - Repository URL
|
|
7103
7088
|
* @param prNumbers - Array of PR numbers to fetch commits for
|
|
7104
|
-
* @returns Map of PR number to array of commit SHAs
|
|
7089
|
+
* @returns Map of PR number to array of commit SHAs in chronological order
|
|
7090
|
+
* (oldest first, HEAD commit last)
|
|
7105
7091
|
*/
|
|
7106
7092
|
async getPrCommitsBatch(_repoUrl, _prNumbers) {
|
|
7107
7093
|
throw new Error("getPrCommitsBatch not implemented for this SCM provider");
|
|
7108
7094
|
}
|
|
7109
|
-
/**
|
|
7110
|
-
* Fetches additions and deletions counts for multiple PRs in batch.
|
|
7111
|
-
* More efficient than fetching individual PR details.
|
|
7112
|
-
*
|
|
7113
|
-
* @param repoUrl - Repository URL
|
|
7114
|
-
* @param prNumbers - Array of PR numbers to fetch metrics for
|
|
7115
|
-
* @returns Map of PR number to additions/deletions count
|
|
7116
|
-
*/
|
|
7117
|
-
async getPrAdditionsDeletionsBatch(_repoUrl, _prNumbers) {
|
|
7118
|
-
throw new Error(
|
|
7119
|
-
"getPrAdditionsDeletionsBatch not implemented for this SCM provider"
|
|
7120
|
-
);
|
|
7121
|
-
}
|
|
7122
7095
|
/**
|
|
7123
7096
|
* Batch fetch PR data (additions/deletions + comments) for multiple PRs.
|
|
7124
7097
|
* Only implemented for GitHub (via GraphQL). Other providers should override if supported.
|
|
7125
|
-
* This is more efficient than calling
|
|
7098
|
+
* This is more efficient than calling separate batch methods.
|
|
7126
7099
|
*
|
|
7127
7100
|
* @param _repoUrl - Repository URL
|
|
7128
7101
|
* @param _prNumbers - Array of PR numbers to fetch data for
|
|
@@ -7364,11 +7337,8 @@ var AdoSCMLib = class extends SCMLib {
|
|
|
7364
7337
|
markdownComment: comment
|
|
7365
7338
|
});
|
|
7366
7339
|
}
|
|
7367
|
-
async
|
|
7368
|
-
throw new Error("
|
|
7369
|
-
}
|
|
7370
|
-
async getSubmitRequestDiff(_submitRequestId) {
|
|
7371
|
-
throw new Error("getSubmitRequestDiff not implemented for ADO");
|
|
7340
|
+
async getSubmitRequestMetadata(_submitRequestId) {
|
|
7341
|
+
throw new Error("getSubmitRequestMetadata not implemented for ADO");
|
|
7372
7342
|
}
|
|
7373
7343
|
async searchSubmitRequests(_params) {
|
|
7374
7344
|
throw new Error("searchSubmitRequests not implemented for ADO");
|
|
@@ -7946,11 +7916,8 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
7946
7916
|
markdownComment: comment
|
|
7947
7917
|
});
|
|
7948
7918
|
}
|
|
7949
|
-
async
|
|
7950
|
-
throw new Error("
|
|
7951
|
-
}
|
|
7952
|
-
async getSubmitRequestDiff(_submitRequestId) {
|
|
7953
|
-
throw new Error("getSubmitRequestDiff not implemented for Bitbucket");
|
|
7919
|
+
async getSubmitRequestMetadata(_submitRequestId) {
|
|
7920
|
+
throw new Error("getSubmitRequestMetadata not implemented for Bitbucket");
|
|
7954
7921
|
}
|
|
7955
7922
|
async searchSubmitRequests(_params) {
|
|
7956
7923
|
throw new Error("searchSubmitRequests not implemented for Bitbucket");
|
|
@@ -7980,8 +7947,6 @@ var REPORT_DEFAULT_FILE_NAME = "report.json";
|
|
|
7980
7947
|
init_env();
|
|
7981
7948
|
|
|
7982
7949
|
// src/features/analysis/scm/github/GithubSCMLib.ts
|
|
7983
|
-
init_env();
|
|
7984
|
-
import pLimit from "p-limit";
|
|
7985
7950
|
import { z as z21 } from "zod";
|
|
7986
7951
|
init_client_generates();
|
|
7987
7952
|
|
|
@@ -8054,18 +8019,6 @@ var GET_PR_METRICS_QUERY = `
|
|
|
8054
8019
|
mergedAt
|
|
8055
8020
|
additions
|
|
8056
8021
|
deletions
|
|
8057
|
-
commits(first: 100) {
|
|
8058
|
-
totalCount
|
|
8059
|
-
nodes {
|
|
8060
|
-
commit {
|
|
8061
|
-
oid
|
|
8062
|
-
committedDate
|
|
8063
|
-
author {
|
|
8064
|
-
date
|
|
8065
|
-
}
|
|
8066
|
-
}
|
|
8067
|
-
}
|
|
8068
|
-
}
|
|
8069
8022
|
comments(first: 100) {
|
|
8070
8023
|
totalCount
|
|
8071
8024
|
nodes {
|
|
@@ -8506,33 +8459,6 @@ function getGithubSdk(params = {}) {
|
|
|
8506
8459
|
commit_sha: commitSha
|
|
8507
8460
|
});
|
|
8508
8461
|
},
|
|
8509
|
-
async getCommitWithDiff({
|
|
8510
|
-
commitSha,
|
|
8511
|
-
owner,
|
|
8512
|
-
repo
|
|
8513
|
-
}) {
|
|
8514
|
-
const [commitData, diffData] = await Promise.all([
|
|
8515
|
-
// Get commit metadata
|
|
8516
|
-
octokit.rest.repos.getCommit({
|
|
8517
|
-
repo,
|
|
8518
|
-
owner,
|
|
8519
|
-
ref: commitSha
|
|
8520
|
-
}),
|
|
8521
|
-
// Get commit diff
|
|
8522
|
-
octokit.request("GET /repos/{owner}/{repo}/commits/{ref}", {
|
|
8523
|
-
owner,
|
|
8524
|
-
repo,
|
|
8525
|
-
ref: commitSha,
|
|
8526
|
-
headers: {
|
|
8527
|
-
Accept: "application/vnd.github.v3.diff"
|
|
8528
|
-
}
|
|
8529
|
-
})
|
|
8530
|
-
]);
|
|
8531
|
-
return {
|
|
8532
|
-
commit: commitData.data,
|
|
8533
|
-
diff: diffData.data
|
|
8534
|
-
};
|
|
8535
|
-
},
|
|
8536
8462
|
async getTagDate({
|
|
8537
8463
|
tag,
|
|
8538
8464
|
owner,
|
|
@@ -8716,14 +8642,6 @@ function getGithubSdk(params = {}) {
|
|
|
8716
8642
|
async getUserInfo() {
|
|
8717
8643
|
return octokit.request(GET_USER);
|
|
8718
8644
|
},
|
|
8719
|
-
async getPrCommits(params2) {
|
|
8720
|
-
const data = await octokit.paginate(octokit.rest.pulls.listCommits, {
|
|
8721
|
-
owner: params2.owner,
|
|
8722
|
-
repo: params2.repo,
|
|
8723
|
-
pull_number: params2.pull_number
|
|
8724
|
-
});
|
|
8725
|
-
return { data };
|
|
8726
|
-
},
|
|
8727
8645
|
async getUserRepos() {
|
|
8728
8646
|
return octokit.rest.repos.listForAuthenticatedUser({
|
|
8729
8647
|
visibility: "all",
|
|
@@ -8767,30 +8685,6 @@ function getGithubSdk(params = {}) {
|
|
|
8767
8685
|
});
|
|
8768
8686
|
return { data };
|
|
8769
8687
|
},
|
|
8770
|
-
/**
|
|
8771
|
-
* Batch fetch additions/deletions for multiple PRs via GraphQL.
|
|
8772
|
-
* Uses GITHUB_GRAPHQL_FRAGMENTS.PR_CHANGES for the field selection.
|
|
8773
|
-
*/
|
|
8774
|
-
async getPrAdditionsDeletionsBatch(params2) {
|
|
8775
|
-
return executeBatchGraphQL(octokit, params2.owner, params2.repo, {
|
|
8776
|
-
items: params2.prNumbers,
|
|
8777
|
-
aliasPrefix: "pr",
|
|
8778
|
-
buildFragment: (prNumber, index) => `
|
|
8779
|
-
pr${index}: pullRequest(number: ${prNumber}) {
|
|
8780
|
-
${GITHUB_GRAPHQL_FRAGMENTS.PR_CHANGES}
|
|
8781
|
-
}`,
|
|
8782
|
-
extractResult: (data) => {
|
|
8783
|
-
const prData = data;
|
|
8784
|
-
if (prData.additions !== void 0 && prData.deletions !== void 0) {
|
|
8785
|
-
return {
|
|
8786
|
-
additions: prData.additions,
|
|
8787
|
-
deletions: prData.deletions
|
|
8788
|
-
};
|
|
8789
|
-
}
|
|
8790
|
-
return void 0;
|
|
8791
|
-
}
|
|
8792
|
-
});
|
|
8793
|
-
},
|
|
8794
8688
|
/**
|
|
8795
8689
|
* Batch fetch comments for multiple PRs via GraphQL.
|
|
8796
8690
|
* Uses GITHUB_GRAPHQL_FRAGMENTS.PR_COMMENTS for the field selection.
|
|
@@ -8818,7 +8712,7 @@ function getGithubSdk(params = {}) {
|
|
|
8818
8712
|
/**
|
|
8819
8713
|
* Batch fetch PR data (additions/deletions + comments) for multiple PRs via GraphQL.
|
|
8820
8714
|
* Combines PR_CHANGES and PR_COMMENTS fragments into a single API call for efficiency.
|
|
8821
|
-
* This is more efficient than calling
|
|
8715
|
+
* This is more efficient than calling separate batch methods.
|
|
8822
8716
|
*/
|
|
8823
8717
|
async getPrDataBatch(params2) {
|
|
8824
8718
|
return executeBatchGraphQL(octokit, params2.owner, params2.repo, {
|
|
@@ -9209,82 +9103,21 @@ var GithubSCMLib = class _GithubSCMLib extends SCMLib {
|
|
|
9209
9103
|
comment_id: commentId
|
|
9210
9104
|
});
|
|
9211
9105
|
}
|
|
9212
|
-
async
|
|
9106
|
+
async getSubmitRequestMetadata(submitRequestId) {
|
|
9213
9107
|
this._validateAccessTokenAndUrl();
|
|
9214
9108
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
9215
|
-
const
|
|
9109
|
+
const prNumber = Number(submitRequestId);
|
|
9110
|
+
const prRes = await this.githubSdk.getPr({
|
|
9216
9111
|
owner,
|
|
9217
9112
|
repo,
|
|
9218
|
-
|
|
9113
|
+
pull_number: prNumber
|
|
9219
9114
|
});
|
|
9220
|
-
const commitTimestamp = commit.commit.committer?.date ? new Date(commit.commit.committer.date) : new Date(commit.commit.author?.date || Date.now());
|
|
9221
|
-
let repositoryCreatedAt = options?.repositoryCreatedAt;
|
|
9222
|
-
if (repositoryCreatedAt === void 0) {
|
|
9223
|
-
try {
|
|
9224
|
-
const repoData = await this.githubSdk.getRepository({ owner, repo });
|
|
9225
|
-
repositoryCreatedAt = repoData.data.created_at ? new Date(repoData.data.created_at) : void 0;
|
|
9226
|
-
} catch (error) {
|
|
9227
|
-
console.error("Failed to fetch repository creation date", {
|
|
9228
|
-
error,
|
|
9229
|
-
owner,
|
|
9230
|
-
repo
|
|
9231
|
-
});
|
|
9232
|
-
repositoryCreatedAt = void 0;
|
|
9233
|
-
}
|
|
9234
|
-
}
|
|
9235
|
-
return {
|
|
9236
|
-
diff,
|
|
9237
|
-
commitTimestamp,
|
|
9238
|
-
commitSha: commit.sha,
|
|
9239
|
-
authorName: commit.commit.author?.name,
|
|
9240
|
-
authorEmail: commit.commit.author?.email,
|
|
9241
|
-
message: commit.commit.message,
|
|
9242
|
-
repositoryCreatedAt
|
|
9243
|
-
};
|
|
9244
|
-
}
|
|
9245
|
-
async getSubmitRequestDiff(submitRequestId) {
|
|
9246
|
-
this._validateAccessTokenAndUrl();
|
|
9247
|
-
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
9248
|
-
const prNumber = Number(submitRequestId);
|
|
9249
|
-
const [prRes, commitsRes, repoData, prDiff] = await Promise.all([
|
|
9250
|
-
this.githubSdk.getPr({ owner, repo, pull_number: prNumber }),
|
|
9251
|
-
this.githubSdk.getPrCommits({ owner, repo, pull_number: prNumber }),
|
|
9252
|
-
this.githubSdk.getRepository({ owner, repo }),
|
|
9253
|
-
this.getPrDiff({ pull_number: prNumber })
|
|
9254
|
-
]);
|
|
9255
9115
|
const pr = prRes.data;
|
|
9256
|
-
const repositoryCreatedAt = repoData.data.created_at ? new Date(repoData.data.created_at) : void 0;
|
|
9257
|
-
const limit = pLimit(GITHUB_API_CONCURRENCY);
|
|
9258
|
-
const commits = await Promise.all(
|
|
9259
|
-
commitsRes.data.map(
|
|
9260
|
-
(commit) => limit(
|
|
9261
|
-
() => this.getCommitDiff(commit.sha, {
|
|
9262
|
-
repositoryCreatedAt
|
|
9263
|
-
})
|
|
9264
|
-
)
|
|
9265
|
-
)
|
|
9266
|
-
);
|
|
9267
|
-
const addedLinesByFile = parseAddedLinesByFile(prDiff);
|
|
9268
|
-
const diffLines = [];
|
|
9269
|
-
for (const [file, lines] of addedLinesByFile) {
|
|
9270
|
-
for (const line of lines) {
|
|
9271
|
-
diffLines.push({ file, line });
|
|
9272
|
-
}
|
|
9273
|
-
}
|
|
9274
9116
|
return {
|
|
9275
|
-
diff: prDiff,
|
|
9276
|
-
createdAt: new Date(pr.created_at),
|
|
9277
|
-
updatedAt: new Date(pr.updated_at),
|
|
9278
|
-
submitRequestId,
|
|
9279
|
-
submitRequestNumber: prNumber,
|
|
9280
|
-
sourceBranch: pr.head.ref,
|
|
9281
|
-
targetBranch: pr.base.ref,
|
|
9282
|
-
authorName: pr.user?.name || pr.user?.login,
|
|
9283
|
-
authorEmail: pr.user?.email || void 0,
|
|
9284
9117
|
title: pr.title,
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9118
|
+
targetBranch: pr.base.ref,
|
|
9119
|
+
sourceBranch: pr.head.ref,
|
|
9120
|
+
headCommitSha: pr.head.sha
|
|
9288
9121
|
};
|
|
9289
9122
|
}
|
|
9290
9123
|
/**
|
|
@@ -9342,7 +9175,7 @@ var GithubSCMLib = class _GithubSCMLib extends SCMLib {
|
|
|
9342
9175
|
}
|
|
9343
9176
|
/**
|
|
9344
9177
|
* Fetches commits for multiple PRs in a single GraphQL request.
|
|
9345
|
-
* Much more efficient than
|
|
9178
|
+
* Much more efficient than fetching commits for each PR individually.
|
|
9346
9179
|
*
|
|
9347
9180
|
* @param repoUrl - Repository URL
|
|
9348
9181
|
* @param prNumbers - Array of PR numbers to fetch commits for
|
|
@@ -9353,23 +9186,6 @@ var GithubSCMLib = class _GithubSCMLib extends SCMLib {
|
|
|
9353
9186
|
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
9354
9187
|
return this.githubSdk.getPrCommitsBatch({ owner, repo, prNumbers });
|
|
9355
9188
|
}
|
|
9356
|
-
/**
|
|
9357
|
-
* Fetches additions and deletions counts for multiple PRs in a single GraphQL request.
|
|
9358
|
-
* Used to enrich search results with changed lines data.
|
|
9359
|
-
*
|
|
9360
|
-
* @param repoUrl - Repository URL
|
|
9361
|
-
* @param prNumbers - Array of PR numbers to fetch metrics for
|
|
9362
|
-
* @returns Map of PR number to additions/deletions count
|
|
9363
|
-
*/
|
|
9364
|
-
async getPrAdditionsDeletionsBatch(repoUrl, prNumbers) {
|
|
9365
|
-
this._validateAccessToken();
|
|
9366
|
-
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
9367
|
-
return this.githubSdk.getPrAdditionsDeletionsBatch({
|
|
9368
|
-
owner,
|
|
9369
|
-
repo,
|
|
9370
|
-
prNumbers
|
|
9371
|
-
});
|
|
9372
|
-
}
|
|
9373
9189
|
/**
|
|
9374
9190
|
* Batch fetch PR data (additions/deletions + comments) for multiple PRs.
|
|
9375
9191
|
* Combines both metrics into a single GraphQL call for efficiency.
|
|
@@ -9469,19 +9285,6 @@ var GithubSCMLib = class _GithubSCMLib extends SCMLib {
|
|
|
9469
9285
|
throw new Error(`Pull request #${prNumber} not found`);
|
|
9470
9286
|
}
|
|
9471
9287
|
const prStatus = determinePrStatus(pr.state, pr.isDraft);
|
|
9472
|
-
const firstCommit = pr.commits.nodes[0];
|
|
9473
|
-
const firstCommitDate = firstCommit ? new Date(
|
|
9474
|
-
firstCommit.commit.author?.date || firstCommit.commit.committedDate || pr.createdAt
|
|
9475
|
-
) : null;
|
|
9476
|
-
let commitShas = pr.commits.nodes.map((node) => node.commit.oid);
|
|
9477
|
-
if (pr.commits.totalCount > 100) {
|
|
9478
|
-
const commitsRes = await this.githubSdk.getPrCommits({
|
|
9479
|
-
owner,
|
|
9480
|
-
repo,
|
|
9481
|
-
pull_number: prNumber
|
|
9482
|
-
});
|
|
9483
|
-
commitShas = commitsRes.data.map((c) => c.sha);
|
|
9484
|
-
}
|
|
9485
9288
|
let commentIds = pr.comments.nodes.map((node) => node.id);
|
|
9486
9289
|
if (pr.comments.totalCount > 100) {
|
|
9487
9290
|
const commentsRes = await this.githubSdk.getGeneralPrComments({
|
|
@@ -9496,10 +9299,7 @@ var GithubSCMLib = class _GithubSCMLib extends SCMLib {
|
|
|
9496
9299
|
repositoryUrl: this.url,
|
|
9497
9300
|
prCreatedAt: new Date(pr.createdAt),
|
|
9498
9301
|
prMergedAt: pr.mergedAt ? new Date(pr.mergedAt) : null,
|
|
9499
|
-
firstCommitDate,
|
|
9500
9302
|
linesAdded: pr.additions,
|
|
9501
|
-
commitsCount: pr.commits.totalCount,
|
|
9502
|
-
commitShas,
|
|
9503
9303
|
prStatus,
|
|
9504
9304
|
commentIds
|
|
9505
9305
|
};
|
|
@@ -9537,7 +9337,7 @@ import {
|
|
|
9537
9337
|
Gitlab
|
|
9538
9338
|
} from "@gitbeaker/rest";
|
|
9539
9339
|
import Debug3 from "debug";
|
|
9540
|
-
import
|
|
9340
|
+
import pLimit from "p-limit";
|
|
9541
9341
|
import {
|
|
9542
9342
|
Agent,
|
|
9543
9343
|
fetch as undiciFetch,
|
|
@@ -9619,14 +9419,6 @@ function removeTrailingSlash2(str) {
|
|
|
9619
9419
|
return str.trim().replace(/\/+$/, "");
|
|
9620
9420
|
}
|
|
9621
9421
|
var MAX_GITLAB_PR_BODY_LENGTH = 1048576;
|
|
9622
|
-
function buildUnifiedDiff(diffs) {
|
|
9623
|
-
return diffs.filter((d) => d.diff).map((d) => {
|
|
9624
|
-
const oldPath = d.old_path || d.new_path || "";
|
|
9625
|
-
const newPath = d.new_path || d.old_path || "";
|
|
9626
|
-
return `diff --git a/${oldPath} b/${newPath}
|
|
9627
|
-
${d.diff}`;
|
|
9628
|
-
}).join("\n");
|
|
9629
|
-
}
|
|
9630
9422
|
function getRandomGitlabCloudAnonToken() {
|
|
9631
9423
|
if (!GITLAB_API_TOKEN || typeof GITLAB_API_TOKEN !== "string") {
|
|
9632
9424
|
return void 0;
|
|
@@ -9776,34 +9568,74 @@ async function getGitlabIsRemoteBranch({
|
|
|
9776
9568
|
return false;
|
|
9777
9569
|
}
|
|
9778
9570
|
}
|
|
9779
|
-
async function
|
|
9571
|
+
async function searchGitlabProjects({
|
|
9572
|
+
url,
|
|
9573
|
+
accessToken,
|
|
9574
|
+
perPage = 20,
|
|
9575
|
+
page = 1
|
|
9576
|
+
}) {
|
|
9577
|
+
if (perPage > GITLAB_MAX_PER_PAGE) {
|
|
9578
|
+
throw new Error(
|
|
9579
|
+
`perPage ${perPage} exceeds GitLab maximum of ${GITLAB_MAX_PER_PAGE}`
|
|
9580
|
+
);
|
|
9581
|
+
}
|
|
9780
9582
|
const api2 = getGitBeaker({ url, gitlabAuthToken: accessToken });
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
})
|
|
9806
|
-
|
|
9583
|
+
let response;
|
|
9584
|
+
try {
|
|
9585
|
+
response = await api2.Projects.all({
|
|
9586
|
+
membership: true,
|
|
9587
|
+
orderBy: "last_activity_at",
|
|
9588
|
+
sort: "desc",
|
|
9589
|
+
pagination: "offset",
|
|
9590
|
+
perPage,
|
|
9591
|
+
page,
|
|
9592
|
+
showExpanded: true
|
|
9593
|
+
});
|
|
9594
|
+
} catch (e) {
|
|
9595
|
+
debug4(
|
|
9596
|
+
"[searchGitlabProjects] order_by=last_activity_at failed, falling back to created_at: %s",
|
|
9597
|
+
e instanceof Error ? e.message : String(e)
|
|
9598
|
+
);
|
|
9599
|
+
response = await api2.Projects.all({
|
|
9600
|
+
membership: true,
|
|
9601
|
+
orderBy: "created_at",
|
|
9602
|
+
sort: "desc",
|
|
9603
|
+
pagination: "offset",
|
|
9604
|
+
perPage,
|
|
9605
|
+
page,
|
|
9606
|
+
showExpanded: true
|
|
9607
|
+
});
|
|
9608
|
+
}
|
|
9609
|
+
const projects = response.data.map((p) => ({
|
|
9610
|
+
id: p.id,
|
|
9611
|
+
path: p.path,
|
|
9612
|
+
web_url: p.web_url,
|
|
9613
|
+
namespace_name: p.namespace?.name ?? "",
|
|
9614
|
+
visibility: p.visibility,
|
|
9615
|
+
last_activity_at: p.last_activity_at
|
|
9616
|
+
}));
|
|
9617
|
+
return {
|
|
9618
|
+
projects,
|
|
9619
|
+
hasMore: response.paginationInfo.next !== null
|
|
9620
|
+
};
|
|
9621
|
+
}
|
|
9622
|
+
async function getGitlabProjectLanguages({
|
|
9623
|
+
url,
|
|
9624
|
+
accessToken,
|
|
9625
|
+
projectId
|
|
9626
|
+
}) {
|
|
9627
|
+
try {
|
|
9628
|
+
const api2 = getGitBeaker({ url, gitlabAuthToken: accessToken });
|
|
9629
|
+
const languages3 = await api2.Projects.showLanguages(projectId);
|
|
9630
|
+
return Object.keys(languages3);
|
|
9631
|
+
} catch (e) {
|
|
9632
|
+
debug4(
|
|
9633
|
+
"[getGitlabProjectLanguages] Failed for project %d: %s",
|
|
9634
|
+
projectId,
|
|
9635
|
+
e instanceof Error ? e.message : String(e)
|
|
9636
|
+
);
|
|
9637
|
+
return [];
|
|
9638
|
+
}
|
|
9807
9639
|
}
|
|
9808
9640
|
async function getGitlabBranchList({
|
|
9809
9641
|
accessToken,
|
|
@@ -9873,6 +9705,11 @@ async function searchGitlabMergeRequests({
|
|
|
9873
9705
|
perPage = GITLAB_PER_PAGE,
|
|
9874
9706
|
page = 1
|
|
9875
9707
|
}) {
|
|
9708
|
+
if (perPage > GITLAB_MAX_PER_PAGE) {
|
|
9709
|
+
throw new Error(
|
|
9710
|
+
`perPage ${perPage} exceeds GitLab maximum of ${GITLAB_MAX_PER_PAGE}`
|
|
9711
|
+
);
|
|
9712
|
+
}
|
|
9876
9713
|
const { projectPath } = parseGitlabOwnerAndRepo(repoUrl);
|
|
9877
9714
|
debug4(
|
|
9878
9715
|
"[searchGitlabMergeRequests] Fetching MRs for %s (page=%d, perPage=%d)",
|
|
@@ -9884,16 +9721,17 @@ async function searchGitlabMergeRequests({
|
|
|
9884
9721
|
url: repoUrl,
|
|
9885
9722
|
gitlabAuthToken: accessToken
|
|
9886
9723
|
});
|
|
9887
|
-
const
|
|
9724
|
+
const response = await api2.MergeRequests.all({
|
|
9888
9725
|
projectId: projectPath,
|
|
9889
9726
|
state: state === "all" ? void 0 : state,
|
|
9890
9727
|
updatedAfter: updatedAfter?.toISOString(),
|
|
9891
9728
|
orderBy,
|
|
9892
9729
|
sort,
|
|
9893
9730
|
perPage,
|
|
9894
|
-
page
|
|
9731
|
+
page,
|
|
9732
|
+
showExpanded: true
|
|
9895
9733
|
});
|
|
9896
|
-
const items =
|
|
9734
|
+
const items = response.data.map((mr) => ({
|
|
9897
9735
|
iid: mr.iid,
|
|
9898
9736
|
title: mr.title,
|
|
9899
9737
|
state: mr.state,
|
|
@@ -9911,7 +9749,7 @@ async function searchGitlabMergeRequests({
|
|
|
9911
9749
|
);
|
|
9912
9750
|
return {
|
|
9913
9751
|
items,
|
|
9914
|
-
hasMore:
|
|
9752
|
+
hasMore: response.paginationInfo.next !== null
|
|
9915
9753
|
};
|
|
9916
9754
|
}
|
|
9917
9755
|
var GITLAB_API_CONCURRENCY = 5;
|
|
@@ -9928,7 +9766,7 @@ async function getGitlabMrCommitsBatch({
|
|
|
9928
9766
|
url: repoUrl,
|
|
9929
9767
|
gitlabAuthToken: accessToken
|
|
9930
9768
|
});
|
|
9931
|
-
const limit =
|
|
9769
|
+
const limit = pLimit(GITLAB_API_CONCURRENCY);
|
|
9932
9770
|
const results = await Promise.all(
|
|
9933
9771
|
mrNumbers.map(
|
|
9934
9772
|
(mrNumber) => limit(async () => {
|
|
@@ -9937,7 +9775,7 @@ async function getGitlabMrCommitsBatch({
|
|
|
9937
9775
|
projectPath,
|
|
9938
9776
|
mrNumber
|
|
9939
9777
|
);
|
|
9940
|
-
return [mrNumber, commits.map((c) => c.id)];
|
|
9778
|
+
return [mrNumber, commits.map((c) => c.id).reverse()];
|
|
9941
9779
|
} catch (error) {
|
|
9942
9780
|
contextLogger.warn(
|
|
9943
9781
|
"[getGitlabMrCommitsBatch] Failed to fetch commits for MR",
|
|
@@ -9967,28 +9805,12 @@ async function getGitlabMrDataBatch({
|
|
|
9967
9805
|
url: repoUrl,
|
|
9968
9806
|
gitlabAuthToken: accessToken
|
|
9969
9807
|
});
|
|
9970
|
-
const limit =
|
|
9808
|
+
const limit = pLimit(GITLAB_API_CONCURRENCY);
|
|
9971
9809
|
const results = await Promise.all(
|
|
9972
9810
|
mrNumbers.map(
|
|
9973
9811
|
(mrNumber) => limit(async () => {
|
|
9974
9812
|
try {
|
|
9975
|
-
const
|
|
9976
|
-
api2.MergeRequests.allDiffs(projectPath, mrNumber),
|
|
9977
|
-
api2.MergeRequestNotes.all(projectPath, mrNumber)
|
|
9978
|
-
]);
|
|
9979
|
-
let additions = 0;
|
|
9980
|
-
let deletions = 0;
|
|
9981
|
-
for (const diff of diffs) {
|
|
9982
|
-
if (diff.diff) {
|
|
9983
|
-
for (const line of diff.diff.split("\n")) {
|
|
9984
|
-
if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
9985
|
-
additions++;
|
|
9986
|
-
} else if (line.startsWith("-") && !line.startsWith("---")) {
|
|
9987
|
-
deletions++;
|
|
9988
|
-
}
|
|
9989
|
-
}
|
|
9990
|
-
}
|
|
9991
|
-
}
|
|
9813
|
+
const notes = await api2.MergeRequestNotes.all(projectPath, mrNumber);
|
|
9992
9814
|
const comments = notes.map((note) => ({
|
|
9993
9815
|
author: note.author ? {
|
|
9994
9816
|
login: note.author.username,
|
|
@@ -9998,7 +9820,7 @@ async function getGitlabMrDataBatch({
|
|
|
9998
9820
|
}));
|
|
9999
9821
|
return [
|
|
10000
9822
|
mrNumber,
|
|
10001
|
-
{ changedLines: { additions, deletions }, comments }
|
|
9823
|
+
{ changedLines: { additions: 0, deletions: 0 }, comments }
|
|
10002
9824
|
];
|
|
10003
9825
|
} catch (error) {
|
|
10004
9826
|
contextLogger.warn(
|
|
@@ -10022,39 +9844,6 @@ async function getGitlabMrDataBatch({
|
|
|
10022
9844
|
);
|
|
10023
9845
|
return new Map(results);
|
|
10024
9846
|
}
|
|
10025
|
-
async function getGitlabMergeRequestLinesAdded({
|
|
10026
|
-
url,
|
|
10027
|
-
prNumber,
|
|
10028
|
-
accessToken
|
|
10029
|
-
}) {
|
|
10030
|
-
try {
|
|
10031
|
-
const { projectPath } = parseGitlabOwnerAndRepo(url);
|
|
10032
|
-
const api2 = getGitBeaker({
|
|
10033
|
-
url,
|
|
10034
|
-
gitlabAuthToken: accessToken
|
|
10035
|
-
});
|
|
10036
|
-
const diffs = await api2.MergeRequests.allDiffs(projectPath, prNumber);
|
|
10037
|
-
let linesAdded = 0;
|
|
10038
|
-
for (const diff of diffs) {
|
|
10039
|
-
if (diff.diff) {
|
|
10040
|
-
const addedLines = diff.diff.split("\n").filter(
|
|
10041
|
-
(line) => line.startsWith("+") && !line.startsWith("+++")
|
|
10042
|
-
).length;
|
|
10043
|
-
linesAdded += addedLines;
|
|
10044
|
-
}
|
|
10045
|
-
}
|
|
10046
|
-
return linesAdded;
|
|
10047
|
-
} catch (error) {
|
|
10048
|
-
contextLogger.warn(
|
|
10049
|
-
"[getGitlabMergeRequestLinesAdded] Failed to fetch diffs for MR",
|
|
10050
|
-
{
|
|
10051
|
-
prNumber,
|
|
10052
|
-
error
|
|
10053
|
-
}
|
|
10054
|
-
);
|
|
10055
|
-
return 0;
|
|
10056
|
-
}
|
|
10057
|
-
}
|
|
10058
9847
|
async function getGitlabMergeRequestMetrics({
|
|
10059
9848
|
url,
|
|
10060
9849
|
prNumber,
|
|
@@ -10065,26 +9854,17 @@ async function getGitlabMergeRequestMetrics({
|
|
|
10065
9854
|
url,
|
|
10066
9855
|
gitlabAuthToken: accessToken
|
|
10067
9856
|
});
|
|
10068
|
-
const [mr,
|
|
9857
|
+
const [mr, notes] = await Promise.all([
|
|
10069
9858
|
api2.MergeRequests.show(projectPath, prNumber),
|
|
10070
|
-
api2.MergeRequests.allCommits(projectPath, prNumber),
|
|
10071
|
-
getGitlabMergeRequestLinesAdded({ url, prNumber, accessToken }),
|
|
10072
9859
|
api2.MergeRequestNotes.all(projectPath, prNumber)
|
|
10073
9860
|
]);
|
|
10074
|
-
const sortedCommits = [...commits].sort(
|
|
10075
|
-
(a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
|
|
10076
|
-
);
|
|
10077
|
-
const firstCommitDate = sortedCommits[0]?.created_at ?? null;
|
|
10078
9861
|
const commentIds = notes.filter((note) => !note.system).map((note) => String(note.id));
|
|
10079
9862
|
return {
|
|
10080
9863
|
state: mr.state,
|
|
10081
9864
|
isDraft: mr.draft ?? false,
|
|
10082
9865
|
createdAt: mr.created_at,
|
|
10083
9866
|
mergedAt: mr.merged_at ?? null,
|
|
10084
|
-
linesAdded,
|
|
10085
|
-
commitsCount: commits.length,
|
|
10086
|
-
commitShas: commits.map((c) => c.id),
|
|
10087
|
-
firstCommitDate,
|
|
9867
|
+
linesAdded: 0,
|
|
10088
9868
|
commentIds
|
|
10089
9869
|
};
|
|
10090
9870
|
}
|
|
@@ -10166,7 +9946,8 @@ function parseGitlabOwnerAndRepo(gitlabUrl) {
|
|
|
10166
9946
|
return { owner: organization, repo: repoName, projectPath };
|
|
10167
9947
|
}
|
|
10168
9948
|
var GITLAB_MAX_RESULTS_LIMIT = 1024;
|
|
10169
|
-
var
|
|
9949
|
+
var GITLAB_MAX_PER_PAGE = 100;
|
|
9950
|
+
var GITLAB_PER_PAGE = GITLAB_MAX_PER_PAGE;
|
|
10170
9951
|
async function getGitlabRecentCommits({
|
|
10171
9952
|
repoUrl,
|
|
10172
9953
|
accessToken,
|
|
@@ -10175,14 +9956,17 @@ async function getGitlabRecentCommits({
|
|
|
10175
9956
|
const { projectPath } = parseGitlabOwnerAndRepo(repoUrl);
|
|
10176
9957
|
const api2 = getGitBeaker({ url: repoUrl, gitlabAuthToken: accessToken });
|
|
10177
9958
|
const allCommits = [];
|
|
9959
|
+
const perPage = GITLAB_PER_PAGE;
|
|
10178
9960
|
let page = 1;
|
|
10179
9961
|
let hasMore = true;
|
|
10180
9962
|
while (hasMore && allCommits.length < GITLAB_MAX_RESULTS_LIMIT) {
|
|
10181
|
-
const
|
|
9963
|
+
const response = await api2.Commits.all(projectPath, {
|
|
10182
9964
|
since,
|
|
10183
|
-
perPage
|
|
10184
|
-
page
|
|
9965
|
+
perPage,
|
|
9966
|
+
page,
|
|
9967
|
+
showExpanded: true
|
|
10185
9968
|
});
|
|
9969
|
+
const commits = response.data;
|
|
10186
9970
|
if (commits.length === 0) {
|
|
10187
9971
|
hasMore = false;
|
|
10188
9972
|
break;
|
|
@@ -10204,11 +9988,8 @@ async function getGitlabRecentCommits({
|
|
|
10204
9988
|
parents: commit.parent_ids?.map((sha) => ({ sha })) || []
|
|
10205
9989
|
});
|
|
10206
9990
|
}
|
|
10207
|
-
|
|
10208
|
-
|
|
10209
|
-
} else {
|
|
10210
|
-
page++;
|
|
10211
|
-
}
|
|
9991
|
+
hasMore = response.paginationInfo.next !== null;
|
|
9992
|
+
page++;
|
|
10212
9993
|
}
|
|
10213
9994
|
if (allCommits.length >= GITLAB_MAX_RESULTS_LIMIT) {
|
|
10214
9995
|
contextLogger.warn("[getGitlabRecentCommits] Hit commit pagination limit", {
|
|
@@ -10220,29 +10001,6 @@ async function getGitlabRecentCommits({
|
|
|
10220
10001
|
}
|
|
10221
10002
|
return allCommits;
|
|
10222
10003
|
}
|
|
10223
|
-
async function getGitlabCommitDiff({
|
|
10224
|
-
repoUrl,
|
|
10225
|
-
accessToken,
|
|
10226
|
-
commitSha
|
|
10227
|
-
}) {
|
|
10228
|
-
const { projectPath } = parseGitlabOwnerAndRepo(repoUrl);
|
|
10229
|
-
const api2 = getGitBeaker({ url: repoUrl, gitlabAuthToken: accessToken });
|
|
10230
|
-
const [commit, diffs] = await Promise.all([
|
|
10231
|
-
api2.Commits.show(projectPath, commitSha),
|
|
10232
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10233
|
-
api2.Commits.showDiff(projectPath, commitSha, { unidiff: true })
|
|
10234
|
-
]);
|
|
10235
|
-
const diffString = buildUnifiedDiff(diffs);
|
|
10236
|
-
const commitTimestamp = commit.committed_date ? new Date(commit.committed_date) : /* @__PURE__ */ new Date();
|
|
10237
|
-
return {
|
|
10238
|
-
diff: diffString,
|
|
10239
|
-
commitTimestamp,
|
|
10240
|
-
commitSha: commit.id,
|
|
10241
|
-
authorName: commit.author_name,
|
|
10242
|
-
authorEmail: commit.author_email,
|
|
10243
|
-
message: commit.message
|
|
10244
|
-
};
|
|
10245
|
-
}
|
|
10246
10004
|
async function getGitlabRateLimitStatus({
|
|
10247
10005
|
repoUrl,
|
|
10248
10006
|
accessToken
|
|
@@ -10324,88 +10082,6 @@ async function brokerRequestHandler(endpoint, options) {
|
|
|
10324
10082
|
};
|
|
10325
10083
|
throw new Error(`gitbeaker: ${response.statusText}`);
|
|
10326
10084
|
}
|
|
10327
|
-
async function getGitlabMergeRequestDiff({
|
|
10328
|
-
repoUrl,
|
|
10329
|
-
accessToken,
|
|
10330
|
-
mrNumber
|
|
10331
|
-
}) {
|
|
10332
|
-
debug4("[getGitlabMergeRequestDiff] Starting for MR #%d", mrNumber);
|
|
10333
|
-
const { projectPath } = parseGitlabOwnerAndRepo(repoUrl);
|
|
10334
|
-
const api2 = getGitBeaker({ url: repoUrl, gitlabAuthToken: accessToken });
|
|
10335
|
-
debug4(
|
|
10336
|
-
"[getGitlabMergeRequestDiff] Fetching MR details, diffs, and commits..."
|
|
10337
|
-
);
|
|
10338
|
-
const startMrFetch = Date.now();
|
|
10339
|
-
const [mr, mrDiffs, mrCommitsRaw] = await Promise.all([
|
|
10340
|
-
api2.MergeRequests.show(projectPath, mrNumber),
|
|
10341
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10342
|
-
api2.MergeRequests.allDiffs(projectPath, mrNumber, { unidiff: true }),
|
|
10343
|
-
api2.MergeRequests.allCommits(projectPath, mrNumber)
|
|
10344
|
-
]);
|
|
10345
|
-
debug4(
|
|
10346
|
-
"[getGitlabMergeRequestDiff] MR fetch took %dms. Diffs: %d, Commits: %d",
|
|
10347
|
-
Date.now() - startMrFetch,
|
|
10348
|
-
mrDiffs.length,
|
|
10349
|
-
mrCommitsRaw.length
|
|
10350
|
-
);
|
|
10351
|
-
const diffString = buildUnifiedDiff(mrDiffs);
|
|
10352
|
-
debug4(
|
|
10353
|
-
"[getGitlabMergeRequestDiff] Fetching commit diffs for %d commits...",
|
|
10354
|
-
mrCommitsRaw.length
|
|
10355
|
-
);
|
|
10356
|
-
const startCommitFetch = Date.now();
|
|
10357
|
-
const commitDiffLimit = pLimit2(GITLAB_API_CONCURRENCY);
|
|
10358
|
-
const commits = await Promise.all(
|
|
10359
|
-
mrCommitsRaw.map(
|
|
10360
|
-
(commit) => commitDiffLimit(async () => {
|
|
10361
|
-
const commitDiff = await getGitlabCommitDiff({
|
|
10362
|
-
repoUrl,
|
|
10363
|
-
accessToken,
|
|
10364
|
-
commitSha: commit.id
|
|
10365
|
-
});
|
|
10366
|
-
return {
|
|
10367
|
-
diff: commitDiff.diff,
|
|
10368
|
-
commitTimestamp: commitDiff.commitTimestamp,
|
|
10369
|
-
commitSha: commitDiff.commitSha,
|
|
10370
|
-
authorName: commitDiff.authorName,
|
|
10371
|
-
authorEmail: commitDiff.authorEmail,
|
|
10372
|
-
message: commitDiff.message
|
|
10373
|
-
};
|
|
10374
|
-
})
|
|
10375
|
-
)
|
|
10376
|
-
);
|
|
10377
|
-
commits.sort(
|
|
10378
|
-
(a, b) => new Date(a.commitTimestamp).getTime() - new Date(b.commitTimestamp).getTime()
|
|
10379
|
-
);
|
|
10380
|
-
debug4(
|
|
10381
|
-
"[getGitlabMergeRequestDiff] Commit diffs fetch took %dms",
|
|
10382
|
-
Date.now() - startCommitFetch
|
|
10383
|
-
);
|
|
10384
|
-
const addedLinesByFile = parseAddedLinesByFile(diffString);
|
|
10385
|
-
const diffLines = [];
|
|
10386
|
-
for (const [file, lines] of addedLinesByFile) {
|
|
10387
|
-
for (const line of lines) {
|
|
10388
|
-
diffLines.push({ file, line });
|
|
10389
|
-
}
|
|
10390
|
-
}
|
|
10391
|
-
return {
|
|
10392
|
-
diff: diffString,
|
|
10393
|
-
createdAt: new Date(mr.created_at),
|
|
10394
|
-
updatedAt: new Date(mr.updated_at),
|
|
10395
|
-
submitRequestId: String(mrNumber),
|
|
10396
|
-
submitRequestNumber: mrNumber,
|
|
10397
|
-
sourceBranch: mr.source_branch,
|
|
10398
|
-
targetBranch: mr.target_branch,
|
|
10399
|
-
authorName: mr.author?.name || mr.author?.username,
|
|
10400
|
-
authorEmail: void 0,
|
|
10401
|
-
// GitLab MR API doesn't expose author email directly
|
|
10402
|
-
title: mr.title,
|
|
10403
|
-
description: mr.description || void 0,
|
|
10404
|
-
commits,
|
|
10405
|
-
headCommitSha: mr.sha,
|
|
10406
|
-
diffLines
|
|
10407
|
-
};
|
|
10408
|
-
}
|
|
10409
10085
|
|
|
10410
10086
|
// src/features/analysis/scm/gitlab/GitlabSCMLib.ts
|
|
10411
10087
|
init_client_generates();
|
|
@@ -10438,7 +10114,20 @@ var GitlabSCMLib = class extends SCMLib {
|
|
|
10438
10114
|
contextLogger.warn("[GitlabSCMLib.getRepoList] No access token provided");
|
|
10439
10115
|
throw new Error("no access token");
|
|
10440
10116
|
}
|
|
10441
|
-
|
|
10117
|
+
const allRepos = [];
|
|
10118
|
+
let cursor;
|
|
10119
|
+
let hasMore = true;
|
|
10120
|
+
while (hasMore) {
|
|
10121
|
+
const page = await this.searchRepos({
|
|
10122
|
+
scmOrg: _scmOrg,
|
|
10123
|
+
limit: 100,
|
|
10124
|
+
cursor
|
|
10125
|
+
});
|
|
10126
|
+
allRepos.push(...page.results);
|
|
10127
|
+
hasMore = page.hasMore;
|
|
10128
|
+
cursor = page.nextCursor;
|
|
10129
|
+
}
|
|
10130
|
+
return allRepos;
|
|
10442
10131
|
}
|
|
10443
10132
|
async getBranchList() {
|
|
10444
10133
|
this._validateAccessTokenAndUrl();
|
|
@@ -10570,33 +10259,23 @@ var GitlabSCMLib = class extends SCMLib {
|
|
|
10570
10259
|
this._validateAccessTokenAndUrl();
|
|
10571
10260
|
return `${this.url}/-/commits/${branchName}`;
|
|
10572
10261
|
}
|
|
10573
|
-
async
|
|
10574
|
-
this._validateAccessTokenAndUrl();
|
|
10575
|
-
const result = await getGitlabCommitDiff({
|
|
10576
|
-
repoUrl: this.url,
|
|
10577
|
-
accessToken: this.accessToken,
|
|
10578
|
-
commitSha
|
|
10579
|
-
});
|
|
10580
|
-
return {
|
|
10581
|
-
diff: result.diff,
|
|
10582
|
-
commitTimestamp: result.commitTimestamp,
|
|
10583
|
-
commitSha: result.commitSha,
|
|
10584
|
-
authorName: result.authorName,
|
|
10585
|
-
authorEmail: result.authorEmail,
|
|
10586
|
-
message: result.message
|
|
10587
|
-
};
|
|
10588
|
-
}
|
|
10589
|
-
async getSubmitRequestDiff(submitRequestId) {
|
|
10262
|
+
async getSubmitRequestMetadata(submitRequestId) {
|
|
10590
10263
|
this._validateAccessTokenAndUrl();
|
|
10591
10264
|
const mrNumber = parseInt(submitRequestId, 10);
|
|
10592
10265
|
if (isNaN(mrNumber) || mrNumber <= 0) {
|
|
10593
10266
|
throw new Error(`Invalid merge request ID: ${submitRequestId}`);
|
|
10594
10267
|
}
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
|
|
10268
|
+
const mr = await getGitlabMergeRequest({
|
|
10269
|
+
url: this.url,
|
|
10270
|
+
prNumber: mrNumber,
|
|
10271
|
+
accessToken: this.accessToken
|
|
10599
10272
|
});
|
|
10273
|
+
return {
|
|
10274
|
+
title: mr.title,
|
|
10275
|
+
targetBranch: mr.target_branch,
|
|
10276
|
+
sourceBranch: mr.source_branch,
|
|
10277
|
+
headCommitSha: mr.sha
|
|
10278
|
+
};
|
|
10600
10279
|
}
|
|
10601
10280
|
async searchSubmitRequests(params) {
|
|
10602
10281
|
this._validateAccessTokenAndUrl();
|
|
@@ -10678,8 +10357,47 @@ var GitlabSCMLib = class extends SCMLib {
|
|
|
10678
10357
|
mrNumbers: prNumbers
|
|
10679
10358
|
});
|
|
10680
10359
|
}
|
|
10681
|
-
async searchRepos(
|
|
10682
|
-
|
|
10360
|
+
async searchRepos(params) {
|
|
10361
|
+
if (!this.accessToken) {
|
|
10362
|
+
throw new Error("no access token");
|
|
10363
|
+
}
|
|
10364
|
+
const page = parseCursorSafe(params.cursor, 1);
|
|
10365
|
+
const perPage = params.limit || 10;
|
|
10366
|
+
const { projects, hasMore } = await searchGitlabProjects({
|
|
10367
|
+
url: this.url,
|
|
10368
|
+
accessToken: this.accessToken,
|
|
10369
|
+
perPage,
|
|
10370
|
+
page
|
|
10371
|
+
});
|
|
10372
|
+
const includeLanguages = params.includeLanguages !== false;
|
|
10373
|
+
const languageMap = /* @__PURE__ */ new Map();
|
|
10374
|
+
if (includeLanguages && projects.length > 0) {
|
|
10375
|
+
const languageResults = await Promise.all(
|
|
10376
|
+
projects.map(
|
|
10377
|
+
(p) => getGitlabProjectLanguages({
|
|
10378
|
+
url: this.url,
|
|
10379
|
+
accessToken: this.accessToken,
|
|
10380
|
+
projectId: p.id
|
|
10381
|
+
}).then((langs) => [p.id, langs])
|
|
10382
|
+
)
|
|
10383
|
+
);
|
|
10384
|
+
for (const [id, langs] of languageResults) {
|
|
10385
|
+
languageMap.set(id, langs);
|
|
10386
|
+
}
|
|
10387
|
+
}
|
|
10388
|
+
const results = projects.map((p) => ({
|
|
10389
|
+
repoName: p.path,
|
|
10390
|
+
repoUrl: p.web_url,
|
|
10391
|
+
repoOwner: p.namespace_name,
|
|
10392
|
+
repoLanguages: languageMap.get(p.id) || [],
|
|
10393
|
+
repoIsPublic: p.visibility === "public",
|
|
10394
|
+
repoUpdatedAt: p.last_activity_at
|
|
10395
|
+
}));
|
|
10396
|
+
return {
|
|
10397
|
+
results,
|
|
10398
|
+
nextCursor: hasMore ? String(page + 1) : void 0,
|
|
10399
|
+
hasMore
|
|
10400
|
+
};
|
|
10683
10401
|
}
|
|
10684
10402
|
async getPullRequestMetrics(prNumber) {
|
|
10685
10403
|
this._validateAccessTokenAndUrl();
|
|
@@ -10704,10 +10422,7 @@ var GitlabSCMLib = class extends SCMLib {
|
|
|
10704
10422
|
repositoryUrl: this.url,
|
|
10705
10423
|
prCreatedAt: new Date(metrics.createdAt),
|
|
10706
10424
|
prMergedAt: metrics.mergedAt ? new Date(metrics.mergedAt) : null,
|
|
10707
|
-
firstCommitDate: metrics.firstCommitDate ? new Date(metrics.firstCommitDate) : null,
|
|
10708
10425
|
linesAdded: metrics.linesAdded,
|
|
10709
|
-
commitsCount: metrics.commitsCount,
|
|
10710
|
-
commitShas: metrics.commitShas,
|
|
10711
10426
|
prStatus,
|
|
10712
10427
|
commentIds: metrics.commentIds
|
|
10713
10428
|
};
|
|
@@ -10837,34 +10552,8 @@ var StubSCMLib = class extends SCMLib {
|
|
|
10837
10552
|
async addCommentToSubmitRequest(_submitRequestId, _comment) {
|
|
10838
10553
|
console.warn("addCommentToSubmitRequest() no-op");
|
|
10839
10554
|
}
|
|
10840
|
-
async
|
|
10841
|
-
|
|
10842
|
-
return {
|
|
10843
|
-
diff: "",
|
|
10844
|
-
commitTimestamp: /* @__PURE__ */ new Date(),
|
|
10845
|
-
commitSha: _commitSha,
|
|
10846
|
-
authorName: void 0,
|
|
10847
|
-
authorEmail: void 0,
|
|
10848
|
-
message: void 0
|
|
10849
|
-
};
|
|
10850
|
-
}
|
|
10851
|
-
async getSubmitRequestDiff(_submitRequestId) {
|
|
10852
|
-
console.warn("getSubmitRequestDiff() returning stub diff");
|
|
10853
|
-
return {
|
|
10854
|
-
diff: "",
|
|
10855
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
10856
|
-
updatedAt: /* @__PURE__ */ new Date(),
|
|
10857
|
-
submitRequestId: _submitRequestId,
|
|
10858
|
-
submitRequestNumber: parseInt(_submitRequestId) || 0,
|
|
10859
|
-
sourceBranch: "",
|
|
10860
|
-
targetBranch: "",
|
|
10861
|
-
authorName: void 0,
|
|
10862
|
-
authorEmail: void 0,
|
|
10863
|
-
title: void 0,
|
|
10864
|
-
description: void 0,
|
|
10865
|
-
commits: [],
|
|
10866
|
-
diffLines: []
|
|
10867
|
-
};
|
|
10555
|
+
async getSubmitRequestMetadata(_submitRequestId) {
|
|
10556
|
+
throw new Error("getSubmitRequestMetadata() not implemented");
|
|
10868
10557
|
}
|
|
10869
10558
|
async getPullRequestMetrics(_prNumber) {
|
|
10870
10559
|
console.warn("getPullRequestMetrics() returning empty object");
|
|
@@ -12001,7 +11690,9 @@ function subscribeStream(query, variables, handlers, wsClientOptions) {
|
|
|
12001
11690
|
finalizeError(error);
|
|
12002
11691
|
},
|
|
12003
11692
|
complete: () => {
|
|
12004
|
-
|
|
11693
|
+
finalizeError(
|
|
11694
|
+
new Error("Subscription completed by server before resolving")
|
|
11695
|
+
);
|
|
12005
11696
|
}
|
|
12006
11697
|
}
|
|
12007
11698
|
);
|
|
@@ -12903,7 +12594,7 @@ import Debug10 from "debug";
|
|
|
12903
12594
|
|
|
12904
12595
|
// src/features/analysis/add_fix_comments_for_pr/utils/utils.ts
|
|
12905
12596
|
import Debug9 from "debug";
|
|
12906
|
-
import
|
|
12597
|
+
import parseDiff from "parse-diff";
|
|
12907
12598
|
import { z as z27 } from "zod";
|
|
12908
12599
|
|
|
12909
12600
|
// src/features/analysis/utils/by_key.ts
|
|
@@ -13276,7 +12967,7 @@ Refresh the page in order to see the changes.`,
|
|
|
13276
12967
|
}
|
|
13277
12968
|
async function getRelevantVulenrabilitiesFromDiff(params) {
|
|
13278
12969
|
const { gqlClient, diff, vulnerabilityReportId } = params;
|
|
13279
|
-
const parsedDiff =
|
|
12970
|
+
const parsedDiff = parseDiff(diff);
|
|
13280
12971
|
const fileHunks = parsedDiff.map((file) => {
|
|
13281
12972
|
const fileNumbers = file.chunks.flatMap((chunk) => chunk.changes).filter((change) => change.type === "add").map((_change) => {
|
|
13282
12973
|
const change = _change;
|
|
@@ -21710,7 +21401,7 @@ import {
|
|
|
21710
21401
|
writeFileSync
|
|
21711
21402
|
} from "fs";
|
|
21712
21403
|
import fs22 from "fs/promises";
|
|
21713
|
-
import
|
|
21404
|
+
import parseDiff2 from "parse-diff";
|
|
21714
21405
|
import path21 from "path";
|
|
21715
21406
|
var PatchApplicationService = class {
|
|
21716
21407
|
/**
|
|
@@ -22394,7 +22085,7 @@ var PatchApplicationService = class {
|
|
|
22394
22085
|
fixId,
|
|
22395
22086
|
scanContext
|
|
22396
22087
|
}) {
|
|
22397
|
-
const parsedPatch =
|
|
22088
|
+
const parsedPatch = parseDiff2(patch);
|
|
22398
22089
|
if (!parsedPatch || parsedPatch.length === 0) {
|
|
22399
22090
|
throw new Error("Failed to parse patch - no changes found");
|
|
22400
22091
|
}
|