heroku 9.0.0 → 9.1.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/lib/commands/domains/index.d.ts +4 -0
- package/lib/commands/domains/index.js +47 -3
- package/lib/lib/container/helpers.js +7 -4
- package/lib/lib/pg/fetcher.js +0 -1
- package/lib/lib/utils/keyValueParser.d.ts +4 -0
- package/lib/lib/utils/keyValueParser.js +9 -0
- package/lib/lib/utils/paginator.d.ts +2 -0
- package/lib/lib/utils/paginator.js +29 -0
- package/oclif.manifest.json +696 -696
- package/package.json +3 -2
|
@@ -36,5 +36,9 @@ export default class DomainsIndex extends Command {
|
|
|
36
36
|
extended: boolean;
|
|
37
37
|
};
|
|
38
38
|
};
|
|
39
|
+
getFilteredDomains: (filterKeyValue: string, domains: Array<Heroku.Domain>) => {
|
|
40
|
+
size: number;
|
|
41
|
+
filteredDomains: Heroku.Domain[];
|
|
42
|
+
};
|
|
39
43
|
run(): Promise<void>;
|
|
40
44
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const command_1 = require("@heroku-cli/command");
|
|
4
|
+
const color_1 = require("@heroku-cli/color");
|
|
4
5
|
const core_1 = require("@oclif/core");
|
|
5
6
|
const Uri = require("urijs");
|
|
7
|
+
const prompts_1 = require("@inquirer/prompts");
|
|
8
|
+
const paginator_1 = require("../../lib/utils/paginator");
|
|
9
|
+
const keyValueParser_1 = require("../../lib/utils/keyValueParser");
|
|
6
10
|
function isApexDomain(hostname) {
|
|
7
11
|
if (hostname.includes('*'))
|
|
8
12
|
return false;
|
|
@@ -44,12 +48,44 @@ class DomainsIndex extends command_1.Command {
|
|
|
44
48
|
}
|
|
45
49
|
return tableConfig;
|
|
46
50
|
};
|
|
51
|
+
this.getFilteredDomains = (filterKeyValue, domains) => {
|
|
52
|
+
const filteredInfo = { size: 0, filteredDomains: domains };
|
|
53
|
+
const { key: filterName, value } = (0, keyValueParser_1.default)(filterKeyValue);
|
|
54
|
+
if (!value) {
|
|
55
|
+
throw new Error('Filter flag has an invalid value');
|
|
56
|
+
}
|
|
57
|
+
if (filterName === 'Domain Name') {
|
|
58
|
+
filteredInfo.filteredDomains = domains.filter(domain => domain.hostname.includes(value));
|
|
59
|
+
}
|
|
60
|
+
if (filterName === 'DNS Record Type') {
|
|
61
|
+
filteredInfo.filteredDomains = domains.filter(domain => {
|
|
62
|
+
const kind = isApexDomain(domain.hostname) ? 'ALIAS or ANAME' : 'CNAME';
|
|
63
|
+
return kind.includes(value);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (filterName === 'DNS Target') {
|
|
67
|
+
filteredInfo.filteredDomains = domains.filter(domain => domain.cname.includes(value));
|
|
68
|
+
}
|
|
69
|
+
if (filterName === 'SNI Endpoint') {
|
|
70
|
+
filteredInfo.filteredDomains = domains.filter(domain => {
|
|
71
|
+
if (!domain.sni_endpoint)
|
|
72
|
+
domain.sni_endpoint = '';
|
|
73
|
+
return domain.sni_endpoint.includes(value);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
filteredInfo.size = filteredInfo.filteredDomains.length;
|
|
77
|
+
return filteredInfo;
|
|
78
|
+
};
|
|
47
79
|
}
|
|
48
80
|
async run() {
|
|
49
81
|
const { flags } = await this.parse(DomainsIndex);
|
|
50
|
-
const
|
|
51
|
-
const herokuDomain = domains.find(domain => domain.kind === 'heroku');
|
|
52
|
-
|
|
82
|
+
const domains = await (0, paginator_1.paginateRequest)(this.heroku, `/apps/${flags.app}/domains`, 1000);
|
|
83
|
+
const herokuDomain = domains.find((domain) => domain.kind === 'heroku');
|
|
84
|
+
let customDomains = domains.filter((domain) => domain.kind === 'custom');
|
|
85
|
+
let displayTotalDomains = false;
|
|
86
|
+
if (flags.filter) {
|
|
87
|
+
customDomains = this.getFilteredDomains(flags.filter, domains).filteredDomains;
|
|
88
|
+
}
|
|
53
89
|
if (flags.json) {
|
|
54
90
|
core_1.ux.styledJSON(domains);
|
|
55
91
|
}
|
|
@@ -57,6 +93,14 @@ class DomainsIndex extends command_1.Command {
|
|
|
57
93
|
core_1.ux.styledHeader(`${flags.app} Heroku Domain`);
|
|
58
94
|
core_1.ux.log(herokuDomain && herokuDomain.hostname);
|
|
59
95
|
if (customDomains && customDomains.length > 0) {
|
|
96
|
+
core_1.ux.log();
|
|
97
|
+
if (customDomains.length > 100 && !flags.csv) {
|
|
98
|
+
core_1.ux.warn(`This app has over 100 domains. Your terminal may not be configured to display the total amount of domains. You can export all domains into a CSV file with: ${color_1.default.cyan('heroku domains -a example-app --csv > example-file.csv')}`);
|
|
99
|
+
displayTotalDomains = await (0, prompts_1.confirm)({ default: false, message: `Display all ${customDomains.length} domains?`, theme: { prefix: '', style: { defaultAnswer: () => '(Y/N)' } } });
|
|
100
|
+
if (!displayTotalDomains) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
60
104
|
core_1.ux.log();
|
|
61
105
|
core_1.ux.styledHeader(`${flags.app} Custom Domains`);
|
|
62
106
|
core_1.ux.table(customDomains, this.tableConfig(true), Object.assign(Object.assign({}, flags), { 'no-truncate': true }));
|
|
@@ -13,12 +13,15 @@ const stackLabelMap = {
|
|
|
13
13
|
* @returns {null} null
|
|
14
14
|
*/
|
|
15
15
|
function ensureContainerStack(app, cmd) {
|
|
16
|
-
var _a, _b
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
var _a, _b;
|
|
17
|
+
const buildStack = (_a = app.build_stack) === null || _a === void 0 ? void 0 : _a.name;
|
|
18
|
+
const appStack = (_b = app.stack) === null || _b === void 0 ? void 0 : _b.name;
|
|
19
|
+
const allowedStack = 'container';
|
|
20
|
+
// either can be container stack and are allowed
|
|
21
|
+
if (buildStack !== allowedStack && appStack !== allowedStack) {
|
|
19
22
|
let message = 'This command is for Docker apps only.';
|
|
20
23
|
if (['push', 'release'].includes(cmd)) {
|
|
21
|
-
message += `
|
|
24
|
+
message += ` Switch stacks by running ${color_1.default.cmd('heroku stack:set container')}. Or, to deploy ${color_1.default.app(app.name)} with ${color_1.default.yellow(appStack)}, run ${color_1.default.cmd('git push heroku main')} instead.`;
|
|
22
25
|
}
|
|
23
26
|
core_1.ux.error(message, { exit: 1 });
|
|
24
27
|
}
|
package/lib/lib/pg/fetcher.js
CHANGED
|
@@ -86,7 +86,6 @@ async function getAttachment(heroku, app, db = 'DATABASE_URL', namespace = '') {
|
|
|
86
86
|
if (attachments.length === 0) {
|
|
87
87
|
throw new Error(`${color_1.default.app(app)} has no databases`);
|
|
88
88
|
}
|
|
89
|
-
console.log('hi', JSON.stringify(attachments));
|
|
90
89
|
matches = attachments.filter(attachment => config[db] && config[db] === config[(0, util_1.getConfigVarName)(attachment.config_vars)]);
|
|
91
90
|
if (matches.length === 0) {
|
|
92
91
|
const validOptions = attachments.map(attachment => (0, util_1.getConfigVarName)(attachment.config_vars));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function parseKeyValue(input) {
|
|
4
|
+
let [key, value] = input.split(/=(.+)/);
|
|
5
|
+
key = key.trim();
|
|
6
|
+
value = value ? value.trim() : '';
|
|
7
|
+
return { key, value };
|
|
8
|
+
}
|
|
9
|
+
exports.default = parseKeyValue;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// page size ranges from 200 - 1000 seen here
|
|
3
|
+
// https://devcenter.heroku.com/articles/platform-api-reference#ranges
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.paginateRequest = void 0;
|
|
6
|
+
async function paginateRequest(client, url, pageSize = 200) {
|
|
7
|
+
let isPartial = true;
|
|
8
|
+
let isFirstRequest = true;
|
|
9
|
+
let nextRange = '';
|
|
10
|
+
let aggregatedResponseBody = [];
|
|
11
|
+
while (isPartial) {
|
|
12
|
+
const response = await client.get(url, {
|
|
13
|
+
headers: {
|
|
14
|
+
Range: `${(isPartial && !isFirstRequest) ? `${nextRange}` : `id ..; max=${pageSize};`}`,
|
|
15
|
+
},
|
|
16
|
+
partial: true,
|
|
17
|
+
});
|
|
18
|
+
aggregatedResponseBody = [...response.body, ...aggregatedResponseBody];
|
|
19
|
+
isFirstRequest = false;
|
|
20
|
+
if (response.statusCode === 206) {
|
|
21
|
+
nextRange = response.headers['next-range'];
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
isPartial = false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return aggregatedResponseBody;
|
|
28
|
+
}
|
|
29
|
+
exports.paginateRequest = paginateRequest;
|