@myapihq/cli 2.16.2 → 2.16.3

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.
@@ -30,5 +30,6 @@ export declare function retryProvisioning(domainArg: string, flags: Flags): Prom
30
30
  export declare function mailServerResync(domainArg: string, flags: Flags): Promise<void>;
31
31
  export declare function settings(domainArg: string, flags: Flags): Promise<void>;
32
32
  export declare function updateSettings(domainArg: string, flags: Flags): Promise<void>;
33
+ export declare const NESTED_SUBCOMMAND_USAGE: Record<string, Record<string, string>>;
33
34
  export declare const SUBCOMMAND_USAGE: Record<string, string>;
34
35
  export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -549,6 +549,19 @@ Examples:
549
549
  --content 'v=spf1 include:_spf.mailersend.net include:_spf.google.com ~all'
550
550
  myapi domain records create x80security.com --type TXT --name @ \\
551
551
  --content 'google-site-verification=...'`;
552
+ // `domain records` is a second level inside a flat command module, so its
553
+ // verbs are invisible to anything reading SUBCOMMAND_USAGE alone — the command
554
+ // manifest could confirm `domain records` and nothing under it. Declared here
555
+ // so `domain records list` can be told apart from `domain records lst`.
556
+ export const NESTED_SUBCOMMAND_USAGE = {
557
+ records: {
558
+ 'create': 'myapi domain records create <domain> --type <T> --name <n> --content <c> [--ttl <n>] [--priority <n>] [--proxied]',
559
+ 'delete': 'myapi domain records delete <domain> <record-id> [--yes]',
560
+ 'get': 'myapi domain records get <domain> <record-id>',
561
+ 'list': 'myapi domain records list <domain> [--type A|AAAA|CNAME|MX|TXT]',
562
+ 'update': 'myapi domain records update <domain> <record-id> [--content ...] [--ttl ...] [--priority ...] [--proxied]',
563
+ },
564
+ };
552
565
  async function recordsRun(sub, args, flags) {
553
566
  if (!sub || (flags.help && !sub)) {
554
567
  info(RECORDS_HELP);
@@ -1,4 +1,5 @@
1
1
  import type { Flags } from '../../helpers.js';
2
2
  import type { Exposes } from '../../exposes.js';
3
3
  export declare const EXPOSES: Exposes;
4
+ export declare const SUBCOMMAND_USAGE: Record<string, string>;
4
5
  export declare function run(sub: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -93,7 +93,7 @@ async function del(address, _flags) {
93
93
  await sdkEmail.deleteMailbox(config.api_key, address);
94
94
  success(`Mailbox deleted: ${address}`);
95
95
  }
96
- const USAGE = {
96
+ export const SUBCOMMAND_USAGE = {
97
97
  'create': `myapi email mailbox create <user@domain> [--display-name <name>]
98
98
  myapi email mailbox create --username <u> --domain <d> [--display-name <name>]
99
99
 
@@ -131,7 +131,7 @@ Subcommands:
131
131
  return;
132
132
  }
