securewithtrace 0.15.0 → 0.16.1
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/README.md +9 -4
- package/dist/index.js +184 -43
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,12 +66,17 @@ tracecli vulnerabilities list --severity HIGH
|
|
|
66
66
|
tracecli auth login
|
|
67
67
|
tracecli auth status
|
|
68
68
|
tracecli auth logout
|
|
69
|
-
tracecli auth org list
|
|
70
|
-
tracecli auth org current
|
|
71
|
-
tracecli auth org switch <organization-id-or-slug>
|
|
72
69
|
```
|
|
73
70
|
|
|
74
|
-
|
|
71
|
+
### Organization context
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
tracecli org list
|
|
75
|
+
tracecli org current
|
|
76
|
+
tracecli org switch <organization-id-or-slug>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
When your account belongs to multiple organizations, use `tracecli org switch` to set the active organization context used by repository, vulnerability, and pentest commands.
|
|
75
80
|
|
|
76
81
|
### Repositories
|
|
77
82
|
|
package/dist/index.js
CHANGED
|
@@ -22645,6 +22645,7 @@ var PatchCapabilitiesResponseSchema = external_exports.object({
|
|
|
22645
22645
|
});
|
|
22646
22646
|
var OrganizationResponseSchema = external_exports.object({
|
|
22647
22647
|
organizationId: external_exports.uuid(),
|
|
22648
|
+
workosOrganizationId: external_exports.string().optional(),
|
|
22648
22649
|
name: external_exports.string(),
|
|
22649
22650
|
slug: external_exports.string(),
|
|
22650
22651
|
logoUrl: external_exports.string().nullable(),
|
|
@@ -23942,7 +23943,9 @@ var VulnerabilityAggregatedCountsRequestSchema = external_exports.object({
|
|
|
23942
23943
|
excludeStatuses: external_exports.array(VulnerabilityStatus).optional(),
|
|
23943
23944
|
defaultBranchOnly: external_exports.boolean().default(true).optional(),
|
|
23944
23945
|
/** Lower bound for time-series data. Only vulnerabilities created on or after this date are included in the timeSeries field. Does not affect byRepoAndSeverity or byStatusAndSeverity. */
|
|
23945
|
-
timeSeriesSince: external_exports.coerce.date().optional()
|
|
23946
|
+
timeSeriesSince: external_exports.coerce.date().optional(),
|
|
23947
|
+
/** When provided, only include vulnerabilities belonging to this repository. */
|
|
23948
|
+
repositoryId: external_exports.uuid().optional()
|
|
23946
23949
|
});
|
|
23947
23950
|
var VulnerabilityAggregatedCountsResponseSchema = external_exports.object({
|
|
23948
23951
|
byRepoAndSeverity: external_exports.array(RepoSeverityCountSchema),
|
|
@@ -24701,17 +24704,21 @@ async function pollForToken(clientId, deviceCode, options = {}) {
|
|
|
24701
24704
|
}
|
|
24702
24705
|
throw new Error("Authorization timed out. Please try again.");
|
|
24703
24706
|
}
|
|
24704
|
-
async function refreshAccessToken(clientId, refreshToken) {
|
|
24707
|
+
async function refreshAccessToken(clientId, refreshToken, organizationId) {
|
|
24708
|
+
const body = new URLSearchParams({
|
|
24709
|
+
grant_type: "refresh_token",
|
|
24710
|
+
client_id: clientId,
|
|
24711
|
+
refresh_token: refreshToken
|
|
24712
|
+
});
|
|
24713
|
+
if (organizationId && organizationId.trim().length > 0) {
|
|
24714
|
+
body.set("organization_id", organizationId);
|
|
24715
|
+
}
|
|
24705
24716
|
const response = await fetch(WORKOS_TOKEN_URL, {
|
|
24706
24717
|
method: "POST",
|
|
24707
24718
|
headers: {
|
|
24708
24719
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
24709
24720
|
},
|
|
24710
|
-
body
|
|
24711
|
-
grant_type: "refresh_token",
|
|
24712
|
-
client_id: clientId,
|
|
24713
|
-
refresh_token: refreshToken
|
|
24714
|
-
})
|
|
24721
|
+
body
|
|
24715
24722
|
});
|
|
24716
24723
|
if (!response.ok) {
|
|
24717
24724
|
const text = await response.text();
|
|
@@ -24899,6 +24906,24 @@ async function refreshStoredAccessToken() {
|
|
|
24899
24906
|
return null;
|
|
24900
24907
|
}
|
|
24901
24908
|
}
|
|
24909
|
+
async function refreshStoredAccessTokenForOrganization(workosOrganizationId) {
|
|
24910
|
+
const clientId = getWorkosClientId();
|
|
24911
|
+
const refreshToken = readRefreshToken();
|
|
24912
|
+
if (!clientId || !refreshToken) {
|
|
24913
|
+
return false;
|
|
24914
|
+
}
|
|
24915
|
+
try {
|
|
24916
|
+
const tokenResponse = await refreshAccessToken(clientId, refreshToken, workosOrganizationId);
|
|
24917
|
+
const nextRefreshToken = tokenResponse.refresh_token ?? refreshToken;
|
|
24918
|
+
writeTokens(tokenResponse.access_token, nextRefreshToken);
|
|
24919
|
+
return true;
|
|
24920
|
+
} catch (error48) {
|
|
24921
|
+
if (error48 instanceof Error && (error48.message.includes(" 400 ") || error48.message.includes(" 401 "))) {
|
|
24922
|
+
removeToken();
|
|
24923
|
+
}
|
|
24924
|
+
return false;
|
|
24925
|
+
}
|
|
24926
|
+
}
|
|
24902
24927
|
async function authenticatedRequest(request) {
|
|
24903
24928
|
const token = readToken();
|
|
24904
24929
|
if (!token) {
|
|
@@ -25027,6 +25052,21 @@ async function resolveOrganizationIdSafe(client) {
|
|
|
25027
25052
|
}
|
|
25028
25053
|
}
|
|
25029
25054
|
|
|
25055
|
+
// src/format.ts
|
|
25056
|
+
var SEVERITY_ORDER = {
|
|
25057
|
+
CRITICAL: 0,
|
|
25058
|
+
HIGH: 1,
|
|
25059
|
+
MEDIUM: 2,
|
|
25060
|
+
LOW: 3,
|
|
25061
|
+
INFORMATIONAL: 4
|
|
25062
|
+
};
|
|
25063
|
+
function formatStatus(status) {
|
|
25064
|
+
return status.toLowerCase().replace("_", " ");
|
|
25065
|
+
}
|
|
25066
|
+
function tsvSafe(value) {
|
|
25067
|
+
return (value ?? "").replace(/[\t\r\n]/g, " ");
|
|
25068
|
+
}
|
|
25069
|
+
|
|
25030
25070
|
// src/auth/commands.ts
|
|
25031
25071
|
function getClientId() {
|
|
25032
25072
|
const clientId = "client_01KEZ01W5Q3107GTBY51WQ67HT";
|
|
@@ -25172,9 +25212,15 @@ Use an organization ID or exact slug.`
|
|
|
25172
25212
|
};
|
|
25173
25213
|
}
|
|
25174
25214
|
return {
|
|
25175
|
-
error: `Organization '${input}' not found. Run \`tracecli
|
|
25215
|
+
error: `Organization '${input}' not found. Run \`tracecli org list\` to see available organizations.`
|
|
25176
25216
|
};
|
|
25177
25217
|
}
|
|
25218
|
+
async function refreshAfterOrganizationSwitch(workosOrganizationId, refreshForOrganization = (organizationId) => refreshStoredAccessTokenForOrganization(organizationId)) {
|
|
25219
|
+
if (!workosOrganizationId || workosOrganizationId.trim().length === 0) {
|
|
25220
|
+
return false;
|
|
25221
|
+
}
|
|
25222
|
+
return refreshForOrganization(workosOrganizationId);
|
|
25223
|
+
}
|
|
25178
25224
|
function createLoginCommand() {
|
|
25179
25225
|
return new Command("login").description("Authenticate with Trace").action(async () => {
|
|
25180
25226
|
const existingToken = readToken();
|
|
@@ -25283,7 +25329,14 @@ function createStatusCommand() {
|
|
|
25283
25329
|
});
|
|
25284
25330
|
}
|
|
25285
25331
|
function createOrgListCommand() {
|
|
25286
|
-
return new Command("list").description("List organizations available to your account").option("--
|
|
25332
|
+
return new Command("list").description("List organizations available to your account").option("-o, --output <format>", "Output format: table (default), json, tsv").addHelpText(
|
|
25333
|
+
"after",
|
|
25334
|
+
`
|
|
25335
|
+
Examples:
|
|
25336
|
+
tracecli org list
|
|
25337
|
+
tracecli org list --output json
|
|
25338
|
+
tracecli org list --output tsv | cut -f1`
|
|
25339
|
+
).action(async (options) => {
|
|
25287
25340
|
const organizationContext = await fetchOrganizationContext();
|
|
25288
25341
|
const items = organizationContext.organizations.map(
|
|
25289
25342
|
(organization) => ({
|
|
@@ -25292,10 +25345,23 @@ function createOrgListCommand() {
|
|
|
25292
25345
|
selected: organization.organizationId === organizationContext.selectedOrganizationId
|
|
25293
25346
|
})
|
|
25294
25347
|
);
|
|
25295
|
-
if (options.json) {
|
|
25348
|
+
if (options.output === "json") {
|
|
25296
25349
|
console.log(JSON.stringify(items, null, 2));
|
|
25297
25350
|
return;
|
|
25298
25351
|
}
|
|
25352
|
+
if (options.output === "tsv") {
|
|
25353
|
+
for (const item of items) {
|
|
25354
|
+
console.log(
|
|
25355
|
+
[
|
|
25356
|
+
tsvSafe(item.name),
|
|
25357
|
+
tsvSafe(item.slug),
|
|
25358
|
+
tsvSafe(item.organizationId),
|
|
25359
|
+
item.active ? "true" : "false"
|
|
25360
|
+
].join(" ")
|
|
25361
|
+
);
|
|
25362
|
+
}
|
|
25363
|
+
return;
|
|
25364
|
+
}
|
|
25299
25365
|
for (const item of items) {
|
|
25300
25366
|
const marker = item.active ? "*" : " ";
|
|
25301
25367
|
const labels = [item.active ? "active" : null, item.selected ? "selected" : null].filter(
|
|
@@ -25312,11 +25378,18 @@ function createOrgListCommand() {
|
|
|
25312
25378
|
});
|
|
25313
25379
|
}
|
|
25314
25380
|
function createOrgCurrentCommand() {
|
|
25315
|
-
return new Command("current").description("Show the active organization used by CLI commands").option("--
|
|
25381
|
+
return new Command("current").description("Show the active organization used by CLI commands").option("-o, --output <format>", "Output format: table (default), json, tsv").addHelpText(
|
|
25382
|
+
"after",
|
|
25383
|
+
`
|
|
25384
|
+
Examples:
|
|
25385
|
+
tracecli org current
|
|
25386
|
+
tracecli org current --output json
|
|
25387
|
+
tracecli org current --output tsv`
|
|
25388
|
+
).action(async (options) => {
|
|
25316
25389
|
const organizationContext = await fetchOrganizationContext();
|
|
25317
25390
|
const active = organizationContext.activeOrganization;
|
|
25318
25391
|
const source = organizationContext.selectedOrganizationId === active.organizationId ? "selected" : "default";
|
|
25319
|
-
if (options.json) {
|
|
25392
|
+
if (options.output === "json") {
|
|
25320
25393
|
console.log(
|
|
25321
25394
|
JSON.stringify(
|
|
25322
25395
|
{
|
|
@@ -25329,6 +25402,17 @@ function createOrgCurrentCommand() {
|
|
|
25329
25402
|
);
|
|
25330
25403
|
return;
|
|
25331
25404
|
}
|
|
25405
|
+
if (options.output === "tsv") {
|
|
25406
|
+
console.log(
|
|
25407
|
+
[
|
|
25408
|
+
tsvSafe(active.name),
|
|
25409
|
+
tsvSafe(active.slug),
|
|
25410
|
+
tsvSafe(active.organizationId),
|
|
25411
|
+
tsvSafe(source)
|
|
25412
|
+
].join(" ")
|
|
25413
|
+
);
|
|
25414
|
+
return;
|
|
25415
|
+
}
|
|
25332
25416
|
console.log(
|
|
25333
25417
|
`Active organization: ${sanitizeForOutput(active.name)} (${sanitizeForOutput(active.slug)})`
|
|
25334
25418
|
);
|
|
@@ -25351,10 +25435,18 @@ function createOrgSwitchCommand() {
|
|
|
25351
25435
|
process.exit(1);
|
|
25352
25436
|
}
|
|
25353
25437
|
writeSelectedOrganizationId(match.organization.organizationId);
|
|
25438
|
+
const refreshed = await refreshAfterOrganizationSwitch(
|
|
25439
|
+
match.organization.workosOrganizationId
|
|
25440
|
+
);
|
|
25354
25441
|
console.log(
|
|
25355
25442
|
`Active organization set to ${sanitizeForOutput(match.organization.name)} (${sanitizeForOutput(match.organization.slug)})`
|
|
25356
25443
|
);
|
|
25357
25444
|
console.log(` Org ID: ${match.organization.organizationId}`);
|
|
25445
|
+
if (!refreshed) {
|
|
25446
|
+
console.warn(
|
|
25447
|
+
"Token refresh for the selected organization was not completed. If repository commands fail, run `tracecli auth login` again."
|
|
25448
|
+
);
|
|
25449
|
+
}
|
|
25358
25450
|
});
|
|
25359
25451
|
}
|
|
25360
25452
|
function createOrgCommand() {
|
|
@@ -25369,7 +25461,7 @@ function createAuthCommand() {
|
|
|
25369
25461
|
auth.addCommand(createLoginCommand());
|
|
25370
25462
|
auth.addCommand(createLogoutCommand());
|
|
25371
25463
|
auth.addCommand(createStatusCommand());
|
|
25372
|
-
auth.addCommand(createOrgCommand());
|
|
25464
|
+
auth.addCommand(createOrgCommand(), { hidden: true });
|
|
25373
25465
|
return auth;
|
|
25374
25466
|
}
|
|
25375
25467
|
|
|
@@ -25755,22 +25847,10 @@ function createCompletionCommand(program3) {
|
|
|
25755
25847
|
});
|
|
25756
25848
|
}
|
|
25757
25849
|
|
|
25758
|
-
// src/format.ts
|
|
25759
|
-
var SEVERITY_ORDER = {
|
|
25760
|
-
CRITICAL: 0,
|
|
25761
|
-
HIGH: 1,
|
|
25762
|
-
MEDIUM: 2,
|
|
25763
|
-
LOW: 3,
|
|
25764
|
-
INFORMATIONAL: 4
|
|
25765
|
-
};
|
|
25766
|
-
function formatStatus(status) {
|
|
25767
|
-
return status.toLowerCase().replace("_", " ");
|
|
25768
|
-
}
|
|
25769
|
-
|
|
25770
25850
|
// src/pentest/commands.ts
|
|
25771
25851
|
var DEFAULT_LIMIT = 30;
|
|
25772
25852
|
var MAX_LIMIT = 100;
|
|
25773
|
-
function
|
|
25853
|
+
function tsvSafe2(value) {
|
|
25774
25854
|
return value.replace(/[\t\n\r]/g, " ");
|
|
25775
25855
|
}
|
|
25776
25856
|
function formatDate(date5) {
|
|
@@ -25889,7 +25969,7 @@ Examples:
|
|
|
25889
25969
|
for (const pt of pentests) {
|
|
25890
25970
|
const cols = [
|
|
25891
25971
|
`PT-${pt.displayId}`,
|
|
25892
|
-
|
|
25972
|
+
tsvSafe2(pt.title),
|
|
25893
25973
|
pt.status,
|
|
25894
25974
|
pt.startedAt ? String(pt.startedAt) : "",
|
|
25895
25975
|
pt.endedAt ? String(pt.endedAt) : "",
|
|
@@ -25972,8 +26052,8 @@ Examples:
|
|
|
25972
26052
|
const cols = [
|
|
25973
26053
|
finding.severity,
|
|
25974
26054
|
finding.status,
|
|
25975
|
-
|
|
25976
|
-
|
|
26055
|
+
tsvSafe2(finding.category),
|
|
26056
|
+
tsvSafe2(finding.title),
|
|
25977
26057
|
finding.cweIds.join(";"),
|
|
25978
26058
|
finding.cvssScore != null ? String(finding.cvssScore) : ""
|
|
25979
26059
|
];
|
|
@@ -26061,6 +26141,8 @@ function extractRepoName(input) {
|
|
|
26061
26141
|
}
|
|
26062
26142
|
var BRANCH_NAME_PATTERN = /^[a-zA-Z0-9._/+-]+$/;
|
|
26063
26143
|
var TRACE_GIT_ASKPASS_TOKEN_ENV = "TRACE_GIT_ASKPASS_TOKEN";
|
|
26144
|
+
var DEFAULT_LIMIT2 = 30;
|
|
26145
|
+
var MAX_LIMIT2 = 100;
|
|
26064
26146
|
var REPOSITORY_PLATFORMS = ["GITHUB", "GITLAB", "BITBUCKET"];
|
|
26065
26147
|
var REPOSITORY_STATUSES = ["CONNECTED", "DISCONNECTED"];
|
|
26066
26148
|
function validateBranchName(branch) {
|
|
@@ -26267,6 +26349,29 @@ function filterRepositories(repositories, options) {
|
|
|
26267
26349
|
return true;
|
|
26268
26350
|
});
|
|
26269
26351
|
}
|
|
26352
|
+
function parseListLimit(value) {
|
|
26353
|
+
const n = Number(value);
|
|
26354
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
26355
|
+
throw new Error("--limit must be a positive integer");
|
|
26356
|
+
}
|
|
26357
|
+
if (n > MAX_LIMIT2) {
|
|
26358
|
+
throw new Error(`--limit cannot exceed ${MAX_LIMIT2}`);
|
|
26359
|
+
}
|
|
26360
|
+
return n;
|
|
26361
|
+
}
|
|
26362
|
+
function printRepositoriesTsv(repositories) {
|
|
26363
|
+
for (const repo of repositories) {
|
|
26364
|
+
console.log(
|
|
26365
|
+
[
|
|
26366
|
+
tsvSafe(repo.repositoryUrl),
|
|
26367
|
+
tsvSafe(repo.platform),
|
|
26368
|
+
tsvSafe(repo.status),
|
|
26369
|
+
tsvSafe(repo.defaultBranch),
|
|
26370
|
+
tsvSafe(repo.primaryLanguage)
|
|
26371
|
+
].join(" ")
|
|
26372
|
+
);
|
|
26373
|
+
}
|
|
26374
|
+
}
|
|
26270
26375
|
function collectFilterExpression(value, previous) {
|
|
26271
26376
|
previous.push(value);
|
|
26272
26377
|
return previous;
|
|
@@ -26291,11 +26396,16 @@ function addRepositoryFilterOptions(command) {
|
|
|
26291
26396
|
"Filter by status (CONNECTED, DISCONNECTED)",
|
|
26292
26397
|
(value) => value.toUpperCase()
|
|
26293
26398
|
).option("--query <query>", "Case-insensitive search across URL, repo, branch, and language").option("--default-branch <branch>", "Filter by default branch (case-insensitive contains)").option("--language <language>", "Filter by primary language (case-insensitive contains)").option(
|
|
26294
|
-
"--filter <expression>",
|
|
26295
|
-
"Advanced filter expression. Repeatable. Examples: platform=GITHUB, repo:trace, status!=DISCONNECTED
|
|
26399
|
+
"-f, --filter <expression>",
|
|
26400
|
+
"Advanced filter expression. Repeatable. Examples: platform=GITHUB, repo:trace, status!=DISCONNECTED",
|
|
26296
26401
|
collectFilterExpression,
|
|
26297
26402
|
[]
|
|
26298
|
-
).option("--
|
|
26403
|
+
).option("-o, --output <format>", "Output format: table (default), json, tsv").option(
|
|
26404
|
+
"-L, --limit <n>",
|
|
26405
|
+
`Maximum repositories to display (default ${DEFAULT_LIMIT2}, max ${MAX_LIMIT2})`,
|
|
26406
|
+
parseListLimit,
|
|
26407
|
+
DEFAULT_LIMIT2
|
|
26408
|
+
).option(
|
|
26299
26409
|
"--dependency <pkg>",
|
|
26300
26410
|
"Filter repositories that use a dependency (e.g. lodash, lodash@4.17.21, @types/node@20)"
|
|
26301
26411
|
);
|
|
@@ -26334,11 +26444,17 @@ async function runRepositoryListCommand(options) {
|
|
|
26334
26444
|
console.log("No repositories found.");
|
|
26335
26445
|
return;
|
|
26336
26446
|
}
|
|
26337
|
-
|
|
26338
|
-
|
|
26447
|
+
const limit = options.limit ?? DEFAULT_LIMIT2;
|
|
26448
|
+
const displayedRepositories = filteredRepositories.slice(0, limit);
|
|
26449
|
+
if (options.output === "json") {
|
|
26450
|
+
console.log(JSON.stringify(displayedRepositories, null, 2));
|
|
26451
|
+
return;
|
|
26452
|
+
}
|
|
26453
|
+
if (options.output === "tsv") {
|
|
26454
|
+
printRepositoriesTsv(displayedRepositories);
|
|
26339
26455
|
return;
|
|
26340
26456
|
}
|
|
26341
|
-
for (const repo of
|
|
26457
|
+
for (const repo of displayedRepositories) {
|
|
26342
26458
|
const status = repo.status === "CONNECTED" ? "connected" : "disconnected";
|
|
26343
26459
|
const url2 = stripAnsi(String(repo.repositoryUrl));
|
|
26344
26460
|
const platform = stripAnsi(String(repo.platform)).toLowerCase();
|
|
@@ -26393,11 +26509,19 @@ async function runDependencyFilter(organizationId, options) {
|
|
|
26393
26509
|
console.log(`No repositories found using dependency '${label}'.`);
|
|
26394
26510
|
return;
|
|
26395
26511
|
}
|
|
26396
|
-
|
|
26397
|
-
|
|
26512
|
+
const limit = options.limit ?? DEFAULT_LIMIT2;
|
|
26513
|
+
const displayedRepos = repos.slice(0, limit);
|
|
26514
|
+
if (options.output === "json") {
|
|
26515
|
+
console.log(JSON.stringify(displayedRepos, null, 2));
|
|
26398
26516
|
return;
|
|
26399
26517
|
}
|
|
26400
|
-
|
|
26518
|
+
if (options.output === "tsv") {
|
|
26519
|
+
for (const repo of displayedRepos) {
|
|
26520
|
+
console.log(`${tsvSafe(repo.fullName)} ${tsvSafe(repo.versions.join(","))}`);
|
|
26521
|
+
}
|
|
26522
|
+
return;
|
|
26523
|
+
}
|
|
26524
|
+
for (const repo of displayedRepos) {
|
|
26401
26525
|
const versions = repo.versions.join(", ");
|
|
26402
26526
|
console.log(`${repo.fullName} (${versions})`);
|
|
26403
26527
|
}
|
|
@@ -26405,6 +26529,16 @@ async function runDependencyFilter(organizationId, options) {
|
|
|
26405
26529
|
function createListCommand2() {
|
|
26406
26530
|
return addRepositoryFilterOptions(
|
|
26407
26531
|
new Command("list").description("List repositories in your organization")
|
|
26532
|
+
).addHelpText(
|
|
26533
|
+
"after",
|
|
26534
|
+
`
|
|
26535
|
+
Examples:
|
|
26536
|
+
tracecli repo list
|
|
26537
|
+
tracecli repo list --platform GITHUB --status CONNECTED
|
|
26538
|
+
tracecli repo list --output json | jq '.[].repositoryUrl'
|
|
26539
|
+
tracecli repo list --output tsv | cut -f1
|
|
26540
|
+
tracecli repo list --filter "language:typescript" --limit 10
|
|
26541
|
+
tracecli repo list --dependency lodash@4.17.21`
|
|
26408
26542
|
).action(async (options) => {
|
|
26409
26543
|
await runRepositoryListCommand(options);
|
|
26410
26544
|
});
|
|
@@ -26412,6 +26546,12 @@ function createListCommand2() {
|
|
|
26412
26546
|
function createFilterCommand() {
|
|
26413
26547
|
return addRepositoryFilterOptions(
|
|
26414
26548
|
new Command("filter").description("Filter repositories in your organization")
|
|
26549
|
+
).addHelpText(
|
|
26550
|
+
"after",
|
|
26551
|
+
`
|
|
26552
|
+
Examples:
|
|
26553
|
+
tracecli repo filter --filter "platform=GITHUB" --filter "status=CONNECTED"
|
|
26554
|
+
tracecli repo filter --language typescript --output json`
|
|
26415
26555
|
).action(async (options) => {
|
|
26416
26556
|
await runRepositoryListCommand(options);
|
|
26417
26557
|
});
|
|
@@ -26533,8 +26673,8 @@ function createRepoCommand() {
|
|
|
26533
26673
|
}
|
|
26534
26674
|
|
|
26535
26675
|
// src/vulnerabilities/commands.ts
|
|
26536
|
-
var
|
|
26537
|
-
var
|
|
26676
|
+
var DEFAULT_LIMIT3 = 30;
|
|
26677
|
+
var MAX_LIMIT3 = 100;
|
|
26538
26678
|
async function resolveRepositoryIdAuthenticated(organizationId, repoIdentifier) {
|
|
26539
26679
|
const result = await authenticatedRequest(
|
|
26540
26680
|
(client) => client.repository.listRepositories({
|
|
@@ -26643,13 +26783,13 @@ function createListCommand3() {
|
|
|
26643
26783
|
(value) => value.toUpperCase()
|
|
26644
26784
|
).option(
|
|
26645
26785
|
"-L, --limit <n>",
|
|
26646
|
-
`Max results to return (default: ${
|
|
26786
|
+
`Max results to return (default: ${DEFAULT_LIMIT3}, max: ${MAX_LIMIT3})`,
|
|
26647
26787
|
(v) => {
|
|
26648
26788
|
const n = Number.parseInt(v, 10);
|
|
26649
26789
|
if (Number.isNaN(n) || n < 1) {
|
|
26650
26790
|
throw new Error("--limit must be a positive integer");
|
|
26651
26791
|
}
|
|
26652
|
-
return Math.min(n,
|
|
26792
|
+
return Math.min(n, MAX_LIMIT3);
|
|
26653
26793
|
}
|
|
26654
26794
|
).option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
26655
26795
|
"after",
|
|
@@ -26680,7 +26820,7 @@ Examples:
|
|
|
26680
26820
|
sortBy: "severity",
|
|
26681
26821
|
sortOrder: "desc"
|
|
26682
26822
|
};
|
|
26683
|
-
const limit = options.limit ??
|
|
26823
|
+
const limit = options.limit ?? DEFAULT_LIMIT3;
|
|
26684
26824
|
const isJson = options.output === "json";
|
|
26685
26825
|
const isTsv = options.output === "tsv";
|
|
26686
26826
|
const collected = [];
|
|
@@ -26746,6 +26886,7 @@ program2.action(() => {
|
|
|
26746
26886
|
program2.outputHelp();
|
|
26747
26887
|
});
|
|
26748
26888
|
program2.addCommand(createAuthCommand());
|
|
26889
|
+
program2.addCommand(createOrgCommand());
|
|
26749
26890
|
program2.addCommand(createRepoCommand());
|
|
26750
26891
|
program2.addCommand(createVulnerabilitiesCommand());
|
|
26751
26892
|
program2.addCommand(createPentestCommand());
|