securewithtrace 0.11.0 → 0.12.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/README.md +14 -0
- package/dist/index.js +75 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,7 @@ tracecli vulnerabilities list --severity HIGH
|
|
|
53
53
|
|
|
54
54
|
- **Authenticate securely** with device authorization flow (`auth login/logout/status`)
|
|
55
55
|
- **List and filter repositories** connected to your Trace organization (`repo list`, `repo filter`)
|
|
56
|
+
- **Find repositories by dependency** with optional version filtering (`repo list --dependency`)
|
|
56
57
|
- **Clone repositories** with secure token handling (`repo clone`)
|
|
57
58
|
- **Filter vulnerabilities** by repo, severity, and status (`vulnerabilities list`)
|
|
58
59
|
- **Export results as JSON or TSV** for automation (`vulnerabilities list --output json`)
|
|
@@ -82,6 +83,18 @@ tracecli repo list --filter "platform=GITHUB" --filter "repo:trace" --filter "st
|
|
|
82
83
|
# Alias command for filtering
|
|
83
84
|
tracecli repo filter --filter "language:typescript" --filter "branch=main"
|
|
84
85
|
|
|
86
|
+
# Find repositories that use a specific dependency
|
|
87
|
+
tracecli repo list --dependency lodash
|
|
88
|
+
|
|
89
|
+
# Filter by dependency at a specific version
|
|
90
|
+
tracecli repo list --dependency lodash@4.17.21
|
|
91
|
+
|
|
92
|
+
# Filter by scoped package with partial version match
|
|
93
|
+
tracecli repo list --dependency @types/node@20
|
|
94
|
+
|
|
95
|
+
# Dependency results as JSON
|
|
96
|
+
tracecli repo list --dependency react --json | jq '.[].fullName'
|
|
97
|
+
|
|
85
98
|
# Clone by owner/repo shorthand
|
|
86
99
|
tracecli repo clone securewithtrace/trace
|
|
87
100
|
|
|
@@ -136,6 +149,7 @@ Repository filter options:
|
|
|
136
149
|
- `--filter`: repeatable advanced expression in the form `<field><operator><value>`
|
|
137
150
|
- Supported fields: `platform`, `status`, `url`, `repo`, `branch`, `language`
|
|
138
151
|
- Supported operators: `=` (exact), `!=` (not exact), `:` (contains), `!:` (not contains)
|
|
152
|
+
- `--dependency`: filter by dependency name with optional `@version` (e.g. `lodash`, `lodash@4.17`, `@types/node@20`)
|
|
139
153
|
|
|
140
154
|
### Pentests
|
|
141
155
|
|
package/dist/index.js
CHANGED
|
@@ -25748,6 +25748,19 @@ function validateBranchName(branch) {
|
|
|
25748
25748
|
}
|
|
25749
25749
|
return branch;
|
|
25750
25750
|
}
|
|
25751
|
+
function parseDependencyFilter(filter) {
|
|
25752
|
+
const isScoped = filter.startsWith("@");
|
|
25753
|
+
const separatorIndex = isScoped ? filter.indexOf("@", 1) : filter.indexOf("@");
|
|
25754
|
+
if (separatorIndex === -1) {
|
|
25755
|
+
return { name: filter };
|
|
25756
|
+
}
|
|
25757
|
+
const name = filter.slice(0, separatorIndex);
|
|
25758
|
+
const version2 = filter.slice(separatorIndex + 1);
|
|
25759
|
+
if (!name || !version2) {
|
|
25760
|
+
return { name: filter };
|
|
25761
|
+
}
|
|
25762
|
+
return { name, version: version2 };
|
|
25763
|
+
}
|
|
25751
25764
|
function parseCloneDepth(value) {
|
|
25752
25765
|
const depth = Number.parseInt(value, 10);
|
|
25753
25766
|
if (!Number.isInteger(depth) || depth < 1) {
|
|
@@ -25958,11 +25971,18 @@ function addRepositoryFilterOptions(command) {
|
|
|
25958
25971
|
"Advanced filter expression. Repeatable. Examples: platform=GITHUB, repo:trace, status!=DISCONNECTED, language!:typescript",
|
|
25959
25972
|
collectFilterExpression,
|
|
25960
25973
|
[]
|
|
25961
|
-
).option("--json", "Output as JSON")
|
|
25974
|
+
).option("--json", "Output as JSON").option(
|
|
25975
|
+
"--dependency <pkg>",
|
|
25976
|
+
"Filter repositories that use a dependency (e.g. lodash, lodash@4.17.21, @types/node@20)"
|
|
25977
|
+
);
|
|
25962
25978
|
}
|
|
25963
25979
|
async function runRepositoryListCommand(options) {
|
|
25964
|
-
let filteredRepositories;
|
|
25965
25980
|
const organizationId = await resolveOrganizationId();
|
|
25981
|
+
if (options.dependency) {
|
|
25982
|
+
await runDependencyFilter(organizationId, options);
|
|
25983
|
+
return;
|
|
25984
|
+
}
|
|
25985
|
+
let filteredRepositories;
|
|
25966
25986
|
const result = await authenticatedRequest(
|
|
25967
25987
|
(client) => client.repository.listRepositories({
|
|
25968
25988
|
params: { organizationId }
|
|
@@ -25998,6 +26018,59 @@ async function runRepositoryListCommand(options) {
|
|
|
25998
26018
|
console.log(`${url2} (${platform}, ${status})`);
|
|
25999
26019
|
}
|
|
26000
26020
|
}
|
|
26021
|
+
async function runDependencyFilter(organizationId, options) {
|
|
26022
|
+
const { name, version: version2 } = parseDependencyFilter(options.dependency);
|
|
26023
|
+
const result = await authenticatedRequest(
|
|
26024
|
+
(client) => client.dependency.searchDependencies({
|
|
26025
|
+
params: { organizationId },
|
|
26026
|
+
body: {
|
|
26027
|
+
query: name,
|
|
26028
|
+
...version2 ? { versionPrefix: version2 } : {},
|
|
26029
|
+
pageSize: 100
|
|
26030
|
+
}
|
|
26031
|
+
})
|
|
26032
|
+
);
|
|
26033
|
+
if (result.status !== 200) {
|
|
26034
|
+
console.error(`Failed to search dependencies (status ${result.status}).`);
|
|
26035
|
+
process.exit(1);
|
|
26036
|
+
}
|
|
26037
|
+
const repoMap = /* @__PURE__ */ new Map();
|
|
26038
|
+
for (const pkg of result.body.packages) {
|
|
26039
|
+
if (pkg.name.toLowerCase() !== name.toLowerCase()) {
|
|
26040
|
+
continue;
|
|
26041
|
+
}
|
|
26042
|
+
for (const repo of pkg.repositories) {
|
|
26043
|
+
const existing = repoMap.get(repo.repositoryId);
|
|
26044
|
+
const versionStrings = repo.versions.map((v) => v.version);
|
|
26045
|
+
if (existing) {
|
|
26046
|
+
for (const v of versionStrings) {
|
|
26047
|
+
if (!existing.versions.includes(v)) {
|
|
26048
|
+
existing.versions.push(v);
|
|
26049
|
+
}
|
|
26050
|
+
}
|
|
26051
|
+
} else {
|
|
26052
|
+
repoMap.set(repo.repositoryId, {
|
|
26053
|
+
fullName: repo.fullName,
|
|
26054
|
+
versions: versionStrings
|
|
26055
|
+
});
|
|
26056
|
+
}
|
|
26057
|
+
}
|
|
26058
|
+
}
|
|
26059
|
+
const repos = Array.from(repoMap.values());
|
|
26060
|
+
if (repos.length === 0) {
|
|
26061
|
+
const label = version2 ? `${name}@${version2}` : name;
|
|
26062
|
+
console.log(`No repositories found using dependency '${label}'.`);
|
|
26063
|
+
return;
|
|
26064
|
+
}
|
|
26065
|
+
if (options.json) {
|
|
26066
|
+
console.log(JSON.stringify(repos, null, 2));
|
|
26067
|
+
return;
|
|
26068
|
+
}
|
|
26069
|
+
for (const repo of repos) {
|
|
26070
|
+
const versions = repo.versions.join(", ");
|
|
26071
|
+
console.log(`${repo.fullName} (${versions})`);
|
|
26072
|
+
}
|
|
26073
|
+
}
|
|
26001
26074
|
function createListCommand2() {
|
|
26002
26075
|
return addRepositoryFilterOptions(
|
|
26003
26076
|
new Command("list").description("List repositories in your organization")
|