npq 3.23.3 → 3.25.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/README.md +17 -0
- package/bin/npq-hero.js +116 -107
- package/bin/npq.js +151 -139
- package/lib/cli.js +26 -8
- package/lib/helpers/auditFailure.js +25 -0
- package/lib/helpers/codingAgentEnvironment.js +23 -0
- package/lib/helpers/jsonOutput.js +24 -0
- package/lib/helpers/jsonPackageSpec.js +29 -0
- package/lib/helpers/jsonReport.js +76 -0
- package/lib/helpers/registryClient.js +2 -7
- package/lib/helpers/registryConfig.js +2 -8
- package/lib/helpers/reportResults.js +5 -16
- package/lib/helpers/versionAge.js +2 -9
- package/lib/jsonAudit.js +71 -0
- package/lib/jsonCli.js +61 -0
- package/lib/marshall.js +11 -6
- package/lib/marshalls/baseMarshall.js +1 -1
- package/lib/marshalls/index.js +44 -7
- package/lib/marshalls/signatures.marshall.js +1 -4
- package/package.json +3 -1
- package/schema/npq-output-v1.schema.json +86 -0
package/README.md
CHANGED
|
@@ -222,6 +222,23 @@ npq install express --dry-run
|
|
|
222
222
|
npq install express --plain
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
+
### Machine-readable audits
|
|
226
|
+
|
|
227
|
+
Use `--json` for a non-interactive, audit-only result suitable for CI:
|
|
228
|
+
|
|
229
|
+
```sh
|
|
230
|
+
npq install express --json
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
When npq detects a supported coding-agent environment, it automatically uses
|
|
234
|
+
the same audit-only JSON mode. This applies to `npq` and to install commands
|
|
235
|
+
intercepted by `npq-hero`; non-install `npq-hero` commands still pass through to
|
|
236
|
+
the configured package manager. See [JSON audit output](docs/feature/json-output.md#coding-agent-detection).
|
|
237
|
+
|
|
238
|
+
JSON mode never invokes the package manager. It exits `0` for a clean audit,
|
|
239
|
+
`1` for findings, and `2` when the audit cannot complete. See
|
|
240
|
+
[JSON audit output](docs/feature/json-output.md).
|
|
241
|
+
|
|
225
242
|
### Disable auto-continue countdown
|
|
226
243
|
|
|
227
244
|
By default, when npq detects only warnings (no errors), it automatically proceeds with installation after a 15-second countdown. To disable this behavior and always require explicit confirmation:
|
package/bin/npq-hero.js
CHANGED
|
@@ -14,133 +14,142 @@ const { Spinner } = require('../lib/helpers/cliSpinner')
|
|
|
14
14
|
const { promiseThrottleHelper } = require('../lib/helpers/promiseThrottler')
|
|
15
15
|
const RegistryConfig = require('../lib/helpers/registryConfig')
|
|
16
16
|
const RegistryClient = require('../lib/helpers/registryClient')
|
|
17
|
+
const { createJsonOutput } = require('../lib/helpers/jsonOutput')
|
|
18
|
+
const { runJsonCli, writeInvalidJsonInvocation } = require('../lib/jsonCli')
|
|
19
|
+
const { isCodingAgentEnvironment } = require('../lib/helpers/codingAgentEnvironment')
|
|
17
20
|
|
|
18
21
|
const PACKAGE_MANAGER_TOOL = process.env.NPQ_PKG_MGR
|
|
19
22
|
const DISABLE_AUTO_CONTINUE = process.env.NPQ_DISABLE_AUTO_CONTINUE === 'true'
|
|
20
23
|
|
|
21
|
-
const
|
|
24
|
+
const codingAgentEnvironment = isCodingAgentEnvironment()
|
|
25
|
+
let cliArgs
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
try {
|
|
28
|
+
cliArgs = CliParser.parseArgsMinimal({ codingAgentEnvironment })
|
|
29
|
+
} catch (error) {
|
|
30
|
+
if (!error || error.npqJsonMode !== true) throw error
|
|
31
|
+
writeInvalidJsonInvocation(createJsonOutput())
|
|
32
|
+
process.exitCode = 2
|
|
33
|
+
}
|
|
24
34
|
|
|
25
|
-
|
|
26
|
-
|
|
35
|
+
if (cliArgs && cliArgs.json) {
|
|
36
|
+
runJsonCli(cliArgs, { output: createJsonOutput() })
|
|
37
|
+
} else if (cliArgs) {
|
|
38
|
+
const silentModeNoPackages = !cliArgs || !cliArgs.packages || cliArgs.packages.length === 0
|
|
27
39
|
|
|
28
|
-
|
|
29
|
-
spinner
|
|
30
|
-
|
|
40
|
+
const isInteractive = cliSupport.isInteractiveTerminal() && !silentModeNoPackages
|
|
41
|
+
const spinner = isInteractive ? new Spinner({ text: 'Initiating...' }) : null
|
|
42
|
+
|
|
43
|
+
if (spinner) {
|
|
44
|
+
spinner.start()
|
|
45
|
+
}
|
|
31
46
|
|
|
32
|
-
RegistryConfig.load({ argv: cliArgs.registryConfigArgs || [] })
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
RegistryConfig.load({ argv: cliArgs.registryConfigArgs || [] })
|
|
48
|
+
.then((registryConfig) => {
|
|
49
|
+
const registryClient = new RegistryClient(registryConfig)
|
|
50
|
+
const marshall = new Marshall({
|
|
51
|
+
pkgs: cliArgs.packages,
|
|
52
|
+
registryClient,
|
|
53
|
+
progressManager: spinner,
|
|
54
|
+
promiseThrottleHelper
|
|
55
|
+
})
|
|
56
|
+
return marshall.process()
|
|
40
57
|
})
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
spinner.stop()
|
|
46
|
-
}
|
|
58
|
+
.then((marshallResults) => {
|
|
59
|
+
if (spinner) {
|
|
60
|
+
spinner.stop()
|
|
61
|
+
}
|
|
47
62
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
countErrors
|
|
56
|
-
|
|
57
|
-
countNotEvaluated = 0,
|
|
58
|
-
useRichFormatting
|
|
59
|
-
} = results
|
|
60
|
-
const hasFindings = countErrors > 0 || countWarnings > 0
|
|
61
|
-
const hasReportableResults = hasFindings || countNotEvaluated > 0
|
|
63
|
+
const results = reportResults(marshallResults)
|
|
64
|
+
if (
|
|
65
|
+
results &&
|
|
66
|
+
Object.hasOwn(results, 'countErrors') &&
|
|
67
|
+
Object.hasOwn(results, 'countWarnings')
|
|
68
|
+
) {
|
|
69
|
+
const { countErrors, countWarnings, countNotEvaluated = 0, useRichFormatting } = results
|
|
70
|
+
const hasFindings = countErrors > 0 || countWarnings > 0
|
|
71
|
+
const hasReportableResults = hasFindings || countNotEvaluated > 0
|
|
62
72
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
hasFindings ? 'Packages with issues found:' : 'Package checks not evaluated:'
|
|
67
|
-
)
|
|
73
|
+
if (hasReportableResults) {
|
|
74
|
+
console.log()
|
|
75
|
+
console.log(hasFindings ? 'Packages with issues found:' : 'Package checks not evaluated:')
|
|
68
76
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
if (useRichFormatting) {
|
|
78
|
+
console.log(results.resultsForPrettyPrint)
|
|
79
|
+
console.log(results.summaryForPrettyPrint)
|
|
80
|
+
} else {
|
|
81
|
+
console.log(results.resultsForPlainTextPrint)
|
|
82
|
+
console.log(results.summaryForPlainTextPrint)
|
|
83
|
+
}
|
|
75
84
|
}
|
|
76
|
-
}
|
|
77
85
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
return {
|
|
87
|
+
anyIssues: hasFindings,
|
|
88
|
+
countErrors,
|
|
89
|
+
countWarnings,
|
|
90
|
+
countNotEvaluated
|
|
91
|
+
}
|
|
83
92
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (result && result.countErrors > 0) {
|
|
89
|
-
console.log()
|
|
90
|
-
return cliPrompt.prompt({
|
|
91
|
-
name: 'install',
|
|
92
|
-
message: 'Continue install ?',
|
|
93
|
-
default: false
|
|
94
|
-
})
|
|
95
|
-
} else {
|
|
96
|
-
if (result && result.countWarnings > 0) {
|
|
93
|
+
return undefined
|
|
94
|
+
})
|
|
95
|
+
.then((result) => {
|
|
96
|
+
if (result && result.countErrors > 0) {
|
|
97
97
|
console.log()
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
return cliPrompt.prompt({
|
|
99
|
+
name: 'install',
|
|
100
|
+
message: 'Continue install ?',
|
|
101
|
+
default: false
|
|
102
|
+
})
|
|
103
|
+
} else {
|
|
104
|
+
if (result && result.countWarnings > 0) {
|
|
105
|
+
console.log()
|
|
106
|
+
// Check if auto-continue is disabled via environment variable
|
|
107
|
+
if (DISABLE_AUTO_CONTINUE) {
|
|
108
|
+
return cliPrompt.prompt({
|
|
109
|
+
name: 'install',
|
|
110
|
+
message: 'Continue install ?',
|
|
111
|
+
default: false
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
return cliPrompt.autoContinue({
|
|
101
115
|
name: 'install',
|
|
102
|
-
message: '
|
|
103
|
-
|
|
116
|
+
message: 'Auto-continue with install in... ',
|
|
117
|
+
timeInSeconds: 15
|
|
104
118
|
})
|
|
105
119
|
}
|
|
106
|
-
return cliPrompt.autoContinue({
|
|
107
|
-
name: 'install',
|
|
108
|
-
message: 'Auto-continue with install in... ',
|
|
109
|
-
timeInSeconds: 15
|
|
110
|
-
})
|
|
111
120
|
}
|
|
112
|
-
}
|
|
113
121
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
122
|
+
return { install: true }
|
|
123
|
+
})
|
|
124
|
+
.then((status) => {
|
|
125
|
+
if (
|
|
126
|
+
status &&
|
|
127
|
+
Object.prototype.hasOwnProperty.call(status, 'install') &&
|
|
128
|
+
status.install === true
|
|
129
|
+
) {
|
|
130
|
+
return pkgMgr.process(PACKAGE_MANAGER_TOOL)
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
.then((exitCode) => {
|
|
134
|
+
if (typeof exitCode === 'number') {
|
|
135
|
+
process.exitCode = exitCode
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
.catch((error) => {
|
|
139
|
+
// Ensure errorCode is always a number
|
|
140
|
+
let errorCode = -1
|
|
141
|
+
if (typeof error.code === 'number') {
|
|
142
|
+
errorCode = error.code
|
|
143
|
+
} else if (error.code === 'ABORT_ERR') {
|
|
144
|
+
errorCode = 1
|
|
145
|
+
} else if (error.code === 'USER_ABORT') {
|
|
146
|
+
errorCode = error.exitCode || 1
|
|
147
|
+
}
|
|
140
148
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
149
|
+
CliParser.exit({
|
|
150
|
+
errorCode,
|
|
151
|
+
message: error.message || 'An error occurred',
|
|
152
|
+
spinner
|
|
153
|
+
})
|
|
145
154
|
})
|
|
146
|
-
|
|
155
|
+
}
|
package/bin/npq.js
CHANGED
|
@@ -15,171 +15,183 @@ const cliPrompt = require('../lib/helpers/cliPrompt.js')
|
|
|
15
15
|
const { reportResults } = require('../lib/helpers/reportResults')
|
|
16
16
|
const { Spinner } = require('../lib/helpers/cliSpinner')
|
|
17
17
|
const { promiseThrottleHelper } = require('../lib/helpers/promiseThrottler')
|
|
18
|
+
const { createJsonOutput } = require('../lib/helpers/jsonOutput')
|
|
19
|
+
const { runJsonCli, writeInvalidJsonInvocation } = require('../lib/jsonCli')
|
|
20
|
+
const { isCodingAgentEnvironment } = require('../lib/helpers/codingAgentEnvironment')
|
|
18
21
|
const RegistryConfig = require('../lib/helpers/registryConfig')
|
|
19
22
|
const RegistryClient = require('../lib/helpers/registryClient')
|
|
20
23
|
|
|
21
24
|
const debug = util.debuglog('npq')
|
|
22
25
|
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
const spinner = isInteractive ? new Spinner({ text: 'Initiating...' }) : null
|
|
26
|
+
const jsonRequested = process.argv.slice(2).includes('--json') || isCodingAgentEnvironment()
|
|
27
|
+
const jsonOutput = jsonRequested ? createJsonOutput() : null
|
|
28
|
+
let cliArgs
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
try {
|
|
31
|
+
cliArgs = CliParser.parseArgsFull()
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (!jsonRequested) throw error
|
|
34
|
+
writeInvalidJsonInvocation(jsonOutput)
|
|
35
|
+
process.exitCode = 2
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
if (cliArgs && cliArgs.json) {
|
|
39
|
+
runJsonCli(cliArgs, { output: jsonOutput })
|
|
40
|
+
} else if (cliArgs) {
|
|
41
|
+
const auditOnly = cliArgs.dryRun || !cliArgs.installSubcommandExplicit
|
|
42
|
+
const isInteractive = cliSupport.isInteractiveTerminal() && !cliArgs.plain
|
|
43
|
+
const spinner = isInteractive ? new Spinner({ text: 'Initiating...' }) : null
|
|
33
44
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
})
|
|
38
|
-
.then(() => {
|
|
39
|
-
if (cliArgs.packages.length === 0) {
|
|
40
|
-
debug('\nNo packages specified, using project packages from package.json')
|
|
41
|
-
return getProjectPackages()
|
|
42
|
-
}
|
|
45
|
+
if (spinner) {
|
|
46
|
+
spinner.start()
|
|
47
|
+
}
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
})
|
|
46
|
-
.then((packages) => {
|
|
47
|
-
if (packages.error) {
|
|
48
|
-
console.log()
|
|
49
|
-
CliParser.exit({
|
|
50
|
-
errorCode: packages.error.code || -1,
|
|
51
|
-
message: packages.message,
|
|
52
|
-
spinner
|
|
53
|
-
})
|
|
54
|
-
}
|
|
49
|
+
let registryClient
|
|
55
50
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
promiseThrottleHelper
|
|
51
|
+
Promise.resolve()
|
|
52
|
+
.then(() => RegistryConfig.load({ argv: cliArgs.registryConfigArgs || [] }))
|
|
53
|
+
.then((registryConfig) => {
|
|
54
|
+
registryClient = new RegistryClient(registryConfig)
|
|
61
55
|
})
|
|
56
|
+
.then(() => {
|
|
57
|
+
if (cliArgs.packages.length === 0) {
|
|
58
|
+
debug('\nNo packages specified, using project packages from package.json')
|
|
59
|
+
return getProjectPackages()
|
|
60
|
+
}
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
spinner.stop()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const results = reportResults(marshallResults, { plain: cliArgs.plain })
|
|
71
|
-
if (
|
|
72
|
-
results &&
|
|
73
|
-
Object.hasOwn(results, 'countErrors') &&
|
|
74
|
-
Object.hasOwn(results, 'countWarnings')
|
|
75
|
-
) {
|
|
76
|
-
const {
|
|
77
|
-
countErrors,
|
|
78
|
-
countWarnings,
|
|
79
|
-
countNotEvaluated = 0,
|
|
80
|
-
useRichFormatting
|
|
81
|
-
} = results
|
|
82
|
-
const hasFindings = countErrors > 0 || countWarnings > 0
|
|
83
|
-
const hasReportableResults = hasFindings || countNotEvaluated > 0
|
|
84
|
-
|
|
85
|
-
if (hasReportableResults) {
|
|
62
|
+
return cliArgs.packages
|
|
63
|
+
})
|
|
64
|
+
.then((packages) => {
|
|
65
|
+
if (packages.error) {
|
|
86
66
|
console.log()
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
console.log(results.resultsForPrettyPrint)
|
|
93
|
-
console.log(results.summaryForPrettyPrint)
|
|
94
|
-
} else {
|
|
95
|
-
console.log(results.resultsForPlainTextPrint)
|
|
96
|
-
console.log(results.summaryForPlainTextPrint)
|
|
97
|
-
}
|
|
67
|
+
CliParser.exit({
|
|
68
|
+
errorCode: packages.error.code || -1,
|
|
69
|
+
message: packages.message,
|
|
70
|
+
spinner
|
|
71
|
+
})
|
|
98
72
|
}
|
|
99
73
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return undefined
|
|
108
|
-
})
|
|
109
|
-
.then((result) => {
|
|
110
|
-
if (auditOnly) {
|
|
111
|
-
const auditFailed = result && (result.countErrors > 0 || result.countWarnings > 0)
|
|
112
|
-
CliParser.exit({
|
|
113
|
-
errorCode: auditFailed ? 1 : 0,
|
|
114
|
-
spinner
|
|
74
|
+
const marshall = new Marshall({
|
|
75
|
+
pkgs: packages,
|
|
76
|
+
registryClient,
|
|
77
|
+
progressManager: spinner,
|
|
78
|
+
promiseThrottleHelper
|
|
115
79
|
})
|
|
80
|
+
|
|
81
|
+
return marshall.process()
|
|
82
|
+
})
|
|
83
|
+
.then((marshallResults) => {
|
|
84
|
+
if (spinner) {
|
|
85
|
+
spinner.stop()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const results = reportResults(marshallResults, { plain: cliArgs.plain })
|
|
89
|
+
if (
|
|
90
|
+
results &&
|
|
91
|
+
Object.hasOwn(results, 'countErrors') &&
|
|
92
|
+
Object.hasOwn(results, 'countWarnings')
|
|
93
|
+
) {
|
|
94
|
+
const { countErrors, countWarnings, countNotEvaluated = 0, useRichFormatting } = results
|
|
95
|
+
const hasFindings = countErrors > 0 || countWarnings > 0
|
|
96
|
+
const hasReportableResults = hasFindings || countNotEvaluated > 0
|
|
97
|
+
|
|
98
|
+
if (hasReportableResults) {
|
|
99
|
+
console.log()
|
|
100
|
+
console.log(hasFindings ? 'Packages with issues found:' : 'Package checks not evaluated:')
|
|
101
|
+
|
|
102
|
+
if (useRichFormatting) {
|
|
103
|
+
console.log(results.resultsForPrettyPrint)
|
|
104
|
+
console.log(results.summaryForPrettyPrint)
|
|
105
|
+
} else {
|
|
106
|
+
console.log(results.resultsForPlainTextPrint)
|
|
107
|
+
console.log(results.summaryForPlainTextPrint)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
anyIssues: hasFindings,
|
|
113
|
+
countErrors,
|
|
114
|
+
countWarnings,
|
|
115
|
+
countNotEvaluated
|
|
116
|
+
}
|
|
117
|
+
}
|
|
116
118
|
return undefined
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
119
|
+
})
|
|
120
|
+
.then((result) => {
|
|
121
|
+
if (auditOnly) {
|
|
122
|
+
const auditFailed = result && (result.countErrors > 0 || result.countWarnings > 0)
|
|
123
|
+
CliParser.exit({
|
|
124
|
+
errorCode: auditFailed ? 1 : 0,
|
|
125
|
+
spinner
|
|
126
|
+
})
|
|
127
|
+
return undefined
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (result && result.countErrors > 0) {
|
|
128
131
|
console.log()
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
return cliPrompt.prompt({
|
|
133
|
+
name: 'install',
|
|
134
|
+
message: 'Continue install ?',
|
|
135
|
+
default: false
|
|
136
|
+
})
|
|
137
|
+
} else {
|
|
138
|
+
if (result && result.countWarnings > 0) {
|
|
139
|
+
console.log()
|
|
140
|
+
// Check if auto-continue is disabled via CLI flag or environment variable
|
|
141
|
+
if (cliArgs.disableAutoContinue) {
|
|
142
|
+
return cliPrompt.prompt({
|
|
143
|
+
name: 'install',
|
|
144
|
+
message: 'Continue install ?',
|
|
145
|
+
default: false
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
return cliPrompt.autoContinue({
|
|
132
149
|
name: 'install',
|
|
133
|
-
message: '
|
|
134
|
-
|
|
150
|
+
message: 'Auto-continue with install in... ',
|
|
151
|
+
timeInSeconds: 15
|
|
135
152
|
})
|
|
136
153
|
}
|
|
137
|
-
return cliPrompt.autoContinue({
|
|
138
|
-
name: 'install',
|
|
139
|
-
message: 'Auto-continue with install in... ',
|
|
140
|
-
timeInSeconds: 15
|
|
141
|
-
})
|
|
142
154
|
}
|
|
143
|
-
}
|
|
144
155
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
156
|
+
return { install: true }
|
|
157
|
+
})
|
|
158
|
+
.then((status) => {
|
|
159
|
+
if (
|
|
160
|
+
status &&
|
|
161
|
+
Object.prototype.hasOwnProperty.call(status, 'install') &&
|
|
162
|
+
status.install === true
|
|
163
|
+
) {
|
|
164
|
+
return pkgMgr.process(cliArgs.packageManager)
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
.then((exitCode) => {
|
|
168
|
+
if (typeof exitCode === 'number') {
|
|
169
|
+
process.exitCode = exitCode
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
.catch((error) => {
|
|
173
|
+
// Ensure errorCode is always a number
|
|
174
|
+
let errorCode = -1
|
|
175
|
+
if (typeof error.code === 'number') {
|
|
176
|
+
errorCode = error.code
|
|
177
|
+
} else if (error.code === 'ABORT_ERR') {
|
|
178
|
+
errorCode = 1
|
|
179
|
+
} else if (error.code === 'USER_ABORT') {
|
|
180
|
+
errorCode = error.exitCode || 1
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
CliParser.exit({
|
|
184
|
+
errorCode,
|
|
185
|
+
message: error.message || 'An error occurred',
|
|
186
|
+
spinner
|
|
187
|
+
})
|
|
188
|
+
})
|
|
171
189
|
|
|
190
|
+
// attach event handler for CTRL+C
|
|
191
|
+
process.on('SIGINT', () => {
|
|
172
192
|
CliParser.exit({
|
|
173
|
-
errorCode,
|
|
174
|
-
message: error.message || 'An error occurred',
|
|
193
|
+
errorCode: 0,
|
|
175
194
|
spinner
|
|
176
195
|
})
|
|
177
196
|
})
|
|
178
|
-
|
|
179
|
-
// attach event handler for CTRL+C
|
|
180
|
-
process.on('SIGINT', () => {
|
|
181
|
-
CliParser.exit({
|
|
182
|
-
errorCode: 0,
|
|
183
|
-
spinner
|
|
184
|
-
})
|
|
185
|
-
})
|
|
197
|
+
}
|