mobbdev 0.0.140 → 0.0.141
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/index.mjs +812 -869
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -267,13 +267,12 @@ var GetVulByNodesMetadataDocument = `
|
|
|
267
267
|
}
|
|
268
268
|
`;
|
|
269
269
|
var UpdateScmTokenDocument = `
|
|
270
|
-
mutation updateScmToken($scmType: String!, $url: String!, $token: String!, $org: String, $
|
|
270
|
+
mutation updateScmToken($scmType: String!, $url: String!, $token: String!, $org: String, $refreshToken: String) {
|
|
271
271
|
updateScmToken(
|
|
272
272
|
scmType: $scmType
|
|
273
273
|
url: $url
|
|
274
274
|
token: $token
|
|
275
275
|
org: $org
|
|
276
|
-
username: $username
|
|
277
276
|
refreshToken: $refreshToken
|
|
278
277
|
) {
|
|
279
278
|
__typename
|
|
@@ -523,11 +522,11 @@ import chalk4 from "chalk";
|
|
|
523
522
|
import Configstore from "configstore";
|
|
524
523
|
import Debug12 from "debug";
|
|
525
524
|
import extract from "extract-zip";
|
|
526
|
-
import
|
|
525
|
+
import fetch4 from "node-fetch";
|
|
527
526
|
import open2 from "open";
|
|
528
527
|
import semver from "semver";
|
|
529
528
|
import tmp2 from "tmp";
|
|
530
|
-
import { z as
|
|
529
|
+
import { z as z11 } from "zod";
|
|
531
530
|
|
|
532
531
|
// src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
|
|
533
532
|
import Debug4 from "debug";
|
|
@@ -1208,13 +1207,67 @@ var AdoSdk = {
|
|
|
1208
1207
|
// src/features/analysis/scm/bitbucket/bitbucket.ts
|
|
1209
1208
|
import querystring3 from "node:querystring";
|
|
1210
1209
|
import * as bitbucketPkg from "bitbucket";
|
|
1211
|
-
import { z as
|
|
1210
|
+
import { z as z8 } from "zod";
|
|
1212
1211
|
|
|
1213
1212
|
// src/features/analysis/scm/scm.ts
|
|
1214
|
-
import {
|
|
1215
|
-
|
|
1213
|
+
import { z as z7 } from "zod";
|
|
1214
|
+
|
|
1215
|
+
// src/features/analysis/scm/github/github.ts
|
|
1216
|
+
import { RequestError } from "@octokit/request-error";
|
|
1217
|
+
|
|
1218
|
+
// src/features/analysis/scm/github/consts.ts
|
|
1219
|
+
var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1220
|
+
var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1221
|
+
var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1222
|
+
var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1223
|
+
var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1224
|
+
var REPLY_TO_CODE_REVIEW_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies";
|
|
1225
|
+
var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
|
|
1226
|
+
var POST_GENERAL_PR_COMMENT = "POST /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
1227
|
+
var GET_GENERAL_PR_COMMENTS = "GET /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
1228
|
+
var DELETE_GENERAL_PR_COMMENT = "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}";
|
|
1229
|
+
var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
|
|
1230
|
+
var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
|
|
1231
|
+
var GET_USER = "GET /user";
|
|
1232
|
+
var GET_USER_REPOS = "GET /user/repos";
|
|
1233
|
+
var GET_REPO_BRANCHES = "GET /repos/{owner}/{repo}/branches";
|
|
1234
|
+
var GET_BLAME_DOCUMENT = `
|
|
1235
|
+
query GetBlame(
|
|
1236
|
+
$owner: String!
|
|
1237
|
+
$repo: String!
|
|
1238
|
+
$ref: String!
|
|
1239
|
+
$path: String!
|
|
1240
|
+
) {
|
|
1241
|
+
repository(name: $repo, owner: $owner) {
|
|
1242
|
+
# branch name
|
|
1243
|
+
object(expression: $ref) {
|
|
1244
|
+
# cast Target to a Commit
|
|
1245
|
+
... on Commit {
|
|
1246
|
+
# full repo-relative path to blame file
|
|
1247
|
+
blame(path: $path) {
|
|
1248
|
+
ranges {
|
|
1249
|
+
commit {
|
|
1250
|
+
author {
|
|
1251
|
+
user {
|
|
1252
|
+
name
|
|
1253
|
+
login
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
authoredDate
|
|
1257
|
+
}
|
|
1258
|
+
startingLine
|
|
1259
|
+
endingLine
|
|
1260
|
+
age
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
`;
|
|
1216
1269
|
|
|
1217
|
-
// src/features/analysis/scm/github/
|
|
1270
|
+
// src/features/analysis/scm/github/utils/encrypt_secret.ts
|
|
1218
1271
|
import sodium from "libsodium-wrappers";
|
|
1219
1272
|
async function encryptSecret(secret, key) {
|
|
1220
1273
|
await sodium.ready;
|
|
@@ -1224,10 +1277,464 @@ async function encryptSecret(secret, key) {
|
|
|
1224
1277
|
return sodium.to_base64(encBytes, sodium.base64_variants.ORIGINAL);
|
|
1225
1278
|
}
|
|
1226
1279
|
|
|
1227
|
-
// src/features/analysis/scm/github/
|
|
1228
|
-
import { RequestError } from "@octokit/request-error";
|
|
1280
|
+
// src/features/analysis/scm/github/utils/utils.ts
|
|
1229
1281
|
import { Octokit } from "octokit";
|
|
1282
|
+
import { fetch as fetch2, ProxyAgent } from "undici";
|
|
1283
|
+
function parseGithubOwnerAndRepo(gitHubUrl) {
|
|
1284
|
+
gitHubUrl = normalizeUrl(gitHubUrl);
|
|
1285
|
+
const parsingResult = parseScmURL(gitHubUrl, "GitHub" /* GitHub */);
|
|
1286
|
+
if (!parsingResult) {
|
|
1287
|
+
throw new InvalidUrlPatternError(`invalid github repo Url ${gitHubUrl}`);
|
|
1288
|
+
}
|
|
1289
|
+
const { organization, repoName } = parsingResult;
|
|
1290
|
+
if (!organization || !repoName) {
|
|
1291
|
+
throw new InvalidUrlPatternError(`invalid github repo Url ${gitHubUrl}`);
|
|
1292
|
+
}
|
|
1293
|
+
return { owner: organization, repo: repoName };
|
|
1294
|
+
}
|
|
1295
|
+
function isGithubOnPrem(url) {
|
|
1296
|
+
if (!url) {
|
|
1297
|
+
return false;
|
|
1298
|
+
}
|
|
1299
|
+
return !url.includes(scmCloudUrl.GitHub);
|
|
1300
|
+
}
|
|
1301
|
+
function getFetch(url) {
|
|
1302
|
+
if (url && BROKERED_HOSTS.includes(new URL(url).origin)) {
|
|
1303
|
+
const dispatcher = new ProxyAgent({
|
|
1304
|
+
uri: process.env["GIT_PROXY_HOST"] || "http://tinyproxy:8888",
|
|
1305
|
+
requestTls: {
|
|
1306
|
+
rejectUnauthorized: false
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
1309
|
+
return (input, init) => {
|
|
1310
|
+
return fetch2(input, {
|
|
1311
|
+
...init,
|
|
1312
|
+
dispatcher
|
|
1313
|
+
});
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
return fetch2;
|
|
1317
|
+
}
|
|
1318
|
+
function getOktoKit(options) {
|
|
1319
|
+
const token = !options?.auth && !isGithubOnPrem(options?.url) ? GITHUB_API_TOKEN : options?.auth;
|
|
1320
|
+
const baseUrl = options?.url && isGithubOnPrem(options.url) ? `${new URL(options.url).origin}/api/v3` : void 0;
|
|
1321
|
+
return new Octokit({
|
|
1322
|
+
...options,
|
|
1323
|
+
auth: token,
|
|
1324
|
+
baseUrl,
|
|
1325
|
+
request: {
|
|
1326
|
+
fetch: getFetch(baseUrl)
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
function isGithubActionActionToken(token) {
|
|
1331
|
+
return token.startsWith("ghs_");
|
|
1332
|
+
}
|
|
1333
|
+
async function githubValidateParams(url, accessToken) {
|
|
1334
|
+
try {
|
|
1335
|
+
const oktoKit = getOktoKit({ auth: accessToken, url });
|
|
1336
|
+
if (accessToken && !isGithubActionActionToken(accessToken)) {
|
|
1337
|
+
await oktoKit.rest.users.getAuthenticated();
|
|
1338
|
+
}
|
|
1339
|
+
if (url && shouldValidateUrl(url)) {
|
|
1340
|
+
const { owner, repo } = parseGithubOwnerAndRepo(url);
|
|
1341
|
+
await oktoKit.request(GET_REPO_BRANCHES, {
|
|
1342
|
+
owner,
|
|
1343
|
+
repo,
|
|
1344
|
+
per_page: 1
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1347
|
+
} catch (e) {
|
|
1348
|
+
console.log("could not init github scm", e);
|
|
1349
|
+
const error = e;
|
|
1350
|
+
const code = error.status || error.statusCode || error.response?.status || error.response?.statusCode || error.response?.code;
|
|
1351
|
+
if (code === 401 || code === 403) {
|
|
1352
|
+
throw new InvalidAccessTokenError(`invalid github access token`);
|
|
1353
|
+
}
|
|
1354
|
+
if (code === 404) {
|
|
1355
|
+
throw new InvalidRepoUrlError(`invalid github repo Url ${url}`);
|
|
1356
|
+
}
|
|
1357
|
+
throw e;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
// src/features/analysis/scm/github/github.ts
|
|
1362
|
+
function getGithubSdk(parmas = {}) {
|
|
1363
|
+
const octokit = getOktoKit(parmas);
|
|
1364
|
+
return {
|
|
1365
|
+
async postPrComment(params) {
|
|
1366
|
+
return octokit.request(POST_COMMENT_PATH, params);
|
|
1367
|
+
},
|
|
1368
|
+
async updatePrComment(params) {
|
|
1369
|
+
return octokit.request(UPDATE_COMMENT_PATH, params);
|
|
1370
|
+
},
|
|
1371
|
+
async getPrComments(params) {
|
|
1372
|
+
return octokit.request(GET_PR_COMMENTS_PATH, params);
|
|
1373
|
+
},
|
|
1374
|
+
async getPrComment(params) {
|
|
1375
|
+
return octokit.request(GET_PR_COMMENT_PATH, params);
|
|
1376
|
+
},
|
|
1377
|
+
async deleteComment(params) {
|
|
1378
|
+
return octokit.request(DELETE_COMMENT_PATH, params);
|
|
1379
|
+
},
|
|
1380
|
+
async replyToCodeReviewComment(params) {
|
|
1381
|
+
return octokit.request(REPLY_TO_CODE_REVIEW_COMMENT_PATH, params);
|
|
1382
|
+
},
|
|
1383
|
+
async getPrDiff(params) {
|
|
1384
|
+
return octokit.request(GET_PR, {
|
|
1385
|
+
...params,
|
|
1386
|
+
mediaType: { format: "diff" }
|
|
1387
|
+
});
|
|
1388
|
+
},
|
|
1389
|
+
async getPr(params) {
|
|
1390
|
+
return octokit.request(GET_PR, { ...params });
|
|
1391
|
+
},
|
|
1392
|
+
async createOrUpdateRepositorySecret(params) {
|
|
1393
|
+
return octokit.request(CREATE_OR_UPDATE_A_REPOSITORY_SECRET, params);
|
|
1394
|
+
},
|
|
1395
|
+
async getRepositoryPublicKey(params) {
|
|
1396
|
+
return octokit.request(GET_A_REPOSITORY_PUBLIC_KEY, params);
|
|
1397
|
+
},
|
|
1398
|
+
async postGeneralPrComment(params) {
|
|
1399
|
+
return octokit.request(POST_GENERAL_PR_COMMENT, params);
|
|
1400
|
+
},
|
|
1401
|
+
async getGeneralPrComments(params) {
|
|
1402
|
+
return octokit.request(GET_GENERAL_PR_COMMENTS, params);
|
|
1403
|
+
},
|
|
1404
|
+
async deleteGeneralPrComment(params) {
|
|
1405
|
+
return octokit.request(DELETE_GENERAL_PR_COMMENT, params);
|
|
1406
|
+
},
|
|
1407
|
+
async getGithubUsername() {
|
|
1408
|
+
const res = await octokit.rest.users.getAuthenticated();
|
|
1409
|
+
return res.data.login;
|
|
1410
|
+
},
|
|
1411
|
+
async getGithubIsUserCollaborator(params) {
|
|
1412
|
+
const { username, repoUrl } = params;
|
|
1413
|
+
try {
|
|
1414
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1415
|
+
const res = await octokit.rest.repos.checkCollaborator({
|
|
1416
|
+
owner,
|
|
1417
|
+
repo,
|
|
1418
|
+
username
|
|
1419
|
+
});
|
|
1420
|
+
if (res.status === 204) {
|
|
1421
|
+
return true;
|
|
1422
|
+
}
|
|
1423
|
+
} catch (e) {
|
|
1424
|
+
return false;
|
|
1425
|
+
}
|
|
1426
|
+
return false;
|
|
1427
|
+
},
|
|
1428
|
+
async getGithubPullRequestStatus(params) {
|
|
1429
|
+
const { repoUrl, prNumber } = params;
|
|
1430
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1431
|
+
const res = await octokit.rest.pulls.get({
|
|
1432
|
+
owner,
|
|
1433
|
+
repo,
|
|
1434
|
+
pull_number: prNumber
|
|
1435
|
+
});
|
|
1436
|
+
if (res.data.merged) {
|
|
1437
|
+
return "merged";
|
|
1438
|
+
}
|
|
1439
|
+
if (res.data.draft) {
|
|
1440
|
+
return "draft";
|
|
1441
|
+
}
|
|
1442
|
+
return res.data.state;
|
|
1443
|
+
},
|
|
1444
|
+
async getGithubIsRemoteBranch(params) {
|
|
1445
|
+
const { repoUrl, branch } = params;
|
|
1446
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1447
|
+
try {
|
|
1448
|
+
const res = await octokit.rest.repos.getBranch({
|
|
1449
|
+
owner,
|
|
1450
|
+
repo,
|
|
1451
|
+
branch
|
|
1452
|
+
});
|
|
1453
|
+
return branch === res.data.name;
|
|
1454
|
+
} catch (e) {
|
|
1455
|
+
return false;
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
async getGithubRepoList() {
|
|
1459
|
+
try {
|
|
1460
|
+
const githubRepos = await octokit.request(GET_USER_REPOS, {
|
|
1461
|
+
sort: "updated"
|
|
1462
|
+
});
|
|
1463
|
+
return githubRepos.data.map((repo) => ({
|
|
1464
|
+
repoName: repo.name,
|
|
1465
|
+
repoUrl: repo.html_url,
|
|
1466
|
+
repoOwner: repo.owner.login,
|
|
1467
|
+
repoLanguages: repo.language ? [repo.language] : [],
|
|
1468
|
+
repoIsPublic: !repo.private,
|
|
1469
|
+
repoUpdatedAt: repo.updated_at
|
|
1470
|
+
}));
|
|
1471
|
+
} catch (e) {
|
|
1472
|
+
if (e instanceof RequestError && e.status === 401) {
|
|
1473
|
+
return [];
|
|
1474
|
+
}
|
|
1475
|
+
if (e instanceof RequestError && e.status === 404) {
|
|
1476
|
+
return [];
|
|
1477
|
+
}
|
|
1478
|
+
throw e;
|
|
1479
|
+
}
|
|
1480
|
+
},
|
|
1481
|
+
async getGithubRepoDefaultBranch(repoUrl) {
|
|
1482
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1483
|
+
const repos = await octokit.rest.repos.get({ repo, owner });
|
|
1484
|
+
return repos.data.default_branch;
|
|
1485
|
+
},
|
|
1486
|
+
async getGithubReferenceData({
|
|
1487
|
+
ref,
|
|
1488
|
+
gitHubUrl
|
|
1489
|
+
}) {
|
|
1490
|
+
const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
|
|
1491
|
+
let res;
|
|
1492
|
+
try {
|
|
1493
|
+
res = await Promise.any([
|
|
1494
|
+
this.getBranch({ owner, repo, branch: ref }).then((result) => ({
|
|
1495
|
+
date: result.data.commit.commit.committer?.date ? new Date(result.data.commit.commit.committer?.date) : void 0,
|
|
1496
|
+
type: "BRANCH" /* BRANCH */,
|
|
1497
|
+
sha: result.data.commit.sha
|
|
1498
|
+
})),
|
|
1499
|
+
this.getCommit({ commitSha: ref, repo, owner }).then((commit) => ({
|
|
1500
|
+
date: new Date(commit.data.committer.date),
|
|
1501
|
+
type: "COMMIT" /* COMMIT */,
|
|
1502
|
+
sha: commit.data.sha
|
|
1503
|
+
})),
|
|
1504
|
+
this.getTagDate({ owner, repo, tag: ref }).then((data) => ({
|
|
1505
|
+
date: new Date(data.date),
|
|
1506
|
+
type: "TAG" /* TAG */,
|
|
1507
|
+
sha: data.sha
|
|
1508
|
+
}))
|
|
1509
|
+
]);
|
|
1510
|
+
return res;
|
|
1511
|
+
} catch (e) {
|
|
1512
|
+
if (e instanceof AggregateError) {
|
|
1513
|
+
throw new RefNotFoundError(`ref: ${ref} does not exist`);
|
|
1514
|
+
}
|
|
1515
|
+
throw e;
|
|
1516
|
+
}
|
|
1517
|
+
},
|
|
1518
|
+
async getBranch({
|
|
1519
|
+
branch,
|
|
1520
|
+
owner,
|
|
1521
|
+
repo
|
|
1522
|
+
}) {
|
|
1523
|
+
return octokit.rest.repos.getBranch({
|
|
1524
|
+
branch,
|
|
1525
|
+
owner,
|
|
1526
|
+
repo
|
|
1527
|
+
});
|
|
1528
|
+
},
|
|
1529
|
+
async getCommit({
|
|
1530
|
+
commitSha,
|
|
1531
|
+
owner,
|
|
1532
|
+
repo
|
|
1533
|
+
}) {
|
|
1534
|
+
return octokit.rest.git.getCommit({
|
|
1535
|
+
repo,
|
|
1536
|
+
owner,
|
|
1537
|
+
commit_sha: commitSha
|
|
1538
|
+
});
|
|
1539
|
+
},
|
|
1540
|
+
async getTagDate({
|
|
1541
|
+
tag,
|
|
1542
|
+
owner,
|
|
1543
|
+
repo
|
|
1544
|
+
}) {
|
|
1545
|
+
const refResponse = await octokit.rest.git.getRef({
|
|
1546
|
+
ref: `tags/${tag}`,
|
|
1547
|
+
owner,
|
|
1548
|
+
repo
|
|
1549
|
+
});
|
|
1550
|
+
const tagSha = refResponse.data.object.sha;
|
|
1551
|
+
if (refResponse.data.object.type === "commit") {
|
|
1552
|
+
const res2 = await octokit.rest.git.getCommit({
|
|
1553
|
+
commit_sha: tagSha,
|
|
1554
|
+
owner,
|
|
1555
|
+
repo
|
|
1556
|
+
});
|
|
1557
|
+
return {
|
|
1558
|
+
date: res2.data.committer.date,
|
|
1559
|
+
sha: res2.data.sha
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1562
|
+
const res = await octokit.rest.git.getTag({
|
|
1563
|
+
tag_sha: tagSha,
|
|
1564
|
+
owner,
|
|
1565
|
+
repo
|
|
1566
|
+
});
|
|
1567
|
+
return {
|
|
1568
|
+
date: res.data.tagger.date,
|
|
1569
|
+
sha: res.data.sha
|
|
1570
|
+
};
|
|
1571
|
+
},
|
|
1572
|
+
async getGithubBlameRanges(params) {
|
|
1573
|
+
const { ref, gitHubUrl, path: path9 } = params;
|
|
1574
|
+
const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
|
|
1575
|
+
const res = await octokit.graphql(
|
|
1576
|
+
GET_BLAME_DOCUMENT,
|
|
1577
|
+
{
|
|
1578
|
+
owner,
|
|
1579
|
+
repo,
|
|
1580
|
+
path: path9,
|
|
1581
|
+
ref
|
|
1582
|
+
}
|
|
1583
|
+
);
|
|
1584
|
+
if (!res?.repository?.object?.blame?.ranges) {
|
|
1585
|
+
return [];
|
|
1586
|
+
}
|
|
1587
|
+
return res.repository.object.blame.ranges.map((range) => ({
|
|
1588
|
+
startingLine: range.startingLine,
|
|
1589
|
+
endingLine: range.endingLine,
|
|
1590
|
+
email: range.commit.author.user?.email || "",
|
|
1591
|
+
name: range.commit.author.user?.name || "",
|
|
1592
|
+
login: range.commit.author.user?.login || ""
|
|
1593
|
+
}));
|
|
1594
|
+
},
|
|
1595
|
+
// todo: refactor the name for this function
|
|
1596
|
+
async createPr(params) {
|
|
1597
|
+
const { sourceRepoUrl, filesPaths, userRepoUrl, title, body } = params;
|
|
1598
|
+
const { owner: sourceOwner, repo: sourceRepo } = parseGithubOwnerAndRepo(sourceRepoUrl);
|
|
1599
|
+
const { owner, repo } = parseGithubOwnerAndRepo(userRepoUrl);
|
|
1600
|
+
const [sourceFilePath, secondFilePath] = filesPaths;
|
|
1601
|
+
const sourceFileContentResponse = await octokit.rest.repos.getContent({
|
|
1602
|
+
owner: sourceOwner,
|
|
1603
|
+
repo: sourceRepo,
|
|
1604
|
+
path: "/" + sourceFilePath
|
|
1605
|
+
});
|
|
1606
|
+
const { data: repository } = await octokit.rest.repos.get({ owner, repo });
|
|
1607
|
+
const defaultBranch = repository.default_branch;
|
|
1608
|
+
const newBranchName = `mobb/workflow-${Date.now()}`;
|
|
1609
|
+
await octokit.rest.git.createRef({
|
|
1610
|
+
owner,
|
|
1611
|
+
repo,
|
|
1612
|
+
ref: `refs/heads/${newBranchName}`,
|
|
1613
|
+
sha: await octokit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha)
|
|
1614
|
+
});
|
|
1615
|
+
const decodedContent = Buffer.from(
|
|
1616
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1617
|
+
// @ts-ignore
|
|
1618
|
+
sourceFileContentResponse.data.content,
|
|
1619
|
+
"base64"
|
|
1620
|
+
).toString("utf-8");
|
|
1621
|
+
const tree = [
|
|
1622
|
+
{
|
|
1623
|
+
path: sourceFilePath,
|
|
1624
|
+
mode: "100644",
|
|
1625
|
+
type: "blob",
|
|
1626
|
+
content: decodedContent
|
|
1627
|
+
}
|
|
1628
|
+
];
|
|
1629
|
+
if (secondFilePath) {
|
|
1630
|
+
const secondFileContentResponse = await octokit.rest.repos.getContent({
|
|
1631
|
+
owner: sourceOwner,
|
|
1632
|
+
repo: sourceRepo,
|
|
1633
|
+
path: "/" + secondFilePath
|
|
1634
|
+
});
|
|
1635
|
+
const secondDecodedContent = Buffer.from(
|
|
1636
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1637
|
+
// @ts-ignore
|
|
1638
|
+
secondFileContentResponse.data.content,
|
|
1639
|
+
"base64"
|
|
1640
|
+
).toString("utf-8");
|
|
1641
|
+
tree.push({
|
|
1642
|
+
path: secondFilePath,
|
|
1643
|
+
mode: "100644",
|
|
1644
|
+
type: "blob",
|
|
1645
|
+
content: secondDecodedContent
|
|
1646
|
+
});
|
|
1647
|
+
}
|
|
1648
|
+
const createTreeResponse = await octokit.rest.git.createTree({
|
|
1649
|
+
owner,
|
|
1650
|
+
repo,
|
|
1651
|
+
base_tree: await octokit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha),
|
|
1652
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1653
|
+
// @ts-ignore
|
|
1654
|
+
tree
|
|
1655
|
+
});
|
|
1656
|
+
const createCommitResponse = await octokit.rest.git.createCommit({
|
|
1657
|
+
owner,
|
|
1658
|
+
repo,
|
|
1659
|
+
message: "Add new yaml file",
|
|
1660
|
+
tree: createTreeResponse.data.sha,
|
|
1661
|
+
parents: [
|
|
1662
|
+
await octokit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha)
|
|
1663
|
+
]
|
|
1664
|
+
});
|
|
1665
|
+
await octokit.rest.git.updateRef({
|
|
1666
|
+
owner,
|
|
1667
|
+
repo,
|
|
1668
|
+
ref: `heads/${newBranchName}`,
|
|
1669
|
+
sha: createCommitResponse.data.sha
|
|
1670
|
+
});
|
|
1671
|
+
const createPRResponse = await octokit.rest.pulls.create({
|
|
1672
|
+
owner,
|
|
1673
|
+
repo,
|
|
1674
|
+
title,
|
|
1675
|
+
head: newBranchName,
|
|
1676
|
+
head_repo: sourceRepo,
|
|
1677
|
+
body,
|
|
1678
|
+
base: defaultBranch
|
|
1679
|
+
});
|
|
1680
|
+
return {
|
|
1681
|
+
pull_request_url: createPRResponse.data.html_url
|
|
1682
|
+
};
|
|
1683
|
+
},
|
|
1684
|
+
async getGithubBranchList(repoUrl) {
|
|
1685
|
+
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1686
|
+
return octokit.rest.repos.listBranches({
|
|
1687
|
+
owner,
|
|
1688
|
+
repo,
|
|
1689
|
+
per_page: 1e3,
|
|
1690
|
+
page: 1
|
|
1691
|
+
});
|
|
1692
|
+
},
|
|
1693
|
+
async createPullRequest(options) {
|
|
1694
|
+
const { owner, repo } = parseGithubOwnerAndRepo(options.repoUrl);
|
|
1695
|
+
return octokit.rest.pulls.create({
|
|
1696
|
+
owner,
|
|
1697
|
+
repo,
|
|
1698
|
+
title: options.title,
|
|
1699
|
+
body: options.body,
|
|
1700
|
+
head: options.sourceBranchName,
|
|
1701
|
+
base: options.targetBranchName,
|
|
1702
|
+
draft: false,
|
|
1703
|
+
maintainer_can_modify: true
|
|
1704
|
+
});
|
|
1705
|
+
},
|
|
1706
|
+
async forkRepo(options) {
|
|
1707
|
+
const { owner, repo } = parseGithubOwnerAndRepo(options.repoUrl);
|
|
1708
|
+
const createForkRes = await octokit.rest.repos.createFork({
|
|
1709
|
+
owner,
|
|
1710
|
+
repo,
|
|
1711
|
+
default_branch_only: false
|
|
1712
|
+
});
|
|
1713
|
+
return { url: createForkRes.data.html_url };
|
|
1714
|
+
},
|
|
1715
|
+
async getUserInfo() {
|
|
1716
|
+
return octokit.request(GET_USER);
|
|
1717
|
+
}
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
1722
|
+
import querystring2 from "node:querystring";
|
|
1723
|
+
import {
|
|
1724
|
+
Gitlab
|
|
1725
|
+
} from "@gitbeaker/rest";
|
|
1726
|
+
import { ProxyAgent as ProxyAgent2 } from "undici";
|
|
1727
|
+
|
|
1728
|
+
// src/features/analysis/scm/env.ts
|
|
1230
1729
|
import { z as z3 } from "zod";
|
|
1730
|
+
var EnvVariablesZod = z3.object({
|
|
1731
|
+
GITLAB_API_TOKEN: z3.string().optional(),
|
|
1732
|
+
BROKERED_HOSTS: z3.string().toLowerCase().transform(
|
|
1733
|
+
(x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
|
|
1734
|
+
).default(""),
|
|
1735
|
+
GITHUB_API_TOKEN: z3.string().optional()
|
|
1736
|
+
});
|
|
1737
|
+
var { GITLAB_API_TOKEN, BROKERED_HOSTS, GITHUB_API_TOKEN } = EnvVariablesZod.parse(process.env);
|
|
1231
1738
|
|
|
1232
1739
|
// src/features/analysis/scm/utils/get_issue_type.ts
|
|
1233
1740
|
var getIssueType = (issueType) => {
|
|
@@ -1338,594 +1845,106 @@ var getIssueType = (issueType) => {
|
|
|
1338
1845
|
return "WCF Misconfiguration: Insufficient Logging";
|
|
1339
1846
|
case "WCF_MISCONFIGURATION_THROTTLING_NOT_ENABLED" /* WcfMisconfigurationThrottlingNotEnabled */:
|
|
1340
1847
|
return "WCF Misconfiguration: Throttling Not Enabled";
|
|
1341
|
-
case "USELESS_REGEXP_CHAR_ESCAPE" /* UselessRegexpCharEscape */:
|
|
1342
|
-
return "Useless regular-expression character escape";
|
|
1343
|
-
case "INCOMPLETE_HOSTNAME_REGEX" /* IncompleteHostnameRegex */:
|
|
1344
|
-
return "Incomplete Hostname Regex";
|
|
1345
|
-
case "OVERLY_LARGE_RANGE" /* OverlyLargeRange */:
|
|
1346
|
-
return "Regex: Overly Large Range";
|
|
1347
|
-
case "INSUFFICIENT_LOGGING" /* InsufficientLogging */:
|
|
1348
|
-
return "Insufficient Logging of Sensitive Operations";
|
|
1349
|
-
case "PRIVACY_VIOLATION" /* PrivacyViolation */:
|
|
1350
|
-
return "Privacy Violation";
|
|
1351
|
-
case "INCOMPLETE_URL_SCHEME_CHECK" /* IncompleteUrlSchemeCheck */:
|
|
1352
|
-
return "Incomplete URL Scheme Check";
|
|
1353
|
-
case "VALUE_NEVER_READ" /* ValueNeverRead */:
|
|
1354
|
-
return "Value Never Read";
|
|
1355
|
-
case "VALUE_SHADOWING" /* ValueShadowing */:
|
|
1356
|
-
return "Value Shadowing";
|
|
1357
|
-
default: {
|
|
1358
|
-
return issueType ? issueType.replaceAll("_", " ") : "Other";
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
};
|
|
1362
|
-
|
|
1363
|
-
// src/features/analysis/scm/utils/index.ts
|
|
1364
|
-
function getFixUrlWithRedirect(params) {
|
|
1365
|
-
const {
|
|
1366
|
-
fixId,
|
|
1367
|
-
projectId,
|
|
1368
|
-
organizationId,
|
|
1369
|
-
analysisId,
|
|
1370
|
-
redirectUrl,
|
|
1371
|
-
appBaseUrl,
|
|
1372
|
-
commentId
|
|
1373
|
-
} = params;
|
|
1374
|
-
const searchParams = new URLSearchParams();
|
|
1375
|
-
searchParams.append("commit_redirect_url", redirectUrl);
|
|
1376
|
-
searchParams.append("comment_id", commentId.toString());
|
|
1377
|
-
return `${getFixUrl({
|
|
1378
|
-
appBaseUrl,
|
|
1379
|
-
fixId,
|
|
1380
|
-
projectId,
|
|
1381
|
-
organizationId,
|
|
1382
|
-
analysisId
|
|
1383
|
-
})}?${searchParams.toString()}`;
|
|
1384
|
-
}
|
|
1385
|
-
function getFixUrl({
|
|
1386
|
-
appBaseUrl,
|
|
1387
|
-
fixId,
|
|
1388
|
-
projectId,
|
|
1389
|
-
organizationId,
|
|
1390
|
-
analysisId
|
|
1391
|
-
}) {
|
|
1392
|
-
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
1393
|
-
}
|
|
1394
|
-
function getCommitUrl(params) {
|
|
1395
|
-
const {
|
|
1396
|
-
fixId,
|
|
1397
|
-
projectId,
|
|
1398
|
-
organizationId,
|
|
1399
|
-
analysisId,
|
|
1400
|
-
redirectUrl,
|
|
1401
|
-
appBaseUrl,
|
|
1402
|
-
commentId
|
|
1403
|
-
} = params;
|
|
1404
|
-
const searchParams = new URLSearchParams();
|
|
1405
|
-
searchParams.append("redirect_url", redirectUrl);
|
|
1406
|
-
searchParams.append("comment_id", commentId.toString());
|
|
1407
|
-
return `${getFixUrl({
|
|
1408
|
-
appBaseUrl,
|
|
1409
|
-
fixId,
|
|
1410
|
-
projectId,
|
|
1411
|
-
organizationId,
|
|
1412
|
-
analysisId
|
|
1413
|
-
})}/commit?${searchParams.toString()}`;
|
|
1414
|
-
}
|
|
1415
|
-
var userNamePattern = /^(https?:\/\/)([^@]+@)?([^/]+\/.+)$/;
|
|
1416
|
-
var sshPattern = /^git@([\w.-]+):([\w./-]+)$/;
|
|
1417
|
-
function normalizeUrl(repoUrl) {
|
|
1418
|
-
let trimmedUrl = repoUrl.trim().replace(/\/+$/, "");
|
|
1419
|
-
if (repoUrl.endsWith(".git")) {
|
|
1420
|
-
trimmedUrl = trimmedUrl.slice(0, -".git".length);
|
|
1421
|
-
}
|
|
1422
|
-
const usernameMatch = trimmedUrl.match(userNamePattern);
|
|
1423
|
-
if (usernameMatch) {
|
|
1424
|
-
const [_all, protocol, _username, repoPath] = usernameMatch;
|
|
1425
|
-
trimmedUrl = `${protocol}${repoPath}`;
|
|
1426
|
-
}
|
|
1427
|
-
const sshMatch = trimmedUrl.match(sshPattern);
|
|
1428
|
-
if (sshMatch) {
|
|
1429
|
-
const [_all, hostname, reporPath] = sshMatch;
|
|
1430
|
-
trimmedUrl = `https://${hostname}/${reporPath}`;
|
|
1431
|
-
}
|
|
1432
|
-
return trimmedUrl;
|
|
1433
|
-
}
|
|
1434
|
-
|
|
1435
|
-
// src/features/analysis/scm/github/github.ts
|
|
1436
|
-
var EnvVariablesZod = z3.object({
|
|
1437
|
-
GITHUB_API_TOKEN: z3.string().optional()
|
|
1438
|
-
});
|
|
1439
|
-
var { GITHUB_API_TOKEN } = EnvVariablesZod.parse(process.env);
|
|
1440
|
-
var GetBlameDocument = `
|
|
1441
|
-
query GetBlame(
|
|
1442
|
-
$owner: String!
|
|
1443
|
-
$repo: String!
|
|
1444
|
-
$ref: String!
|
|
1445
|
-
$path: String!
|
|
1446
|
-
) {
|
|
1447
|
-
repository(name: $repo, owner: $owner) {
|
|
1448
|
-
# branch name
|
|
1449
|
-
object(expression: $ref) {
|
|
1450
|
-
# cast Target to a Commit
|
|
1451
|
-
... on Commit {
|
|
1452
|
-
# full repo-relative path to blame file
|
|
1453
|
-
blame(path: $path) {
|
|
1454
|
-
ranges {
|
|
1455
|
-
commit {
|
|
1456
|
-
author {
|
|
1457
|
-
user {
|
|
1458
|
-
name
|
|
1459
|
-
login
|
|
1460
|
-
}
|
|
1461
|
-
}
|
|
1462
|
-
authoredDate
|
|
1463
|
-
}
|
|
1464
|
-
startingLine
|
|
1465
|
-
endingLine
|
|
1466
|
-
age
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
`;
|
|
1475
|
-
function getOktoKit(options) {
|
|
1476
|
-
const token = options?.githubAuthToken ?? GITHUB_API_TOKEN ?? "";
|
|
1477
|
-
return new Octokit({ auth: token });
|
|
1478
|
-
}
|
|
1479
|
-
function isGithbActionActionToken(token) {
|
|
1480
|
-
return token.startsWith("ghs_");
|
|
1481
|
-
}
|
|
1482
|
-
async function githubValidateParams(url, accessToken) {
|
|
1483
|
-
try {
|
|
1484
|
-
const oktoKit = getOktoKit({ githubAuthToken: accessToken });
|
|
1485
|
-
if (accessToken) {
|
|
1486
|
-
isGithbActionActionToken(accessToken) ? null : await oktoKit.rest.users.getAuthenticated();
|
|
1487
|
-
}
|
|
1488
|
-
if (url) {
|
|
1489
|
-
const { owner, repo } = parseGithubOwnerAndRepo(url);
|
|
1490
|
-
await oktoKit.request("GET /repos/{owner}/{repo}/branches", {
|
|
1491
|
-
owner,
|
|
1492
|
-
repo,
|
|
1493
|
-
per_page: 1
|
|
1494
|
-
});
|
|
1495
|
-
}
|
|
1496
|
-
} catch (e) {
|
|
1497
|
-
console.log("could not init github scm", e);
|
|
1498
|
-
const error = e;
|
|
1499
|
-
const code = error.status || error.statusCode || error.response?.status || error.response?.statusCode || error.response?.code;
|
|
1500
|
-
if (code === 401 || code === 403) {
|
|
1501
|
-
throw new InvalidAccessTokenError(`invalid github access token`);
|
|
1502
|
-
}
|
|
1503
|
-
if (code === 404) {
|
|
1504
|
-
throw new InvalidRepoUrlError(`invalid github repo Url ${url}`);
|
|
1505
|
-
}
|
|
1506
|
-
throw e;
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
async function getGithubUsername(accessToken) {
|
|
1510
|
-
const oktoKit = getOktoKit({ githubAuthToken: accessToken });
|
|
1511
|
-
const res = await oktoKit.rest.users.getAuthenticated();
|
|
1512
|
-
return res.data.login;
|
|
1513
|
-
}
|
|
1514
|
-
async function getGithubIsUserCollaborator(username, accessToken, repoUrl) {
|
|
1515
|
-
try {
|
|
1516
|
-
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1517
|
-
const oktoKit = getOktoKit({ githubAuthToken: accessToken });
|
|
1518
|
-
const res = await oktoKit.rest.repos.checkCollaborator({
|
|
1519
|
-
owner,
|
|
1520
|
-
repo,
|
|
1521
|
-
username
|
|
1522
|
-
});
|
|
1523
|
-
if (res.status === 204) {
|
|
1524
|
-
return true;
|
|
1525
|
-
}
|
|
1526
|
-
} catch (e) {
|
|
1527
|
-
return false;
|
|
1528
|
-
}
|
|
1529
|
-
return false;
|
|
1530
|
-
}
|
|
1531
|
-
async function getGithubPullRequestStatus(accessToken, repoUrl, prNumber) {
|
|
1532
|
-
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1533
|
-
const oktoKit = getOktoKit({ githubAuthToken: accessToken });
|
|
1534
|
-
const res = await oktoKit.rest.pulls.get({
|
|
1535
|
-
owner,
|
|
1536
|
-
repo,
|
|
1537
|
-
pull_number: prNumber
|
|
1538
|
-
});
|
|
1539
|
-
if (res.data.merged) {
|
|
1540
|
-
return "merged";
|
|
1541
|
-
}
|
|
1542
|
-
if (res.data.draft) {
|
|
1543
|
-
return "draft";
|
|
1544
|
-
}
|
|
1545
|
-
return res.data.state;
|
|
1546
|
-
}
|
|
1547
|
-
async function getGithubIsRemoteBranch(accessToken, repoUrl, branch) {
|
|
1548
|
-
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1549
|
-
const oktoKit = getOktoKit({ githubAuthToken: accessToken });
|
|
1550
|
-
try {
|
|
1551
|
-
const res = await oktoKit.rest.repos.getBranch({
|
|
1552
|
-
owner,
|
|
1553
|
-
repo,
|
|
1554
|
-
branch
|
|
1555
|
-
});
|
|
1556
|
-
return branch === res.data.name;
|
|
1557
|
-
} catch (e) {
|
|
1558
|
-
return false;
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
async function getGithubRepoList(accessToken) {
|
|
1562
|
-
const oktoKit = getOktoKit({ githubAuthToken: accessToken });
|
|
1563
|
-
try {
|
|
1564
|
-
const githubRepos = await getRepos(oktoKit);
|
|
1565
|
-
return githubRepos.map(
|
|
1566
|
-
(repo) => {
|
|
1567
|
-
const repoLanguages = [];
|
|
1568
|
-
if (repo.language) {
|
|
1569
|
-
repoLanguages.push(repo.language);
|
|
1570
|
-
}
|
|
1571
|
-
return {
|
|
1572
|
-
repoName: repo.name,
|
|
1573
|
-
repoUrl: repo.html_url,
|
|
1574
|
-
repoOwner: repo.owner.login,
|
|
1575
|
-
repoLanguages,
|
|
1576
|
-
repoIsPublic: !repo.private,
|
|
1577
|
-
repoUpdatedAt: repo.updated_at
|
|
1578
|
-
};
|
|
1579
|
-
}
|
|
1580
|
-
);
|
|
1581
|
-
} catch (e) {
|
|
1582
|
-
if (e instanceof RequestError && e.status === 401) {
|
|
1583
|
-
return [];
|
|
1584
|
-
}
|
|
1585
|
-
if (e instanceof RequestError && e.status === 404) {
|
|
1586
|
-
return [];
|
|
1587
|
-
}
|
|
1588
|
-
throw e;
|
|
1589
|
-
}
|
|
1590
|
-
}
|
|
1591
|
-
async function getGithubBranchList(accessToken, repoUrl) {
|
|
1592
|
-
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1593
|
-
const oktoKit = getOktoKit({ githubAuthToken: accessToken });
|
|
1594
|
-
const res = await oktoKit.rest.repos.listBranches({
|
|
1595
|
-
owner,
|
|
1596
|
-
repo,
|
|
1597
|
-
per_page: 1e3,
|
|
1598
|
-
page: 1
|
|
1599
|
-
});
|
|
1600
|
-
return res.data.map((branch) => branch.name);
|
|
1601
|
-
}
|
|
1602
|
-
async function createPullRequest(options) {
|
|
1603
|
-
const { owner, repo } = parseGithubOwnerAndRepo(options.repoUrl);
|
|
1604
|
-
const oktoKit = getOktoKit({ githubAuthToken: options.accessToken });
|
|
1605
|
-
const res = await oktoKit.rest.pulls.create({
|
|
1606
|
-
owner,
|
|
1607
|
-
repo,
|
|
1608
|
-
title: options.title,
|
|
1609
|
-
body: options.body,
|
|
1610
|
-
head: options.sourceBranchName,
|
|
1611
|
-
base: options.targetBranchName,
|
|
1612
|
-
draft: false,
|
|
1613
|
-
maintainer_can_modify: true
|
|
1614
|
-
});
|
|
1615
|
-
return res.data.number;
|
|
1616
|
-
}
|
|
1617
|
-
async function forkRepo(options) {
|
|
1618
|
-
const { owner, repo } = parseGithubOwnerAndRepo(options.repoUrl);
|
|
1619
|
-
const oktoKit = getOktoKit({ githubAuthToken: options.accessToken });
|
|
1620
|
-
const res = await oktoKit.rest.repos.createFork({
|
|
1621
|
-
owner,
|
|
1622
|
-
repo,
|
|
1623
|
-
default_branch_only: false
|
|
1624
|
-
});
|
|
1625
|
-
return { url: res.data.html_url ? String(res.data.html_url) : null };
|
|
1626
|
-
}
|
|
1627
|
-
async function getRepos(oktoKit) {
|
|
1628
|
-
const res = await oktoKit.request("GET /user/repos?sort=updated", {
|
|
1629
|
-
headers: {
|
|
1630
|
-
"X-GitHub-Api-Version": "2022-11-28",
|
|
1631
|
-
per_page: 100
|
|
1632
|
-
}
|
|
1633
|
-
});
|
|
1634
|
-
return res.data;
|
|
1635
|
-
}
|
|
1636
|
-
async function getGithubRepoDefaultBranch(repoUrl, options) {
|
|
1637
|
-
const oktoKit = getOktoKit(options);
|
|
1638
|
-
const { owner, repo } = parseGithubOwnerAndRepo(repoUrl);
|
|
1639
|
-
return (await oktoKit.rest.repos.get({ repo, owner })).data.default_branch;
|
|
1640
|
-
}
|
|
1641
|
-
async function getGithubReferenceData({ ref, gitHubUrl }, options) {
|
|
1642
|
-
const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
|
|
1643
|
-
let res;
|
|
1644
|
-
try {
|
|
1645
|
-
const oktoKit = getOktoKit(options);
|
|
1646
|
-
res = await Promise.any([
|
|
1647
|
-
getBranch({ owner, repo, branch: ref }, oktoKit).then((result) => ({
|
|
1648
|
-
date: result.data.commit.commit.committer?.date ? new Date(result.data.commit.commit.committer?.date) : void 0,
|
|
1649
|
-
type: "BRANCH" /* BRANCH */,
|
|
1650
|
-
sha: result.data.commit.sha
|
|
1651
|
-
})),
|
|
1652
|
-
getCommit({ commitSha: ref, repo, owner }, oktoKit).then((commit) => ({
|
|
1653
|
-
date: new Date(commit.data.committer.date),
|
|
1654
|
-
type: "COMMIT" /* COMMIT */,
|
|
1655
|
-
sha: commit.data.sha
|
|
1656
|
-
})),
|
|
1657
|
-
getTagDate({ owner, repo, tag: ref }, oktoKit).then((data) => ({
|
|
1658
|
-
date: new Date(data.date),
|
|
1659
|
-
type: "TAG" /* TAG */,
|
|
1660
|
-
sha: data.sha
|
|
1661
|
-
}))
|
|
1662
|
-
]);
|
|
1663
|
-
return res;
|
|
1664
|
-
} catch (e) {
|
|
1665
|
-
if (e instanceof AggregateError) {
|
|
1666
|
-
throw new RefNotFoundError(`ref: ${ref} does not exist`);
|
|
1667
|
-
}
|
|
1668
|
-
throw e;
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
async function getBranch({ branch, owner, repo }, oktoKit) {
|
|
1672
|
-
return oktoKit.rest.repos.getBranch({
|
|
1673
|
-
branch,
|
|
1674
|
-
owner,
|
|
1675
|
-
repo
|
|
1676
|
-
});
|
|
1677
|
-
}
|
|
1678
|
-
async function getTagDate({ tag, owner, repo }, oktoKit) {
|
|
1679
|
-
const refResponse = await oktoKit.rest.git.getRef({
|
|
1680
|
-
ref: `tags/${tag}`,
|
|
1681
|
-
owner,
|
|
1682
|
-
repo
|
|
1683
|
-
});
|
|
1684
|
-
const tagSha = refResponse.data.object.sha;
|
|
1685
|
-
if (refResponse.data.object.type === "commit") {
|
|
1686
|
-
const res2 = await oktoKit.rest.git.getCommit({
|
|
1687
|
-
commit_sha: tagSha,
|
|
1688
|
-
owner,
|
|
1689
|
-
repo
|
|
1690
|
-
});
|
|
1691
|
-
return {
|
|
1692
|
-
date: res2.data.committer.date,
|
|
1693
|
-
sha: res2.data.sha
|
|
1694
|
-
};
|
|
1695
|
-
}
|
|
1696
|
-
const res = await oktoKit.rest.git.getTag({
|
|
1697
|
-
tag_sha: tagSha,
|
|
1698
|
-
owner,
|
|
1699
|
-
repo
|
|
1700
|
-
});
|
|
1701
|
-
return {
|
|
1702
|
-
date: res.data.tagger.date,
|
|
1703
|
-
sha: res.data.sha
|
|
1704
|
-
};
|
|
1705
|
-
}
|
|
1706
|
-
async function getCommit({
|
|
1707
|
-
commitSha,
|
|
1708
|
-
owner,
|
|
1709
|
-
repo
|
|
1710
|
-
}, oktoKit) {
|
|
1711
|
-
return oktoKit.rest.git.getCommit({
|
|
1712
|
-
repo,
|
|
1713
|
-
owner,
|
|
1714
|
-
commit_sha: commitSha
|
|
1715
|
-
});
|
|
1716
|
-
}
|
|
1717
|
-
function parseGithubOwnerAndRepo(gitHubUrl) {
|
|
1718
|
-
gitHubUrl = normalizeUrl(gitHubUrl);
|
|
1719
|
-
const parsingResult = parseScmURL(gitHubUrl, "GitHub" /* GitHub */);
|
|
1720
|
-
if (!parsingResult || parsingResult.hostname !== "github.com") {
|
|
1721
|
-
throw new InvalidUrlPatternError(`invalid github repo Url ${gitHubUrl}`);
|
|
1722
|
-
}
|
|
1723
|
-
const { organization, repoName } = parsingResult;
|
|
1724
|
-
if (!organization || !repoName) {
|
|
1725
|
-
throw new InvalidUrlPatternError(`invalid github repo Url ${gitHubUrl}`);
|
|
1726
|
-
}
|
|
1727
|
-
return { owner: organization, repo: repoName };
|
|
1728
|
-
}
|
|
1729
|
-
async function queryGithubGraphql(query, variables, options) {
|
|
1730
|
-
const token = options?.githubAuthToken ?? GITHUB_API_TOKEN ?? "";
|
|
1731
|
-
const parameters = variables ?? {};
|
|
1732
|
-
const authorizationHeader = {
|
|
1733
|
-
headers: {
|
|
1734
|
-
authorization: `bearer ${token}`
|
|
1735
|
-
}
|
|
1736
|
-
};
|
|
1737
|
-
try {
|
|
1738
|
-
const oktoKit = getOktoKit(options);
|
|
1739
|
-
const res = await oktoKit.graphql(query, {
|
|
1740
|
-
...parameters,
|
|
1741
|
-
...authorizationHeader
|
|
1742
|
-
});
|
|
1743
|
-
return res;
|
|
1744
|
-
} catch (e) {
|
|
1745
|
-
if (e instanceof RequestError) {
|
|
1746
|
-
return null;
|
|
1848
|
+
case "USELESS_REGEXP_CHAR_ESCAPE" /* UselessRegexpCharEscape */:
|
|
1849
|
+
return "Useless regular-expression character escape";
|
|
1850
|
+
case "INCOMPLETE_HOSTNAME_REGEX" /* IncompleteHostnameRegex */:
|
|
1851
|
+
return "Incomplete Hostname Regex";
|
|
1852
|
+
case "OVERLY_LARGE_RANGE" /* OverlyLargeRange */:
|
|
1853
|
+
return "Regex: Overly Large Range";
|
|
1854
|
+
case "INSUFFICIENT_LOGGING" /* InsufficientLogging */:
|
|
1855
|
+
return "Insufficient Logging of Sensitive Operations";
|
|
1856
|
+
case "PRIVACY_VIOLATION" /* PrivacyViolation */:
|
|
1857
|
+
return "Privacy Violation";
|
|
1858
|
+
case "INCOMPLETE_URL_SCHEME_CHECK" /* IncompleteUrlSchemeCheck */:
|
|
1859
|
+
return "Incomplete URL Scheme Check";
|
|
1860
|
+
case "VALUE_NEVER_READ" /* ValueNeverRead */:
|
|
1861
|
+
return "Value Never Read";
|
|
1862
|
+
case "VALUE_SHADOWING" /* ValueShadowing */:
|
|
1863
|
+
return "Value Shadowing";
|
|
1864
|
+
default: {
|
|
1865
|
+
return issueType ? issueType.replaceAll("_", " ") : "Other";
|
|
1747
1866
|
}
|
|
1748
|
-
throw e;
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
async function getGithubBlameRanges({ ref, gitHubUrl, path: path9 }, options) {
|
|
1752
|
-
const { owner, repo } = parseGithubOwnerAndRepo(gitHubUrl);
|
|
1753
|
-
const variables = {
|
|
1754
|
-
owner,
|
|
1755
|
-
repo,
|
|
1756
|
-
path: path9,
|
|
1757
|
-
ref
|
|
1758
|
-
};
|
|
1759
|
-
const res = await queryGithubGraphql(
|
|
1760
|
-
GetBlameDocument,
|
|
1761
|
-
variables,
|
|
1762
|
-
options
|
|
1763
|
-
);
|
|
1764
|
-
if (!res?.repository?.object?.blame?.ranges) {
|
|
1765
|
-
return [];
|
|
1766
|
-
}
|
|
1767
|
-
return res.repository.object.blame.ranges.map((range) => ({
|
|
1768
|
-
startingLine: range.startingLine,
|
|
1769
|
-
endingLine: range.endingLine,
|
|
1770
|
-
email: range.commit.author.user?.email || "",
|
|
1771
|
-
name: range.commit.author.user?.name || "",
|
|
1772
|
-
login: range.commit.author.user?.login || ""
|
|
1773
|
-
}));
|
|
1774
|
-
}
|
|
1775
|
-
async function createPr({
|
|
1776
|
-
sourceRepoUrl,
|
|
1777
|
-
filesPaths,
|
|
1778
|
-
userRepoUrl,
|
|
1779
|
-
title,
|
|
1780
|
-
body
|
|
1781
|
-
}, options) {
|
|
1782
|
-
const oktoKit = getOktoKit(options);
|
|
1783
|
-
const { owner: sourceOwner, repo: sourceRepo } = parseGithubOwnerAndRepo(sourceRepoUrl);
|
|
1784
|
-
const { owner, repo } = parseGithubOwnerAndRepo(userRepoUrl);
|
|
1785
|
-
const [sourceFilePath, secondFilePath] = filesPaths;
|
|
1786
|
-
const sourceFileContentResponse = await oktoKit.rest.repos.getContent({
|
|
1787
|
-
owner: sourceOwner,
|
|
1788
|
-
repo: sourceRepo,
|
|
1789
|
-
path: "/" + sourceFilePath
|
|
1790
|
-
});
|
|
1791
|
-
const { data: repository } = await oktoKit.rest.repos.get({ owner, repo });
|
|
1792
|
-
const defaultBranch = repository.default_branch;
|
|
1793
|
-
const newBranchName = `mobb/workflow-${Date.now()}`;
|
|
1794
|
-
await oktoKit.rest.git.createRef({
|
|
1795
|
-
owner,
|
|
1796
|
-
repo,
|
|
1797
|
-
ref: `refs/heads/${newBranchName}`,
|
|
1798
|
-
sha: await oktoKit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha)
|
|
1799
|
-
});
|
|
1800
|
-
const decodedContent = Buffer.from(
|
|
1801
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1802
|
-
// @ts-ignore
|
|
1803
|
-
sourceFileContentResponse.data.content,
|
|
1804
|
-
"base64"
|
|
1805
|
-
).toString("utf-8");
|
|
1806
|
-
const tree = [
|
|
1807
|
-
{
|
|
1808
|
-
path: sourceFilePath,
|
|
1809
|
-
mode: "100644",
|
|
1810
|
-
type: "blob",
|
|
1811
|
-
content: decodedContent
|
|
1812
|
-
}
|
|
1813
|
-
];
|
|
1814
|
-
if (secondFilePath) {
|
|
1815
|
-
const secondFileContentResponse = await oktoKit.rest.repos.getContent({
|
|
1816
|
-
owner: sourceOwner,
|
|
1817
|
-
repo: sourceRepo,
|
|
1818
|
-
path: "/" + secondFilePath
|
|
1819
|
-
});
|
|
1820
|
-
const secondDecodedContent = Buffer.from(
|
|
1821
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1822
|
-
// @ts-ignore
|
|
1823
|
-
secondFileContentResponse.data.content,
|
|
1824
|
-
"base64"
|
|
1825
|
-
).toString("utf-8");
|
|
1826
|
-
tree.push({
|
|
1827
|
-
path: secondFilePath,
|
|
1828
|
-
mode: "100644",
|
|
1829
|
-
type: "blob",
|
|
1830
|
-
content: secondDecodedContent
|
|
1831
|
-
});
|
|
1832
1867
|
}
|
|
1833
|
-
|
|
1834
|
-
owner,
|
|
1835
|
-
repo,
|
|
1836
|
-
base_tree: await oktoKit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha),
|
|
1837
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1838
|
-
// @ts-ignore
|
|
1839
|
-
tree
|
|
1840
|
-
});
|
|
1841
|
-
const createCommitResponse = await oktoKit.rest.git.createCommit({
|
|
1842
|
-
owner,
|
|
1843
|
-
repo,
|
|
1844
|
-
message: "Add new yaml file",
|
|
1845
|
-
tree: createTreeResponse.data.sha,
|
|
1846
|
-
parents: [
|
|
1847
|
-
await oktoKit.rest.git.getRef({ owner, repo, ref: `heads/${defaultBranch}` }).then((response) => response.data.object.sha)
|
|
1848
|
-
]
|
|
1849
|
-
});
|
|
1850
|
-
await oktoKit.rest.git.updateRef({
|
|
1851
|
-
owner,
|
|
1852
|
-
repo,
|
|
1853
|
-
ref: `heads/${newBranchName}`,
|
|
1854
|
-
sha: createCommitResponse.data.sha
|
|
1855
|
-
});
|
|
1856
|
-
const createPRResponse = await oktoKit.rest.pulls.create({
|
|
1857
|
-
owner,
|
|
1858
|
-
repo,
|
|
1859
|
-
title,
|
|
1860
|
-
head: newBranchName,
|
|
1861
|
-
head_repo: sourceRepo,
|
|
1862
|
-
body,
|
|
1863
|
-
base: defaultBranch
|
|
1864
|
-
});
|
|
1865
|
-
return {
|
|
1866
|
-
pull_request_url: createPRResponse.data.html_url
|
|
1867
|
-
};
|
|
1868
|
-
}
|
|
1869
|
-
|
|
1870
|
-
// src/features/analysis/scm/github/consts.ts
|
|
1871
|
-
var POST_COMMENT_PATH = "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1872
|
-
var DELETE_COMMENT_PATH = "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1873
|
-
var UPDATE_COMMENT_PATH = "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1874
|
-
var GET_PR_COMMENTS_PATH = "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments";
|
|
1875
|
-
var GET_PR_COMMENT_PATH = "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}";
|
|
1876
|
-
var GET_PR = "GET /repos/{owner}/{repo}/pulls/{pull_number}";
|
|
1877
|
-
var POST_GENERAL_PR_COMMENT = "POST /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
1878
|
-
var GET_GENERAL_PR_COMMENTS = "GET /repos/{owner}/{repo}/issues/{issue_number}/comments";
|
|
1879
|
-
var DELETE_GENERAL_PR_COMMENT = "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}";
|
|
1880
|
-
var CREATE_OR_UPDATE_A_REPOSITORY_SECRET = "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}";
|
|
1881
|
-
var GET_A_REPOSITORY_PUBLIC_KEY = "GET /repos/{owner}/{repo}/actions/secrets/public-key";
|
|
1868
|
+
};
|
|
1882
1869
|
|
|
1883
|
-
// src/features/analysis/scm/
|
|
1884
|
-
function
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
return
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
}
|
|
1905
|
-
function createOrUpdateRepositorySecret(client, params) {
|
|
1906
|
-
return client.request(CREATE_OR_UPDATE_A_REPOSITORY_SECRET, params);
|
|
1870
|
+
// src/features/analysis/scm/utils/index.ts
|
|
1871
|
+
function getFixUrlWithRedirect(params) {
|
|
1872
|
+
const {
|
|
1873
|
+
fixId,
|
|
1874
|
+
projectId,
|
|
1875
|
+
organizationId,
|
|
1876
|
+
analysisId,
|
|
1877
|
+
redirectUrl,
|
|
1878
|
+
appBaseUrl,
|
|
1879
|
+
commentId
|
|
1880
|
+
} = params;
|
|
1881
|
+
const searchParams = new URLSearchParams();
|
|
1882
|
+
searchParams.append("commit_redirect_url", redirectUrl);
|
|
1883
|
+
searchParams.append("comment_id", commentId.toString());
|
|
1884
|
+
return `${getFixUrl({
|
|
1885
|
+
appBaseUrl,
|
|
1886
|
+
fixId,
|
|
1887
|
+
projectId,
|
|
1888
|
+
organizationId,
|
|
1889
|
+
analysisId
|
|
1890
|
+
})}?${searchParams.toString()}`;
|
|
1907
1891
|
}
|
|
1908
|
-
function
|
|
1909
|
-
|
|
1892
|
+
function getFixUrl({
|
|
1893
|
+
appBaseUrl,
|
|
1894
|
+
fixId,
|
|
1895
|
+
projectId,
|
|
1896
|
+
organizationId,
|
|
1897
|
+
analysisId
|
|
1898
|
+
}) {
|
|
1899
|
+
return `${appBaseUrl}/organization/${organizationId}/project/${projectId}/report/${analysisId}/fix/${fixId}`;
|
|
1910
1900
|
}
|
|
1911
|
-
function
|
|
1912
|
-
|
|
1901
|
+
function getCommitUrl(params) {
|
|
1902
|
+
const {
|
|
1903
|
+
fixId,
|
|
1904
|
+
projectId,
|
|
1905
|
+
organizationId,
|
|
1906
|
+
analysisId,
|
|
1907
|
+
redirectUrl,
|
|
1908
|
+
appBaseUrl,
|
|
1909
|
+
commentId
|
|
1910
|
+
} = params;
|
|
1911
|
+
const searchParams = new URLSearchParams();
|
|
1912
|
+
searchParams.append("redirect_url", redirectUrl);
|
|
1913
|
+
searchParams.append("comment_id", commentId.toString());
|
|
1914
|
+
return `${getFixUrl({
|
|
1915
|
+
appBaseUrl,
|
|
1916
|
+
fixId,
|
|
1917
|
+
projectId,
|
|
1918
|
+
organizationId,
|
|
1919
|
+
analysisId
|
|
1920
|
+
})}/commit?${searchParams.toString()}`;
|
|
1913
1921
|
}
|
|
1914
|
-
|
|
1915
|
-
|
|
1922
|
+
var userNamePattern = /^(https?:\/\/)([^@]+@)?([^/]+\/.+)$/;
|
|
1923
|
+
var sshPattern = /^git@([\w.-]+):([\w./-]+)$/;
|
|
1924
|
+
function normalizeUrl(repoUrl) {
|
|
1925
|
+
let trimmedUrl = repoUrl.trim().replace(/\/+$/, "");
|
|
1926
|
+
if (repoUrl.endsWith(".git")) {
|
|
1927
|
+
trimmedUrl = trimmedUrl.slice(0, -".git".length);
|
|
1928
|
+
}
|
|
1929
|
+
const usernameMatch = trimmedUrl.match(userNamePattern);
|
|
1930
|
+
if (usernameMatch) {
|
|
1931
|
+
const [_all, protocol, _username, repoPath] = usernameMatch;
|
|
1932
|
+
trimmedUrl = `${protocol}${repoPath}`;
|
|
1933
|
+
}
|
|
1934
|
+
const sshMatch = trimmedUrl.match(sshPattern);
|
|
1935
|
+
if (sshMatch) {
|
|
1936
|
+
const [_all, hostname, reporPath] = sshMatch;
|
|
1937
|
+
trimmedUrl = `https://${hostname}/${reporPath}`;
|
|
1938
|
+
}
|
|
1939
|
+
return trimmedUrl;
|
|
1916
1940
|
}
|
|
1917
|
-
|
|
1918
|
-
return
|
|
1941
|
+
var isUrlHasPath = (url) => {
|
|
1942
|
+
return new URL(url).origin !== url;
|
|
1943
|
+
};
|
|
1944
|
+
function shouldValidateUrl(repoUrl) {
|
|
1945
|
+
return repoUrl && isUrlHasPath(repoUrl);
|
|
1919
1946
|
}
|
|
1920
1947
|
|
|
1921
|
-
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
1922
|
-
import querystring2 from "node:querystring";
|
|
1923
|
-
import {
|
|
1924
|
-
Gitlab
|
|
1925
|
-
} from "@gitbeaker/rest";
|
|
1926
|
-
import { ProxyAgent } from "undici";
|
|
1927
|
-
import { z as z5 } from "zod";
|
|
1928
|
-
|
|
1929
1948
|
// src/features/analysis/scm/gitlab/types.ts
|
|
1930
1949
|
import { z as z4 } from "zod";
|
|
1931
1950
|
var GitlabAuthResultZ = z4.object({
|
|
@@ -1935,13 +1954,6 @@ var GitlabAuthResultZ = z4.object({
|
|
|
1935
1954
|
});
|
|
1936
1955
|
|
|
1937
1956
|
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
1938
|
-
var EnvVariablesZod2 = z5.object({
|
|
1939
|
-
GITLAB_API_TOKEN: z5.string().optional(),
|
|
1940
|
-
BROKERED_HOSTS: z5.string().toLowerCase().transform(
|
|
1941
|
-
(x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
|
|
1942
|
-
).default("")
|
|
1943
|
-
});
|
|
1944
|
-
var { GITLAB_API_TOKEN, BROKERED_HOSTS } = EnvVariablesZod2.parse(process.env);
|
|
1945
1957
|
function removeTrailingSlash2(str) {
|
|
1946
1958
|
return str.trim().replace(/\/+$/, "");
|
|
1947
1959
|
}
|
|
@@ -1963,7 +1975,7 @@ async function gitlabValidateParams({
|
|
|
1963
1975
|
if (accessToken) {
|
|
1964
1976
|
await api2.Users.showCurrentUser();
|
|
1965
1977
|
}
|
|
1966
|
-
if (url) {
|
|
1978
|
+
if (url && shouldValidateUrl(url)) {
|
|
1967
1979
|
const { projectPath } = parseGitlabOwnerAndRepo(url);
|
|
1968
1980
|
await api2.Projects.show(projectPath);
|
|
1969
1981
|
}
|
|
@@ -2216,7 +2228,7 @@ function initGitlabFetchMock() {
|
|
|
2216
2228
|
if (urlParsed && BROKERED_HOSTS.includes(
|
|
2217
2229
|
`${urlParsed.protocol?.toLowerCase()}//${urlParsed.host?.toLowerCase()}`
|
|
2218
2230
|
)) {
|
|
2219
|
-
const dispatcher = new
|
|
2231
|
+
const dispatcher = new ProxyAgent2({
|
|
2220
2232
|
uri: process.env["GIT_PROXY_HOST"] || "http://tinyproxy:8888",
|
|
2221
2233
|
requestTls: {
|
|
2222
2234
|
rejectUnauthorized: false
|
|
@@ -2236,88 +2248,88 @@ import parseDiff from "parse-diff";
|
|
|
2236
2248
|
import path3 from "path";
|
|
2237
2249
|
import { simpleGit } from "simple-git";
|
|
2238
2250
|
import tmp from "tmp";
|
|
2239
|
-
import { z as
|
|
2251
|
+
import { z as z6 } from "zod";
|
|
2240
2252
|
|
|
2241
2253
|
// src/features/analysis/scm/scmSubmit/types.ts
|
|
2242
|
-
import { z as
|
|
2243
|
-
var BaseSubmitToScmMessageZ =
|
|
2244
|
-
submitFixRequestId:
|
|
2245
|
-
fixes:
|
|
2246
|
-
|
|
2247
|
-
fixId:
|
|
2248
|
-
patches:
|
|
2254
|
+
import { z as z5 } from "zod";
|
|
2255
|
+
var BaseSubmitToScmMessageZ = z5.object({
|
|
2256
|
+
submitFixRequestId: z5.string().uuid(),
|
|
2257
|
+
fixes: z5.array(
|
|
2258
|
+
z5.object({
|
|
2259
|
+
fixId: z5.string().uuid(),
|
|
2260
|
+
patches: z5.array(z5.string())
|
|
2249
2261
|
})
|
|
2250
2262
|
),
|
|
2251
|
-
commitHash:
|
|
2252
|
-
repoUrl:
|
|
2263
|
+
commitHash: z5.string(),
|
|
2264
|
+
repoUrl: z5.string()
|
|
2253
2265
|
});
|
|
2254
2266
|
var submitToScmMessageType = {
|
|
2255
2267
|
commitToSameBranch: "commitToSameBranch",
|
|
2256
2268
|
submitFixesForDifferentBranch: "submitFixesForDifferentBranch"
|
|
2257
2269
|
};
|
|
2258
2270
|
var CommitToSameBranchParamsZ = BaseSubmitToScmMessageZ.merge(
|
|
2259
|
-
|
|
2260
|
-
type:
|
|
2261
|
-
branch:
|
|
2262
|
-
commitMessage:
|
|
2263
|
-
commitDescription:
|
|
2264
|
-
githubCommentId:
|
|
2271
|
+
z5.object({
|
|
2272
|
+
type: z5.literal(submitToScmMessageType.commitToSameBranch),
|
|
2273
|
+
branch: z5.string(),
|
|
2274
|
+
commitMessage: z5.string(),
|
|
2275
|
+
commitDescription: z5.string().nullish(),
|
|
2276
|
+
githubCommentId: z5.number().nullish()
|
|
2265
2277
|
})
|
|
2266
2278
|
);
|
|
2267
|
-
var SubmitFixesToDifferentBranchParamsZ =
|
|
2268
|
-
type:
|
|
2269
|
-
submitBranch:
|
|
2270
|
-
baseBranch:
|
|
2279
|
+
var SubmitFixesToDifferentBranchParamsZ = z5.object({
|
|
2280
|
+
type: z5.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
2281
|
+
submitBranch: z5.string(),
|
|
2282
|
+
baseBranch: z5.string()
|
|
2271
2283
|
}).merge(BaseSubmitToScmMessageZ);
|
|
2272
|
-
var SubmitFixesMessageZ =
|
|
2284
|
+
var SubmitFixesMessageZ = z5.union([
|
|
2273
2285
|
CommitToSameBranchParamsZ,
|
|
2274
2286
|
SubmitFixesToDifferentBranchParamsZ
|
|
2275
2287
|
]);
|
|
2276
|
-
var FixResponseArrayZ =
|
|
2277
|
-
|
|
2278
|
-
fixId:
|
|
2288
|
+
var FixResponseArrayZ = z5.array(
|
|
2289
|
+
z5.object({
|
|
2290
|
+
fixId: z5.string().uuid()
|
|
2279
2291
|
})
|
|
2280
2292
|
);
|
|
2281
|
-
var SubmitFixesBaseResponseMessageZ =
|
|
2282
|
-
submitFixRequestId:
|
|
2283
|
-
submitBranches:
|
|
2284
|
-
|
|
2285
|
-
branchName:
|
|
2293
|
+
var SubmitFixesBaseResponseMessageZ = z5.object({
|
|
2294
|
+
submitFixRequestId: z5.string().uuid(),
|
|
2295
|
+
submitBranches: z5.array(
|
|
2296
|
+
z5.object({
|
|
2297
|
+
branchName: z5.string(),
|
|
2286
2298
|
fixes: FixResponseArrayZ
|
|
2287
2299
|
})
|
|
2288
2300
|
),
|
|
2289
|
-
error:
|
|
2290
|
-
type:
|
|
2301
|
+
error: z5.object({
|
|
2302
|
+
type: z5.enum([
|
|
2291
2303
|
"InitialRepoAccessError",
|
|
2292
2304
|
"PushBranchError",
|
|
2293
2305
|
"UnknownError"
|
|
2294
2306
|
]),
|
|
2295
|
-
info:
|
|
2296
|
-
message:
|
|
2297
|
-
pushBranchName:
|
|
2307
|
+
info: z5.object({
|
|
2308
|
+
message: z5.string(),
|
|
2309
|
+
pushBranchName: z5.string().optional()
|
|
2298
2310
|
})
|
|
2299
2311
|
}).optional()
|
|
2300
2312
|
});
|
|
2301
|
-
var SubmitFixesToSameBranchResponseMessageZ =
|
|
2302
|
-
type:
|
|
2303
|
-
githubCommentId:
|
|
2313
|
+
var SubmitFixesToSameBranchResponseMessageZ = z5.object({
|
|
2314
|
+
type: z5.literal(submitToScmMessageType.commitToSameBranch),
|
|
2315
|
+
githubCommentId: z5.number().nullish()
|
|
2304
2316
|
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
2305
|
-
var SubmitFixesToDifferentBranchResponseMessageZ =
|
|
2306
|
-
type:
|
|
2307
|
-
githubCommentId:
|
|
2317
|
+
var SubmitFixesToDifferentBranchResponseMessageZ = z5.object({
|
|
2318
|
+
type: z5.literal(submitToScmMessageType.submitFixesForDifferentBranch),
|
|
2319
|
+
githubCommentId: z5.number().optional()
|
|
2308
2320
|
}).merge(SubmitFixesBaseResponseMessageZ);
|
|
2309
|
-
var SubmitFixesResponseMessageZ =
|
|
2321
|
+
var SubmitFixesResponseMessageZ = z5.discriminatedUnion("type", [
|
|
2310
2322
|
SubmitFixesToSameBranchResponseMessageZ,
|
|
2311
2323
|
SubmitFixesToDifferentBranchResponseMessageZ
|
|
2312
2324
|
]);
|
|
2313
2325
|
|
|
2314
2326
|
// src/features/analysis/scm/scmSubmit/index.ts
|
|
2315
|
-
var
|
|
2316
|
-
BROKERED_HOSTS:
|
|
2327
|
+
var EnvVariablesZod2 = z6.object({
|
|
2328
|
+
BROKERED_HOSTS: z6.string().toLowerCase().transform(
|
|
2317
2329
|
(x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
|
|
2318
2330
|
).default("")
|
|
2319
2331
|
});
|
|
2320
|
-
var { BROKERED_HOSTS: BROKERED_HOSTS2 } =
|
|
2332
|
+
var { BROKERED_HOSTS: BROKERED_HOSTS2 } = EnvVariablesZod2.parse(process.env);
|
|
2321
2333
|
var isValidBranchName = async (branchName) => {
|
|
2322
2334
|
const git = simpleGit();
|
|
2323
2335
|
try {
|
|
@@ -2330,18 +2342,18 @@ var isValidBranchName = async (branchName) => {
|
|
|
2330
2342
|
return false;
|
|
2331
2343
|
}
|
|
2332
2344
|
};
|
|
2333
|
-
var FixesZ =
|
|
2334
|
-
|
|
2335
|
-
fixId:
|
|
2336
|
-
patches:
|
|
2345
|
+
var FixesZ = z6.array(
|
|
2346
|
+
z6.object({
|
|
2347
|
+
fixId: z6.string(),
|
|
2348
|
+
patches: z6.array(z6.string())
|
|
2337
2349
|
})
|
|
2338
2350
|
).nonempty();
|
|
2339
2351
|
|
|
2340
2352
|
// src/features/analysis/scm/scm.ts
|
|
2341
|
-
var GetRefererenceResultZ =
|
|
2342
|
-
date:
|
|
2343
|
-
sha:
|
|
2344
|
-
type:
|
|
2353
|
+
var GetRefererenceResultZ = z7.object({
|
|
2354
|
+
date: z7.date().optional(),
|
|
2355
|
+
sha: z7.string(),
|
|
2356
|
+
type: z7.nativeEnum(ReferenceType)
|
|
2345
2357
|
});
|
|
2346
2358
|
function getCloudScmLibTypeFromUrl(url) {
|
|
2347
2359
|
if (!url) {
|
|
@@ -2382,11 +2394,11 @@ var scmTypeToScmLibScmType = {
|
|
|
2382
2394
|
["Bitbucket" /* Bitbucket */]: "BITBUCKET" /* BITBUCKET */
|
|
2383
2395
|
};
|
|
2384
2396
|
function getScmTypeFromScmLibType(scmLibType) {
|
|
2385
|
-
const parsedScmLibType =
|
|
2397
|
+
const parsedScmLibType = z7.nativeEnum(ScmLibScmType).parse(scmLibType);
|
|
2386
2398
|
return scmLibScmTypeToScmType[parsedScmLibType];
|
|
2387
2399
|
}
|
|
2388
2400
|
function getScmLibTypeFromScmType(scmType) {
|
|
2389
|
-
const parsedScmType =
|
|
2401
|
+
const parsedScmType = z7.nativeEnum(ScmType).parse(scmType);
|
|
2390
2402
|
return scmTypeToScmLibScmType[parsedScmType];
|
|
2391
2403
|
}
|
|
2392
2404
|
function getScmConfig({
|
|
@@ -2581,10 +2593,7 @@ var SCMLib = class {
|
|
|
2581
2593
|
scmType,
|
|
2582
2594
|
scmOrg
|
|
2583
2595
|
}) {
|
|
2584
|
-
|
|
2585
|
-
if (url) {
|
|
2586
|
-
trimmedUrl = url.trim().replace(/\/$/, "").replace(/.git$/i, "");
|
|
2587
|
-
}
|
|
2596
|
+
const trimmedUrl = url ? url.trim().replace(/\/$/, "").replace(/.git$/i, "") : void 0;
|
|
2588
2597
|
try {
|
|
2589
2598
|
switch (scmType) {
|
|
2590
2599
|
case "GITHUB" /* GITHUB */: {
|
|
@@ -2612,7 +2621,7 @@ var SCMLib = class {
|
|
|
2612
2621
|
if (e instanceof InvalidRepoUrlError && url) {
|
|
2613
2622
|
throw new RepoNoTokenAccessError(
|
|
2614
2623
|
"no access to repo",
|
|
2615
|
-
scmLibScmTypeToScmType[
|
|
2624
|
+
scmLibScmTypeToScmType[z7.nativeEnum(ScmLibScmType).parse(scmType)]
|
|
2616
2625
|
);
|
|
2617
2626
|
}
|
|
2618
2627
|
}
|
|
@@ -2907,46 +2916,37 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
2907
2916
|
// we don't always need a url, what's important is that we have an access token
|
|
2908
2917
|
constructor(url, accessToken, scmOrg) {
|
|
2909
2918
|
super(url, accessToken, scmOrg);
|
|
2910
|
-
__publicField(this, "
|
|
2911
|
-
this.
|
|
2919
|
+
__publicField(this, "githubSdk");
|
|
2920
|
+
this.githubSdk = getGithubSdk({
|
|
2921
|
+
auth: accessToken,
|
|
2922
|
+
url
|
|
2923
|
+
});
|
|
2912
2924
|
}
|
|
2913
2925
|
async createSubmitRequest(params) {
|
|
2914
2926
|
this._validateAccessTokenAndUrl();
|
|
2915
2927
|
const { targetBranchName, sourceBranchName, title, body } = params;
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
})
|
|
2925
|
-
);
|
|
2928
|
+
const pullRequestResult = await this.githubSdk.createPullRequest({
|
|
2929
|
+
title,
|
|
2930
|
+
body,
|
|
2931
|
+
targetBranchName,
|
|
2932
|
+
sourceBranchName,
|
|
2933
|
+
repoUrl: this.url
|
|
2934
|
+
});
|
|
2935
|
+
return String(pullRequestResult.data.number);
|
|
2926
2936
|
}
|
|
2927
2937
|
async forkRepo(repoUrl) {
|
|
2928
2938
|
this._validateToken();
|
|
2929
|
-
return forkRepo({
|
|
2930
|
-
repoUrl
|
|
2931
|
-
accessToken: this.accessToken
|
|
2939
|
+
return this.githubSdk.forkRepo({
|
|
2940
|
+
repoUrl
|
|
2932
2941
|
});
|
|
2933
2942
|
}
|
|
2934
|
-
async createOrUpdateRepositorySecret(params
|
|
2935
|
-
|
|
2936
|
-
throw new Error("cannot delete comment without access token or url");
|
|
2937
|
-
}
|
|
2938
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2943
|
+
async createOrUpdateRepositorySecret(params) {
|
|
2944
|
+
this._validateAccessTokenAndUrl();
|
|
2939
2945
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
2940
|
-
const { data: repositoryPublicKeyResponse } = await
|
|
2941
|
-
oktokit,
|
|
2942
|
-
{
|
|
2943
|
-
owner,
|
|
2944
|
-
repo
|
|
2945
|
-
}
|
|
2946
|
-
);
|
|
2946
|
+
const { data: repositoryPublicKeyResponse } = await this.githubSdk.getRepositoryPublicKey({ owner, repo });
|
|
2947
2947
|
const { key_id, key } = repositoryPublicKeyResponse;
|
|
2948
2948
|
const encryptedValue = await encryptSecret(params.value, key);
|
|
2949
|
-
return createOrUpdateRepositorySecret(
|
|
2949
|
+
return this.githubSdk.createOrUpdateRepositorySecret({
|
|
2950
2950
|
encrypted_value: encryptedValue,
|
|
2951
2951
|
secret_name: params.name,
|
|
2952
2952
|
key_id,
|
|
@@ -2955,66 +2955,49 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
2955
2955
|
});
|
|
2956
2956
|
}
|
|
2957
2957
|
async createPullRequestWithNewFile(sourceRepoUrl, filesPaths, userRepoUrl, title, body) {
|
|
2958
|
-
const { pull_request_url } = await createPr(
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
},
|
|
2966
|
-
{
|
|
2967
|
-
githubAuthToken: this.accessToken
|
|
2968
|
-
}
|
|
2969
|
-
);
|
|
2958
|
+
const { pull_request_url } = await this.githubSdk.createPr({
|
|
2959
|
+
sourceRepoUrl,
|
|
2960
|
+
filesPaths,
|
|
2961
|
+
userRepoUrl,
|
|
2962
|
+
title,
|
|
2963
|
+
body
|
|
2964
|
+
});
|
|
2970
2965
|
return { pull_request_url };
|
|
2971
2966
|
}
|
|
2972
2967
|
async validateParams() {
|
|
2973
2968
|
return githubValidateParams(this.url, this.accessToken);
|
|
2974
2969
|
}
|
|
2975
|
-
async postPrComment(params
|
|
2976
|
-
|
|
2977
|
-
throw new Error("cannot post on PR without access token or url");
|
|
2978
|
-
}
|
|
2979
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2970
|
+
async postPrComment(params) {
|
|
2971
|
+
this._validateAccessTokenAndUrl();
|
|
2980
2972
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
2981
|
-
return postPrComment(
|
|
2973
|
+
return this.githubSdk.postPrComment({
|
|
2982
2974
|
...params,
|
|
2983
2975
|
owner,
|
|
2984
2976
|
repo
|
|
2985
2977
|
});
|
|
2986
2978
|
}
|
|
2987
|
-
async updatePrComment(params
|
|
2988
|
-
|
|
2989
|
-
throw new Error("cannot update on PR without access token or url");
|
|
2990
|
-
}
|
|
2991
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2979
|
+
async updatePrComment(params) {
|
|
2980
|
+
this._validateAccessTokenAndUrl();
|
|
2992
2981
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
2993
|
-
return updatePrComment(
|
|
2982
|
+
return this.githubSdk.updatePrComment({
|
|
2994
2983
|
...params,
|
|
2995
2984
|
owner,
|
|
2996
2985
|
repo
|
|
2997
2986
|
});
|
|
2998
2987
|
}
|
|
2999
|
-
async deleteComment(params
|
|
3000
|
-
|
|
3001
|
-
throw new Error("cannot delete comment without access token or url");
|
|
3002
|
-
}
|
|
3003
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2988
|
+
async deleteComment(params) {
|
|
2989
|
+
this._validateAccessTokenAndUrl();
|
|
3004
2990
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3005
|
-
return deleteComment(
|
|
2991
|
+
return this.githubSdk.deleteComment({
|
|
3006
2992
|
...params,
|
|
3007
2993
|
owner,
|
|
3008
2994
|
repo
|
|
3009
2995
|
});
|
|
3010
2996
|
}
|
|
3011
|
-
async getPrComments(params
|
|
3012
|
-
|
|
3013
|
-
throw new Error("cannot get Pr Comments without access token or url");
|
|
3014
|
-
}
|
|
3015
|
-
const oktokit = _oktokit || this.oktokit;
|
|
2997
|
+
async getPrComments(params) {
|
|
2998
|
+
this._validateAccessTokenAndUrl();
|
|
3016
2999
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3017
|
-
return getPrComments(
|
|
3000
|
+
return this.githubSdk.getPrComments({
|
|
3018
3001
|
per_page: 100,
|
|
3019
3002
|
...params,
|
|
3020
3003
|
owner,
|
|
@@ -3022,27 +3005,23 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3022
3005
|
});
|
|
3023
3006
|
}
|
|
3024
3007
|
async getPrDiff(params) {
|
|
3025
|
-
|
|
3026
|
-
throw new Error("cannot get Pr Comments without access token or url");
|
|
3027
|
-
}
|
|
3008
|
+
this._validateAccessTokenAndUrl();
|
|
3028
3009
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3029
|
-
const prRes = await getPrDiff(
|
|
3010
|
+
const prRes = await this.githubSdk.getPrDiff({
|
|
3030
3011
|
...params,
|
|
3031
3012
|
owner,
|
|
3032
3013
|
repo
|
|
3033
3014
|
});
|
|
3034
|
-
return
|
|
3015
|
+
return z7.string().parse(prRes.data);
|
|
3035
3016
|
}
|
|
3036
3017
|
async getRepoList(_scmOrg) {
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
throw new Error("no access token");
|
|
3040
|
-
}
|
|
3041
|
-
return getGithubRepoList(this.accessToken);
|
|
3018
|
+
this._validateToken();
|
|
3019
|
+
return this.githubSdk.getGithubRepoList();
|
|
3042
3020
|
}
|
|
3043
3021
|
async getBranchList() {
|
|
3044
3022
|
this._validateAccessTokenAndUrl();
|
|
3045
|
-
|
|
3023
|
+
const branches = await this.githubSdk.getGithubBranchList(this.url);
|
|
3024
|
+
return branches.data.map((branch) => branch.name);
|
|
3046
3025
|
}
|
|
3047
3026
|
getScmLibType() {
|
|
3048
3027
|
return "GITHUB" /* GITHUB */;
|
|
@@ -3054,73 +3033,57 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3054
3033
|
return {};
|
|
3055
3034
|
}
|
|
3056
3035
|
getDownloadUrl(sha) {
|
|
3057
|
-
this.url;
|
|
3058
3036
|
this._validateUrl();
|
|
3059
3037
|
const res = parseScmURL(this.url, "GitHub" /* GitHub */);
|
|
3060
3038
|
if (!res) {
|
|
3061
3039
|
throw new InvalidRepoUrlError("invalid repo url");
|
|
3062
3040
|
}
|
|
3063
|
-
const { hostname, organization, repoName } = res;
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
);
|
|
3041
|
+
const { protocol, hostname, organization, repoName } = res;
|
|
3042
|
+
const downloadUrl = isGithubOnPrem(this.url) ? `${protocol}//${hostname}/api/v3/repos/${organization}/${repoName}/zipball/${sha}` : `https://api.${hostname}/repos/${organization}/${repoName}/zipball/${sha}`;
|
|
3043
|
+
return Promise.resolve(downloadUrl);
|
|
3067
3044
|
}
|
|
3068
3045
|
async _getUsernameForAuthUrl() {
|
|
3069
3046
|
return this.getUsername();
|
|
3070
3047
|
}
|
|
3071
3048
|
async getIsRemoteBranch(branch) {
|
|
3072
|
-
this.
|
|
3073
|
-
return getGithubIsRemoteBranch(
|
|
3049
|
+
this._validateUrl();
|
|
3050
|
+
return this.githubSdk.getGithubIsRemoteBranch({ branch, repoUrl: this.url });
|
|
3074
3051
|
}
|
|
3075
3052
|
async getUserHasAccessToRepo() {
|
|
3076
|
-
|
|
3077
|
-
console.error("no access token or no url");
|
|
3078
|
-
throw new Error("no access token or no url");
|
|
3079
|
-
}
|
|
3053
|
+
this._validateAccessTokenAndUrl();
|
|
3080
3054
|
const username = await this.getUsername();
|
|
3081
|
-
return
|
|
3055
|
+
return this.githubSdk.getGithubIsUserCollaborator({
|
|
3056
|
+
repoUrl: this.url,
|
|
3057
|
+
username
|
|
3058
|
+
});
|
|
3082
3059
|
}
|
|
3083
3060
|
async getUsername() {
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
throw new Error("no access token");
|
|
3087
|
-
}
|
|
3088
|
-
return getGithubUsername(this.accessToken);
|
|
3061
|
+
this._validateToken();
|
|
3062
|
+
return this.githubSdk.getGithubUsername();
|
|
3089
3063
|
}
|
|
3090
3064
|
async getSubmitRequestStatus(scmSubmitRequestId) {
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
this.accessToken,
|
|
3097
|
-
this.url,
|
|
3098
|
-
Number(scmSubmitRequestId)
|
|
3099
|
-
);
|
|
3100
|
-
return state;
|
|
3065
|
+
this._validateAccessTokenAndUrl();
|
|
3066
|
+
return this.githubSdk.getGithubPullRequestStatus({
|
|
3067
|
+
repoUrl: this.url,
|
|
3068
|
+
prNumber: Number(scmSubmitRequestId)
|
|
3069
|
+
});
|
|
3101
3070
|
}
|
|
3102
3071
|
async getRepoBlameRanges(ref, path9) {
|
|
3103
3072
|
this._validateUrl();
|
|
3104
|
-
return await getGithubBlameRanges(
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
);
|
|
3073
|
+
return await this.githubSdk.getGithubBlameRanges({
|
|
3074
|
+
ref,
|
|
3075
|
+
path: path9,
|
|
3076
|
+
gitHubUrl: this.url
|
|
3077
|
+
});
|
|
3110
3078
|
}
|
|
3111
3079
|
async getReferenceData(ref) {
|
|
3112
3080
|
this._validateUrl();
|
|
3113
|
-
return
|
|
3114
|
-
{ ref, gitHubUrl: this.url },
|
|
3115
|
-
{
|
|
3116
|
-
githubAuthToken: this.accessToken
|
|
3117
|
-
}
|
|
3118
|
-
);
|
|
3081
|
+
return this.githubSdk.getGithubReferenceData({ ref, gitHubUrl: this.url });
|
|
3119
3082
|
}
|
|
3120
3083
|
async getPrComment(commentId) {
|
|
3121
3084
|
this._validateUrl();
|
|
3122
3085
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3123
|
-
return await getPrComment(
|
|
3086
|
+
return await this.githubSdk.getPrComment({
|
|
3124
3087
|
repo,
|
|
3125
3088
|
owner,
|
|
3126
3089
|
comment_id: commentId
|
|
@@ -3128,17 +3091,12 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3128
3091
|
}
|
|
3129
3092
|
async getRepoDefaultBranch() {
|
|
3130
3093
|
this._validateUrl();
|
|
3131
|
-
return await getGithubRepoDefaultBranch(this.url
|
|
3132
|
-
githubAuthToken: this.accessToken
|
|
3133
|
-
});
|
|
3094
|
+
return await this.githubSdk.getGithubRepoDefaultBranch(this.url);
|
|
3134
3095
|
}
|
|
3135
3096
|
async getPrUrl(prNumber) {
|
|
3136
|
-
|
|
3137
|
-
console.error("no url");
|
|
3138
|
-
throw new Error("no url");
|
|
3139
|
-
}
|
|
3097
|
+
this._validateAccessTokenAndUrl();
|
|
3140
3098
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3141
|
-
const getPrRes = await getPr(
|
|
3099
|
+
const getPrRes = await this.githubSdk.getPr({
|
|
3142
3100
|
owner,
|
|
3143
3101
|
repo,
|
|
3144
3102
|
pull_number: prNumber
|
|
@@ -3147,21 +3105,20 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3147
3105
|
}
|
|
3148
3106
|
async postGeneralPrComment(params) {
|
|
3149
3107
|
const { prNumber, body } = params;
|
|
3150
|
-
this.
|
|
3108
|
+
this._validateAccessTokenAndUrl();
|
|
3151
3109
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3152
|
-
return await postGeneralPrComment(
|
|
3110
|
+
return await this.githubSdk.postGeneralPrComment({
|
|
3153
3111
|
issue_number: prNumber,
|
|
3154
3112
|
owner,
|
|
3155
3113
|
repo,
|
|
3156
3114
|
body
|
|
3157
3115
|
});
|
|
3158
3116
|
}
|
|
3159
|
-
async getGeneralPrComments(params
|
|
3117
|
+
async getGeneralPrComments(params) {
|
|
3160
3118
|
const { prNumber } = params;
|
|
3161
|
-
this.
|
|
3162
|
-
const oktoKit = auth ? new Octokit2({ auth: auth.authToken }) : this.oktokit;
|
|
3119
|
+
this._validateAccessTokenAndUrl();
|
|
3163
3120
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3164
|
-
return await getGeneralPrComments(
|
|
3121
|
+
return await this.githubSdk.getGeneralPrComments({
|
|
3165
3122
|
issue_number: prNumber,
|
|
3166
3123
|
owner,
|
|
3167
3124
|
repo
|
|
@@ -3170,9 +3127,9 @@ var GithubSCMLib = class extends SCMLib {
|
|
|
3170
3127
|
async deleteGeneralPrComment({
|
|
3171
3128
|
commentId
|
|
3172
3129
|
}) {
|
|
3173
|
-
this.
|
|
3130
|
+
this._validateAccessTokenAndUrl();
|
|
3174
3131
|
const { owner, repo } = parseGithubOwnerAndRepo(this.url);
|
|
3175
|
-
return deleteGeneralPrComment(
|
|
3132
|
+
return this.githubSdk.deleteGeneralPrComment({
|
|
3176
3133
|
owner,
|
|
3177
3134
|
repo,
|
|
3178
3135
|
comment_id: commentId
|
|
@@ -3246,7 +3203,7 @@ var StubSCMLib = class extends SCMLib {
|
|
|
3246
3203
|
};
|
|
3247
3204
|
function getUserAndPassword(token) {
|
|
3248
3205
|
const [username, password] = token.split(":");
|
|
3249
|
-
const safePasswordAndUsername =
|
|
3206
|
+
const safePasswordAndUsername = z7.object({ username: z7.string(), password: z7.string() }).parse({ username, password });
|
|
3250
3207
|
return {
|
|
3251
3208
|
username: safePasswordAndUsername.username,
|
|
3252
3209
|
password: safePasswordAndUsername.password
|
|
@@ -3282,7 +3239,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3282
3239
|
return { username, password, authType };
|
|
3283
3240
|
}
|
|
3284
3241
|
case "token": {
|
|
3285
|
-
return { authType, token:
|
|
3242
|
+
return { authType, token: z7.string().parse(this.accessToken) };
|
|
3286
3243
|
}
|
|
3287
3244
|
case "public":
|
|
3288
3245
|
return { authType };
|
|
@@ -3294,7 +3251,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3294
3251
|
...params,
|
|
3295
3252
|
repoUrl: this.url
|
|
3296
3253
|
});
|
|
3297
|
-
return String(
|
|
3254
|
+
return String(z7.number().parse(pullRequestRes.id));
|
|
3298
3255
|
}
|
|
3299
3256
|
async validateParams() {
|
|
3300
3257
|
return validateBitbucketParams({
|
|
@@ -3366,7 +3323,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3366
3323
|
async getUsername() {
|
|
3367
3324
|
this._validateToken();
|
|
3368
3325
|
const res = await this.bitbucketSdk.getUser();
|
|
3369
|
-
return
|
|
3326
|
+
return z7.string().parse(res.username);
|
|
3370
3327
|
}
|
|
3371
3328
|
async getSubmitRequestStatus(_scmSubmitRequestId) {
|
|
3372
3329
|
this._validateAccessTokenAndUrl();
|
|
@@ -3395,7 +3352,7 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3395
3352
|
async getRepoDefaultBranch() {
|
|
3396
3353
|
this._validateUrl();
|
|
3397
3354
|
const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
|
|
3398
|
-
return
|
|
3355
|
+
return z7.string().parse(repoRes.mainbranch?.name);
|
|
3399
3356
|
}
|
|
3400
3357
|
getPrUrl(prNumber) {
|
|
3401
3358
|
this._validateUrl();
|
|
@@ -3419,25 +3376,25 @@ var BitbucketSCMLib = class extends SCMLib {
|
|
|
3419
3376
|
// src/features/analysis/scm/bitbucket/bitbucket.ts
|
|
3420
3377
|
var { Bitbucket } = bitbucketPkg;
|
|
3421
3378
|
var BITBUCKET_HOSTNAME = "bitbucket.org";
|
|
3422
|
-
var TokenExpiredErrorZ =
|
|
3423
|
-
status:
|
|
3424
|
-
error:
|
|
3425
|
-
type:
|
|
3426
|
-
error:
|
|
3427
|
-
message:
|
|
3379
|
+
var TokenExpiredErrorZ = z8.object({
|
|
3380
|
+
status: z8.number(),
|
|
3381
|
+
error: z8.object({
|
|
3382
|
+
type: z8.string(),
|
|
3383
|
+
error: z8.object({
|
|
3384
|
+
message: z8.string()
|
|
3428
3385
|
})
|
|
3429
3386
|
})
|
|
3430
3387
|
});
|
|
3431
3388
|
var BITBUCKET_ACCESS_TOKEN_URL = `https://${BITBUCKET_HOSTNAME}/site/oauth2/access_token`;
|
|
3432
|
-
var BitbucketAuthResultZ =
|
|
3433
|
-
access_token:
|
|
3434
|
-
token_type:
|
|
3435
|
-
refresh_token:
|
|
3389
|
+
var BitbucketAuthResultZ = z8.object({
|
|
3390
|
+
access_token: z8.string(),
|
|
3391
|
+
token_type: z8.string(),
|
|
3392
|
+
refresh_token: z8.string()
|
|
3436
3393
|
});
|
|
3437
|
-
var BitbucketParseResultZ =
|
|
3438
|
-
organization:
|
|
3439
|
-
repoName:
|
|
3440
|
-
hostname:
|
|
3394
|
+
var BitbucketParseResultZ = z8.object({
|
|
3395
|
+
organization: z8.string(),
|
|
3396
|
+
repoName: z8.string(),
|
|
3397
|
+
hostname: z8.literal(BITBUCKET_HOSTNAME)
|
|
3441
3398
|
});
|
|
3442
3399
|
function parseBitbucketOrganizationAndRepo(bitbucketUrl) {
|
|
3443
3400
|
const parsedGitHubUrl = normalizeUrl(bitbucketUrl);
|
|
@@ -3515,7 +3472,7 @@ function getBitbucketSdk(params) {
|
|
|
3515
3472
|
if (!res.data.values) {
|
|
3516
3473
|
return [];
|
|
3517
3474
|
}
|
|
3518
|
-
return res.data.values.filter((branch) => !!branch.name).map((branch) =>
|
|
3475
|
+
return res.data.values.filter((branch) => !!branch.name).map((branch) => z8.string().parse(branch.name));
|
|
3519
3476
|
},
|
|
3520
3477
|
async getIsUserCollaborator(params2) {
|
|
3521
3478
|
const { repoUrl } = params2;
|
|
@@ -3630,7 +3587,7 @@ function getBitbucketSdk(params) {
|
|
|
3630
3587
|
return GetRefererenceResultZ.parse({
|
|
3631
3588
|
sha: tagRes.data.target?.hash,
|
|
3632
3589
|
type: "TAG" /* TAG */,
|
|
3633
|
-
date: new Date(
|
|
3590
|
+
date: new Date(z8.string().parse(tagRes.data.target?.date))
|
|
3634
3591
|
});
|
|
3635
3592
|
},
|
|
3636
3593
|
async getBranchRef(params2) {
|
|
@@ -3638,7 +3595,7 @@ function getBitbucketSdk(params) {
|
|
|
3638
3595
|
return GetRefererenceResultZ.parse({
|
|
3639
3596
|
sha: getBranchRes.target?.hash,
|
|
3640
3597
|
type: "BRANCH" /* BRANCH */,
|
|
3641
|
-
date: new Date(
|
|
3598
|
+
date: new Date(z8.string().parse(getBranchRes.target?.date))
|
|
3642
3599
|
});
|
|
3643
3600
|
},
|
|
3644
3601
|
async getCommitRef(params2) {
|
|
@@ -3646,13 +3603,13 @@ function getBitbucketSdk(params) {
|
|
|
3646
3603
|
return GetRefererenceResultZ.parse({
|
|
3647
3604
|
sha: getCommitRes.hash,
|
|
3648
3605
|
type: "COMMIT" /* COMMIT */,
|
|
3649
|
-
date: new Date(
|
|
3606
|
+
date: new Date(z8.string().parse(getCommitRes.date))
|
|
3650
3607
|
});
|
|
3651
3608
|
},
|
|
3652
3609
|
async getDownloadUrl({ url, sha }) {
|
|
3653
3610
|
this.getReferenceData({ ref: sha, url });
|
|
3654
3611
|
const repoRes = await this.getRepo({ repoUrl: url });
|
|
3655
|
-
const parsedRepoUrl =
|
|
3612
|
+
const parsedRepoUrl = z8.string().url().parse(repoRes.links?.html?.href);
|
|
3656
3613
|
return `${parsedRepoUrl}/get/${sha}.zip`;
|
|
3657
3614
|
},
|
|
3658
3615
|
async getPullRequest(params2) {
|
|
@@ -3675,7 +3632,7 @@ async function validateBitbucketParams(params) {
|
|
|
3675
3632
|
if (authType !== "public") {
|
|
3676
3633
|
await bitbucketClient.getUser();
|
|
3677
3634
|
}
|
|
3678
|
-
if (params.url) {
|
|
3635
|
+
if (params.url && shouldValidateUrl(params.url)) {
|
|
3679
3636
|
await bitbucketClient.getRepo({ repoUrl: params.url });
|
|
3680
3637
|
}
|
|
3681
3638
|
} catch (e) {
|
|
@@ -3695,7 +3652,7 @@ async function validateBitbucketParams(params) {
|
|
|
3695
3652
|
}
|
|
3696
3653
|
async function getUsersworkspacesSlugs(bitbucketClient) {
|
|
3697
3654
|
const res = await bitbucketClient.workspaces.getWorkspaces({});
|
|
3698
|
-
return res.data.values?.map((v) =>
|
|
3655
|
+
return res.data.values?.map((v) => z8.string().parse(v.slug));
|
|
3699
3656
|
}
|
|
3700
3657
|
async function getllUsersrepositories(bitbucketClient) {
|
|
3701
3658
|
const userWorspacesSlugs = await getUsersworkspacesSlugs(bitbucketClient);
|
|
@@ -3727,7 +3684,7 @@ var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
|
|
|
3727
3684
|
// src/features/analysis/add_fix_comments_for_pr/utils.ts
|
|
3728
3685
|
import Debug3 from "debug";
|
|
3729
3686
|
import parseDiff2 from "parse-diff";
|
|
3730
|
-
import { z as
|
|
3687
|
+
import { z as z9 } from "zod";
|
|
3731
3688
|
|
|
3732
3689
|
// src/features/analysis/utils/by_key.ts
|
|
3733
3690
|
function keyBy(array, keyBy2) {
|
|
@@ -3958,7 +3915,7 @@ async function getRelevantVulenrabilitiesFromDiff(params) {
|
|
|
3958
3915
|
});
|
|
3959
3916
|
const lineAddedRanges = calculateRanges(fileNumbers);
|
|
3960
3917
|
const fileFilter = {
|
|
3961
|
-
path:
|
|
3918
|
+
path: z9.string().parse(file.to),
|
|
3962
3919
|
ranges: lineAddedRanges.map(([startLine, endLine]) => ({
|
|
3963
3920
|
endLine,
|
|
3964
3921
|
startLine
|
|
@@ -4265,30 +4222,30 @@ function subscribe(query, variables, callback, wsClientOptions) {
|
|
|
4265
4222
|
}
|
|
4266
4223
|
|
|
4267
4224
|
// src/features/analysis/graphql/types.ts
|
|
4268
|
-
import { z as
|
|
4269
|
-
var VulnerabilityReportIssueCodeNodeZ =
|
|
4270
|
-
vulnerabilityReportIssueId:
|
|
4271
|
-
path:
|
|
4272
|
-
startLine:
|
|
4273
|
-
vulnerabilityReportIssue:
|
|
4274
|
-
fixId:
|
|
4225
|
+
import { z as z10 } from "zod";
|
|
4226
|
+
var VulnerabilityReportIssueCodeNodeZ = z10.object({
|
|
4227
|
+
vulnerabilityReportIssueId: z10.string(),
|
|
4228
|
+
path: z10.string(),
|
|
4229
|
+
startLine: z10.number(),
|
|
4230
|
+
vulnerabilityReportIssue: z10.object({
|
|
4231
|
+
fixId: z10.string()
|
|
4275
4232
|
})
|
|
4276
4233
|
});
|
|
4277
|
-
var GetVulByNodesMetadataZ =
|
|
4278
|
-
vulnerabilityReportIssueCodeNodes:
|
|
4279
|
-
nonFixablePrVuls:
|
|
4280
|
-
aggregate:
|
|
4281
|
-
count:
|
|
4234
|
+
var GetVulByNodesMetadataZ = z10.object({
|
|
4235
|
+
vulnerabilityReportIssueCodeNodes: z10.array(VulnerabilityReportIssueCodeNodeZ),
|
|
4236
|
+
nonFixablePrVuls: z10.object({
|
|
4237
|
+
aggregate: z10.object({
|
|
4238
|
+
count: z10.number()
|
|
4282
4239
|
})
|
|
4283
4240
|
}),
|
|
4284
|
-
fixablePrVuls:
|
|
4285
|
-
aggregate:
|
|
4286
|
-
count:
|
|
4241
|
+
fixablePrVuls: z10.object({
|
|
4242
|
+
aggregate: z10.object({
|
|
4243
|
+
count: z10.number()
|
|
4287
4244
|
})
|
|
4288
4245
|
}),
|
|
4289
|
-
totalScanVulnerabilities:
|
|
4290
|
-
aggregate:
|
|
4291
|
-
count:
|
|
4246
|
+
totalScanVulnerabilities: z10.object({
|
|
4247
|
+
aggregate: z10.object({
|
|
4248
|
+
count: z10.number()
|
|
4292
4249
|
})
|
|
4293
4250
|
})
|
|
4294
4251
|
});
|
|
@@ -4383,13 +4340,12 @@ var GQLClient = class {
|
|
|
4383
4340
|
}
|
|
4384
4341
|
}
|
|
4385
4342
|
async updateScmToken(args) {
|
|
4386
|
-
const { scmType, url, token, org,
|
|
4343
|
+
const { scmType, url, token, org, refreshToken } = args;
|
|
4387
4344
|
const updateScmTokenResult = await this._clientSdk.updateScmToken({
|
|
4388
4345
|
scmType,
|
|
4389
4346
|
url,
|
|
4390
4347
|
token,
|
|
4391
4348
|
org,
|
|
4392
|
-
username,
|
|
4393
4349
|
refreshToken
|
|
4394
4350
|
});
|
|
4395
4351
|
return updateScmTokenResult;
|
|
@@ -4919,7 +4875,7 @@ async function getSnykReport(reportPath, repoRoot, { skipPrompts = false }) {
|
|
|
4919
4875
|
|
|
4920
4876
|
// src/features/analysis/upload-file.ts
|
|
4921
4877
|
import Debug11 from "debug";
|
|
4922
|
-
import
|
|
4878
|
+
import fetch3, { File, fileFrom, FormData } from "node-fetch";
|
|
4923
4879
|
var debug10 = Debug11("mobbdev:upload-file");
|
|
4924
4880
|
async function uploadFile({
|
|
4925
4881
|
file,
|
|
@@ -4944,7 +4900,7 @@ async function uploadFile({
|
|
|
4944
4900
|
debug10("upload file from buffer");
|
|
4945
4901
|
form.append("file", new File([file], "file"));
|
|
4946
4902
|
}
|
|
4947
|
-
const response = await
|
|
4903
|
+
const response = await fetch3(url, {
|
|
4948
4904
|
method: "POST",
|
|
4949
4905
|
body: form
|
|
4950
4906
|
});
|
|
@@ -4975,7 +4931,7 @@ async function downloadRepo({
|
|
|
4975
4931
|
debug11("download repo %s %s %s", repoUrl, dirname);
|
|
4976
4932
|
const zipFilePath = path6.join(dirname, "repo.zip");
|
|
4977
4933
|
debug11("download URL: %s auth headers: %o", downloadUrl, authHeaders);
|
|
4978
|
-
const response = await
|
|
4934
|
+
const response = await fetch4(downloadUrl, {
|
|
4979
4935
|
method: "GET",
|
|
4980
4936
|
headers: {
|
|
4981
4937
|
...authHeaders
|
|
@@ -5186,7 +5142,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5186
5142
|
spinner: mobbSpinner,
|
|
5187
5143
|
submitVulnerabilityReportVariables: {
|
|
5188
5144
|
fixReportId: reportUploadInfo.fixReportId,
|
|
5189
|
-
repoUrl:
|
|
5145
|
+
repoUrl: z11.string().parse(repo),
|
|
5190
5146
|
reference,
|
|
5191
5147
|
projectId,
|
|
5192
5148
|
vulnerabilityReportFileName: "report.json",
|
|
@@ -5438,9 +5394,9 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5438
5394
|
}
|
|
5439
5395
|
});
|
|
5440
5396
|
if (command === "review") {
|
|
5441
|
-
const params2 =
|
|
5442
|
-
repo:
|
|
5443
|
-
githubActionToken:
|
|
5397
|
+
const params2 = z11.object({
|
|
5398
|
+
repo: z11.string().url(),
|
|
5399
|
+
githubActionToken: z11.string()
|
|
5444
5400
|
}).parse({ repo, githubActionToken });
|
|
5445
5401
|
const scm2 = await SCMLib.init({
|
|
5446
5402
|
url: params2.repo,
|
|
@@ -5457,7 +5413,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
|
|
|
5457
5413
|
analysisId,
|
|
5458
5414
|
gqlClient,
|
|
5459
5415
|
scm: scm2,
|
|
5460
|
-
scanner:
|
|
5416
|
+
scanner: z11.nativeEnum(SCANNERS).parse(scanner)
|
|
5461
5417
|
});
|
|
5462
5418
|
},
|
|
5463
5419
|
callbackStates: ["Finished" /* Finished */]
|
|
@@ -5541,7 +5497,7 @@ var packageJson2 = JSON.parse(
|
|
|
5541
5497
|
);
|
|
5542
5498
|
var config3 = new Configstore2(packageJson2.name, { apiToken: "" });
|
|
5543
5499
|
async function addScmToken(addScmTokenOptions) {
|
|
5544
|
-
const { apiKey, token, organization, scmType, url,
|
|
5500
|
+
const { apiKey, token, organization, scmType, url, refreshToken } = addScmTokenOptions;
|
|
5545
5501
|
const gqlClient = new GQLClient({
|
|
5546
5502
|
apiKey: apiKey || config3.get("apiToken"),
|
|
5547
5503
|
type: "apiKey"
|
|
@@ -5554,7 +5510,6 @@ async function addScmToken(addScmTokenOptions) {
|
|
|
5554
5510
|
url,
|
|
5555
5511
|
token,
|
|
5556
5512
|
org: organization,
|
|
5557
|
-
username,
|
|
5558
5513
|
refreshToken
|
|
5559
5514
|
});
|
|
5560
5515
|
}
|
|
@@ -5650,10 +5605,6 @@ var scmOrgOption = {
|
|
|
5650
5605
|
describe: chalk5.bold("Organization name in SCM (used in Azure DevOps)"),
|
|
5651
5606
|
type: "string"
|
|
5652
5607
|
};
|
|
5653
|
-
var scmUsernameOption = {
|
|
5654
|
-
describe: chalk5.bold("Username in SCM (used in GitHub, Bitbucket)"),
|
|
5655
|
-
type: "string"
|
|
5656
|
-
};
|
|
5657
5608
|
var scmRefreshTokenOption = {
|
|
5658
5609
|
describe: chalk5.bold("SCM refresh token (used in GitLab)"),
|
|
5659
5610
|
type: "string"
|
|
@@ -5667,7 +5618,7 @@ var scmTokenOption = {
|
|
|
5667
5618
|
// src/args/validation.ts
|
|
5668
5619
|
import chalk6 from "chalk";
|
|
5669
5620
|
import path8 from "path";
|
|
5670
|
-
import { z as
|
|
5621
|
+
import { z as z12 } from "zod";
|
|
5671
5622
|
function throwRepoUrlErrorMessage({
|
|
5672
5623
|
error,
|
|
5673
5624
|
repoUrl,
|
|
@@ -5684,7 +5635,7 @@ Example:
|
|
|
5684
5635
|
)}`;
|
|
5685
5636
|
throw new CliError(formattedErrorMessage);
|
|
5686
5637
|
}
|
|
5687
|
-
var UrlZ =
|
|
5638
|
+
var UrlZ = z12.string({
|
|
5688
5639
|
invalid_type_error: "is not a valid GitHub / GitLab / ADO URL"
|
|
5689
5640
|
}).refine((data) => !!sanityRepoURL(data), {
|
|
5690
5641
|
message: "is not a valid GitHub / GitLab / ADO URL"
|
|
@@ -5839,15 +5790,15 @@ async function scanHandler(args) {
|
|
|
5839
5790
|
}
|
|
5840
5791
|
|
|
5841
5792
|
// src/args/commands/token.ts
|
|
5842
|
-
import { z as
|
|
5793
|
+
import { z as z13 } from "zod";
|
|
5843
5794
|
function addScmTokenBuilder(args) {
|
|
5844
|
-
return args.option("scm-type", scmTypeOption).option("url", urlOption).option("token", scmTokenOption).option("organization", scmOrgOption).option("
|
|
5795
|
+
return args.option("scm-type", scmTypeOption).option("url", urlOption).option("token", scmTokenOption).option("organization", scmOrgOption).option("refresh-token", scmRefreshTokenOption).option("api-key", apiKeyOption).example(
|
|
5845
5796
|
"$0 add-scm-token --scm-type Ado --url https://dev.azure.com/adoorg/test/_git/repo --token abcdef0123456 --organization myOrg",
|
|
5846
5797
|
"Add your SCM (Github, Gitlab, Azure DevOps) token to Mobb to enable automated fixes."
|
|
5847
5798
|
).help().demandOption(["url", "token"]);
|
|
5848
5799
|
}
|
|
5849
5800
|
function validateAddScmTokenOptions(argv) {
|
|
5850
|
-
if (!
|
|
5801
|
+
if (!z13.nativeEnum(ScmType).safeParse(argv.scmType).success) {
|
|
5851
5802
|
throw new CliError(
|
|
5852
5803
|
"\nError: --scm-type must reference a valid SCM type (GitHub, GitLab, Ado, Bitbutcket)"
|
|
5853
5804
|
);
|
|
@@ -5855,25 +5806,17 @@ function validateAddScmTokenOptions(argv) {
|
|
|
5855
5806
|
Object.values(scmValidationMap).forEach((validate) => validate(argv));
|
|
5856
5807
|
}
|
|
5857
5808
|
var scmValidationMap = {
|
|
5858
|
-
["GitHub" /* GitHub */]:
|
|
5809
|
+
["GitHub" /* GitHub */]: () => {
|
|
5810
|
+
return;
|
|
5811
|
+
},
|
|
5859
5812
|
["GitLab" /* GitLab */]: () => {
|
|
5860
5813
|
return;
|
|
5861
5814
|
},
|
|
5862
5815
|
["Ado" /* Ado */]: validateAdo,
|
|
5863
|
-
["Bitbucket" /* Bitbucket */]:
|
|
5864
|
-
|
|
5865
|
-
function validateBitbucket(argv) {
|
|
5866
|
-
const urlObj = new URL(argv.url);
|
|
5867
|
-
if (urlObj.hostname.toLowerCase() === scmCloudHostname.Bitbucket && !argv.username) {
|
|
5868
|
-
throw new CliError("\nError: --username flag is required for Bitbucket");
|
|
5869
|
-
}
|
|
5870
|
-
}
|
|
5871
|
-
function validateGithub(argv) {
|
|
5872
|
-
const urlObj = new URL(argv.url);
|
|
5873
|
-
if (urlObj.hostname.toLowerCase() === scmCloudHostname.GitHub && !argv.username) {
|
|
5874
|
-
throw new CliError("\nError: --username flag is required for GitHub");
|
|
5816
|
+
["Bitbucket" /* Bitbucket */]: () => {
|
|
5817
|
+
return;
|
|
5875
5818
|
}
|
|
5876
|
-
}
|
|
5819
|
+
};
|
|
5877
5820
|
function validateAdo(argv) {
|
|
5878
5821
|
const urlObj = new URL(argv.url);
|
|
5879
5822
|
if ((urlObj.hostname.toLowerCase() === scmCloudHostname.Ado || urlObj.hostname.toLowerCase().endsWith(".visualstudio.com")) && !argv.organization) {
|