heroku 10.6.2-alpha.0 → 10.7.0-beta.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/bin/run +7 -36
- package/lib/analytics.js +1 -3
- package/lib/commands/addons/create.js +0 -9
- package/lib/commands/keys/add.js +1 -1
- package/lib/global_telemetry.d.ts +1 -1
- package/lib/global_telemetry.js +1 -3
- package/lib/lib/ci/source.js +3 -2
- package/oclif.manifest.json +624 -624
- package/package.json +4 -8
- package/bin/heroku-prompts.js +0 -235
- package/bin/heroku-repl.js +0 -620
- package/lib/hooks/plugins/preinstall/disclaimers.d.ts +0 -3
- package/lib/hooks/plugins/preinstall/disclaimers.js +0 -26
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "heroku",
|
|
3
3
|
"description": "CLI to interact with Heroku",
|
|
4
|
-
"version": "10.
|
|
4
|
+
"version": "10.7.0-beta.0",
|
|
5
5
|
"author": "Heroku",
|
|
6
6
|
"bin": "./bin/run",
|
|
7
7
|
"bugs": "https://github.com/heroku/cli/issues",
|
|
@@ -79,8 +79,7 @@
|
|
|
79
79
|
"validator": "^13.7.0",
|
|
80
80
|
"word-wrap": "^1.2.5",
|
|
81
81
|
"ws": "^6.2.2",
|
|
82
|
-
"yaml": "^2.0.1"
|
|
83
|
-
"yargs-parser": "18.1.3"
|
|
82
|
+
"yaml": "^2.0.1"
|
|
84
83
|
},
|
|
85
84
|
"devDependencies": {
|
|
86
85
|
"@heroku-cli/schema": "^1.0.25",
|
|
@@ -321,9 +320,6 @@
|
|
|
321
320
|
"./lib/hooks/init/terms-of-service",
|
|
322
321
|
"./lib/hooks/init/performance_analytics"
|
|
323
322
|
],
|
|
324
|
-
"plugins:preinstall": [
|
|
325
|
-
"./lib/hooks/plugins/preinstall/disclaimers"
|
|
326
|
-
],
|
|
327
323
|
"prerun": [
|
|
328
324
|
"./lib/hooks/prerun/analytics"
|
|
329
325
|
],
|
|
@@ -392,12 +388,12 @@
|
|
|
392
388
|
"test:acceptance": "yarn pretest && mocha --forbid-only \"test/**/*.acceptance.test.ts\" && node ./bin/bats-test-runner",
|
|
393
389
|
"test:integration": "yarn pretest && mocha --forbid-only \"test/**/*.integration.test.ts\"",
|
|
394
390
|
"test:smoke": "yarn pretest && mocha --forbid-only \"test/**/smoke.acceptance.test.ts\"",
|
|
395
|
-
"test:unit:justTest:local": "mocha \"test/**/*.unit.test.ts\"",
|
|
391
|
+
"test:unit:justTest:local": "nyc mocha \"test/**/*.unit.test.ts\"",
|
|
396
392
|
"test:unit:justTest:ci": "nyc --reporter=lcov --reporter=text-summary mocha --forbid-only \"test/**/*.unit.test.ts\"",
|
|
397
393
|
"test": "yarn pretest && yarn test:unit:justTest:ci",
|
|
398
394
|
"test:local": "yarn pretest && yarn test:unit:justTest:local",
|
|
399
395
|
"version": "oclif readme --multi && git add README.md ../../docs"
|
|
400
396
|
},
|
|
401
397
|
"types": "lib/index.d.ts",
|
|
402
|
-
"gitHead": "
|
|
398
|
+
"gitHead": "eb24290509cdedb393f263cc748b9a675a9cd120"
|
|
403
399
|
}
|
package/bin/heroku-prompts.js
DELETED
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
const fs = require('node:fs')
|
|
2
|
-
const inquirer = require('inquirer')
|
|
3
|
-
|
|
4
|
-
function choicesPrompt(description, choices, required, defaultValue) {
|
|
5
|
-
return inquirer.prompt([{
|
|
6
|
-
type: 'list',
|
|
7
|
-
name: 'choices',
|
|
8
|
-
message: description,
|
|
9
|
-
choices,
|
|
10
|
-
default: defaultValue,
|
|
11
|
-
validate(input) {
|
|
12
|
-
if (!required || input) {
|
|
13
|
-
return true
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return `${description} is required`
|
|
17
|
-
},
|
|
18
|
-
}])
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function prompt(description, required) {
|
|
22
|
-
return inquirer.prompt([{
|
|
23
|
-
type: 'input',
|
|
24
|
-
name: 'input',
|
|
25
|
-
message: description,
|
|
26
|
-
validate(input) {
|
|
27
|
-
if (!required || input.trim()) {
|
|
28
|
-
return true
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return `${description} is required`
|
|
32
|
-
},
|
|
33
|
-
}])
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function filePrompt(description, defaultPath) {
|
|
37
|
-
return inquirer.prompt([{
|
|
38
|
-
type: 'input',
|
|
39
|
-
name: 'path',
|
|
40
|
-
message: description,
|
|
41
|
-
default: defaultPath,
|
|
42
|
-
validate(input) {
|
|
43
|
-
if (fs.existsSync(input)) {
|
|
44
|
-
return true
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return 'File does not exist. Please enter a valid file path.'
|
|
48
|
-
},
|
|
49
|
-
}])
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const showBooleanPrompt = async (commandFlag, userInputMap, defaultOption) => {
|
|
53
|
-
const {description, default: defaultValue, name: flagOrArgName} = commandFlag
|
|
54
|
-
const choice = await choicesPrompt(description, [
|
|
55
|
-
{name: 'yes', value: true},
|
|
56
|
-
{name: 'no', value: false},
|
|
57
|
-
], defaultOption)
|
|
58
|
-
|
|
59
|
-
// user cancelled
|
|
60
|
-
if (choice === undefined || choice === 'Cancel') {
|
|
61
|
-
return true
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (choice === 'Yes') {
|
|
65
|
-
userInputMap.set(flagOrArgName, defaultValue)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return false
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const showOtherDialog = async (commandFlagOrArg, userInputMap) => {
|
|
72
|
-
const {description, default: defaultValue, options, required, name: flagOrArgName} = commandFlagOrArg
|
|
73
|
-
|
|
74
|
-
let input
|
|
75
|
-
const isFileInput = description?.includes('absolute path')
|
|
76
|
-
if (isFileInput) {
|
|
77
|
-
input = await filePrompt(description, '')
|
|
78
|
-
} else if (options) {
|
|
79
|
-
const choices = options.map(option => ({name: option, value: option}))
|
|
80
|
-
input = await choicesPrompt(`Select the ${description}`, choices, required, defaultValue)
|
|
81
|
-
} else {
|
|
82
|
-
input = await prompt(`${description.slice(0, 1).toUpperCase()}${description.slice(1)} (${required ? 'required' : 'optional - press "Enter" to bypass'})`, required)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (input === undefined) {
|
|
86
|
-
return true
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (input !== '') {
|
|
90
|
-
userInputMap.set(flagOrArgName, input)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return false
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function collectInputsFromManifest(flagsOrArgsManifest, omitOptional) {
|
|
97
|
-
const requiredInputs = []
|
|
98
|
-
const optionalInputs = []
|
|
99
|
-
|
|
100
|
-
// Prioritize options over booleans to
|
|
101
|
-
// prevent the user from yo-yo back and
|
|
102
|
-
// forth between the different input dialogs
|
|
103
|
-
const keysByType = Object.keys(flagsOrArgsManifest).sort((a, b) => {
|
|
104
|
-
const {type: aType} = flagsOrArgsManifest[a]
|
|
105
|
-
const {type: bType} = flagsOrArgsManifest[b]
|
|
106
|
-
if (aType === bType) {
|
|
107
|
-
return 0
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (aType === 'option') {
|
|
111
|
-
return -1
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (bType === 'option') {
|
|
115
|
-
return 1
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return 0
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
keysByType.forEach(key => {
|
|
122
|
-
const isRequired = Reflect.get(flagsOrArgsManifest[key], 'required');
|
|
123
|
-
(isRequired ? requiredInputs : optionalInputs).push(key)
|
|
124
|
-
})
|
|
125
|
-
// Prioritize required inputs
|
|
126
|
-
// over optional inputs when
|
|
127
|
-
// prompting the user.
|
|
128
|
-
// required inputs are sorted
|
|
129
|
-
// alphabetically. optional
|
|
130
|
-
// inputs are sorted alphabetically
|
|
131
|
-
// and then pushed to the end of
|
|
132
|
-
// the list.
|
|
133
|
-
requiredInputs.sort((a, b) => {
|
|
134
|
-
if (a < b) {
|
|
135
|
-
return -1
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (a > b) {
|
|
139
|
-
return 1
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return 0
|
|
143
|
-
})
|
|
144
|
-
// Include optional only when not explicitly omitted
|
|
145
|
-
return omitOptional ? requiredInputs : [...requiredInputs, ...optionalInputs]
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async function getInput(flagsOrArgsManifest, userInputMap, omitOptional) {
|
|
149
|
-
const flagsOrArgs = collectInputsFromManifest(flagsOrArgsManifest, omitOptional)
|
|
150
|
-
|
|
151
|
-
for (const flagOrArg of flagsOrArgs) {
|
|
152
|
-
const {name, description, type, hidden} = flagsOrArgsManifest[flagOrArg]
|
|
153
|
-
if (userInputMap.has(name)) {
|
|
154
|
-
continue
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// hidden args and flags may be exposed later
|
|
158
|
-
// based on the user type. For now, skip them.
|
|
159
|
-
if (!description || hidden) {
|
|
160
|
-
continue
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const cancelled = await (type === 'boolean' ? showBooleanPrompt : showOtherDialog)(flagsOrArgsManifest[flagOrArg], userInputMap)
|
|
164
|
-
if (cancelled) {
|
|
165
|
-
return true
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return false
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
async function promptForInputs(commandName, commandManifest, userArgs, userFlags) {
|
|
173
|
-
const {args, flags} = commandManifest
|
|
174
|
-
|
|
175
|
-
const userInputByArg = new Map()
|
|
176
|
-
Object.keys(args).forEach((argKey, index) => {
|
|
177
|
-
if (userArgs[index]) {
|
|
178
|
-
userInputByArg.set(argKey, userArgs[index])
|
|
179
|
-
}
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
let cancelled = await getInput(args, userInputByArg)
|
|
183
|
-
if (cancelled) {
|
|
184
|
-
return {userInputByArg}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
const userInputByFlag = new Map()
|
|
188
|
-
Object.keys(flags).forEach(flagKey => {
|
|
189
|
-
const {name, char} = flags[flagKey]
|
|
190
|
-
if (userFlags[name] || userFlags[char]) {
|
|
191
|
-
userInputByFlag.set(flagKey, userFlags[flagKey])
|
|
192
|
-
}
|
|
193
|
-
})
|
|
194
|
-
cancelled = await getInput(flags, userInputByFlag)
|
|
195
|
-
if (cancelled) {
|
|
196
|
-
return
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
return {userInputByArg, userInputByFlag}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
module.exports.promptUser = async (config, commandName, args, flags) => {
|
|
203
|
-
const commandMeta = config.findCommand(commandName)
|
|
204
|
-
if (!commandMeta) {
|
|
205
|
-
process.stderr.write(`"${commandName}" not a valid command\n$ `)
|
|
206
|
-
return
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const {userInputByArg, userInputByFlag} = await promptForInputs(commandName, commandMeta, args, flags)
|
|
210
|
-
|
|
211
|
-
try {
|
|
212
|
-
for (const [, {input: argValue}] of userInputByArg) {
|
|
213
|
-
if (argValue) {
|
|
214
|
-
args.push(argValue)
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
for (const [flagName, {input: flagValue}] of userInputByFlag) {
|
|
219
|
-
if (!flagValue) {
|
|
220
|
-
continue
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (flagValue === true) {
|
|
224
|
-
args.push(`--${flagName}`)
|
|
225
|
-
continue
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
args.push(`--${flagName}`, flagValue)
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return args
|
|
232
|
-
} catch (error) {
|
|
233
|
-
process.stderr.write(error.message)
|
|
234
|
-
}
|
|
235
|
-
}
|