@socketsecurity/cli 0.10.1 → 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.
Files changed (81) hide show
  1. package/README.md +22 -22
  2. package/bin/npm +2 -0
  3. package/bin/npx +2 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +3419 -0
  7. package/dist/errors.d.ts +7 -0
  8. package/dist/link.d.ts +2 -0
  9. package/dist/link.js +45 -0
  10. package/dist/npm-cli.d.ts +2 -0
  11. package/dist/npm-cli.js +84 -0
  12. package/dist/npm-injection.d.ts +1 -0
  13. package/dist/npm-injection.js +913 -0
  14. package/dist/npm-injection2.d.ts +25 -0
  15. package/dist/npm-injection2.js +899 -0
  16. package/dist/npx-cli.d.ts +2 -0
  17. package/dist/npx-cli.js +60 -0
  18. package/dist/path-resolve.d.ts +12 -0
  19. package/dist/path-resolve.js +139 -0
  20. package/dist/sdk.d.ts +27 -0
  21. package/dist/sdk.js +224 -0
  22. package/dist/settings.d.ts +9 -0
  23. package/dist/type-helpers.d.ts +3 -0
  24. package/dist/vendor.js +25421 -0
  25. package/package.json +105 -52
  26. package/{lib/shadow/translations.json → translations.json} +20 -20
  27. package/cli.js +0 -72
  28. package/lib/commands/audit-log/index.js +0 -162
  29. package/lib/commands/cdxgen/index.js +0 -211
  30. package/lib/commands/dependencies/index.js +0 -150
  31. package/lib/commands/index.js +0 -14
  32. package/lib/commands/info/index.js +0 -287
  33. package/lib/commands/login/index.js +0 -170
  34. package/lib/commands/logout/index.js +0 -35
  35. package/lib/commands/npm/index.js +0 -27
  36. package/lib/commands/npx/index.js +0 -22
  37. package/lib/commands/raw-npm/index.js +0 -59
  38. package/lib/commands/raw-npx/index.js +0 -59
  39. package/lib/commands/report/create.js +0 -251
  40. package/lib/commands/report/index.js +0 -24
  41. package/lib/commands/report/view.js +0 -176
  42. package/lib/commands/repos/create.js +0 -166
  43. package/lib/commands/repos/delete.js +0 -93
  44. package/lib/commands/repos/index.js +0 -30
  45. package/lib/commands/repos/list.js +0 -170
  46. package/lib/commands/repos/update.js +0 -166
  47. package/lib/commands/repos/view.js +0 -128
  48. package/lib/commands/scan/create.js +0 -245
  49. package/lib/commands/scan/delete.js +0 -112
  50. package/lib/commands/scan/index.js +0 -30
  51. package/lib/commands/scan/list.js +0 -192
  52. package/lib/commands/scan/metadata.js +0 -113
  53. package/lib/commands/scan/stream.js +0 -115
  54. package/lib/commands/wrapper/index.js +0 -199
  55. package/lib/flags/command.js +0 -14
  56. package/lib/flags/index.js +0 -3
  57. package/lib/flags/output.js +0 -16
  58. package/lib/flags/validation.js +0 -14
  59. package/lib/shadow/bin/npm +0 -2
  60. package/lib/shadow/bin/npx +0 -2
  61. package/lib/shadow/link.cjs +0 -50
  62. package/lib/shadow/npm-cli.cjs +0 -27
  63. package/lib/shadow/npm-injection.cjs +0 -649
  64. package/lib/shadow/npx-cli.cjs +0 -27
  65. package/lib/shadow/package.json +0 -3
  66. package/lib/shadow/tty-server.cjs +0 -222
  67. package/lib/shadow/update-notifier.mjs +0 -3
  68. package/lib/utils/api-helpers.js +0 -42
  69. package/lib/utils/chalk-markdown.js +0 -125
  70. package/lib/utils/errors.js +0 -14
  71. package/lib/utils/flags.js +0 -27
  72. package/lib/utils/format-issues.js +0 -99
  73. package/lib/utils/formatting.js +0 -47
  74. package/lib/utils/issue-rules.cjs +0 -180
  75. package/lib/utils/meow-with-subcommands.js +0 -87
  76. package/lib/utils/misc.js +0 -61
  77. package/lib/utils/path-resolve.js +0 -204
  78. package/lib/utils/sdk.js +0 -99
  79. package/lib/utils/settings.js +0 -69
  80. package/lib/utils/type-helpers.cjs +0 -13
  81. 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
- }
@@ -1,3 +0,0 @@
1
- // ESM entrypoint doesn't work w/ --require, this needs to be done w/ a spawnSync sadly
2
- import { initUpdateNotifier } from '../utils/update-notifier.js'
3
- initUpdateNotifier()
@@ -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
- }
@@ -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
- }
@@ -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
- }
@@ -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
- }