@capraconsulting/cals-cli 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cals-cli.js +72 -28
- package/lib/cals-cli.js.map +1 -1
- package/lib/index.es.js +71 -28
- package/lib/index.es.js.map +1 -1
- package/lib/index.js +71 -28
- package/lib/index.js.map +1 -1
- package/lib/snyk/types.d.ts +36 -0
- package/package.json +1 -1
package/lib/cals-cli.js
CHANGED
|
@@ -13,6 +13,7 @@ var fetch = require('node-fetch');
|
|
|
13
13
|
var pLimit = require('p-limit');
|
|
14
14
|
var keytar = require('keytar');
|
|
15
15
|
var process$2 = require('process');
|
|
16
|
+
var perf_hooks = require('perf_hooks');
|
|
16
17
|
var util = require('util');
|
|
17
18
|
var path = require('path');
|
|
18
19
|
var rimraf = require('rimraf');
|
|
@@ -67,7 +68,7 @@ var read__default = /*#__PURE__*/_interopDefaultLegacy(read);
|
|
|
67
68
|
var findUp__default = /*#__PURE__*/_interopDefaultLegacy(findUp);
|
|
68
69
|
var execa__default = /*#__PURE__*/_interopDefaultLegacy(execa);
|
|
69
70
|
|
|
70
|
-
var version = "3.
|
|
71
|
+
var version = "3.2.0";
|
|
71
72
|
var engines = {
|
|
72
73
|
node: ">=12.0.0"
|
|
73
74
|
};
|
|
@@ -663,19 +664,25 @@ class GitHubService {
|
|
|
663
664
|
const headers = {
|
|
664
665
|
Authorization: `Bearer ${token}`,
|
|
665
666
|
};
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
667
|
+
let requestDuration = -1;
|
|
668
|
+
const response = await this.semaphore(() => {
|
|
669
|
+
const requestStart = perf_hooks.performance.now();
|
|
670
|
+
const result = fetch__default["default"](url, {
|
|
671
|
+
method: "POST",
|
|
672
|
+
headers,
|
|
673
|
+
body: JSON.stringify({ query }),
|
|
674
|
+
agent: this.config.agent,
|
|
675
|
+
});
|
|
676
|
+
requestDuration = perf_hooks.performance.now() - requestStart;
|
|
677
|
+
return result;
|
|
678
|
+
});
|
|
672
679
|
if (response.status === 401) {
|
|
673
680
|
process__namespace.stderr.write("Unauthorized\n");
|
|
674
681
|
await this.tokenProvider.markInvalid();
|
|
675
682
|
}
|
|
676
683
|
// If you get 502 after 10s, it is a timeout.
|
|
677
684
|
if (response.status === 502) {
|
|
678
|
-
throw new Error(`Response from Github likely timed out (10s max) with status ${response.status}: ${await response.text()}`);
|
|
685
|
+
throw new Error(`Response from Github likely timed out (10s max) after elapsed ${requestDuration}ms with status ${response.status}: ${await response.text()}`);
|
|
679
686
|
}
|
|
680
687
|
if (!response.ok) {
|
|
681
688
|
throw new Error(`Response from GitHub not OK (${response.status}): ${await response.text()}`);
|
|
@@ -858,7 +865,7 @@ class GitHubService {
|
|
|
858
865
|
search(
|
|
859
866
|
query: "is:open is:pr user:${owner} owner:${owner} archived:false",
|
|
860
867
|
type: ISSUE,
|
|
861
|
-
first:
|
|
868
|
+
first: 50${after === null
|
|
862
869
|
? ""
|
|
863
870
|
: `,
|
|
864
871
|
after: "${after}"`}
|
|
@@ -885,7 +892,7 @@ class GitHubService {
|
|
|
885
892
|
login
|
|
886
893
|
}
|
|
887
894
|
title
|
|
888
|
-
commits(first:
|
|
895
|
+
commits(first: 3) {
|
|
889
896
|
nodes {
|
|
890
897
|
commit {
|
|
891
898
|
messageHeadline
|
|
@@ -1117,23 +1124,60 @@ class SnykService {
|
|
|
1117
1124
|
if (token === undefined) {
|
|
1118
1125
|
throw new Error("Missing token for Snyk");
|
|
1119
1126
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1127
|
+
let backportedProjects = [];
|
|
1128
|
+
const snykRestApiVersion = "2023-08-04";
|
|
1129
|
+
let nextUrl = `/orgs/${encodeURIComponent(snykAccountId)}/projects?version=${snykRestApiVersion}&meta.latest_dependency_total=true&meta.latest_issue_counts=true&limit=100`;
|
|
1130
|
+
/* The Snyk REST API only allows us to retrieve 100 projects at a time.
|
|
1131
|
+
* The "links.next" value in the response gives us a pointer to the next 100 results.
|
|
1132
|
+
* We continue calling the Snyk API and retrieving more projects until links.next is null
|
|
1133
|
+
* */
|
|
1134
|
+
while (nextUrl) {
|
|
1135
|
+
const response = await fetch__default["default"](`https://api.snyk.io/rest${nextUrl}`, {
|
|
1136
|
+
method: "GET",
|
|
1137
|
+
headers: {
|
|
1138
|
+
Accept: "application/json",
|
|
1139
|
+
Authorization: `token ${token}`,
|
|
1140
|
+
},
|
|
1141
|
+
agent: this.config.agent,
|
|
1142
|
+
});
|
|
1143
|
+
if (response.status === 401) {
|
|
1144
|
+
process.stderr.write("Unauthorized - removing token\n");
|
|
1145
|
+
await this.tokenProvider.markInvalid();
|
|
1146
|
+
}
|
|
1147
|
+
if (!response.ok) {
|
|
1148
|
+
throw new Error(`Response from Snyk not OK (${response.status}): ${JSON.stringify(response)}`);
|
|
1149
|
+
}
|
|
1150
|
+
// Check if the Sunset header is present in the response
|
|
1151
|
+
const sunsetHeader = response.headers.get("Sunset") || response.headers.get("sunset");
|
|
1152
|
+
if (sunsetHeader) {
|
|
1153
|
+
console.warn(`Snyk endpoint with version ${snykRestApiVersion} has been marked as deprecated with deprecation date ${sunsetHeader}`);
|
|
1154
|
+
}
|
|
1155
|
+
const jsonResponse = (await response.json());
|
|
1156
|
+
/* We transform the data to a standard format that we used for data from Snyk API v1 in order for
|
|
1157
|
+
the data to be backover compatible with existing consuments */
|
|
1158
|
+
backportedProjects = [
|
|
1159
|
+
...backportedProjects,
|
|
1160
|
+
...jsonResponse.data.map((project) => {
|
|
1161
|
+
return {
|
|
1162
|
+
id: project.id,
|
|
1163
|
+
name: project.attributes.name,
|
|
1164
|
+
type: project.attributes.type,
|
|
1165
|
+
created: project.attributes.created,
|
|
1166
|
+
origin: project.attributes.origin,
|
|
1167
|
+
testFrequency: project.attributes.settings.recurring_tests.frequency,
|
|
1168
|
+
isMonitored: project.attributes.status === "active",
|
|
1169
|
+
totalDependencies: project.meta.latest_dependency_total.total,
|
|
1170
|
+
issueCountsBySeverity: project.meta.latest_issue_counts,
|
|
1171
|
+
lastTestedDate: project.meta.latest_dependency_total.updated_at,
|
|
1172
|
+
browseUrl: `https://app.snyk.io/org/${snykAccountId}/project/${project.id}`,
|
|
1173
|
+
};
|
|
1174
|
+
}),
|
|
1175
|
+
];
|
|
1176
|
+
/* Update nextUrl with pointer to the next page of results based
|
|
1177
|
+
* on the "links.next" field in the JSON response */
|
|
1178
|
+
nextUrl = jsonResponse.links.next;
|
|
1179
|
+
}
|
|
1180
|
+
return backportedProjects;
|
|
1137
1181
|
}
|
|
1138
1182
|
}
|
|
1139
1183
|
function createSnykService(props) {
|
|
@@ -3358,7 +3402,7 @@ async function main() {
|
|
|
3358
3402
|
/ /___/ ___ |/ /______/ /
|
|
3359
3403
|
\\____/_/ |_/_____/____/
|
|
3360
3404
|
cli ${version}
|
|
3361
|
-
built ${"2023-
|
|
3405
|
+
built ${"2023-08-21T11:00:37+0000"}
|
|
3362
3406
|
|
|
3363
3407
|
https://github.com/capralifecycle/cals-cli/
|
|
3364
3408
|
|
package/lib/cals-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cals-cli.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cals-cli.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/lib/index.es.js
CHANGED
|
@@ -15,15 +15,15 @@ import fetch from 'node-fetch';
|
|
|
15
15
|
import pLimit from 'p-limit';
|
|
16
16
|
import keytar from 'keytar';
|
|
17
17
|
import * as process$1 from 'process';
|
|
18
|
+
import { performance } from 'perf_hooks';
|
|
18
19
|
import { SecretsManagerClient, DescribeSecretCommand, UntagResourceCommand, TagResourceCommand, GetSecretValueCommand, CreateSecretCommand, RestoreSecretCommand, PutSecretValueCommand } from '@aws-sdk/client-secrets-manager';
|
|
19
20
|
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
|
|
20
21
|
import read from 'read';
|
|
21
22
|
import { strict } from 'assert';
|
|
22
23
|
import execa from 'execa';
|
|
23
|
-
import { performance } from 'perf_hooks';
|
|
24
24
|
import { Transform } from 'stream';
|
|
25
25
|
|
|
26
|
-
var version = "3.
|
|
26
|
+
var version = "3.2.0";
|
|
27
27
|
|
|
28
28
|
class CacheProvider {
|
|
29
29
|
constructor(config) {
|
|
@@ -720,19 +720,25 @@ class GitHubService {
|
|
|
720
720
|
const headers = {
|
|
721
721
|
Authorization: `Bearer ${token}`,
|
|
722
722
|
};
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
723
|
+
let requestDuration = -1;
|
|
724
|
+
const response = await this.semaphore(() => {
|
|
725
|
+
const requestStart = performance.now();
|
|
726
|
+
const result = fetch(url, {
|
|
727
|
+
method: "POST",
|
|
728
|
+
headers,
|
|
729
|
+
body: JSON.stringify({ query }),
|
|
730
|
+
agent: this.config.agent,
|
|
731
|
+
});
|
|
732
|
+
requestDuration = performance.now() - requestStart;
|
|
733
|
+
return result;
|
|
734
|
+
});
|
|
729
735
|
if (response.status === 401) {
|
|
730
736
|
process$1.stderr.write("Unauthorized\n");
|
|
731
737
|
await this.tokenProvider.markInvalid();
|
|
732
738
|
}
|
|
733
739
|
// If you get 502 after 10s, it is a timeout.
|
|
734
740
|
if (response.status === 502) {
|
|
735
|
-
throw new Error(`Response from Github likely timed out (10s max) with status ${response.status}: ${await response.text()}`);
|
|
741
|
+
throw new Error(`Response from Github likely timed out (10s max) after elapsed ${requestDuration}ms with status ${response.status}: ${await response.text()}`);
|
|
736
742
|
}
|
|
737
743
|
if (!response.ok) {
|
|
738
744
|
throw new Error(`Response from GitHub not OK (${response.status}): ${await response.text()}`);
|
|
@@ -915,7 +921,7 @@ class GitHubService {
|
|
|
915
921
|
search(
|
|
916
922
|
query: "is:open is:pr user:${owner} owner:${owner} archived:false",
|
|
917
923
|
type: ISSUE,
|
|
918
|
-
first:
|
|
924
|
+
first: 50${after === null
|
|
919
925
|
? ""
|
|
920
926
|
: `,
|
|
921
927
|
after: "${after}"`}
|
|
@@ -942,7 +948,7 @@ class GitHubService {
|
|
|
942
948
|
login
|
|
943
949
|
}
|
|
944
950
|
title
|
|
945
|
-
commits(first:
|
|
951
|
+
commits(first: 3) {
|
|
946
952
|
nodes {
|
|
947
953
|
commit {
|
|
948
954
|
messageHeadline
|
|
@@ -1465,23 +1471,60 @@ class SnykService {
|
|
|
1465
1471
|
if (token === undefined) {
|
|
1466
1472
|
throw new Error("Missing token for Snyk");
|
|
1467
1473
|
}
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1474
|
+
let backportedProjects = [];
|
|
1475
|
+
const snykRestApiVersion = "2023-08-04";
|
|
1476
|
+
let nextUrl = `/orgs/${encodeURIComponent(snykAccountId)}/projects?version=${snykRestApiVersion}&meta.latest_dependency_total=true&meta.latest_issue_counts=true&limit=100`;
|
|
1477
|
+
/* The Snyk REST API only allows us to retrieve 100 projects at a time.
|
|
1478
|
+
* The "links.next" value in the response gives us a pointer to the next 100 results.
|
|
1479
|
+
* We continue calling the Snyk API and retrieving more projects until links.next is null
|
|
1480
|
+
* */
|
|
1481
|
+
while (nextUrl) {
|
|
1482
|
+
const response = await fetch(`https://api.snyk.io/rest${nextUrl}`, {
|
|
1483
|
+
method: "GET",
|
|
1484
|
+
headers: {
|
|
1485
|
+
Accept: "application/json",
|
|
1486
|
+
Authorization: `token ${token}`,
|
|
1487
|
+
},
|
|
1488
|
+
agent: this.config.agent,
|
|
1489
|
+
});
|
|
1490
|
+
if (response.status === 401) {
|
|
1491
|
+
process.stderr.write("Unauthorized - removing token\n");
|
|
1492
|
+
await this.tokenProvider.markInvalid();
|
|
1493
|
+
}
|
|
1494
|
+
if (!response.ok) {
|
|
1495
|
+
throw new Error(`Response from Snyk not OK (${response.status}): ${JSON.stringify(response)}`);
|
|
1496
|
+
}
|
|
1497
|
+
// Check if the Sunset header is present in the response
|
|
1498
|
+
const sunsetHeader = response.headers.get("Sunset") || response.headers.get("sunset");
|
|
1499
|
+
if (sunsetHeader) {
|
|
1500
|
+
console.warn(`Snyk endpoint with version ${snykRestApiVersion} has been marked as deprecated with deprecation date ${sunsetHeader}`);
|
|
1501
|
+
}
|
|
1502
|
+
const jsonResponse = (await response.json());
|
|
1503
|
+
/* We transform the data to a standard format that we used for data from Snyk API v1 in order for
|
|
1504
|
+
the data to be backover compatible with existing consuments */
|
|
1505
|
+
backportedProjects = [
|
|
1506
|
+
...backportedProjects,
|
|
1507
|
+
...jsonResponse.data.map((project) => {
|
|
1508
|
+
return {
|
|
1509
|
+
id: project.id,
|
|
1510
|
+
name: project.attributes.name,
|
|
1511
|
+
type: project.attributes.type,
|
|
1512
|
+
created: project.attributes.created,
|
|
1513
|
+
origin: project.attributes.origin,
|
|
1514
|
+
testFrequency: project.attributes.settings.recurring_tests.frequency,
|
|
1515
|
+
isMonitored: project.attributes.status === "active",
|
|
1516
|
+
totalDependencies: project.meta.latest_dependency_total.total,
|
|
1517
|
+
issueCountsBySeverity: project.meta.latest_issue_counts,
|
|
1518
|
+
lastTestedDate: project.meta.latest_dependency_total.updated_at,
|
|
1519
|
+
browseUrl: `https://app.snyk.io/org/${snykAccountId}/project/${project.id}`,
|
|
1520
|
+
};
|
|
1521
|
+
}),
|
|
1522
|
+
];
|
|
1523
|
+
/* Update nextUrl with pointer to the next page of results based
|
|
1524
|
+
* on the "links.next" field in the JSON response */
|
|
1525
|
+
nextUrl = jsonResponse.links.next;
|
|
1526
|
+
}
|
|
1527
|
+
return backportedProjects;
|
|
1485
1528
|
}
|
|
1486
1529
|
}
|
|
1487
1530
|
function createSnykService(props) {
|
package/lib/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/lib/index.js
CHANGED
|
@@ -19,12 +19,12 @@ var fetch = require('node-fetch');
|
|
|
19
19
|
var pLimit = require('p-limit');
|
|
20
20
|
var keytar = require('keytar');
|
|
21
21
|
var process$1 = require('process');
|
|
22
|
+
var perf_hooks = require('perf_hooks');
|
|
22
23
|
var clientSecretsManager = require('@aws-sdk/client-secrets-manager');
|
|
23
24
|
var clientSts = require('@aws-sdk/client-sts');
|
|
24
25
|
var read = require('read');
|
|
25
26
|
var assert = require('assert');
|
|
26
27
|
var execa = require('execa');
|
|
27
|
-
var perf_hooks = require('perf_hooks');
|
|
28
28
|
var stream = require('stream');
|
|
29
29
|
|
|
30
30
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -64,7 +64,7 @@ var process__namespace = /*#__PURE__*/_interopNamespace(process$1);
|
|
|
64
64
|
var read__default = /*#__PURE__*/_interopDefaultLegacy(read);
|
|
65
65
|
var execa__default = /*#__PURE__*/_interopDefaultLegacy(execa);
|
|
66
66
|
|
|
67
|
-
var version = "3.
|
|
67
|
+
var version = "3.2.0";
|
|
68
68
|
|
|
69
69
|
class CacheProvider {
|
|
70
70
|
constructor(config) {
|
|
@@ -761,19 +761,25 @@ class GitHubService {
|
|
|
761
761
|
const headers = {
|
|
762
762
|
Authorization: `Bearer ${token}`,
|
|
763
763
|
};
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
764
|
+
let requestDuration = -1;
|
|
765
|
+
const response = await this.semaphore(() => {
|
|
766
|
+
const requestStart = perf_hooks.performance.now();
|
|
767
|
+
const result = fetch__default["default"](url, {
|
|
768
|
+
method: "POST",
|
|
769
|
+
headers,
|
|
770
|
+
body: JSON.stringify({ query }),
|
|
771
|
+
agent: this.config.agent,
|
|
772
|
+
});
|
|
773
|
+
requestDuration = perf_hooks.performance.now() - requestStart;
|
|
774
|
+
return result;
|
|
775
|
+
});
|
|
770
776
|
if (response.status === 401) {
|
|
771
777
|
process__namespace.stderr.write("Unauthorized\n");
|
|
772
778
|
await this.tokenProvider.markInvalid();
|
|
773
779
|
}
|
|
774
780
|
// If you get 502 after 10s, it is a timeout.
|
|
775
781
|
if (response.status === 502) {
|
|
776
|
-
throw new Error(`Response from Github likely timed out (10s max) with status ${response.status}: ${await response.text()}`);
|
|
782
|
+
throw new Error(`Response from Github likely timed out (10s max) after elapsed ${requestDuration}ms with status ${response.status}: ${await response.text()}`);
|
|
777
783
|
}
|
|
778
784
|
if (!response.ok) {
|
|
779
785
|
throw new Error(`Response from GitHub not OK (${response.status}): ${await response.text()}`);
|
|
@@ -956,7 +962,7 @@ class GitHubService {
|
|
|
956
962
|
search(
|
|
957
963
|
query: "is:open is:pr user:${owner} owner:${owner} archived:false",
|
|
958
964
|
type: ISSUE,
|
|
959
|
-
first:
|
|
965
|
+
first: 50${after === null
|
|
960
966
|
? ""
|
|
961
967
|
: `,
|
|
962
968
|
after: "${after}"`}
|
|
@@ -983,7 +989,7 @@ class GitHubService {
|
|
|
983
989
|
login
|
|
984
990
|
}
|
|
985
991
|
title
|
|
986
|
-
commits(first:
|
|
992
|
+
commits(first: 3) {
|
|
987
993
|
nodes {
|
|
988
994
|
commit {
|
|
989
995
|
messageHeadline
|
|
@@ -1506,23 +1512,60 @@ class SnykService {
|
|
|
1506
1512
|
if (token === undefined) {
|
|
1507
1513
|
throw new Error("Missing token for Snyk");
|
|
1508
1514
|
}
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1515
|
+
let backportedProjects = [];
|
|
1516
|
+
const snykRestApiVersion = "2023-08-04";
|
|
1517
|
+
let nextUrl = `/orgs/${encodeURIComponent(snykAccountId)}/projects?version=${snykRestApiVersion}&meta.latest_dependency_total=true&meta.latest_issue_counts=true&limit=100`;
|
|
1518
|
+
/* The Snyk REST API only allows us to retrieve 100 projects at a time.
|
|
1519
|
+
* The "links.next" value in the response gives us a pointer to the next 100 results.
|
|
1520
|
+
* We continue calling the Snyk API and retrieving more projects until links.next is null
|
|
1521
|
+
* */
|
|
1522
|
+
while (nextUrl) {
|
|
1523
|
+
const response = await fetch__default["default"](`https://api.snyk.io/rest${nextUrl}`, {
|
|
1524
|
+
method: "GET",
|
|
1525
|
+
headers: {
|
|
1526
|
+
Accept: "application/json",
|
|
1527
|
+
Authorization: `token ${token}`,
|
|
1528
|
+
},
|
|
1529
|
+
agent: this.config.agent,
|
|
1530
|
+
});
|
|
1531
|
+
if (response.status === 401) {
|
|
1532
|
+
process.stderr.write("Unauthorized - removing token\n");
|
|
1533
|
+
await this.tokenProvider.markInvalid();
|
|
1534
|
+
}
|
|
1535
|
+
if (!response.ok) {
|
|
1536
|
+
throw new Error(`Response from Snyk not OK (${response.status}): ${JSON.stringify(response)}`);
|
|
1537
|
+
}
|
|
1538
|
+
// Check if the Sunset header is present in the response
|
|
1539
|
+
const sunsetHeader = response.headers.get("Sunset") || response.headers.get("sunset");
|
|
1540
|
+
if (sunsetHeader) {
|
|
1541
|
+
console.warn(`Snyk endpoint with version ${snykRestApiVersion} has been marked as deprecated with deprecation date ${sunsetHeader}`);
|
|
1542
|
+
}
|
|
1543
|
+
const jsonResponse = (await response.json());
|
|
1544
|
+
/* We transform the data to a standard format that we used for data from Snyk API v1 in order for
|
|
1545
|
+
the data to be backover compatible with existing consuments */
|
|
1546
|
+
backportedProjects = [
|
|
1547
|
+
...backportedProjects,
|
|
1548
|
+
...jsonResponse.data.map((project) => {
|
|
1549
|
+
return {
|
|
1550
|
+
id: project.id,
|
|
1551
|
+
name: project.attributes.name,
|
|
1552
|
+
type: project.attributes.type,
|
|
1553
|
+
created: project.attributes.created,
|
|
1554
|
+
origin: project.attributes.origin,
|
|
1555
|
+
testFrequency: project.attributes.settings.recurring_tests.frequency,
|
|
1556
|
+
isMonitored: project.attributes.status === "active",
|
|
1557
|
+
totalDependencies: project.meta.latest_dependency_total.total,
|
|
1558
|
+
issueCountsBySeverity: project.meta.latest_issue_counts,
|
|
1559
|
+
lastTestedDate: project.meta.latest_dependency_total.updated_at,
|
|
1560
|
+
browseUrl: `https://app.snyk.io/org/${snykAccountId}/project/${project.id}`,
|
|
1561
|
+
};
|
|
1562
|
+
}),
|
|
1563
|
+
];
|
|
1564
|
+
/* Update nextUrl with pointer to the next page of results based
|
|
1565
|
+
* on the "links.next" field in the JSON response */
|
|
1566
|
+
nextUrl = jsonResponse.links.next;
|
|
1567
|
+
}
|
|
1568
|
+
return backportedProjects;
|
|
1526
1569
|
}
|
|
1527
1570
|
}
|
|
1528
1571
|
function createSnykService(props) {
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/lib/snyk/types.d.ts
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
export interface ProjectResponse {
|
|
2
|
+
data: RestAPIProject[];
|
|
3
|
+
links: {
|
|
4
|
+
next?: string;
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export interface RestAPIProject {
|
|
8
|
+
id: string;
|
|
9
|
+
attributes: {
|
|
10
|
+
name: string;
|
|
11
|
+
type: string;
|
|
12
|
+
origin: string;
|
|
13
|
+
created: string;
|
|
14
|
+
status: string;
|
|
15
|
+
settings: {
|
|
16
|
+
recurring_tests: {
|
|
17
|
+
frequency: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
status: boolean;
|
|
22
|
+
meta: {
|
|
23
|
+
latest_dependency_total: {
|
|
24
|
+
updated_at: string;
|
|
25
|
+
total: number;
|
|
26
|
+
};
|
|
27
|
+
latest_issue_counts: {
|
|
28
|
+
critical?: number;
|
|
29
|
+
high: number;
|
|
30
|
+
medium: number;
|
|
31
|
+
low: number;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** Type represents format of responses from the deprecated List all projects v1 API
|
|
36
|
+
https://snyk.docs.apiary.io/#reference/projects/all-projects/list-all-projects **/
|
|
1
37
|
export interface SnykProject {
|
|
2
38
|
name: string;
|
|
3
39
|
id: string;
|