@socketsecurity/cli 0.11.0 → 0.11.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 +22 -22
- package/bin/npm +2 -0
- package/bin/npx +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +3419 -0
- package/dist/errors.d.ts +7 -0
- package/dist/link.d.ts +2 -0
- package/dist/link.js +45 -0
- package/dist/npm-cli.d.ts +2 -0
- package/dist/npm-cli.js +84 -0
- package/dist/npm-injection.d.ts +1 -0
- package/dist/npm-injection.js +913 -0
- package/dist/npm-injection2.d.ts +25 -0
- package/dist/npm-injection2.js +899 -0
- package/dist/npx-cli.d.ts +2 -0
- package/dist/npx-cli.js +60 -0
- package/dist/path-resolve.d.ts +12 -0
- package/dist/path-resolve.js +139 -0
- package/dist/sdk.d.ts +27 -0
- package/dist/sdk.js +224 -0
- package/dist/settings.d.ts +9 -0
- package/dist/type-helpers.d.ts +3 -0
- package/dist/vendor.js +25421 -0
- package/package.json +105 -52
- package/{lib/shadow/translations.json → translations.json} +20 -20
- package/cli.js +0 -72
- package/lib/commands/audit-log/index.js +0 -162
- package/lib/commands/cdxgen/index.js +0 -211
- package/lib/commands/dependencies/index.js +0 -150
- package/lib/commands/index.js +0 -15
- package/lib/commands/info/index.js +0 -287
- package/lib/commands/login/index.js +0 -170
- package/lib/commands/logout/index.js +0 -35
- package/lib/commands/npm/index.js +0 -27
- package/lib/commands/npx/index.js +0 -22
- package/lib/commands/organizations/index.js +0 -81
- package/lib/commands/raw-npm/index.js +0 -59
- package/lib/commands/raw-npx/index.js +0 -59
- package/lib/commands/report/create.js +0 -251
- package/lib/commands/report/index.js +0 -24
- package/lib/commands/report/view.js +0 -176
- package/lib/commands/repos/create.js +0 -166
- package/lib/commands/repos/delete.js +0 -93
- package/lib/commands/repos/index.js +0 -30
- package/lib/commands/repos/list.js +0 -170
- package/lib/commands/repos/update.js +0 -166
- package/lib/commands/repos/view.js +0 -128
- package/lib/commands/scan/create.js +0 -245
- package/lib/commands/scan/delete.js +0 -112
- package/lib/commands/scan/index.js +0 -30
- package/lib/commands/scan/list.js +0 -192
- package/lib/commands/scan/metadata.js +0 -113
- package/lib/commands/scan/stream.js +0 -115
- package/lib/commands/wrapper/index.js +0 -199
- package/lib/flags/command.js +0 -14
- package/lib/flags/index.js +0 -3
- package/lib/flags/output.js +0 -16
- package/lib/flags/validation.js +0 -14
- package/lib/shadow/bin/npm +0 -2
- package/lib/shadow/bin/npx +0 -2
- package/lib/shadow/link.cjs +0 -50
- package/lib/shadow/npm-cli.cjs +0 -27
- package/lib/shadow/npm-injection.cjs +0 -649
- package/lib/shadow/npx-cli.cjs +0 -27
- package/lib/shadow/package.json +0 -3
- package/lib/shadow/tty-server.cjs +0 -222
- package/lib/shadow/update-notifier.mjs +0 -3
- package/lib/utils/api-helpers.js +0 -42
- package/lib/utils/chalk-markdown.js +0 -125
- package/lib/utils/errors.js +0 -14
- package/lib/utils/flags.js +0 -27
- package/lib/utils/format-issues.js +0 -99
- package/lib/utils/formatting.js +0 -47
- package/lib/utils/issue-rules.cjs +0 -180
- package/lib/utils/meow-with-subcommands.js +0 -87
- package/lib/utils/misc.js +0 -61
- package/lib/utils/path-resolve.js +0 -204
- package/lib/utils/sdk.js +0 -99
- package/lib/utils/settings.js +0 -69
- package/lib/utils/type-helpers.cjs +0 -13
- package/lib/utils/update-notifier.js +0 -18
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
const path = require('path')
|
|
2
|
-
const { PassThrough } = require('stream')
|
|
3
|
-
|
|
4
|
-
const ipc_version = require('../../package.json').version
|
|
5
|
-
const { isErrnoException } = require('../utils/type-helpers.cjs')
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {import('stream').Readable} Readable
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* @typedef {import('stream').Writable} Writable
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* @param {import('chalk')['default']['level']} colorLevel
|
|
15
|
-
* @param {boolean} isInteractive
|
|
16
|
-
* @param {any} npmlog
|
|
17
|
-
* @returns {Promise<{ captureTTY<RET extends any>(mutexFn: (input: Readable | null, output?: Writable, colorLevel: import('chalk')['default']['level']) => Promise<RET>): Promise<RET> }>}
|
|
18
|
-
*/
|
|
19
|
-
module.exports = async function createTTYServer (colorLevel, isInteractive, npmlog) {
|
|
20
|
-
const TTY_IPC = process.env['SOCKET_SECURITY_TTY_IPC']
|
|
21
|
-
const net = require('net')
|
|
22
|
-
/**
|
|
23
|
-
* @type {import('readline')}
|
|
24
|
-
*/
|
|
25
|
-
let readline
|
|
26
|
-
const isSTDINInteractive = isInteractive
|
|
27
|
-
if (!isSTDINInteractive && TTY_IPC) {
|
|
28
|
-
return {
|
|
29
|
-
async captureTTY (mutexFn) {
|
|
30
|
-
return new Promise((resolve, reject) => {
|
|
31
|
-
const conn = net.createConnection({
|
|
32
|
-
path: TTY_IPC
|
|
33
|
-
}).on('error', reject)
|
|
34
|
-
let captured = false
|
|
35
|
-
/**
|
|
36
|
-
* @type {Array<Buffer>}
|
|
37
|
-
*/
|
|
38
|
-
const bufs = []
|
|
39
|
-
conn.on('data', function awaitCapture (chunk) {
|
|
40
|
-
bufs.push(chunk)
|
|
41
|
-
/**
|
|
42
|
-
* @type {Buffer | null}
|
|
43
|
-
*/
|
|
44
|
-
let lineBuff = Buffer.concat(bufs)
|
|
45
|
-
try {
|
|
46
|
-
if (!captured) {
|
|
47
|
-
const EOL = lineBuff.indexOf('\n'.charCodeAt(0))
|
|
48
|
-
if (EOL !== -1) {
|
|
49
|
-
conn.removeListener('data', awaitCapture)
|
|
50
|
-
conn.push(lineBuff.slice(EOL + 1))
|
|
51
|
-
const {
|
|
52
|
-
ipc_version: remote_ipc_version,
|
|
53
|
-
capabilities: { input: hasInput, output: hasOutput, colorLevel: ipcColorLevel }
|
|
54
|
-
} = JSON.parse(lineBuff.slice(0, EOL).toString('utf-8'))
|
|
55
|
-
lineBuff = null
|
|
56
|
-
captured = true
|
|
57
|
-
if (remote_ipc_version !== ipc_version) {
|
|
58
|
-
throw new Error('Mismatched STDIO tunnel IPC version, ensure you only have 1 version of socket CLI being called.')
|
|
59
|
-
}
|
|
60
|
-
const input = hasInput ? new PassThrough() : null
|
|
61
|
-
input?.pause()
|
|
62
|
-
if (input) conn.pipe(input)
|
|
63
|
-
const output = hasOutput ? new PassThrough() : null
|
|
64
|
-
output?.pipe(conn)
|
|
65
|
-
// make ora happy
|
|
66
|
-
// @ts-ignore
|
|
67
|
-
output.isTTY = true
|
|
68
|
-
// @ts-ignore
|
|
69
|
-
output.cursorTo = function cursorTo (x, y, callback) {
|
|
70
|
-
readline = readline || require('readline')
|
|
71
|
-
// @ts-ignore
|
|
72
|
-
readline.cursorTo(this, x, y, callback)
|
|
73
|
-
}
|
|
74
|
-
// @ts-ignore
|
|
75
|
-
output.clearLine = function clearLine (dir, callback) {
|
|
76
|
-
readline = readline || require('readline')
|
|
77
|
-
// @ts-ignore
|
|
78
|
-
readline.clearLine(this, dir, callback)
|
|
79
|
-
}
|
|
80
|
-
mutexFn(hasInput ? input : null, hasOutput ? /** @type {Writable} */(output) : undefined, ipcColorLevel)
|
|
81
|
-
.then(resolve, reject)
|
|
82
|
-
.finally(() => {
|
|
83
|
-
conn.unref()
|
|
84
|
-
conn.end()
|
|
85
|
-
input?.end()
|
|
86
|
-
output?.end()
|
|
87
|
-
// process.exit(13)
|
|
88
|
-
})
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
} catch (e) {
|
|
92
|
-
reject(e)
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* @type {Array<{resolve(): void}>}}
|
|
101
|
-
*/
|
|
102
|
-
const pendingCaptures = []
|
|
103
|
-
let captured = false
|
|
104
|
-
const sock = path.join(require('os').tmpdir(), `socket-security-tty-${process.pid}.sock`)
|
|
105
|
-
process.env['SOCKET_SECURITY_TTY_IPC'] = sock
|
|
106
|
-
try {
|
|
107
|
-
await require('fs/promises').unlink(sock)
|
|
108
|
-
} catch (e) {
|
|
109
|
-
if (isErrnoException(e) && e.code !== 'ENOENT') {
|
|
110
|
-
throw e
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
const input = isSTDINInteractive ? process.stdin : null
|
|
114
|
-
const output = process.stderr
|
|
115
|
-
if (input) {
|
|
116
|
-
await new Promise((resolve, reject) => {
|
|
117
|
-
const server = net.createServer(async (conn) => {
|
|
118
|
-
if (captured) {
|
|
119
|
-
const captured = new Promise((resolve) => {
|
|
120
|
-
pendingCaptures.push({
|
|
121
|
-
resolve () {
|
|
122
|
-
resolve(undefined)
|
|
123
|
-
}
|
|
124
|
-
})
|
|
125
|
-
})
|
|
126
|
-
await captured
|
|
127
|
-
} else {
|
|
128
|
-
captured = true
|
|
129
|
-
}
|
|
130
|
-
const wasProgressEnabled = npmlog.progressEnabled
|
|
131
|
-
npmlog.pause()
|
|
132
|
-
if (wasProgressEnabled) {
|
|
133
|
-
npmlog.disableProgress()
|
|
134
|
-
}
|
|
135
|
-
conn.write(`${JSON.stringify({
|
|
136
|
-
ipc_version,
|
|
137
|
-
capabilities: {
|
|
138
|
-
input: Boolean(input),
|
|
139
|
-
output: true,
|
|
140
|
-
colorLevel
|
|
141
|
-
}
|
|
142
|
-
})}\n`)
|
|
143
|
-
conn.on('data', (data) => {
|
|
144
|
-
output.write(data)
|
|
145
|
-
})
|
|
146
|
-
conn.on('error', (e) => {
|
|
147
|
-
output.write(`there was an error prompting from a subshell (${e.message}), socket npm closing`)
|
|
148
|
-
process.exit(1)
|
|
149
|
-
})
|
|
150
|
-
input.on('data', (data) => {
|
|
151
|
-
conn.write(data)
|
|
152
|
-
})
|
|
153
|
-
input.on('end', () => {
|
|
154
|
-
conn.unref()
|
|
155
|
-
conn.end()
|
|
156
|
-
if (wasProgressEnabled) {
|
|
157
|
-
npmlog.enableProgress()
|
|
158
|
-
}
|
|
159
|
-
npmlog.resume()
|
|
160
|
-
nextCapture()
|
|
161
|
-
})
|
|
162
|
-
}).listen(sock, () => resolve(server)).on('error', (err) => {
|
|
163
|
-
reject(err)
|
|
164
|
-
}).unref()
|
|
165
|
-
process.on('exit', () => {
|
|
166
|
-
server.close()
|
|
167
|
-
try {
|
|
168
|
-
require('fs').unlinkSync(sock)
|
|
169
|
-
} catch (e) {
|
|
170
|
-
if (isErrnoException(e) && e.code !== 'ENOENT') {
|
|
171
|
-
throw e
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
resolve(server)
|
|
176
|
-
})
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
*
|
|
180
|
-
*/
|
|
181
|
-
function nextCapture () {
|
|
182
|
-
if (pendingCaptures.length > 0) {
|
|
183
|
-
const nextCapture = pendingCaptures.shift()
|
|
184
|
-
if (nextCapture) {
|
|
185
|
-
nextCapture.resolve()
|
|
186
|
-
}
|
|
187
|
-
} else {
|
|
188
|
-
captured = false
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return {
|
|
192
|
-
async captureTTY (mutexFn) {
|
|
193
|
-
if (captured) {
|
|
194
|
-
const captured = new Promise((resolve) => {
|
|
195
|
-
pendingCaptures.push({
|
|
196
|
-
resolve () {
|
|
197
|
-
resolve(undefined)
|
|
198
|
-
}
|
|
199
|
-
})
|
|
200
|
-
})
|
|
201
|
-
await captured
|
|
202
|
-
} else {
|
|
203
|
-
captured = true
|
|
204
|
-
}
|
|
205
|
-
const wasProgressEnabled = npmlog.progressEnabled
|
|
206
|
-
try {
|
|
207
|
-
npmlog.pause()
|
|
208
|
-
if (wasProgressEnabled) {
|
|
209
|
-
npmlog.disableProgress()
|
|
210
|
-
}
|
|
211
|
-
// need await here for proper finally timing
|
|
212
|
-
return await mutexFn(input, output, colorLevel)
|
|
213
|
-
} finally {
|
|
214
|
-
if (wasProgressEnabled) {
|
|
215
|
-
npmlog.enableProgress()
|
|
216
|
-
}
|
|
217
|
-
npmlog.resume()
|
|
218
|
-
nextCapture()
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
package/lib/utils/api-helpers.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import { ErrorWithCause } from 'pony-cause'
|
|
3
|
-
|
|
4
|
-
import { AuthError } from './errors.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @template {import('@socketsecurity/sdk').SocketSdkOperations} T
|
|
8
|
-
* @param {T} _name
|
|
9
|
-
* @param {import('@socketsecurity/sdk').SocketSdkErrorType<T>} result
|
|
10
|
-
* @param {import('ora').Ora} spinner
|
|
11
|
-
* @returns {never}
|
|
12
|
-
*/
|
|
13
|
-
export function handleUnsuccessfulApiResponse (_name, result, spinner) {
|
|
14
|
-
const resultError = 'error' in result && result.error && typeof result.error === 'object' ? result.error : {}
|
|
15
|
-
const message = 'message' in resultError && typeof resultError.message === 'string' ? resultError.message : 'No error message returned'
|
|
16
|
-
|
|
17
|
-
if (result.status === 401 || result.status === 403) {
|
|
18
|
-
spinner.stop()
|
|
19
|
-
throw new AuthError(message)
|
|
20
|
-
}
|
|
21
|
-
spinner.fail(chalk.white.bgRed('API returned an error:') + ' ' + message)
|
|
22
|
-
process.exit(1)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @template T
|
|
27
|
-
* @param {Promise<T>} value
|
|
28
|
-
* @param {string} description
|
|
29
|
-
* @returns {Promise<T>}
|
|
30
|
-
*/
|
|
31
|
-
export async function handleApiCall (value, description) {
|
|
32
|
-
/** @type {T} */
|
|
33
|
-
let result
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
result = await value
|
|
37
|
-
} catch (cause) {
|
|
38
|
-
throw new ErrorWithCause(`Failed ${description}`, { cause })
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return result
|
|
42
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import isUnicodeSupported from 'is-unicode-supported'
|
|
3
|
-
import terminalLink from 'terminal-link'
|
|
4
|
-
|
|
5
|
-
// From the 'log-symbols' module
|
|
6
|
-
const unicodeLogSymbols = {
|
|
7
|
-
info: chalk.blue('ℹ'),
|
|
8
|
-
success: chalk.green('✔'),
|
|
9
|
-
warning: chalk.yellow('⚠'),
|
|
10
|
-
error: chalk.red('✖'),
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// From the 'log-symbols' module
|
|
14
|
-
const fallbackLogSymbols = {
|
|
15
|
-
info: chalk.blue('i'),
|
|
16
|
-
success: chalk.green('√'),
|
|
17
|
-
warning: chalk.yellow('‼'),
|
|
18
|
-
error: chalk.red('×'),
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// From the 'log-symbols' module
|
|
22
|
-
export const logSymbols = isUnicodeSupported() ? unicodeLogSymbols : fallbackLogSymbols
|
|
23
|
-
|
|
24
|
-
const markdownLogSymbols = {
|
|
25
|
-
info: ':information_source:',
|
|
26
|
-
error: ':stop_sign:',
|
|
27
|
-
success: ':white_check_mark:',
|
|
28
|
-
warning: ':warning:',
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export class ChalkOrMarkdown {
|
|
32
|
-
/** @type {boolean} */
|
|
33
|
-
useMarkdown
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @param {boolean} useMarkdown
|
|
37
|
-
*/
|
|
38
|
-
constructor (useMarkdown) {
|
|
39
|
-
this.useMarkdown = !!useMarkdown
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @param {string} text
|
|
44
|
-
* @param {number} [level]
|
|
45
|
-
* @returns {string}
|
|
46
|
-
*/
|
|
47
|
-
header (text, level = 1) {
|
|
48
|
-
return this.useMarkdown
|
|
49
|
-
? `\n${''.padStart(level, '#')} ${text}\n`
|
|
50
|
-
: chalk.underline(`\n${level === 1 ? chalk.bold(text) : text}\n`)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @param {string} text
|
|
55
|
-
* @returns {string}
|
|
56
|
-
*/
|
|
57
|
-
bold (text) {
|
|
58
|
-
return this.useMarkdown
|
|
59
|
-
? `**${text}**`
|
|
60
|
-
: chalk.bold(`${text}`)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @param {string} text
|
|
65
|
-
* @returns {string}
|
|
66
|
-
*/
|
|
67
|
-
italic (text) {
|
|
68
|
-
return this.useMarkdown
|
|
69
|
-
? `_${text}_`
|
|
70
|
-
: chalk.italic(`${text}`)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @param {string} text
|
|
75
|
-
* @param {string|undefined} url
|
|
76
|
-
* @param {{ fallback?: boolean, fallbackToUrl?: boolean }} options
|
|
77
|
-
* @returns {string}
|
|
78
|
-
*/
|
|
79
|
-
hyperlink (text, url, { fallback = true, fallbackToUrl } = {}) {
|
|
80
|
-
if (!url) return text
|
|
81
|
-
return this.useMarkdown
|
|
82
|
-
? `[${text}](${url})`
|
|
83
|
-
: terminalLink(text, url, {
|
|
84
|
-
fallback: fallbackToUrl ? (_text, url) => url : fallback
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* @param {string[]} items
|
|
90
|
-
* @returns {string}
|
|
91
|
-
*/
|
|
92
|
-
list (items) {
|
|
93
|
-
const indentedContent = items.map(item => this.indent(item).trimStart())
|
|
94
|
-
return this.useMarkdown
|
|
95
|
-
? '* ' + indentedContent.join('\n* ') + '\n'
|
|
96
|
-
: indentedContent.join('\n') + '\n'
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* @returns {typeof logSymbols}
|
|
101
|
-
*/
|
|
102
|
-
get logSymbols () {
|
|
103
|
-
return this.useMarkdown ? markdownLogSymbols : logSymbols
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* @param {string} text
|
|
108
|
-
* @param {number} [level]
|
|
109
|
-
* @returns {string}
|
|
110
|
-
*/
|
|
111
|
-
indent (text, level = 1) {
|
|
112
|
-
const indent = ''.padStart(level * 2, ' ')
|
|
113
|
-
return indent + text.split('\n').join('\n' + indent)
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* @param {unknown} value
|
|
118
|
-
* @returns {string}
|
|
119
|
-
*/
|
|
120
|
-
json (value) {
|
|
121
|
-
return this.useMarkdown
|
|
122
|
-
? '```json\n' + JSON.stringify(value) + '\n```'
|
|
123
|
-
: JSON.stringify(value)
|
|
124
|
-
}
|
|
125
|
-
}
|
package/lib/utils/errors.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export class AuthError extends Error {}
|
|
2
|
-
|
|
3
|
-
export class InputError extends Error {
|
|
4
|
-
/**
|
|
5
|
-
* @param {string} message
|
|
6
|
-
* @param {string} [body]
|
|
7
|
-
*/
|
|
8
|
-
constructor (message, body) {
|
|
9
|
-
super(message)
|
|
10
|
-
|
|
11
|
-
/** @type {string|undefined} */
|
|
12
|
-
this.body = body
|
|
13
|
-
}
|
|
14
|
-
}
|
package/lib/utils/flags.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef FlagExtensions
|
|
3
|
-
* @property {string} description
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @template {import('meow').FlagType} Type
|
|
8
|
-
* @template Default
|
|
9
|
-
* @template {boolean} [IsMultiple=false]
|
|
10
|
-
* @typedef {import('meow').Flag<Type, Default, IsMultiple> & FlagExtensions} Flag
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/** @typedef {Flag<'string', string> | Flag<'string', string[], true>} StringFlag */
|
|
14
|
-
/** @typedef {Flag<'boolean', boolean> | Flag<'boolean', boolean[], true>} BooleanFlag */
|
|
15
|
-
/** @typedef {Flag<'number', number> | Flag<'number', number[], true>} NumberFlag */
|
|
16
|
-
/** @typedef {StringFlag | BooleanFlag | NumberFlag} AnyFlag */
|
|
17
|
-
/** @typedef {Record<string, AnyFlag>} AnyFlags */
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @template {AnyFlags} Flags
|
|
21
|
-
* @param {Flags} flags
|
|
22
|
-
* @returns {Readonly<Flags>}
|
|
23
|
-
*/
|
|
24
|
-
export function prepareFlags (flags) {
|
|
25
|
-
// As we can't do "satisfies AnyFlags" in JS yet (+ we add a bonus through Readonly<>)
|
|
26
|
-
return flags
|
|
27
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/** @typedef {import('@socketsecurity/sdk').SocketSdkReturnType<'getIssuesByNPMPackage'>['data']} SocketIssueList */
|
|
2
|
-
/** @typedef {SocketIssueList[number]['value'] extends infer U | undefined ? U : never} SocketIssue */
|
|
3
|
-
|
|
4
|
-
import { pick, stringJoinWithSeparateFinalSeparator } from './misc.js'
|
|
5
|
-
|
|
6
|
-
const SEVERITIES_BY_ORDER = /** @type {const} */ ([
|
|
7
|
-
'critical',
|
|
8
|
-
'high',
|
|
9
|
-
'middle',
|
|
10
|
-
'low',
|
|
11
|
-
])
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @param {SocketIssue['severity']|undefined} lowestToInclude
|
|
15
|
-
* @returns {Array<SocketIssue['severity']>}
|
|
16
|
-
*/
|
|
17
|
-
function getDesiredSeverities (lowestToInclude) {
|
|
18
|
-
/** @type {Array<SocketIssue['severity']>} */
|
|
19
|
-
const result = []
|
|
20
|
-
|
|
21
|
-
for (const severity of SEVERITIES_BY_ORDER) {
|
|
22
|
-
result.push(severity)
|
|
23
|
-
if (severity === lowestToInclude) {
|
|
24
|
-
break
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return result
|
|
29
|
-
}
|
|
30
|
-
/* TODO: Delete this function when we remove the report command */
|
|
31
|
-
/**
|
|
32
|
-
* @param {SocketIssueList} issues
|
|
33
|
-
* @param {SocketIssue['severity']} [lowestToInclude]
|
|
34
|
-
* @returns {Record<SocketIssue['severity'], number>}
|
|
35
|
-
*/
|
|
36
|
-
export function getSeverityCount (issues, lowestToInclude) {
|
|
37
|
-
const severityCount = pick(
|
|
38
|
-
{ low: 0, middle: 0, high: 0, critical: 0 },
|
|
39
|
-
getDesiredSeverities(lowestToInclude)
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
for (const issue of issues) {
|
|
43
|
-
const value = issue.value
|
|
44
|
-
|
|
45
|
-
if (!value) {
|
|
46
|
-
continue
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (severityCount[value.severity] !== undefined) {
|
|
50
|
-
severityCount[value.severity] += 1
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return severityCount
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/* The following function is the updated one */
|
|
58
|
-
/**
|
|
59
|
-
* @param {Array<SocketIssue>} issues
|
|
60
|
-
* @param {SocketIssue['severity']} [lowestToInclude]
|
|
61
|
-
* @returns {Record<SocketIssue['severity'], number>}
|
|
62
|
-
*/
|
|
63
|
-
export function getCountSeverity (issues, lowestToInclude) {
|
|
64
|
-
const severityCount = pick(
|
|
65
|
-
{ low: 0, middle: 0, high: 0, critical: 0 },
|
|
66
|
-
getDesiredSeverities(lowestToInclude)
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
for (const issue of issues) {
|
|
70
|
-
const severity = issue.severity
|
|
71
|
-
|
|
72
|
-
if (!severity) {
|
|
73
|
-
continue
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (severityCount[severity] !== undefined) {
|
|
77
|
-
severityCount[severity] += 1
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return severityCount
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* @param {Record<SocketIssue['severity'], number>} severityCount
|
|
86
|
-
* @returns {string}
|
|
87
|
-
*/
|
|
88
|
-
export function formatSeverityCount (severityCount) {
|
|
89
|
-
/** @type {string[]} */
|
|
90
|
-
const summary = []
|
|
91
|
-
|
|
92
|
-
for (const severity of SEVERITIES_BY_ORDER) {
|
|
93
|
-
if (severityCount[severity]) {
|
|
94
|
-
summary.push(`${severityCount[severity]} ${severity}`)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return stringJoinWithSeparateFinalSeparator(summary)
|
|
99
|
-
}
|
package/lib/utils/formatting.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/** @typedef {string|{ description: string }} ListDescription */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef HelpListOptions
|
|
5
|
-
* @property {string} [keyPrefix]
|
|
6
|
-
* @property {number} [padName]
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @param {Record<string,ListDescription>} list
|
|
11
|
-
* @param {number} indent
|
|
12
|
-
* @param {HelpListOptions} options
|
|
13
|
-
* @returns {string}
|
|
14
|
-
*/
|
|
15
|
-
export function printHelpList (list, indent, options = {}) {
|
|
16
|
-
const {
|
|
17
|
-
keyPrefix = '',
|
|
18
|
-
padName = 18,
|
|
19
|
-
} = options
|
|
20
|
-
|
|
21
|
-
const names = Object.keys(list).sort()
|
|
22
|
-
|
|
23
|
-
let result = ''
|
|
24
|
-
|
|
25
|
-
for (const name of names) {
|
|
26
|
-
const rawDescription = list[name]
|
|
27
|
-
const description = (typeof rawDescription === 'object' ? rawDescription.description : rawDescription) || ''
|
|
28
|
-
|
|
29
|
-
result += ''.padEnd(indent) + (keyPrefix + name).padEnd(padName) + description + '\n'
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return result.trim()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @param {Record<string, ListDescription>} list
|
|
37
|
-
* @param {number} indent
|
|
38
|
-
* @param {HelpListOptions} options
|
|
39
|
-
* @returns {string}
|
|
40
|
-
*/
|
|
41
|
-
export function printFlagList (list, indent, options = {}) {
|
|
42
|
-
return printHelpList({
|
|
43
|
-
'help': 'Print this help and exits.',
|
|
44
|
-
'version': 'Prints current version and exits.',
|
|
45
|
-
...list,
|
|
46
|
-
}, indent, { keyPrefix: '--', ...options })
|
|
47
|
-
}
|