mobbdev 0.0.148 → 0.0.155

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +1643 -1513
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -32,663 +32,174 @@ import fs4 from "node:fs";
32
32
  import path7 from "node:path";
33
33
 
34
34
  // src/constants.ts
35
- import path from "node:path";
35
+ import path2 from "node:path";
36
36
  import { fileURLToPath } from "node:url";
37
37
  import chalk from "chalk";
38
38
  import Debug from "debug";
39
39
  import * as dotenv from "dotenv";
40
- import { z } from "zod";
41
- var debug = Debug("mobbdev:constants");
42
- var __dirname = path.dirname(fileURLToPath(import.meta.url));
43
- dotenv.config({ path: path.join(__dirname, "../.env") });
44
- var ScmTypes = {
45
- Github: "GitHub",
46
- Gitlab: "GitLab",
47
- AzureDevOps: "Ado"
48
- };
49
- var SCANNERS = {
50
- Checkmarx: "checkmarx",
51
- Codeql: "codeql",
52
- Fortify: "fortify",
53
- Snyk: "snyk",
54
- Sonarqube: "sonarqube"
55
- };
56
- var SupportedScannersZ = z.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
57
- var envVariablesSchema = z.object({
58
- WEB_APP_URL: z.string(),
59
- API_URL: z.string(),
60
- HASURA_ACCESS_KEY: z.string(),
61
- LOCAL_GRAPHQL_ENDPOINT: z.string()
62
- }).required();
63
- var envVariables = envVariablesSchema.parse(process.env);
64
- debug("config %o", envVariables);
65
- var mobbAscii = `
66
- ..
67
- ..........
68
- .................
69
- ...........................
70
- ..............................
71
- ................................
72
- ..................................
73
- ....................................
74
- .....................................
75
- .............................................
76
- .................................................
77
- ............................... .................
78
- .................................. ............
79
- .................. ............. ..........
80
- ......... ........ ......... ......
81
- ............... ....
82
- .... ..
83
-
84
- . ...
85
- ..............
86
- ......................
87
- ...........................
88
- ................................
89
- ......................................
90
- ...............................
91
- .................
92
- `;
93
- var PROJECT_DEFAULT_NAME = "My first project";
94
- var WEB_APP_URL = envVariables.WEB_APP_URL;
95
- var API_URL = envVariables.API_URL;
96
- var HASURA_ACCESS_KEY = envVariables.HASURA_ACCESS_KEY;
97
- var LOCAL_GRAPHQL_ENDPOINT = envVariables.LOCAL_GRAPHQL_ENDPOINT;
98
- var errorMessages = {
99
- missingCxProjectName: `project name ${chalk.bold(
100
- "(--cx-project-name)"
101
- )} is needed if you're using checkmarx`,
102
- missingUrl: `url ${chalk.bold(
103
- "(--url)"
104
- )} is needed if you're adding an SCM token`,
105
- invalidScmType: `SCM type ${chalk.bold(
106
- "(--scm-type)"
107
- )} is invalid, please use one of: ${Object.values(ScmTypes).join(", ")}`,
108
- missingToken: `SCM token ${chalk.bold(
109
- "(--token)"
110
- )} is needed if you're adding an SCM token`
111
- };
112
- var progressMassages = {
113
- processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report proccessed successfully",
114
- processingVulnerabilityReport: "\u2699\uFE0F Proccessing vulnerability report",
115
- processingVulnerabilityReportFailed: "\u2699\uFE0F Error Proccessing vulnerability report"
40
+ import { z as z10 } from "zod";
41
+
42
+ // src/features/analysis/scm/shared/src/types.ts
43
+ var scmCloudUrl = {
44
+ GitLab: "https://gitlab.com",
45
+ GitHub: "https://github.com",
46
+ Ado: "https://dev.azure.com",
47
+ Bitbucket: "https://bitbucket.org"
116
48
  };
117
- var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 20;
49
+ var ScmType = /* @__PURE__ */ ((ScmType2) => {
50
+ ScmType2["GitHub"] = "GitHub";
51
+ ScmType2["GitLab"] = "GitLab";
52
+ ScmType2["Ado"] = "Ado";
53
+ ScmType2["Bitbucket"] = "Bitbucket";
54
+ return ScmType2;
55
+ })(ScmType || {});
118
56
 
119
- // src/features/analysis/index.ts
120
- import crypto from "node:crypto";
121
- import fs3 from "node:fs";
122
- import os from "node:os";
123
- import path6 from "node:path";
124
- import { pipeline } from "node:stream/promises";
57
+ // src/features/analysis/scm/ado/constants.ts
58
+ var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
125
59
 
126
- // src/generates/client_generates.ts
127
- var MeDocument = `
128
- query Me {
129
- me {
130
- id
131
- email
132
- scmConfigs {
133
- id
134
- orgId
135
- refreshToken
136
- scmType
137
- scmUrl
138
- scmUsername
139
- token
140
- tokenLastUpdate
141
- userId
142
- scmOrg
143
- isTokenAvailable
60
+ // src/features/analysis/scm/ado/utils.ts
61
+ import querystring3 from "node:querystring";
62
+ import * as api from "azure-devops-node-api";
63
+ import { z as z9 } from "zod";
64
+
65
+ // src/features/analysis/scm/env.ts
66
+ import { z } from "zod";
67
+ var EnvVariablesZod = z.object({
68
+ GITLAB_API_TOKEN: z.string().optional(),
69
+ BROKERED_HOSTS: z.string().toLowerCase().transform(
70
+ (x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
71
+ ).default(""),
72
+ GITHUB_API_TOKEN: z.string().optional(),
73
+ GIT_PROXY_HOST: z.string().default("http://tinyproxy:8888")
74
+ });
75
+ var { GITLAB_API_TOKEN, BROKERED_HOSTS, GITHUB_API_TOKEN, GIT_PROXY_HOST } = EnvVariablesZod.parse(process.env);
76
+
77
+ // src/features/analysis/scm/scm.ts
78
+ import { z as z7 } from "zod";
79
+
80
+ // src/features/analysis/scm/bitbucket/bitbucket.ts
81
+ import querystring from "node:querystring";
82
+ import bitbucketPkg from "bitbucket";
83
+ import * as bitbucketPkgNode from "bitbucket";
84
+ import { z as z3 } from "zod";
85
+
86
+ // src/features/analysis/scm/shared/src/urlParser/urlParser.ts
87
+ import { z as z2 } from "zod";
88
+ function detectAdoUrl(args) {
89
+ const { pathname, hostname, scmType } = args;
90
+ const hostnameParts = hostname.split(".");
91
+ const adoCloudHostname = new URL(scmCloudUrl.Ado).hostname;
92
+ const prefixPath = pathname.at(0)?.toLowerCase() === ADO_PREFIX_PATH ? ADO_PREFIX_PATH : "";
93
+ const normilizedPath = prefixPath ? pathname.slice(1) : pathname;
94
+ if (hostnameParts.length === 3 && hostnameParts[1] === "visualstudio" && hostnameParts[2] === "com") {
95
+ if (normilizedPath.length === 2 && normilizedPath[0] === "_git") {
96
+ const [_git, projectName] = normilizedPath;
97
+ const [organization] = hostnameParts;
98
+ return {
99
+ scmType: "Ado" /* Ado */,
100
+ organization,
101
+ // project has single repo - repoName === projectName
102
+ projectName: z2.string().parse(projectName),
103
+ repoName: projectName,
104
+ prefixPath
105
+ };
106
+ }
107
+ if (normilizedPath.length === 3 && normilizedPath[1] === "_git") {
108
+ const [projectName, _git, repoName] = normilizedPath;
109
+ const [organization] = hostnameParts;
110
+ return {
111
+ scmType: "Ado" /* Ado */,
112
+ organization,
113
+ projectName: z2.string().parse(projectName),
114
+ repoName,
115
+ prefixPath
116
+ };
144
117
  }
145
118
  }
146
- }
147
- `;
148
- var GetOrgAndProjectIdDocument = `
149
- query getOrgAndProjectId($filters: organization_to_organization_role_bool_exp, $limit: Int) {
150
- organization_to_organization_role(
151
- where: $filters
152
- order_by: {organization: {createdOn: desc}}
153
- limit: $limit
154
- ) {
155
- organization {
156
- id
157
- projects(order_by: {updatedAt: desc}) {
158
- id
159
- name
119
+ if (hostname === adoCloudHostname || scmType === "Ado" /* Ado */) {
120
+ if (normilizedPath[normilizedPath.length - 2] === "_git") {
121
+ if (normilizedPath.length === 3) {
122
+ const [organization, _git, repoName] = normilizedPath;
123
+ return {
124
+ scmType: "Ado" /* Ado */,
125
+ organization,
126
+ // project has only one repo - repoName === projectName
127
+ projectName: z2.string().parse(repoName),
128
+ repoName,
129
+ prefixPath
130
+ };
131
+ }
132
+ if (normilizedPath.length === 4) {
133
+ const [organization, projectName, _git, repoName] = normilizedPath;
134
+ return {
135
+ scmType: "Ado" /* Ado */,
136
+ organization,
137
+ projectName: z2.string().parse(projectName),
138
+ repoName,
139
+ prefixPath
140
+ };
160
141
  }
161
142
  }
162
143
  }
144
+ return null;
163
145
  }
164
- `;
165
- var GetEncryptedApiTokenDocument = `
166
- query GetEncryptedApiToken($loginId: uuid!) {
167
- cli_login_by_pk(id: $loginId) {
168
- encryptedApiToken
169
- }
170
- }
171
- `;
172
- var FixReportStateDocument = `
173
- query FixReportState($id: uuid!) {
174
- fixReport_by_pk(id: $id) {
175
- state
146
+ function detectGithubUrl(args) {
147
+ const { pathname, hostname, scmType } = args;
148
+ const githubHostname = new URL(scmCloudUrl.GitHub).hostname;
149
+ if (hostname === githubHostname || scmType === "GitHub" /* GitHub */) {
150
+ if (pathname.length === 2) {
151
+ return {
152
+ scmType: "GitHub" /* GitHub */,
153
+ organization: pathname[0],
154
+ repoName: pathname[1]
155
+ };
156
+ }
176
157
  }
158
+ return null;
177
159
  }
178
- `;
179
- var GetVulnerabilityReportPathsDocument = `
180
- query GetVulnerabilityReportPaths($vulnerabilityReportId: uuid!) {
181
- vulnerability_report_path(
182
- where: {vulnerabilityReportId: {_eq: $vulnerabilityReportId}}
183
- ) {
184
- path
160
+ function detectGitlabUrl(args) {
161
+ const { pathname, hostname, scmType } = args;
162
+ const gitlabHostname = new URL(scmCloudUrl.GitLab).hostname;
163
+ if (hostname === gitlabHostname || scmType === "GitLab" /* GitLab */) {
164
+ if (pathname.length >= 2) {
165
+ return {
166
+ scmType: "GitLab" /* GitLab */,
167
+ organization: pathname[0],
168
+ repoName: pathname[pathname.length - 1]
169
+ };
170
+ }
185
171
  }
172
+ return null;
186
173
  }
187
- `;
188
- var GetAnalysisDocument = `
189
- subscription getAnalysis($analysisId: uuid!) {
190
- analysis: fixReport_by_pk(id: $analysisId) {
191
- id
192
- state
174
+ function detectBitbucketUrl(args) {
175
+ const { pathname, hostname, scmType } = args;
176
+ const bitbucketHostname = new URL(scmCloudUrl.Bitbucket).hostname;
177
+ if (hostname === bitbucketHostname || scmType === "Bitbucket" /* Bitbucket */) {
178
+ if (pathname.length === 2) {
179
+ return {
180
+ scmType: "Bitbucket" /* Bitbucket */,
181
+ organization: pathname[0],
182
+ repoName: pathname[1]
183
+ };
184
+ }
193
185
  }
186
+ return null;
194
187
  }
195
- `;
196
- var GetAnalsyisDocument = `
197
- query getAnalsyis($analysisId: uuid!) {
198
- analysis: fixReport_by_pk(id: $analysisId) {
199
- id
200
- state
201
- repo {
202
- commitSha
203
- pullRequest
204
- }
205
- vulnerabilityReportId
206
- vulnerabilityReport {
207
- projectId
208
- project {
209
- organizationId
210
- }
211
- file {
212
- signedFile {
213
- url
214
- }
215
- }
188
+ var getRepoUrlFunctionMap = {
189
+ ["GitLab" /* GitLab */]: detectGitlabUrl,
190
+ ["GitHub" /* GitHub */]: detectGithubUrl,
191
+ ["Ado" /* Ado */]: detectAdoUrl,
192
+ ["Bitbucket" /* Bitbucket */]: detectBitbucketUrl
193
+ };
194
+ function getRepoInfo(args) {
195
+ for (const detectUrl of Object.values(getRepoUrlFunctionMap)) {
196
+ const detectUrlRes = detectUrl(args);
197
+ if (detectUrlRes) {
198
+ return detectUrlRes;
216
199
  }
217
200
  }
201
+ return null;
218
202
  }
219
- `;
220
- var GetFixesDocument = `
221
- query getFixes($filters: fix_bool_exp!) {
222
- fixes: fix(where: $filters) {
223
- issueType
224
- id
225
- patchAndQuestions {
226
- __typename
227
- ... on FixData {
228
- patch
229
- }
230
- }
231
- }
232
- }
233
- `;
234
- var GetVulByNodesMetadataDocument = `
235
- query getVulByNodesMetadata($filters: [vulnerability_report_issue_code_node_bool_exp!], $vulnerabilityReportId: uuid!) {
236
- vulnerabilityReportIssueCodeNodes: vulnerability_report_issue_code_node(
237
- order_by: {index: desc}
238
- where: {_or: $filters, vulnerabilityReportIssue: {fixId: {_is_null: false}, vulnerabilityReportId: {_eq: $vulnerabilityReportId}}}
239
- ) {
240
- vulnerabilityReportIssueId
241
- path
242
- startLine
243
- vulnerabilityReportIssue {
244
- issueType
245
- fixId
246
- }
247
- }
248
- fixablePrVuls: vulnerability_report_issue_aggregate(
249
- where: {fixId: {_is_null: false}, vulnerabilityReportId: {_eq: $vulnerabilityReportId}, codeNodes: {_or: $filters}}
250
- ) {
251
- aggregate {
252
- count
253
- }
254
- }
255
- nonFixablePrVuls: vulnerability_report_issue_aggregate(
256
- where: {fixId: {_is_null: true}, vulnerabilityReportId: {_eq: $vulnerabilityReportId}, codeNodes: {_or: $filters}}
257
- ) {
258
- aggregate {
259
- count
260
- }
261
- }
262
- totalScanVulnerabilities: vulnerability_report_issue_aggregate(
263
- where: {vulnerabilityReportId: {_eq: $vulnerabilityReportId}}
264
- ) {
265
- aggregate {
266
- count
267
- }
268
- }
269
- }
270
- `;
271
- var UpdateScmTokenDocument = `
272
- mutation updateScmToken($scmType: String!, $url: String!, $token: String!, $org: String, $refreshToken: String) {
273
- updateScmToken(
274
- scmType: $scmType
275
- url: $url
276
- token: $token
277
- org: $org
278
- refreshToken: $refreshToken
279
- ) {
280
- __typename
281
- ... on ScmAccessTokenUpdateSuccess {
282
- token
283
- }
284
- ... on InvalidScmTypeError {
285
- status
286
- error
287
- }
288
- ... on BadScmCredentials {
289
- status
290
- error
291
- }
292
- }
293
- }
294
- `;
295
- var UploadS3BucketInfoDocument = `
296
- mutation uploadS3BucketInfo($fileName: String!) {
297
- uploadS3BucketInfo(fileName: $fileName) {
298
- status
299
- error
300
- reportUploadInfo: uploadInfo {
301
- url
302
- fixReportId
303
- uploadFieldsJSON
304
- uploadKey
305
- }
306
- repoUploadInfo {
307
- url
308
- fixReportId
309
- uploadFieldsJSON
310
- uploadKey
311
- }
312
- }
313
- }
314
- `;
315
- var DigestVulnerabilityReportDocument = `
316
- mutation DigestVulnerabilityReport($vulnerabilityReportFileName: String!, $fixReportId: String!, $projectId: String!, $scanSource: String!) {
317
- digestVulnerabilityReport(
318
- fixReportId: $fixReportId
319
- vulnerabilityReportFileName: $vulnerabilityReportFileName
320
- projectId: $projectId
321
- scanSource: $scanSource
322
- ) {
323
- __typename
324
- ... on VulnerabilityReport {
325
- vulnerabilityReportId
326
- fixReportId
327
- }
328
- ... on RabbitSendError {
329
- status
330
- error
331
- }
332
- ... on ReportValidationError {
333
- status
334
- error
335
- }
336
- ... on ReferenceNotFoundError {
337
- status
338
- error
339
- }
340
- }
341
- }
342
- `;
343
- var SubmitVulnerabilityReportDocument = `
344
- mutation SubmitVulnerabilityReport($fixReportId: String!, $repoUrl: String!, $reference: String!, $projectId: String!, $scanSource: String!, $sha: String, $experimentalEnabled: Boolean, $vulnerabilityReportFileName: String, $pullRequest: Int) {
345
- submitVulnerabilityReport(
346
- fixReportId: $fixReportId
347
- repoUrl: $repoUrl
348
- reference: $reference
349
- sha: $sha
350
- experimentalEnabled: $experimentalEnabled
351
- pullRequest: $pullRequest
352
- projectId: $projectId
353
- vulnerabilityReportFileName: $vulnerabilityReportFileName
354
- scanSource: $scanSource
355
- ) {
356
- __typename
357
- ... on VulnerabilityReport {
358
- vulnerabilityReportId
359
- fixReportId
360
- }
361
- }
362
- }
363
- `;
364
- var CreateCommunityUserDocument = `
365
- mutation CreateCommunityUser {
366
- initOrganizationAndProject {
367
- __typename
368
- ... on InitOrganizationAndProjectGoodResponse {
369
- projectId
370
- userId
371
- organizationId
372
- }
373
- ... on UserAlreadyInProjectError {
374
- error
375
- status
376
- }
377
- }
378
- }
379
- `;
380
- var CreateCliLoginDocument = `
381
- mutation CreateCliLogin($publicKey: String!) {
382
- insert_cli_login_one(object: {publicKey: $publicKey}) {
383
- id
384
- }
385
- }
386
- `;
387
- var PerformCliLoginDocument = `
388
- mutation performCliLogin($loginId: String!) {
389
- performCliLogin(loginId: $loginId) {
390
- status
391
- }
392
- }
393
- `;
394
- var CreateProjectDocument = `
395
- mutation CreateProject($organizationId: String!, $projectName: String!) {
396
- createProject(organizationId: $organizationId, projectName: $projectName) {
397
- projectId
398
- }
399
- }
400
- `;
401
- var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
402
- function getSdk(client, withWrapper = defaultWrapper) {
403
- return {
404
- Me(variables, requestHeaders) {
405
- return withWrapper((wrappedRequestHeaders) => client.request(MeDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "Me", "query", variables);
406
- },
407
- getOrgAndProjectId(variables, requestHeaders) {
408
- return withWrapper((wrappedRequestHeaders) => client.request(GetOrgAndProjectIdDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getOrgAndProjectId", "query", variables);
409
- },
410
- GetEncryptedApiToken(variables, requestHeaders) {
411
- return withWrapper((wrappedRequestHeaders) => client.request(GetEncryptedApiTokenDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "GetEncryptedApiToken", "query", variables);
412
- },
413
- FixReportState(variables, requestHeaders) {
414
- return withWrapper((wrappedRequestHeaders) => client.request(FixReportStateDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "FixReportState", "query", variables);
415
- },
416
- GetVulnerabilityReportPaths(variables, requestHeaders) {
417
- return withWrapper((wrappedRequestHeaders) => client.request(GetVulnerabilityReportPathsDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "GetVulnerabilityReportPaths", "query", variables);
418
- },
419
- getAnalysis(variables, requestHeaders) {
420
- return withWrapper((wrappedRequestHeaders) => client.request(GetAnalysisDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getAnalysis", "subscription", variables);
421
- },
422
- getAnalsyis(variables, requestHeaders) {
423
- return withWrapper((wrappedRequestHeaders) => client.request(GetAnalsyisDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getAnalsyis", "query", variables);
424
- },
425
- getFixes(variables, requestHeaders) {
426
- return withWrapper((wrappedRequestHeaders) => client.request(GetFixesDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getFixes", "query", variables);
427
- },
428
- getVulByNodesMetadata(variables, requestHeaders) {
429
- return withWrapper((wrappedRequestHeaders) => client.request(GetVulByNodesMetadataDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getVulByNodesMetadata", "query", variables);
430
- },
431
- updateScmToken(variables, requestHeaders) {
432
- return withWrapper((wrappedRequestHeaders) => client.request(UpdateScmTokenDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "updateScmToken", "mutation", variables);
433
- },
434
- uploadS3BucketInfo(variables, requestHeaders) {
435
- return withWrapper((wrappedRequestHeaders) => client.request(UploadS3BucketInfoDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "uploadS3BucketInfo", "mutation", variables);
436
- },
437
- DigestVulnerabilityReport(variables, requestHeaders) {
438
- return withWrapper((wrappedRequestHeaders) => client.request(DigestVulnerabilityReportDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "DigestVulnerabilityReport", "mutation", variables);
439
- },
440
- SubmitVulnerabilityReport(variables, requestHeaders) {
441
- return withWrapper((wrappedRequestHeaders) => client.request(SubmitVulnerabilityReportDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "SubmitVulnerabilityReport", "mutation", variables);
442
- },
443
- CreateCommunityUser(variables, requestHeaders) {
444
- return withWrapper((wrappedRequestHeaders) => client.request(CreateCommunityUserDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "CreateCommunityUser", "mutation", variables);
445
- },
446
- CreateCliLogin(variables, requestHeaders) {
447
- return withWrapper((wrappedRequestHeaders) => client.request(CreateCliLoginDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "CreateCliLogin", "mutation", variables);
448
- },
449
- performCliLogin(variables, requestHeaders) {
450
- return withWrapper((wrappedRequestHeaders) => client.request(PerformCliLoginDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "performCliLogin", "mutation", variables);
451
- },
452
- CreateProject(variables, requestHeaders) {
453
- return withWrapper((wrappedRequestHeaders) => client.request(CreateProjectDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "CreateProject", "mutation", variables);
454
- }
455
- };
456
- }
457
-
458
- // src/utils/index.ts
459
- var utils_exports = {};
460
- __export(utils_exports, {
461
- CliError: () => CliError,
462
- Spinner: () => Spinner,
463
- getDirName: () => getDirName,
464
- getTopLevelDirName: () => getTopLevelDirName,
465
- keypress: () => keypress,
466
- sleep: () => sleep
467
- });
468
-
469
- // src/utils/dirname.ts
470
- import path2 from "node:path";
471
- import { fileURLToPath as fileURLToPath2 } from "node:url";
472
- function getDirName() {
473
- return path2.dirname(fileURLToPath2(import.meta.url));
474
- }
475
- function getTopLevelDirName(fullPath) {
476
- return path2.parse(fullPath).name;
477
- }
478
-
479
- // src/utils/keypress.ts
480
- import readline from "node:readline";
481
- async function keypress() {
482
- const rl = readline.createInterface({
483
- input: process.stdin,
484
- output: process.stdout
485
- });
486
- return new Promise((resolve) => {
487
- rl.question("", (answer) => {
488
- rl.close();
489
- process.stderr.moveCursor(0, -1);
490
- process.stderr.clearLine(1);
491
- resolve(answer);
492
- });
493
- });
494
- }
495
-
496
- // src/utils/spinner.ts
497
- import {
498
- createSpinner as _createSpinner
499
- } from "nanospinner";
500
- var mockSpinner = {
501
- success: () => mockSpinner,
502
- error: () => mockSpinner,
503
- warn: () => mockSpinner,
504
- stop: () => mockSpinner,
505
- start: () => mockSpinner,
506
- update: () => mockSpinner,
507
- reset: () => mockSpinner,
508
- clear: () => mockSpinner,
509
- spin: () => mockSpinner
510
- };
511
- function Spinner({ ci = false } = {}) {
512
- return {
513
- createSpinner: (text, options) => ci ? mockSpinner : _createSpinner(text, options)
514
- };
515
- }
516
-
517
- // src/utils/index.ts
518
- var sleep = (ms = 2e3) => new Promise((r) => setTimeout(r, ms));
519
- var CliError = class extends Error {
520
- };
521
-
522
- // src/features/analysis/index.ts
523
- import chalk4 from "chalk";
524
- import Configstore from "configstore";
525
- import Debug12 from "debug";
526
- import extract from "extract-zip";
527
- import fetch4 from "node-fetch";
528
- import open2 from "open";
529
- import semver from "semver";
530
- import tmp2 from "tmp";
531
- import { z as z12 } from "zod";
532
-
533
- // src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
534
- import Debug4 from "debug";
535
-
536
- // src/features/analysis/scm/types.ts
537
- var ReferenceType = /* @__PURE__ */ ((ReferenceType2) => {
538
- ReferenceType2["BRANCH"] = "BRANCH";
539
- ReferenceType2["COMMIT"] = "COMMIT";
540
- ReferenceType2["TAG"] = "TAG";
541
- return ReferenceType2;
542
- })(ReferenceType || {});
543
- var ScmLibScmType = /* @__PURE__ */ ((ScmLibScmType2) => {
544
- ScmLibScmType2["GITHUB"] = "GITHUB";
545
- ScmLibScmType2["GITLAB"] = "GITLAB";
546
- ScmLibScmType2["ADO"] = "ADO";
547
- ScmLibScmType2["BITBUCKET"] = "BITBUCKET";
548
- return ScmLibScmType2;
549
- })(ScmLibScmType || {});
550
- var scmCloudUrl = {
551
- GitLab: "https://gitlab.com",
552
- GitHub: "https://github.com",
553
- Ado: "https://dev.azure.com",
554
- Bitbucket: "https://bitbucket.org"
555
- };
556
- var ScmType = /* @__PURE__ */ ((ScmType2) => {
557
- ScmType2["GitHub"] = "GitHub";
558
- ScmType2["GitLab"] = "GitLab";
559
- ScmType2["Ado"] = "Ado";
560
- ScmType2["Bitbucket"] = "Bitbucket";
561
- return ScmType2;
562
- })(ScmType || {});
563
-
564
- // src/features/analysis/scm/ado/constants.ts
565
- var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
566
-
567
- // src/features/analysis/scm/ado/utils.ts
568
- import querystring3 from "node:querystring";
569
- import * as api from "azure-devops-node-api";
570
- import { z as z9 } from "zod";
571
-
572
- // src/features/analysis/scm/env.ts
573
- import { z as z2 } from "zod";
574
- var EnvVariablesZod = z2.object({
575
- GITLAB_API_TOKEN: z2.string().optional(),
576
- BROKERED_HOSTS: z2.string().toLowerCase().transform(
577
- (x) => x.split(",").map((url) => url.trim(), []).filter(Boolean)
578
- ).default(""),
579
- GITHUB_API_TOKEN: z2.string().optional(),
580
- GIT_PROXY_HOST: z2.string().default("http://tinyproxy:8888")
581
- });
582
- var { GITLAB_API_TOKEN, BROKERED_HOSTS, GITHUB_API_TOKEN, GIT_PROXY_HOST } = EnvVariablesZod.parse(process.env);
583
-
584
- // src/features/analysis/scm/scm.ts
585
- import { z as z7 } from "zod";
586
-
587
- // src/features/analysis/scm/bitbucket/bitbucket.ts
588
- import querystring from "node:querystring";
589
- import bitbucketPkg from "bitbucket";
590
- import * as bitbucketPkgNode from "bitbucket";
591
- import { z as z3 } from "zod";
592
-
593
- // src/features/analysis/scm/urlParser.ts
594
- function detectAdoUrl(args) {
595
- const { pathname, hostname, scmType } = args;
596
- const hostnameParts = hostname.split(".");
597
- const adoHostname = new URL(scmCloudUrl.Ado).hostname;
598
- if (hostnameParts.length === 3 && hostnameParts[1] === "visualstudio" && hostnameParts[2] === "com") {
599
- if (pathname.length === 2 && pathname[0] === "_git") {
600
- return {
601
- organization: hostnameParts[0],
602
- projectName: pathname[1],
603
- repoName: pathname[1]
604
- };
605
- }
606
- if (pathname.length === 3 && pathname[1] === "_git") {
607
- return {
608
- organization: hostnameParts[0],
609
- projectName: pathname[0],
610
- repoName: pathname[2]
611
- };
612
- }
613
- }
614
- if (hostname === adoHostname || scmType === "Ado" /* Ado */) {
615
- if (pathname[pathname.length - 2] === "_git") {
616
- if (pathname.length === 3) {
617
- return {
618
- organization: pathname[0],
619
- projectName: pathname[2],
620
- repoName: pathname[2]
621
- };
622
- }
623
- if (pathname.length > 3) {
624
- return {
625
- organization: pathname[pathname.length - 4],
626
- projectName: pathname[pathname.length - 3],
627
- repoName: pathname[pathname.length - 1]
628
- };
629
- }
630
- }
631
- }
632
- return null;
633
- }
634
- function detectGithubUrl(args) {
635
- const { pathname, hostname, scmType } = args;
636
- const githubHostname = new URL(scmCloudUrl.GitHub).hostname;
637
- if (hostname === githubHostname || scmType === "GitHub" /* GitHub */) {
638
- if (pathname.length === 2) {
639
- return {
640
- organization: pathname[0],
641
- projectName: void 0,
642
- repoName: pathname[1]
643
- };
644
- }
645
- }
646
- return null;
647
- }
648
- function detectGitlabUrl(args) {
649
- const { pathname, hostname, scmType } = args;
650
- const gitlabHostname = new URL(scmCloudUrl.GitLab).hostname;
651
- if (hostname === gitlabHostname || scmType === "GitLab" /* GitLab */) {
652
- if (pathname.length >= 2) {
653
- return {
654
- organization: pathname[0],
655
- projectName: void 0,
656
- repoName: pathname[pathname.length - 1]
657
- };
658
- }
659
- }
660
- return null;
661
- }
662
- function detectBitbucketUrl(args) {
663
- const { pathname, hostname, scmType } = args;
664
- const bitbucketHostname = new URL(scmCloudUrl.Bitbucket).hostname;
665
- if (hostname === bitbucketHostname || scmType === "Bitbucket" /* Bitbucket */) {
666
- if (pathname.length === 2) {
667
- return {
668
- organization: pathname[0],
669
- projectName: void 0,
670
- repoName: pathname[1]
671
- };
672
- }
673
- }
674
- return null;
675
- }
676
- var getRepoUrlFunctionMap = {
677
- ["GitLab" /* GitLab */]: detectGitlabUrl,
678
- ["GitHub" /* GitHub */]: detectGithubUrl,
679
- ["Ado" /* Ado */]: detectAdoUrl,
680
- ["Bitbucket" /* Bitbucket */]: detectBitbucketUrl
681
- };
682
- function getRepoInfo(args) {
683
- for (const detectUrl of Object.values(getRepoUrlFunctionMap)) {
684
- const detectUrlRes = detectUrl(args);
685
- if (detectUrlRes) {
686
- return detectUrlRes;
687
- }
688
- }
689
- return null;
690
- }
691
- var NAME_REGEX = /[a-z0-9\-_.+]+/i;
692
203
  var parseScmURL = (scmURL, scmType) => {
693
204
  try {
694
205
  const url = new URL(scmURL);
@@ -701,41 +212,55 @@ var parseScmURL = (scmURL, scmType) => {
701
212
  });
702
213
  if (!repo)
703
214
  return null;
704
- const { organization, repoName, projectName } = repo;
215
+ const { organization, repoName } = repo;
705
216
  if (!organization || !repoName)
706
217
  return null;
707
218
  if (!organization.match(NAME_REGEX) || !repoName.match(NAME_REGEX))
708
- return null;
709
- return {
710
- hostname,
711
- organization,
712
- projectPath,
713
- repoName,
714
- projectName,
715
- protocol: url.protocol,
716
- pathElements: projectPath.split("/")
717
- };
718
- } catch (e) {
719
- return null;
720
- }
721
- };
722
- var sanityRepoURL = (scmURL) => {
723
- try {
724
- const url = new URL(scmURL);
725
- const projectPath = url.pathname.substring(1).replace(/.git$/i, "");
726
- const pathParts = projectPath.split("/");
727
- if (pathParts.length < 2)
728
- return false;
729
- if (pathParts.length > 4)
730
- return false;
731
- if (pathParts.some((part) => !part.match(NAME_REGEX)))
732
- return false;
733
- return true;
219
+ return null;
220
+ const res = {
221
+ hostname,
222
+ organization,
223
+ projectPath,
224
+ repoName,
225
+ protocol: url.protocol,
226
+ pathElements: projectPath.split("/")
227
+ };
228
+ if (repo.scmType === "Ado" /* Ado */) {
229
+ return {
230
+ projectName: repo.projectName,
231
+ prefixPath: repo.prefixPath,
232
+ scmType: repo.scmType,
233
+ ...res
234
+ };
235
+ }
236
+ return {
237
+ scmType: repo.scmType,
238
+ ...res
239
+ };
734
240
  } catch (e) {
735
241
  return null;
736
242
  }
737
243
  };
738
244
 
245
+ // src/features/analysis/scm/shared/src/index.ts
246
+ var NAME_REGEX = /[a-z0-9\-_.+]+/i;
247
+ var ADO_PREFIX_PATH = "tfs";
248
+
249
+ // src/features/analysis/scm/types.ts
250
+ var ReferenceType = /* @__PURE__ */ ((ReferenceType2) => {
251
+ ReferenceType2["BRANCH"] = "BRANCH";
252
+ ReferenceType2["COMMIT"] = "COMMIT";
253
+ ReferenceType2["TAG"] = "TAG";
254
+ return ReferenceType2;
255
+ })(ReferenceType || {});
256
+ var ScmLibScmType = /* @__PURE__ */ ((ScmLibScmType2) => {
257
+ ScmLibScmType2["GITHUB"] = "GITHUB";
258
+ ScmLibScmType2["GITLAB"] = "GITLAB";
259
+ ScmLibScmType2["ADO"] = "ADO";
260
+ ScmLibScmType2["BITBUCKET"] = "BITBUCKET";
261
+ return ScmLibScmType2;
262
+ })(ScmLibScmType || {});
263
+
739
264
  // src/features/analysis/scm/utils/get_issue_type.ts
740
265
  var getIssueType = (issueType) => {
741
266
  switch (issueType) {
@@ -861,6 +386,8 @@ var getIssueType = (issueType) => {
861
386
  return "Value Never Read";
862
387
  case "VALUE_SHADOWING" /* ValueShadowing */:
863
388
  return "Value Shadowing";
389
+ case "ERRONEOUS_STRING_COMPARE" /* ErroneousStringCompare */:
390
+ return "Erroneous String Compare";
864
391
  default: {
865
392
  return issueType ? issueType.replaceAll("_", " ") : "Other";
866
393
  }
@@ -944,6 +471,22 @@ var isUrlHasPath = (url) => {
944
471
  function shouldValidateUrl(repoUrl) {
945
472
  return repoUrl && isUrlHasPath(repoUrl);
946
473
  }
474
+ var sanityRepoURL = (scmURL) => {
475
+ try {
476
+ const url = new URL(scmURL);
477
+ const projectPath = url.pathname.substring(1).replace(/.git$/i, "");
478
+ const pathParts = projectPath.split("/");
479
+ if (pathParts.length < 2)
480
+ return false;
481
+ if (pathParts.length > 4 && pathParts.at(0) !== ADO_PREFIX_PATH)
482
+ return false;
483
+ if (pathParts.some((part) => !part.match(NAME_REGEX)))
484
+ return false;
485
+ return true;
486
+ } catch (e) {
487
+ return null;
488
+ }
489
+ };
947
490
 
948
491
  // src/features/analysis/scm/bitbucket/bitbucket.ts
949
492
  var BITBUCKET_HOSTNAME = "bitbucket.org";
@@ -2063,7 +1606,7 @@ initGitlabFetchMock();
2063
1606
  // src/features/analysis/scm/scmSubmit/index.ts
2064
1607
  import fs from "node:fs/promises";
2065
1608
  import parseDiff from "parse-diff";
2066
- import path3 from "path";
1609
+ import path from "path";
2067
1610
  import { simpleGit } from "simple-git";
2068
1611
  import tmp from "tmp";
2069
1612
  import { z as z6 } from "zod";
@@ -2195,10 +1738,10 @@ function getCloudScmLibTypeFromUrl(url) {
2195
1738
  return void 0;
2196
1739
  }
2197
1740
  var scmCloudHostname = {
2198
- GitLab: new URL(scmCloudUrl.GitLab).hostname,
2199
- GitHub: new URL(scmCloudUrl.GitHub).hostname,
2200
- Ado: new URL(scmCloudUrl.Ado).hostname,
2201
- Bitbucket: new URL(scmCloudUrl.Bitbucket).hostname
1741
+ ["GitLab" /* GitLab */]: new URL(scmCloudUrl.GitLab).hostname,
1742
+ ["GitHub" /* GitHub */]: new URL(scmCloudUrl.GitHub).hostname,
1743
+ ["Ado" /* Ado */]: new URL(scmCloudUrl.Ado).hostname,
1744
+ ["Bitbucket" /* Bitbucket */]: new URL(scmCloudUrl.Bitbucket).hostname
2202
1745
  };
2203
1746
  var scmLibScmTypeToScmType = {
2204
1747
  ["GITLAB" /* GITLAB */]: "GitLab" /* GitLab */,
@@ -2212,10 +1755,6 @@ var scmTypeToScmLibScmType = {
2212
1755
  ["Ado" /* Ado */]: "ADO" /* ADO */,
2213
1756
  ["Bitbucket" /* Bitbucket */]: "BITBUCKET" /* BITBUCKET */
2214
1757
  };
2215
- function getScmTypeFromScmLibType(scmLibType) {
2216
- const parsedScmLibType = z7.nativeEnum(ScmLibScmType).parse(scmLibType);
2217
- return scmLibScmTypeToScmType[parsedScmLibType];
2218
- }
2219
1758
  function getScmLibTypeFromScmType(scmType) {
2220
1759
  const parsedScmType = z7.nativeEnum(ScmType).parse(scmType);
2221
1760
  return scmTypeToScmLibScmType[parsedScmType];
@@ -2271,24 +1810,6 @@ function getScmConfig({
2271
1810
  scmOrg: void 0
2272
1811
  };
2273
1812
  }
2274
- async function scmCanReachRepo({
2275
- repoUrl,
2276
- scmType,
2277
- accessToken,
2278
- scmOrg
2279
- }) {
2280
- try {
2281
- await SCMLib.init({
2282
- url: repoUrl,
2283
- accessToken,
2284
- scmType: getScmLibTypeFromScmType(scmType),
2285
- scmOrg
2286
- });
2287
- return true;
2288
- } catch (e) {
2289
- return false;
2290
- }
2291
- }
2292
1813
  var InvalidRepoUrlError = class extends Error {
2293
1814
  constructor(m) {
2294
1815
  super(m);
@@ -2407,12 +1928,7 @@ var SCMLib = class {
2407
1928
  static async getIsValidBranchName(branchName) {
2408
1929
  return isValidBranchName(branchName);
2409
1930
  }
2410
- static async init({
2411
- url,
2412
- accessToken,
2413
- scmType,
2414
- scmOrg
2415
- }) {
1931
+ static async init({ url, accessToken, scmType, scmOrg }, { propagateExceptions = false } = {}) {
2416
1932
  const trimmedUrl = url ? url.trim().replace(/\/$/, "").replace(/.git$/i, "") : void 0;
2417
1933
  try {
2418
1934
  switch (scmType) {
@@ -2428,6 +1944,7 @@ var SCMLib = class {
2428
1944
  }
2429
1945
  case "ADO" /* ADO */: {
2430
1946
  const scm = new AdoSCMLib(trimmedUrl, accessToken, scmOrg);
1947
+ await scm.getAdoSdk();
2431
1948
  await scm.validateParams();
2432
1949
  return scm;
2433
1950
  }
@@ -2445,6 +1962,9 @@ var SCMLib = class {
2445
1962
  );
2446
1963
  }
2447
1964
  console.error(`error validating scm: ${scmType} `, e);
1965
+ if (propagateExceptions) {
1966
+ throw e;
1967
+ }
2448
1968
  }
2449
1969
  return new StubSCMLib(trimmedUrl, void 0, void 0);
2450
1970
  }
@@ -2943,792 +2463,1360 @@ var GithubSCMLib = class extends SCMLib {
2943
2463
  async postGeneralPrComment(params) {
2944
2464
  const { prNumber, body } = params;
2945
2465
  this._validateAccessTokenAndUrl();
2946
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
2947
- return await this.githubSdk.postGeneralPrComment({
2948
- issue_number: prNumber,
2949
- owner,
2950
- repo,
2951
- body
2952
- });
2466
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
2467
+ return await this.githubSdk.postGeneralPrComment({
2468
+ issue_number: prNumber,
2469
+ owner,
2470
+ repo,
2471
+ body
2472
+ });
2473
+ }
2474
+ async getGeneralPrComments(params) {
2475
+ const { prNumber } = params;
2476
+ this._validateAccessTokenAndUrl();
2477
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
2478
+ return await this.githubSdk.getGeneralPrComments({
2479
+ issue_number: prNumber,
2480
+ owner,
2481
+ repo
2482
+ });
2483
+ }
2484
+ async deleteGeneralPrComment({
2485
+ commentId
2486
+ }) {
2487
+ this._validateAccessTokenAndUrl();
2488
+ const { owner, repo } = parseGithubOwnerAndRepo(this.url);
2489
+ return this.githubSdk.deleteGeneralPrComment({
2490
+ owner,
2491
+ repo,
2492
+ comment_id: commentId
2493
+ });
2494
+ }
2495
+ };
2496
+ var StubSCMLib = class extends SCMLib {
2497
+ async createSubmitRequest(_params) {
2498
+ console.error("createSubmitRequest() not implemented");
2499
+ throw new Error("createSubmitRequest() not implemented");
2500
+ }
2501
+ getScmLibType() {
2502
+ console.error("getScmLibType() not implemented");
2503
+ throw new Error("getScmLibType() not implemented");
2504
+ }
2505
+ getAuthHeaders() {
2506
+ console.error("getAuthHeaders() not implemented");
2507
+ throw new Error("getAuthHeaders() not implemented");
2508
+ }
2509
+ getDownloadUrl(_sha) {
2510
+ console.error("getDownloadUrl() not implemented");
2511
+ throw new Error("getDownloadUrl() not implemented");
2512
+ }
2513
+ async getIsRemoteBranch(_branch) {
2514
+ console.error("getIsRemoteBranch() not implemented");
2515
+ throw new Error("getIsRemoteBranch() not implemented");
2516
+ }
2517
+ async validateParams() {
2518
+ console.error("validateParams() not implemented");
2519
+ throw new Error("validateParams() not implemented");
2520
+ }
2521
+ async getRepoList(_scmOrg) {
2522
+ console.error("getRepoList() not implemented");
2523
+ throw new Error("getRepoList() not implemented");
2524
+ }
2525
+ async getBranchList() {
2526
+ console.error("getBranchList() not implemented");
2527
+ throw new Error("getBranchList() not implemented");
2528
+ }
2529
+ async getUsername() {
2530
+ console.error("getUsername() not implemented");
2531
+ throw new Error("getUsername() not implemented");
2532
+ }
2533
+ async getSubmitRequestStatus(_scmSubmitRequestId) {
2534
+ console.error("getSubmitRequestStatus() not implemented");
2535
+ throw new Error("getSubmitRequestStatus() not implemented");
2536
+ }
2537
+ async getUserHasAccessToRepo() {
2538
+ console.error("getUserHasAccessToRepo() not implemented");
2539
+ throw new Error("getUserHasAccessToRepo() not implemented");
2540
+ }
2541
+ async getRepoBlameRanges(_ref, _path) {
2542
+ console.error("getRepoBlameRanges() not implemented");
2543
+ throw new Error("getRepoBlameRanges() not implemented");
2544
+ }
2545
+ async getReferenceData(_ref) {
2546
+ console.error("getReferenceData() not implemented");
2547
+ throw new Error("getReferenceData() not implemented");
2548
+ }
2549
+ async getRepoDefaultBranch() {
2550
+ console.error("getRepoDefaultBranch() not implemented");
2551
+ throw new Error("getRepoDefaultBranch() not implemented");
2552
+ }
2553
+ async getPrUrl(_prNumber) {
2554
+ console.error("getPr() not implemented");
2555
+ throw new Error("getPr() not implemented");
2556
+ }
2557
+ _getUsernameForAuthUrl() {
2558
+ throw new Error("Method not implemented.");
2559
+ }
2560
+ };
2561
+ function getUserAndPassword(token) {
2562
+ const [username, password] = token.split(":");
2563
+ const safePasswordAndUsername = z7.object({ username: z7.string(), password: z7.string() }).parse({ username, password });
2564
+ return {
2565
+ username: safePasswordAndUsername.username,
2566
+ password: safePasswordAndUsername.password
2567
+ };
2568
+ }
2569
+ function createBitbucketSdk(token) {
2570
+ if (!token) {
2571
+ return getBitbucketSdk({ authType: "public" });
2572
+ }
2573
+ if (token.includes(":")) {
2574
+ const { password, username } = getUserAndPassword(token);
2575
+ return getBitbucketSdk({
2576
+ authType: "basic",
2577
+ username,
2578
+ password
2579
+ });
2580
+ }
2581
+ return getBitbucketSdk({ authType: "token", token });
2582
+ }
2583
+ var BitbucketSCMLib = class extends SCMLib {
2584
+ constructor(url, accessToken, scmOrg) {
2585
+ super(url, accessToken, scmOrg);
2586
+ __publicField(this, "bitbucketSdk");
2587
+ const bitbucketSdk = createBitbucketSdk(accessToken);
2588
+ this.bitbucketSdk = bitbucketSdk;
2589
+ }
2590
+ getAuthData() {
2591
+ const authType = this.bitbucketSdk.getAuthType();
2592
+ switch (authType) {
2593
+ case "basic": {
2594
+ this._validateAccessToken();
2595
+ const { username, password } = getUserAndPassword(this.accessToken);
2596
+ return { username, password, authType };
2597
+ }
2598
+ case "token": {
2599
+ return { authType, token: z7.string().parse(this.accessToken) };
2600
+ }
2601
+ case "public":
2602
+ return { authType };
2603
+ }
2604
+ }
2605
+ async createSubmitRequest(params) {
2606
+ this._validateAccessTokenAndUrl();
2607
+ const pullRequestRes = await this.bitbucketSdk.createPullRequest({
2608
+ ...params,
2609
+ repoUrl: this.url
2610
+ });
2611
+ return String(z7.number().parse(pullRequestRes.id));
2612
+ }
2613
+ async validateParams() {
2614
+ return validateBitbucketParams({
2615
+ bitbucketClient: this.bitbucketSdk,
2616
+ url: this.url
2617
+ });
2618
+ }
2619
+ async getRepoList(scmOrg) {
2620
+ this._validateAccessToken();
2621
+ return this.bitbucketSdk.getRepos({
2622
+ workspaceSlug: scmOrg
2623
+ });
2624
+ }
2625
+ async getBranchList() {
2626
+ this._validateAccessTokenAndUrl();
2627
+ return this.bitbucketSdk.getBranchList({
2628
+ repoUrl: this.url
2629
+ });
2630
+ }
2631
+ getScmLibType() {
2632
+ return "BITBUCKET" /* BITBUCKET */;
2633
+ }
2634
+ getAuthHeaders() {
2635
+ const authType = this.bitbucketSdk.getAuthType();
2636
+ switch (authType) {
2637
+ case "public":
2638
+ return {};
2639
+ case "token":
2640
+ return { authorization: `Bearer ${this.accessToken}` };
2641
+ case "basic": {
2642
+ this._validateAccessToken();
2643
+ const { username, password } = getUserAndPassword(this.accessToken);
2644
+ return {
2645
+ authorization: `Basic ${Buffer.from(
2646
+ username + ":" + password
2647
+ ).toString("base64")}`
2648
+ };
2649
+ }
2650
+ }
2651
+ }
2652
+ async getDownloadUrl(sha) {
2653
+ this._validateUrl();
2654
+ return this.bitbucketSdk.getDownloadUrl({ url: this.url, sha });
2655
+ }
2656
+ async _getUsernameForAuthUrl() {
2657
+ this._validateAccessTokenAndUrl();
2658
+ const user = await this.bitbucketSdk.getUser();
2659
+ if (!user.username) {
2660
+ throw new Error("no username found");
2661
+ }
2662
+ return user.username;
2953
2663
  }
2954
- async getGeneralPrComments(params) {
2955
- const { prNumber } = params;
2664
+ async getIsRemoteBranch(branch) {
2956
2665
  this._validateAccessTokenAndUrl();
2957
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
2958
- return await this.githubSdk.getGeneralPrComments({
2959
- issue_number: prNumber,
2960
- owner,
2961
- repo
2962
- });
2666
+ try {
2667
+ const res = await this.bitbucketSdk.getBranch({
2668
+ branchName: branch,
2669
+ repoUrl: this.url
2670
+ });
2671
+ return res.name === branch;
2672
+ } catch (e) {
2673
+ return false;
2674
+ }
2963
2675
  }
2964
- async deleteGeneralPrComment({
2965
- commentId
2966
- }) {
2676
+ async getUserHasAccessToRepo() {
2967
2677
  this._validateAccessTokenAndUrl();
2968
- const { owner, repo } = parseGithubOwnerAndRepo(this.url);
2969
- return this.githubSdk.deleteGeneralPrComment({
2970
- owner,
2971
- repo,
2972
- comment_id: commentId
2973
- });
2678
+ return this.bitbucketSdk.getIsUserCollaborator({ repoUrl: this.url });
2974
2679
  }
2975
- };
2976
- var StubSCMLib = class extends SCMLib {
2977
- async createSubmitRequest(_params) {
2978
- console.error("createSubmitRequest() not implemented");
2979
- throw new Error("createSubmitRequest() not implemented");
2680
+ async getUsername() {
2681
+ this._validateAccessToken();
2682
+ const res = await this.bitbucketSdk.getUser();
2683
+ return z7.string().parse(res.username);
2980
2684
  }
2981
- getScmLibType() {
2982
- console.error("getScmLibType() not implemented");
2983
- throw new Error("getScmLibType() not implemented");
2685
+ async getSubmitRequestStatus(_scmSubmitRequestId) {
2686
+ this._validateAccessTokenAndUrl();
2687
+ const pullRequestRes = await this.bitbucketSdk.getPullRequest({
2688
+ prNumber: Number(_scmSubmitRequestId),
2689
+ url: this.url
2690
+ });
2691
+ switch (pullRequestRes.state) {
2692
+ case "OPEN":
2693
+ return "open";
2694
+ case "MERGED":
2695
+ return "merged";
2696
+ case "DECLINED":
2697
+ return "closed";
2698
+ default:
2699
+ throw new Error(`unknown state ${pullRequestRes.state} `);
2700
+ }
2984
2701
  }
2985
- getAuthHeaders() {
2986
- console.error("getAuthHeaders() not implemented");
2987
- throw new Error("getAuthHeaders() not implemented");
2702
+ async getRepoBlameRanges(_ref, _path) {
2703
+ return [];
2988
2704
  }
2989
- getDownloadUrl(_sha) {
2990
- console.error("getDownloadUrl() not implemented");
2991
- throw new Error("getDownloadUrl() not implemented");
2705
+ async getReferenceData(ref) {
2706
+ this._validateUrl();
2707
+ return this.bitbucketSdk.getReferenceData({ url: this.url, ref });
2992
2708
  }
2993
- async getIsRemoteBranch(_branch) {
2994
- console.error("getIsRemoteBranch() not implemented");
2995
- throw new Error("getIsRemoteBranch() not implemented");
2709
+ async getRepoDefaultBranch() {
2710
+ this._validateUrl();
2711
+ const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
2712
+ return z7.string().parse(repoRes.mainbranch?.name);
2996
2713
  }
2997
- async validateParams() {
2998
- console.error("validateParams() not implemented");
2999
- throw new Error("validateParams() not implemented");
2714
+ getPrUrl(prNumber) {
2715
+ this._validateUrl();
2716
+ const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
2717
+ return Promise.resolve(
2718
+ `https://bitbucket.org/${workspace}/${repoSlug}/pull-requests/${prNumber}`
2719
+ );
3000
2720
  }
3001
- async getRepoList(_scmOrg) {
3002
- console.error("getRepoList() not implemented");
3003
- throw new Error("getRepoList() not implemented");
2721
+ async refreshToken(params) {
2722
+ const getBitbucketTokenResponse = await getBitbucketToken({
2723
+ authType: "refresh_token",
2724
+ ...params
2725
+ });
2726
+ return {
2727
+ accessToken: getBitbucketTokenResponse.access_token,
2728
+ refreshToken: getBitbucketTokenResponse.refresh_token
2729
+ };
3004
2730
  }
3005
- async getBranchList() {
3006
- console.error("getBranchList() not implemented");
3007
- throw new Error("getBranchList() not implemented");
2731
+ };
2732
+
2733
+ // src/features/analysis/scm/ado/validation.ts
2734
+ import { z as z8 } from "zod";
2735
+ var ValidPullRequestStatusZ = z8.union([
2736
+ z8.literal(1 /* Active */),
2737
+ z8.literal(2 /* Abandoned */),
2738
+ z8.literal(3 /* Completed */)
2739
+ ]);
2740
+ var AdoAuthResultZ = z8.object({
2741
+ access_token: z8.string().min(1),
2742
+ token_type: z8.string().min(1),
2743
+ refresh_token: z8.string().min(1)
2744
+ });
2745
+ var profileZ = z8.object({
2746
+ displayName: z8.string(),
2747
+ publicAlias: z8.string().min(1),
2748
+ emailAddress: z8.string(),
2749
+ coreRevision: z8.number(),
2750
+ timeStamp: z8.string(),
2751
+ id: z8.string(),
2752
+ revision: z8.number()
2753
+ });
2754
+ var accountsZ = z8.object({
2755
+ count: z8.number(),
2756
+ value: z8.array(
2757
+ z8.object({
2758
+ accountId: z8.string(),
2759
+ accountUri: z8.string(),
2760
+ accountName: z8.string()
2761
+ })
2762
+ )
2763
+ });
2764
+
2765
+ // src/features/analysis/scm/ado/utils.ts
2766
+ function _getPublicAdoClient({
2767
+ orgName,
2768
+ origin: origin2
2769
+ }) {
2770
+ const orgUrl = `${origin2}/${orgName}`;
2771
+ const authHandler = api.getPersonalAccessTokenHandler("");
2772
+ authHandler.canHandleAuthentication = () => false;
2773
+ authHandler.prepareRequest = (_options) => {
2774
+ return;
2775
+ };
2776
+ const connection = new api.WebApi(orgUrl, authHandler);
2777
+ return connection;
2778
+ }
2779
+ function removeTrailingSlash2(str) {
2780
+ return str.trim().replace(/\/+$/, "");
2781
+ }
2782
+ function parseAdoOwnerAndRepo(adoUrl) {
2783
+ adoUrl = removeTrailingSlash2(adoUrl);
2784
+ const parsingResult = parseScmURL(adoUrl, "Ado" /* Ado */);
2785
+ if (!parsingResult || parsingResult.scmType !== "Ado" /* Ado */) {
2786
+ throw new InvalidUrlPatternError(`
2787
+ : ${adoUrl}`);
3008
2788
  }
3009
- async getUsername() {
3010
- console.error("getUsername() not implemented");
3011
- throw new Error("getUsername() not implemented");
2789
+ const {
2790
+ organization,
2791
+ repoName,
2792
+ projectName,
2793
+ projectPath,
2794
+ pathElements,
2795
+ hostname,
2796
+ protocol
2797
+ } = parsingResult;
2798
+ return {
2799
+ owner: decodeURI(organization),
2800
+ repo: decodeURI(repoName),
2801
+ projectName: projectName ? decodeURI(projectName) : void 0,
2802
+ projectPath,
2803
+ pathElements,
2804
+ prefixPath: parsingResult.prefixPath,
2805
+ origin: `${protocol}//${hostname}`
2806
+ };
2807
+ }
2808
+ async function getAdoConnectData({
2809
+ url,
2810
+ tokenOrg,
2811
+ adoTokenInfo
2812
+ }) {
2813
+ if (url) {
2814
+ const urlObject = new URL(url);
2815
+ if (tokenOrg && (urlObject.origin === url || `${urlObject.origin}/tfs` === url)) {
2816
+ return {
2817
+ origin: url,
2818
+ org: tokenOrg
2819
+ };
2820
+ }
2821
+ const { owner, origin: origin2, prefixPath } = parseAdoOwnerAndRepo(url);
2822
+ return {
2823
+ org: owner,
2824
+ origin: prefixPath ? `${origin2}/${prefixPath}` : origin2
2825
+ };
3012
2826
  }
3013
- async getSubmitRequestStatus(_scmSubmitRequestId) {
3014
- console.error("getSubmitRequestStatus() not implemented");
3015
- throw new Error("getSubmitRequestStatus() not implemented");
2827
+ if (!tokenOrg) {
2828
+ if (adoTokenInfo.type === "OAUTH" /* OAUTH */) {
2829
+ const [org] = await _getOrgsForOauthToken({
2830
+ oauthToken: adoTokenInfo.accessToken
2831
+ });
2832
+ return {
2833
+ org: z9.string().parse(org),
2834
+ origin: DEFUALT_ADO_ORIGIN
2835
+ };
2836
+ }
2837
+ throw new InvalidRepoUrlError("ADO URL is null");
3016
2838
  }
3017
- async getUserHasAccessToRepo() {
3018
- console.error("getUserHasAccessToRepo() not implemented");
3019
- throw new Error("getUserHasAccessToRepo() not implemented");
2839
+ return {
2840
+ org: tokenOrg,
2841
+ origin: DEFUALT_ADO_ORIGIN
2842
+ };
2843
+ }
2844
+ function isAdoOnCloud(url) {
2845
+ const urlObj = new URL(url);
2846
+ return urlObj.origin.toLowerCase() === DEFUALT_ADO_ORIGIN || urlObj.hostname.toLowerCase().endsWith(".visualstudio.com");
2847
+ }
2848
+ async function getAdoApiClient(params) {
2849
+ const { origin: origin2 = DEFUALT_ADO_ORIGIN, orgName } = params;
2850
+ if (params.tokenType === "NONE" /* NONE */ || // note: move to public client if the token is not associated with the PAT org
2851
+ // we're only doing it the ado on the cloud
2852
+ params.tokenType === "PAT" /* PAT */ && params.patTokenOrg !== orgName && isAdoOnCloud(origin2)) {
2853
+ return _getPublicAdoClient({ orgName, origin: origin2 });
3020
2854
  }
3021
- async getRepoBlameRanges(_ref, _path) {
3022
- console.error("getRepoBlameRanges() not implemented");
3023
- throw new Error("getRepoBlameRanges() not implemented");
2855
+ const orgUrl = `${origin2}/${orgName}`;
2856
+ if (params.tokenType === "OAUTH" /* OAUTH */) {
2857
+ if (!isAdoOnCloud(origin2)) {
2858
+ throw new Error(
2859
+ `Oauth token is not supported for ADO on prem - ${origin2} `
2860
+ );
2861
+ }
2862
+ const connection2 = new api.WebApi(
2863
+ orgUrl,
2864
+ api.getBearerHandler(params.accessToken),
2865
+ {}
2866
+ );
2867
+ return connection2;
3024
2868
  }
3025
- async getReferenceData(_ref) {
3026
- console.error("getReferenceData() not implemented");
3027
- throw new Error("getReferenceData() not implemented");
2869
+ const authHandler = api.getPersonalAccessTokenHandler(params.accessToken);
2870
+ const isBroker = BROKERED_HOSTS.includes(new URL(orgUrl).origin);
2871
+ const connection = new api.WebApi(
2872
+ orgUrl,
2873
+ authHandler,
2874
+ isBroker ? {
2875
+ proxy: {
2876
+ proxyUrl: GIT_PROXY_HOST
2877
+ },
2878
+ ignoreSslError: true
2879
+ } : void 0
2880
+ );
2881
+ return connection;
2882
+ }
2883
+ function getAdoTokenInfo(token) {
2884
+ if (!token) {
2885
+ return { type: "NONE" /* NONE */ };
3028
2886
  }
3029
- async getRepoDefaultBranch() {
3030
- console.error("getRepoDefaultBranch() not implemented");
3031
- throw new Error("getRepoDefaultBranch() not implemented");
2887
+ if (token.includes(".")) {
2888
+ return { type: "OAUTH" /* OAUTH */, accessToken: token };
3032
2889
  }
3033
- async getPrUrl(_prNumber) {
3034
- console.error("getPr() not implemented");
3035
- throw new Error("getPr() not implemented");
2890
+ return { type: "PAT" /* PAT */, accessToken: token };
2891
+ }
2892
+ async function getAdoClientParams(params) {
2893
+ const { url, accessToken, tokenOrg } = params;
2894
+ const adoTokenInfo = getAdoTokenInfo(accessToken);
2895
+ const { org, origin: origin2 } = await getAdoConnectData({
2896
+ url,
2897
+ tokenOrg,
2898
+ adoTokenInfo
2899
+ });
2900
+ switch (adoTokenInfo.type) {
2901
+ case "NONE" /* NONE */:
2902
+ return {
2903
+ tokenType: "NONE" /* NONE */,
2904
+ origin: origin2,
2905
+ orgName: org.toLowerCase()
2906
+ };
2907
+ case "OAUTH" /* OAUTH */: {
2908
+ return {
2909
+ tokenType: "OAUTH" /* OAUTH */,
2910
+ accessToken: adoTokenInfo.accessToken,
2911
+ origin: origin2,
2912
+ orgName: org.toLowerCase()
2913
+ };
2914
+ }
2915
+ case "PAT" /* PAT */: {
2916
+ return {
2917
+ tokenType: "PAT" /* PAT */,
2918
+ accessToken: adoTokenInfo.accessToken,
2919
+ patTokenOrg: z9.string().parse(tokenOrg).toLowerCase(),
2920
+ origin: origin2,
2921
+ orgName: org.toLowerCase()
2922
+ };
2923
+ }
3036
2924
  }
3037
- _getUsernameForAuthUrl() {
3038
- throw new Error("Method not implemented.");
2925
+ }
2926
+ async function adoValidateParams({
2927
+ url,
2928
+ accessToken,
2929
+ tokenOrg
2930
+ }) {
2931
+ try {
2932
+ const api2 = await getAdoApiClient(
2933
+ await getAdoClientParams({ url, accessToken, tokenOrg })
2934
+ );
2935
+ await api2.connect();
2936
+ } catch (e) {
2937
+ console.log("adoValidateParams error", e);
2938
+ const error = e;
2939
+ const code = error.code || error.status || error.statusCode || error.response?.status || error.response?.statusCode || error.response?.code;
2940
+ const description = error.description || `${e}`;
2941
+ if (code === 401 || code === 403 || description.includes("401") || description.includes("403")) {
2942
+ throw new InvalidAccessTokenError(`invalid ADO access token`);
2943
+ }
2944
+ if (code === 404 || description.includes("404") || description.includes("Not Found")) {
2945
+ throw new InvalidRepoUrlError(`invalid ADO repo URL ${url}`);
2946
+ }
2947
+ throw e;
3039
2948
  }
3040
- };
3041
- function getUserAndPassword(token) {
3042
- const [username, password] = token.split(":");
3043
- const safePasswordAndUsername = z7.object({ username: z7.string(), password: z7.string() }).parse({ username, password });
2949
+ }
2950
+ async function _getOrgsForOauthToken({
2951
+ oauthToken
2952
+ }) {
2953
+ const profileRes = await fetch(
2954
+ "https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=6.0",
2955
+ {
2956
+ method: "GET",
2957
+ headers: {
2958
+ Authorization: `Bearer ${oauthToken}`
2959
+ }
2960
+ }
2961
+ );
2962
+ const profileJson = await profileRes.json();
2963
+ const profile = profileZ.parse(profileJson);
2964
+ const accountsRes = await fetch(
2965
+ `https://app.vssps.visualstudio.com/_apis/accounts?memberId=${profile.publicAlias}&api-version=6.0`,
2966
+ {
2967
+ method: "GET",
2968
+ headers: {
2969
+ Authorization: `Bearer ${oauthToken}`
2970
+ }
2971
+ }
2972
+ );
2973
+ const accountsJson = await accountsRes.json();
2974
+ const accounts = accountsZ.parse(accountsJson);
2975
+ const orgs = accounts.value.map((account) => account.accountName).filter((value, index, array) => array.indexOf(value) === index);
2976
+ return orgs;
2977
+ }
2978
+
2979
+ // src/features/analysis/scm/ado/ado.ts
2980
+ async function getAdoSdk(params) {
2981
+ const api2 = await getAdoApiClient(params);
3044
2982
  return {
3045
- username: safePasswordAndUsername.username,
3046
- password: safePasswordAndUsername.password
2983
+ async getAdoIsUserCollaborator({ repoUrl }) {
2984
+ try {
2985
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
2986
+ const git = await api2.getGitApi();
2987
+ const branches = await git.getBranches(repo, projectName);
2988
+ if (!branches || branches.length === 0) {
2989
+ throw new InvalidRepoUrlError("no branches");
2990
+ }
2991
+ return true;
2992
+ } catch (e) {
2993
+ return false;
2994
+ }
2995
+ },
2996
+ async getAdoPullRequestStatus({
2997
+ repoUrl,
2998
+ prNumber
2999
+ }) {
3000
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3001
+ const git = await api2.getGitApi();
3002
+ const res = await git.getPullRequest(repo, prNumber, projectName);
3003
+ const parsedPullRequestStatus = ValidPullRequestStatusZ.safeParse(
3004
+ res.status
3005
+ );
3006
+ if (!parsedPullRequestStatus.success) {
3007
+ throw new Error("bad pr status for ADO");
3008
+ }
3009
+ return parsedPullRequestStatus.data;
3010
+ },
3011
+ async getAdoIsRemoteBranch({
3012
+ repoUrl,
3013
+ branch
3014
+ }) {
3015
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3016
+ const git = await api2.getGitApi();
3017
+ try {
3018
+ const branchStatus = await git.getBranch(repo, branch, projectName);
3019
+ if (!branchStatus || !branchStatus.commit) {
3020
+ throw new InvalidRepoUrlError("no branch status");
3021
+ }
3022
+ return branchStatus.name === branch;
3023
+ } catch (e) {
3024
+ return false;
3025
+ }
3026
+ },
3027
+ async getAdoPrUrl({ url, prNumber }) {
3028
+ const { repo, projectName } = parseAdoOwnerAndRepo(url);
3029
+ const git = await api2.getGitApi();
3030
+ const getRepositoryRes = await git.getRepository(
3031
+ decodeURI(repo),
3032
+ projectName ? decodeURI(projectName) : void 0
3033
+ );
3034
+ return `${getRepositoryRes.webUrl}/pullrequest/${prNumber}`;
3035
+ },
3036
+ getAdoDownloadUrl({
3037
+ repoUrl,
3038
+ branch
3039
+ }) {
3040
+ const { owner, repo, projectName, prefixPath } = parseAdoOwnerAndRepo(repoUrl);
3041
+ const url = new URL(repoUrl);
3042
+ const origin2 = url.origin.toLowerCase().endsWith(".visualstudio.com") ? DEFUALT_ADO_ORIGIN : url.origin.toLowerCase();
3043
+ const params2 = `path=/&versionDescriptor[versionOptions]=0&versionDescriptor[versionType]=commit&versionDescriptor[version]=${branch}&resolveLfs=true&$format=zip&api-version=5.0&download=true`;
3044
+ const path9 = [
3045
+ prefixPath,
3046
+ owner,
3047
+ projectName,
3048
+ "_apis",
3049
+ "git",
3050
+ "repositories",
3051
+ repo,
3052
+ "items",
3053
+ "items"
3054
+ ].filter(Boolean).join("/");
3055
+ return new URL(`${path9}?${params2}`, origin2).toString();
3056
+ },
3057
+ async getAdoBranchList({ repoUrl }) {
3058
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3059
+ const git = await api2.getGitApi();
3060
+ try {
3061
+ const res = await git.getBranches(repo, projectName);
3062
+ res.sort((a, b) => {
3063
+ if (!a.commit?.committer?.date || !b.commit?.committer?.date) {
3064
+ return 0;
3065
+ }
3066
+ return b.commit?.committer?.date.getTime() - a.commit?.committer?.date.getTime();
3067
+ });
3068
+ return res.reduce((acc, branch) => {
3069
+ if (!branch.name) {
3070
+ return acc;
3071
+ }
3072
+ acc.push(branch.name);
3073
+ return acc;
3074
+ }, []);
3075
+ } catch (e) {
3076
+ return [];
3077
+ }
3078
+ },
3079
+ async createAdoPullRequest(options) {
3080
+ const { repoUrl, sourceBranchName, targetBranchName, title, body } = options;
3081
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3082
+ const git = await api2.getGitApi();
3083
+ const res = await git.createPullRequest(
3084
+ {
3085
+ sourceRefName: `refs/heads/${sourceBranchName}`,
3086
+ targetRefName: `refs/heads/${targetBranchName}`,
3087
+ title,
3088
+ description: body
3089
+ },
3090
+ repo,
3091
+ projectName
3092
+ );
3093
+ return res.pullRequestId;
3094
+ },
3095
+ async getAdoRepoDefaultBranch({
3096
+ repoUrl
3097
+ }) {
3098
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3099
+ const git = await api2.getGitApi();
3100
+ const getRepositoryRes = await git.getRepository(
3101
+ decodeURI(repo),
3102
+ projectName ? decodeURI(projectName) : void 0
3103
+ );
3104
+ if (!getRepositoryRes?.defaultBranch) {
3105
+ throw new InvalidRepoUrlError("no default branch");
3106
+ }
3107
+ return getRepositoryRes.defaultBranch.replace("refs/heads/", "");
3108
+ },
3109
+ // todo: refactor this function
3110
+ async getAdoReferenceData({
3111
+ ref,
3112
+ repoUrl
3113
+ }) {
3114
+ const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3115
+ if (!projectName) {
3116
+ throw new InvalidUrlPatternError("no project name");
3117
+ }
3118
+ const git = await api2.getGitApi();
3119
+ const results = await Promise.allSettled([
3120
+ (async () => {
3121
+ const res = await git.getBranch(repo, ref, projectName);
3122
+ if (!res.commit || !res.commit.commitId) {
3123
+ throw new InvalidRepoUrlError("no commit on branch");
3124
+ }
3125
+ return {
3126
+ sha: res.commit.commitId,
3127
+ type: "BRANCH" /* BRANCH */,
3128
+ date: res.commit.committer?.date || /* @__PURE__ */ new Date()
3129
+ };
3130
+ })(),
3131
+ (async () => {
3132
+ const res = await git.getCommits(
3133
+ repo,
3134
+ {
3135
+ fromCommitId: ref,
3136
+ toCommitId: ref,
3137
+ $top: 1
3138
+ },
3139
+ projectName
3140
+ );
3141
+ const commit = res[0];
3142
+ if (!commit || !commit.commitId) {
3143
+ throw new Error("no commit");
3144
+ }
3145
+ return {
3146
+ sha: commit.commitId,
3147
+ type: "COMMIT" /* COMMIT */,
3148
+ date: commit.committer?.date || /* @__PURE__ */ new Date()
3149
+ };
3150
+ })(),
3151
+ (async () => {
3152
+ const res = await git.getRefs(repo, projectName, `tags/${ref}`);
3153
+ if (!res[0] || !res[0].objectId) {
3154
+ throw new Error("no tag ref");
3155
+ }
3156
+ let objectId = res[0].objectId;
3157
+ try {
3158
+ const tag = await git.getAnnotatedTag(projectName, repo, objectId);
3159
+ if (tag.taggedObject?.objectId) {
3160
+ objectId = tag.taggedObject.objectId;
3161
+ }
3162
+ } catch (e) {
3163
+ }
3164
+ const commitRes2 = await git.getCommits(
3165
+ repo,
3166
+ {
3167
+ fromCommitId: objectId,
3168
+ toCommitId: objectId,
3169
+ $top: 1
3170
+ },
3171
+ projectName
3172
+ );
3173
+ const commit = commitRes2[0];
3174
+ if (!commit) {
3175
+ throw new Error("no commit");
3176
+ }
3177
+ return {
3178
+ sha: objectId,
3179
+ type: "TAG" /* TAG */,
3180
+ date: commit.committer?.date || /* @__PURE__ */ new Date()
3181
+ };
3182
+ })()
3183
+ ]);
3184
+ const [branchRes, commitRes, tagRes] = results;
3185
+ if (tagRes.status === "fulfilled") {
3186
+ return tagRes.value;
3187
+ }
3188
+ if (branchRes.status === "fulfilled") {
3189
+ return branchRes.value;
3190
+ }
3191
+ if (commitRes.status === "fulfilled") {
3192
+ return commitRes.value;
3193
+ }
3194
+ throw new RefNotFoundError(`ref: ${ref} does not exist`);
3195
+ },
3196
+ getAdoBlameRanges() {
3197
+ return [];
3198
+ }
3047
3199
  };
3048
3200
  }
3049
- function createBitbucketSdk(token) {
3050
- if (!token) {
3051
- return getBitbucketSdk({ authType: "public" });
3201
+ async function getAdoRepoList({
3202
+ orgName,
3203
+ tokenOrg,
3204
+ accessToken
3205
+ }) {
3206
+ let orgs = [];
3207
+ const adoTokenInfo = getAdoTokenInfo(accessToken);
3208
+ if (adoTokenInfo.type === "NONE" /* NONE */) {
3209
+ return [];
3052
3210
  }
3053
- if (token.includes(":")) {
3054
- const { password, username } = getUserAndPassword(token);
3055
- return getBitbucketSdk({
3056
- authType: "basic",
3057
- username,
3058
- password
3059
- });
3211
+ if (adoTokenInfo.type === "OAUTH" /* OAUTH */) {
3212
+ orgs = await _getOrgsForOauthToken({ oauthToken: accessToken });
3060
3213
  }
3061
- return getBitbucketSdk({ authType: "token", token });
3214
+ if (orgs.length === 0 && !orgName) {
3215
+ throw new Error(`no orgs for ADO`);
3216
+ } else if (orgs.length === 0 && orgName) {
3217
+ orgs = [orgName];
3218
+ }
3219
+ const repos = (await Promise.allSettled(
3220
+ orgs.map(async (org) => {
3221
+ const orgApi = await getAdoApiClient({
3222
+ ...await getAdoClientParams({
3223
+ accessToken,
3224
+ tokenOrg: tokenOrg || org,
3225
+ url: void 0
3226
+ }),
3227
+ orgName: org
3228
+ });
3229
+ const gitOrg = await orgApi.getGitApi();
3230
+ const orgRepos = await gitOrg.getRepositories();
3231
+ const repoInfoList = (await Promise.allSettled(
3232
+ orgRepos.map(async (repo) => {
3233
+ if (!repo.name || !repo.remoteUrl || !repo.defaultBranch) {
3234
+ throw new InvalidRepoUrlError("bad repo");
3235
+ }
3236
+ const branch = await gitOrg.getBranch(
3237
+ repo.name,
3238
+ repo.defaultBranch.replace(/^refs\/heads\//, ""),
3239
+ repo.project?.name
3240
+ );
3241
+ return {
3242
+ repoName: repo.name,
3243
+ repoUrl: repo.remoteUrl.replace(
3244
+ /^[hH][tT][tT][pP][sS]:\/\/[^/]+@/,
3245
+ "https://"
3246
+ ),
3247
+ repoOwner: org,
3248
+ repoIsPublic: repo.project?.visibility === 2 /* Public */,
3249
+ repoLanguages: [],
3250
+ repoUpdatedAt: branch.commit?.committer?.date?.toDateString() || repo.project?.lastUpdateTime?.toDateString() || (/* @__PURE__ */ new Date()).toDateString()
3251
+ };
3252
+ })
3253
+ )).reduce((acc, res) => {
3254
+ if (res.status === "fulfilled") {
3255
+ acc.push(res.value);
3256
+ }
3257
+ return acc;
3258
+ }, []);
3259
+ return repoInfoList;
3260
+ })
3261
+ )).reduce((acc, res) => {
3262
+ if (res.status === "fulfilled") {
3263
+ return acc.concat(res.value);
3264
+ }
3265
+ return acc;
3266
+ }, []);
3267
+ return repos;
3062
3268
  }
3063
- var BitbucketSCMLib = class extends SCMLib {
3064
- constructor(url, accessToken, scmOrg) {
3065
- super(url, accessToken, scmOrg);
3066
- __publicField(this, "bitbucketSdk");
3067
- const bitbucketSdk = createBitbucketSdk(accessToken);
3068
- this.bitbucketSdk = bitbucketSdk;
3269
+
3270
+ // src/features/analysis/scm/constants.ts
3271
+ var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
3272
+
3273
+ // src/constants.ts
3274
+ var debug = Debug("mobbdev:constants");
3275
+ var __dirname = path2.dirname(fileURLToPath(import.meta.url));
3276
+ dotenv.config({ path: path2.join(__dirname, "../.env") });
3277
+ var scmFriendlyText = {
3278
+ ["Ado" /* Ado */]: "Azure DevOps",
3279
+ ["Bitbucket" /* Bitbucket */]: "Bitbucket",
3280
+ ["GitHub" /* GitHub */]: "GitGub",
3281
+ ["GitLab" /* GitLab */]: "GitLab"
3282
+ };
3283
+ var SCANNERS = {
3284
+ Checkmarx: "checkmarx",
3285
+ Codeql: "codeql",
3286
+ Fortify: "fortify",
3287
+ Snyk: "snyk",
3288
+ Sonarqube: "sonarqube"
3289
+ };
3290
+ var SupportedScannersZ = z10.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
3291
+ var envVariablesSchema = z10.object({
3292
+ WEB_APP_URL: z10.string(),
3293
+ API_URL: z10.string(),
3294
+ HASURA_ACCESS_KEY: z10.string(),
3295
+ LOCAL_GRAPHQL_ENDPOINT: z10.string()
3296
+ }).required();
3297
+ var envVariables = envVariablesSchema.parse(process.env);
3298
+ debug("config %o", envVariables);
3299
+ var mobbAscii = `
3300
+ ..
3301
+ ..........
3302
+ .................
3303
+ ...........................
3304
+ ..............................
3305
+ ................................
3306
+ ..................................
3307
+ ....................................
3308
+ .....................................
3309
+ .............................................
3310
+ .................................................
3311
+ ............................... .................
3312
+ .................................. ............
3313
+ .................. ............. ..........
3314
+ ......... ........ ......... ......
3315
+ ............... ....
3316
+ .... ..
3317
+
3318
+ . ...
3319
+ ..............
3320
+ ......................
3321
+ ...........................
3322
+ ................................
3323
+ ......................................
3324
+ ...............................
3325
+ .................
3326
+ `;
3327
+ var PROJECT_DEFAULT_NAME = "My first project";
3328
+ var WEB_APP_URL = envVariables.WEB_APP_URL;
3329
+ var API_URL = envVariables.API_URL;
3330
+ var HASURA_ACCESS_KEY = envVariables.HASURA_ACCESS_KEY;
3331
+ var LOCAL_GRAPHQL_ENDPOINT = envVariables.LOCAL_GRAPHQL_ENDPOINT;
3332
+ var errorMessages = {
3333
+ missingCxProjectName: `project name ${chalk.bold(
3334
+ "(--cx-project-name)"
3335
+ )} is needed if you're using checkmarx`,
3336
+ missingUrl: `url ${chalk.bold(
3337
+ "(--url)"
3338
+ )} is needed if you're adding an SCM token`,
3339
+ invalidScmType: `SCM type ${chalk.bold(
3340
+ "(--scm-type)"
3341
+ )} is invalid, please use one of: ${Object.values(ScmType).join(", ")}`,
3342
+ missingToken: `SCM token ${chalk.bold(
3343
+ "(--token)"
3344
+ )} is needed if you're adding an SCM token`
3345
+ };
3346
+ var progressMassages = {
3347
+ processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report proccessed successfully",
3348
+ processingVulnerabilityReport: "\u2699\uFE0F Proccessing vulnerability report",
3349
+ processingVulnerabilityReportFailed: "\u2699\uFE0F Error Proccessing vulnerability report"
3350
+ };
3351
+ var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 20;
3352
+
3353
+ // src/features/analysis/index.ts
3354
+ import crypto from "node:crypto";
3355
+ import fs3 from "node:fs";
3356
+ import os from "node:os";
3357
+ import path6 from "node:path";
3358
+ import { pipeline } from "node:stream/promises";
3359
+
3360
+ // src/generates/client_generates.ts
3361
+ var MeDocument = `
3362
+ query Me {
3363
+ me {
3364
+ id
3365
+ email
3366
+ scmConfigs {
3367
+ id
3368
+ orgId
3369
+ refreshToken
3370
+ scmType
3371
+ scmUrl
3372
+ scmUsername
3373
+ token
3374
+ tokenLastUpdate
3375
+ userId
3376
+ scmOrg
3377
+ isTokenAvailable
3378
+ }
3069
3379
  }
3070
- getAuthData() {
3071
- const authType = this.bitbucketSdk.getAuthType();
3072
- switch (authType) {
3073
- case "basic": {
3074
- this._validateAccessToken();
3075
- const { username, password } = getUserAndPassword(this.accessToken);
3076
- return { username, password, authType };
3077
- }
3078
- case "token": {
3079
- return { authType, token: z7.string().parse(this.accessToken) };
3380
+ }
3381
+ `;
3382
+ var GetOrgAndProjectIdDocument = `
3383
+ query getOrgAndProjectId($filters: organization_to_organization_role_bool_exp, $limit: Int) {
3384
+ organization_to_organization_role(
3385
+ where: $filters
3386
+ order_by: {organization: {createdOn: desc}}
3387
+ limit: $limit
3388
+ ) {
3389
+ organization {
3390
+ id
3391
+ projects(order_by: {updatedAt: desc}) {
3392
+ id
3393
+ name
3080
3394
  }
3081
- case "public":
3082
- return { authType };
3083
3395
  }
3084
3396
  }
3085
- async createSubmitRequest(params) {
3086
- this._validateAccessTokenAndUrl();
3087
- const pullRequestRes = await this.bitbucketSdk.createPullRequest({
3088
- ...params,
3089
- repoUrl: this.url
3090
- });
3091
- return String(z7.number().parse(pullRequestRes.id));
3092
- }
3093
- async validateParams() {
3094
- return validateBitbucketParams({
3095
- bitbucketClient: this.bitbucketSdk,
3096
- url: this.url
3097
- });
3397
+ }
3398
+ `;
3399
+ var GetEncryptedApiTokenDocument = `
3400
+ query GetEncryptedApiToken($loginId: uuid!) {
3401
+ cli_login_by_pk(id: $loginId) {
3402
+ encryptedApiToken
3098
3403
  }
3099
- async getRepoList(scmOrg) {
3100
- this._validateAccessToken();
3101
- return this.bitbucketSdk.getRepos({
3102
- workspaceSlug: scmOrg
3103
- });
3404
+ }
3405
+ `;
3406
+ var FixReportStateDocument = `
3407
+ query FixReportState($id: uuid!) {
3408
+ fixReport_by_pk(id: $id) {
3409
+ state
3104
3410
  }
3105
- async getBranchList() {
3106
- this._validateAccessTokenAndUrl();
3107
- return this.bitbucketSdk.getBranchList({
3108
- repoUrl: this.url
3109
- });
3411
+ }
3412
+ `;
3413
+ var GetVulnerabilityReportPathsDocument = `
3414
+ query GetVulnerabilityReportPaths($vulnerabilityReportId: uuid!) {
3415
+ vulnerability_report_path(
3416
+ where: {vulnerabilityReportId: {_eq: $vulnerabilityReportId}}
3417
+ ) {
3418
+ path
3110
3419
  }
3111
- getScmLibType() {
3112
- return "BITBUCKET" /* BITBUCKET */;
3420
+ }
3421
+ `;
3422
+ var GetAnalysisDocument = `
3423
+ subscription getAnalysis($analysisId: uuid!) {
3424
+ analysis: fixReport_by_pk(id: $analysisId) {
3425
+ id
3426
+ state
3113
3427
  }
3114
- getAuthHeaders() {
3115
- const authType = this.bitbucketSdk.getAuthType();
3116
- switch (authType) {
3117
- case "public":
3118
- return {};
3119
- case "token":
3120
- return { authorization: `Bearer ${this.accessToken}` };
3121
- case "basic": {
3122
- this._validateAccessToken();
3123
- const { username, password } = getUserAndPassword(this.accessToken);
3124
- return {
3125
- authorization: `Basic ${Buffer.from(
3126
- username + ":" + password
3127
- ).toString("base64")}`
3128
- };
3428
+ }
3429
+ `;
3430
+ var GetAnalsyisDocument = `
3431
+ query getAnalsyis($analysisId: uuid!) {
3432
+ analysis: fixReport_by_pk(id: $analysisId) {
3433
+ id
3434
+ state
3435
+ repo {
3436
+ commitSha
3437
+ pullRequest
3438
+ }
3439
+ vulnerabilityReportId
3440
+ vulnerabilityReport {
3441
+ projectId
3442
+ project {
3443
+ organizationId
3444
+ }
3445
+ file {
3446
+ signedFile {
3447
+ url
3448
+ }
3129
3449
  }
3130
3450
  }
3131
3451
  }
3132
- async getDownloadUrl(sha) {
3133
- this._validateUrl();
3134
- return this.bitbucketSdk.getDownloadUrl({ url: this.url, sha });
3135
- }
3136
- async _getUsernameForAuthUrl() {
3137
- this._validateAccessTokenAndUrl();
3138
- const user = await this.bitbucketSdk.getUser();
3139
- if (!user.username) {
3140
- throw new Error("no username found");
3452
+ }
3453
+ `;
3454
+ var GetFixesDocument = `
3455
+ query getFixes($filters: fix_bool_exp!) {
3456
+ fixes: fix(where: $filters) {
3457
+ issueType
3458
+ id
3459
+ patchAndQuestions {
3460
+ __typename
3461
+ ... on FixData {
3462
+ patch
3463
+ }
3141
3464
  }
3142
- return user.username;
3143
3465
  }
3144
- async getIsRemoteBranch(branch) {
3145
- this._validateAccessTokenAndUrl();
3146
- try {
3147
- const res = await this.bitbucketSdk.getBranch({
3148
- branchName: branch,
3149
- repoUrl: this.url
3150
- });
3151
- return res.name === branch;
3152
- } catch (e) {
3153
- return false;
3466
+ }
3467
+ `;
3468
+ var GetVulByNodesMetadataDocument = `
3469
+ query getVulByNodesMetadata($filters: [vulnerability_report_issue_code_node_bool_exp!], $vulnerabilityReportId: uuid!) {
3470
+ vulnerabilityReportIssueCodeNodes: vulnerability_report_issue_code_node(
3471
+ order_by: {index: desc}
3472
+ where: {_or: $filters, vulnerabilityReportIssue: {fixId: {_is_null: false}, vulnerabilityReportId: {_eq: $vulnerabilityReportId}}}
3473
+ ) {
3474
+ vulnerabilityReportIssueId
3475
+ path
3476
+ startLine
3477
+ vulnerabilityReportIssue {
3478
+ issueType
3479
+ fixId
3154
3480
  }
3155
3481
  }
3156
- async getUserHasAccessToRepo() {
3157
- this._validateAccessTokenAndUrl();
3158
- return this.bitbucketSdk.getIsUserCollaborator({ repoUrl: this.url });
3159
- }
3160
- async getUsername() {
3161
- this._validateAccessToken();
3162
- const res = await this.bitbucketSdk.getUser();
3163
- return z7.string().parse(res.username);
3164
- }
3165
- async getSubmitRequestStatus(_scmSubmitRequestId) {
3166
- this._validateAccessTokenAndUrl();
3167
- const pullRequestRes = await this.bitbucketSdk.getPullRequest({
3168
- prNumber: Number(_scmSubmitRequestId),
3169
- url: this.url
3170
- });
3171
- switch (pullRequestRes.state) {
3172
- case "OPEN":
3173
- return "open";
3174
- case "MERGED":
3175
- return "merged";
3176
- case "DECLINED":
3177
- return "closed";
3178
- default:
3179
- throw new Error(`unknown state ${pullRequestRes.state} `);
3482
+ fixablePrVuls: vulnerability_report_issue_aggregate(
3483
+ where: {fixId: {_is_null: false}, vulnerabilityReportId: {_eq: $vulnerabilityReportId}, codeNodes: {_or: $filters}}
3484
+ ) {
3485
+ aggregate {
3486
+ count
3180
3487
  }
3181
3488
  }
3182
- async getRepoBlameRanges(_ref, _path) {
3183
- return [];
3184
- }
3185
- async getReferenceData(ref) {
3186
- this._validateUrl();
3187
- return this.bitbucketSdk.getReferenceData({ url: this.url, ref });
3188
- }
3189
- async getRepoDefaultBranch() {
3190
- this._validateUrl();
3191
- const repoRes = await this.bitbucketSdk.getRepo({ repoUrl: this.url });
3192
- return z7.string().parse(repoRes.mainbranch?.name);
3193
- }
3194
- getPrUrl(prNumber) {
3195
- this._validateUrl();
3196
- const { repoSlug, workspace } = parseBitbucketOrganizationAndRepo(this.url);
3197
- return Promise.resolve(
3198
- `https://bitbucket.org/${workspace}/${repoSlug}/pull-requests/${prNumber}`
3199
- );
3200
- }
3201
- async refreshToken(params) {
3202
- const getBitbucketTokenResponse = await getBitbucketToken({
3203
- authType: "refresh_token",
3204
- ...params
3205
- });
3206
- return {
3207
- accessToken: getBitbucketTokenResponse.access_token,
3208
- refreshToken: getBitbucketTokenResponse.refresh_token
3209
- };
3489
+ nonFixablePrVuls: vulnerability_report_issue_aggregate(
3490
+ where: {fixId: {_is_null: true}, vulnerabilityReportId: {_eq: $vulnerabilityReportId}, codeNodes: {_or: $filters}}
3491
+ ) {
3492
+ aggregate {
3493
+ count
3494
+ }
3495
+ }
3496
+ totalScanVulnerabilities: vulnerability_report_issue_aggregate(
3497
+ where: {vulnerabilityReportId: {_eq: $vulnerabilityReportId}}
3498
+ ) {
3499
+ aggregate {
3500
+ count
3501
+ }
3210
3502
  }
3211
- };
3212
-
3213
- // src/features/analysis/scm/ado/validation.ts
3214
- import { z as z8 } from "zod";
3215
- var ValidPullRequestStatusZ = z8.union([
3216
- z8.literal(1 /* Active */),
3217
- z8.literal(2 /* Abandoned */),
3218
- z8.literal(3 /* Completed */)
3219
- ]);
3220
- var AdoAuthResultZ = z8.object({
3221
- access_token: z8.string().min(1),
3222
- token_type: z8.string().min(1),
3223
- refresh_token: z8.string().min(1)
3224
- });
3225
- var profileZ = z8.object({
3226
- displayName: z8.string(),
3227
- publicAlias: z8.string().min(1),
3228
- emailAddress: z8.string(),
3229
- coreRevision: z8.number(),
3230
- timeStamp: z8.string(),
3231
- id: z8.string(),
3232
- revision: z8.number()
3233
- });
3234
- var accountsZ = z8.object({
3235
- count: z8.number(),
3236
- value: z8.array(
3237
- z8.object({
3238
- accountId: z8.string(),
3239
- accountUri: z8.string(),
3240
- accountName: z8.string()
3241
- })
3242
- )
3243
- });
3244
-
3245
- // src/features/analysis/scm/ado/utils.ts
3246
- function _getPublicAdoClient({
3247
- orgName,
3248
- origin: origin2
3249
- }) {
3250
- const orgUrl = `${origin2}/${orgName}`;
3251
- const authHandler = api.getPersonalAccessTokenHandler("");
3252
- authHandler.canHandleAuthentication = () => false;
3253
- authHandler.prepareRequest = (_options) => {
3254
- return;
3255
- };
3256
- const connection = new api.WebApi(orgUrl, authHandler);
3257
- return connection;
3258
- }
3259
- function removeTrailingSlash2(str) {
3260
- return str.trim().replace(/\/+$/, "");
3261
3503
  }
3262
- function parseAdoOwnerAndRepo(adoUrl) {
3263
- adoUrl = removeTrailingSlash2(adoUrl);
3264
- const parsingResult = parseScmURL(adoUrl, "Ado" /* Ado */);
3265
- if (!parsingResult) {
3266
- throw new InvalidUrlPatternError(`
3267
- : ${adoUrl}`);
3504
+ `;
3505
+ var UpdateScmTokenDocument = `
3506
+ mutation updateScmToken($scmType: String!, $url: String!, $token: String!, $org: String, $refreshToken: String) {
3507
+ updateScmToken(
3508
+ scmType: $scmType
3509
+ url: $url
3510
+ token: $token
3511
+ org: $org
3512
+ refreshToken: $refreshToken
3513
+ ) {
3514
+ __typename
3515
+ ... on ScmAccessTokenUpdateSuccess {
3516
+ token
3517
+ }
3518
+ ... on InvalidScmTypeError {
3519
+ status
3520
+ error
3521
+ }
3522
+ ... on BadScmCredentials {
3523
+ status
3524
+ error
3525
+ }
3268
3526
  }
3269
- const {
3270
- organization,
3271
- repoName,
3272
- projectName,
3273
- projectPath,
3274
- pathElements,
3275
- hostname,
3276
- protocol
3277
- } = parsingResult;
3278
- return {
3279
- owner: decodeURI(organization),
3280
- repo: decodeURI(repoName),
3281
- projectName: projectName ? decodeURI(projectName) : void 0,
3282
- projectPath,
3283
- pathElements,
3284
- origin: `${protocol}//${hostname}`
3285
- };
3286
3527
  }
3287
- async function getAdoConnectData({
3288
- url,
3289
- tokenOrg,
3290
- adoTokenInfo
3291
- }) {
3292
- if (url && new URL(url).origin !== url) {
3293
- const { owner, origin: origin2 } = parseAdoOwnerAndRepo(url);
3294
- return {
3295
- org: owner,
3296
- origin: origin2
3297
- };
3528
+ `;
3529
+ var UploadS3BucketInfoDocument = `
3530
+ mutation uploadS3BucketInfo($fileName: String!) {
3531
+ uploadS3BucketInfo(fileName: $fileName) {
3532
+ status
3533
+ error
3534
+ reportUploadInfo: uploadInfo {
3535
+ url
3536
+ fixReportId
3537
+ uploadFieldsJSON
3538
+ uploadKey
3539
+ }
3540
+ repoUploadInfo {
3541
+ url
3542
+ fixReportId
3543
+ uploadFieldsJSON
3544
+ uploadKey
3545
+ }
3298
3546
  }
3299
- if (!tokenOrg) {
3300
- if (adoTokenInfo.type === "OAUTH" /* OAUTH */) {
3301
- const [org] = await _getOrgsForOauthToken({
3302
- oauthToken: adoTokenInfo.accessToken
3303
- });
3304
- return {
3305
- org: z9.string().parse(org),
3306
- origin: DEFUALT_ADO_ORIGIN
3307
- };
3547
+ }
3548
+ `;
3549
+ var DigestVulnerabilityReportDocument = `
3550
+ mutation DigestVulnerabilityReport($vulnerabilityReportFileName: String!, $fixReportId: String!, $projectId: String!, $scanSource: String!) {
3551
+ digestVulnerabilityReport(
3552
+ fixReportId: $fixReportId
3553
+ vulnerabilityReportFileName: $vulnerabilityReportFileName
3554
+ projectId: $projectId
3555
+ scanSource: $scanSource
3556
+ ) {
3557
+ __typename
3558
+ ... on VulnerabilityReport {
3559
+ vulnerabilityReportId
3560
+ fixReportId
3561
+ }
3562
+ ... on RabbitSendError {
3563
+ status
3564
+ error
3565
+ }
3566
+ ... on ReportValidationError {
3567
+ status
3568
+ error
3569
+ }
3570
+ ... on ReferenceNotFoundError {
3571
+ status
3572
+ error
3308
3573
  }
3309
- throw new InvalidRepoUrlError("ADO URL is null");
3310
3574
  }
3311
- return {
3312
- org: tokenOrg,
3313
- origin: DEFUALT_ADO_ORIGIN
3314
- };
3315
3575
  }
3316
- async function getAdoApiClient(params) {
3317
- const { origin: origin2 = DEFUALT_ADO_ORIGIN, orgName } = params;
3318
- if (params.tokenType === "NONE" /* NONE */ || // move to public client if the token is not associated with the PAT org
3319
- params.tokenType === "PAT" /* PAT */ && params.patTokenOrg !== orgName) {
3320
- return _getPublicAdoClient({ orgName, origin: origin2 });
3576
+ `;
3577
+ var SubmitVulnerabilityReportDocument = `
3578
+ mutation SubmitVulnerabilityReport($fixReportId: String!, $repoUrl: String!, $reference: String!, $projectId: String!, $scanSource: String!, $sha: String, $experimentalEnabled: Boolean, $vulnerabilityReportFileName: String, $pullRequest: Int) {
3579
+ submitVulnerabilityReport(
3580
+ fixReportId: $fixReportId
3581
+ repoUrl: $repoUrl
3582
+ reference: $reference
3583
+ sha: $sha
3584
+ experimentalEnabled: $experimentalEnabled
3585
+ pullRequest: $pullRequest
3586
+ projectId: $projectId
3587
+ vulnerabilityReportFileName: $vulnerabilityReportFileName
3588
+ scanSource: $scanSource
3589
+ ) {
3590
+ __typename
3591
+ ... on VulnerabilityReport {
3592
+ vulnerabilityReportId
3593
+ fixReportId
3594
+ }
3321
3595
  }
3322
- const orgUrl = `${origin2}/${orgName}`;
3323
- if (params.tokenType === "OAUTH" /* OAUTH */) {
3324
- if (origin2 !== DEFUALT_ADO_ORIGIN) {
3325
- throw new Error(
3326
- `Oauth token is not supported for ADO on prem - ${origin2} `
3327
- );
3596
+ }
3597
+ `;
3598
+ var CreateCommunityUserDocument = `
3599
+ mutation CreateCommunityUser {
3600
+ initOrganizationAndProject {
3601
+ __typename
3602
+ ... on InitOrganizationAndProjectGoodResponse {
3603
+ projectId
3604
+ userId
3605
+ organizationId
3606
+ }
3607
+ ... on UserAlreadyInProjectError {
3608
+ error
3609
+ status
3328
3610
  }
3329
- const connection2 = new api.WebApi(
3330
- orgUrl,
3331
- api.getBearerHandler(params.accessToken),
3332
- {}
3333
- );
3334
- return connection2;
3335
3611
  }
3336
- const authHandler = api.getPersonalAccessTokenHandler(params.accessToken);
3337
- const isBroker = BROKERED_HOSTS.includes(new URL(orgUrl).origin);
3338
- const connection = new api.WebApi(
3339
- orgUrl,
3340
- authHandler,
3341
- isBroker ? {
3342
- proxy: {
3343
- proxyUrl: GIT_PROXY_HOST
3344
- },
3345
- ignoreSslError: true
3346
- } : void 0
3347
- );
3348
- return connection;
3349
3612
  }
3350
- function getAdoTokenInfo(token) {
3351
- if (!token) {
3352
- return { type: "NONE" /* NONE */ };
3613
+ `;
3614
+ var CreateCliLoginDocument = `
3615
+ mutation CreateCliLogin($publicKey: String!) {
3616
+ insert_cli_login_one(object: {publicKey: $publicKey}) {
3617
+ id
3353
3618
  }
3354
- if (token.includes(".")) {
3355
- return { type: "OAUTH" /* OAUTH */, accessToken: token };
3619
+ }
3620
+ `;
3621
+ var PerformCliLoginDocument = `
3622
+ mutation performCliLogin($loginId: String!) {
3623
+ performCliLogin(loginId: $loginId) {
3624
+ status
3356
3625
  }
3357
- return { type: "PAT" /* PAT */, accessToken: token };
3358
3626
  }
3359
- async function getAdoClientParams(params) {
3360
- const { url, accessToken, tokenOrg } = params;
3361
- const adoTokenInfo = getAdoTokenInfo(accessToken);
3362
- const { org, origin: origin2 } = await getAdoConnectData({
3363
- url,
3364
- tokenOrg,
3365
- adoTokenInfo
3366
- });
3367
- switch (adoTokenInfo.type) {
3368
- case "NONE" /* NONE */:
3369
- return {
3370
- tokenType: "NONE" /* NONE */,
3371
- origin: origin2,
3372
- orgName: org.toLowerCase()
3373
- };
3374
- case "OAUTH" /* OAUTH */: {
3375
- return {
3376
- tokenType: "OAUTH" /* OAUTH */,
3377
- accessToken: adoTokenInfo.accessToken,
3378
- origin: origin2,
3379
- orgName: org.toLowerCase()
3380
- };
3381
- }
3382
- case "PAT" /* PAT */: {
3383
- return {
3384
- tokenType: "PAT" /* PAT */,
3385
- accessToken: adoTokenInfo.accessToken,
3386
- patTokenOrg: z9.string().parse(tokenOrg).toLowerCase(),
3387
- origin: origin2,
3388
- orgName: org.toLowerCase()
3389
- };
3390
- }
3627
+ `;
3628
+ var CreateProjectDocument = `
3629
+ mutation CreateProject($organizationId: String!, $projectName: String!) {
3630
+ createProject(organizationId: $organizationId, projectName: $projectName) {
3631
+ projectId
3391
3632
  }
3392
3633
  }
3393
- async function adoValidateParams({
3394
- url,
3395
- accessToken,
3396
- tokenOrg
3397
- }) {
3398
- try {
3399
- const api2 = await getAdoApiClient(
3400
- await getAdoClientParams({ url, accessToken, tokenOrg })
3401
- );
3402
- await api2.connect();
3403
- } catch (e) {
3404
- console.log("adoValidateParams error", e);
3405
- const error = e;
3406
- const code = error.code || error.status || error.statusCode || error.response?.status || error.response?.statusCode || error.response?.code;
3407
- const description = error.description || `${e}`;
3408
- if (code === 401 || code === 403 || description.includes("401") || description.includes("403")) {
3409
- throw new InvalidAccessTokenError(`invalid ADO access token`);
3634
+ `;
3635
+ var ValidateRepoUrlDocument = `
3636
+ query validateRepoUrl($repoUrl: String!) {
3637
+ validateRepoUrl(repoUrl: $repoUrl) {
3638
+ __typename
3639
+ ... on RepoValidationSuccess {
3640
+ status
3641
+ defaultBranch
3642
+ defaultBranchLastModified
3643
+ defaultBranchSha
3644
+ scmType
3410
3645
  }
3411
- if (code === 404 || description.includes("404") || description.includes("Not Found")) {
3412
- throw new InvalidRepoUrlError(`invalid ADO repo URL ${url}`);
3646
+ ... on RepoUnreachableError {
3647
+ status
3648
+ error
3649
+ scmType
3650
+ }
3651
+ ... on BadScmCredentials {
3652
+ status
3653
+ error
3654
+ scmType
3413
3655
  }
3414
- throw e;
3415
3656
  }
3416
3657
  }
3417
- async function _getOrgsForOauthToken({
3418
- oauthToken
3419
- }) {
3420
- const profileRes = await fetch(
3421
- "https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=6.0",
3422
- {
3423
- method: "GET",
3424
- headers: {
3425
- Authorization: `Bearer ${oauthToken}`
3426
- }
3658
+ `;
3659
+ var GitReferenceDocument = `
3660
+ query gitReference($repoUrl: String!, $reference: String!) {
3661
+ gitReference(repoUrl: $repoUrl, reference: $reference) {
3662
+ __typename
3663
+ ... on GitReferenceData {
3664
+ status
3665
+ sha
3666
+ date
3427
3667
  }
3428
- );
3429
- const profileJson = await profileRes.json();
3430
- const profile = profileZ.parse(profileJson);
3431
- const accountsRes = await fetch(
3432
- `https://app.vssps.visualstudio.com/_apis/accounts?memberId=${profile.publicAlias}&api-version=6.0`,
3433
- {
3434
- method: "GET",
3435
- headers: {
3436
- Authorization: `Bearer ${oauthToken}`
3437
- }
3668
+ ... on ReferenceNotFoundError {
3669
+ status
3670
+ error
3438
3671
  }
3439
- );
3440
- const accountsJson = await accountsRes.json();
3441
- const accounts = accountsZ.parse(accountsJson);
3442
- const orgs = accounts.value.map((account) => account.accountName).filter((value, index, array) => array.indexOf(value) === index);
3443
- return orgs;
3672
+ }
3444
3673
  }
3445
-
3446
- // src/features/analysis/scm/ado/ado.ts
3447
- async function getAdoSdk(params) {
3448
- const api2 = await getAdoApiClient(params);
3674
+ `;
3675
+ var defaultWrapper = (action, _operationName, _operationType, _variables) => action();
3676
+ function getSdk(client, withWrapper = defaultWrapper) {
3449
3677
  return {
3450
- async getAdoIsUserCollaborator({ repoUrl }) {
3451
- try {
3452
- const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3453
- const git = await api2.getGitApi();
3454
- const branches = await git.getBranches(repo, projectName);
3455
- if (!branches || branches.length === 0) {
3456
- throw new InvalidRepoUrlError("no branches");
3457
- }
3458
- return true;
3459
- } catch (e) {
3460
- return false;
3461
- }
3678
+ Me(variables, requestHeaders) {
3679
+ return withWrapper((wrappedRequestHeaders) => client.request(MeDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "Me", "query", variables);
3462
3680
  },
3463
- async getAdoPullRequestStatus({
3464
- repoUrl,
3465
- prNumber
3466
- }) {
3467
- const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3468
- const git = await api2.getGitApi();
3469
- const res = await git.getPullRequest(repo, prNumber, projectName);
3470
- const parsedPullRequestStatus = ValidPullRequestStatusZ.safeParse(
3471
- res.status
3472
- );
3473
- if (!parsedPullRequestStatus.success) {
3474
- throw new Error("bad pr status for ADO");
3475
- }
3476
- return parsedPullRequestStatus.data;
3681
+ getOrgAndProjectId(variables, requestHeaders) {
3682
+ return withWrapper((wrappedRequestHeaders) => client.request(GetOrgAndProjectIdDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getOrgAndProjectId", "query", variables);
3477
3683
  },
3478
- async getAdoIsRemoteBranch({
3479
- repoUrl,
3480
- branch
3481
- }) {
3482
- const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3483
- const git = await api2.getGitApi();
3484
- try {
3485
- const branchStatus = await git.getBranch(repo, branch, projectName);
3486
- if (!branchStatus || !branchStatus.commit) {
3487
- throw new InvalidRepoUrlError("no branch status");
3488
- }
3489
- return branchStatus.name === branch;
3490
- } catch (e) {
3491
- return false;
3492
- }
3684
+ GetEncryptedApiToken(variables, requestHeaders) {
3685
+ return withWrapper((wrappedRequestHeaders) => client.request(GetEncryptedApiTokenDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "GetEncryptedApiToken", "query", variables);
3493
3686
  },
3494
- async getAdoPrUrl({ url, prNumber }) {
3495
- const { repo, projectName } = parseAdoOwnerAndRepo(url);
3496
- const git = await api2.getGitApi();
3497
- const getRepositoryRes = await git.getRepository(
3498
- decodeURI(repo),
3499
- projectName ? decodeURI(projectName) : void 0
3500
- );
3501
- return `${getRepositoryRes.webUrl}/pullrequest/${prNumber}`;
3687
+ FixReportState(variables, requestHeaders) {
3688
+ return withWrapper((wrappedRequestHeaders) => client.request(FixReportStateDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "FixReportState", "query", variables);
3502
3689
  },
3503
- getAdoDownloadUrl({
3504
- repoUrl,
3505
- branch
3506
- }) {
3507
- const { owner, repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3508
- const url = new URL(repoUrl);
3509
- const origin2 = url.origin.toLowerCase().endsWith(".visualstudio.com") ? DEFUALT_ADO_ORIGIN : url.origin.toLowerCase();
3510
- return `${origin2}/${owner}/${projectName}/_apis/git/repositories/${repo}/items/items?path=/&versionDescriptor[versionOptions]=0&versionDescriptor[versionType]=commit&versionDescriptor[version]=${branch}&resolveLfs=true&$format=zip&api-version=5.0&download=true`;
3690
+ GetVulnerabilityReportPaths(variables, requestHeaders) {
3691
+ return withWrapper((wrappedRequestHeaders) => client.request(GetVulnerabilityReportPathsDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "GetVulnerabilityReportPaths", "query", variables);
3511
3692
  },
3512
- async getAdoBranchList({ repoUrl }) {
3513
- const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3514
- const git = await api2.getGitApi();
3515
- try {
3516
- const res = await git.getBranches(repo, projectName);
3517
- res.sort((a, b) => {
3518
- if (!a.commit?.committer?.date || !b.commit?.committer?.date) {
3519
- return 0;
3520
- }
3521
- return b.commit?.committer?.date.getTime() - a.commit?.committer?.date.getTime();
3522
- });
3523
- return res.reduce((acc, branch) => {
3524
- if (!branch.name) {
3525
- return acc;
3526
- }
3527
- acc.push(branch.name);
3528
- return acc;
3529
- }, []);
3530
- } catch (e) {
3531
- return [];
3532
- }
3693
+ getAnalysis(variables, requestHeaders) {
3694
+ return withWrapper((wrappedRequestHeaders) => client.request(GetAnalysisDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getAnalysis", "subscription", variables);
3533
3695
  },
3534
- async createAdoPullRequest(options) {
3535
- const { repoUrl, sourceBranchName, targetBranchName, title, body } = options;
3536
- const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3537
- const git = await api2.getGitApi();
3538
- const res = await git.createPullRequest(
3539
- {
3540
- sourceRefName: `refs/heads/${sourceBranchName}`,
3541
- targetRefName: `refs/heads/${targetBranchName}`,
3542
- title,
3543
- description: body
3544
- },
3545
- repo,
3546
- projectName
3547
- );
3548
- return res.pullRequestId;
3696
+ getAnalsyis(variables, requestHeaders) {
3697
+ return withWrapper((wrappedRequestHeaders) => client.request(GetAnalsyisDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getAnalsyis", "query", variables);
3549
3698
  },
3550
- async getAdoRepoDefaultBranch({
3551
- repoUrl
3552
- }) {
3553
- const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3554
- const git = await api2.getGitApi();
3555
- const getRepositoryRes = await git.getRepository(
3556
- decodeURI(repo),
3557
- projectName ? decodeURI(projectName) : void 0
3558
- );
3559
- if (!getRepositoryRes?.defaultBranch) {
3560
- throw new InvalidRepoUrlError("no default branch");
3561
- }
3562
- return getRepositoryRes.defaultBranch.replace("refs/heads/", "");
3699
+ getFixes(variables, requestHeaders) {
3700
+ return withWrapper((wrappedRequestHeaders) => client.request(GetFixesDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getFixes", "query", variables);
3563
3701
  },
3564
- // todo: refactor this function
3565
- async getAdoReferenceData({
3566
- ref,
3567
- repoUrl
3568
- }) {
3569
- const { repo, projectName } = parseAdoOwnerAndRepo(repoUrl);
3570
- if (!projectName) {
3571
- throw new InvalidUrlPatternError("no project name");
3572
- }
3573
- const git = await api2.getGitApi();
3574
- const results = await Promise.allSettled([
3575
- (async () => {
3576
- const res = await git.getBranch(repo, ref, projectName);
3577
- if (!res.commit || !res.commit.commitId) {
3578
- throw new InvalidRepoUrlError("no commit on branch");
3579
- }
3580
- return {
3581
- sha: res.commit.commitId,
3582
- type: "BRANCH" /* BRANCH */,
3583
- date: res.commit.committer?.date || /* @__PURE__ */ new Date()
3584
- };
3585
- })(),
3586
- (async () => {
3587
- const res = await git.getCommits(
3588
- repo,
3589
- {
3590
- fromCommitId: ref,
3591
- toCommitId: ref,
3592
- $top: 1
3593
- },
3594
- projectName
3595
- );
3596
- const commit = res[0];
3597
- if (!commit || !commit.commitId) {
3598
- throw new Error("no commit");
3599
- }
3600
- return {
3601
- sha: commit.commitId,
3602
- type: "COMMIT" /* COMMIT */,
3603
- date: commit.committer?.date || /* @__PURE__ */ new Date()
3604
- };
3605
- })(),
3606
- (async () => {
3607
- const res = await git.getRefs(repo, projectName, `tags/${ref}`);
3608
- if (!res[0] || !res[0].objectId) {
3609
- throw new Error("no tag ref");
3610
- }
3611
- let objectId = res[0].objectId;
3612
- try {
3613
- const tag = await git.getAnnotatedTag(projectName, repo, objectId);
3614
- if (tag.taggedObject?.objectId) {
3615
- objectId = tag.taggedObject.objectId;
3616
- }
3617
- } catch (e) {
3618
- }
3619
- const commitRes2 = await git.getCommits(
3620
- repo,
3621
- {
3622
- fromCommitId: objectId,
3623
- toCommitId: objectId,
3624
- $top: 1
3625
- },
3626
- projectName
3627
- );
3628
- const commit = commitRes2[0];
3629
- if (!commit) {
3630
- throw new Error("no commit");
3631
- }
3632
- return {
3633
- sha: objectId,
3634
- type: "TAG" /* TAG */,
3635
- date: commit.committer?.date || /* @__PURE__ */ new Date()
3636
- };
3637
- })()
3638
- ]);
3639
- const [branchRes, commitRes, tagRes] = results;
3640
- if (tagRes.status === "fulfilled") {
3641
- return tagRes.value;
3642
- }
3643
- if (branchRes.status === "fulfilled") {
3644
- return branchRes.value;
3645
- }
3646
- if (commitRes.status === "fulfilled") {
3647
- return commitRes.value;
3648
- }
3649
- throw new RefNotFoundError(`ref: ${ref} does not exist`);
3702
+ getVulByNodesMetadata(variables, requestHeaders) {
3703
+ return withWrapper((wrappedRequestHeaders) => client.request(GetVulByNodesMetadataDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "getVulByNodesMetadata", "query", variables);
3704
+ },
3705
+ updateScmToken(variables, requestHeaders) {
3706
+ return withWrapper((wrappedRequestHeaders) => client.request(UpdateScmTokenDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "updateScmToken", "mutation", variables);
3650
3707
  },
3651
- getAdoBlameRanges() {
3652
- return [];
3708
+ uploadS3BucketInfo(variables, requestHeaders) {
3709
+ return withWrapper((wrappedRequestHeaders) => client.request(UploadS3BucketInfoDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "uploadS3BucketInfo", "mutation", variables);
3710
+ },
3711
+ DigestVulnerabilityReport(variables, requestHeaders) {
3712
+ return withWrapper((wrappedRequestHeaders) => client.request(DigestVulnerabilityReportDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "DigestVulnerabilityReport", "mutation", variables);
3713
+ },
3714
+ SubmitVulnerabilityReport(variables, requestHeaders) {
3715
+ return withWrapper((wrappedRequestHeaders) => client.request(SubmitVulnerabilityReportDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "SubmitVulnerabilityReport", "mutation", variables);
3716
+ },
3717
+ CreateCommunityUser(variables, requestHeaders) {
3718
+ return withWrapper((wrappedRequestHeaders) => client.request(CreateCommunityUserDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "CreateCommunityUser", "mutation", variables);
3719
+ },
3720
+ CreateCliLogin(variables, requestHeaders) {
3721
+ return withWrapper((wrappedRequestHeaders) => client.request(CreateCliLoginDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "CreateCliLogin", "mutation", variables);
3722
+ },
3723
+ performCliLogin(variables, requestHeaders) {
3724
+ return withWrapper((wrappedRequestHeaders) => client.request(PerformCliLoginDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "performCliLogin", "mutation", variables);
3725
+ },
3726
+ CreateProject(variables, requestHeaders) {
3727
+ return withWrapper((wrappedRequestHeaders) => client.request(CreateProjectDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "CreateProject", "mutation", variables);
3728
+ },
3729
+ validateRepoUrl(variables, requestHeaders) {
3730
+ return withWrapper((wrappedRequestHeaders) => client.request(ValidateRepoUrlDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "validateRepoUrl", "query", variables);
3731
+ },
3732
+ gitReference(variables, requestHeaders) {
3733
+ return withWrapper((wrappedRequestHeaders) => client.request(GitReferenceDocument, variables, { ...requestHeaders, ...wrappedRequestHeaders }), "gitReference", "query", variables);
3653
3734
  }
3654
3735
  };
3655
3736
  }
3656
- async function getAdoRepoList({
3657
- orgName,
3658
- tokenOrg,
3659
- accessToken
3660
- }) {
3661
- let orgs = [];
3662
- const adoTokenInfo = getAdoTokenInfo(accessToken);
3663
- if (adoTokenInfo.type === "NONE" /* NONE */) {
3664
- return [];
3665
- }
3666
- if (adoTokenInfo.type === "OAUTH" /* OAUTH */) {
3667
- orgs = await _getOrgsForOauthToken({ oauthToken: accessToken });
3668
- }
3669
- if (orgs.length === 0 && !orgName) {
3670
- throw new Error(`no orgs for ADO`);
3671
- } else if (orgs.length === 0 && orgName) {
3672
- orgs = [orgName];
3673
- }
3674
- const repos = (await Promise.allSettled(
3675
- orgs.map(async (org) => {
3676
- const orgApi = await getAdoApiClient({
3677
- ...await getAdoClientParams({
3678
- accessToken,
3679
- tokenOrg: tokenOrg || org,
3680
- url: void 0
3681
- }),
3682
- orgName: org
3683
- });
3684
- const gitOrg = await orgApi.getGitApi();
3685
- const orgRepos = await gitOrg.getRepositories();
3686
- const repoInfoList = (await Promise.allSettled(
3687
- orgRepos.map(async (repo) => {
3688
- if (!repo.name || !repo.remoteUrl || !repo.defaultBranch) {
3689
- throw new InvalidRepoUrlError("bad repo");
3690
- }
3691
- const branch = await gitOrg.getBranch(
3692
- repo.name,
3693
- repo.defaultBranch.replace(/^refs\/heads\//, ""),
3694
- repo.project?.name
3695
- );
3696
- return {
3697
- repoName: repo.name,
3698
- repoUrl: repo.remoteUrl.replace(
3699
- /^[hH][tT][tT][pP][sS]:\/\/[^/]+@/,
3700
- "https://"
3701
- ),
3702
- repoOwner: org,
3703
- repoIsPublic: repo.project?.visibility === 2 /* Public */,
3704
- repoLanguages: [],
3705
- repoUpdatedAt: branch.commit?.committer?.date?.toDateString() || repo.project?.lastUpdateTime?.toDateString() || (/* @__PURE__ */ new Date()).toDateString()
3706
- };
3707
- })
3708
- )).reduce((acc, res) => {
3709
- if (res.status === "fulfilled") {
3710
- acc.push(res.value);
3711
- }
3712
- return acc;
3713
- }, []);
3714
- return repoInfoList;
3715
- })
3716
- )).reduce((acc, res) => {
3717
- if (res.status === "fulfilled") {
3718
- return acc.concat(res.value);
3719
- }
3720
- return acc;
3721
- }, []);
3722
- return repos;
3737
+
3738
+ // src/utils/index.ts
3739
+ var utils_exports = {};
3740
+ __export(utils_exports, {
3741
+ CliError: () => CliError,
3742
+ Spinner: () => Spinner,
3743
+ getDirName: () => getDirName,
3744
+ getTopLevelDirName: () => getTopLevelDirName,
3745
+ keypress: () => keypress,
3746
+ sleep: () => sleep
3747
+ });
3748
+
3749
+ // src/utils/dirname.ts
3750
+ import path3 from "node:path";
3751
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
3752
+ function getDirName() {
3753
+ return path3.dirname(fileURLToPath2(import.meta.url));
3754
+ }
3755
+ function getTopLevelDirName(fullPath) {
3756
+ return path3.parse(fullPath).name;
3723
3757
  }
3724
3758
 
3725
- // src/features/analysis/scm/constants.ts
3726
- var MOBB_ICON_IMG = "https://app.mobb.ai/gh-action/Logo_Rounded_Icon.svg";
3759
+ // src/utils/keypress.ts
3760
+ import readline from "node:readline";
3761
+ async function keypress() {
3762
+ const rl = readline.createInterface({
3763
+ input: process.stdin,
3764
+ output: process.stdout
3765
+ });
3766
+ return new Promise((resolve) => {
3767
+ rl.question("", (answer) => {
3768
+ rl.close();
3769
+ process.stderr.moveCursor(0, -1);
3770
+ process.stderr.clearLine(1);
3771
+ resolve(answer);
3772
+ });
3773
+ });
3774
+ }
3775
+
3776
+ // src/utils/spinner.ts
3777
+ import {
3778
+ createSpinner as _createSpinner
3779
+ } from "nanospinner";
3780
+ var mockSpinner = {
3781
+ success: () => mockSpinner,
3782
+ error: () => mockSpinner,
3783
+ warn: () => mockSpinner,
3784
+ stop: () => mockSpinner,
3785
+ start: () => mockSpinner,
3786
+ update: () => mockSpinner,
3787
+ reset: () => mockSpinner,
3788
+ clear: () => mockSpinner,
3789
+ spin: () => mockSpinner
3790
+ };
3791
+ function Spinner({ ci = false } = {}) {
3792
+ return {
3793
+ createSpinner: (text, options) => ci ? mockSpinner : _createSpinner(text, options)
3794
+ };
3795
+ }
3796
+
3797
+ // src/utils/index.ts
3798
+ var sleep = (ms = 2e3) => new Promise((r) => setTimeout(r, ms));
3799
+ var CliError = class extends Error {
3800
+ };
3801
+
3802
+ // src/features/analysis/index.ts
3803
+ import chalk4 from "chalk";
3804
+ import Configstore from "configstore";
3805
+ import Debug12 from "debug";
3806
+ import extract from "extract-zip";
3807
+ import fetch4 from "node-fetch";
3808
+ import open2 from "open";
3809
+ import semver from "semver";
3810
+ import tmp2 from "tmp";
3811
+ import { z as z13 } from "zod";
3812
+
3813
+ // src/features/analysis/add_fix_comments_for_pr/add_fix_comments_for_pr.ts
3814
+ import Debug4 from "debug";
3727
3815
 
3728
3816
  // src/features/analysis/add_fix_comments_for_pr/utils.ts
3729
3817
  import Debug3 from "debug";
3730
3818
  import parseDiff2 from "parse-diff";
3731
- import { z as z10 } from "zod";
3819
+ import { z as z11 } from "zod";
3732
3820
 
3733
3821
  // src/features/analysis/utils/by_key.ts
3734
3822
  function keyBy(array, keyBy2) {
@@ -3960,7 +4048,7 @@ async function getRelevantVulenrabilitiesFromDiff(params) {
3960
4048
  });
3961
4049
  const lineAddedRanges = calculateRanges(fileNumbers);
3962
4050
  const fileFilter = {
3963
- path: z10.string().parse(file.to),
4051
+ path: z11.string().parse(file.to),
3964
4052
  ranges: lineAddedRanges.map(([startLine, endLine]) => ({
3965
4053
  endLine,
3966
4054
  startLine
@@ -4267,30 +4355,30 @@ function subscribe(query, variables, callback, wsClientOptions) {
4267
4355
  }
4268
4356
 
4269
4357
  // src/features/analysis/graphql/types.ts
4270
- import { z as z11 } from "zod";
4271
- var VulnerabilityReportIssueCodeNodeZ = z11.object({
4272
- vulnerabilityReportIssueId: z11.string(),
4273
- path: z11.string(),
4274
- startLine: z11.number(),
4275
- vulnerabilityReportIssue: z11.object({
4276
- fixId: z11.string()
4358
+ import { z as z12 } from "zod";
4359
+ var VulnerabilityReportIssueCodeNodeZ = z12.object({
4360
+ vulnerabilityReportIssueId: z12.string(),
4361
+ path: z12.string(),
4362
+ startLine: z12.number(),
4363
+ vulnerabilityReportIssue: z12.object({
4364
+ fixId: z12.string()
4277
4365
  })
4278
4366
  });
4279
- var GetVulByNodesMetadataZ = z11.object({
4280
- vulnerabilityReportIssueCodeNodes: z11.array(VulnerabilityReportIssueCodeNodeZ),
4281
- nonFixablePrVuls: z11.object({
4282
- aggregate: z11.object({
4283
- count: z11.number()
4367
+ var GetVulByNodesMetadataZ = z12.object({
4368
+ vulnerabilityReportIssueCodeNodes: z12.array(VulnerabilityReportIssueCodeNodeZ),
4369
+ nonFixablePrVuls: z12.object({
4370
+ aggregate: z12.object({
4371
+ count: z12.number()
4284
4372
  })
4285
4373
  }),
4286
- fixablePrVuls: z11.object({
4287
- aggregate: z11.object({
4288
- count: z11.number()
4374
+ fixablePrVuls: z12.object({
4375
+ aggregate: z12.object({
4376
+ count: z12.number()
4289
4377
  })
4290
4378
  }),
4291
- totalScanVulnerabilities: z11.object({
4292
- aggregate: z11.object({
4293
- count: z11.number()
4379
+ totalScanVulnerabilities: z12.object({
4380
+ aggregate: z12.object({
4381
+ count: z12.number()
4294
4382
  })
4295
4383
  })
4296
4384
  });
@@ -4563,6 +4651,12 @@ var GQLClient = class {
4563
4651
  });
4564
4652
  return res;
4565
4653
  }
4654
+ async validateRepoUrl(args) {
4655
+ return this._clientSdk.validateRepoUrl(args);
4656
+ }
4657
+ async getReferenceData(args) {
4658
+ return this._clientSdk.gitReference(args);
4659
+ }
4566
4660
  };
4567
4661
 
4568
4662
  // src/features/analysis/pack.ts
@@ -5063,6 +5157,70 @@ function _getUrlForScmType({
5063
5157
  };
5064
5158
  }
5065
5159
  }
5160
+ async function getScmTokenInfo(params) {
5161
+ const { gqlClient, repo } = params;
5162
+ const userInfo = await gqlClient.getUserInfo();
5163
+ if (!userInfo) {
5164
+ throw new Error("userInfo is null");
5165
+ }
5166
+ const scmConfigs = getFromArraySafe(userInfo.scmConfigs);
5167
+ return getScmConfig({
5168
+ url: repo,
5169
+ scmConfigs,
5170
+ includeOrgTokens: false
5171
+ });
5172
+ }
5173
+ async function getReport(params, { skipPrompts }) {
5174
+ const {
5175
+ scanner,
5176
+ repoUrl,
5177
+ gqlClient,
5178
+ sha,
5179
+ dirname,
5180
+ reference,
5181
+ cxProjectName,
5182
+ ci
5183
+ } = params;
5184
+ const tokenInfo = await getScmTokenInfo({ gqlClient, repo: repoUrl });
5185
+ const scm = await SCMLib.init(
5186
+ {
5187
+ url: repoUrl,
5188
+ accessToken: tokenInfo.accessToken,
5189
+ scmOrg: tokenInfo.scmOrg,
5190
+ scmType: tokenInfo.scmLibType
5191
+ },
5192
+ { propagateExceptions: true }
5193
+ );
5194
+ const downloadUrl = await scm.getDownloadUrl(sha);
5195
+ const repositoryRoot = await downloadRepo({
5196
+ repoUrl,
5197
+ dirname,
5198
+ ci,
5199
+ authHeaders: scm.getAuthHeaders(),
5200
+ downloadUrl
5201
+ });
5202
+ const reportPath = path6.join(dirname, "report.json");
5203
+ switch (scanner) {
5204
+ case "snyk":
5205
+ await getSnykReport(reportPath, repositoryRoot, { skipPrompts });
5206
+ break;
5207
+ case "checkmarx":
5208
+ if (!cxProjectName) {
5209
+ throw new Error("cxProjectName is required for checkmarx scanner");
5210
+ }
5211
+ await getCheckmarxReport(
5212
+ {
5213
+ reportPath,
5214
+ repositoryRoot,
5215
+ branch: reference,
5216
+ projectName: cxProjectName
5217
+ },
5218
+ { skipPrompts }
5219
+ );
5220
+ break;
5221
+ }
5222
+ return reportPath;
5223
+ }
5066
5224
  async function _scan(params, { skipPrompts = false } = {}) {
5067
5225
  const {
5068
5226
  dirname,
@@ -5106,68 +5264,64 @@ async function _scan(params, { skipPrompts = false } = {}) {
5106
5264
  if (!repo) {
5107
5265
  throw new Error("repo is required in case srcPath is not provided");
5108
5266
  }
5109
- const userInfo = await gqlClient.getUserInfo();
5110
- if (!userInfo) {
5111
- throw new Error("userInfo is null");
5112
- }
5113
- const scmConfigs = getFromArraySafe(userInfo.scmConfigs);
5114
- const tokenInfo = getScmConfig({
5115
- url: repo,
5116
- scmConfigs,
5117
- includeOrgTokens: false
5118
- });
5119
- const isRepoAvailable = await scmCanReachRepo({
5120
- repoUrl: repo,
5121
- accessToken: tokenInfo.accessToken,
5122
- scmOrg: tokenInfo.scmOrg,
5123
- scmType: getScmTypeFromScmLibType(tokenInfo.scmLibType)
5124
- });
5267
+ const tokenInfo = await getScmTokenInfo({ gqlClient, repo });
5268
+ const validateRes = await gqlClient.validateRepoUrl({ repoUrl: repo });
5269
+ const isRepoAvailable = validateRes.validateRepoUrl?.__typename === "RepoValidationSuccess";
5125
5270
  const cloudScmLibType = getCloudScmLibTypeFromUrl(repo);
5126
5271
  const { authUrl: scmAuthUrl } = _getUrlForScmType({
5127
5272
  scmLibType: cloudScmLibType
5128
5273
  });
5129
- let myToken = tokenInfo.accessToken;
5130
5274
  if (!isRepoAvailable) {
5131
5275
  if (ci || !cloudScmLibType || !scmAuthUrl) {
5132
5276
  const errorMessage = scmAuthUrl ? `Cannot access repo ${repo}` : `Cannot access repo ${repo} with the provided token, please visit ${scmAuthUrl} to refresh your source control management system token`;
5133
5277
  throw new Error(errorMessage);
5134
5278
  }
5135
5279
  if (cloudScmLibType && scmAuthUrl) {
5136
- myToken = await handleScmIntegration(tokenInfo.accessToken, scmAuthUrl, repo) || "";
5137
- const isRepoAvailable2 = await scmCanReachRepo({
5138
- repoUrl: repo,
5139
- accessToken: myToken,
5140
- scmOrg: tokenInfo.scmOrg,
5141
- scmType: getScmTypeFromScmLibType(tokenInfo.scmLibType)
5280
+ await handleScmIntegration(tokenInfo.accessToken, scmAuthUrl, repo);
5281
+ const repoValidationResponse = await gqlClient.validateRepoUrl({
5282
+ repoUrl: repo
5142
5283
  });
5284
+ const isRepoAvailable2 = repoValidationResponse.validateRepoUrl?.__typename === "RepoValidationSuccess";
5143
5285
  if (!isRepoAvailable2) {
5144
5286
  throw new Error(
5145
- `Cannot access repo ${repo} with the provided credentials`
5287
+ `Cannot access repo ${repo} with the provided credentials: ${repoValidationResponse.validateRepoUrl?.__typename}`
5146
5288
  );
5147
5289
  }
5148
5290
  }
5149
5291
  }
5150
- const scm = await SCMLib.init({
5151
- url: repo,
5152
- accessToken: myToken,
5153
- scmOrg: tokenInfo.scmOrg,
5154
- scmType: tokenInfo.scmLibType
5292
+ const revalidateRes = await gqlClient.validateRepoUrl({ repoUrl: repo });
5293
+ if (revalidateRes.validateRepoUrl?.__typename !== "RepoValidationSuccess") {
5294
+ throw new Error(
5295
+ `could not reach repo ${repo}: ${revalidateRes.validateRepoUrl?.__typename}`
5296
+ );
5297
+ }
5298
+ const reference = ref ?? revalidateRes.validateRepoUrl.defaultBranch;
5299
+ const getReferenceDataRes = await gqlClient.getReferenceData({
5300
+ reference,
5301
+ repoUrl: repo
5155
5302
  });
5156
- const reference = ref ?? await scm.getRepoDefaultBranch();
5157
- const { sha } = await scm.getReferenceData(reference);
5158
- const downloadUrl = await scm.getDownloadUrl(sha);
5159
- debug11("org id %s", organizationId);
5303
+ if (getReferenceDataRes.gitReference?.__typename !== "GitReferenceData") {
5304
+ throw new Error(
5305
+ `Could not get reference data for ${reference}: ${getReferenceDataRes.gitReference?.__typename}`
5306
+ );
5307
+ }
5308
+ const { sha } = getReferenceDataRes.gitReference;
5160
5309
  debug11("project id %s", projectId);
5161
5310
  debug11("default branch %s", reference);
5162
- const repositoryRoot = await downloadRepo({
5163
- repoUrl: repo,
5164
- dirname,
5165
- ci,
5166
- authHeaders: scm.getAuthHeaders(),
5167
- downloadUrl
5168
- });
5169
5311
  if (command === "scan") {
5170
- reportPath = await getReport(SupportedScannersZ.parse(scanner));
5312
+ reportPath = await getReport(
5313
+ {
5314
+ scanner: SupportedScannersZ.parse(scanner),
5315
+ repoUrl: repo,
5316
+ sha,
5317
+ gqlClient,
5318
+ cxProjectName,
5319
+ dirname,
5320
+ reference,
5321
+ ci
5322
+ },
5323
+ { skipPrompts }
5324
+ );
5171
5325
  }
5172
5326
  if (!reportPath) {
5173
5327
  throw new Error("reportPath is null");
@@ -5191,7 +5345,7 @@ async function _scan(params, { skipPrompts = false } = {}) {
5191
5345
  spinner: mobbSpinner,
5192
5346
  submitVulnerabilityReportVariables: {
5193
5347
  fixReportId: reportUploadInfo.fixReportId,
5194
- repoUrl: z12.string().parse(repo),
5348
+ repoUrl: z13.string().parse(repo),
5195
5349
  reference,
5196
5350
  projectId,
5197
5351
  vulnerabilityReportFileName: "report.json",
@@ -5210,29 +5364,6 @@ async function _scan(params, { skipPrompts = false } = {}) {
5210
5364
  });
5211
5365
  await askToOpenAnalysis();
5212
5366
  return reportUploadInfo.fixReportId;
5213
- async function getReport(scanner2) {
5214
- const reportPath2 = path6.join(dirname, "report.json");
5215
- switch (scanner2) {
5216
- case "snyk":
5217
- await getSnykReport(reportPath2, repositoryRoot, { skipPrompts });
5218
- break;
5219
- case "checkmarx":
5220
- if (!cxProjectName) {
5221
- throw new Error("cxProjectName is required for checkmarx scanner");
5222
- }
5223
- await getCheckmarxReport(
5224
- {
5225
- reportPath: reportPath2,
5226
- repositoryRoot,
5227
- branch: reference,
5228
- projectName: cxProjectName
5229
- },
5230
- { skipPrompts }
5231
- );
5232
- break;
5233
- }
5234
- return reportPath2;
5235
- }
5236
5367
  async function askToOpenAnalysis() {
5237
5368
  if (!repoUploadInfo || !reportUploadInfo) {
5238
5369
  throw new Error("uploadS3BucketInfo is null");
@@ -5329,14 +5460,14 @@ async function _scan(params, { skipPrompts = false } = {}) {
5329
5460
  );
5330
5461
  await open2(scmAuthUrl2);
5331
5462
  for (let i = 0; i < LOGIN_MAX_WAIT / LOGIN_CHECK_DELAY; i++) {
5332
- const userInfo2 = await gqlClient.getUserInfo();
5333
- if (!userInfo2) {
5463
+ const userInfo = await gqlClient.getUserInfo();
5464
+ if (!userInfo) {
5334
5465
  throw new CliError2("User info not found");
5335
5466
  }
5336
- const scmConfigs2 = getFromArraySafe(userInfo2.scmConfigs);
5467
+ const scmConfigs = getFromArraySafe(userInfo.scmConfigs);
5337
5468
  const tokenInfo2 = getScmConfig({
5338
5469
  url: repoUrl,
5339
- scmConfigs: scmConfigs2,
5470
+ scmConfigs,
5340
5471
  includeOrgTokens: false
5341
5472
  });
5342
5473
  if (tokenInfo2.accessToken && tokenInfo2.accessToken !== oldToken) {
@@ -5443,16 +5574,21 @@ async function _scan(params, { skipPrompts = false } = {}) {
5443
5574
  }
5444
5575
  });
5445
5576
  if (command === "review") {
5446
- const params2 = z12.object({
5447
- repo: z12.string().url(),
5448
- githubActionToken: z12.string()
5577
+ const params2 = z13.object({
5578
+ repo: z13.string().url(),
5579
+ githubActionToken: z13.string()
5449
5580
  }).parse({ repo, githubActionToken });
5450
- const scm2 = await SCMLib.init({
5451
- url: params2.repo,
5452
- accessToken: params2.githubActionToken,
5453
- scmOrg: "",
5454
- scmType: "GITHUB" /* GITHUB */
5455
- });
5581
+ const scm = await SCMLib.init(
5582
+ {
5583
+ url: params2.repo,
5584
+ accessToken: params2.githubActionToken,
5585
+ scmOrg: "",
5586
+ scmType: "GITHUB" /* GITHUB */
5587
+ },
5588
+ {
5589
+ propagateExceptions: true
5590
+ }
5591
+ );
5456
5592
  await gqlClient.subscribeToAnalysis({
5457
5593
  subscribeToAnalysisParams: {
5458
5594
  analysisId: reportUploadInfo.fixReportId
@@ -5461,8 +5597,8 @@ async function _scan(params, { skipPrompts = false } = {}) {
5461
5597
  return addFixCommentsForPr({
5462
5598
  analysisId,
5463
5599
  gqlClient,
5464
- scm: scm2,
5465
- scanner: z12.nativeEnum(SCANNERS).parse(scanner)
5600
+ scm,
5601
+ scanner: z13.nativeEnum(SCANNERS).parse(scanner)
5466
5602
  });
5467
5603
  },
5468
5604
  callbackStates: ["Finished" /* Finished */]
@@ -5648,12 +5784,12 @@ var commitHashOption = {
5648
5784
  };
5649
5785
  var scmTypeOption = {
5650
5786
  demandOption: true,
5651
- describe: chalk5.bold("SCM type (GitHub, GitLab, Ado, Bitbucket)"),
5652
- type: "string"
5787
+ describe: chalk5.bold("SCM type"),
5788
+ choices: Object.values(ScmType)
5653
5789
  };
5654
5790
  var urlOption = {
5655
5791
  describe: chalk5.bold(
5656
- "URL of the repository (used in GitHub, GitLab, Azure DevOps, Bitbucket)"
5792
+ `URL of the repository (used in ${Object.values(ScmType).join(", ")})`
5657
5793
  ),
5658
5794
  type: "string",
5659
5795
  demandOption: true
@@ -5675,7 +5811,7 @@ var scmTokenOption = {
5675
5811
  // src/args/validation.ts
5676
5812
  import chalk6 from "chalk";
5677
5813
  import path8 from "path";
5678
- import { z as z13 } from "zod";
5814
+ import { z as z14 } from "zod";
5679
5815
  function throwRepoUrlErrorMessage({
5680
5816
  error,
5681
5817
  repoUrl,
@@ -5692,13 +5828,13 @@ Example:
5692
5828
  )}`;
5693
5829
  throw new CliError(formattedErrorMessage);
5694
5830
  }
5695
- var UrlZ = z13.string({
5696
- invalid_type_error: "is not a valid GitHub / GitLab / ADO URL"
5831
+ var UrlZ = z14.string({
5832
+ invalid_type_error: `is not a valid ${Object.values(ScmType).join("/ ")} URL`
5697
5833
  }).refine((data) => !!sanityRepoURL(data), {
5698
- message: "is not a valid GitHub / GitLab / ADO URL"
5834
+ message: `is not a valid ${Object.values(ScmType).join(" / ")} URL`
5699
5835
  });
5700
5836
  function validateOrganizationId(organizationId) {
5701
- const orgIdValidation = z13.string().uuid().nullish().safeParse(organizationId);
5837
+ const orgIdValidation = z14.string().uuid().nullish().safeParse(organizationId);
5702
5838
  if (!orgIdValidation.success) {
5703
5839
  throw new CliError(`organizationId: ${organizationId} is not a valid UUID`);
5704
5840
  }
@@ -5855,20 +5991,15 @@ async function scanHandler(args) {
5855
5991
  }
5856
5992
 
5857
5993
  // src/args/commands/token.ts
5858
- import { z as z14 } from "zod";
5859
5994
  function addScmTokenBuilder(args) {
5860
5995
  return args.option("scm-type", scmTypeOption).option("url", urlOption).option("token", scmTokenOption).option("organization", scmOrgOption).option("refresh-token", scmRefreshTokenOption).option("api-key", apiKeyOption).example(
5861
5996
  "$0 add-scm-token --scm-type Ado --url https://dev.azure.com/adoorg/test/_git/repo --token abcdef0123456 --organization myOrg",
5862
- "Add your SCM (Github, Gitlab, Azure DevOps) token to Mobb to enable automated fixes."
5997
+ `Add your SCM (${Object.values(scmFriendlyText).join(", ")}) token to Mobb to enable automated fixes.`
5863
5998
  ).help().demandOption(["url", "token"]);
5864
5999
  }
5865
- function validateAddScmTokenOptions(argv) {
5866
- if (!z14.nativeEnum(ScmType).safeParse(argv.scmType).success) {
5867
- throw new CliError(
5868
- "\nError: --scm-type must reference a valid SCM type (GitHub, GitLab, Ado, Bitbutcket)"
5869
- );
5870
- }
5871
- Object.values(scmValidationMap).forEach((validate) => validate(argv));
6000
+ async function validateAddScmTokenOptions(argv) {
6001
+ const scmType = argv["scm-type"];
6002
+ scmValidationMap[scmType];
5872
6003
  }
5873
6004
  var scmValidationMap = {
5874
6005
  ["GitHub" /* GitHub */]: () => {
@@ -5883,15 +6014,14 @@ var scmValidationMap = {
5883
6014
  }
5884
6015
  };
5885
6016
  function validateAdo(argv) {
5886
- const urlObj = new URL(argv.url);
5887
- if ((urlObj.hostname.toLowerCase() === scmCloudHostname.Ado || urlObj.hostname.toLowerCase().endsWith(".visualstudio.com")) && !argv.organization) {
6017
+ if (!argv.organization) {
5888
6018
  throw new CliError(
5889
6019
  "\nError: --organization flag is required for Azure DevOps"
5890
6020
  );
5891
6021
  }
5892
6022
  }
5893
6023
  async function addScmTokenHandler(args) {
5894
- validateAddScmTokenOptions(args);
6024
+ await validateAddScmTokenOptions(args);
5895
6025
  await addScmToken(args);
5896
6026
  }
5897
6027