heroku 11.0.0-alpha.1 → 11.0.0-alpha.10

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 (76) hide show
  1. package/README.md +3 -0
  2. package/lib/commands/local/index.d.ts +19 -0
  3. package/lib/commands/local/index.js +77 -0
  4. package/lib/commands/local/run.d.ts +11 -0
  5. package/lib/commands/local/run.js +37 -0
  6. package/lib/commands/local/version.d.ts +5 -0
  7. package/lib/commands/local/version.js +10 -0
  8. package/lib/commands/members/add.d.ts +13 -0
  9. package/lib/commands/members/add.js +32 -0
  10. package/lib/commands/members/index.d.ts +12 -0
  11. package/lib/commands/members/index.js +80 -0
  12. package/lib/commands/members/remove.d.ts +10 -0
  13. package/lib/commands/members/remove.js +43 -0
  14. package/lib/commands/members/set.d.ts +11 -0
  15. package/lib/commands/members/set.js +24 -0
  16. package/lib/commands/pipelines/add.d.ts +14 -0
  17. package/lib/commands/pipelines/add.js +58 -0
  18. package/lib/commands/pipelines/connect.d.ts +12 -0
  19. package/lib/commands/pipelines/connect.js +49 -0
  20. package/lib/commands/pipelines/create.d.ts +15 -0
  21. package/lib/commands/pipelines/create.js +89 -0
  22. package/lib/commands/pipelines/destroy.d.ts +9 -0
  23. package/lib/commands/pipelines/destroy.js +24 -0
  24. package/lib/commands/pipelines/diff.d.ts +20 -0
  25. package/lib/commands/pipelines/diff.js +156 -0
  26. package/lib/commands/pipelines/index.d.ts +9 -0
  27. package/lib/commands/pipelines/index.js +25 -0
  28. package/lib/commands/pipelines/info.d.ts +13 -0
  29. package/lib/commands/pipelines/info.js +41 -0
  30. package/lib/lib/local/env-file-validator.d.ts +1 -0
  31. package/lib/lib/local/env-file-validator.js +10 -0
  32. package/lib/lib/local/fork-foreman.js +7 -0
  33. package/lib/lib/local/load-foreman-procfile.d.ts +1 -2
  34. package/lib/lib/local/load-foreman-procfile.js +5 -1
  35. package/lib/lib/local/{run-foreman.js → run-foreman.cjs} +2 -1
  36. package/lib/lib/members/team-invite-utils.d.ts +14 -0
  37. package/lib/lib/members/team-invite-utils.js +26 -0
  38. package/lib/lib/pipelines/disambiguate.js +2 -2
  39. package/lib/lib/pipelines/ownership.d.ts +5 -1
  40. package/lib/lib/pipelines/ownership.js +33 -44
  41. package/lib/lib/pipelines/render-pipeline.d.ts +7 -1
  42. package/lib/lib/pipelines/render-pipeline.js +62 -68
  43. package/npm-shrinkwrap.json +31675 -0
  44. package/oclif.manifest.json +7573 -0
  45. package/package.json +10 -8
  46. package/lib/lib/members/utils.d.ts +0 -2
  47. package/lib/lib/members/utils.js +0 -10
  48. package/lib/oldCommands/local/index.d.ts +0 -1
  49. package/lib/oldCommands/local/index.js +0 -91
  50. package/lib/oldCommands/local/run.d.ts +0 -1
  51. package/lib/oldCommands/local/run.js +0 -54
  52. package/lib/oldCommands/local/version.d.ts +0 -1
  53. package/lib/oldCommands/local/version.js +0 -17
  54. package/lib/oldCommands/members/add.d.ts +0 -1
  55. package/lib/oldCommands/members/add.js +0 -36
  56. package/lib/oldCommands/members/index.d.ts +0 -1
  57. package/lib/oldCommands/members/index.js +0 -92
  58. package/lib/oldCommands/members/remove.d.ts +0 -1
  59. package/lib/oldCommands/members/remove.js +0 -70
  60. package/lib/oldCommands/members/set.d.ts +0 -1
  61. package/lib/oldCommands/members/set.js +0 -24
  62. package/lib/oldCommands/pipelines/add.d.ts +0 -1
  63. package/lib/oldCommands/pipelines/add.js +0 -70
  64. package/lib/oldCommands/pipelines/connect.d.ts +0 -1
  65. package/lib/oldCommands/pipelines/connect.js +0 -69
  66. package/lib/oldCommands/pipelines/create.d.ts +0 -1
  67. package/lib/oldCommands/pipelines/create.js +0 -105
  68. package/lib/oldCommands/pipelines/destroy.d.ts +0 -1
  69. package/lib/oldCommands/pipelines/destroy.js +0 -34
  70. package/lib/oldCommands/pipelines/diff.d.ts +0 -1
  71. package/lib/oldCommands/pipelines/diff.js +0 -202
  72. package/lib/oldCommands/pipelines/index.d.ts +0 -1
  73. package/lib/oldCommands/pipelines/index.js +0 -34
  74. package/lib/oldCommands/pipelines/info.d.ts +0 -1
  75. package/lib/oldCommands/pipelines/info.js +0 -51
  76. /package/lib/lib/local/{run-foreman.d.ts → run-foreman.d.cts} +0 -0
