@myapihq/cli 1.0.84 → 1.1.0-wip.1

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.
Files changed (77) hide show
  1. package/dist/commands/auth.d.ts +8 -3
  2. package/dist/commands/auth.js +84 -60
  3. package/dist/commands/billing.d.ts +8 -4
  4. package/dist/commands/billing.js +46 -27
  5. package/dist/commands/config.d.ts +8 -5
  6. package/dist/commands/config.js +52 -27
  7. package/dist/commands/domain.d.ts +12 -9
  8. package/dist/commands/domain.js +124 -86
  9. package/dist/commands/email/campaign.d.ts +2 -0
  10. package/dist/commands/email/campaign.js +152 -0
  11. package/dist/commands/email/index.d.ts +4 -0
  12. package/dist/commands/email/index.js +98 -0
  13. package/dist/commands/email/mailbox.d.ts +2 -0
  14. package/dist/commands/email/mailbox.js +88 -0
  15. package/dist/commands/email/message.d.ts +2 -0
  16. package/dist/commands/email/message.js +115 -0
  17. package/dist/commands/email/template.d.ts +2 -0
  18. package/dist/commands/email/template.js +106 -0
  19. package/dist/commands/email/warmup.d.ts +2 -0
  20. package/dist/commands/email/warmup.js +43 -0
  21. package/dist/commands/email.d.ts +4 -12
  22. package/dist/commands/email.js +528 -146
  23. package/dist/commands/funnel.d.ts +10 -7
  24. package/dist/commands/funnel.js +79 -55
  25. package/dist/commands/image.js +25 -15
  26. package/dist/commands/keys.d.ts +8 -3
  27. package/dist/commands/keys.js +71 -35
  28. package/dist/commands/org.d.ts +9 -5
  29. package/dist/commands/org.js +100 -64
  30. package/dist/commands/pixel.js +23 -11
  31. package/dist/commands/setup.d.ts +3 -2
  32. package/dist/commands/setup.js +160 -165
  33. package/dist/commands/storage.js +25 -15
  34. package/dist/commands/update.d.ts +2 -1
  35. package/dist/commands/update.js +5 -0
  36. package/dist/commands/url.js +19 -7
  37. package/dist/commands/webhook.d.ts +8 -5
  38. package/dist/commands/webhook.js +70 -38
  39. package/dist/commands/workflow.d.ts +13 -7
  40. package/dist/commands/workflow.js +179 -58
  41. package/dist/config.js +10 -5
  42. package/dist/flags.d.ts +8 -0
  43. package/dist/flags.js +88 -0
  44. package/dist/flags.test.d.ts +1 -0
  45. package/dist/flags.test.js +73 -0
  46. package/dist/helpers.d.ts +6 -0
  47. package/dist/helpers.js +31 -0
  48. package/dist/index.js +98 -109
  49. package/dist/output.d.ts +12 -1
  50. package/dist/output.js +16 -6
  51. package/dist/prompt.d.ts +24 -0
  52. package/dist/prompt.js +41 -0
  53. package/dist/skills/my-email-api/README.md +45 -0
  54. package/dist/skills/my-email-api/SKILL.md +104 -0
  55. package/dist/skills/my-email-api/claude/.claude-plugin/plugin.json +6 -0
  56. package/dist/skills/my-email-api/make/.gitkeep +0 -0
  57. package/dist/skills/my-email-api/n8n/.gitkeep +0 -0
  58. package/dist/skills/my-email-api/openapi/.gitkeep +0 -0
  59. package/dist/skills/my-webhook-api/README.md +40 -0
  60. package/dist/skills/my-webhook-api/SKILL.md +138 -0
  61. package/dist/skills/my-webhook-api/claude/.claude-plugin/plugin.json +6 -0
  62. package/dist/skills/my-webhook-api/make/.gitkeep +0 -0
  63. package/dist/skills/my-webhook-api/n8n/.gitkeep +0 -0
  64. package/dist/skills/my-webhook-api/openapi/.gitkeep +0 -0
  65. package/dist/skills/my-workflow-api/README.md +36 -0
  66. package/dist/skills/my-workflow-api/SKILL.md +156 -0
  67. package/dist/skills/my-workflow-api/claude/.claude-plugin/plugin.json +6 -0
  68. package/dist/skills/my-workflow-api/make/.gitkeep +0 -0
  69. package/dist/skills/my-workflow-api/n8n/.gitkeep +0 -0
  70. package/dist/skills/my-workflow-api/openapi/.gitkeep +0 -0
  71. package/dist/utils.d.ts +26 -4
  72. package/dist/utils.js +32 -33
  73. package/dist/utils.test.d.ts +1 -0
  74. package/dist/utils.test.js +48 -0
  75. package/package.json +9 -4
  76. package/dist/commands/account.d.ts +0 -4
  77. package/dist/commands/account.js +0 -80
