insta 0.0.79 → 0.0.80
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/dist/commands/billing.js +5 -1
- package/dist/commands/domain.js +18 -15
- package/dist/index.js +4 -2
- package/package.json +1 -1
package/dist/commands/billing.js
CHANGED
|
@@ -5,7 +5,11 @@ import { cycleLine, dimensionLines } from './metrics.js';
|
|
|
5
5
|
export async function resolveOrgId(opts) {
|
|
6
6
|
if (opts.org)
|
|
7
7
|
return opts.org;
|
|
8
|
-
|
|
8
|
+
// `ProjectConfig.orgId` is typed string but INSTA_PROJECT_ID resolves a project with no org.
|
|
9
|
+
const orgId = (await requireProject()).orgId;
|
|
10
|
+
if (!orgId)
|
|
11
|
+
die('INSTA_PROJECT_ID names no organization — set INSTA_ORG_ID, or pass --org <id>');
|
|
12
|
+
return orgId;
|
|
9
13
|
}
|
|
10
14
|
// Format the billing overview into printable lines (pure, so it's unit-testable).
|
|
11
15
|
// `org` is the caller's --org, echoed into the portal hint: `billing` and `billing portal` resolve
|
package/dist/commands/domain.js
CHANGED
|
@@ -36,7 +36,10 @@ export async function domainSearch(keyword, opts, deps) {
|
|
|
36
36
|
export async function domainBuy(name, opts, deps) {
|
|
37
37
|
const years = whole('--years', opts.years);
|
|
38
38
|
const { api, project: p } = await domainDeps(deps);
|
|
39
|
-
const
|
|
39
|
+
const orgId = p.orgId || die('this project link names no organization — set INSTA_ORG_ID');
|
|
40
|
+
// The org route still signs for a PROJECT in agent mode: `domain.purchase` is read there, and a
|
|
41
|
+
// bootstrap session names none, so the platform refuses it.
|
|
42
|
+
const res = await api.rawRequest('POST', `/orgs/${orgId}/domains/orders`, { domainName: name, years }, { projectId: p.projectId });
|
|
40
43
|
if (handleApproval(res, opts.json))
|
|
41
44
|
return;
|
|
42
45
|
if (opts.json)
|
|
@@ -57,12 +60,13 @@ export function ownerOf(host, owned) {
|
|
|
57
60
|
*/
|
|
58
61
|
export async function domainAttach(host, opts, deps) {
|
|
59
62
|
const { api, project: p } = await domainDeps(deps);
|
|
63
|
+
const orgId = p.orgId || die('this project link names no organization — set INSTA_ORG_ID');
|
|
60
64
|
const name = host.trim().toLowerCase();
|
|
61
|
-
const { items } = await api.request('GET', `/
|
|
65
|
+
const { items } = await api.request('GET', `/orgs/${orgId}/domains`);
|
|
62
66
|
const owner = ownerOf(name, items);
|
|
63
67
|
if (!owner) {
|
|
64
68
|
// The domains list holds registered names only; a bought name still registering is an order.
|
|
65
|
-
const { items: orders } = await api.request('GET', `/
|
|
69
|
+
const { items: orders } = await api.request('GET', `/orgs/${orgId}/domains/orders`);
|
|
66
70
|
const o = ownerOf(name, orders);
|
|
67
71
|
if (o)
|
|
68
72
|
die(`${o.domainName} is not registered yet — its order is ${o.status}: insta domain status ${o.domainName}`);
|
|
@@ -83,10 +87,10 @@ export async function domainAttach(host, opts, deps) {
|
|
|
83
87
|
info(`then: insta domain status ${owner.domainName}`);
|
|
84
88
|
}
|
|
85
89
|
// ---- list / status ----
|
|
86
|
-
function domainLines(d) {
|
|
90
|
+
function domainLines(d, linked = true) {
|
|
87
91
|
const out = [`${d.domainName} ${d.status}${d.expiresAt ? ` (expires ${d.expiresAt.slice(0, 10)}${d.autorenew ? ', auto-renews' : ''})` : ''}`];
|
|
88
92
|
// Vacuously true for a domain with no hostnames, which is every domain until something attaches.
|
|
89
|
-
if (d.hostnames.every((h) => h.state === 'failed')) {
|
|
93
|
+
if (linked && d.hostnames.every((h) => h.state === 'failed')) {
|
|
90
94
|
const names = d.hostnames.map((h) => h.hostname);
|
|
91
95
|
// Attaching the bought name itself re-attaches its www.
|
|
92
96
|
const retry = names.includes(d.domainName) ? names.filter((h) => h !== `www.${d.domainName}`) : names;
|
|
@@ -97,30 +101,29 @@ function domainLines(d) {
|
|
|
97
101
|
out.push(` ${h.hostname.padEnd(w)} ${h.state}${h.service ? ` → ${h.service}` : ''}${h.reason ? ` — ${h.reason}` : ''}`);
|
|
98
102
|
return out;
|
|
99
103
|
}
|
|
100
|
-
function orderStatusLines(o) {
|
|
104
|
+
function orderStatusLines(o, linked = true) {
|
|
101
105
|
const out = [`order ${o.id}: ${o.domainName} — ${o.status}${o.failedReason ? ` — ${o.failedReason}` : ''}`];
|
|
102
|
-
if (o.status === 'canceled')
|
|
106
|
+
if (linked && o.status === 'canceled')
|
|
103
107
|
out.push(` the checkout closed without payment — order again: insta domain buy ${o.domainName}`);
|
|
104
108
|
return out;
|
|
105
109
|
}
|
|
106
110
|
export async function domainList(opts, deps) {
|
|
107
|
-
const { api,
|
|
108
|
-
const r = await api.request('GET', `/
|
|
111
|
+
const { api, orgId } = await orgDeps(opts, deps);
|
|
112
|
+
const r = await api.request('GET', `/orgs/${orgId}/domains`);
|
|
109
113
|
if (opts.json)
|
|
110
114
|
return printJson(r);
|
|
111
115
|
if (!r.items.length)
|
|
112
116
|
return info('no domains bought through InstaCloud in this org (search: insta domain search <keyword>)');
|
|
113
117
|
for (const d of r.items)
|
|
114
|
-
for (const line of domainLines(d))
|
|
118
|
+
for (const line of domainLines(d, !opts.org))
|
|
115
119
|
info(line);
|
|
116
120
|
}
|
|
117
121
|
export async function domainStatus(name, opts, deps) {
|
|
118
|
-
const { api,
|
|
122
|
+
const { api, orgId } = await orgDeps(opts, deps);
|
|
119
123
|
const host = name.trim().toLowerCase();
|
|
120
|
-
// Both are the ORG's; the project in the path is the scope the agent policy is read at.
|
|
121
124
|
const [{ items: domains }, { items: orders }] = await Promise.all([
|
|
122
|
-
api.request('GET', `/
|
|
123
|
-
api.request('GET', `/
|
|
125
|
+
api.request('GET', `/orgs/${orgId}/domains`),
|
|
126
|
+
api.request('GET', `/orgs/${orgId}/domains/orders`),
|
|
124
127
|
]);
|
|
125
128
|
const domain = domains.find((d) => d.domainName === host) ?? null;
|
|
126
129
|
const order = orders.find((o) => o.domainName === host) ?? null;
|
|
@@ -128,7 +131,7 @@ export async function domainStatus(name, opts, deps) {
|
|
|
128
131
|
die(`${host} was not bought through this org`);
|
|
129
132
|
if (opts.json)
|
|
130
133
|
return printJson({ domain, order });
|
|
131
|
-
for (const line of domain ? domainLines(domain) : orderStatusLines(order))
|
|
134
|
+
for (const line of domain ? domainLines(domain, !opts.org) : orderStatusLines(order, !opts.org))
|
|
132
135
|
info(line);
|
|
133
136
|
}
|
|
134
137
|
export function recordLines(records) {
|
package/dist/index.js
CHANGED
|
@@ -371,9 +371,11 @@ dom.command('buy <name>').description('Buy a domain — pay at the printed Strip
|
|
|
371
371
|
dom.command('attach <hostname>').description('Point a bought domain, or any subdomain of one, at a compute service — `abc.com` binds it and its www, `api.abc.com` binds only that (gated: deploy)')
|
|
372
372
|
.option('--branch <b>').option('--group <g>', "compute service (default: the branch's sole compute service)").option('--json')
|
|
373
373
|
.action(guard((hostname, o) => domainCmd.domainAttach(hostname, o)));
|
|
374
|
-
dom.command('list').description("Domains bought through InstaCloud in this org — a domain belongs to the org, each of its hostnames to a service")
|
|
374
|
+
dom.command('list').description("Domains bought through InstaCloud in this org — a domain belongs to the org, each of its hostnames to a service")
|
|
375
|
+
.option('--org <id>', "target org (default: linked project's org)").option('--json')
|
|
375
376
|
.action(guard((o) => domainCmd.domainList(o)));
|
|
376
|
-
dom.command('status <name>').description("A bought domain's order and attach state")
|
|
377
|
+
dom.command('status <name>').description("A bought domain's order and attach state")
|
|
378
|
+
.option('--org <id>', "target org (default: linked project's org)").option('--json')
|
|
377
379
|
.action(guard((name, o) => domainCmd.domainStatus(name, o)));
|
|
378
380
|
const rec = dom.command('records').description('DNS records of a bought domain — the zone InstaCloud holds at the registrar');
|
|
379
381
|
rec.command('list <domain>').description('Every record in the zone, managed ones marked')
|