heroku 11.5.0 → 11.6.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/CHANGELOG.md +67 -0
- package/dist/commands/accounts/add.js +9 -11
- package/dist/commands/accounts/current.js +3 -2
- package/dist/commands/accounts/index.js +5 -4
- package/dist/commands/accounts/remove.js +8 -4
- package/dist/commands/accounts/set.js +7 -5
- package/dist/commands/apps/create.js +1 -0
- package/dist/commands/auth/login.js +9 -0
- package/dist/commands/auth/logout.js +15 -1
- package/dist/commands/auth/whoami.js +1 -1
- package/dist/commands/ci/config/unset.js +1 -1
- package/dist/commands/git/clone.js +1 -0
- package/dist/commands/git/credentials.d.ts +6 -0
- package/dist/commands/git/credentials.js +38 -3
- package/dist/commands/git/remote.js +1 -0
- package/dist/lib/accounts/accounts.d.ts +22 -8
- package/dist/lib/accounts/accounts.js +88 -26
- package/dist/lib/analytics-telemetry/backboard-herokulytics-client.d.ts +1 -5
- package/dist/lib/analytics-telemetry/backboard-herokulytics-client.js +5 -22
- package/dist/lib/git/git.d.ts +15 -2
- package/dist/lib/git/git.js +41 -5
- package/npm-shrinkwrap.json +312 -2102
- package/oclif.manifest.json +151 -151
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { APIClient } from '@heroku-cli/command';
|
|
2
2
|
import { HTTP } from '@heroku/http-call';
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
4
|
import path from 'node:path';
|
|
@@ -8,8 +8,8 @@ export default class BackboardHerokulyticsClient {
|
|
|
8
8
|
config;
|
|
9
9
|
http;
|
|
10
10
|
userConfig;
|
|
11
|
+
heroku;
|
|
11
12
|
isInitialized = false;
|
|
12
|
-
netrc;
|
|
13
13
|
constructor(config) {
|
|
14
14
|
this.config = config;
|
|
15
15
|
this.http = HTTP.create({
|
|
@@ -17,26 +17,11 @@ export default class BackboardHerokulyticsClient {
|
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
19
|
get authorizationToken() {
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
get netrcLogin() {
|
|
23
|
-
return this.netrc?.machines[vars.apiHost]?.login;
|
|
24
|
-
}
|
|
25
|
-
get netrcToken() {
|
|
26
|
-
return this.netrc?.machines[vars.apiHost]?.password;
|
|
20
|
+
return this.heroku.auth;
|
|
27
21
|
}
|
|
28
22
|
get url() {
|
|
29
23
|
return process.env.HEROKU_ANALYTICS_URL || 'https://backboard.heroku.com/hamurai';
|
|
30
24
|
}
|
|
31
|
-
get user() {
|
|
32
|
-
if (this.usingHerokuAPIKey)
|
|
33
|
-
return undefined;
|
|
34
|
-
return this.netrcLogin;
|
|
35
|
-
}
|
|
36
|
-
get usingHerokuAPIKey() {
|
|
37
|
-
const k = process.env.HEROKU_API_KEY;
|
|
38
|
-
return Boolean(k && k.length > 0);
|
|
39
|
-
}
|
|
40
25
|
async _acAnalytics(id) {
|
|
41
26
|
if (id === 'autocomplete:options')
|
|
42
27
|
return 0;
|
|
@@ -110,10 +95,8 @@ export default class BackboardHerokulyticsClient {
|
|
|
110
95
|
}
|
|
111
96
|
telemetryDebug('Initializing Herokulytics client...');
|
|
112
97
|
this.isInitialized = true;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
this.netrc = new NetrcClass();
|
|
116
|
-
await this.netrc.load();
|
|
98
|
+
this.heroku = new APIClient(this.config);
|
|
99
|
+
await this.heroku.getAuth();
|
|
117
100
|
this.userConfig = new HerokulyticsConfig(this.config);
|
|
118
101
|
await this.userConfig.init();
|
|
119
102
|
telemetryDebug('Herokulytics client initialized (install_id: %s)', this.userConfig.install);
|
package/dist/lib/git/git.d.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
|
+
import cp from 'node:child_process';
|
|
1
2
|
export default class Git {
|
|
3
|
+
private readonly execFile;
|
|
4
|
+
/** Configures `heroku git:credentials` as a Git credential helper
|
|
5
|
+
* that is URL-scoped to Heroku Git operations only.
|
|
6
|
+
*/
|
|
7
|
+
configureCredentialHelper(): Promise<void>;
|
|
2
8
|
createRemote(remote: string, url: string): Promise<string | null>;
|
|
9
|
+
/** Erases stored credentials for the Heroku Git host */
|
|
10
|
+
eraseCredentials(): Promise<void>;
|
|
3
11
|
exec(args: string[]): Promise<string>;
|
|
4
12
|
getBranch(symbolicRef: string): Promise<string>;
|
|
5
13
|
getCommitTitle(ref: string): Promise<string>;
|
|
6
14
|
getRef(branch: string): Promise<string>;
|
|
7
15
|
hasGitRemote(remote: string): Promise<boolean>;
|
|
8
16
|
httpGitUrl(app: string): string;
|
|
9
|
-
inGitRepo():
|
|
17
|
+
inGitRepo(): boolean;
|
|
10
18
|
readCommit(commit: string): Promise<{
|
|
11
19
|
branch: string;
|
|
12
20
|
message: string;
|
|
@@ -14,6 +22,11 @@ export default class Git {
|
|
|
14
22
|
}>;
|
|
15
23
|
remoteFromGitConfig(): Promise<string | void>;
|
|
16
24
|
remoteUrl(name: string): Promise<string>;
|
|
17
|
-
|
|
25
|
+
/** Removes `heroku git:credentials` from the global config */
|
|
26
|
+
removeCredentialHelper(): Promise<void>;
|
|
27
|
+
spawn(args: string[], options?: {
|
|
28
|
+
input?: string;
|
|
29
|
+
stdio?: cp.StdioOptions;
|
|
30
|
+
}): Promise<unknown>;
|
|
18
31
|
url(app: string): string;
|
|
19
32
|
}
|
package/dist/lib/git/git.js
CHANGED
|
@@ -3,18 +3,39 @@ import { ux } from '@oclif/core/ux';
|
|
|
3
3
|
import cp from 'node:child_process';
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
|
-
const
|
|
6
|
+
const execFilePromise = promisify(cp.execFile);
|
|
7
7
|
import debug from 'debug';
|
|
8
8
|
const gitDebug = debug('git');
|
|
9
9
|
export default class Git {
|
|
10
|
+
execFile = execFilePromise;
|
|
11
|
+
/** Configures `heroku git:credentials` as a Git credential helper
|
|
12
|
+
* that is URL-scoped to Heroku Git operations only.
|
|
13
|
+
*/
|
|
14
|
+
async configureCredentialHelper() {
|
|
15
|
+
const { httpGitHost } = vars;
|
|
16
|
+
await this.exec([
|
|
17
|
+
'config',
|
|
18
|
+
'--global',
|
|
19
|
+
`credential.https://${httpGitHost}.helper`,
|
|
20
|
+
'!heroku git:credentials',
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
10
23
|
createRemote(remote, url) {
|
|
11
24
|
return this.hasGitRemote(remote)
|
|
12
25
|
.then(exists => exists ? null : this.exec(['remote', 'add', remote, url]));
|
|
13
26
|
}
|
|
27
|
+
/** Erases stored credentials for the Heroku Git host */
|
|
28
|
+
async eraseCredentials() {
|
|
29
|
+
const { httpGitHost } = vars;
|
|
30
|
+
await this.spawn(['credential', 'reject'], {
|
|
31
|
+
input: `protocol=https\nhost=${httpGitHost}\n\n`,
|
|
32
|
+
stdio: ['pipe', 'ignore', 'ignore'],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
14
35
|
async exec(args) {
|
|
15
36
|
gitDebug('exec: git %o', args);
|
|
16
37
|
try {
|
|
17
|
-
const { stderr, stdout } = await execFile('git', args);
|
|
38
|
+
const { stderr, stdout } = await this.execFile('git', args);
|
|
18
39
|
if (stderr)
|
|
19
40
|
process.stderr.write(stderr);
|
|
20
41
|
return stdout.trim();
|
|
@@ -51,6 +72,7 @@ export default class Git {
|
|
|
51
72
|
catch (error) {
|
|
52
73
|
if (error.code !== 'ENOENT')
|
|
53
74
|
throw error;
|
|
75
|
+
return false;
|
|
54
76
|
}
|
|
55
77
|
}
|
|
56
78
|
async readCommit(commit) {
|
|
@@ -73,13 +95,27 @@ export default class Git {
|
|
|
73
95
|
.find(r => r[0] === name)?.[1]
|
|
74
96
|
?.split(' ')[0] ?? '';
|
|
75
97
|
}
|
|
76
|
-
|
|
98
|
+
/** Removes `heroku git:credentials` from the global config */
|
|
99
|
+
async removeCredentialHelper() {
|
|
100
|
+
const { httpGitHost } = vars;
|
|
101
|
+
await this.exec(['config', '--global', '--unset-all', `credential.https://${httpGitHost}.helper`]);
|
|
102
|
+
}
|
|
103
|
+
spawn(args, options = {}) {
|
|
77
104
|
return new Promise((resolve, reject) => {
|
|
78
105
|
gitDebug('spawn: git %o', args);
|
|
79
|
-
const s = cp.spawn('git', args, { stdio: [0, 1, 2] });
|
|
106
|
+
const s = cp.spawn('git', args, { stdio: options.stdio ?? [0, 1, 2] });
|
|
107
|
+
if (options.input && s.stdin) {
|
|
108
|
+
s.stdin.write(options.input);
|
|
109
|
+
s.stdin.end();
|
|
110
|
+
}
|
|
80
111
|
s.on('error', (err) => {
|
|
81
112
|
if (err.code === 'ENOENT') {
|
|
82
|
-
|
|
113
|
+
try {
|
|
114
|
+
ux.error('Git must be installed to use the Heroku CLI. See instructions here: https://git-scm.com');
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
reject(error);
|
|
118
|
+
}
|
|
83
119
|
}
|
|
84
120
|
else
|
|
85
121
|
reject(err);
|