@@ -1,7 +1,10 @@
1
- export declare function list(flags: Record<string, string | boolean>): Promise<void>;
2
- export declare function create(flags: Record<string, string | boolean>): Promise<void>;
3
- export declare function get(id: string, flags: Record<string, string | boolean>): Promise<void>;
4
- export declare function del(id: string, flags: Record<string, string | boolean>): Promise<void>;
5
- export declare function push(slug: string, flags: Record<string, string | boolean>): Promise<void>;
6
- export declare function verify(id: string, flags: Record<string, string | boolean>): Promise<void>;
7
- export declare function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>): Promise<void>;
1
+ import type { FlagSchema } from '../flags.js';
2
+ import { type Flags } from '../helpers.js';
3
+ export declare const SCHEMA: FlagSchema;
4
+ export declare function list(flags: Flags): Promise<void>;
5
+ export declare function create(flags: Flags): Promise<void>;
6
+ export declare function get(id: string, flags: Flags): Promise<void>;
7
+ export declare function del(id: string, flags: Flags): Promise<void>;
8
+ export declare function push(slug: string, flags: Flags): Promise<void>;
9
+ export declare function verify(id: string, flags: Flags): Promise<void>;
10
+ export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -1,12 +1,16 @@
1
1
  import { funnel as sdkFunnel, hq } from '@myapihq/sdk';
2
- import { requireConfig, saveConfig } from '../config.js';
2
+ import { requireConfig } from '../config.js';
3
3
  import { success, error, printTable, info, printJson } from '../output.js';
4
4
  import { formatDate } from '../utils.js';
5
+ import { requireOrg } from '../helpers.js';
6
+ export const SCHEMA = {
7
+ org: 'string',
8
+ funnel: 'string',
9
+ slug: 'string',
10
+ };
5
11
  export async function list(flags) {
6
12
  const config = requireConfig();
7
- const orgId = flags.org || config.default_org;
8
- if (!orgId)
9
- error("Missing required arguments.\nUsage: myapi funnel list --org <id>\n(Or set defaults via: myapi config set-org <id>)");
13
+ const orgId = requireOrg(flags, config, 'myapi funnel list [--org <id>]');
10
14
  const funnels = await sdkFunnel.listFunnels(config.api_key, orgId);
11
15
  if (flags.json) {
12
16
  printJson(funnels);
@@ -18,18 +22,14 @@ export async function list(flags) {
18
22
  created_at: formatDate(f.created_at),
19
23
  updated_at: formatDate(f.updated_at),
20
24
  }));
21
- if (rows.length === 0) {
22
- info('No funnels found. Create one with: myapi funnel create');
23
- return;
24
- }
25
- printTable(rows);
25
+ printTable(rows, {
26
+ flags,
27
+ empty: 'No funnels found. Create one with: myapi funnel create',
28
+ });
26
29
  }
