@socketsecurity/cli 0.4.2 → 0.5.2
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/lib/commands/index.js +2 -0
- package/lib/commands/info/index.js +9 -27
- package/lib/commands/npm/index.js +22 -0
- package/lib/commands/npx/index.js +22 -0
- package/lib/commands/report/create.js +26 -35
- package/lib/commands/report/view.js +9 -28
- package/lib/flags/index.js +2 -0
- package/lib/flags/output.js +16 -0
- package/lib/flags/validation.js +14 -0
- package/lib/shadow/bin/npm +2 -0
- package/lib/shadow/bin/npx +2 -0
- package/lib/shadow/global.d.ts +3 -0
- package/lib/shadow/link.cjs +43 -0
- package/lib/shadow/npm-cli.cjs +27 -0
- package/lib/shadow/npm-injection.cjs +369 -0
- package/lib/shadow/npx-cli.cjs +27 -0
- package/lib/shadow/package.json +3 -0
- package/lib/shadow/translations.json +689 -0
- package/lib/utils/api-helpers.js +3 -2
- package/lib/utils/flags.js +27 -0
- package/lib/utils/formatting.js +20 -9
- package/package.json +17 -7
package/lib/commands/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import chalk from 'chalk'
|
|
|
4
4
|
import meow from 'meow'
|
|
5
5
|
import ora from 'ora'
|
|
6
6
|
|
|
7
|
+
import { outputFlags, validationFlags } from '../../flags/index.js'
|
|
7
8
|
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
|
|
8
9
|
import { ChalkOrMarkdown } from '../../utils/chalk-markdown.js'
|
|
9
10
|
import { InputError } from '../../utils/errors.js'
|
|
@@ -47,17 +48,17 @@ export const info = {
|
|
|
47
48
|
* @returns {void|CommandContext}
|
|
48
49
|
*/
|
|
49
50
|
function setupCommand (name, description, argv, importMeta) {
|
|
51
|
+
const flags = {
|
|
52
|
+
...outputFlags,
|
|
53
|
+
...validationFlags,
|
|
54
|
+
}
|
|
55
|
+
|
|
50
56
|
const cli = meow(`
|
|
51
57
|
Usage
|
|
52
58
|
$ ${name} <name>
|
|
53
59
|
|
|
54
60
|
Options
|
|
55
|
-
${printFlagList(
|
|
56
|
-
'--all': 'Include all issues',
|
|
57
|
-
'--json': 'Output result as json',
|
|
58
|
-
'--markdown': 'Output result as markdown',
|
|
59
|
-
'--strict': 'Exits with an error code if any matching issues are found',
|
|
60
|
-
}, 6)}
|
|
61
|
+
${printFlagList(flags, 6)}
|
|
61
62
|
|
|
62
63
|
Examples
|
|
63
64
|
$ ${name} webtorrent
|
|
@@ -66,26 +67,7 @@ function setupCommand (name, description, argv, importMeta) {
|
|
|
66
67
|
argv,
|
|
67
68
|
description,
|
|
68
69
|
importMeta,
|
|
69
|
-
flags
|
|
70
|
-
all: {
|
|
71
|
-
type: 'boolean',
|
|
72
|
-
default: false,
|
|
73
|
-
},
|
|
74
|
-
json: {
|
|
75
|
-
type: 'boolean',
|
|
76
|
-
alias: 'j',
|
|
77
|
-
default: false,
|
|
78
|
-
},
|
|
79
|
-
markdown: {
|
|
80
|
-
type: 'boolean',
|
|
81
|
-
alias: 'm',
|
|
82
|
-
default: false,
|
|
83
|
-
},
|
|
84
|
-
strict: {
|
|
85
|
-
type: 'boolean',
|
|
86
|
-
default: false,
|
|
87
|
-
},
|
|
88
|
-
}
|
|
70
|
+
flags
|
|
89
71
|
})
|
|
90
72
|
|
|
91
73
|
const {
|
|
@@ -147,7 +129,7 @@ async function fetchPackageData (pkgName, pkgVersion, { includeAllIssues, strict
|
|
|
147
129
|
const result = await handleApiCall(socketSdk.getIssuesByNPMPackage(pkgName, pkgVersion), spinner, 'looking up package')
|
|
148
130
|
|
|
149
131
|
if (result.success === false) {
|
|
150
|
-
return handleUnsuccessfulApiResponse(result, spinner)
|
|
132
|
+
return handleUnsuccessfulApiResponse('getIssuesByNPMPackage', result, spinner)
|
|
151
133
|
}
|
|
152
134
|
|
|
153
135
|
// Conclude the status of the API call
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { spawn } from 'child_process'
|
|
2
|
+
import { fileURLToPath } from 'url'
|
|
3
|
+
|
|
4
|
+
const description = 'npm wrapper functionality'
|
|
5
|
+
|
|
6
|
+
/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */
|
|
7
|
+
export const npm = {
|
|
8
|
+
description,
|
|
9
|
+
run: async (argv, _importMeta, _ctx) => {
|
|
10
|
+
const wrapperPath = fileURLToPath(new URL('../../shadow/npm-cli.cjs', import.meta.url))
|
|
11
|
+
process.exitCode = 1
|
|
12
|
+
spawn(process.execPath, [wrapperPath, ...argv], {
|
|
13
|
+
stdio: 'inherit'
|
|
14
|
+
}).on('exit', (code, signal) => {
|
|
15
|
+
if (signal) {
|
|
16
|
+
process.kill(process.pid, signal)
|
|
17
|
+
} else if (code !== null) {
|
|
18
|
+
process.exit(code)
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { spawn } from 'child_process'
|
|
2
|
+
import { fileURLToPath } from 'url'
|
|
3
|
+
|
|
4
|
+
const description = 'npx wrapper functionality'
|
|
5
|
+
|
|
6
|
+
/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */
|
|
7
|
+
export const npx = {
|
|
8
|
+
description,
|
|
9
|
+
run: async (argv, _importMeta, _ctx) => {
|
|
10
|
+
const wrapperPath = fileURLToPath(new URL('../../shadow/npx-cli.cjs', import.meta.url))
|
|
11
|
+
process.exitCode = 1
|
|
12
|
+
spawn(process.execPath, [wrapperPath, ...argv], {
|
|
13
|
+
stdio: 'inherit'
|
|
14
|
+
}).on('exit', (code, signal) => {
|
|
15
|
+
if (signal) {
|
|
16
|
+
process.kill(process.pid, signal)
|
|
17
|
+
} else if (code !== null) {
|
|
18
|
+
process.exit(code)
|
|
19
|
+
}
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -9,9 +9,11 @@ import ora from 'ora'
|
|
|
9
9
|
import { ErrorWithCause } from 'pony-cause'
|
|
10
10
|
|
|
11
11
|
import { fetchReportData, formatReportDataOutput } from './view.js'
|
|
12
|
+
import { outputFlags, validationFlags } from '../../flags/index.js'
|
|
12
13
|
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
|
|
13
14
|
import { ChalkOrMarkdown, logSymbols } from '../../utils/chalk-markdown.js'
|
|
14
15
|
import { InputError } from '../../utils/errors.js'
|
|
16
|
+
import { prepareFlags } from '../../utils/flags.js'
|
|
15
17
|
import { printFlagList } from '../../utils/formatting.js'
|
|
16
18
|
import { createDebugLogger } from '../../utils/misc.js'
|
|
17
19
|
import { getPackageFiles } from '../../utils/path-resolve.js'
|
|
@@ -79,6 +81,28 @@ export const create = {
|
|
|
79
81
|
* @returns {Promise<void|CommandContext>}
|
|
80
82
|
*/
|
|
81
83
|
async function setupCommand (name, description, argv, importMeta) {
|
|
84
|
+
const flags = prepareFlags({
|
|
85
|
+
...outputFlags,
|
|
86
|
+
...validationFlags,
|
|
87
|
+
debug: {
|
|
88
|
+
type: 'boolean',
|
|
89
|
+
alias: 'd',
|
|
90
|
+
default: false,
|
|
91
|
+
description: 'Output debug information',
|
|
92
|
+
},
|
|
93
|
+
dryRun: {
|
|
94
|
+
type: 'boolean',
|
|
95
|
+
default: false,
|
|
96
|
+
description: 'Only output what will be done without actually doing it',
|
|
97
|
+
},
|
|
98
|
+
view: {
|
|
99
|
+
type: 'boolean',
|
|
100
|
+
alias: 'v',
|
|
101
|
+
default: false,
|
|
102
|
+
description: 'Will wait for and return the created report'
|
|
103
|
+
},
|
|
104
|
+
})
|
|
105
|
+
|
|
82
106
|
const cli = meow(`
|
|
83
107
|
Usage
|
|
84
108
|
$ ${name} <paths-to-package-folders-and-files>
|
|
@@ -114,40 +138,7 @@ async function setupCommand (name, description, argv, importMeta) {
|
|
|
114
138
|
argv,
|
|
115
139
|
description,
|
|
116
140
|
importMeta,
|
|
117
|
-
flags
|
|
118
|
-
all: {
|
|
119
|
-
type: 'boolean',
|
|
120
|
-
default: false,
|
|
121
|
-
},
|
|
122
|
-
debug: {
|
|
123
|
-
type: 'boolean',
|
|
124
|
-
alias: 'd',
|
|
125
|
-
default: false,
|
|
126
|
-
},
|
|
127
|
-
dryRun: {
|
|
128
|
-
type: 'boolean',
|
|
129
|
-
default: false,
|
|
130
|
-
},
|
|
131
|
-
json: {
|
|
132
|
-
type: 'boolean',
|
|
133
|
-
alias: 'j',
|
|
134
|
-
default: false,
|
|
135
|
-
},
|
|
136
|
-
markdown: {
|
|
137
|
-
type: 'boolean',
|
|
138
|
-
alias: 'm',
|
|
139
|
-
default: false,
|
|
140
|
-
},
|
|
141
|
-
strict: {
|
|
142
|
-
type: 'boolean',
|
|
143
|
-
default: false,
|
|
144
|
-
},
|
|
145
|
-
view: {
|
|
146
|
-
type: 'boolean',
|
|
147
|
-
alias: 'v',
|
|
148
|
-
default: false,
|
|
149
|
-
},
|
|
150
|
-
}
|
|
141
|
+
flags,
|
|
151
142
|
})
|
|
152
143
|
|
|
153
144
|
const {
|
|
@@ -224,7 +215,7 @@ async function createReport (packagePaths, { config, cwd, debugLog, dryRun }) {
|
|
|
224
215
|
const result = await handleApiCall(apiCall, spinner, 'creating report')
|
|
225
216
|
|
|
226
217
|
if (result.success === false) {
|
|
227
|
-
return handleUnsuccessfulApiResponse(result, spinner)
|
|
218
|
+
return handleUnsuccessfulApiResponse('createReport', result, spinner)
|
|
228
219
|
}
|
|
229
220
|
|
|
230
221
|
// Conclude the status of the API call
|
|
@@ -4,6 +4,7 @@ import chalk from 'chalk'
|
|
|
4
4
|
import meow from 'meow'
|
|
5
5
|
import ora from 'ora'
|
|
6
6
|
|
|
7
|
+
import { outputFlags, validationFlags } from '../../flags/index.js'
|
|
7
8
|
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api-helpers.js'
|
|
8
9
|
import { ChalkOrMarkdown } from '../../utils/chalk-markdown.js'
|
|
9
10
|
import { InputError } from '../../utils/errors.js'
|
|
@@ -28,7 +29,6 @@ export const view = {
|
|
|
28
29
|
|
|
29
30
|
// Internal functions
|
|
30
31
|
|
|
31
|
-
// TODO: Share more of the flag setup inbetween the commands
|
|
32
32
|
/**
|
|
33
33
|
* @typedef CommandContext
|
|
34
34
|
* @property {boolean} includeAllIssues
|
|
@@ -46,17 +46,17 @@ export const view = {
|
|
|
46
46
|
* @returns {void|CommandContext}
|
|
47
47
|
*/
|
|
48
48
|
function setupCommand (name, description, argv, importMeta) {
|
|
49
|
+
const flags = {
|
|
50
|
+
...outputFlags,
|
|
51
|
+
...validationFlags,
|
|
52
|
+
}
|
|
53
|
+
|
|
49
54
|
const cli = meow(`
|
|
50
55
|
Usage
|
|
51
56
|
$ ${name} <report-identifier>
|
|
52
57
|
|
|
53
58
|
Options
|
|
54
|
-
${printFlagList(
|
|
55
|
-
'--all': 'Include all issues',
|
|
56
|
-
'--json': 'Output result as json',
|
|
57
|
-
'--markdown': 'Output result as markdown',
|
|
58
|
-
'--strict': 'Exits with an error code if report result is deemed unhealthy',
|
|
59
|
-
}, 6)}
|
|
59
|
+
${printFlagList(flags, 6)}
|
|
60
60
|
|
|
61
61
|
Examples
|
|
62
62
|
$ ${name} QXU8PmK7LfH608RAwfIKdbcHgwEd_ZeWJ9QEGv05FJUQ
|
|
@@ -64,26 +64,7 @@ function setupCommand (name, description, argv, importMeta) {
|
|
|
64
64
|
argv,
|
|
65
65
|
description,
|
|
66
66
|
importMeta,
|
|
67
|
-
flags
|
|
68
|
-
all: {
|
|
69
|
-
type: 'boolean',
|
|
70
|
-
default: false,
|
|
71
|
-
},
|
|
72
|
-
json: {
|
|
73
|
-
type: 'boolean',
|
|
74
|
-
alias: 'j',
|
|
75
|
-
default: false,
|
|
76
|
-
},
|
|
77
|
-
markdown: {
|
|
78
|
-
type: 'boolean',
|
|
79
|
-
alias: 'm',
|
|
80
|
-
default: false,
|
|
81
|
-
},
|
|
82
|
-
strict: {
|
|
83
|
-
type: 'boolean',
|
|
84
|
-
default: false,
|
|
85
|
-
},
|
|
86
|
-
}
|
|
67
|
+
flags,
|
|
87
68
|
})
|
|
88
69
|
|
|
89
70
|
// Extract the input
|
|
@@ -134,7 +115,7 @@ export async function fetchReportData (reportId, { includeAllIssues, strict }) {
|
|
|
134
115
|
const result = await handleApiCall(socketSdk.getReport(reportId), spinner, 'fetching report')
|
|
135
116
|
|
|
136
117
|
if (result.success === false) {
|
|
137
|
-
return handleUnsuccessfulApiResponse(result, spinner)
|
|
118
|
+
return handleUnsuccessfulApiResponse('getReport', result, spinner)
|
|
138
119
|
}
|
|
139
120
|
|
|
140
121
|
// Conclude the status of the API call
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { prepareFlags } from '../utils/flags.js'
|
|
2
|
+
|
|
3
|
+
export const outputFlags = prepareFlags({
|
|
4
|
+
json: {
|
|
5
|
+
type: 'boolean',
|
|
6
|
+
alias: 'j',
|
|
7
|
+
default: false,
|
|
8
|
+
description: 'Output result as json',
|
|
9
|
+
},
|
|
10
|
+
markdown: {
|
|
11
|
+
type: 'boolean',
|
|
12
|
+
alias: 'm',
|
|
13
|
+
default: false,
|
|
14
|
+
description: 'Output result as markdown',
|
|
15
|
+
},
|
|
16
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { prepareFlags } from '../utils/flags.js'
|
|
2
|
+
|
|
3
|
+
export const validationFlags = prepareFlags({
|
|
4
|
+
all: {
|
|
5
|
+
type: 'boolean',
|
|
6
|
+
default: false,
|
|
7
|
+
description: 'Include all issues',
|
|
8
|
+
},
|
|
9
|
+
strict: {
|
|
10
|
+
type: 'boolean',
|
|
11
|
+
default: false,
|
|
12
|
+
description: 'Exits with an error code if any matching issues are found',
|
|
13
|
+
},
|
|
14
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
const { chmodSync, realpathSync } = require('fs')
|
|
3
|
+
const path = require('path')
|
|
4
|
+
|
|
5
|
+
const which = require('which')
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} realDirname path to shadow/bin
|
|
9
|
+
* @param {'npm' | 'npx'} binname
|
|
10
|
+
* @returns {string} path to npm provided cli / npx bin
|
|
11
|
+
*/
|
|
12
|
+
function installLinks (realDirname, binname) {
|
|
13
|
+
const realNpmShadowBinDir = realDirname
|
|
14
|
+
// find npm being shadowed by this process
|
|
15
|
+
const npms = which.sync(binname, {
|
|
16
|
+
all: true
|
|
17
|
+
})
|
|
18
|
+
let shadowIndex = -1
|
|
19
|
+
const npmpath = npms.find((npmPath, i) => {
|
|
20
|
+
const isShadow = realpathSync(path.dirname(npmPath)) === realNpmShadowBinDir
|
|
21
|
+
if (isShadow) {
|
|
22
|
+
shadowIndex = i
|
|
23
|
+
}
|
|
24
|
+
return !isShadow
|
|
25
|
+
})
|
|
26
|
+
if (!npmpath) {
|
|
27
|
+
console.error('Socket unable to locate npm ensure it is available in the PATH environment variable')
|
|
28
|
+
process.exit(127)
|
|
29
|
+
}
|
|
30
|
+
if (shadowIndex === -1) {
|
|
31
|
+
chmodSync(realNpmShadowBinDir, parseInt('755', 8))
|
|
32
|
+
const bindir = path.join(realDirname)
|
|
33
|
+
process.env['PATH'] = `${
|
|
34
|
+
bindir
|
|
35
|
+
}${
|
|
36
|
+
process.platform === 'win32' ? ';' : ':'
|
|
37
|
+
}${
|
|
38
|
+
process.env['PATH']
|
|
39
|
+
}`
|
|
40
|
+
}
|
|
41
|
+
return npmpath
|
|
42
|
+
}
|
|
43
|
+
module.exports = installLinks
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// THIS FILE USES .cjs to get around the extension-free entrypoint problem with ESM
|
|
3
|
+
'use strict'
|
|
4
|
+
const { spawn } = require('child_process')
|
|
5
|
+
const { realpathSync } = require('fs')
|
|
6
|
+
const path = require('path')
|
|
7
|
+
|
|
8
|
+
const realFilename = realpathSync(__filename)
|
|
9
|
+
const realDirname = path.dirname(realFilename)
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*/
|
|
13
|
+
async function main () {
|
|
14
|
+
const npmpath = await require('./link.cjs')(path.join(realDirname, 'bin'), 'npm')
|
|
15
|
+
process.exitCode = 1
|
|
16
|
+
const injectionpath = path.join(realDirname, 'npm-injection.cjs')
|
|
17
|
+
spawn(process.execPath, ['--require', injectionpath, npmpath, ...process.argv.slice(2)], {
|
|
18
|
+
stdio: 'inherit'
|
|
19
|
+
}).on('exit', (code, signal) => {
|
|
20
|
+
if (signal) {
|
|
21
|
+
process.kill(process.pid, signal)
|
|
22
|
+
} else if (code !== null) {
|
|
23
|
+
process.exit(code)
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
main()
|