@myapihq/cli 1.0.37 → 1.0.39
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/auth.js +8 -0
- package/dist/commands/billing.js +15 -17
- package/dist/commands/domain.d.ts +1 -0
- package/dist/commands/domain.js +33 -13
- package/dist/commands/org.js +9 -4
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +11 -0
- package/package.json +1 -1
- package/src/commands/auth.ts +8 -0
- package/src/commands/billing.ts +20 -21
- package/src/commands/domain.ts +33 -16
- package/src/commands/org.ts +14 -9
- package/src/utils.ts +11 -0
package/dist/commands/auth.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as readline from 'readline';
|
|
|
2
2
|
import { loadConfig, saveConfig, addAccount, switchAccount, listAccounts } from '../config.js';
|
|
3
3
|
import { info, success, error } from '../output.js';
|
|
4
4
|
import { installSkills } from './setup.js';
|
|
5
|
+
import { hq } from '@myapihq/sdk';
|
|
5
6
|
const API_BASE = process.env.MYAPI_API_BASE ?? 'https://api.myapihq.com';
|
|
6
7
|
function ask(rl, q) {
|
|
7
8
|
return new Promise(resolve => rl.question(q, resolve));
|
|
@@ -114,6 +115,13 @@ export async function whoami() {
|
|
|
114
115
|
info(`Org: ${config.default_org ?? '(none)'}`);
|
|
115
116
|
info(`Funnel: ${config.default_funnel ?? '(none)'}`);
|
|
116
117
|
info(`Type: ${config.is_anonymous ? 'anonymous' : 'registered'}`);
|
|
118
|
+
try {
|
|
119
|
+
const bal = await hq.getBalance(config.api_key);
|
|
120
|
+
info(`Balance: ${bal.balance_display} | Credits: ${bal.credits_display}`);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Balance fetch is best-effort; don't fail whoami if it errors.
|
|
124
|
+
}
|
|
117
125
|
}
|
|
118
126
|
// myapi auth switch — switch between saved accounts.
|
|
119
127
|
export async function switchCmd() {
|
package/dist/commands/billing.js
CHANGED
|
@@ -2,6 +2,7 @@ import * as readline from 'readline';
|
|
|
2
2
|
import { hq } from '@myapihq/sdk';
|
|
3
3
|
import { requireConfig } from '../config.js';
|
|
4
4
|
import { success, error, printTable, info, printJson } from '../output.js';
|
|
5
|
+
import { formatDate } from '../utils.js';
|
|
5
6
|
export async function balance(flags) {
|
|
6
7
|
if (flags.help) {
|
|
7
8
|
info('Usage: myapi billing balance\n\nShows your current account balance, credits, and payment method status.');
|
|
@@ -10,6 +11,8 @@ export async function balance(flags) {
|
|
|
10
11
|
const config = requireConfig();
|
|
11
12
|
const result = await hq.getBalance(config.api_key);
|
|
12
13
|
const pm = result.has_payment_method ? 'yes' : 'no';
|
|
14
|
+
const accountType = config.is_anonymous ? 'anonymous' : `registered (${config.email ?? ''})`;
|
|
15
|
+
info(`Account: ${accountType}`);
|
|
13
16
|
info(`Balance: ${result.balance_display} | Credits: ${result.credits_display} | Payment method: ${pm}`);
|
|
14
17
|
}
|
|
15
18
|
export async function history(flags) {
|
|
@@ -23,17 +26,16 @@ export async function history(flags) {
|
|
|
23
26
|
printJson(items);
|
|
24
27
|
return;
|
|
25
28
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
29
|
+
if (items.length === 0) {
|
|
30
|
+
info('No transactions yet.');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const formattedItems = items.map(item => ({
|
|
34
|
+
Type: item.type || 'unknown',
|
|
35
|
+
Amount: item.amount_display,
|
|
36
|
+
Status: item.status ? item.status.charAt(0).toUpperCase() + item.status.slice(1) : '',
|
|
37
|
+
Date: formatDate(item.created_at),
|
|
38
|
+
}));
|
|
37
39
|
printTable(formattedItems);
|
|
38
40
|
}
|
|
39
41
|
export async function topup(amountStr, flags) {
|
|
@@ -41,13 +43,9 @@ export async function topup(amountStr, flags) {
|
|
|
41
43
|
info('Usage: myapi billing topup <amount>\n\nAmount is in whole dollars (e.g. "10" charges $10).\nUse --yes to skip confirmation.\nExample: myapi billing topup 10');
|
|
42
44
|
return;
|
|
43
45
|
}
|
|
44
|
-
if (!amountStr) {
|
|
45
|
-
error("Missing amount. Usage: myapi billing topup <amount>\nExample: myapi billing topup 10");
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
46
|
const amount = Math.round(parseFloat(amountStr));
|
|
49
|
-
if (isNaN(amount) || amount <= 0) {
|
|
50
|
-
error("
|
|
47
|
+
if (!amountStr || isNaN(amount) || amount <= 0) {
|
|
48
|
+
error("Amount must be a positive whole number of dollars (e.g. myapi billing topup 10)");
|
|
51
49
|
return;
|
|
52
50
|
}
|
|
53
51
|
if (!flags.yes && !flags.y && amount >= 50) {
|
|
@@ -4,6 +4,7 @@ export declare function importDomain(domainArg: string, flags: Record<string, st
|
|
|
4
4
|
export declare function list(flags: Record<string, string | boolean>): Promise<void>;
|
|
5
5
|
export declare function assign(domainArg: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
6
6
|
export declare function unassign(domainArg: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
7
|
+
export declare function status(domainArg: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
7
8
|
export declare function settings(domainArg: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
8
9
|
export declare function updateSettings(domainArg: string, flags: Record<string, string | boolean>): Promise<void>;
|
|
9
10
|
export declare function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>): Promise<void>;
|
package/dist/commands/domain.js
CHANGED
|
@@ -6,13 +6,14 @@ export async function check(domainArg, flags) {
|
|
|
6
6
|
const orgId = flags.org || config.default_org;
|
|
7
7
|
const domain = domainArg || config.default_domain;
|
|
8
8
|
if (!orgId || !domain)
|
|
9
|
-
error("Missing required arguments.\nUsage: myapi domain check <domain> --org <id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
9
|
+
error("Missing required arguments.\nUsage: myapi domain check <domain> --org <id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
10
10
|
const res = await sdkDomain.checkDomain(config.api_key, orgId, domain);
|
|
11
11
|
if (res.available) {
|
|
12
|
-
|
|
12
|
+
const price = res.price_display || `$${(res.price_cents / 100).toFixed(2)}`;
|
|
13
|
+
info(`${domain} — Available ✓ ${price}/yr`);
|
|
13
14
|
}
|
|
14
15
|
else {
|
|
15
|
-
info(
|
|
16
|
+
info(`${domain} — ${res.message || 'Not available'} ✗`);
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
export async function register(domainArg, flags) {
|
|
@@ -20,7 +21,7 @@ export async function register(domainArg, flags) {
|
|
|
20
21
|
const orgId = flags.org || config.default_org;
|
|
21
22
|
const domain = domainArg || config.default_domain;
|
|
22
23
|
if (!orgId || !domain)
|
|
23
|
-
error("Missing required arguments.\nUsage: myapi domain register <domain> --org <id> [--years <num>]\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
24
|
+
error("Missing required arguments.\nUsage: myapi domain register <domain> --org <id> [--years <num>]\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
24
25
|
const years = parseInt(flags.years) || 1;
|
|
25
26
|
const res = await sdkDomain.registerDomain(config.api_key, orgId, domain, years);
|
|
26
27
|
success(`Registered ${domain}!\n${JSON.stringify(res, null, 2)}`);
|
|
@@ -30,7 +31,7 @@ export async function importDomain(domainArg, flags) {
|
|
|
30
31
|
const orgId = flags.org || config.default_org;
|
|
31
32
|
const domain = domainArg || config.default_domain;
|
|
32
33
|
if (!orgId || !domain)
|
|
33
|
-
error("Missing required arguments.\nUsage: myapi domain import <domain> --org <id> [--namecheap-user <user> --namecheap-key <key>]\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
34
|
+
error("Missing required arguments.\nUsage: myapi domain import <domain> --org <id> [--namecheap-user <user> --namecheap-key <key>]\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
34
35
|
const payload = { domain };
|
|
35
36
|
if (flags['namecheap-user'])
|
|
36
37
|
payload.namecheap_api_user = flags['namecheap-user'];
|
|
@@ -43,7 +44,7 @@ export async function list(flags) {
|
|
|
43
44
|
const config = requireConfig();
|
|
44
45
|
const orgId = flags.org || config.default_org;
|
|
45
46
|
if (!orgId)
|
|
46
|
-
error("Missing required arguments.\nUsage: myapi domain list --org <id> [--filter=all|unassigned|org]\n(Or set a default org via: myapi config set-org <id>)");
|
|
47
|
+
error("Missing required arguments.\nUsage: myapi domain list --org <id> [--filter=all|unassigned|org]\n(Or set a default org via: myapi auth config set-org <id>)");
|
|
47
48
|
const filter = flags.filter;
|
|
48
49
|
const domains = await sdkDomain.listDomains(config.api_key, orgId, filter);
|
|
49
50
|
printTable(domains);
|
|
@@ -54,8 +55,8 @@ export async function assign(domainArg, flags) {
|
|
|
54
55
|
const domain = domainArg || config.default_domain;
|
|
55
56
|
const targetOrgId = flags.target;
|
|
56
57
|
if (!orgId || !domain || !targetOrgId)
|
|
57
|
-
error("Missing required arguments.\nUsage: myapi domain assign <domain> --org <id> --target <target_org_id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
58
|
-
|
|
58
|
+
error("Missing required arguments.\nUsage: myapi domain assign <domain> --org <id> --target <target_org_id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
59
|
+
await sdkDomain.assignDomain(config.api_key, orgId, domain, targetOrgId);
|
|
59
60
|
success(`Assigned ${domain} to org ${targetOrgId}`);
|
|
60
61
|
}
|
|
61
62
|
export async function unassign(domainArg, flags) {
|
|
@@ -63,16 +64,31 @@ export async function unassign(domainArg, flags) {
|
|
|
63
64
|
const orgId = flags.org || config.default_org;
|
|
64
65
|
const domain = domainArg || config.default_domain;
|
|
65
66
|
if (!orgId || !domain)
|
|
66
|
-
error("Missing required arguments.\nUsage: myapi domain unassign <domain> --org <id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
67
|
-
|
|
67
|
+
error("Missing required arguments.\nUsage: myapi domain unassign <domain> --org <id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
68
|
+
await sdkDomain.unassignDomain(config.api_key, orgId, domain);
|
|
68
69
|
success(`Unassigned ${domain} from org ${orgId}`);
|
|
69
70
|
}
|
|
71
|
+
export async function status(domainArg, flags) {
|
|
72
|
+
const config = requireConfig();
|
|
73
|
+
const orgId = flags.org || config.default_org;
|
|
74
|
+
const domain = domainArg || config.default_domain;
|
|
75
|
+
if (!orgId || !domain)
|
|
76
|
+
error("Missing required arguments.\nUsage: myapi domain status <domain> --org <id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
77
|
+
const res = await sdkDomain.getDomainStatus(config.api_key, orgId, domain);
|
|
78
|
+
const display = {
|
|
79
|
+
domain: res.domain,
|
|
80
|
+
status: res.status,
|
|
81
|
+
};
|
|
82
|
+
if (res.expires_at)
|
|
83
|
+
display.expires_at = res.expires_at;
|
|
84
|
+
printJson(display);
|
|
85
|
+
}
|
|
70
86
|
export async function settings(domainArg, flags) {
|
|
71
87
|
const config = requireConfig();
|
|
72
88
|
const orgId = flags.org || config.default_org;
|
|
73
89
|
const domain = domainArg || config.default_domain;
|
|
74
90
|
if (!orgId || !domain)
|
|
75
|
-
error("Missing required arguments.\nUsage: myapi domain settings <domain> --org <id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
91
|
+
error("Missing required arguments.\nUsage: myapi domain settings <domain> --org <id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
76
92
|
const res = await sdkDomain.getDomainSettings(config.api_key, orgId, domain);
|
|
77
93
|
printJson(res);
|
|
78
94
|
}
|
|
@@ -81,7 +97,7 @@ export async function updateSettings(domainArg, flags) {
|
|
|
81
97
|
const orgId = flags.org || config.default_org;
|
|
82
98
|
const domain = domainArg || config.default_domain;
|
|
83
99
|
if (!orgId || !domain)
|
|
84
|
-
error("Missing required arguments.\nUsage: myapi domain update-settings <domain> --org <id> [--security=...] [--browser-check=...] [--purge-cache]\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
100
|
+
error("Missing required arguments.\nUsage: myapi domain update-settings <domain> --org <id> [--security=...] [--browser-check=...] [--purge-cache]\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
85
101
|
const payload = {};
|
|
86
102
|
if (flags.security)
|
|
87
103
|
payload.security_level = flags.security;
|
|
@@ -94,7 +110,7 @@ export async function updateSettings(domainArg, flags) {
|
|
|
94
110
|
}
|
|
95
111
|
export async function run(subcommand, args, flags) {
|
|
96
112
|
if (!subcommand || (flags.help && !subcommand)) {
|
|
97
|
-
info('Usage: myapi domain <subcommand>\n\nSubcommands:\n list List domains\n check Check domain availability\n register Register a domain\n import Import an existing domain\n assign Assign domain to org\n unassign Unassign domain from its current org\n settings Get domain settings\n update-settings Update domain settings\n\nNote: All domain commands require the --org <id> flag.');
|
|
113
|
+
info('Usage: myapi domain <subcommand>\n\nSubcommands:\n list List domains\n check Check domain availability\n register Register a domain\n import Import an existing domain\n assign Assign domain to org\n unassign Unassign domain from its current org\n status Get domain status\n settings Get domain settings\n update-settings Update domain settings\n\nNote: All domain commands require the --org <id> flag.');
|
|
98
114
|
return;
|
|
99
115
|
}
|
|
100
116
|
if (flags.help) {
|
|
@@ -110,6 +126,8 @@ export async function run(subcommand, args, flags) {
|
|
|
110
126
|
info('Usage: myapi domain assign <domain> --org <id> --target <target_org_id>\n\nAssigns a domain to a different organization.');
|
|
111
127
|
else if (subcommand === 'unassign')
|
|
112
128
|
info('Usage: myapi domain unassign <domain> --org <id>\n\nUnassigns a domain from its current organization.');
|
|
129
|
+
else if (subcommand === 'status')
|
|
130
|
+
info('Usage: myapi domain status <domain> --org <id>\n\nGets the registration status of a domain.');
|
|
113
131
|
else if (subcommand === 'settings')
|
|
114
132
|
info('Usage: myapi domain settings <domain> --org <id>\n\nGets the DNS settings and configuration for a domain.');
|
|
115
133
|
else if (subcommand === 'update-settings')
|
|
@@ -128,6 +146,8 @@ export async function run(subcommand, args, flags) {
|
|
|
128
146
|
await assign(args[0], flags);
|
|
129
147
|
else if (subcommand === 'unassign')
|
|
130
148
|
await unassign(args[0], flags);
|
|
149
|
+
else if (subcommand === 'status')
|
|
150
|
+
await status(args[0], flags);
|
|
131
151
|
else if (subcommand === 'settings')
|
|
132
152
|
await settings(args[0], flags);
|
|
133
153
|
else if (subcommand === 'update-settings')
|
package/dist/commands/org.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { hq } from '@myapihq/sdk';
|
|
2
2
|
import { requireConfig } from '../config.js';
|
|
3
|
-
import { success, error, printJson, info } from '../output.js';
|
|
4
|
-
import { sleep } from '../utils.js';
|
|
3
|
+
import { success, error, printTable, printJson, info } from '../output.js';
|
|
4
|
+
import { sleep, formatDate } from '../utils.js';
|
|
5
5
|
export async function create(flags) {
|
|
6
6
|
if (flags.help) {
|
|
7
7
|
info('Usage: myapi org create --name="My Org" [options]\n\nOptions:\n --name Organization name (required)\n --tagline Short tagline\n --description Detailed description\n --business-sector Sector (e.g. Technology)\n --logo-url URL to logo image');
|
|
@@ -29,12 +29,17 @@ export async function create(flags) {
|
|
|
29
29
|
}
|
|
30
30
|
export async function list(flags) {
|
|
31
31
|
if (flags.help) {
|
|
32
|
-
info('Usage: myapi org list\n\nLists all organizations in your account
|
|
32
|
+
info('Usage: myapi org list\n\nLists all organizations in your account.');
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
const config = requireConfig();
|
|
36
36
|
const orgs = await hq.listOrgs(config.api_key);
|
|
37
|
-
|
|
37
|
+
const rows = orgs.map((o) => ({
|
|
38
|
+
id: o.id,
|
|
39
|
+
name: o.name,
|
|
40
|
+
created_at: o.created_at ? formatDate(o.created_at) : '',
|
|
41
|
+
}));
|
|
42
|
+
printTable(rows);
|
|
38
43
|
}
|
|
39
44
|
export async function get(id, flags) {
|
|
40
45
|
if (flags.help) {
|
package/dist/utils.d.ts
CHANGED
|
@@ -3,3 +3,8 @@ export declare function parseArgs(argv: string[]): {
|
|
|
3
3
|
flags: Record<string, string | boolean>;
|
|
4
4
|
};
|
|
5
5
|
export declare function sleep(ms: number): Promise<unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* Formats an ISO/Go timestamp string to "YYYY-MM-DD HH:mm" (UTC).
|
|
8
|
+
* Strips Go's " +0000 UTC" suffix before parsing.
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatDate(str: string): string;
|
package/dist/utils.js
CHANGED
|
@@ -28,3 +28,14 @@ export function parseArgs(argv) {
|
|
|
28
28
|
export function sleep(ms) {
|
|
29
29
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Formats an ISO/Go timestamp string to "YYYY-MM-DD HH:mm" (UTC).
|
|
33
|
+
* Strips Go's " +0000 UTC" suffix before parsing.
|
|
34
|
+
*/
|
|
35
|
+
export function formatDate(str) {
|
|
36
|
+
const clean = str.replace(' +0000 UTC', 'Z');
|
|
37
|
+
const date = new Date(clean);
|
|
38
|
+
if (isNaN(date.getTime()))
|
|
39
|
+
return str;
|
|
40
|
+
return date.toISOString().replace('T', ' ').slice(0, 16);
|
|
41
|
+
}
|
package/package.json
CHANGED
package/src/commands/auth.ts
CHANGED
|
@@ -3,6 +3,7 @@ import * as readline from 'readline';
|
|
|
3
3
|
import { loadConfig, saveConfig, addAccount, switchAccount, listAccounts } from '../config.js';
|
|
4
4
|
import { info, success, error } from '../output.js';
|
|
5
5
|
import { installSkills } from './setup.js';
|
|
6
|
+
import { hq } from '@myapihq/sdk';
|
|
6
7
|
|
|
7
8
|
const API_BASE = process.env.MYAPI_API_BASE ?? 'https://api.myapihq.com';
|
|
8
9
|
|
|
@@ -121,6 +122,13 @@ export async function whoami() {
|
|
|
121
122
|
info(`Org: ${config!.default_org ?? '(none)'}`);
|
|
122
123
|
info(`Funnel: ${config!.default_funnel ?? '(none)'}`);
|
|
123
124
|
info(`Type: ${config!.is_anonymous ? 'anonymous' : 'registered'}`);
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const bal = await hq.getBalance(config!.api_key);
|
|
128
|
+
info(`Balance: ${bal.balance_display} | Credits: ${bal.credits_display}`);
|
|
129
|
+
} catch {
|
|
130
|
+
// Balance fetch is best-effort; don't fail whoami if it errors.
|
|
131
|
+
}
|
|
124
132
|
}
|
|
125
133
|
|
|
126
134
|
// myapi auth switch — switch between saved accounts.
|
package/src/commands/billing.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as readline from 'readline';
|
|
|
2
2
|
import { hq } from '@myapihq/sdk';
|
|
3
3
|
import { requireConfig } from '../config.js';
|
|
4
4
|
import { success, error, printTable, info, printJson } from '../output.js';
|
|
5
|
+
import { formatDate } from '../utils.js';
|
|
5
6
|
|
|
6
7
|
export async function balance(flags: Record<string, string | boolean>) {
|
|
7
8
|
if (flags.help) {
|
|
@@ -10,8 +11,10 @@ export async function balance(flags: Record<string, string | boolean>) {
|
|
|
10
11
|
}
|
|
11
12
|
const config = requireConfig();
|
|
12
13
|
const result = await hq.getBalance(config.api_key);
|
|
13
|
-
|
|
14
|
+
|
|
14
15
|
const pm = result.has_payment_method ? 'yes' : 'no';
|
|
16
|
+
const accountType = config.is_anonymous ? 'anonymous' : `registered (${config.email ?? ''})`;
|
|
17
|
+
info(`Account: ${accountType}`);
|
|
15
18
|
info(`Balance: ${result.balance_display} | Credits: ${result.credits_display} | Payment method: ${pm}`);
|
|
16
19
|
}
|
|
17
20
|
|
|
@@ -22,24 +25,24 @@ export async function history(flags: Record<string, string | boolean>) {
|
|
|
22
25
|
}
|
|
23
26
|
const config = requireConfig();
|
|
24
27
|
const items = await hq.getBillingHistory(config.api_key);
|
|
25
|
-
|
|
28
|
+
|
|
26
29
|
if (flags.json) {
|
|
27
30
|
printJson(items);
|
|
28
31
|
return;
|
|
29
32
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
-
|
|
33
|
+
|
|
34
|
+
if (items.length === 0) {
|
|
35
|
+
info('No transactions yet.');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const formattedItems = items.map(item => ({
|
|
40
|
+
Type: item.type || 'unknown',
|
|
41
|
+
Amount: item.amount_display,
|
|
42
|
+
Status: item.status ? item.status.charAt(0).toUpperCase() + item.status.slice(1) : '',
|
|
43
|
+
Date: formatDate(item.created_at),
|
|
44
|
+
}));
|
|
45
|
+
|
|
43
46
|
printTable(formattedItems as unknown as Record<string, unknown>[]);
|
|
44
47
|
}
|
|
45
48
|
|
|
@@ -48,13 +51,9 @@ export async function topup(amountStr: string, flags: Record<string, string | bo
|
|
|
48
51
|
info('Usage: myapi billing topup <amount>\n\nAmount is in whole dollars (e.g. "10" charges $10).\nUse --yes to skip confirmation.\nExample: myapi billing topup 10');
|
|
49
52
|
return;
|
|
50
53
|
}
|
|
51
|
-
if (!amountStr) {
|
|
52
|
-
error("Missing amount. Usage: myapi billing topup <amount>\nExample: myapi billing topup 10");
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
54
|
const amount = Math.round(parseFloat(amountStr));
|
|
56
|
-
if (isNaN(amount) || amount <= 0) {
|
|
57
|
-
error("
|
|
55
|
+
if (!amountStr || isNaN(amount) || amount <= 0) {
|
|
56
|
+
error("Amount must be a positive whole number of dollars (e.g. myapi billing topup 10)");
|
|
58
57
|
return;
|
|
59
58
|
}
|
|
60
59
|
|
package/src/commands/domain.ts
CHANGED
|
@@ -6,12 +6,13 @@ export async function check(domainArg: string, flags: Record<string, string | bo
|
|
|
6
6
|
const config = requireConfig();
|
|
7
7
|
const orgId = (flags.org as string) || config.default_org;
|
|
8
8
|
const domain = domainArg || (config.default_domain as string);
|
|
9
|
-
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain check <domain> --org <id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
10
|
-
const res = await sdkDomain.checkDomain(config.api_key, orgId, domain);
|
|
9
|
+
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain check <domain> --org <id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
10
|
+
const res = await sdkDomain.checkDomain(config.api_key, orgId, domain) as { available: boolean; price_cents: number; price_display?: string; message?: string };
|
|
11
11
|
if (res.available) {
|
|
12
|
-
|
|
12
|
+
const price = res.price_display || `$${(res.price_cents / 100).toFixed(2)}`;
|
|
13
|
+
info(`${domain} — Available ✓ ${price}/yr`);
|
|
13
14
|
} else {
|
|
14
|
-
info(
|
|
15
|
+
info(`${domain} — ${res.message || 'Not available'} ✗`);
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -19,7 +20,7 @@ export async function register(domainArg: string, flags: Record<string, string |
|
|
|
19
20
|
const config = requireConfig();
|
|
20
21
|
const orgId = (flags.org as string) || config.default_org;
|
|
21
22
|
const domain = domainArg || (config.default_domain as string);
|
|
22
|
-
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain register <domain> --org <id> [--years <num>]\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
23
|
+
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain register <domain> --org <id> [--years <num>]\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
23
24
|
const years = parseInt(flags.years as string) || 1;
|
|
24
25
|
const res = await sdkDomain.registerDomain(config.api_key, orgId, domain, years);
|
|
25
26
|
success(`Registered ${domain}!\n${JSON.stringify(res, null, 2)}`);
|
|
@@ -29,7 +30,7 @@ export async function importDomain(domainArg: string, flags: Record<string, stri
|
|
|
29
30
|
const config = requireConfig();
|
|
30
31
|
const orgId = (flags.org as string) || config.default_org;
|
|
31
32
|
const domain = domainArg || (config.default_domain as string);
|
|
32
|
-
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain import <domain> --org <id> [--namecheap-user <user> --namecheap-key <key>]\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
33
|
+
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain import <domain> --org <id> [--namecheap-user <user> --namecheap-key <key>]\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
33
34
|
const payload: { domain: string; namecheap_api_user?: string; namecheap_api_key?: string } = { domain };
|
|
34
35
|
if (flags['namecheap-user']) payload.namecheap_api_user = flags['namecheap-user'] as string;
|
|
35
36
|
if (flags['namecheap-key']) payload.namecheap_api_key = flags['namecheap-key'] as string;
|
|
@@ -40,7 +41,7 @@ export async function importDomain(domainArg: string, flags: Record<string, stri
|
|
|
40
41
|
export async function list(flags: Record<string, string | boolean>) {
|
|
41
42
|
const config = requireConfig();
|
|
42
43
|
const orgId = (flags.org as string) || config.default_org;
|
|
43
|
-
if (!orgId) error("Missing required arguments.\nUsage: myapi domain list --org <id> [--filter=all|unassigned|org]\n(Or set a default org via: myapi config set-org <id>)");
|
|
44
|
+
if (!orgId) error("Missing required arguments.\nUsage: myapi domain list --org <id> [--filter=all|unassigned|org]\n(Or set a default org via: myapi auth config set-org <id>)");
|
|
44
45
|
const filter = flags.filter as 'all' | 'unassigned' | 'org' | undefined;
|
|
45
46
|
const domains = await sdkDomain.listDomains(config.api_key, orgId, filter);
|
|
46
47
|
printTable(domains as unknown as Record<string, unknown>[]);
|
|
@@ -51,8 +52,8 @@ export async function assign(domainArg: string, flags: Record<string, string | b
|
|
|
51
52
|
const orgId = (flags.org as string) || config.default_org;
|
|
52
53
|
const domain = domainArg || (config.default_domain as string);
|
|
53
54
|
const targetOrgId = flags.target as string;
|
|
54
|
-
if (!orgId || !domain || !targetOrgId) error("Missing required arguments.\nUsage: myapi domain assign <domain> --org <id> --target <target_org_id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
55
|
-
|
|
55
|
+
if (!orgId || !domain || !targetOrgId) error("Missing required arguments.\nUsage: myapi domain assign <domain> --org <id> --target <target_org_id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
56
|
+
await sdkDomain.assignDomain(config.api_key, orgId, domain, targetOrgId);
|
|
56
57
|
success(`Assigned ${domain} to org ${targetOrgId}`);
|
|
57
58
|
}
|
|
58
59
|
|
|
@@ -60,16 +61,30 @@ export async function unassign(domainArg: string, flags: Record<string, string |
|
|
|
60
61
|
const config = requireConfig();
|
|
61
62
|
const orgId = (flags.org as string) || config.default_org;
|
|
62
63
|
const domain = domainArg || (config.default_domain as string);
|
|
63
|
-
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain unassign <domain> --org <id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
64
|
-
|
|
64
|
+
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain unassign <domain> --org <id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
65
|
+
await sdkDomain.unassignDomain(config.api_key, orgId, domain);
|
|
65
66
|
success(`Unassigned ${domain} from org ${orgId}`);
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
export async function status(domainArg: string, flags: Record<string, string | boolean>) {
|
|
70
|
+
const config = requireConfig();
|
|
71
|
+
const orgId = (flags.org as string) || config.default_org;
|
|
72
|
+
const domain = domainArg || (config.default_domain as string);
|
|
73
|
+
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain status <domain> --org <id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
74
|
+
const res = await sdkDomain.getDomainStatus(config.api_key, orgId, domain);
|
|
75
|
+
const display: Record<string, unknown> = {
|
|
76
|
+
domain: res.domain,
|
|
77
|
+
status: res.status,
|
|
78
|
+
};
|
|
79
|
+
if (res.expires_at) display.expires_at = res.expires_at;
|
|
80
|
+
printJson(display);
|
|
81
|
+
}
|
|
82
|
+
|
|
68
83
|
export async function settings(domainArg: string, flags: Record<string, string | boolean>) {
|
|
69
84
|
const config = requireConfig();
|
|
70
85
|
const orgId = (flags.org as string) || config.default_org;
|
|
71
86
|
const domain = domainArg || (config.default_domain as string);
|
|
72
|
-
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain settings <domain> --org <id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
87
|
+
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain settings <domain> --org <id>\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
73
88
|
const res = await sdkDomain.getDomainSettings(config.api_key, orgId, domain);
|
|
74
89
|
printJson(res);
|
|
75
90
|
}
|
|
@@ -78,22 +93,22 @@ export async function updateSettings(domainArg: string, flags: Record<string, st
|
|
|
78
93
|
const config = requireConfig();
|
|
79
94
|
const orgId = (flags.org as string) || config.default_org;
|
|
80
95
|
const domain = domainArg || (config.default_domain as string);
|
|
81
|
-
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain update-settings <domain> --org <id> [--security=...] [--browser-check=...] [--purge-cache]\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
96
|
+
if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain update-settings <domain> --org <id> [--security=...] [--browser-check=...] [--purge-cache]\n(Or set defaults via: myapi auth config set-org <id> / set-domain <domain>)");
|
|
82
97
|
const payload: any = {};
|
|
83
98
|
if (flags.security) payload.security_level = flags.security as string;
|
|
84
99
|
if (flags['browser-check']) payload.browser_check = flags['browser-check'] as string;
|
|
85
100
|
if (flags['purge-cache']) payload.purge_cache = true;
|
|
86
|
-
|
|
101
|
+
|
|
87
102
|
const res = await sdkDomain.updateDomainSettings(config.api_key, orgId, domain, payload);
|
|
88
103
|
success(`Updated settings for ${domain}!\n${JSON.stringify(res, null, 2)}`);
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
|
|
92
107
|
if (!subcommand || (flags.help && !subcommand)) {
|
|
93
|
-
info('Usage: myapi domain <subcommand>\n\nSubcommands:\n list List domains\n check Check domain availability\n register Register a domain\n import Import an existing domain\n assign Assign domain to org\n unassign Unassign domain from its current org\n settings Get domain settings\n update-settings Update domain settings\n\nNote: All domain commands require the --org <id> flag.');
|
|
108
|
+
info('Usage: myapi domain <subcommand>\n\nSubcommands:\n list List domains\n check Check domain availability\n register Register a domain\n import Import an existing domain\n assign Assign domain to org\n unassign Unassign domain from its current org\n status Get domain status\n settings Get domain settings\n update-settings Update domain settings\n\nNote: All domain commands require the --org <id> flag.');
|
|
94
109
|
return;
|
|
95
110
|
}
|
|
96
|
-
|
|
111
|
+
|
|
97
112
|
if (flags.help) {
|
|
98
113
|
if (subcommand === 'list') info('Usage: myapi domain list --org <id> [--filter=all|unassigned|org]\n\nLists all registered domains in your account.\n --filter=all Lists all domains owned by the account.\n --filter=unassigned Lists domains not assigned to an org.\n --filter=org (Default) Lists domains assigned to the current org.');
|
|
99
114
|
else if (subcommand === 'check') info('Usage: myapi domain check <domain> --org <id>\n\nChecks if a domain name is available for registration.');
|
|
@@ -101,6 +116,7 @@ export async function run(subcommand: string | undefined, args: string[], flags:
|
|
|
101
116
|
else if (subcommand === 'import') info('Usage: myapi domain import <domain> --org <id> --namecheap-user <user> --namecheap-key <key>\n\nImports an existing domain from Namecheap.');
|
|
102
117
|
else if (subcommand === 'assign') info('Usage: myapi domain assign <domain> --org <id> --target <target_org_id>\n\nAssigns a domain to a different organization.');
|
|
103
118
|
else if (subcommand === 'unassign') info('Usage: myapi domain unassign <domain> --org <id>\n\nUnassigns a domain from its current organization.');
|
|
119
|
+
else if (subcommand === 'status') info('Usage: myapi domain status <domain> --org <id>\n\nGets the registration status of a domain.');
|
|
104
120
|
else if (subcommand === 'settings') info('Usage: myapi domain settings <domain> --org <id>\n\nGets the DNS settings and configuration for a domain.');
|
|
105
121
|
else if (subcommand === 'update-settings') info('Usage: myapi domain update-settings <domain> --org <id> [--security=essentially_off|medium|high|under_attack] [--browser-check=on|off] [--purge-cache]\n\nUpdates edge settings for a domain.');
|
|
106
122
|
return;
|
|
@@ -112,6 +128,7 @@ export async function run(subcommand: string | undefined, args: string[], flags:
|
|
|
112
128
|
else if (subcommand === 'import') await importDomain(args[0], flags);
|
|
113
129
|
else if (subcommand === 'assign') await assign(args[0], flags);
|
|
114
130
|
else if (subcommand === 'unassign') await unassign(args[0], flags);
|
|
131
|
+
else if (subcommand === 'status') await status(args[0], flags);
|
|
115
132
|
else if (subcommand === 'settings') await settings(args[0], flags);
|
|
116
133
|
else if (subcommand === 'update-settings') await updateSettings(args[0], flags);
|
|
117
134
|
else error(`Unknown subcommand: ${subcommand}. Run "myapi domain --help" for a list of valid subcommands.`);
|
package/src/commands/org.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { hq } from '@myapihq/sdk';
|
|
2
2
|
import { requireConfig } from '../config.js';
|
|
3
3
|
import { success, error, printTable, printJson, info } from '../output.js';
|
|
4
|
-
import { sleep } from '../utils.js';
|
|
4
|
+
import { sleep, formatDate } from '../utils.js';
|
|
5
5
|
|
|
6
6
|
export async function create(flags: Record<string, string | boolean>) {
|
|
7
7
|
if (flags.help) {
|
|
@@ -18,7 +18,7 @@ export async function create(flags: Record<string, string | boolean>) {
|
|
|
18
18
|
if (flags.description) payload.description = flags.description as string;
|
|
19
19
|
if (flags['business-sector']) payload.business_sector = flags['business-sector'] as string;
|
|
20
20
|
if (flags['logo-url']) payload.logo_url = flags['logo-url'] as string;
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
const org = await hq.createOrg(config.api_key, payload);
|
|
23
23
|
success(`Org created! ID: ${org.id}, Name: ${org.name}`);
|
|
24
24
|
if (org.preview_subdomain) {
|
|
@@ -28,12 +28,17 @@ export async function create(flags: Record<string, string | boolean>) {
|
|
|
28
28
|
|
|
29
29
|
export async function list(flags: Record<string, string | boolean>) {
|
|
30
30
|
if (flags.help) {
|
|
31
|
-
info('Usage: myapi org list\n\nLists all organizations in your account
|
|
31
|
+
info('Usage: myapi org list\n\nLists all organizations in your account.');
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
const config = requireConfig();
|
|
35
35
|
const orgs = await hq.listOrgs(config.api_key);
|
|
36
|
-
|
|
36
|
+
const rows = orgs.map((o: any) => ({
|
|
37
|
+
id: o.id,
|
|
38
|
+
name: o.name,
|
|
39
|
+
created_at: o.created_at ? formatDate(o.created_at) : '',
|
|
40
|
+
}));
|
|
41
|
+
printTable(rows as unknown as Record<string, unknown>[]);
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
export async function get(id: string, flags: Record<string, string | boolean>) {
|
|
@@ -75,19 +80,19 @@ export async function importOrg(args: string[], flags: Record<string, string | b
|
|
|
75
80
|
const config = requireConfig();
|
|
76
81
|
const domain = args[0] || (config.default_domain as string);
|
|
77
82
|
const orgId = (flags.org as string) || config.default_org;
|
|
78
|
-
|
|
83
|
+
|
|
79
84
|
if (!domain || !orgId) {
|
|
80
85
|
error("Missing required arguments.\nUsage: myapi org import <domain> --org <id>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
|
|
81
86
|
return;
|
|
82
87
|
}
|
|
83
|
-
|
|
88
|
+
|
|
84
89
|
const result = await hq.importOrg(config.api_key, orgId, domain);
|
|
85
90
|
const importId = result.job_id;
|
|
86
|
-
|
|
91
|
+
|
|
87
92
|
process.stdout.write("Importing ");
|
|
88
93
|
const chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
89
94
|
let i = 0;
|
|
90
|
-
|
|
95
|
+
|
|
91
96
|
while (true) {
|
|
92
97
|
const status = await hq.getOrgImportStatus(config.api_key, importId);
|
|
93
98
|
if (status.status === 'awaiting_confirm') {
|
|
@@ -101,7 +106,7 @@ export async function importOrg(args: string[], flags: Record<string, string | b
|
|
|
101
106
|
process.stdout.write(`\rImporting ${chars[i++ % chars.length]}`);
|
|
102
107
|
await sleep(3000);
|
|
103
108
|
}
|
|
104
|
-
|
|
109
|
+
|
|
105
110
|
const org = await hq.confirmOrgImport(config.api_key, importId);
|
|
106
111
|
success(`Import complete! Org ID: ${org.id}`);
|
|
107
112
|
}
|
package/src/utils.ts
CHANGED
|
@@ -28,3 +28,14 @@ export function parseArgs(argv: string[]) {
|
|
|
28
28
|
export function sleep(ms: number) {
|
|
29
29
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Formats an ISO/Go timestamp string to "YYYY-MM-DD HH:mm" (UTC).
|
|
34
|
+
* Strips Go's " +0000 UTC" suffix before parsing.
|
|
35
|
+
*/
|
|
36
|
+
export function formatDate(str: string): string {
|
|
37
|
+
const clean = str.replace(' +0000 UTC', 'Z');
|
|
38
|
+
const date = new Date(clean);
|
|
39
|
+
if (isNaN(date.getTime())) return str;
|
|
40
|
+
return date.toISOString().replace('T', ' ').slice(0, 16);
|
|
41
|
+
}
|