@myapihq/cli 1.0.61 → 1.0.65

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 (52) hide show
  1. package/dist/commands/auth.js +13 -5
  2. package/dist/commands/config.d.ts +4 -4
  3. package/dist/commands/config.js +13 -13
  4. package/dist/commands/domain.d.ts +0 -1
  5. package/dist/commands/domain.js +10 -24
  6. package/dist/commands/funnel.js +7 -3
  7. package/dist/commands/keys.js +2 -2
  8. package/dist/commands/org.js +8 -4
  9. package/dist/commands/update.js +1 -1
  10. package/dist/index.js +6 -6
  11. package/dist/skills/my-api-hq/README.md +37 -0
  12. package/dist/skills/my-api-hq/SKILL.md +116 -0
  13. package/dist/skills/my-api-hq/claude/.claude-plugin/plugin.json +6 -0
  14. package/dist/skills/my-api-hq/make/.gitkeep +0 -0
  15. package/dist/skills/my-api-hq/n8n/.gitkeep +0 -0
  16. package/dist/skills/my-api-hq/openapi/.gitkeep +0 -0
  17. package/dist/skills/my-domain-api/README.md +37 -0
  18. package/dist/skills/my-domain-api/SKILL.md +83 -0
  19. package/dist/skills/my-domain-api/claude/.claude-plugin/plugin.json +6 -0
  20. package/dist/skills/my-domain-api/make/.gitkeep +0 -0
  21. package/dist/skills/my-domain-api/n8n/.gitkeep +0 -0
  22. package/dist/skills/my-domain-api/openapi/.gitkeep +0 -0
  23. package/dist/skills/my-funnel-api/README.md +39 -0
  24. package/dist/skills/my-funnel-api/SKILL.md +35 -0
  25. package/dist/skills/my-funnel-api/claude/.claude-plugin/plugin.json +6 -0
  26. package/dist/skills/my-funnel-api/make/.gitkeep +0 -0
  27. package/dist/skills/my-funnel-api/n8n/.gitkeep +0 -0
  28. package/dist/skills/my-funnel-api/openapi/.gitkeep +0 -0
  29. package/package.json +4 -1
  30. package/scripts/copy-skills.js +0 -13
  31. package/src/commands/auth.ts +0 -190
  32. package/src/commands/billing.ts +0 -92
  33. package/src/commands/config.ts +0 -71
  34. package/src/commands/domain.ts +0 -146
  35. package/src/commands/email.ts +0 -185
  36. package/src/commands/funnel.ts +0 -122
  37. package/src/commands/image.ts +0 -85
  38. package/src/commands/keys.ts +0 -68
  39. package/src/commands/org.ts +0 -134
  40. package/src/commands/pixel.ts +0 -62
  41. package/src/commands/setup.ts +0 -335
  42. package/src/commands/storage.ts +0 -56
  43. package/src/commands/update.ts +0 -89
  44. package/src/commands/url.ts +0 -28
  45. package/src/commands/webhook.ts +0 -66
  46. package/src/commands/workflow.ts +0 -102
  47. package/src/config.ts +0 -123
  48. package/src/index.ts +0 -200
  49. package/src/output.ts +0 -49
  50. package/src/utils.ts +0 -45
  51. package/thank-you.html +0 -56
  52. package/tsconfig.json +0 -15
