@herodevs/cli 2.0.0-beta.3 → 2.0.0-beta.5
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 +142 -110
- package/bin/main.js +2 -2
- package/dist/api/gql-operations.d.ts +2 -0
- package/dist/api/gql-operations.js +36 -0
- package/dist/api/nes.client.d.ts +12 -0
- package/dist/api/nes.client.js +71 -0
- package/dist/commands/scan/eol.d.ts +12 -20
- package/dist/commands/scan/eol.js +162 -148
- package/dist/config/constants.d.ts +9 -3
- package/dist/config/constants.js +19 -3
- package/dist/hooks/finally.d.ts +3 -0
- package/dist/hooks/finally.js +14 -0
- package/dist/hooks/prerun.js +12 -0
- package/dist/service/analytics.svc.d.ts +28 -0
- package/dist/service/analytics.svc.js +112 -0
- package/dist/service/{eol/cdx.svc.d.ts → cdx.svc.d.ts} +8 -16
- package/dist/service/{eol/cdx.svc.js → cdx.svc.js} +17 -7
- package/dist/service/display.svc.d.ts +22 -0
- package/dist/service/display.svc.js +72 -0
- package/dist/service/file.svc.d.ts +20 -0
- package/dist/service/file.svc.js +71 -0
- package/dist/service/log.svc.d.ts +1 -0
- package/dist/service/log.svc.js +9 -0
- package/dist/service/{eol/sbom.worker.js → sbom.worker.js} +2 -1
- package/package.json +24 -17
- package/dist/api/client.d.ts +0 -12
- package/dist/api/client.js +0 -43
- package/dist/api/nes/nes.client.d.ts +0 -24
- package/dist/api/nes/nes.client.js +0 -127
- package/dist/api/queries/nes/sbom.d.ts +0 -3
- package/dist/api/queries/nes/sbom.js +0 -36
- package/dist/api/queries/nes/telemetry.d.ts +0 -2
- package/dist/api/queries/nes/telemetry.js +0 -24
- package/dist/api/types/hd-cli.types.d.ts +0 -31
- package/dist/api/types/hd-cli.types.js +0 -10
- package/dist/api/types/nes.types.d.ts +0 -54
- package/dist/api/types/nes.types.js +0 -1
- package/dist/commands/report/committers.d.ts +0 -23
- package/dist/commands/report/committers.js +0 -146
- package/dist/commands/report/purls.d.ts +0 -15
- package/dist/commands/report/purls.js +0 -84
- package/dist/commands/scan/sbom.d.ts +0 -21
- package/dist/commands/scan/sbom.js +0 -159
- package/dist/service/committers.svc.d.ts +0 -70
- package/dist/service/committers.svc.js +0 -196
- package/dist/service/eol/eol.svc.d.ts +0 -14
- package/dist/service/eol/eol.svc.js +0 -49
- package/dist/service/error.svc.d.ts +0 -8
- package/dist/service/error.svc.js +0 -28
- package/dist/service/nes/nes.svc.d.ts +0 -5
- package/dist/service/nes/nes.svc.js +0 -28
- package/dist/service/purls.svc.d.ts +0 -23
- package/dist/service/purls.svc.js +0 -99
- package/dist/ui/date.ui.d.ts +0 -1
- package/dist/ui/date.ui.js +0 -15
- package/dist/ui/eol.ui.d.ts +0 -15
- package/dist/ui/eol.ui.js +0 -134
- package/dist/ui/shared.ui.d.ts +0 -6
- package/dist/ui/shared.ui.js +0 -16
- /package/dist/service/{eol/sbom.worker.d.ts → sbom.worker.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -14,8 +14,8 @@ The HeroDevs CLI
|
|
|
14
14
|
|
|
15
15
|
1. Install node v20 or higher: [Download Node](https://nodejs.org/en/download)
|
|
16
16
|
1. Install the CLI using one of the following methods:
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
* Globally: Refer to the [Usage](#usage) instructions on installing the CLI globally
|
|
18
|
+
* npx: `npx @herodevs/cli@beta`
|
|
19
19
|
1. Refer to the [Commands](#commands) section for a list of commands
|
|
20
20
|
|
|
21
21
|
## TERMS
|
|
@@ -24,13 +24,12 @@ Use of this CLI is governed by the [HeroDevs End of Life Dataset Terms of Servic
|
|
|
24
24
|
|
|
25
25
|
## Scanning Behavior
|
|
26
26
|
|
|
27
|
-
The CLI
|
|
27
|
+
The CLI is designed to be non-invasive:
|
|
28
28
|
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* It does not install dependencies or modify package manager files (package-lock.json, yarn.lock, etc.)
|
|
30
|
+
* It analyzes the project in its current state
|
|
31
31
|
* If you need dependencies installed for accurate scanning, please install them manually before running the scan
|
|
32
32
|
|
|
33
|
-
|
|
34
33
|
## Usage
|
|
35
34
|
<!-- usage -->
|
|
36
35
|
```sh-session
|
|
@@ -38,7 +37,7 @@ $ npm install -g @herodevs/cli
|
|
|
38
37
|
$ hd COMMAND
|
|
39
38
|
running command...
|
|
40
39
|
$ hd (--version)
|
|
41
|
-
@herodevs/cli/2.0.0-beta.
|
|
40
|
+
@herodevs/cli/2.0.0-beta.5 linux-x64 node-v22.18.0
|
|
42
41
|
$ hd --help [COMMAND]
|
|
43
42
|
USAGE
|
|
44
43
|
$ hd COMMAND
|
|
@@ -48,10 +47,7 @@ USAGE
|
|
|
48
47
|
## Commands
|
|
49
48
|
<!-- commands -->
|
|
50
49
|
* [`hd help [COMMAND]`](#hd-help-command)
|
|
51
|
-
* [`hd report committers`](#hd-report-committers)
|
|
52
|
-
* [`hd report purls`](#hd-report-purls)
|
|
53
50
|
* [`hd scan eol`](#hd-scan-eol)
|
|
54
|
-
* [`hd scan sbom`](#hd-scan-sbom)
|
|
55
51
|
* [`hd update [CHANNEL]`](#hd-update-channel)
|
|
56
52
|
|
|
57
53
|
## `hd help [COMMAND]`
|
|
@@ -72,170 +68,206 @@ DESCRIPTION
|
|
|
72
68
|
Display help for hd.
|
|
73
69
|
```
|
|
74
70
|
|
|
75
|
-
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.
|
|
71
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.32/src/commands/help.ts)_
|
|
76
72
|
|
|
77
|
-
## `hd
|
|
73
|
+
## `hd scan eol`
|
|
78
74
|
|
|
79
|
-
|
|
75
|
+
Scan a given SBOM for EOL data
|
|
80
76
|
|
|
81
77
|
```
|
|
82
78
|
USAGE
|
|
83
|
-
$ hd
|
|
79
|
+
$ hd scan eol [--json] [-f <value> | -d <value>] [-s] [--saveSbom]
|
|
84
80
|
|
|
85
81
|
FLAGS
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-s, --save
|
|
82
|
+
-d, --dir=<value> [default: <current directory>] The directory to scan in order to create a cyclonedx SBOM
|
|
83
|
+
-f, --file=<value> The file path of an existing cyclonedx SBOM to scan for EOL
|
|
84
|
+
-s, --save Save the generated report as herodevs.report.json in the scanned directory
|
|
85
|
+
--saveSbom Save the generated SBOM as herodevs.sbom.json in the scanned directory
|
|
89
86
|
|
|
90
87
|
GLOBAL FLAGS
|
|
91
88
|
--json Format output as json.
|
|
92
89
|
|
|
93
90
|
DESCRIPTION
|
|
94
|
-
|
|
91
|
+
Scan a given SBOM for EOL data
|
|
95
92
|
|
|
96
93
|
EXAMPLES
|
|
97
|
-
|
|
94
|
+
Default behavior (no command or flags specified)
|
|
95
|
+
|
|
96
|
+
$ hd
|
|
97
|
+
|
|
98
|
+
Equivalent to
|
|
99
|
+
|
|
100
|
+
$ hd scan eol --dir .
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
Skip SBOM generation and specify an existing file
|
|
100
103
|
|
|
101
|
-
|
|
104
|
+
$ hd scan eol --file /path/to/sbom.json
|
|
102
105
|
|
|
103
|
-
|
|
106
|
+
Save the report or SBOM to a file
|
|
107
|
+
|
|
108
|
+
$ hd scan eol --save --saveSbom
|
|
109
|
+
|
|
110
|
+
Output the report in JSON format (for APIs, CI, etc.)
|
|
111
|
+
|
|
112
|
+
$ hd scan eol --json
|
|
104
113
|
```
|
|
105
114
|
|
|
106
|
-
_See code: [src/commands/
|
|
115
|
+
_See code: [src/commands/scan/eol.ts](https://github.com/herodevs/cli/blob/v2.0.0-beta.5/src/commands/scan/eol.ts)_
|
|
107
116
|
|
|
108
|
-
## `hd
|
|
117
|
+
## `hd update [CHANNEL]`
|
|
109
118
|
|
|
110
|
-
|
|
119
|
+
update the hd CLI
|
|
111
120
|
|
|
112
121
|
```
|
|
113
122
|
USAGE
|
|
114
|
-
$ hd
|
|
123
|
+
$ hd update [CHANNEL] [--force | | [-a | -v <value> | -i]] [-b ]
|
|
115
124
|
|
|
116
125
|
FLAGS
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
|
|
122
|
-
GLOBAL FLAGS
|
|
123
|
-
--json Format output as json.
|
|
126
|
+
-a, --available See available versions.
|
|
127
|
+
-b, --verbose Show more details about the available versions.
|
|
128
|
+
-i, --interactive Interactively select version to install. This is ignored if a channel is provided.
|
|
129
|
+
-v, --version=<value> Install a specific version.
|
|
130
|
+
--force Force a re-download of the requested version.
|
|
124
131
|
|
|
125
132
|
DESCRIPTION
|
|
126
|
-
|
|
133
|
+
update the hd CLI
|
|
127
134
|
|
|
128
135
|
EXAMPLES
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
$ hd report purls --dir=./my-project
|
|
136
|
+
Update to the stable channel:
|
|
132
137
|
|
|
133
|
-
|
|
138
|
+
$ hd update stable
|
|
134
139
|
|
|
135
|
-
|
|
140
|
+
Update to a specific version:
|
|
136
141
|
|
|
137
|
-
|
|
138
|
-
```
|
|
142
|
+
$ hd update --version 1.0.0
|
|
139
143
|
|
|
140
|
-
|
|
144
|
+
Interactively select version:
|
|
141
145
|
|
|
142
|
-
|
|
146
|
+
$ hd update --interactive
|
|
143
147
|
|
|
144
|
-
|
|
148
|
+
See available versions:
|
|
145
149
|
|
|
150
|
+
$ hd update --available
|
|
146
151
|
```
|
|
147
|
-
USAGE
|
|
148
|
-
$ hd scan eol [--json] [-f <value>] [-p <value>] [-d <value>] [-s] [-a] [-t]
|
|
149
|
-
|
|
150
|
-
FLAGS
|
|
151
|
-
-a, --all Show all components (default is EOL and SUPPORTED only)
|
|
152
|
-
-d, --dir=<value> The directory to scan in order to create a cyclonedx sbom
|
|
153
|
-
-f, --file=<value> The file path of an existing cyclonedx sbom to scan for EOL
|
|
154
|
-
-p, --purls=<value> The file path of a list of purls to scan for EOL
|
|
155
|
-
-s, --save Save the generated report as eol.report.json in the scanned directory
|
|
156
|
-
-t, --table Display the results in a table
|
|
157
152
|
|
|
158
|
-
|
|
159
|
-
|
|
153
|
+
_See code: [@oclif/plugin-update](https://github.com/oclif/plugin-update/blob/v4.7.4/src/commands/update.ts)_
|
|
154
|
+
<!-- commandsstop -->
|
|
160
155
|
|
|
161
|
-
|
|
162
|
-
Scan a given sbom for EOL data
|
|
156
|
+
## CI/CD Usage
|
|
163
157
|
|
|
164
|
-
|
|
165
|
-
$ hd scan eol --dir=./my-project
|
|
158
|
+
You can use `@herodevs/cli` in your CI/CD pipelines to automate EOL scanning.
|
|
166
159
|
|
|
167
|
-
|
|
160
|
+
### Using the Docker Image (recommended)
|
|
168
161
|
|
|
169
|
-
|
|
162
|
+
We provide a Docker image that's pre-configured to run EOL scans. Based on [`cdxgen`](https://github.com/CycloneDX/cdxgen),
|
|
163
|
+
it contains build tools for most project types and will provide best results when generating an SBOM. Use these templates to generate a report and save it to your CI job artifact for analysis and processing after your scan runs.
|
|
170
164
|
|
|
171
|
-
|
|
172
|
-
```
|
|
165
|
+
#### GitHub Actions
|
|
173
166
|
|
|
174
|
-
|
|
167
|
+
```yaml
|
|
168
|
+
## .github/workflows/herodevs-eol-scan.yml
|
|
169
|
+
name: HeroDevs EOL Scan
|
|
175
170
|
|
|
176
|
-
|
|
171
|
+
on:
|
|
172
|
+
push:
|
|
173
|
+
branches: [ main ]
|
|
174
|
+
pull_request:
|
|
175
|
+
branches: [ main ]
|
|
177
176
|
|
|
178
|
-
|
|
177
|
+
jobs:
|
|
178
|
+
scan:
|
|
179
|
+
runs-on: ubuntu-latest
|
|
180
|
+
steps:
|
|
181
|
+
- uses: actions/checkout@v4
|
|
179
182
|
|
|
183
|
+
- name: Run EOL Scan with Docker
|
|
184
|
+
uses: docker://ghcr.io/herodevs/eol-scan
|
|
185
|
+
with:
|
|
186
|
+
args: "-s"
|
|
187
|
+
|
|
188
|
+
- name: Upload artifact
|
|
189
|
+
uses: actions/upload-artifact@v4
|
|
190
|
+
with:
|
|
191
|
+
name: my-eol-report
|
|
192
|
+
path: herodevs.report.json
|
|
180
193
|
```
|
|
181
|
-
USAGE
|
|
182
|
-
$ hd scan sbom [--json] [-f <value>] [-d <value>] [-s] [-b]
|
|
183
194
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
195
|
+
#### GitLab CI/CD
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
eol-scan:
|
|
199
|
+
image:
|
|
200
|
+
name: "ghcr.io/herodevs/eol-scan"
|
|
201
|
+
# Entrypoint or base command must be disabled due
|
|
202
|
+
# to GitLab's execution mechanism and run manually
|
|
203
|
+
entrypoint: [""]
|
|
204
|
+
script: "npx @herodevs/cli@beta scan eol -s"
|
|
205
|
+
artifacts:
|
|
206
|
+
paths:
|
|
207
|
+
- herodevs.report.json
|
|
208
|
+
```
|
|
189
209
|
|
|
190
|
-
|
|
191
|
-
--json Format output as json.
|
|
210
|
+
### Using `npx`
|
|
192
211
|
|
|
193
|
-
|
|
194
|
-
Scan a SBOM for purls
|
|
212
|
+
You can use `npx` to run the CLI just like you'd run it locally.
|
|
195
213
|
|
|
196
|
-
|
|
197
|
-
|
|
214
|
+
> [!NOTE]
|
|
215
|
+
> The development environment is expected to be ready to run the app. For best results,
|
|
216
|
+
prefer [using the prebuilt image](#using-the-docker-image-recommended), but otherwise, prepare
|
|
217
|
+
all requirements before the scan step.
|
|
198
218
|
|
|
199
|
-
|
|
200
|
-
```
|
|
219
|
+
#### GitHub Actions
|
|
201
220
|
|
|
202
|
-
|
|
221
|
+
```yaml
|
|
222
|
+
## .github/workflows/herodevs-eol-scan.yml
|
|
223
|
+
name: HeroDevs EOL Scan
|
|
203
224
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
225
|
+
on:
|
|
226
|
+
push:
|
|
227
|
+
branches: [ main ]
|
|
228
|
+
pull_request:
|
|
229
|
+
branches: [ main ]
|
|
207
230
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
-v, --version=<value> Install a specific version.
|
|
217
|
-
--force Force a re-download of the requested version.
|
|
231
|
+
jobs:
|
|
232
|
+
scan:
|
|
233
|
+
runs-on: ubuntu-latest
|
|
234
|
+
steps:
|
|
235
|
+
- uses: actions/checkout@v4
|
|
236
|
+
- uses: actions/setup-node@v4
|
|
237
|
+
with:
|
|
238
|
+
node-version: '20'
|
|
218
239
|
|
|
219
|
-
|
|
220
|
-
update the hd CLI
|
|
240
|
+
- run: echo # Prepare environment, install tooling, perform setup, etc.
|
|
221
241
|
|
|
222
|
-
|
|
223
|
-
|
|
242
|
+
- name: Run EOL Scan
|
|
243
|
+
run: npx @herodevs/cli@beta
|
|
224
244
|
|
|
225
|
-
|
|
245
|
+
- name: Upload artifact
|
|
246
|
+
uses: actions/upload-artifact@v4
|
|
247
|
+
with:
|
|
248
|
+
name: my-eol-report
|
|
249
|
+
path: herodevs.report.json
|
|
250
|
+
```
|
|
226
251
|
|
|
227
|
-
|
|
252
|
+
#### GitLab CI/CD
|
|
228
253
|
|
|
229
|
-
|
|
254
|
+
```yaml
|
|
255
|
+
image: alpine
|
|
230
256
|
|
|
231
|
-
|
|
257
|
+
eol-scan:
|
|
258
|
+
script:
|
|
259
|
+
- echo # Prepare environment, install tooling, perform setup, etc.
|
|
260
|
+
- npx @herodevs/cli@beta scan eol -s
|
|
261
|
+
artifacts:
|
|
262
|
+
paths:
|
|
263
|
+
- herodevs.report.json
|
|
264
|
+
```
|
|
232
265
|
|
|
233
|
-
|
|
266
|
+
## Local Docker image scans
|
|
234
267
|
|
|
235
|
-
|
|
268
|
+
The same pre-configured image can be pulled locally to scan in an optimized environment. Mount your code
|
|
269
|
+
to `/app` or a specified working directory to perform the scan:
|
|
236
270
|
|
|
237
|
-
|
|
271
|
+
```shell
|
|
272
|
+
docker run -v "$PWD":/app ghcr.io/herodevs/eol-scan
|
|
238
273
|
```
|
|
239
|
-
|
|
240
|
-
_See code: [@oclif/plugin-update](https://github.com/oclif/plugin-update/blob/v4.6.42/src/commands/update.ts)_
|
|
241
|
-
<!-- commandsstop -->
|
package/bin/main.js
CHANGED
|
@@ -7,9 +7,9 @@ async function main(isProduction = false) {
|
|
|
7
7
|
strict: false, // Don't validate flags
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
// If no arguments at all, default to scan:eol
|
|
10
|
+
// If no arguments at all, default to scan:eol
|
|
11
11
|
if (positionals.length === 0) {
|
|
12
|
-
process.argv.splice(2, 0, 'scan:eol'
|
|
12
|
+
process.argv.splice(2, 0, 'scan:eol');
|
|
13
13
|
}
|
|
14
14
|
// If only flags are provided, set scan:eol as the command for those flags
|
|
15
15
|
else if (positionals.length === 1 && positionals[0].startsWith('-')) {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { gql } from '@apollo/client/core/core.cjs';
|
|
2
|
+
export const createReportMutation = gql `
|
|
3
|
+
mutation createReport($input: CreateEolReportInput) {
|
|
4
|
+
eol {
|
|
5
|
+
createReport(input: $input) {
|
|
6
|
+
success
|
|
7
|
+
id
|
|
8
|
+
totalRecords
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
export const getEolReportQuery = gql `
|
|
14
|
+
query GetEolReport($input: GetEolReportInput) {
|
|
15
|
+
eol {
|
|
16
|
+
report(input: $input) {
|
|
17
|
+
id
|
|
18
|
+
createdOn
|
|
19
|
+
metadata
|
|
20
|
+
components {
|
|
21
|
+
purl
|
|
22
|
+
metadata
|
|
23
|
+
nesRemediation {
|
|
24
|
+
remediations {
|
|
25
|
+
urls {
|
|
26
|
+
main
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
page
|
|
32
|
+
totalRecords
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ApolloClient } from '@apollo/client/core/index.js';
|
|
2
|
+
import type { CreateEolReportInput, EolReport } from '@herodevs/eol-shared';
|
|
3
|
+
export declare const createApollo: (uri: string) => ApolloClient<import("@apollo/client/core/index.js").NormalizedCacheObject>;
|
|
4
|
+
export declare const SbomScanner: (client: ReturnType<typeof createApollo>) => (input: CreateEolReportInput) => Promise<EolReport>;
|
|
5
|
+
export declare class NesClient {
|
|
6
|
+
startScan: ReturnType<typeof SbomScanner>;
|
|
7
|
+
constructor(url: string);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Submit a scan for a list of purls
|
|
11
|
+
*/
|
|
12
|
+
export declare function submitScan(input: CreateEolReportInput): Promise<EolReport>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client/core/index.js';
|
|
2
|
+
import { config } from "../config/constants.js";
|
|
3
|
+
import { debugLogger } from "../service/log.svc.js";
|
|
4
|
+
import { createReportMutation, getEolReportQuery } from "./gql-operations.js";
|
|
5
|
+
export const createApollo = (uri) => new ApolloClient({
|
|
6
|
+
cache: new InMemoryCache({ addTypename: false }),
|
|
7
|
+
defaultOptions: {
|
|
8
|
+
query: { fetchPolicy: 'no-cache' },
|
|
9
|
+
},
|
|
10
|
+
link: new HttpLink({
|
|
11
|
+
uri,
|
|
12
|
+
headers: {
|
|
13
|
+
'User-Agent': `hdcli/${process.env.npm_package_version ?? 'unknown'}`,
|
|
14
|
+
},
|
|
15
|
+
}),
|
|
16
|
+
});
|
|
17
|
+
export const SbomScanner = (client) => {
|
|
18
|
+
return async (input) => {
|
|
19
|
+
const res = await client.mutate({
|
|
20
|
+
mutation: createReportMutation,
|
|
21
|
+
variables: { input },
|
|
22
|
+
});
|
|
23
|
+
const result = res.data?.eol?.createReport;
|
|
24
|
+
if (!result?.success || !result.id) {
|
|
25
|
+
debugLogger('failed scan %o', result || {});
|
|
26
|
+
throw new Error('Failed to create EOL report');
|
|
27
|
+
}
|
|
28
|
+
const totalRecords = result.totalRecords || 0;
|
|
29
|
+
const totalPages = Math.ceil(totalRecords / config.pageSize);
|
|
30
|
+
const pages = Array.from({ length: totalPages }, (_, index) => client.query({
|
|
31
|
+
query: getEolReportQuery,
|
|
32
|
+
variables: {
|
|
33
|
+
input: {
|
|
34
|
+
id: result.id,
|
|
35
|
+
page: index + 1,
|
|
36
|
+
size: config.pageSize,
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
const components = [];
|
|
41
|
+
let reportMetadata = null;
|
|
42
|
+
for (let i = 0; i < pages.length; i += config.concurrentPageRequests) {
|
|
43
|
+
const batch = pages.slice(i, i + config.concurrentPageRequests);
|
|
44
|
+
const batchResponses = await Promise.all(batch);
|
|
45
|
+
for (const response of batchResponses) {
|
|
46
|
+
const report = response.data.eol.report;
|
|
47
|
+
reportMetadata ??= report;
|
|
48
|
+
components.push(...(report?.components ?? []));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (!reportMetadata) {
|
|
52
|
+
throw new Error('Failed to fetch EOL report');
|
|
53
|
+
}
|
|
54
|
+
return { ...reportMetadata, components };
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export class NesClient {
|
|
58
|
+
startScan;
|
|
59
|
+
constructor(url) {
|
|
60
|
+
this.startScan = SbomScanner(createApollo(url));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Submit a scan for a list of purls
|
|
65
|
+
*/
|
|
66
|
+
export function submitScan(input) {
|
|
67
|
+
const url = config.graphqlHost + config.graphqlPath;
|
|
68
|
+
debugLogger('Submitting scan to %s', url);
|
|
69
|
+
const client = new NesClient(url);
|
|
70
|
+
return client.startScan(input);
|
|
71
|
+
}
|
|
@@ -1,32 +1,24 @@
|
|
|
1
|
+
import type { EolReport } from '@herodevs/eol-shared';
|
|
1
2
|
import { Command } from '@oclif/core';
|
|
2
|
-
import type { InsightsEolScanComponent } from '../../api/types/nes.types.ts';
|
|
3
3
|
export default class ScanEol extends Command {
|
|
4
4
|
static description: string;
|
|
5
5
|
static enableJsonFlag: boolean;
|
|
6
|
-
static examples:
|
|
6
|
+
static examples: {
|
|
7
|
+
description: string;
|
|
8
|
+
command: string;
|
|
9
|
+
}[];
|
|
7
10
|
static flags: {
|
|
8
11
|
file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
-
|
|
10
|
-
dir: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
dir: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
13
|
save: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
|
|
13
|
-
table: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
saveSbom: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
15
|
};
|
|
15
|
-
run(): Promise<
|
|
16
|
-
|
|
17
|
-
createdOn: string;
|
|
18
|
-
}>;
|
|
19
|
-
private getScan;
|
|
20
|
-
private getPurlsFromFile;
|
|
21
|
-
private printWebReportUrl;
|
|
16
|
+
run(): Promise<EolReport | undefined>;
|
|
17
|
+
private loadSbom;
|
|
22
18
|
private scanSbom;
|
|
23
|
-
private getFilteredComponents;
|
|
24
19
|
private saveReport;
|
|
20
|
+
private saveSbom;
|
|
25
21
|
private displayResults;
|
|
26
|
-
private
|
|
27
|
-
private
|
|
28
|
-
private displayNoComponentsMessage;
|
|
29
|
-
private logLine;
|
|
30
|
-
private displayStatusSection;
|
|
31
|
-
private logLegend;
|
|
22
|
+
private getSbomFromScan;
|
|
23
|
+
private getSbomFromFile;
|
|
32
24
|
}
|