@@ -0,0 +1,9 @@
1
+ import { Command } from '@heroku-cli/command';
2
+ export default class PipelinesDestroy extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ pipeline: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,24 @@
1
+ import { color } from '@heroku-cli/color';
2
+ import { Command } from '@heroku-cli/command';
3
+ import { Args, ux } from '@oclif/core';
4
+ import { destroyPipeline } from '../../lib/api.js';
5
+ import disambiguate from '../../lib/pipelines/disambiguate.js';
6
+ export default class PipelinesDestroy extends Command {
7
+ static description = 'destroy a pipeline';
8
+ static examples = [
9
+ '$ heroku pipelines:destroy my-pipeline',
10
+ ];
11
+ static args = {
12
+ pipeline: Args.string({
13
+ description: 'name of pipeline',
14
+ required: true,
15
+ }),
16
+ };
17
+ async run() {
18
+ const { args } = await this.parse(PipelinesDestroy);
19
+ const pipeline = await disambiguate(this.heroku, args.pipeline);
20
+ ux.action.start(`Destroying ${color.pipeline(pipeline.name)} pipeline`);
21
+ await destroyPipeline(this.heroku, pipeline.name, pipeline.id);
22
+ ux.action.stop();
23
+ }
24
+ }
@@ -0,0 +1,20 @@
1
+ import { Command } from '@heroku-cli/command';
2
+ import KolkrabbiAPI from '../../lib/pipelines/kolkrabbi-api.js';
3
+ import { GenerationKind } from '../../lib/apps/generation.js';
4
+ interface AppInfo {
5
+ name: string;
6
+ repo?: string;
7
+ hash?: string;
8
+ }
9
+ export default class PipelinesDiff extends Command {
10
+ static description: string;
11
+ static examples: string[];
12
+ static flags: {
13
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
+ remote: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ };
16
+ kolkrabbi: KolkrabbiAPI;
17
+ getAppInfo: (appName: string, appId: string, generation: GenerationKind) => Promise<AppInfo>;
18
+ run(): Promise<undefined>;
19
+ }
20
+ export {};
@@ -0,0 +1,156 @@
1
+ import { color } from '@heroku-cli/color';
2
+ import { Command, flags } from '@heroku-cli/command';
3
+ import { ux } from '@oclif/core';
4
+ import { hux } from '@heroku/heroku-cli-util';
5
+ import { HTTP } from '@heroku/http-call';
6
+ import { getCoupling, getPipeline, getReleases, listPipelineApps, SDK_HEADER } from '../../lib/api.js';
7
+ import KolkrabbiAPI from '../../lib/pipelines/kolkrabbi-api.js';
8
+ import { getGeneration } from '../../lib/apps/generation.js';
9
+ const PROMOTION_ORDER = ['development', 'staging', 'production'];
10
+ async function diff(targetApp, downstreamApp, githubToken, herokuUserAgent) {
11
+ if (!downstreamApp.repo) {
12
+ return ux.stdout(`\n${color.app(targetApp.name)} was not compared to ${color.app(downstreamApp.name)} as ${color.app(downstreamApp.name)} is not connected to GitHub`);
13
+ }
14
+ if (downstreamApp.repo !== targetApp.repo) {
15
+ return ux.stdout(`\n${color.app(targetApp.name)} was not compared to ${color.app(downstreamApp.name)} as ${color.app(downstreamApp.name)} is not connected to the same GitHub repo as ${color.app(targetApp.name)}`);
16
+ }
17
+ if (!downstreamApp.hash) {
18
+ return ux.stdout(`\n${color.app(targetApp.name)} was not compared to ${color.app(downstreamApp.name)} as ${color.app(downstreamApp.name)} does not have any releases`);
19
+ }
20
+ if (downstreamApp.hash === targetApp.hash) {
21
+ return ux.stdout(`\n${color.app(targetApp.name)} is up to date with ${color.app(downstreamApp.name)}`);
22
+ }
23
+ // Do the actual GitHub diff
24
+ try {
25
+ const path = `${targetApp.repo}/compare/${downstreamApp.hash}...${targetApp.hash}`;
26
+ const headers = {
27
+ authorization: 'token ' + githubToken,
28
+ 'Content-Type': 'application/vnd.github+json',
29
+ 'X-GitHub-Api-Version': '2022-11-28',
30
+ };
31
+ if (herokuUserAgent) {
32
+ Reflect.set(headers, 'user-agent', herokuUserAgent);
33
+ }
34
+ const { body: githubDiff } = await HTTP.get(`https://api.github.com/repos/${path}`, { headers });
35
+ ux.stdout('');
36
+ hux.styledHeader(`${color.app(targetApp.name)} is ahead of ${color.app(downstreamApp.name)} by ${githubDiff.ahead_by} commit${githubDiff.ahead_by === 1 ? '' : 's'}`);
37
+ const mapped = githubDiff.commits.map((commit) => ({
38
+ sha: commit.sha.slice(0, 7),
39
+ date: commit.commit.author.date,
40
+ author: commit.commit.author.name,
41
+ message: commit.commit.message.split('\n')[0],
42
+ })).reverse();
43
+ hux.table(mapped, {
44
+ sha: {
45
+ header: 'SHA',
46
+ },
47
+ date: {},
48
+ author: {},
49
+ message: {},
50
+ });
51
+ ux.stdout(`\nhttps://github.com/${path}`);
52
+ }
53
+ catch {
54
+ ux.stdout(`\n${color.app(targetApp.name)} was not compared to ${color.app(downstreamApp.name)} because we were unable to perform a diff`);
55
+ ux.stdout('are you sure you have pushed your latest commits to GitHub?');
56
+ }
57
+ }
58
+ export default class PipelinesDiff extends Command {
59
+ static description = 'compares the latest release of this app to its downstream app(s)';
60
+ static examples = [
61
+ '$ heroku pipelines:diff -a my-app-staging',
62
+ ];
63
+ static flags = {
64
+ app: flags.app({ required: true }),
65
+ remote: flags.remote(),
66
+ };
67
+ kolkrabbi = new KolkrabbiAPI(this.config.userAgent, () => this.heroku.auth);
68
+ getAppInfo = async (appName, appId, generation) => {
69
+ // Find GitHub connection for the app
70
+ const githubApp = await this.kolkrabbi.getAppLink(appId)
71
+ .catch(() => ({ name: appName, repo: null, hash: null }));
72
+ // Find the commit hash of the latest release for this app
73
+ let slug;
74
+ let ociImages;
75
+ let commit;
76
+ try {
77
+ const { body: releases } = await getReleases(this.heroku, appId);
78
+ const release = releases.find(r => r.status === 'succeeded');
79
+ if (!release || !(release.slug || release.oci_image)) {
80
+ throw new Error(`no release found for ${appName}`);
81
+ }
82
+ if (generation === 'cedar' && release.slug) {
83
+ slug = await this.heroku.get(`/apps/${appId}/slugs/${release.slug.id}`, {
84
+ headers: { Accept: SDK_HEADER },
85
+ }).then(res => res.body);
86
+ commit = slug.commit;
87
+ }
88
+ else if (generation === 'fir' && release.oci_image) {
89
+ ociImages = await this.heroku.get(`/apps/${appId}/oci-images/${release.oci_image.id}`, {
90
+ headers: { Accept: SDK_HEADER },
91
+ }).then(res => res.body);
92
+ commit = ociImages[0]?.commit;
93
+ }
94
+ }
95
+ catch {
96
+ return { name: appName, repo: githubApp.repo, hash: undefined };
97
+ }
98
+ return { name: appName, repo: githubApp.repo, hash: commit };
99
+ };
100
+ async run() {
101
+ const { flags } = await this.parse(PipelinesDiff);
102
+ const targetAppName = flags.app;
103
+ let coupling;
104
+ try {
105
+ ({ body: coupling } = await getCoupling(this.heroku, targetAppName));
106
+ }
107
+ catch {
108
+ ux.error(`This app (${targetAppName}) does not seem to be a part of any pipeline`);
109
+ return;
110
+ }
111
+ const { body: pipeline } = await getPipeline(this.heroku, coupling.pipeline.id);
112
+ const targetAppId = coupling.app.id;
113
+ const generation = getGeneration(pipeline);
114
+ ux.action.start('Fetching apps from pipeline');
115
+ const allApps = await listPipelineApps(this.heroku, coupling.pipeline.id);
116
+ ux.action.stop();
117
+ const sourceStage = coupling.stage;
118
+ if (!sourceStage) {
119
+ return ux.error(`Unable to diff ${targetAppName}`);
120
+ }
121
+ const downstreamStage = PROMOTION_ORDER[PROMOTION_ORDER.indexOf(sourceStage) + 1];
122
+ if (!downstreamStage || !PROMOTION_ORDER.includes(sourceStage)) {
123
+ return ux.error(`Unable to diff ${targetAppName}`);
124
+ }
125
+ const downstreamApps = allApps.filter(app => app.pipelineCoupling.stage === downstreamStage);
126
+ if (downstreamApps.length === 0) {
127
+ return ux.error(`Cannot diff ${targetAppName} as there are no downstream apps configured`);
128
+ }
129
+ // Fetch GitHub repo/latest release hash for [target, downstream[0], .., downstream[n]] apps
130
+ const appInfoPromises = [this.getAppInfo(targetAppName, targetAppId, generation)];
131
+ downstreamApps.forEach(app => {
132
+ if (app.name && app.id) {
133
+ appInfoPromises.push(this.getAppInfo(app.name, app.id, generation));
134
+ }
135
+ });
136
+ ux.action.start('Fetching release info for all apps');
137
+ const appInfo = await Promise.all(appInfoPromises);
138
+ ux.action.stop();
139
+ // Verify the target app
140
+ const targetAppInfo = appInfo[0];
141
+ if (!targetAppInfo.repo) {
142
+ const command = `heroku pipelines:open ${coupling.pipeline.name}`;
143
+ return ux.error(`${targetAppName} does not seem to be connected to GitHub!\nRun ${color.cyan(command)} and "Connect to GitHub".`);
144
+ }
145
+ if (!targetAppInfo.hash) {
146
+ return ux.error(`No release was found for ${targetAppName}, unable to diff`);
147
+ }
148
+ // Fetch GitHub token for the user
149
+ const githubAccount = await this.kolkrabbi.getAccount();
150
+ // Diff [{target, downstream[0]}, {target, downstream[1]}, .., {target, downstream[n]}]
151
+ const downstreamAppsInfo = appInfo.slice(1);
152
+ for (const downstreamAppInfo of downstreamAppsInfo) {
153
+ await diff(targetAppInfo, downstreamAppInfo, githubAccount.github.token, this.config.userAgent);
154
+ }
155
+ }
156
+ }
@@ -0,0 +1,9 @@
1
+ import { Command } from '@heroku-cli/command';
2
+ export default class Pipelines extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,25 @@
1
+ import { Command, flags } from '@heroku-cli/command';
2
+ import { ux } from '@oclif/core';
3
+ import { hux } from '@heroku/heroku-cli-util';
4
+ export default class Pipelines extends Command {
5
+ static description = 'list pipelines you have access to';
6
+ static examples = [
7
+ '$ heroku pipelines',
8
+ ];
9
+ static flags = {
10
+ json: flags.boolean({ description: 'output in json format' }),
11
+ };
12
+ async run() {
13
+ const { flags } = await this.parse(Pipelines);
14
+ const { body: pipelines } = await this.heroku.get('/pipelines');
15
+ if (flags.json) {
16
+ hux.styledJSON(pipelines);
17
+ }
18
+ else {
19
+ hux.styledHeader('My Pipelines');
20
+ for (const pipeline of pipelines) {
21
+ ux.stdout(pipeline.name);
22
+ }
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from '@heroku-cli/command';
2
+ export default class PipelinesInfo extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ 'with-owners': import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ static args: {
10
+ pipeline: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,41 @@
1
+ import { Command, flags } from '@heroku-cli/command';
2
+ import { Args } from '@oclif/core';
3
+ import { hux } from '@heroku/heroku-cli-util';
4
+ import { listPipelineApps } from '../../lib/api.js';
5
+ import disambiguate from '../../lib/pipelines/disambiguate.js';
6
+ import renderPipeline from '../../lib/pipelines/render-pipeline.js';
7
+ export default class PipelinesInfo extends Command {
8
+ static description = 'show list of apps in a pipeline';
9
+ static examples = [
10
+ '$ heroku pipelines:info my-pipeline',
11
+ ];
12
+ static flags = {
13
+ json: flags.boolean({
14
+ description: 'output in json format',
15
+ }),
16
+ 'with-owners': flags.boolean({
17
+ description: 'shows owner of every app',
18
+ hidden: true,
19
+ }),
20
+ };
21
+ static args = {
22
+ pipeline: Args.string({
23
+ description: 'pipeline to show list of apps for',
24
+ required: true,
25
+ }),
26
+ };
27
+ async run() {
28
+ const { args, flags } = await this.parse(PipelinesInfo);
29
+ const pipeline = await disambiguate(this.heroku, args.pipeline);
30
+ const pipelineApps = await listPipelineApps(this.heroku, pipeline.id);
31
+ if (flags.json) {
32
+ hux.styledJSON({ pipeline, apps: pipelineApps });
33
+ }
34
+ else {
35
+ await renderPipeline(this.heroku, pipeline, pipelineApps, {
36
+ withOwners: flags['with-owners'],
37
+ showOwnerWarning: true,
38
+ });
39
+ }
40
+ }
41
+ }
@@ -0,0 +1 @@
1
+ export declare function validateEnvFile(envFile: string | undefined, warn: (message: string) => void): string;
@@ -0,0 +1,10 @@
1
+ import * as fs from 'fs';
2
+ import { color } from '@heroku-cli/color';
3
+ export function validateEnvFile(envFile, warn) {
4
+ const resolvedEnvFile = envFile || '.env';
5
+ if (fs.existsSync(resolvedEnvFile) && !fs.statSync(resolvedEnvFile).isFile()) {
6
+ warn(`The specified location for the env file, ${color.bold(resolvedEnvFile)}, is not a file, ignoring.`);
7
+ return '';
8
+ }
9
+ return resolvedEnvFile;
10
+ }
@@ -1,13 +1,20 @@
1
1
  import { fork as forkChildProcess } from 'child_process';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
+ import { fileURLToPath } from 'url';
4
5
  // depending if this is being ran before or after compilation
5
6
  // we need to check for `.ts` and `.js` extensions and use
6
7
  // the appropriate one.
7
8
  function getForemanScriptPath() {
8
9
  const file = 'run-foreman';
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+ const withCjsExtension = path.join(__dirname, file + '.cjs');
9
13
  const withJsExtension = path.join(__dirname, file + '.js');
10
14
  const withTsExtension = path.join(__dirname, file + '.ts');
15
+ if (fs.existsSync(withCjsExtension)) {
16
+ return withCjsExtension;
17
+ }
11
18
  if (fs.existsSync(withJsExtension)) {
12
19
  return withJsExtension;
13
20
  }
@@ -1,2 +1 @@
1
- import parseProcfile from 'parse-procfile';
2
- export default parseProcfile;
1
+ export declare const loadProc: (procfilePath: string) => any;
@@ -1,3 +1,7 @@
1
1
  // @ts-expect-error - parse-procfile lacks TypeScript definitions
2
2
  import parseProcfile from 'parse-procfile';
3
- export default parseProcfile;
3
+ import fs from 'fs';
4
+ export const loadProc = (procfilePath) => {
5
+ const content = fs.readFileSync(procfilePath, 'utf8');
6
+ return parseProcfile(content);
7
+ };
@@ -1,7 +1,9 @@
1
+ "use strict";
1
2
  // Copyright IBM Corp. 2012,2015. All Rights Reserved.
2
3
  // Node module: foreman
3
4
  // This file is licensed under the MIT License.
4
5
  // License text available at https://opensource.org/licenses/MIT
6
+ Object.defineProperty(exports, "__esModule", { value: true });
5
7
  // This file is copied from the Node Foreman package. It was copied in order to fix
6
8
  // a bug related to the use of port 5000 as a default. It is not meant to be a
7
9
  // long-term solution, we plan to eventually remove our dependency on Node Foreman.
@@ -232,4 +234,3 @@ if (process.argv.slice(2).length === 0) {
232
234
  program.outputHelp();
233
235
  process.exit(1);
234
236
  }
235
- export {};
@@ -0,0 +1,14 @@
1
+ import { APIClient } from '@heroku-cli/command';
2
+ import * as Heroku from '@heroku-cli/schema';
3
+ /**
4
+ * Standard role description for consistent usage across commands
5
+ */
6
+ export declare const ROLE_DESCRIPTION = "member role (admin, collaborator, member, owner)";
7
+ /**
8
+ * Check if team invite acceptance feature is enabled for a team
9
+ */
10
+ export declare function isTeamInviteFeatureEnabled(team: string, heroku: APIClient): Promise<boolean>;
11
+ /**
12
+ * Get team invitations with proper headers
13
+ */
14
+ export declare function getTeamInvites(team: string, heroku: APIClient): Promise<Heroku.TeamInvitation[]>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Standard role description for consistent usage across commands
3
+ */
4
+ export const ROLE_DESCRIPTION = 'member role (admin, collaborator, member, owner)';
5
+ /**
6
+ * Check if team invite acceptance feature is enabled for a team
7
+ */
8
+ export async function isTeamInviteFeatureEnabled(team, heroku) {
9
+ const { body: teamInfo } = await heroku.get(`/teams/${team}`);
10
+ if (teamInfo.type !== 'team') {
11
+ return false;
12
+ }
13
+ const { body: teamFeatures } = await heroku.get(`/teams/${team}/features`);
14
+ return teamFeatures.some(feature => feature.name === 'team-invite-acceptance' && feature.enabled);
15
+ }
16
+ /**
17
+ * Get team invitations with proper headers
18
+ */
19
+ export async function getTeamInvites(team, heroku) {
20
+ const { body: teamInvites } = await heroku.get(`/teams/${team}/invitations`, {
21
+ headers: {
22
+ Accept: 'application/vnd.heroku+json; version=3.team-invitations',
23
+ },
24
+ });
25
+ return teamInvites;
26
+ }
@@ -1,4 +1,4 @@
1
- import { prompt } from 'inquirer';
1
+ import inquirer from 'inquirer';
2
2
  import { uuidValidate } from '../utils/uuid-validate.js';
3
3
  import { findPipelineByName, getPipeline, } from '../api.js';
4
4
  export default async function disambiguate(heroku, pipelineIDOrName) {
@@ -31,7 +31,7 @@ export default async function disambiguate(heroku, pipelineIDOrName) {
31
31
  }];
32
32
  // eslint-disable-next-line no-async-promise-executor
33
33
  pipeline = await new Promise(async function (resolve, reject) {
34
- const answers = await prompt(questions);
34
+ const answers = await inquirer.prompt(questions);
35
35
  if (answers.pipeline) {
36
36
  resolve(answers.pipeline);
37
37
  }
@@ -1 +1,5 @@
1
- export {};
1
+ import { APIClient } from '@heroku-cli/command';
2
+ import * as Heroku from '@heroku-cli/schema';
3
+ import { AppWithPipelineCoupling } from '../api.js';
4
+ export declare function warnMixedOwnership(pipelineApps: Array<AppWithPipelineCoupling>, pipeline: Heroku.Pipeline, owner: string): void;
5
+ export declare function getOwner(heroku: APIClient, apps: Array<AppWithPipelineCoupling>, pipeline: Heroku.Pipeline): Promise<any>;
@@ -1,46 +1,35 @@
1
- export {};
2
- /*
3
- import color from '@heroku-cli/color'
4
- import {APIClient} from '@heroku-cli/command'
5
- import * as Heroku from '@heroku-cli/schema'
6
- import {ux} from '@oclif/core'
7
-
8
- import {AppWithPipelineCoupling, getTeam} from '../api'
9
-
10
- export function warnMixedOwnership(pipelineApps: Array<AppWithPipelineCoupling>, pipeline: Heroku.Pipeline, owner: string) {
11
- const hasMixedOwnership = pipelineApps.some(app => {
12
- return (app.owner && app.owner.id) !== pipeline.owner.id
13
- })
14
-
15
- if (hasMixedOwnership) {
16
- ux.log()
17
- let message = `Some apps in this pipeline do not belong to ${color.cmd(owner)}.`
18
- message += '\n\nAll apps in a pipeline must have the same owner as the pipeline owner.'
19
- message += '\nTransfer these apps or change the pipeline owner in pipeline settings.'
20
- message += `\nSee ${color.cyan('https://devcenter.heroku.com/articles/pipeline-ownership-transition')} for more info.`
21
- ux.warn(message)
22
- }
1
+ import { color } from '@heroku-cli/color';
2
+ import { ux } from '@oclif/core';
3
+ import { getTeam } from '../api.js';
4
+ export function warnMixedOwnership(pipelineApps, pipeline, owner) {
5
+ const hasMixedOwnership = pipelineApps.some(app => {
6
+ return (app.owner && app.owner.id) !== pipeline.owner.id;
7
+ });
8
+ if (hasMixedOwnership) {
9
+ ux.stdout();
10
+ let message = `Some apps in this pipeline do not belong to ${color.cmd(owner)}.`;
11
+ message += '\n\nAll apps in a pipeline must have the same owner as the pipeline owner.';
12
+ message += '\nTransfer these apps or change the pipeline owner in pipeline settings.';
13
+ message += `\nSee ${color.cyan('https://devcenter.heroku.com/articles/pipeline-ownership-transition')} for more info.`;
14
+ ux.warn(message);
15
+ }
23
16
  }
24
-
25
- export function getOwner(heroku: APIClient, apps: Array<AppWithPipelineCoupling>, pipeline: Heroku.Pipeline) {
26
- let owner
27
- let ownerPromise
28
-
29
- if (pipeline.owner.type === 'team') {
30
- ownerPromise = getTeam(heroku, pipeline.owner.id).then(response => response.body)
31
- } else {
32
- const app = apps.find(app => {
33
- return app.owner ? app.owner.id === pipeline.owner.id : false
34
- })
35
-
36
- // If pipeline owner doesn't own any application and type is user (unlikely)
37
- // We return the uuid as default
38
- owner = app ? app.owner && app.owner.email : pipeline.owner.id
39
- ownerPromise = Promise.resolve(owner)
40
- }
41
-
42
- return ownerPromise.then(owner => {
43
- return owner.name ? `${owner.name} (team)` : owner
44
- })
17
+ export function getOwner(heroku, apps, pipeline) {
18
+ let owner;
19
+ let ownerPromise;
20
+ if (pipeline.owner.type === 'team') {
21
+ ownerPromise = getTeam(heroku, pipeline.owner.id).then(response => response.body);
22
+ }
23
+ else {
24
+ const app = apps.find(app => {
25
+ return app.owner ? app.owner.id === pipeline.owner.id : false;
26
+ });
27
+ // If pipeline owner doesn't own any application and type is user (unlikely)
28
+ // We return the uuid as default
29
+ owner = app ? app.owner && app.owner.email : pipeline.owner.id;
30
+ ownerPromise = Promise.resolve(owner);
31
+ }
32
+ return ownerPromise.then(owner => {
33
+ return owner.name ? `${owner.name} (team)` : owner;
34
+ });
45
35
  }
46
- */
@@ -1 +1,7 @@
1
- export {};
1
+ import { APIClient } from '@heroku-cli/command';
2
+ import * as Heroku from '@heroku-cli/schema';
3
+ import { AppWithPipelineCoupling } from '../api.js';
4
+ export default function renderPipeline(heroku: APIClient, pipeline: Heroku.Pipeline, pipelineApps: Array<AppWithPipelineCoupling>, { withOwners, showOwnerWarning }?: {
5
+ withOwners: boolean;
6
+ showOwnerWarning: boolean;
7
+ }): Promise<void>;