@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.
@@ -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() {
@@ -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
- const formattedItems = items.map(item => {
27
- const cleanDate = item.created_at.replace(' +0000 UTC', 'Z');
28
- const date = new Date(cleanDate);
29
- const dateStr = isNaN(date.getTime()) ? item.created_at : date.toLocaleString();
30
- return {
31
- Type: item.type || 'unknown',
32
- Amount: item.amount_display,
33
- Status: item.status ? item.status.charAt(0).toUpperCase() + item.status.slice(1) : '',
34
- Date: dateStr,
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("Invalid amount. Must be a positive whole number of dollars (e.g. 10)");
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>;
@@ -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
- info(`${domain} Available ✓ Price: $${(res.price_cents / 100).toFixed(2)}/yr`);
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(`Not available ✗`);
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
- const res = await sdkDomain.assignDomain(config.api_key, orgId, domain, targetOrgId);
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
- const res = await sdkDomain.unassignDomain(config.api_key, orgId, domain);
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')
@@ -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 as JSON.');
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
- printJson(orgs);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myapihq/cli",
3
- "version": "1.0.37",
3
+ "version": "1.0.39",
4
4
  "description": "MyAPI command-line interface",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -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.
@@ -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
- const formattedItems = items.map(item => {
32
- const cleanDate = item.created_at.replace(' +0000 UTC', 'Z');
33
- const date = new Date(cleanDate);
34
- const dateStr = isNaN(date.getTime()) ? item.created_at : date.toLocaleString();
35
- return {
36
- Type: item.type || 'unknown',
37
- Amount: item.amount_display,
38
- Status: item.status ? item.status.charAt(0).toUpperCase() + item.status.slice(1) : '',
39
- Date: dateStr,
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("Invalid amount. Must be a positive whole number of dollars (e.g. 10)");
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
 
@@ -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
- info(`${domain} Available ✓ Price: $${(res.price_cents / 100).toFixed(2)}/yr`);
12
+ const price = res.price_display || `$${(res.price_cents / 100).toFixed(2)}`;
13
+ info(`${domain} — Available ✓ ${price}/yr`);
13
14
  } else {
14
- info(`Not available ✗`);
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
- const res = await sdkDomain.assignDomain(config.api_key, orgId, domain, targetOrgId);
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
- const res = await sdkDomain.unassignDomain(config.api_key, orgId, domain);
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.`);
@@ -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 as JSON.');
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
- printJson(orgs);
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
+ }