@socketsecurity/cli 0.9.3 → 0.10.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/cli.js +2 -0
- package/lib/commands/audit-log/index.js +162 -0
- package/lib/commands/cdxgen/index.js +211 -0
- package/lib/commands/dependencies/index.js +150 -0
- package/lib/commands/index.js +9 -4
- package/lib/commands/info/index.js +123 -81
- package/lib/commands/login/index.js +1 -1
- package/lib/commands/logout/index.js +1 -1
- package/lib/commands/npm/index.js +8 -3
- package/lib/commands/npx/index.js +1 -1
- package/lib/commands/report/create.js +1 -1
- package/lib/commands/report/index.js +1 -1
- package/lib/commands/report/view.js +1 -1
- package/lib/commands/repos/create.js +166 -0
- package/lib/commands/repos/delete.js +93 -0
- package/lib/commands/repos/index.js +30 -0
- package/lib/commands/repos/list.js +170 -0
- package/lib/commands/repos/update.js +166 -0
- package/lib/commands/repos/view.js +128 -0
- package/lib/commands/scan/create.js +245 -0
- package/lib/commands/scan/delete.js +112 -0
- package/lib/commands/scan/index.js +30 -0
- package/lib/commands/scan/list.js +192 -0
- package/lib/commands/scan/metadata.js +113 -0
- package/lib/commands/scan/stream.js +115 -0
- package/lib/commands/wrapper/index.js +1 -1
- package/lib/shadow/npm-injection.cjs +11 -1
- package/lib/utils/format-issues.js +28 -1
- package/lib/utils/meow-with-subcommands.js +1 -2
- package/lib/utils/misc.js +0 -1
- package/lib/utils/path-resolve.js +30 -5
- package/lib/utils/sdk.js +0 -3
- package/package.json +77 -61
package/cli.js
CHANGED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { Separator } from '@inquirer/select'
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
import inquirer from 'inquirer'
|
|
5
|
+
import meow from 'meow'
|
|
6
|
+
import ora from 'ora'
|
|
7
|
+
|
|
8
|
+
import { outputFlags } from '../../flags/index.js'
|
|
9
|
+
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
|
|
10
|
+
import { prepareFlags } from '../../utils/flags.js'
|
|
11
|
+
import { printFlagList } from '../../utils/formatting.js'
|
|
12
|
+
import { FREE_API_KEY, getDefaultKey, setupSdk } from '../../utils/sdk.js'
|
|
13
|
+
|
|
14
|
+
/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
|
|
15
|
+
export const auditlog = {
|
|
16
|
+
description: 'Look up the audit log for an organization',
|
|
17
|
+
async run (argv, importMeta, { parentName }) {
|
|
18
|
+
const name = parentName + ' audit-log'
|
|
19
|
+
|
|
20
|
+
const input = setupCommand(name, auditlog.description, argv, importMeta)
|
|
21
|
+
if (input) {
|
|
22
|
+
const spinner = ora(`Looking up audit log for ${input.orgSlug}\n`).start()
|
|
23
|
+
await fetchOrgAuditLog(input.orgSlug, input, spinner)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const auditLogFlags = prepareFlags({
|
|
29
|
+
type: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
shortFlag: 't',
|
|
32
|
+
default: '',
|
|
33
|
+
description: 'Type of log event',
|
|
34
|
+
},
|
|
35
|
+
perPage: {
|
|
36
|
+
type: 'number',
|
|
37
|
+
shortFlag: 'pp',
|
|
38
|
+
default: 30,
|
|
39
|
+
description: 'Results per page - default is 30',
|
|
40
|
+
},
|
|
41
|
+
page: {
|
|
42
|
+
type: 'number',
|
|
43
|
+
shortFlag: 'p',
|
|
44
|
+
default: 1,
|
|
45
|
+
description: 'Page number - default is 1',
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
// Internal functions
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @typedef CommandInput
|
|
53
|
+
* @property {boolean} outputJson
|
|
54
|
+
* @property {boolean} outputMarkdown
|
|
55
|
+
* @property {string} orgSlug
|
|
56
|
+
* @property {string} type
|
|
57
|
+
* @property {number} page
|
|
58
|
+
* @property {number} per_page
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} name
|
|
63
|
+
* @param {string} description
|
|
64
|
+
* @param {readonly string[]} argv
|
|
65
|
+
* @param {ImportMeta} importMeta
|
|
66
|
+
* @returns {void|CommandInput}
|
|
67
|
+
*/
|
|
68
|
+
function setupCommand (name, description, argv, importMeta) {
|
|
69
|
+
const flags = {
|
|
70
|
+
...auditLogFlags,
|
|
71
|
+
...outputFlags
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const cli = meow(`
|
|
75
|
+
Usage
|
|
76
|
+
$ ${name} <org slug>
|
|
77
|
+
|
|
78
|
+
Options
|
|
79
|
+
${printFlagList(flags, 6)}
|
|
80
|
+
|
|
81
|
+
Examples
|
|
82
|
+
$ ${name} FakeOrg
|
|
83
|
+
`, {
|
|
84
|
+
argv,
|
|
85
|
+
description,
|
|
86
|
+
importMeta,
|
|
87
|
+
flags
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const {
|
|
91
|
+
json: outputJson,
|
|
92
|
+
markdown: outputMarkdown,
|
|
93
|
+
type,
|
|
94
|
+
page,
|
|
95
|
+
perPage
|
|
96
|
+
} = cli.flags
|
|
97
|
+
|
|
98
|
+
if (cli.input.length < 1) {
|
|
99
|
+
console.error(`${chalk.bgRed('Input error')}: Please provide an organization slug \n`)
|
|
100
|
+
cli.showHelp()
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
const [orgSlug = ''] = cli.input
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
outputJson,
|
|
107
|
+
outputMarkdown,
|
|
108
|
+
orgSlug,
|
|
109
|
+
type: type && type.charAt(0).toUpperCase() + type.slice(1),
|
|
110
|
+
page,
|
|
111
|
+
per_page: perPage
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @typedef AuditLogData
|
|
117
|
+
* @property {import('@socketsecurity/sdk').SocketSdkReturnType<'getAuditLogEvents'>["data"]} data
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {string} orgSlug
|
|
122
|
+
* @param {CommandInput} input
|
|
123
|
+
* @param {import('ora').Ora} spinner
|
|
124
|
+
* @returns {Promise<void|AuditLogData>}
|
|
125
|
+
*/
|
|
126
|
+
async function fetchOrgAuditLog (orgSlug, input, spinner) {
|
|
127
|
+
const socketSdk = await setupSdk(getDefaultKey() || FREE_API_KEY)
|
|
128
|
+
const result = await handleApiCall(socketSdk.getAuditLogEvents(orgSlug, input), `Looking up audit log for ${orgSlug}\n`)
|
|
129
|
+
|
|
130
|
+
if (!result.success) {
|
|
131
|
+
return handleUnsuccessfulApiResponse('getAuditLogEvents', result, spinner)
|
|
132
|
+
}
|
|
133
|
+
spinner.stop()
|
|
134
|
+
|
|
135
|
+
const /** @type {({name: string} | Separator)[]} */ data = []
|
|
136
|
+
const /** @type {{[key: string]: string}} */ logDetails = {}
|
|
137
|
+
|
|
138
|
+
result.data.results.map(d => {
|
|
139
|
+
data.push({
|
|
140
|
+
name: `${d.created_at && new Date(d.created_at).toLocaleDateString('en-us', { year: 'numeric', month: 'numeric', day: 'numeric' })} - ${d.user_email} - ${d.type} - ${d.ip_address} - ${d.user_agent}`
|
|
141
|
+
}, new Separator())
|
|
142
|
+
|
|
143
|
+
logDetails[`${d.created_at && new Date(d.created_at).toLocaleDateString('en-us', { year: 'numeric', month: 'numeric', day: 'numeric' })} - ${d.user_email} - ${d.type} - ${d.ip_address} - ${d.user_agent}`] = JSON.stringify(d.payload)
|
|
144
|
+
return data
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
inquirer
|
|
148
|
+
.prompt(
|
|
149
|
+
{
|
|
150
|
+
type: 'list',
|
|
151
|
+
name: 'log',
|
|
152
|
+
message: input.type ? `\n Audit log for: ${orgSlug} with type: ${input.type} \n` : `\n Audit log for: ${orgSlug} \n`,
|
|
153
|
+
choices: data,
|
|
154
|
+
pageSize: 30
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
.then((/** @type {{log: string}} */ answers) => console.log(logDetails[answers.log]))
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
data: result.data
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
3
|
+
import { existsSync, promises as fs } from 'node:fs'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
import { fileURLToPath } from 'node:url'
|
|
6
|
+
|
|
7
|
+
import chalk from 'chalk'
|
|
8
|
+
import { $ } from 'execa'
|
|
9
|
+
import yargsParse from 'yargs-parser'
|
|
10
|
+
|
|
11
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
SBOM_SIGN_ALGORITHM, // Algorithm. Example: RS512
|
|
15
|
+
SBOM_SIGN_PRIVATE_KEY, // Location to the RSA private key
|
|
16
|
+
SBOM_SIGN_PUBLIC_KEY // Optional. Location to the RSA public key
|
|
17
|
+
} = process.env
|
|
18
|
+
|
|
19
|
+
const toLower = (/** @type {string} */ arg) => arg.toLowerCase()
|
|
20
|
+
const arrayToLower = (/** @type {string[]} */ arg) => arg.map(toLower)
|
|
21
|
+
|
|
22
|
+
const execaConfig = {
|
|
23
|
+
env: { NODE_ENV: '' },
|
|
24
|
+
localDir: path.join(__dirname, 'node_modules'),
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const nodejsPlatformTypes = [
|
|
28
|
+
'javascript',
|
|
29
|
+
'js',
|
|
30
|
+
'nodejs',
|
|
31
|
+
'npm',
|
|
32
|
+
'pnpm',
|
|
33
|
+
'ts',
|
|
34
|
+
'tsx',
|
|
35
|
+
'typescript'
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
const yargsConfig = {
|
|
39
|
+
configuration: {
|
|
40
|
+
'camel-case-expansion': false,
|
|
41
|
+
'strip-aliased': true,
|
|
42
|
+
'parse-numbers': false,
|
|
43
|
+
'populate--': true,
|
|
44
|
+
'unknown-options-as-args': true
|
|
45
|
+
},
|
|
46
|
+
coerce: {
|
|
47
|
+
author: arrayToLower,
|
|
48
|
+
filter: arrayToLower,
|
|
49
|
+
only: arrayToLower,
|
|
50
|
+
profile: toLower,
|
|
51
|
+
standard: arrayToLower,
|
|
52
|
+
type: toLower
|
|
53
|
+
},
|
|
54
|
+
default: {
|
|
55
|
+
//author: ['OWASP Foundation'],
|
|
56
|
+
//'auto-compositions': true,
|
|
57
|
+
//babel: true,
|
|
58
|
+
//evidence: false,
|
|
59
|
+
//'include-crypto': false,
|
|
60
|
+
//'include-formulation': false,
|
|
61
|
+
//'install-deps': true,
|
|
62
|
+
//output: 'bom.json',
|
|
63
|
+
//profile: 'generic',
|
|
64
|
+
//'project-version': '',
|
|
65
|
+
//recurse: true,
|
|
66
|
+
//'server-host': '127.0.0.1',
|
|
67
|
+
//'server-port': '9090',
|
|
68
|
+
//'spec-version': '1.5',
|
|
69
|
+
type: 'js',
|
|
70
|
+
//validate: true,
|
|
71
|
+
},
|
|
72
|
+
alias: {
|
|
73
|
+
help: ['h'],
|
|
74
|
+
output: ['o'],
|
|
75
|
+
print: ['p'],
|
|
76
|
+
recurse: ['r'],
|
|
77
|
+
'resolve-class': ['c'],
|
|
78
|
+
type: ['t'],
|
|
79
|
+
version: ['v'],
|
|
80
|
+
},
|
|
81
|
+
array: [
|
|
82
|
+
{ key: 'author', type: 'string' },
|
|
83
|
+
{ key: 'exclude', type: 'string' },
|
|
84
|
+
{ key: 'filter', type: 'string' },
|
|
85
|
+
{ key: 'only', type: 'string' },
|
|
86
|
+
{ key: 'standard', type: 'string' }
|
|
87
|
+
],
|
|
88
|
+
boolean: [
|
|
89
|
+
'auto-compositions',
|
|
90
|
+
'babel',
|
|
91
|
+
'deep',
|
|
92
|
+
'evidence',
|
|
93
|
+
'fail-on-error',
|
|
94
|
+
'generate-key-and-sign',
|
|
95
|
+
'help',
|
|
96
|
+
'include-formulation',
|
|
97
|
+
'include-crypto',
|
|
98
|
+
'install-deps',
|
|
99
|
+
'print',
|
|
100
|
+
'required-only',
|
|
101
|
+
'server',
|
|
102
|
+
'validate',
|
|
103
|
+
'version',
|
|
104
|
+
],
|
|
105
|
+
string: [
|
|
106
|
+
'api-key',
|
|
107
|
+
'output',
|
|
108
|
+
'parent-project-id',
|
|
109
|
+
'profile',
|
|
110
|
+
'project-group',
|
|
111
|
+
'project-name',
|
|
112
|
+
'project-version',
|
|
113
|
+
'project-id',
|
|
114
|
+
'server-host',
|
|
115
|
+
'server-port',
|
|
116
|
+
'server-url',
|
|
117
|
+
'spec-version',
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
*
|
|
123
|
+
* @param {{ [key: string]: boolean | null | number | string | (string | number)[]}} argv
|
|
124
|
+
* @returns {string[]}
|
|
125
|
+
*/
|
|
126
|
+
function argvToArray (/** @type {any} */ argv) {
|
|
127
|
+
if (argv['help']) return ['--help']
|
|
128
|
+
const result = []
|
|
129
|
+
for (const { 0: key, 1: value } of Object.entries(argv)) {
|
|
130
|
+
if (key === '_' || key === '--') continue
|
|
131
|
+
if (key === 'babel' || key === 'install-deps' || key === 'validate') {
|
|
132
|
+
// cdxgen documents no-babel, no-install-deps, and no-validate flags so
|
|
133
|
+
// use them when relevant.
|
|
134
|
+
result.push(`--${value ? key : `no-${key}`}`)
|
|
135
|
+
} else if (value === true) {
|
|
136
|
+
result.push(`--${key}`)
|
|
137
|
+
} else if (typeof value === 'string') {
|
|
138
|
+
result.push(`--${key}=${value}`)
|
|
139
|
+
} else if (Array.isArray(value)) {
|
|
140
|
+
result.push(`--${key}`, ...value.map(String))
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (argv['--']) {
|
|
144
|
+
result.push('--', ...argv['--'])
|
|
145
|
+
}
|
|
146
|
+
return result
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
|
|
150
|
+
export const cdxgen = {
|
|
151
|
+
description: 'Create an SBOM with CycloneDX generator (cdxgen)',
|
|
152
|
+
async run (argv_) {
|
|
153
|
+
const /** @type {any} */ yargv = {
|
|
154
|
+
__proto__: null,
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
...yargsParse(argv_, yargsConfig)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const /** @type {string[]} */ unknown = yargv._
|
|
160
|
+
const { length: unknownLength } = unknown
|
|
161
|
+
if (unknownLength) {
|
|
162
|
+
console.error(`Unknown argument${unknownLength > 1 ? 's' : ''}: ${yargv._.join(', ')}`)
|
|
163
|
+
process.exitCode = 1
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let cleanupPackageLock = false
|
|
168
|
+
if (
|
|
169
|
+
yargv.type !== 'yarn' &&
|
|
170
|
+
nodejsPlatformTypes.includes(yargv.type) &&
|
|
171
|
+
existsSync('./yarn.lock')
|
|
172
|
+
) {
|
|
173
|
+
if (existsSync('./package-lock.json')) {
|
|
174
|
+
yargv.type = 'npm'
|
|
175
|
+
} else {
|
|
176
|
+
// Use synp to create a package-lock.json from the yarn.lock,
|
|
177
|
+
// based on the node_modules folder, for a more accurate SBOM.
|
|
178
|
+
try {
|
|
179
|
+
await $(execaConfig)`synp --source-file ./yarn.lock`
|
|
180
|
+
yargv.type = 'npm'
|
|
181
|
+
cleanupPackageLock = true
|
|
182
|
+
} catch {}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (yargv.output === undefined) {
|
|
187
|
+
yargv.output = 'socket-cdx.json'
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
await $({
|
|
191
|
+
...execaConfig,
|
|
192
|
+
env: {
|
|
193
|
+
NODE_ENV: '',
|
|
194
|
+
SBOM_SIGN_ALGORITHM,
|
|
195
|
+
SBOM_SIGN_PRIVATE_KEY,
|
|
196
|
+
SBOM_SIGN_PUBLIC_KEY
|
|
197
|
+
},
|
|
198
|
+
stdout: 'inherit'
|
|
199
|
+
})`cdxgen ${argvToArray(yargv)}`
|
|
200
|
+
|
|
201
|
+
if (cleanupPackageLock) {
|
|
202
|
+
try {
|
|
203
|
+
await fs.unlink('./package-lock.json')
|
|
204
|
+
} catch {}
|
|
205
|
+
}
|
|
206
|
+
const fullOutputPath = path.join(process.cwd(), yargv.output)
|
|
207
|
+
if (existsSync(fullOutputPath)) {
|
|
208
|
+
console.log(chalk.cyanBright(`${yargv.output} created!`))
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
import chalkTable from 'chalk-table'
|
|
6
|
+
import meow from 'meow'
|
|
7
|
+
import ora from 'ora'
|
|
8
|
+
|
|
9
|
+
import { outputFlags } from '../../flags/index.js'
|
|
10
|
+
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
|
|
11
|
+
import { prepareFlags } from '../../utils/flags.js'
|
|
12
|
+
import { printFlagList } from '../../utils/formatting.js'
|
|
13
|
+
import { getDefaultKey, setupSdk } from '../../utils/sdk.js'
|
|
14
|
+
|
|
15
|
+
/** @type {import('../../utils/meow-with-subcommands.js').CliSubcommand} */
|
|
16
|
+
export const dependencies = {
|
|
17
|
+
description: 'Search for any dependency that is being used in your organization',
|
|
18
|
+
async run (argv, importMeta, { parentName }) {
|
|
19
|
+
const name = parentName + ' dependencies'
|
|
20
|
+
|
|
21
|
+
const input = setupCommand(name, dependencies.description, argv, importMeta)
|
|
22
|
+
if (input) {
|
|
23
|
+
const spinnerText = 'Searching dependencies...'
|
|
24
|
+
const spinner = ora(spinnerText).start()
|
|
25
|
+
await searchDeps(input, spinner)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const dependenciesFlags = prepareFlags({
|
|
31
|
+
limit: {
|
|
32
|
+
type: 'number',
|
|
33
|
+
shortFlag: 'l',
|
|
34
|
+
default: 50,
|
|
35
|
+
description: 'Maximum number of dependencies returned',
|
|
36
|
+
},
|
|
37
|
+
offset: {
|
|
38
|
+
type: 'number',
|
|
39
|
+
shortFlag: 'o',
|
|
40
|
+
default: 0,
|
|
41
|
+
description: 'Page number',
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
// Internal functions
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @typedef Command
|
|
49
|
+
* @property {boolean} outputJson
|
|
50
|
+
* @property {boolean} outputMarkdown
|
|
51
|
+
* @property {number} limit
|
|
52
|
+
* @property {number} offset
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {string} name
|
|
57
|
+
* @param {string} description
|
|
58
|
+
* @param {readonly string[]} argv
|
|
59
|
+
* @param {ImportMeta} importMeta
|
|
60
|
+
* @returns {void|Command}
|
|
61
|
+
*/
|
|
62
|
+
function setupCommand (name, description, argv, importMeta) {
|
|
63
|
+
const flags = {
|
|
64
|
+
...outputFlags,
|
|
65
|
+
...dependenciesFlags
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const cli = meow(`
|
|
69
|
+
Usage
|
|
70
|
+
$ ${name}
|
|
71
|
+
|
|
72
|
+
Options
|
|
73
|
+
${printFlagList(flags, 6)}
|
|
74
|
+
|
|
75
|
+
Examples
|
|
76
|
+
$ ${name}
|
|
77
|
+
`, {
|
|
78
|
+
argv,
|
|
79
|
+
description,
|
|
80
|
+
importMeta,
|
|
81
|
+
flags
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const {
|
|
85
|
+
json: outputJson,
|
|
86
|
+
markdown: outputMarkdown,
|
|
87
|
+
limit,
|
|
88
|
+
offset
|
|
89
|
+
} = cli.flags
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
outputJson,
|
|
93
|
+
outputMarkdown,
|
|
94
|
+
limit,
|
|
95
|
+
offset
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @typedef DependenciesData
|
|
101
|
+
* @property {import('@socketsecurity/sdk').SocketSdkReturnType<'searchDependencies'>["data"]} data
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @param {Command} input
|
|
106
|
+
* @param {import('ora').Ora} spinner
|
|
107
|
+
* @returns {Promise<void|DependenciesData>}
|
|
108
|
+
*/
|
|
109
|
+
async function searchDeps ({ limit, offset, outputJson }, spinner) {
|
|
110
|
+
const socketSdk = await setupSdk(getDefaultKey())
|
|
111
|
+
const result = await handleApiCall(socketSdk.searchDependencies({ limit, offset }), 'Searching dependencies')
|
|
112
|
+
|
|
113
|
+
if (!result.success) {
|
|
114
|
+
return handleUnsuccessfulApiResponse('searchDependencies', result, spinner)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
spinner.stop()
|
|
118
|
+
|
|
119
|
+
console.log('Organization dependencies: \n')
|
|
120
|
+
|
|
121
|
+
if (outputJson) {
|
|
122
|
+
return console.log(result.data)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const options = {
|
|
126
|
+
columns: [
|
|
127
|
+
{ field: 'namespace', name: chalk.cyan('Namespace') },
|
|
128
|
+
{ field: 'name', name: chalk.cyan('Name') },
|
|
129
|
+
{ field: 'version', name: chalk.cyan('Version') },
|
|
130
|
+
{ field: 'repository', name: chalk.cyan('Repository') },
|
|
131
|
+
{ field: 'branch', name: chalk.cyan('Branch') },
|
|
132
|
+
{ field: 'type', name: chalk.cyan('Type') },
|
|
133
|
+
{ field: 'direct', name: chalk.cyan('Direct') }
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const formattedResults = result.data.rows.map((/** @type {{[key:string]: any}} */ d) => {
|
|
138
|
+
return {
|
|
139
|
+
...d
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
const table = chalkTable(options, formattedResults)
|
|
144
|
+
|
|
145
|
+
console.log(table, '\n')
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
data: result.data
|
|
149
|
+
}
|
|
150
|
+
}
|
package/lib/commands/index.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
export * from './cdxgen/index.js'
|
|
1
2
|
export * from './info/index.js'
|
|
2
|
-
export * from './report/index.js'
|
|
3
|
-
export * from './npm/index.js'
|
|
4
|
-
export * from './npx/index.js'
|
|
5
3
|
export * from './login/index.js'
|
|
6
4
|
export * from './logout/index.js'
|
|
7
|
-
export * from './
|
|
5
|
+
export * from './npm/index.js'
|
|
6
|
+
export * from './npx/index.js'
|
|
8
7
|
export * from './raw-npm/index.js'
|
|
9
8
|
export * from './raw-npx/index.js'
|
|
9
|
+
export * from './report/index.js'
|
|
10
|
+
export * from './wrapper/index.js'
|
|
11
|
+
export * from './scan/index.js'
|
|
12
|
+
export * from './audit-log/index.js'
|
|
13
|
+
export * from './repos/index.js'
|
|
14
|
+
export * from './dependencies/index.js'
|