@@ -1,146 +0,0 @@
1
- import { domain as sdkDomain } from '@myapihq/sdk';
2
- import { requireConfig } from '../config.js';
3
- import { success, error, info, printTable, printJson } from '../output.js';
4
- import { formatDate } from '../utils.js';
5
-
6
- export async function check(domainArg: string, flags: Record<string, string | boolean>) {
7
- const config = requireConfig();
8
- const orgId = (flags.org as string) || config.default_org;
9
- const domain = domainArg || (config.default_domain as string);
10
- if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain check <domain> --org <id>\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
11
- const res = await sdkDomain.checkDomain(config.api_key, orgId, domain) as { available: boolean; price_cents: number; price_display?: string; message?: unknown };
12
- if (flags.json) {
13
- printJson(res);
14
- return;
15
- }
16
- if (res.available) {
17
- const price = res.price_display || `$${(res.price_cents / 100).toFixed(2)}`;
18
- info(`${domain} — Available ✓ ${price}/yr`);
19
- } else {
20
- const msg = typeof res.message === 'string' ? res.message : res.message ? JSON.stringify(res.message) : 'Not available';
21
- info(`${domain} — ${msg} ✗`);
22
- }
23
- }
24
-
25
- export async function register(domainArg: string, flags: Record<string, string | boolean>) {
26
- const config = requireConfig();
27
- const orgId = (flags.org as string) || config.default_org;
28
- const domain = domainArg || (config.default_domain as string);
29
- if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain register <domain> --org <id> [--years <num>]\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
30
- const years = parseInt(flags.years as string) || 1;
31
- const res = await sdkDomain.registerDomain(config.api_key, orgId, domain, years);
32
- success(`Registered ${domain}!`);
33
- info(`Assign it to your org now:\n myapi domain assign ${domain} --org ${orgId}`);
34
- info(`DNS propagation can take a few minutes — track it with: myapi domain status ${domain}`);
35
- info(`Your funnel will be live on https://${domain} once propagation completes.`);
36
- }
37
-
38
- export async function importDomain(domainArg: string, flags: Record<string, string | boolean>) {
39
- const config = requireConfig();
40
- const orgId = (flags.org as string) || config.default_org;
41
- const domain = domainArg || (config.default_domain as string);
42
- if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain import <domain> --org <id> [--namecheap-user <user> --namecheap-key <key>]\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
43
- const payload: { domain: string; namecheap_api_user?: string; namecheap_api_key?: string } = { domain };
44
- if (flags['namecheap-user']) payload.namecheap_api_user = flags['namecheap-user'] as string;
45
- if (flags['namecheap-key']) payload.namecheap_api_key = flags['namecheap-key'] as string;
46
- await sdkDomain.importDomain(config.api_key, orgId, payload);
47
- success(`Imported ${domain}`);
48
- }
49
-
50
- export async function list(flags: Record<string, string | boolean>) {
51
- const config = requireConfig();
52
- const orgId = (flags.org as string) || config.default_org;
53
- if (!orgId) error("Missing required arguments.\nUsage: myapi domain list --org <id> [--filter=all|unassigned|org]\n(Set default: myapi auth config set-org <id>)");
54
- const filter = flags.filter as 'all' | 'unassigned' | 'org' | undefined;
55
- const domains = await sdkDomain.listDomains(config.api_key, orgId, filter);
56
- if ((domains as unknown[]).length === 0) { info('No domains found in this organization. Register one with: myapi domain register <name>'); return; }
57
- printTable(domains as unknown as Record<string, unknown>[]);
58
- }
59
-
60
- export async function assign(domainArg: string, flags: Record<string, string | boolean>) {
61
- const config = requireConfig();
62
- const orgId = (flags.org as string) || config.default_org;
63
- const domain = domainArg || (config.default_domain as string);
64
- if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain assign <domain> --org <id>\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
65
- await sdkDomain.assignDomain(config.api_key, orgId, domain);
66
- success(`Assigned ${domain} to org ${orgId}`);
67
- }
68
-
69
- export async function unassign(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 unassign <domain> --org <id>\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
74
- await sdkDomain.unassignDomain(config.api_key, orgId, domain);
75
- success(`Unassigned ${domain} from org ${orgId}`);
76
- }
77
-
78
- export async function status(domainArg: string, flags: Record<string, string | boolean>) {
79
- const config = requireConfig();
80
- const orgId = (flags.org as string) || config.default_org;
81
- const domain = domainArg || (config.default_domain as string);
82
- if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain status <domain> --org <id>\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
83
- const res = await sdkDomain.getDomainStatus(config.api_key, orgId, domain);
84
- if (flags.json) {
85
- printJson(res);
86
- return;
87
- }
88
- info(`Domain: ${res.domain}`);
89
- info(`Status: ${res.status}`);
90
- if ((res as any).expires_at) info(`Expires: ${formatDate((res as any).expires_at)}`);
91
- if (res.status === 'active') info(`Note: if recently activated, the SSL certificate may still be provisioning — allow a few minutes before the site is reachable over HTTPS.`);
92
- }
93
-
94
- export async function settings(domainArg: string, flags: Record<string, string | boolean>) {
95
- const config = requireConfig();
96
- const orgId = (flags.org as string) || config.default_org;
97
- const domain = domainArg || (config.default_domain as string);
98
- if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain settings <domain> --org <id>\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
99
- const res = await sdkDomain.getDomainSettings(config.api_key, orgId, domain);
100
- printJson(res);
101
- }
102
-
103
- export async function updateSettings(domainArg: string, flags: Record<string, string | boolean>) {
104
- const config = requireConfig();
105
- const orgId = (flags.org as string) || config.default_org;
106
- const domain = domainArg || (config.default_domain as string);
107
- if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain update-settings <domain> --org <id> [--security=...] [--browser-check=...] [--purge-cache]\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
108
- const payload: any = {};
109
- if (flags.security) payload.security_level = flags.security as string;
110
- if (flags['browser-check']) payload.browser_check = flags['browser-check'] as string;
111
- if (flags['purge-cache']) payload.purge_cache = true;
112
-
113
- const res = await sdkDomain.updateDomainSettings(config.api_key, orgId, domain, payload);
114
- success(`Updated settings for ${domain}!\n${JSON.stringify(res, null, 2)}`);
115
- }
116
-
117
- export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
118
- if (!subcommand || (flags.help && !subcommand)) {
119
- 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 an 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\nTip: Set defaults with "myapi auth config set-org <id>" to skip --org on every command.');
120
- return;
121
- }
122
-
123
- if (flags.help) {
124
- 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.');
125
- else if (subcommand === 'check') info('Usage: myapi domain check <domain> --org <id> [--json]\n\nChecks if a domain name is available for registration.\n\nFlags:\n --json Output raw JSON');
126
- else if (subcommand === 'register') info('Usage: myapi domain register <domain> --org <id> [--years <num>]\n\nRegisters a new domain name.');
127
- 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.');
128
- else if (subcommand === 'assign') info('Usage: myapi domain assign <domain> --org <id>\n\nAssigns a domain to the specified organization.');
129
- else if (subcommand === 'unassign') info('Usage: myapi domain unassign <domain> --org <id>\n\nUnassigns a domain from its current organization.');
130
- else if (subcommand === 'status') info('Usage: myapi domain status <domain> --org <id> [--json]\n\nGets the registration status of a domain.\n\nFlags:\n --json Output raw JSON');
131
- else if (subcommand === 'settings') info('Usage: myapi domain settings <domain> --org <id>\n\nGets the DNS settings and configuration for a domain.');
132
- 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.');
133
- return;
134
- }
135
-
136
- if (subcommand === 'list') await list(flags);
137
- else if (subcommand === 'check') await check(args[0], flags);
138
- else if (subcommand === 'register') await register(args[0], flags);
139
- else if (subcommand === 'import') await importDomain(args[0], flags);
140
- else if (subcommand === 'assign') await assign(args[0], flags);
141
- else if (subcommand === 'unassign') await unassign(args[0], flags);
142
- else if (subcommand === 'status') await status(args[0], flags);
143
- else if (subcommand === 'settings') await settings(args[0], flags);
144
- else if (subcommand === 'update-settings') await updateSettings(args[0], flags);
145
- else error(`Unknown subcommand: ${subcommand}. Run "myapi domain --help" for a list of valid subcommands.`);
146
- }
@@ -1,185 +0,0 @@
1
- import { email as sdkEmail } from '@myapihq/sdk';
2
- import { requireConfig } from '../config.js';
3
- import { success, error, printTable, printJson, info } from '../output.js';
4
- import { sleep } from '../utils.js';
5
-
6
- export async function createMailbox(flags: Record<string, string | boolean>) {
7
- const config = requireConfig();
8
- const orgId = (flags.org as string) || config.default_org;
9
- const domain = (flags.domain as string) || config.default_domain;
10
- if (!orgId || !domain || !flags.username) {
11
- error("Missing required arguments.\nUsage: myapi email create-mailbox --org <id> --domain <domain> --username <user>\n(Or set defaults via: myapi config set-org <id> / set-domain <domain>)");
12
- }
13
- const address = await sdkEmail.createMailbox(config.api_key, orgId, domain, flags.username as string);
14
- success(`Mailbox created: ${address.address}`);
15
- }
16
-
17
- export async function listMailboxes(flags: Record<string, string | boolean>) {
18
- const config = requireConfig();
19
- const orgId = (flags.org as string) || config.default_org;
20
- if (!orgId) error("Missing required arguments.\nUsage: myapi email list-mailboxes --org <id> [--domain <domain> | --filter unassigned]\n(Or set a default org via: myapi config set-org <id>)");
21
- if (!flags.domain && flags.filter !== 'unassigned') error("Must provide either --domain <domain> or --filter unassigned");
22
- const mailboxes = await sdkEmail.listMailboxes(config.api_key, orgId, {
23
- domain: flags.domain as string | undefined,
24
- filter: flags.filter === 'unassigned' ? 'unassigned' : undefined
25
- });
26
- printTable(mailboxes as unknown as Record<string, unknown>[]);
27
- }
28
-
29
- export async function sent(flags: Record<string, string | boolean>) {
30
- const config = requireConfig();
31
- const orgId = (flags.org as string) || config.default_org;
32
- if (!orgId) error("Missing required arguments.\nUsage: myapi email sent --org <id> [--limit <num>] [--offset <num>]\n(Or set defaults via: myapi config set-org <id>)");
33
- const limit = parseInt(flags.limit as string) || 50;
34
- const offset = parseInt(flags.offset as string) || 0;
35
- const emails = await sdkEmail.getSentEmails(config.api_key, orgId, limit, offset);
36
- printTable(emails as unknown as Record<string, unknown>[]);
37
- }
38
-
39
- export async function send(flags: Record<string, string | boolean>) {
40
- const config = requireConfig();
41
- const orgId = (flags.org as string) || config.default_org;
42
- if (!orgId || !flags.from || !flags.to || !flags.subject) {
43
- error("Missing required arguments.\nUsage: myapi email send --org <id> --from <email> --to <email> --subject <str> [--body <str> | --template-id <id> [--template-vars <json_str>]]");
44
- }
45
- if (!flags.body && !flags['template-id']) error("Must provide either --body or --template-id");
46
- if (flags.body && flags['template-id']) error("Cannot provide both --body and --template-id");
47
-
48
- let templateVars: Record<string, string> | undefined;
49
- if (flags['template-vars']) {
50
- try {
51
- templateVars = JSON.parse(flags['template-vars'] as string);
52
- } catch (e) {
53
- error("--template-vars must be a valid JSON string");
54
- }
55
- }
56
-
57
- const res = await sdkEmail.sendEmail(config.api_key, orgId, {
58
- from: flags.from as string,
59
- to: [flags.to as string],
60
- subject: flags.subject as string,
61
- text: flags.body as string | undefined,
62
- template_id: flags['template-id'] as string | undefined,
63
- template_vars: templateVars
64
- });
65
- success(`Email sent! Message ID: ${res.message_id}`);
66
- }
67
-
68
- export async function inbox(address: string, flags: Record<string, string | boolean>) {
69
- const config = requireConfig();
70
- const orgId = (flags.org as string) || config.default_org;
71
- if (!orgId || !address) error("Missing required arguments.\nUsage: myapi email inbox <address> --org <id>");
72
- const messages = await sdkEmail.getInbox(config.api_key, orgId, address);
73
- printTable(messages as unknown as Record<string, unknown>[]);
74
- }
75
-
76
- export async function outbox(address: string, flags: Record<string, string | boolean>) {
77
- const config = requireConfig();
78
- const orgId = (flags.org as string) || config.default_org;
79
- if (!orgId || !address) error("Missing required arguments.\nUsage: myapi email outbox <address> --org <id>");
80
- const messages = await sdkEmail.getOutbox(config.api_key, orgId, address);
81
- printTable(messages as unknown as Record<string, unknown>[]);
82
- }
83
- export async function listTemplates(flags: Record<string, string | boolean>) {
84
- const config = requireConfig();
85
- const orgId = (flags.org as string) || config.default_org;
86
- if (!orgId) error("Missing required arguments.\nUsage: myapi email list-templates --org <id>\n(Or set defaults via: myapi config set-org <id>)");
87
- const templates = await sdkEmail.listTemplates(config.api_key, orgId);
88
- if (flags.json) printJson(templates);
89
- else printTable(templates as unknown as Record<string, unknown>[]);
90
- }
91
-
92
- export async function deleteTemplate(id: string, flags: Record<string, string | boolean>) {
93
- const config = requireConfig();
94
- const orgId = (flags.org as string) || config.default_org;
95
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi email delete-template <id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
96
- await sdkEmail.deleteTemplate(config.api_key, orgId, id);
97
- success(`Deleted template ${id}`);
98
- }
99
-
100
- export async function generateTemplate(flags: Record<string, string | boolean>) {
101
- const config = requireConfig();
102
- const orgId = (flags.org as string) || config.default_org;
103
- if (!orgId || !flags.prompt || !flags.name) {
104
- error("Missing required arguments.\nUsage: myapi email generate-template --org <id> --prompt <str> --name <str>");
105
- }
106
-
107
- const job = await sdkEmail.generateTemplate(config.api_key, orgId, {
108
- prompt: flags.prompt as string,
109
- name: flags.name as string
110
- });
111
-
112
- process.stdout.write("Generating template ");
113
- const chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
114
- let i = 0;
115
- let elapsed = 0;
116
-
117
- while (elapsed < 90000) {
118
- const status = await sdkEmail.getTemplateJobStatus(config.api_key, orgId, job.job_id);
119
- if (status.status === 'completed') {
120
- process.stdout.write('\r\x1b[K');
121
- success(`Template generated! ID: ${status.template_id}\nPreview: ${status.result?.preview_url}`);
122
- return;
123
- }
124
- if (status.status === 'failed') {
125
- process.stdout.write('\r\x1b[K');
126
- error("Template generation failed");
127
- }
128
- process.stdout.write(`\rGenerating template ${chars[i++ % chars.length]}`);
129
- await sleep(3000);
130
- elapsed += 3000;
131
- }
132
- process.stdout.write('\r\x1b[K');
133
- error("Template generation timed out");
134
- }
135
-
136
- export async function listCampaigns(flags: Record<string, string | boolean>) {
137
- const config = requireConfig();
138
- const orgId = (flags.org as string) || config.default_org;
139
- if (!orgId) error("Missing required arguments.\nUsage: myapi email list-campaigns --org <id>\n(Or set a default org via: myapi config set-org <id>)");
140
- const campaigns = await sdkEmail.listCampaigns(config.api_key, orgId);
141
- printTable(campaigns as unknown as Record<string, unknown>[]);
142
- }
143
-
144
- export async function campaignStats(id: string, flags: Record<string, string | boolean>) {
145
- const config = requireConfig();
146
- const orgId = (flags.org as string) || config.default_org;
147
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi email campaign-stats <id> --org <id>");
148
- const stats = await sdkEmail.getCampaignStats(config.api_key, orgId, id);
149
- printJson(stats);
150
- }
151
-
152
- export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
153
- if (!subcommand || (flags.help && !subcommand)) {
154
- info('Usage: myapi email <subcommand>\n\nSubcommands:\n create-mailbox Create a new mailbox\n list-mailboxes List mailboxes\n send Send an email\n sent List sent emails\n inbox Read received emails\n outbox Read sent emails for address\n list-templates List email templates\n generate-template Generate AI template\n delete-template Delete a template\n list-campaigns List campaigns\n campaign-stats Get campaign stats\n\nNote: All email commands require the --org <id> flag.');
155
- return;
156
- }
157
-
158
- if (flags.help) {
159
- if (subcommand === 'create-mailbox') info('Usage: myapi email create-mailbox --org <id> --domain <domain> --username <user>');
160
- else if (subcommand === 'list-mailboxes') info('Usage: myapi email list-mailboxes --org <id> [--domain <domain> | --filter unassigned]');
161
- else if (subcommand === 'send') info('Usage: myapi email send --org <id> --from <email> --to <email> --subject <str> [--body <str> | --template-id <id> [--template-vars <json_str>]]');
162
- else if (subcommand === 'sent') info('Usage: myapi email sent --org <id> [--limit <num>] [--offset <num>]');
163
- else if (subcommand === 'inbox') info('Usage: myapi email inbox <address> --org <id>');
164
- else if (subcommand === 'outbox') info('Usage: myapi email outbox <address> --org <id>');
165
- else if (subcommand === 'list-templates') info('Usage: myapi email list-templates --org <id>');
166
- else if (subcommand === 'generate-template') info('Usage: myapi email generate-template --org <id> --prompt <str> --name <str>');
167
- else if (subcommand === 'delete-template') info('Usage: myapi email delete-template <id> --org <id>');
168
- else if (subcommand === 'list-campaigns') info('Usage: myapi email list-campaigns --org <id>');
169
- else if (subcommand === 'campaign-stats') info('Usage: myapi email campaign-stats <campaign_id> --org <id>');
170
- return;
171
- }
172
-
173
- if (subcommand === 'create-mailbox') await createMailbox(flags);
174
- else if (subcommand === 'list-mailboxes') await listMailboxes(flags);
175
- else if (subcommand === 'send') await send(flags);
176
- else if (subcommand === 'sent') await sent(flags);
177
- else if (subcommand === 'inbox') await inbox(args[0], flags);
178
- else if (subcommand === 'outbox') await outbox(args[0], flags);
179
- else if (subcommand === 'list-templates') await listTemplates(flags);
180
- else if (subcommand === 'generate-template') await generateTemplate(flags);
181
- else if (subcommand === 'delete-template') await deleteTemplate(args[0], flags);
182
- else if (subcommand === 'list-campaigns') await listCampaigns(flags);
183
- else if (subcommand === 'campaign-stats') await campaignStats(args[0], flags);
184
- else error(`Unknown subcommand: ${subcommand}. Run "myapi email --help" for a list of valid subcommands.`);
185
- }
@@ -1,122 +0,0 @@
1
- import { funnel as sdkFunnel, hq } from '@myapihq/sdk';
2
- import { requireConfig, saveConfig } from '../config.js';
3
- import { success, error, printTable, info, printJson } from '../output.js';
4
- import { formatDate } from '../utils.js';
5
- import * as fs from 'fs';
6
-
7
- export async function list(flags: Record<string, string | boolean>) {
8
- const config = requireConfig();
9
- const orgId = (flags.org as string) || config.default_org;
10
- if (!orgId) error("Missing required arguments.\nUsage: myapi funnel list --org <id>\n(Or set defaults via: myapi config set-org <id>)");
11
- const funnels = await sdkFunnel.listFunnels(config.api_key, orgId);
12
- const rows = funnels.map(f => ({ id: f.id, created_at: formatDate(f.created_at), updated_at: formatDate(f.updated_at) }));
13
- if (rows.length === 0) { info('No funnels found. Create one with: myapi funnel create'); return; }
14
- printTable(rows as unknown as Record<string, unknown>[]);
15
- }
16
-
17
- export async function create(flags: Record<string, string | boolean>) {
18
- const config = requireConfig();
19
- const orgId = (flags.org as string) || config.default_org;
20
-
21
- if (!orgId) {
22
- error("Missing required arguments.\nUsage: myapi funnel create --org <id>\n(Or set defaults via: myapi config set-org <id>)");
23
- }
24
-
25
- const result = await sdkFunnel.createFunnel(config.api_key, orgId);
26
- success(`Funnel created! ID: ${result.funnel.id}`);
27
- if (result.domain_url) info(`Live: ${result.domain_url}`);
28
- else if (result.subdomain_url) info(`Preview: ${result.subdomain_url}`);
29
- }
30
-
31
- export async function get(id: string, flags: Record<string, string | boolean>) {
32
- const config = requireConfig();
33
- const orgId = (flags.org as string) || config.default_org;
34
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi funnel get <id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
35
- const funnel = await sdkFunnel.getFunnel(config.api_key, orgId, id);
36
- printJson(funnel);
37
- }
38
-
39
- export async function del(id: string, flags: Record<string, string | boolean>) {
40
- const config = requireConfig();
41
- const orgId = (flags.org as string) || config.default_org;
42
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi funnel delete <id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
43
- await sdkFunnel.deleteFunnel(config.api_key, orgId, id);
44
- success(`Funnel ${id} deleted`);
45
- }
46
-
47
- export async function push(id: string, slug: string, flags: Record<string, string | boolean>) {
48
- const config = requireConfig();
49
- const orgId = (flags.org as string) || config.default_org;
50
- if (!orgId) error("Missing org. Set a default with: myapi auth config set-org <id>");
51
-
52
- if (slug && flags.slug && slug !== flags.slug) {
53
- info(`› Note: positional slug "${slug}" takes precedence over --slug "${flags.slug}".`);
54
- }
55
- const rawSlug = slug || (flags.slug as string) || '/';
56
- const finalSlug = rawSlug.startsWith('/') ? rawSlug : `/${rawSlug}`;
57
-
58
- let funnelId = id || config.default_funnel;
59
- if (!funnelId) {
60
- const existing = await sdkFunnel.listFunnels(config.api_key, orgId);
61
- if (existing.length === 0) error("No funnel found for this org. Try: myapi auth config set-org <id>");
62
- funnelId = existing[0].id;
63
- config.default_funnel = funnelId;
64
- saveConfig(config);
65
- }
66
-
67
- const html = await new Promise<string>((resolve, reject) => {
68
- let data = '';
69
- process.stdin.setEncoding('utf-8');
70
- process.stdin.on('data', chunk => { data += chunk; });
71
- process.stdin.on('end', () => resolve(data));
72
- process.stdin.on('error', reject);
73
- });
74
-
75
- if (!html.trim()) error("No content provided via stdin. Usage: echo '<h1>Hello</h1>' | myapi funnel push [id] [slug]");
76
-
77
- const result = await sdkFunnel.pushFunnelPage(config.api_key, orgId, funnelId, { slug: finalSlug, html });
78
- success(`Pushed page to ${finalSlug}`);
79
- if (result?.url) {
80
- info(`Preview: ${result.url}`);
81
- } else {
82
- const org = await hq.getOrg(config.api_key, orgId);
83
- if (org.preview_subdomain) {
84
- info(`Preview: https://${org.preview_subdomain}.makeautonomous.com${finalSlug}`);
85
- }
86
- }
87
- }
88
-
89
- export async function verify(id: string, flags: Record<string, string | boolean>) {
90
- const config = requireConfig();
91
- const orgId = (flags.org as string) || config.default_org;
92
- if (!orgId || !id) error("Missing required arguments.\nUsage: myapi funnel verify <id> --org <id> [--slug <slug>]\n(Or set defaults via: myapi config set-org <id>)");
93
- const opts: any = {};
94
- if (flags.slug) opts.slug = flags.slug as string;
95
- const v = await sdkFunnel.verifyFunnel(config.api_key, orgId, id, opts);
96
- printJson(v);
97
- }
98
-
99
- export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
100
- if (!subcommand || (flags.help && !subcommand)) {
101
- 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>).');
102
- return;
103
- }
104
-
105
- if (flags.help) {
106
- if (subcommand === 'list') info('Usage: myapi funnel list --org <id>\n\nLists all funnels in the organization.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)');
107
- else if (subcommand === 'create') 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)');
108
- else if (subcommand === 'get') info('Usage: myapi funnel get <id> --org <id>\n\nFetches details of a specific funnel.\n\nFlags:\n --org <id> Organization ID (or set default via myapi auth config set-org)');
109
- else if (subcommand === 'delete') 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)');
110
- else if (subcommand === 'push') info('Usage: myapi funnel push [funnel_id] [slug] < index.html\n\nPushes an HTML page from stdin to a slug path within a funnel.\nUses your configured default funnel and slug "/" when arguments are omitted.\n\nFlags:\n --org <id> Organization ID\n --slug <path> Target slug path (default: /)');
111
- else if (subcommand === 'pull') info('Usage: myapi funnel pull [funnel_id] [slug]\n\nFetches the HTML content of a funnel page.');
112
- return;
113
- }
114
-
115
- if (subcommand === 'list') await list(flags);
116
- else if (subcommand === 'create') await create(flags);
117
- else if (subcommand === 'get') await get(args[0], flags);
118
- else if (subcommand === 'delete') await del(args[0], flags);
119
- else if (subcommand === 'push') await push(args[0], args[1], flags);
120
- else if (subcommand === 'verify') await verify(args[0], flags);
121
- else error(`Unknown subcommand: ${subcommand}. Run "myapi funnel --help" for a list of valid subcommands.`);
122
- }
@@ -1,85 +0,0 @@
1
- import { image as sdkImage } from '@myapihq/sdk';
2
- import { requireConfig } from '../config.js';
3
- import { success, error, printTable, info, printJson } from '../output.js';
4
- import { sleep } from '../utils.js';
5
-
6
- export async function generate(flags: Record<string, string | boolean>) {
7
- const config = requireConfig();
8
- const orgId = (flags.org as string) || config.default_org;
9
-
10
- if (!orgId || !flags.prompt) {
11
- error("Missing required arguments.\nUsage: myapi image generate --prompt <text> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
12
- }
13
-
14
- const payload: any = { prompt: flags.prompt as string };
15
- if (flags.ratio) payload.aspect_ratio = flags.ratio as string;
16
- if (flags.style) payload.style = flags.style as string;
17
- if (flags.colors) payload.colors = flags.colors as string;
18
-
19
- const res = await sdkImage.generateImage(config.api_key, orgId, payload);
20
-
21
- process.stdout.write("Generating image ");
22
- const chars = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
23
- let i = 0;
24
- let elapsed = 0;
25
-
26
- while (elapsed < 60000) {
27
- const job = await sdkImage.getImageJob(config.api_key, orgId, res.job_id);
28
- if (job.status === 'completed') {
29
- process.stdout.write('\r\x1b[K');
30
- if (flags.json) printJson(job);
31
- else success(`Image generated!\nURL: ${job.url}`);
32
- return;
33
- }
34
- if (job.status === 'failed') {
35
- process.stdout.write('\r\x1b[K');
36
- error(`Image generation failed: ${job.error || 'Unknown error'}`);
37
- }
38
- process.stdout.write(`\rGenerating image ${chars[i++ % chars.length]}`);
39
- await sleep(3000);
40
- elapsed += 3000;
41
- }
42
- process.stdout.write('\r\x1b[K');
43
- error("Image generation timed out");
44
- }
45
-
46
- export async function list(flags: Record<string, string | boolean>) {
47
- const config = requireConfig();
48
- const orgId = (flags.org as string) || config.default_org;
49
- if (!orgId) error("Missing required arguments.\nUsage: myapi image list --org <id>\n(Or set defaults via: myapi config set-org <id>)");
50
-
51
- const images = await sdkImage.listImages(config.api_key, orgId);
52
- if (flags.json) printJson(images);
53
- else printTable(images as unknown as Record<string, unknown>[]);
54
- }
55
-
56
- export async function del(id: string, flags: Record<string, string | boolean>) {
57
- const config = requireConfig();
58
- const orgId = (flags.org as string) || config.default_org;
59
-
60
- if (!orgId || !id) {
61
- error("Missing required arguments.\nUsage: myapi image delete <job_id> --org <id>\n(Or set defaults via: myapi config set-org <id>)");
62
- }
63
-
64
- await sdkImage.deleteImage(config.api_key, orgId, id);
65
- success(`Image deleted! (Job ${id} history retained, URL nullified)`);
66
- }
67
-
68
- export async function run(subcommand: string | undefined, args: string[], flags: Record<string, string | boolean>) {
69
- if (!subcommand || (flags.help && !subcommand)) {
70
- 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.');
71
- return;
72
- }
73
-
74
- if (flags.help) {
75
- if (subcommand === 'list') info('Usage: myapi image list --org <id> [--json]');
76
- else if (subcommand === 'generate') 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.');
77
- else if (subcommand === 'delete') 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.');
78
- return;
79
- }
80
-
81
- if (subcommand === 'list') await list(flags);
82
- else if (subcommand === 'generate') await generate(flags);
83
- else if (subcommand === 'delete') await del(args[0], flags);
84
- else error(`Unknown subcommand: ${subcommand}. Run "myapi image --help" for a list of valid subcommands.`);
85
- }
@@ -1,68 +0,0 @@
1
- import { hq } from '@myapihq/sdk';
2
- import { requireConfig } from '../config.js';
3
- import { success, error, printTable, info, printJson } from '../output.js';
4
- import { formatDate } from '../utils.js';
5
- import * as readline from 'readline';
6
-
7
- export async function createNew(flags: Record<string, string | boolean>) {
8
- if (flags.help) {
9
- info('Usage: myapi auth api-keys create [--name <name>]\n\nCreates a new API key.\n\nFlags:\n --name <name> Key name (skips prompt)');
10
- return;
11
- }
12
- const config = requireConfig();
13
- let name = (flags.name as string) || '';
14
- if (!name) {
15
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
16
- name = await new Promise<string>(resolve => rl.question('Enter a name for the new key: ', resolve));
17
- rl.close();
18
- }
19
- if (!name.trim()) {
20
- error('Key name cannot be empty. Use --name <name>');
21
- return;
22
- }
23
- const keyInfo = await hq.createApiKey(config.api_key, name.trim());
24
- 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!`);
25
- }
26
-
27
- export async function list(flags: Record<string, string | boolean>) {
28
- if (flags.help) {
29
- info('Usage: myapi keys list [--json]\n\nLists all API keys associated with your account.');
30
- return;
31
- }
32
- const config = requireConfig();
33
- const keysList = await hq.listApiKeys(config.api_key);
34
-
35
- if (flags.json) {
36
- printJson(keysList);
37
- return;
38
- }
39
-
40
- const formattedKeys = keysList.map(k => {
41
- const createdStr = formatDate(k.created_at);
42
- const lastUsedStr = k.last_used_at ? formatDate(k.last_used_at) : 'Never';
43
-
44
- return {
45
- Name: k.name || 'Unnamed',
46
- Prefix: k.prefix,
47
- ID: k.id,
48
- 'Created At': createdStr,
49
- 'Last Used': lastUsedStr
50
- };
51
- });
52
-
53
- printTable(formattedKeys as unknown as Record<string, unknown>[]);
54
- }
55
-
56
- export async function revoke(id: string, flags: Record<string, string | boolean>) {
57
- if (flags.help) {
58
- info('Usage: myapi keys revoke <id>\n\nRevokes an API key permanently.');
59
- return;
60
- }
61
- if (!id) {
62
- error("Missing key ID. Usage: myapi keys revoke <id>");
63
- return;
64
- }
65
- const config = requireConfig();
66
- await hq.revokeApiKey(config.api_key, id);
67
- success(`Key ${id} revoked successfully.`);
68
- }