27
30
  export async function create(flags) {
28
31
  const config = requireConfig();
29
- const orgId = flags.org || config.default_org;
30
- if (!orgId) {
31
- error("Missing required arguments.\nUsage: myapi funnel create --org <id>\n(Or set defaults via: myapi config set-org <id>)");
32
- }
32
+ const orgId = requireOrg(flags, config, 'myapi funnel create [--org <id>]');
33
33
  const result = await sdkFunnel.createFunnel(config.api_key, orgId);
34
34
  success(`Funnel created! ID: ${result.funnel.id}`);
35
35
  if (result.domain_url)
@@ -39,10 +39,14 @@ export async function create(flags) {
39
39
  }
40
40
  export async function get(id, flags) {
41
41
  const config = requireConfig();
42
- const orgId = flags.org || config.default_org;
43
- if (!orgId || !id)
44
- error("Missing required arguments.\nUsage: myapi funnel get <id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
42
+ const orgId = requireOrg(flags, config, 'myapi funnel get <id> [--org <id>]');
43
+ if (!id)
44
+ error('Missing required arguments.\nUsage: myapi funnel get <id> [--org <id>]');
45
45
  const raw = await sdkFunnel.getFunnel(config.api_key, orgId, id);
46
+ // Backend response shape varies between two layouts:
47
+ // 1) { funnel: {...}, subdomain_url, domain_url } (newer, wrapped)
48
+ // 2) { id, ..., subdomain_url, domain_url } (older, flat)
49
+ // Coalesce both so this works regardless of which shape we get back.
46
50
  const funnel = raw.funnel ?? raw;
47
51
  const subdomain_url = raw.subdomain_url ?? funnel.subdomain_url;
48
52
  const domain_url = raw.domain_url ?? funnel.domain_url;
@@ -64,27 +68,28 @@ export async function get(id, flags) {
64
68
  }
65
69
  export async function del(id, flags) {
66
70
  const config = requireConfig();
67
- const orgId = flags.org || config.default_org;
68
- if (!orgId || !id)
69
- error("Missing required arguments.\nUsage: myapi funnel delete <id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
71
+ const orgId = requireOrg(flags, config, 'myapi funnel delete <id> [--org <id>]');
72
+ if (!id)
73
+ error('Missing required arguments.\nUsage: myapi funnel delete <id> [--org <id>]');
70
74
  await sdkFunnel.deleteFunnel(config.api_key, orgId, id);
71
75
  success(`Funnel ${id} deleted`);
72
76
  }
73
77
  export async function push(slug, flags) {
74
78
  const config = requireConfig();
75
- const orgId = flags.org || config.default_org;
76
- if (!orgId)
77
- error("Missing org. Set a default with: myapi config set-org <id>");
79
+ const orgId = requireOrg(flags, config, 'myapi funnel push [slug] [--funnel <id>] [--org <id>]');
78
80
  const rawSlug = slug || flags.slug || '/';
79
81
  const finalSlug = rawSlug.startsWith('/') ? rawSlug : `/${rawSlug}`;
80
82
  let funnelId = flags.funnel || config.default_funnel;
83
+ let resolvedFromOrg = false;
81
84
  if (!funnelId) {
82
85
  const existing = await sdkFunnel.listFunnels(config.api_key, orgId);
83
86
  if (existing.length === 0)
84
- error("No funnel found for this org. Try: myapi auth config set-org <id>");
87
+ error('No funnel found for this org. Create one with: myapi funnel create');
88
+ if (existing.length > 1) {
89
+ error(`Multiple funnels exist for this org and no default is set.\nPick one with --funnel <id>, or set a default:\n myapi config set-funnel <id>\n\nFunnels:\n${existing.map(f => ` ${f.id}`).join('\n')}`);
90
+ }
85
91
  funnelId = existing[0].id;
86
- config.default_funnel = funnelId;
87
- saveConfig(config);
92
+ resolvedFromOrg = true;
88
93
  }
89
94
  if (process.stdin.isTTY) {
90
95
  error("No content provided via stdin. Use a pipe or file:\n echo '<h1>Hello</h1>' | myapi funnel push /\n cat page.html | myapi funnel push /about");
@@ -100,6 +105,9 @@ export async function push(slug, flags) {
100
105
  error("No content provided via stdin. Usage: echo '<h1>Hello</h1>' | myapi funnel push [slug]");
101
106
  const result = await sdkFunnel.pushFunnelPage(config.api_key, orgId, funnelId, { slug: finalSlug, html });
102
107
  success(`Pushed page to ${finalSlug}`);
108
+ if (resolvedFromOrg) {
109
+ info(`(Used the org's only funnel: ${funnelId}. Set a default with: myapi config set-funnel ${funnelId})`);
110
+ }
103
111
  if (result?.url) {
104
112
  info(`Preview: ${result.url}`);
105
113
  }
@@ -112,47 +120,63 @@ export async function push(slug, flags) {
112
120
  }
113
121
  export async function verify(id, flags) {
114
122
  const config = requireConfig();
115
- const orgId = flags.org || config.default_org;
116
- if (!orgId || !id)
117
- error("Missing required arguments.\nUsage: myapi funnel verify <id> --org <id> [--slug <slug>]\n(Or set defaults via: myapi config set-org <id>)");
123
+ const orgId = requireOrg(flags, config, 'myapi funnel verify <id> [--slug <slug>] [--org <id>]');
124
+ if (!id)
125
+ error('Missing required arguments.\nUsage: myapi funnel verify <id> [--slug <slug>] [--org <id>]');
118
126
  const opts = {};
119
127
  if (flags.slug)
120
128
  opts.slug = flags.slug;
121
129
  const v = await sdkFunnel.verifyFunnel(config.api_key, orgId, id, opts);
122
130
  printJson(v);
123
131
  }
132
+ // ── Dispatcher ───────────────────────────────────────────────────────────────
133
+ const SUBCOMMAND_USAGE = {
134
+ 'list': 'myapi funnel list [--org <id>] [--json]',
135
+ 'create': 'myapi funnel create [--org <id>]',
136
+ 'get': 'myapi funnel get <id> [--org <id>] [--json]',
137
+ 'delete': 'myapi funnel delete <id> [--org <id>]',
138
+ 'push': `myapi funnel push [slug] [--funnel <id>] [--slug <path>] [--org <id>] < page.html
139
+
140
+ Reads HTML from stdin and publishes to <slug> on your funnel. Funnel is resolved
141
+ from --funnel, the default funnel, or (only if the org has exactly one) auto-picked.
142
+
143
+ Examples:
144
+ echo '<h1>Hello</h1>' | myapi funnel push /
145
+ cat about.html | myapi funnel push /about
146
+ myapi funnel push < index.html
147
+ cat p.html | myapi funnel push /pricing --funnel <uuid>`,
148
+ 'verify': 'myapi funnel verify <id> [--slug <slug>] [--org <id>]',
149
+ };
124
150
  export async function run(subcommand, args, flags) {
125
151
  if (!subcommand || (flags.help && !subcommand)) {
126
- info('Usage: myapi funnel <subcommand>\n\nSubcommands:\n list List funnels\n create Create a funnel\n get Get funnel details\n delete Delete a funnel\n push Push a raw HTML page to a slug\n\nNote: Most funnel commands require the --org <id> flag (or set a default via myapi auth config set-org <id>).');
152
+ info(`Usage: myapi funnel <subcommand>
153
+
154
+ Subcommands:
155
+ list List funnels
156
+ create Create a funnel
157
+ get <id> Get funnel details
158
+ delete Delete a funnel
159
+ push Push a raw HTML page from stdin to a slug
160
+ verify Verify a published page is reachable
161
+
162
+ All commands accept --org <id> (or set default: myapi config set-org <id>).`);
127
163
  return;
128
164
  }
129
165
  if (flags.help) {
130
- if (subcommand === 'list')
131
- info('Usage: myapi funnel list --org <id> [--json]\n\nLists all funnels (websites) in the organization.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)\n --json Output raw JSON');
132
- else if (subcommand === 'create')
133
- info('Usage: myapi funnel create --org <id>\n\nCreates a new funnel in the organization.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)');
134
- else if (subcommand === 'get')
135
- info('Usage: myapi funnel get <id> --org <id>\n\nFetches details of a specific funnel including its pages and settings.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)');
136
- else if (subcommand === 'delete')
137
- info('Usage: myapi funnel delete <id> --org <id>\n\nDeletes a funnel permanently.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)');
138
- else if (subcommand === 'push')
139
- info('Usage: myapi funnel push [slug] < page.html\n\nPublishes an HTML page from stdin to a path within your funnel (website).\nThe funnel is always resolved from your default or --funnel flag.\n\nFlags:\n --org <id> Organization ID (or set default via myapi config set-org)\n --funnel <id> Funnel ID (or set default via myapi config set-funnel)\n --slug <path> Alternative way to specify the slug\n\nExamples:\n echo \'<h1>Hello</h1>\' | myapi funnel push / # push to /\n cat about.html | myapi funnel push /about # push to /about\n myapi funnel push < index.html # push to / on default funnel\n cat p.html | myapi funnel push /pricing --funnel <uuid>');
140
- else if (subcommand === 'pull')
141
- info('Usage: myapi funnel pull [funnel_id] [slug]\n\nFetches the HTML content of a funnel page.');
166
+ const usage = SUBCOMMAND_USAGE[subcommand];
167
+ if (usage)
168
+ info(`Usage: ${usage}`);
169
+ else
170
+ info(`Unknown subcommand: ${subcommand}. Run "myapi funnel --help" for the list.`);
142
171
  return;
143
172
  }
144
- if (subcommand === 'list')
145
- await list(flags);
146
- else if (subcommand === 'create')
147
- await create(flags);
148
- else if (subcommand === 'get')
149
- await get(args[0], flags);
150
- else if (subcommand === 'delete')
151
- await del(args[0], flags);
152
- else if (subcommand === 'push')
153
- await push(args[0], flags);
154
- else if (subcommand === 'verify')
155
- await verify(args[0], flags);
156
- else
157
- error(`Unknown subcommand: ${subcommand}. Run "myapi funnel --help" for a list of valid subcommands.`);
173
+ switch (subcommand) {
174
+ case 'list': return list(flags);
175
+ case 'create': return create(flags);
176
+ case 'get': return get(args[0], flags);
177
+ case 'delete': return del(args[0], flags);
178
+ case 'push': return push(args[0], flags);
179
+ case 'verify': return verify(args[0], flags);
180
+ default: error(`Unknown subcommand: ${subcommand}. Run "myapi funnel --help" for a list of valid subcommands.`);
181
+ }
158
182
  }
@@ -61,26 +61,36 @@ export async function del(id, flags) {
61
61
  await sdkImage.deleteImage(config.api_key, orgId, id);
62
62
  success(`Image deleted! (Job ${id} history retained, URL nullified)`);
63
63
  }
64
+ // ── Dispatcher ───────────────────────────────────────────────────────────────
65
+ const SUBCOMMAND_USAGE = {
66
+ 'list': 'myapi image list [--org <id>] [--json]',
67
+ 'generate': 'myapi image generate --prompt "<text>" [--ratio <1:1|16:9>] [--style <style>] [--colors <hex_list>] [--org <id>]',
68
+ 'delete': 'myapi image delete <job_id> [--org <id>]',
69
+ };
64
70
  export async function run(subcommand, args, flags) {
65
71
  if (!subcommand || (flags.help && !subcommand)) {
66
- info('Usage: myapi image <subcommand>\n\nSubcommands:\n list List all your generated images\n generate Generate a new AI image from a prompt\n delete Delete the physical image file for a job\n\nNote: All image commands require the --org <id> flag.');
72
+ info(`Usage: myapi image <subcommand>
73
+
74
+ Subcommands:
75
+ list List all your generated images
76
+ generate Generate a new AI image from a prompt ($0.05 per generation)
77
+ delete Delete the physical image file for a job (history retained, URL nullified)
78
+
79
+ All commands accept --org <id> (or set default: myapi config set-org <id>).`);
67
80
  return;
68
81
  }
69
82
  if (flags.help) {
70
- if (subcommand === 'list')
71
- info('Usage: myapi image list --org <id> [--json]');
72
- else if (subcommand === 'generate')
73
- info('Usage: myapi image generate --prompt "<text>" [--ratio <1:1|16:9>] [--style <style>] [--colors <hex_list>] --org <id>\n\nGenerates an AI image and polls until the public URL is ready. Costs $0.05 per generation.');
74
- else if (subcommand === 'delete')
75
- info('Usage: myapi image delete <job_id> --org <id>\n\nDeletes the physical image file from storage. The generation job history is kept, but its URL will become null.');
83
+ const usage = SUBCOMMAND_USAGE[subcommand];
84
+ if (usage)
85
+ info(`Usage: ${usage}`);
86
+ else
87
+ info(`Unknown subcommand: ${subcommand}. Run "myapi image --help" for the list.`);
76
88
  return;
77
89
  }
78
- if (subcommand === 'list')
79
- await list(flags);
80
- else if (subcommand === 'generate')
81
- await generate(flags);
82
- else if (subcommand === 'delete')
83
- await del(args[0], flags);
84
- else
85
- error(`Unknown subcommand: ${subcommand}. Run "myapi image --help" for a list of valid subcommands.`);
90
+ switch (subcommand) {
91
+ case 'list': return list(flags);
92
+ case 'generate': return generate(flags);
93
+ case 'delete': return del(args[0], flags);
94
+ default: error(`Unknown subcommand: ${subcommand}. Run "myapi image --help" for a list of valid subcommands.`);
95
+ }
86
96
  }
@@ -1,3 +1,8 @@
1
- export declare function createNew(flags: Record<string, string | boolean>): Promise<void>;
2
- export declare function list(flags: Record<string, string | boolean>): Promise<void>;
3
- export declare function revoke(id: string, flags: Record<string, string | boolean>): Promise<void>;
1
+ import type { FlagSchema } from '../flags.js';
2
+ import type { Flags } from '../helpers.js';
3
+ export declare const SCHEMA: FlagSchema;
4
+ export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
5
+ export declare function runApiKeys(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
6
+ export declare function createNew(flags: Flags): Promise<void>;
7
+ export declare function list(flags: Flags): Promise<void>;
8
+ export declare function revoke(id: string, _flags: Flags): Promise<void>;
@@ -2,59 +2,95 @@ import { hq } from '@myapihq/sdk';
2
2
  import { requireConfig } from '../config.js';
3
3
  import { success, error, printTable, info, printJson } from '../output.js';
4
4
  import { formatDate } from '../utils.js';
5
- import * as readline from 'readline';
6
- export async function createNew(flags) {
5
+ import { ask } from '../prompt.js';
6
+ import { requireArg } from '../helpers.js';
7
+ export const SCHEMA = {
8
+ name: 'string',
9
+ };
10
+ const KEYS_HEADER = `Usage: myapi keys <subcommand>
11
+
12
+ Manage programmatic API keys for your account.
13
+
14
+ Subcommands:
15
+ list List all API keys with IDs and creation dates
16
+ create Create a new API key (the key value is shown once)
17
+ revoke <id> Permanently revoke an API key by ID
18
+
19
+ Alias for: myapi auth api-keys`;
20
+ const API_KEYS_HEADER = `Usage: myapi auth api-keys <subcommand>
21
+
22
+ Manage programmatic API keys for your account.
23
+
24
+ Subcommands:
25
+ list List all API keys with IDs and creation dates
26
+ create Create a new API key (the key value is shown once)
27
+ revoke <id> Permanently revoke an API key by ID
28
+
29
+ Alias: myapi keys <subcommand>`;
30
+ function subcommandUsage(prefix) {
31
+ return {
32
+ 'list': `myapi ${prefix} list [--json]`,
33
+ 'create': `myapi ${prefix} create [--name <name>]\n\nCreates a new API key. If --name is omitted you will be prompted.`,
34
+ 'revoke': `myapi ${prefix} revoke <id>\n\nPermanently revokes an API key by ID. The key stops working immediately and the action cannot be undone.`,
35
+ };
36
+ }
37
+ async function dispatch(prefix, subcommand, args, flags) {
38
+ if (!subcommand || (flags.help && !subcommand)) {
39
+ info(prefix === 'keys' ? KEYS_HEADER : API_KEYS_HEADER);
40
+ return;
41
+ }
7
42
  if (flags.help) {
8
- info('Usage: myapi auth api-keys create [--name <name>]\n\nCreates a new API key.\n\nFlags:\n --name <name> Key name (skips prompt)');
43
+ const usage = subcommandUsage(prefix)[subcommand];
44
+ if (usage)
45
+ info(`Usage: ${usage}`);
46
+ else
47
+ info(`Unknown subcommand: ${subcommand}. Run "myapi ${prefix} --help" for the list.`);
9
48
  return;
10
49
  }
50
+ switch (subcommand) {
51
+ case 'create': return createNew(flags);
52
+ case 'list': return list(flags);
53
+ case 'revoke': return revoke(args[0], flags);
54
+ default: error(`Unknown subcommand: ${subcommand}. Run "myapi ${prefix} --help" for available subcommands.`);
55
+ }
56
+ }
57
+ export async function run(subcommand, args, flags) {
58
+ return dispatch('keys', subcommand, args, flags);
59
+ }
60
+ export async function runApiKeys(subcommand, args, flags) {
61
+ return dispatch('auth api-keys', subcommand, args, flags);
62
+ }
63
+ export async function createNew(flags) {
11
64
  const config = requireConfig();
12
65
  let name = flags.name || '';
13
- if (!name) {
14
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
15
- name = await new Promise(resolve => rl.question('Enter a name for the new key: ', resolve));
16
- rl.close();
17
- }
18
- if (!name.trim()) {
66
+ if (!name)
67
+ name = await ask('Enter a name for the new key: ');
68
+ if (!name.trim())
19
69
  error('Key name cannot be empty. Use --name <name>');
20
- return;
21
- }
22
70
  const keyInfo = await hq.createApiKey(config.api_key, name.trim());
23
71
  success(`New API key created!\n\nName: ${keyInfo.prefix}...\nKey: ${keyInfo.api_key}\n\nMake sure to copy your new API key now. You won't be able to see it again!`);
24
72
  }
25
73
  export async function list(flags) {
26
- if (flags.help) {
27
- info('Usage: myapi auth api-keys list [--json]\n\nLists all API keys associated with your account.\n\nAlias: myapi keys list\n\nFlags:\n --json Output raw JSON');
28
- return;
29
- }
30
74
  const config = requireConfig();
31
75
  const keysList = await hq.listApiKeys(config.api_key);
32
76
  if (flags.json) {
33
77
  printJson(keysList);
34
78
  return;
35
79
  }
36
- const formattedKeys = keysList.map(k => {
37
- const createdStr = formatDate(k.created_at);
38
- const lastUsedStr = k.last_used_at ? formatDate(k.last_used_at) : 'Never';
39
- return {
40
- Name: k.name || 'Unnamed',
41
- Prefix: k.prefix,
42
- ID: k.id,
43
- 'Created At': createdStr,
44
- 'Last Used': lastUsedStr
45
- };
80
+ const formattedKeys = keysList.map(k => ({
81
+ Name: k.name || 'Unnamed',
82
+ Prefix: k.prefix,
83
+ ID: k.id,
84
+ 'Created At': formatDate(k.created_at),
85
+ 'Last Used': k.last_used_at ? formatDate(k.last_used_at) : 'Never',
86
+ }));
87
+ printTable(formattedKeys, {
88
+ flags,
89
+ empty: 'No API keys yet. Create one with: myapi keys create',
46
90
  });
47
- printTable(formattedKeys);
48
91
  }
49
- export async function revoke(id, flags) {
50
- if (flags.help) {
51
- info('Usage: myapi auth api-keys revoke <id>\n\nPermanently revokes an API key by ID. This action cannot be undone.\nThe key stops working immediately.\n\nAlias: myapi keys revoke <id>');
52
- return;
53
- }
54
- if (!id) {
55
- error("Missing key ID. Usage: myapi keys revoke <id>");
56
- return;
57
- }
92
+ export async function revoke(id, _flags) {
93
+ requireArg(id, 'id', 'myapi keys revoke <id>');
58
94
  const config = requireConfig();
59
95
  await hq.revokeApiKey(config.api_key, id);
60
96
  success(`Key ${id} revoked successfully.`);
@@ -1,5 +1,9 @@
1
- export declare function create(restArgs: string[], flags: Record<string, string | boolean>): Promise<void>;
2
- export declare function list(flags: Record<string, string | boolean>): Promise<void>;
3
- export declare function get(id: string, flags: Record<string, string | boolean>): Promise<void>;
4
- export declare function del(id: string, flags: Record<string, string | boolean>): Promise<void>;
5
- export declare function importOrg(args: string[], flags: Record<string, string | boolean>): Promise<void>;
1
+ import type { FlagSchema } from '../flags.js';
2
+ import { type Flags } from '../helpers.js';
3
+ export declare const SCHEMA: FlagSchema;
4
+ export declare function create(restArgs: string[], flags: Flags): Promise<void>;
5
+ export declare function list(flags: Flags): Promise<void>;
6
+ export declare function get(id: string, flags: Flags): Promise<void>;
7
+ export declare function del(id: string, _flags: Flags): Promise<void>;
8
+ export declare function importOrg(args: string[], flags: Flags): Promise<void>;
9
+ export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;