@heroku/heroku-cli-util 10.6.1 → 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/README.md +45 -22
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/types/pg/platform-api.d.ts +10 -10
- package/dist/types/pg/tunnel.d.ts +2 -2
- package/dist/utils/addons/index.d.ts +3 -0
- package/dist/utils/addons/index.js +3 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/pg/config-vars.d.ts +1 -1
- package/dist/utils/pg/databases.d.ts +2 -2
- package/dist/utils/pg/host.d.ts +1 -1
- package/dist/utils/pg/host.js +1 -1
- package/dist/utils/pg/index.d.ts +5 -0
- package/dist/utils/pg/index.js +5 -0
- package/dist/ux/any-key.js +2 -1
- package/dist/ux/confirm-command.js +17 -8
- package/dist/ux/index.d.ts +16 -0
- package/dist/ux/index.js +16 -0
- package/dist/ux/table.d.ts +2 -2
- package/dist/ux/table.js +10 -8
- package/package.json +50 -16
package/README.md
CHANGED
|
@@ -19,24 +19,38 @@ npm install @heroku/heroku-cli-util
|
|
|
19
19
|
|
|
20
20
|
## Usage
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Import only the utilities you need for better performance and smaller bundle sizes.
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import * as color from '@heroku/heroku-cli-util/color';
|
|
26
|
+
import { confirm, table } from '@heroku/heroku-cli-util/hux';
|
|
27
|
+
import { DatabaseResolver } from '@heroku/heroku-cli-util/utils/pg';
|
|
28
|
+
import { AddonResolver } from '@heroku/heroku-cli-util/utils/addons';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Available import paths:**
|
|
32
|
+
- `@heroku/heroku-cli-util/color` - Color utilities
|
|
33
|
+
- `@heroku/heroku-cli-util/hux` - UX utilities (prompts, tables, output formatting)
|
|
34
|
+
- `@heroku/heroku-cli-util/utils` - All utility functions
|
|
35
|
+
- `@heroku/heroku-cli-util/utils/pg` - PostgreSQL-specific utilities
|
|
36
|
+
- `@heroku/heroku-cli-util/utils/addons` - Addon-specific utilities
|
|
23
37
|
|
|
24
38
|
### Output Utilities
|
|
25
39
|
|
|
26
40
|
```js
|
|
27
|
-
import {
|
|
41
|
+
import { styledHeader, styledJSON, styledObject, table, wait } from '@heroku/heroku-cli-util/hux';
|
|
28
42
|
|
|
29
43
|
// Styled header
|
|
30
|
-
|
|
44
|
+
styledHeader('My CLI Header');
|
|
31
45
|
|
|
32
46
|
// Styled JSON
|
|
33
|
-
|
|
47
|
+
styledJSON({ foo: 'bar' });
|
|
34
48
|
|
|
35
49
|
// Styled object
|
|
36
|
-
|
|
50
|
+
styledObject({ foo: 'bar' });
|
|
37
51
|
|
|
38
52
|
// Table output
|
|
39
|
-
|
|
53
|
+
table([
|
|
40
54
|
{name: 'Alice', age: 30},
|
|
41
55
|
{name: 'Bob', age: 25},
|
|
42
56
|
], {
|
|
@@ -45,7 +59,7 @@ hux.table([
|
|
|
45
59
|
});
|
|
46
60
|
|
|
47
61
|
// Wait indicator
|
|
48
|
-
const stop =
|
|
62
|
+
const stop = wait('Processing...');
|
|
49
63
|
// ...do async work...
|
|
50
64
|
stop();
|
|
51
65
|
```
|
|
@@ -53,16 +67,16 @@ stop();
|
|
|
53
67
|
### User Interaction
|
|
54
68
|
|
|
55
69
|
```js
|
|
56
|
-
import {
|
|
70
|
+
import { prompt, confirm } from '@heroku/heroku-cli-util/hux';
|
|
57
71
|
|
|
58
|
-
const name = await
|
|
59
|
-
const proceed = await
|
|
72
|
+
const name = await prompt('What is your name?');
|
|
73
|
+
const proceed = await confirm('Continue?');
|
|
60
74
|
```
|
|
61
75
|
|
|
62
76
|
### Colors
|
|
63
77
|
|
|
64
78
|
```js
|
|
65
|
-
import
|
|
79
|
+
import * as color from '@heroku/heroku-cli-util/color';
|
|
66
80
|
|
|
67
81
|
// App-related colors
|
|
68
82
|
console.log(color.app('my-awesome-app')); // Purple, bold with app icon
|
|
@@ -93,21 +107,21 @@ See the [COLORS.md](docs/COLORS.md) documentation for the complete color palette
|
|
|
93
107
|
#### Error Classes
|
|
94
108
|
|
|
95
109
|
```js
|
|
96
|
-
import {
|
|
110
|
+
import { AmbiguousError, NotFound } from '@heroku/heroku-cli-util/utils';
|
|
97
111
|
|
|
98
112
|
// Error types
|
|
99
113
|
try {
|
|
100
|
-
throw new
|
|
114
|
+
throw new AmbiguousError([{ name: 'foo' }, { name: 'bar' }], 'addon');
|
|
101
115
|
} catch (err) {
|
|
102
|
-
if (err instanceof
|
|
116
|
+
if (err instanceof AmbiguousError) {
|
|
103
117
|
console.error('Ambiguous:', err.message);
|
|
104
118
|
}
|
|
105
119
|
}
|
|
106
120
|
|
|
107
121
|
try {
|
|
108
|
-
throw new
|
|
122
|
+
throw new NotFound();
|
|
109
123
|
} catch (err) {
|
|
110
|
-
if (err instanceof
|
|
124
|
+
if (err instanceof NotFound) {
|
|
111
125
|
console.error('Not found:', err.message);
|
|
112
126
|
}
|
|
113
127
|
}
|
|
@@ -155,16 +169,25 @@ import type {
|
|
|
155
169
|
### Database and Utility Helpers
|
|
156
170
|
|
|
157
171
|
```js
|
|
158
|
-
import {
|
|
172
|
+
import { DatabaseResolver, PsqlService, getHost, getPsqlConfigs } from '@heroku/heroku-cli-util/utils/pg';
|
|
173
|
+
import { AddonResolver, isPostgresAddon } from '@heroku/heroku-cli-util/utils/addons';
|
|
159
174
|
|
|
160
|
-
//
|
|
161
|
-
|
|
175
|
+
// Resolve a database from an app (requires APIClient from @heroku-cli/command)
|
|
176
|
+
const resolver = new DatabaseResolver(herokuApiClient, app, db);
|
|
177
|
+
const database = await resolver.resolve();
|
|
162
178
|
|
|
163
179
|
// Get Heroku Postgres host
|
|
164
|
-
const host =
|
|
180
|
+
const host = getHost();
|
|
181
|
+
|
|
182
|
+
// Create a PSQL service
|
|
183
|
+
const psql = new PsqlService(database);
|
|
184
|
+
|
|
185
|
+
// Check if addon is PostgreSQL
|
|
186
|
+
const isPg = isPostgresAddon(addon);
|
|
165
187
|
|
|
166
|
-
//
|
|
167
|
-
|
|
188
|
+
// Resolve an addon
|
|
189
|
+
const addonResolver = new AddonResolver(herokuApiClient, app, addonName);
|
|
190
|
+
const addon = await addonResolver.resolve();
|
|
168
191
|
```
|
|
169
192
|
|
|
170
193
|
## Development
|
package/dist/index.d.ts
CHANGED
|
@@ -37,9 +37,8 @@ export declare const utils: {
|
|
|
37
37
|
NotFound: typeof NotFound;
|
|
38
38
|
};
|
|
39
39
|
pg: {
|
|
40
|
-
DatabaseResolver: typeof DatabaseResolver;
|
|
41
|
-
PsqlService: typeof PsqlService;
|
|
42
40
|
addonService: () => string;
|
|
41
|
+
DatabaseResolver: typeof DatabaseResolver;
|
|
43
42
|
host: typeof getHost;
|
|
44
43
|
isAdvancedDatabase: (addon: DataApiTypes.ExtendedAddon | DataApiTypes.ExtendedAddonAttachment["addon"]) => boolean;
|
|
45
44
|
isAdvancedPrivateDatabase: (addon: DataApiTypes.ExtendedAddon | DataApiTypes.ExtendedAddonAttachment["addon"]) => boolean;
|
|
@@ -52,6 +51,7 @@ export declare const utils: {
|
|
|
52
51
|
getPsqlConfigs: typeof getPsqlConfigs;
|
|
53
52
|
sshTunnel: typeof sshTunnel;
|
|
54
53
|
};
|
|
54
|
+
PsqlService: typeof PsqlService;
|
|
55
55
|
};
|
|
56
56
|
};
|
|
57
57
|
export declare const hux: {
|
package/dist/index.js
CHANGED
|
@@ -10,8 +10,8 @@ import PsqlService from './utils/pg/psql.js';
|
|
|
10
10
|
import { ago } from './ux/ago.js';
|
|
11
11
|
import { alignColumns } from './ux/align-columns.js';
|
|
12
12
|
import { anykey } from './ux/any-key.js';
|
|
13
|
-
import { confirm } from './ux/confirm.js';
|
|
14
13
|
import { confirmCommand } from './ux/confirm-command.js';
|
|
14
|
+
import { confirm } from './ux/confirm.js';
|
|
15
15
|
import { toHumanReadableDataSize } from './ux/data-size.js';
|
|
16
16
|
import { formatPrice } from './ux/format-price.js';
|
|
17
17
|
import { openUrl } from './ux/open-url.js';
|
|
@@ -29,9 +29,8 @@ export const utils = {
|
|
|
29
29
|
NotFound, // This should be NotFoundError for consistency, but we're keeping it for backwards compatibility
|
|
30
30
|
},
|
|
31
31
|
pg: {
|
|
32
|
-
DatabaseResolver,
|
|
33
|
-
PsqlService,
|
|
34
32
|
addonService: getAddonService,
|
|
33
|
+
DatabaseResolver,
|
|
35
34
|
host: getHost,
|
|
36
35
|
isAdvancedDatabase,
|
|
37
36
|
isAdvancedPrivateDatabase,
|
|
@@ -44,6 +43,7 @@ export const utils = {
|
|
|
44
43
|
getPsqlConfigs,
|
|
45
44
|
sshTunnel,
|
|
46
45
|
},
|
|
46
|
+
PsqlService,
|
|
47
47
|
},
|
|
48
48
|
};
|
|
49
49
|
export const hux = {
|
|
@@ -10,44 +10,44 @@ type AddonDescriptor = DeepRequired<Heroku.AddOnAttachment>['addon'];
|
|
|
10
10
|
* This is the modified type for the `addon` property when the request to Platform API includes the value `addon:plan`
|
|
11
11
|
* in the `Accept-Inclusion` header.
|
|
12
12
|
*/
|
|
13
|
-
type AddonDescriptorWithPlanInclusion = {
|
|
13
|
+
type AddonDescriptorWithPlanInclusion = AddonDescriptor & {
|
|
14
14
|
plan: {
|
|
15
15
|
id: string;
|
|
16
16
|
name: string;
|
|
17
17
|
};
|
|
18
|
-
}
|
|
18
|
+
};
|
|
19
19
|
/**
|
|
20
20
|
* This is the modified type for the `AddOnAttachment` type when the request to Platform API includes the value
|
|
21
21
|
* `config_vars` in the `Accept-Inclusion` header.
|
|
22
22
|
*/
|
|
23
|
-
type AddonAttachmentWithConfigVarsInclusion = {
|
|
23
|
+
type AddonAttachmentWithConfigVarsInclusion = DeepRequired<Heroku.AddOnAttachment> & {
|
|
24
24
|
config_vars: string[];
|
|
25
|
-
}
|
|
25
|
+
};
|
|
26
26
|
/**
|
|
27
27
|
* This is the modified type for the `AddOnAttachment` we use on these lib functions because all requests made to
|
|
28
28
|
* Platform API to get add-on attachments, either through the Add-on Attachment List endpoint or the
|
|
29
29
|
* add-on attachment resolver action endpoint, include the header `Accept-Inclusion: addon:plan,config_vars`.
|
|
30
30
|
*/
|
|
31
|
-
export type ExtendedAddonAttachment = {
|
|
31
|
+
export type ExtendedAddonAttachment = AddonAttachmentWithConfigVarsInclusion & {
|
|
32
32
|
addon: AddonDescriptorWithPlanInclusion;
|
|
33
|
-
}
|
|
33
|
+
};
|
|
34
34
|
/**
|
|
35
35
|
* This is the modified type for the `AddOn` we use on these lib functions because all requests made to
|
|
36
36
|
* Platform API to get add-ons, either through the Add-on List endpoint or the add-on resolver action endpoint,
|
|
37
37
|
* include the header `Accept-Expansion: addon_service,plan`.
|
|
38
38
|
*/
|
|
39
|
-
export type ExtendedAddon = {
|
|
39
|
+
export type ExtendedAddon = DeepRequired<Heroku.AddOn> & {
|
|
40
40
|
addon_service: DeepRequired<Heroku.AddOnService>;
|
|
41
41
|
plan: DeepRequired<Heroku.Plan>;
|
|
42
|
-
}
|
|
42
|
+
};
|
|
43
43
|
/**
|
|
44
44
|
* The next two types need review and cleanup. They're not used anywhere in this codebase yet.
|
|
45
45
|
*/
|
|
46
|
-
export type AddOnWithRelatedData = {
|
|
46
|
+
export type AddOnWithRelatedData = AddonDescriptor & {
|
|
47
47
|
attachment_names?: string[];
|
|
48
48
|
links?: Link[];
|
|
49
49
|
plan: DeepRequired<Heroku.AddOn['plan']>;
|
|
50
|
-
}
|
|
50
|
+
};
|
|
51
51
|
export type Link = {
|
|
52
52
|
attachment_name?: string;
|
|
53
53
|
created_at: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Server } from 'node:net';
|
|
2
2
|
import type { ExtendedAddonAttachment } from './platform-api.js';
|
|
3
|
-
export type ConnectionDetails = {
|
|
3
|
+
export type ConnectionDetails = BastionConfig & {
|
|
4
4
|
_tunnel?: Server;
|
|
5
5
|
attachment?: ExtendedAddonAttachment;
|
|
6
6
|
database: string;
|
|
@@ -10,7 +10,7 @@ export type ConnectionDetails = {
|
|
|
10
10
|
port: string;
|
|
11
11
|
url: string;
|
|
12
12
|
user: string;
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
14
|
export interface TunnelConfig {
|
|
15
15
|
dstHost: string;
|
|
16
16
|
dstPort: number;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default as AddonResolver } from './addon-resolver.js';
|
|
2
|
+
export { default as AttachmentResolver } from './attachment-resolver.js';
|
|
3
|
+
export { getAddonService, isAdvancedDatabase, isAdvancedPrivateDatabase, isEssentialDatabase, isLegacyDatabase, isLegacyEssentialDatabase, isPostgresAddon, } from './helpers.js';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default as AddonResolver } from './addon-resolver.js';
|
|
2
|
+
export { default as AttachmentResolver } from './attachment-resolver.js';
|
|
3
|
+
export { getAddonService, isAdvancedDatabase, isAdvancedPrivateDatabase, isEssentialDatabase, isLegacyDatabase, isLegacyEssentialDatabase, isPostgresAddon, } from './helpers.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { AmbiguousError } from '../errors/ambiguous.js';
|
|
2
|
+
export { NotFound } from '../errors/not-found.js';
|
|
3
|
+
export { default as AddonResolver } from './addons/addon-resolver.js';
|
|
4
|
+
export { getAddonService, isAdvancedDatabase, isAdvancedPrivateDatabase, isEssentialDatabase, isLegacyDatabase, isLegacyEssentialDatabase, isPostgresAddon, } from './addons/helpers.js';
|
|
5
|
+
export { getPsqlConfigs, sshTunnel } from './pg/bastion.js';
|
|
6
|
+
export { getConfigVarNameFromAttachment } from './pg/config-vars.js';
|
|
7
|
+
export { default as DatabaseResolver } from './pg/databases.js';
|
|
8
|
+
export { default as getHost } from './pg/host.js';
|
|
9
|
+
export { default as PsqlService } from './pg/psql.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { AmbiguousError } from '../errors/ambiguous.js';
|
|
2
|
+
export { NotFound } from '../errors/not-found.js';
|
|
3
|
+
export { default as AddonResolver } from './addons/addon-resolver.js';
|
|
4
|
+
export { getAddonService, isAdvancedDatabase, isAdvancedPrivateDatabase, isEssentialDatabase, isLegacyDatabase, isLegacyEssentialDatabase, isPostgresAddon, } from './addons/helpers.js';
|
|
5
|
+
export { getPsqlConfigs, sshTunnel } from './pg/bastion.js';
|
|
6
|
+
export { getConfigVarNameFromAttachment } from './pg/config-vars.js';
|
|
7
|
+
export { default as DatabaseResolver } from './pg/databases.js';
|
|
8
|
+
export { default as getHost } from './pg/host.js';
|
|
9
|
+
export { default as PsqlService } from './pg/psql.js';
|
|
@@ -25,9 +25,9 @@ export default class DatabaseResolver {
|
|
|
25
25
|
* @returns Promise resolving to all Heroku Postgres databases
|
|
26
26
|
* @throws {Error} When no legacy database add-on exists on the app
|
|
27
27
|
*/
|
|
28
|
-
getAllLegacyDatabases(app: string): Promise<Array<{
|
|
28
|
+
getAllLegacyDatabases(app: string): Promise<Array<ExtendedAddonAttachment['addon'] & {
|
|
29
29
|
attachment_names?: string[];
|
|
30
|
-
}
|
|
30
|
+
}>>;
|
|
31
31
|
/**
|
|
32
32
|
* Resolves an arbitrary legacy database add-on based on the provided app name.
|
|
33
33
|
*
|
package/dist/utils/pg/host.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default function (): string;
|
|
1
|
+
export default function getHost(): string;
|
package/dist/utils/pg/host.js
CHANGED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { getPsqlConfigs, sshTunnel } from './bastion.js';
|
|
2
|
+
export { getConfigVarNameFromAttachment } from './config-vars.js';
|
|
3
|
+
export { default as DatabaseResolver } from './databases.js';
|
|
4
|
+
export { default as getHost } from './host.js';
|
|
5
|
+
export { default as PsqlService } from './psql.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { getPsqlConfigs, sshTunnel } from './bastion.js';
|
|
2
|
+
export { getConfigVarNameFromAttachment } from './config-vars.js';
|
|
3
|
+
export { default as DatabaseResolver } from './databases.js';
|
|
4
|
+
export { default as getHost } from './host.js';
|
|
5
|
+
export { default as PsqlService } from './psql.js';
|
package/dist/ux/any-key.js
CHANGED
|
@@ -14,7 +14,8 @@ function readChar() {
|
|
|
14
14
|
export async function anykey(message) {
|
|
15
15
|
const { isRaw, isTTY } = process.stdin;
|
|
16
16
|
if (!message) {
|
|
17
|
-
message = isTTY
|
|
17
|
+
message = isTTY
|
|
18
|
+
? `Press any key to continue or ${color.yellow('q')} to exit`
|
|
18
19
|
: `Press enter to continue or ${color.yellow('q')} to exit`;
|
|
19
20
|
}
|
|
20
21
|
if (isTTY)
|
|
@@ -38,19 +38,28 @@ export async function confirmCommand({ abortedMessage, comparison, confirmation,
|
|
|
38
38
|
if (confirmation) {
|
|
39
39
|
if (confirmation === comparison)
|
|
40
40
|
return;
|
|
41
|
-
throw new Error(`Confirmation ${color.
|
|
41
|
+
throw new Error(`Confirmation ${color.warning(confirmation)} did not match ${color.info(comparison)}. ${abortedMessage}`);
|
|
42
42
|
}
|
|
43
43
|
if (!warningMessage) {
|
|
44
|
-
warningMessage = heredoc
|
|
44
|
+
warningMessage = heredoc(`
|
|
45
45
|
Destructive Action
|
|
46
|
-
This command will affect the app ${color.
|
|
47
|
-
|
|
46
|
+
This command will affect the app ${color.app(comparison)}
|
|
47
|
+
`).trimEnd();
|
|
48
48
|
}
|
|
49
49
|
ux.warn(warningMessage);
|
|
50
50
|
process.stderr.write('\n');
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
try {
|
|
52
|
+
const entered = await promptFunction(`To proceed, type ${color.warning(comparison)} or re-run this command with ${color.code(`--confirm ${comparison}`)}`, { required: true });
|
|
53
|
+
if (entered === comparison) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
throw new Error(`Confirmation did not match ${color.info(comparison)}. ${abortedMessage}`);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const err = error;
|
|
60
|
+
if (err.name === 'ExitPromptError' && err.message.includes('SIGINT')) {
|
|
61
|
+
throw new Error(`Cancelled with ${color.warning('CTRL+C')}. ${abortedMessage}`);
|
|
62
|
+
}
|
|
63
|
+
throw error;
|
|
54
64
|
}
|
|
55
|
-
throw new Error(`Confirmation did not match ${color.bold.red(comparison)}. ${abortedMessage}`);
|
|
56
65
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { ago } from './ago.js';
|
|
2
|
+
export { alignColumns } from './align-columns.js';
|
|
3
|
+
export { anykey } from './any-key.js';
|
|
4
|
+
export * as color from './colors.js';
|
|
5
|
+
export { confirmCommand } from './confirm-command.js';
|
|
6
|
+
export { confirm } from './confirm.js';
|
|
7
|
+
export { toHumanReadableDataSize } from './data-size.js';
|
|
8
|
+
export { formatPrice } from './format-price.js';
|
|
9
|
+
export { openUrl } from './open-url.js';
|
|
10
|
+
export { prompt } from './prompt.js';
|
|
11
|
+
export { styledHeader } from './styled-header.js';
|
|
12
|
+
export { styledJSON } from './styled-json.js';
|
|
13
|
+
export { styledObject } from './styled-object.js';
|
|
14
|
+
export { table } from './table.js';
|
|
15
|
+
export { toTitleCase } from './to-title-case.js';
|
|
16
|
+
export { wait } from './wait.js';
|
package/dist/ux/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { ago } from './ago.js';
|
|
2
|
+
export { alignColumns } from './align-columns.js';
|
|
3
|
+
export { anykey } from './any-key.js';
|
|
4
|
+
export * as color from './colors.js';
|
|
5
|
+
export { confirmCommand } from './confirm-command.js';
|
|
6
|
+
export { confirm } from './confirm.js';
|
|
7
|
+
export { toHumanReadableDataSize } from './data-size.js';
|
|
8
|
+
export { formatPrice } from './format-price.js';
|
|
9
|
+
export { openUrl } from './open-url.js';
|
|
10
|
+
export { prompt } from './prompt.js';
|
|
11
|
+
export { styledHeader } from './styled-header.js';
|
|
12
|
+
export { styledJSON } from './styled-json.js';
|
|
13
|
+
export { styledObject } from './styled-object.js';
|
|
14
|
+
export { table } from './table.js';
|
|
15
|
+
export { toTitleCase } from './to-title-case.js';
|
|
16
|
+
export { wait } from './wait.js';
|
package/dist/ux/table.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ type Column<T extends Record<string, unknown>> = {
|
|
|
8
8
|
type Columns<T extends Record<string, unknown>> = {
|
|
9
9
|
[key: string]: Partial<Column<T>>;
|
|
10
10
|
};
|
|
11
|
-
export declare function table<T extends Record<string, unknown>>(data: T[], columns: Columns<T>, options?: {
|
|
11
|
+
export declare function table<T extends Record<string, unknown>>(data: T[], columns: Columns<T>, options?: Omit<TableOptions<T>, 'columns' | 'data'> & {
|
|
12
12
|
printLine?(s: unknown): void;
|
|
13
|
-
}
|
|
13
|
+
}): void;
|
|
14
14
|
export {};
|
package/dist/ux/table.js
CHANGED
|
@@ -9,14 +9,16 @@ export function table(data, columns, options) {
|
|
|
9
9
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10
10
|
const { printLine, ...tableOptions } = options || {};
|
|
11
11
|
printTable({
|
|
12
|
-
...(tableOptions?.noStyle
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
...(tableOptions?.noStyle
|
|
13
|
+
? {}
|
|
14
|
+
: {
|
|
15
|
+
borderColor: 'whiteBright',
|
|
16
|
+
borderStyle: 'headers-only-with-underline',
|
|
17
|
+
headerOptions: {
|
|
18
|
+
bold: true,
|
|
19
|
+
color: 'white', // or 'reset' to use default terminal color
|
|
20
|
+
},
|
|
21
|
+
}),
|
|
20
22
|
...tableOptions,
|
|
21
23
|
columns: cols,
|
|
22
24
|
data: d,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@heroku/heroku-cli-util",
|
|
4
|
-
"version": "10.
|
|
4
|
+
"version": "10.7.0-beta.0",
|
|
5
5
|
"description": "Set of helpful CLI utilities",
|
|
6
6
|
"author": "Heroku",
|
|
7
7
|
"license": "ISC",
|
|
@@ -11,36 +11,71 @@
|
|
|
11
11
|
},
|
|
12
12
|
"main": "dist/index.js",
|
|
13
13
|
"types": "dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./color": {
|
|
21
|
+
"types": "./dist/ux/colors.d.ts",
|
|
22
|
+
"import": "./dist/ux/colors.js",
|
|
23
|
+
"default": "./dist/ux/colors.js"
|
|
24
|
+
},
|
|
25
|
+
"./colors": {
|
|
26
|
+
"types": "./dist/ux/colors.d.ts",
|
|
27
|
+
"import": "./dist/ux/colors.js",
|
|
28
|
+
"default": "./dist/ux/colors.js"
|
|
29
|
+
},
|
|
30
|
+
"./hux": {
|
|
31
|
+
"types": "./dist/ux/index.d.ts",
|
|
32
|
+
"import": "./dist/ux/index.js",
|
|
33
|
+
"default": "./dist/ux/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./utils": {
|
|
36
|
+
"types": "./dist/utils/index.d.ts",
|
|
37
|
+
"import": "./dist/utils/index.js",
|
|
38
|
+
"default": "./dist/utils/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./utils/pg": {
|
|
41
|
+
"types": "./dist/utils/pg/index.d.ts",
|
|
42
|
+
"import": "./dist/utils/pg/index.js",
|
|
43
|
+
"default": "./dist/utils/pg/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./utils/addons": {
|
|
46
|
+
"types": "./dist/utils/addons/index.d.ts",
|
|
47
|
+
"import": "./dist/utils/addons/index.js",
|
|
48
|
+
"default": "./dist/utils/addons/index.js"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
14
51
|
"files": [
|
|
15
52
|
"dist"
|
|
16
53
|
],
|
|
17
54
|
"devDependencies": {
|
|
18
55
|
"@heroku-cli/schema": "^2.0.0",
|
|
19
|
-
"@heroku-cli/test-utils": "^0.
|
|
20
|
-
"@types/chai": "^
|
|
56
|
+
"@heroku-cli/test-utils": "^0.2.0",
|
|
57
|
+
"@types/chai": "^5.2.3",
|
|
21
58
|
"@types/chai-as-promised": "^8.0.2",
|
|
22
59
|
"@types/debug": "^4.1.12",
|
|
23
60
|
"@types/mocha": "^10.0.10",
|
|
24
61
|
"@types/node": "^22.15.3",
|
|
25
|
-
"@types/sinon": "^
|
|
62
|
+
"@types/sinon": "^20.0.0",
|
|
26
63
|
"@types/sinon-chai": "^4.0.0",
|
|
27
64
|
"@types/tmp": "^0.2.6",
|
|
28
65
|
"@types/tunnel-ssh": "4.1.1",
|
|
29
|
-
"c8": "^
|
|
30
|
-
"chai": "^
|
|
31
|
-
"chai-as-promised": "^8.0.
|
|
66
|
+
"c8": "^11.0.0",
|
|
67
|
+
"chai": "^5.3.3",
|
|
68
|
+
"chai-as-promised": "^8.0.2",
|
|
32
69
|
"eslint": "^9",
|
|
33
70
|
"eslint-config-oclif": "^6.0.144",
|
|
34
|
-
"eslint-plugin-mocha": "^11.2.0",
|
|
35
71
|
"mocha": "^11",
|
|
36
72
|
"mock-stdin": "^1.0.0",
|
|
37
|
-
"nock": "^
|
|
73
|
+
"nock": "^14.0.11",
|
|
38
74
|
"open": "^11",
|
|
39
|
-
"sinon": "^
|
|
40
|
-
"sinon-chai": "^
|
|
75
|
+
"sinon": "^20.0.0",
|
|
76
|
+
"sinon-chai": "^4.0.1",
|
|
41
77
|
"tmp": "^0.2.5",
|
|
42
|
-
"
|
|
43
|
-
"tsconfig-paths": "^4.2.0",
|
|
78
|
+
"tsx": "^4.21.0",
|
|
44
79
|
"typescript": "^5.4.0"
|
|
45
80
|
},
|
|
46
81
|
"dependencies": {
|
|
@@ -63,10 +98,9 @@
|
|
|
63
98
|
"clean": "rm -rf dist",
|
|
64
99
|
"example": "sh examples/run.sh",
|
|
65
100
|
"lint": "eslint .",
|
|
66
|
-
"
|
|
101
|
+
"lint:fix": "eslint --fix",
|
|
67
102
|
"prepare": "npm run build",
|
|
68
|
-
"test": "c8 mocha --forbid-only \"test/**/*.test.ts\""
|
|
69
|
-
"test:local": "c8 mocha \"${npm_config_file:-test/**/*.test.+(ts|tsx)}\""
|
|
103
|
+
"test": "npm run build && c8 --all --check-coverage --reporter=lcov --reporter=text-summary mocha --forbid-only \"test/**/*.test.ts\""
|
|
70
104
|
},
|
|
71
105
|
"overrides": {
|
|
72
106
|
"serialize-javascript": "^7.0.3"
|