133
133
  if (flags.help) {
134
- const usage = USAGE[sub];
134
+ const usage = SUBCOMMAND_USAGE[sub];
135
135
  if (usage)
136
136
  info(`Usage: ${usage}`);
137
137
  else
@@ -1,4 +1,5 @@
1
1
  import type { Flags } from '../../helpers.js';
2
2
  import type { Exposes } from '../../exposes.js';
3
3
  export declare const EXPOSES: Exposes;
4
+ export declare const SUBCOMMAND_USAGE: Record<string, string>;
4
5
  export declare function run(sub: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -108,7 +108,7 @@ async function get(messageId, flags) {
108
108
  const res = await sdkEmail.getMessage(config.api_key, messageId, flags.address);
109
109
  printJson(res);
110
110
  }
111
- const USAGE = {
111
+ export const SUBCOMMAND_USAGE = {
112
112
  'send': 'myapi email message send --from <email> --to <email> --subject <str> [--body <str> | --html <str> | --template-id <id> [--template-vars <json>]]',
113
113
  'status': 'myapi email message status <message_id>',
114
114
  'sent': 'myapi email message sent [--limit <n>] [--offset <n>]',
@@ -130,7 +130,7 @@ Subcommands:
130
130
  return;
131
131
  }
132
132
  if (flags.help) {
133
- const usage = USAGE[sub];
133
+ const usage = SUBCOMMAND_USAGE[sub];
134
134
  if (usage)
135
135
  info(`Usage: ${usage}`);
136
136
  else
@@ -1,4 +1,5 @@
1
1
  import { type Flags } from '../../helpers.js';
2
2
  import type { Exposes } from '../../exposes.js';
3
3
  export declare const EXPOSES: Exposes;
4
+ export declare const SUBCOMMAND_USAGE: Record<string, string>;
4
5
  export declare function run(sub: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -118,7 +118,7 @@ async function del(id, flags) {
118
118
  await sdkEmail.deleteTemplate(config.api_key, orgId, id);
119
119
  success(`Deleted template ${id}`);
120
120
  }
121
- const USAGE = {
121
+ export const SUBCOMMAND_USAGE = {
122
122
  'generate': `myapi email template generate <name> --prompt <str> [--org <id>]
123
123
  myapi email template generate --name <name> --prompt <str> [--org <id>]
124
124
 
@@ -147,7 +147,7 @@ All commands accept --org <id> (or set default: myapi config set-org <id>).`);
147
147
  return;
148
148
  }
149
149
  if (flags.help) {
150
- const usage = USAGE[sub];
150
+ const usage = SUBCOMMAND_USAGE[sub];
151
151
  if (usage)
152
152
  info(`Usage: ${usage}`);
153
153
  else
@@ -4,4 +4,5 @@ import type { Exposes } from '../../exposes.js';
4
4
  export declare const EXPOSES: Exposes;
5
5
  export declare const SCHEMA: FlagSchema;
6
6
  export declare const VERIFY_HELP = "Usage: myapi email verify <email> [--org <id>] [--json]\n myapi email verify bulk [--quick] [--org <id>] < emails.txt\n myapi email verify job <job_id> [--org <id>] [--json]\n\nSingle-address verification (sync): syntax + DNS + Microsoft probe.\nReturns a verdict in <1s for ~50% of inputs; the rest get\nverdict='unknown' with smtp_recommended=true.\n\nBulk verification (async): reads up to 500 addresses from stdin (one per\nline), starts a job, and prints a job_id. It runs the cheap verdict on\nevery address then SMTP-probes the uncertain ones. --quick skips the\ncatch-all check (faster, but catch-all domains aren't flagged). Poll with\n\"myapi email verify job <job_id>\".\n";
7
+ export declare const SUBCOMMAND_USAGE: Record<string, string>;
7
8
  export declare function run(arg: string | undefined, rest: string[], flags?: Flags): Promise<void>;
@@ -22,6 +22,13 @@ every address then SMTP-probes the uncertain ones. --quick skips the
22
22
  catch-all check (faster, but catch-all domains aren't flagged). Poll with
23
23
  "myapi email verify job <job_id>".
24
24
  `;
25
+ // `email verify` takes an address directly, so these are its only two real
26
+ // subcommands. Listed so the command manifest — and the site-copy checker
27
+ // that reads it — can tell `verify bulk` from a typo.
28
+ export const SUBCOMMAND_USAGE = {
29
+ 'bulk': 'myapi email verify bulk [--quick] [--org <id>] < emails.txt',
30
+ 'job': 'myapi email verify job <job_id> [--org <id>] [--json]',
31
+ };
25
32
  async function readStdinLines() {
26
33
  if (process.stdin.isTTY) {
27
34
  error('No input on stdin. Pipe a newline-separated list of addresses:\n myapi email verify bulk < emails.txt');
@@ -1,4 +1,5 @@
1
1
  import type { Flags } from '../../helpers.js';
2
2
  import type { Exposes } from '../../exposes.js';
3
3
  export declare const EXPOSES: Exposes;
4
+ export declare const SUBCOMMAND_USAGE: Record<string, string>;
4
5
  export declare function run(sub: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -8,13 +8,21 @@ export const EXPOSES = [
8
8
  'POST /email/warmup/stop',
9
9
  'GET /email/warmup/stats/{address}',
10
10
  ];
11
+ export const SUBCOMMAND_USAGE = {
12
+ 'start': 'myapi email warmup start --address <email>',
13
+ 'pause': 'myapi email warmup pause --address <email>',
14
+ 'resume': 'myapi email warmup resume --address <email>',
15
+ 'stop': 'myapi email warmup stop --address <email>',
16
+ 'stats': 'myapi email warmup stats --address <email>',
17
+ };
11
18
  export async function run(sub, args, flags) {
12
19
  if (!sub || (flags.help && !sub)) {
13
- info('Usage: myapi email warmup <start|pause|resume|stop|stats> --address <email>');
20
+ info(`Usage: myapi email warmup <${Object.keys(SUBCOMMAND_USAGE).join('|')}> --address <email>`);
14
21
  return;
15
22
  }
16
23
  if (flags.help) {
17
- info(`Usage: myapi email warmup ${sub} --address <email>`);
24
+ const usage = SUBCOMMAND_USAGE[sub];
25
+ info(usage ? `Usage: ${usage}` : `Unknown warmup subcommand: ${sub}. Run "myapi email warmup --help".`);
18
26
  return;
19
27
  }
20
28
  const config = requireConfig();
@@ -41,10 +41,17 @@ const MODULE_ALIAS = {
41
41
  };
42
42
  // Commands implemented inline in index.ts, with no module of their own.
43
43
  const INLINE = new Set(['completion', 'help', 'install-skills', 'whoami', 'login', 'setup', 'status', 'update', 'doctor']);
44
- async function usageMapFor(file) {
44
+ async function registriesFor(file) {
45
45
  const mod = await import(pathToFileURL(file).href).catch(() => null);
46
46
  const usage = mod?.SUBCOMMAND_USAGE;
47
- return usage && typeof usage === 'object' ? usage : null;
47
+ const nested = mod?.NESTED_SUBCOMMAND_USAGE;
48
+ return {
49
+ usage: usage && typeof usage === 'object' ? usage : null,
50
+ // A third level inside a flat module — `domain records list`. Namespaces
51
+ // that get a directory of their own (email/, crm/) express this by file
52
+ // layout instead and need no such export.
53
+ nested: nested && typeof nested === 'object' ? nested : null,
54
+ };
48
55
  }
49
56
  // Shipped code runs from dist/ (.js); the test suite runs the sources (.ts).
50
57
  // Matching only .js made the enrichment pass find nothing under vitest and
@@ -97,7 +104,7 @@ export async function buildManifest(version) {
97
104
  if (!isModule(f))
98
105
  continue;
99
106
  const group = f.replace(MODULE_RE, '');
100
- const usage = await usageMapFor(path.join(HERE, ns, f));
107
+ const { usage } = await registriesFor(path.join(HERE, ns, f));
101
108
  if (!usage)
102
109
  continue;
103
110
  if (group === 'index') {
@@ -116,8 +123,8 @@ export async function buildManifest(version) {
116
123
  continue;
117
124
  const base = entry.name.replace(MODULE_RE, '');
118
125
  const cmd = MODULE_ALIAS[base] ?? base;
119
- const usage = await usageMapFor(path.join(HERE, entry.name));
120
- if (!usage)
126
+ const { usage, nested } = await registriesFor(path.join(HERE, entry.name));
127
+ if (!usage && !nested)
121
128
  continue;
122
129
  if (!COMMANDS.includes(cmd)) {
123
130
  // Not fatal: `verify.js` backs `email verify`, not a top-level command.
@@ -125,8 +132,13 @@ export async function buildManifest(version) {
125
132
  warnings.push(`module "${base}.js" publishes subcommands but "${cmd}" is not a top-level command`);
126
133
  continue;
127
134
  }
128
- for (const [sub, u] of Object.entries(usage))
135
+ for (const [sub, u] of Object.entries(usage ?? {}))
129
136
  add(`${cmd} ${sub}`, u);
137
+ for (const [sub, subs] of Object.entries(nested ?? {})) {
138
+ add(`${cmd} ${sub}`);
139
+ for (const [leaf, u] of Object.entries(subs))
140
+ add(`${cmd} ${sub} ${leaf}`, u);
141
+ }
130
142
  }
131
143
  // The spine alone always yields a plausible-looking manifest, so "the
132
144
  // enrichment pass found nothing" is invisible unless it is stated. It means
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@myapihq/cli",
3
3
  "license": "Apache-2.0",
4
- "version": "2.16.2",
4
+ "version": "2.16.3",
5
5
  "description": "MyAPI command-line interface",
6
6
  "repository": {
7
7
  "type": "git",
@@ -46,7 +46,7 @@
46
46
  "lint:skills:strict": "node scripts/copy-skills.js && node scripts/lint-skills.js --strict"
47
47
  },
48
48
  "dependencies": {
49
- "@myapihq/sdk": "^2.16.2"
49
+ "@myapihq/sdk": "^2.16.3"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^25.6.0",