@cakemail-org/cakemail-cli 1.2.0 → 1.5.0

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 (88) hide show
  1. package/README.md +140 -0
  2. package/dist/cli.js +48 -6
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client.js +0 -2
  5. package/dist/client.js.map +1 -1
  6. package/dist/commands/account.d.ts +5 -0
  7. package/dist/commands/account.d.ts.map +1 -0
  8. package/dist/commands/account.js +231 -0
  9. package/dist/commands/account.js.map +1 -0
  10. package/dist/commands/attributes.d.ts +5 -0
  11. package/dist/commands/attributes.d.ts.map +1 -0
  12. package/dist/commands/attributes.js +126 -0
  13. package/dist/commands/attributes.js.map +1 -0
  14. package/dist/commands/campaigns.d.ts.map +1 -1
  15. package/dist/commands/campaigns.js +153 -19
  16. package/dist/commands/campaigns.js.map +1 -1
  17. package/dist/commands/config.d.ts +8 -0
  18. package/dist/commands/config.d.ts.map +1 -0
  19. package/dist/commands/config.js +235 -0
  20. package/dist/commands/config.js.map +1 -0
  21. package/dist/commands/contacts.d.ts.map +1 -1
  22. package/dist/commands/contacts.js +436 -14
  23. package/dist/commands/contacts.js.map +1 -1
  24. package/dist/commands/emails.d.ts.map +1 -1
  25. package/dist/commands/emails.js +53 -0
  26. package/dist/commands/emails.js.map +1 -1
  27. package/dist/commands/lists.d.ts.map +1 -1
  28. package/dist/commands/lists.js +282 -11
  29. package/dist/commands/lists.js.map +1 -1
  30. package/dist/commands/reports.d.ts +5 -0
  31. package/dist/commands/reports.d.ts.map +1 -0
  32. package/dist/commands/reports.js +334 -0
  33. package/dist/commands/reports.js.map +1 -0
  34. package/dist/commands/segments.d.ts +5 -0
  35. package/dist/commands/segments.d.ts.map +1 -0
  36. package/dist/commands/segments.js +203 -0
  37. package/dist/commands/segments.js.map +1 -0
  38. package/dist/commands/senders.d.ts.map +1 -1
  39. package/dist/commands/senders.js +36 -5
  40. package/dist/commands/senders.js.map +1 -1
  41. package/dist/commands/suppressed.d.ts +5 -0
  42. package/dist/commands/suppressed.d.ts.map +1 -0
  43. package/dist/commands/suppressed.js +193 -0
  44. package/dist/commands/suppressed.js.map +1 -0
  45. package/dist/commands/templates.d.ts.map +1 -1
  46. package/dist/commands/templates.js +11 -3
  47. package/dist/commands/templates.js.map +1 -1
  48. package/dist/types/profile.d.ts +92 -0
  49. package/dist/types/profile.d.ts.map +1 -0
  50. package/dist/types/profile.js +119 -0
  51. package/dist/types/profile.js.map +1 -0
  52. package/dist/utils/auth.d.ts +26 -0
  53. package/dist/utils/auth.d.ts.map +1 -0
  54. package/dist/utils/auth.js +198 -0
  55. package/dist/utils/auth.js.map +1 -0
  56. package/dist/utils/config-file.d.ts +92 -0
  57. package/dist/utils/config-file.d.ts.map +1 -0
  58. package/dist/utils/config-file.js +244 -0
  59. package/dist/utils/config-file.js.map +1 -0
  60. package/dist/utils/config.d.ts +11 -2
  61. package/dist/utils/config.d.ts.map +1 -1
  62. package/dist/utils/config.js +74 -8
  63. package/dist/utils/config.js.map +1 -1
  64. package/dist/utils/confirm.d.ts +38 -0
  65. package/dist/utils/confirm.d.ts.map +1 -0
  66. package/dist/utils/confirm.js +124 -0
  67. package/dist/utils/confirm.js.map +1 -0
  68. package/dist/utils/defaults.d.ts +39 -0
  69. package/dist/utils/defaults.d.ts.map +1 -0
  70. package/dist/utils/defaults.js +195 -0
  71. package/dist/utils/defaults.js.map +1 -0
  72. package/dist/utils/errors.d.ts +67 -0
  73. package/dist/utils/errors.d.ts.map +1 -0
  74. package/dist/utils/errors.js +395 -0
  75. package/dist/utils/errors.js.map +1 -0
  76. package/dist/utils/interactive.d.ts +97 -0
  77. package/dist/utils/interactive.d.ts.map +1 -0
  78. package/dist/utils/interactive.js +265 -0
  79. package/dist/utils/interactive.js.map +1 -0
  80. package/dist/utils/output.d.ts +72 -2
  81. package/dist/utils/output.d.ts.map +1 -1
  82. package/dist/utils/output.js +383 -37
  83. package/dist/utils/output.js.map +1 -1
  84. package/dist/utils/progress.d.ts +139 -0
  85. package/dist/utils/progress.d.ts.map +1 -0
  86. package/dist/utils/progress.js +216 -0
  87. package/dist/utils/progress.js.map +1 -0
  88. package/package.json +3 -1
package/README.md CHANGED
@@ -370,6 +370,146 @@ cakemail webhooks archive <id>
370
370
  cakemail webhooks unarchive <id>
371
371
  ```
372
372
 
373
+ #### Reports & Analytics (NEW in v1.3)
374
+
375
+ ```bash
376
+ # Campaign analytics
377
+ cakemail reports campaign <id>
378
+ cakemail reports campaign-links <id>
379
+
380
+ # List analytics
381
+ cakemail reports list <id>
382
+
383
+ # Account analytics
384
+ cakemail reports account
385
+
386
+ # Email API statistics
387
+ cakemail reports emails --from 2025-01-01 --to 2025-12-31
388
+ cakemail reports emails-summary
389
+ cakemail reports transactional-emails
390
+
391
+ # Export campaign reports
392
+ cakemail reports export-campaigns --from 2025-01-01 --status delivered
393
+ cakemail reports campaigns-exports
394
+ cakemail reports campaigns-export <export-id>
395
+ cakemail reports download-campaigns-export <export-id>
396
+ cakemail reports delete-campaigns-export <export-id> --force
397
+ ```
398
+
399
+ #### Segments (NEW in v1.3)
400
+
401
+ ```bash
402
+ # List all segments
403
+ cakemail segments list <list-id>
404
+
405
+ # Get segment details
406
+ cakemail segments get <list-id> <segment-id>
407
+
408
+ # Create a segment
409
+ cakemail segments create <list-id> -n "Active Users" -c '{"conditions":[...]}'
410
+
411
+ # Update segment
412
+ cakemail segments update <list-id> <segment-id> -n "New Name"
413
+
414
+ # Delete segment
415
+ cakemail segments delete <list-id> <segment-id> --force
416
+
417
+ # List contacts in segment
418
+ cakemail segments contacts <list-id> <segment-id>
419
+ ```
420
+
421
+ #### Custom Attributes (NEW in v1.3)
422
+
423
+ ```bash
424
+ # List all custom attributes
425
+ cakemail attributes list <list-id>
426
+
427
+ # Get attribute details
428
+ cakemail attributes get <list-id> <attribute-name>
429
+
430
+ # Create custom attribute
431
+ cakemail attributes create <list-id> -n "company" -t text
432
+ cakemail attributes create <list-id> -n "age" -t number
433
+ cakemail attributes create <list-id> -n "subscribed_date" -t date
434
+ cakemail attributes create <list-id> -n "active" -t boolean
435
+
436
+ # Delete attribute
437
+ cakemail attributes delete <list-id> <attribute-name> --force
438
+ ```
439
+
440
+ #### Suppression List (NEW in v1.3)
441
+
442
+ ```bash
443
+ # List suppressed emails
444
+ cakemail suppressed list
445
+
446
+ # Add to suppression list
447
+ cakemail suppressed add bounced@example.com
448
+
449
+ # Remove from suppression list
450
+ cakemail suppressed delete recovered@example.com --force
451
+
452
+ # Export suppressed emails
453
+ cakemail suppressed export
454
+ cakemail suppressed exports
455
+ cakemail suppressed export-get <export-id>
456
+ cakemail suppressed export-download <export-id>
457
+ ```
458
+
459
+ #### Contact Import/Export & Tagging (NEW in v1.3)
460
+
461
+ ```bash
462
+ # Import contacts from file (TODO: Not yet implemented - requires CSV/JSON parser)
463
+
464
+ # Export contacts
465
+ cakemail contacts export <list-id> --status subscribed --format csv
466
+ cakemail contacts exports <list-id>
467
+ cakemail contacts export-get <list-id> <export-id>
468
+ cakemail contacts export-download <list-id> <export-id>
469
+ cakemail contacts export-delete <list-id> <export-id> --force
470
+
471
+ # Tag single contact
472
+ cakemail contacts tag <list-id> <contact-id> -t "vip,premium"
473
+
474
+ # Untag single contact
475
+ cakemail contacts untag <list-id> <contact-id> -t "trial"
476
+
477
+ # Tag multiple contacts
478
+ cakemail contacts tag-bulk <list-id> -c "1,2,3,4,5" -t "segment-a,active"
479
+
480
+ # Untag multiple contacts
481
+ cakemail contacts untag-bulk <list-id> -c "1,2,3,4,5" -t "old-tag"
482
+ ```
483
+
484
+ #### Extended List Operations (NEW in v1.3)
485
+
486
+ ```bash
487
+ # Update list
488
+ cakemail lists update <id> -n "New Name" -l en_US
489
+
490
+ # Archive list
491
+ cakemail lists archive <id>
492
+
493
+ # Accept list policy
494
+ cakemail lists accept-policy <id>
495
+
496
+ # Manage subscription forms
497
+ cakemail lists forms <id>
498
+ cakemail lists form-create <id> -d "example.com" -n "Signup Form"
499
+ cakemail lists form-delete <list-id> <form-id> --force
500
+ ```
501
+
502
+ #### Extended Email API (NEW in v1.3)
503
+
504
+ ```bash
505
+ # View Email API logs
506
+ cakemail emails logs --from 2025-01-01 --to 2025-12-31
507
+ cakemail emails logs --tag newsletter --status delivered
508
+
509
+ # List all email tags
510
+ cakemail emails tags
511
+ ```
512
+
373
513
  ## Examples
374
514
 
375
515
  ```bash
package/dist/cli.js CHANGED
@@ -10,22 +10,37 @@ import { createSendersCommand } from './commands/senders.js';
10
10
  import { createWebhooksCommand } from './commands/webhooks.js';
11
11
  import { createEmailsCommand } from './commands/emails.js';
12
12
  import { createTemplatesCommand } from './commands/templates.js';
13
+ import { createReportsCommand } from './commands/reports.js';
14
+ import { createSegmentsCommand } from './commands/segments.js';
15
+ import { createAttributesCommand } from './commands/attributes.js';
16
+ import { createSuppressedCommand } from './commands/suppressed.js';
17
+ import { createAccountCommand } from './commands/account.js';
18
+ import { registerConfigCommands } from './commands/config.js';
13
19
  import chalk from 'chalk';
14
20
  async function main() {
15
21
  const program = new Command();
16
22
  program
17
23
  .name('cakemail')
18
24
  .description('Official Cakemail CLI - Command-line interface for the Cakemail API')
19
- .version('1.2.0')
25
+ .version('1.5.0')
20
26
  .option('-f, --format <format>', 'Output format (json|table|compact)')
27
+ .option('--profile <type>', 'Override profile for this command (developer|marketer|balanced)')
28
+ .option('--batch', 'Run in batch/scripting mode (disable all interactive prompts)')
21
29
  .option('--access-token <token>', 'Cakemail access token (overrides env)')
22
30
  .option('--email <email>', 'Cakemail account email (overrides env)')
23
- .option('--password <password>', 'Cakemail account password (overrides env)');
31
+ .option('--password <password>', 'Cakemail account password (overrides env)')
32
+ .option('--account <id>', 'Account ID to use for this command (overrides current account)');
24
33
  try {
25
- // Get config (don't require credentials for help/version)
26
- const config = getConfig(false);
34
+ // Check if this is a help/version command that doesn't need credentials
35
+ const args = process.argv.slice(2);
36
+ const isHelpOrVersion = args.length === 0 ||
37
+ args.includes('-h') ||
38
+ args.includes('--help') ||
39
+ args.includes('-V') ||
40
+ args.includes('--version');
41
+ // Get config with interactive authentication if needed
42
+ const config = await getConfig(!isHelpOrVersion, !isHelpOrVersion);
27
43
  // Create client and formatter with lazy format evaluation
28
- // Client will fail on first API call if credentials are missing
29
44
  const client = new CakemailClient(config);
30
45
  const formatter = new OutputFormatter(() => {
31
46
  const opts = program.opts();
@@ -36,10 +51,33 @@ async function main() {
36
51
  config.email = opts.email;
37
52
  if (opts.password)
38
53
  config.password = opts.password;
39
- // Priority: CLI flag > env var > default
54
+ if (opts.account)
55
+ config.currentAccountId = opts.account;
56
+ // Priority: CLI flag > env var > profile config > default
40
57
  return opts.format || config.outputFormat || 'json';
58
+ }, () => {
59
+ const opts = program.opts();
60
+ // Handle --batch flag by setting environment variable
61
+ if (opts.batch) {
62
+ process.env.CAKEMAIL_BATCH_MODE = 'true';
63
+ }
64
+ // Handle --profile override
65
+ if (opts.profile) {
66
+ const { getProfileConfig } = require('./utils/config-file.js');
67
+ const validProfiles = ['developer', 'marketer', 'balanced'];
68
+ if (!validProfiles.includes(opts.profile)) {
69
+ console.error(chalk.red(`Invalid profile: ${opts.profile}`));
70
+ console.error(chalk.gray(`Valid profiles: ${validProfiles.join(', ')}`));
71
+ process.exit(1);
72
+ }
73
+ return getProfileConfig(opts.profile);
74
+ }
75
+ // Return default profile config
76
+ return config.profileConfig;
41
77
  });
42
78
  // Add commands
79
+ registerConfigCommands(program);
80
+ program.addCommand(createAccountCommand(client, formatter));
43
81
  program.addCommand(createCampaignsCommand(client, formatter));
44
82
  program.addCommand(createListsCommand(client, formatter));
45
83
  program.addCommand(createContactsCommand(client, formatter));
@@ -47,6 +85,10 @@ async function main() {
47
85
  program.addCommand(createWebhooksCommand(client, formatter));
48
86
  program.addCommand(createEmailsCommand(client, formatter));
49
87
  program.addCommand(createTemplatesCommand(client, formatter));
88
+ program.addCommand(createReportsCommand(client, formatter));
89
+ program.addCommand(createSegmentsCommand(client, formatter));
90
+ program.addCommand(createAttributesCommand(client, formatter));
91
+ program.addCommand(createSuppressedCommand(client, formatter));
50
92
  // Parse
51
93
  await program.parseAsync(process.argv);
52
94
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -4,8 +4,6 @@ import { CakemailClient as SDK } from '@cakemail-org/cakemail-sdk';
4
4
  * Provides backward compatibility with our CLI while using the SDK
5
5
  */
6
6
  export class CakemailClient {
7
- sdk;
8
- config;
9
7
  constructor(config) {
10
8
  this.config = config;
11
9
  // The SDK requires email and password
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,IAAI,GAAG,EAAwB,MAAM,4BAA4B,CAAC;AASzF;;;GAGG;AACH,MAAM,OAAO,cAAc;IAClB,GAAG,CAAM;IACR,MAAM,CAAiB;IAE/B,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,sCAAsC;QACtC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,SAAS,GAAyB;YACtC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,0BAA0B;SACvF,CAAC;QAEF,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAG,CAAU,GAAW,EAAE,MAAyB;QACvD,iDAAiD;QACjD,4FAA4F;QAC5F,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;IAED,KAAK,CAAC,IAAI,CAAU,GAAW,EAAE,IAAU;QACzC,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;IAED,KAAK,CAAC,KAAK,CAAU,GAAW,EAAE,IAAU;QAC1C,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;IAED,KAAK,CAAC,MAAM,CAAU,GAAW;QAC/B,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;CACF"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,IAAI,GAAG,EAAwB,MAAM,4BAA4B,CAAC;AASzF;;;GAGG;AACH,MAAM,OAAO,cAAc;IAIzB,YAAY,MAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,sCAAsC;QACtC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,SAAS,GAAyB;YACtC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,0BAA0B;SACvF,CAAC;QAEF,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,GAAG,CAAU,GAAW,EAAE,MAAyB;QACvD,iDAAiD;QACjD,4FAA4F;QAC5F,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;IAED,KAAK,CAAC,IAAI,CAAU,GAAW,EAAE,IAAU;QACzC,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;IAED,KAAK,CAAC,KAAK,CAAU,GAAW,EAAE,IAAU;QAC1C,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;IAED,KAAK,CAAC,MAAM,CAAU,GAAW;QAC/B,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;IACvH,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import { Command } from 'commander';
2
+ import { CakemailClient } from '../client.js';
3
+ import { OutputFormatter } from '../utils/output.js';
4
+ export declare function createAccountCommand(client: CakemailClient, formatter: OutputFormatter): Command;
5
+ //# sourceMappingURL=account.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../src/commands/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAQrD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,GAAG,OAAO,CAgQhG"}
@@ -0,0 +1,231 @@
1
+ import { Command } from 'commander';
2
+ import { testCredentials } from '../utils/auth.js';
3
+ import { readFileSync, existsSync, writeFileSync } from 'fs';
4
+ import { join } from 'path';
5
+ import ora from 'ora';
6
+ import chalk from 'chalk';
7
+ import { confirmAction } from '../utils/confirm.js';
8
+ export function createAccountCommand(client, formatter) {
9
+ const account = new Command('account')
10
+ .description('Manage account context and multi-tenant access');
11
+ // Show current account
12
+ account
13
+ .command('show')
14
+ .description('Display current account details')
15
+ .action(async () => {
16
+ const spinner = ora('Fetching account details...').start();
17
+ try {
18
+ const data = await client.sdk.accountService.getSelfAccount();
19
+ spinner.stop();
20
+ const currentAccountId = process.env.CAKEMAIL_CURRENT_ACCOUNT_ID;
21
+ if (currentAccountId) {
22
+ formatter.info(`Current account context: ${currentAccountId}`);
23
+ }
24
+ formatter.output(data);
25
+ }
26
+ catch (error) {
27
+ spinner.stop();
28
+ formatter.error(error.message);
29
+ process.exit(1);
30
+ }
31
+ });
32
+ // List all accessible accounts
33
+ account
34
+ .command('list')
35
+ .description('List all accessible accounts (parent and sub-accounts)')
36
+ .option('-r, --recursive', 'Include nested sub-accounts')
37
+ .action(async (options) => {
38
+ const spinner = ora('Fetching accessible accounts...').start();
39
+ try {
40
+ // Get main account
41
+ const mainAccount = await client.sdk.accountService.getSelfAccount();
42
+ const accounts = [mainAccount.data];
43
+ // Get sub-accounts
44
+ const subAccounts = await client.sdk.subAccountService.listAccounts({
45
+ partnerAccountId: parseInt(mainAccount.data.id),
46
+ recursive: options.recursive !== false
47
+ });
48
+ if (subAccounts.data && subAccounts.data.length > 0) {
49
+ accounts.push(...subAccounts.data);
50
+ }
51
+ spinner.stop();
52
+ // Mark current account
53
+ const currentAccountId = process.env.CAKEMAIL_CURRENT_ACCOUNT_ID || mainAccount.data.id;
54
+ console.log(chalk.cyan('Available accounts:\n'));
55
+ accounts.forEach(acc => {
56
+ const isCurrent = acc.id === currentAccountId;
57
+ const marker = isCurrent ? chalk.green('• ') : ' ';
58
+ const suffix = isCurrent ? chalk.gray(' (current)') : '';
59
+ console.log(`${marker}${acc.name || `Account ${acc.id}`} (ID: ${acc.id})${suffix}`);
60
+ });
61
+ console.log('');
62
+ formatter.info(`Total accessible accounts: ${accounts.length}`);
63
+ }
64
+ catch (error) {
65
+ spinner.stop();
66
+ formatter.error(error.message);
67
+ process.exit(1);
68
+ }
69
+ });
70
+ // Switch active account
71
+ account
72
+ .command('use <id>')
73
+ .description('Switch active account context')
74
+ .action(async (id) => {
75
+ const spinner = ora('Switching account context...').start();
76
+ try {
77
+ const accountId = id;
78
+ // Verify the account exists and is accessible
79
+ // First check if it's the main account
80
+ const mainAccount = await client.sdk.accountService.getSelfAccount();
81
+ if (mainAccount.data.id === accountId) {
82
+ // It's the main account
83
+ spinner.stop();
84
+ }
85
+ else {
86
+ // Check sub-accounts
87
+ const subAccounts = await client.sdk.subAccountService.listAccounts({
88
+ partnerAccountId: parseInt(mainAccount.data.id),
89
+ recursive: true
90
+ });
91
+ const hasAccess = subAccounts.data?.some(acc => acc.id === accountId);
92
+ if (!hasAccess) {
93
+ spinner.stop();
94
+ formatter.error(`Account ${accountId} not found or not accessible`);
95
+ process.exit(1);
96
+ }
97
+ spinner.stop();
98
+ }
99
+ // Update .env file with new account context
100
+ const envPath = join(process.cwd(), '.env');
101
+ let envContent = '';
102
+ if (existsSync(envPath)) {
103
+ envContent = readFileSync(envPath, 'utf-8');
104
+ }
105
+ // Parse existing env variables
106
+ const envLines = envContent.split('\n');
107
+ const envVars = {};
108
+ envLines.forEach(line => {
109
+ const match = line.match(/^([^=]+)=(.*)$/);
110
+ if (match) {
111
+ envVars[match[1].trim()] = match[2].trim();
112
+ }
113
+ });
114
+ // Update account ID
115
+ envVars['CAKEMAIL_CURRENT_ACCOUNT_ID'] = accountId;
116
+ // Rebuild .env content
117
+ const newEnvContent = Object.entries(envVars)
118
+ .map(([key, value]) => `${key}=${value}`)
119
+ .join('\n') + '\n';
120
+ writeFileSync(envPath, newEnvContent, 'utf-8');
121
+ // Get account name for confirmation
122
+ let accountName = `Account ${accountId}`;
123
+ if (mainAccount.data.id === accountId) {
124
+ accountName = mainAccount.data.name || accountName;
125
+ }
126
+ else {
127
+ const subAccounts = await client.sdk.subAccountService.listAccounts({
128
+ partnerAccountId: parseInt(mainAccount.data.id),
129
+ recursive: true
130
+ });
131
+ const targetAccount = subAccounts.data?.find(acc => acc.id === accountId);
132
+ if (targetAccount) {
133
+ accountName = targetAccount.name || accountName;
134
+ }
135
+ }
136
+ formatter.success(`Now using: ${accountName} (ID: ${accountId})`);
137
+ }
138
+ catch (error) {
139
+ spinner.stop();
140
+ formatter.error(error.message);
141
+ process.exit(1);
142
+ }
143
+ });
144
+ // Test current credentials
145
+ account
146
+ .command('test')
147
+ .description('Validate current credentials')
148
+ .action(async () => {
149
+ const spinner = ora('Testing credentials...').start();
150
+ try {
151
+ const email = process.env.CAKEMAIL_EMAIL;
152
+ const password = process.env.CAKEMAIL_PASSWORD;
153
+ if (!email || !password) {
154
+ spinner.stop();
155
+ formatter.error('No credentials found in .env file');
156
+ process.exit(1);
157
+ }
158
+ const isValid = await testCredentials(email, password);
159
+ spinner.stop();
160
+ if (isValid) {
161
+ formatter.success('Credentials are valid');
162
+ // Show account info
163
+ const accountData = await client.sdk.accountService.getSelfAccount();
164
+ const account = accountData.data;
165
+ console.log(chalk.gray(`\nAuthenticated as: ${email}`));
166
+ console.log(chalk.gray(`Account: ${account.name || `ID ${account.id}`}`));
167
+ }
168
+ else {
169
+ formatter.error('Invalid credentials');
170
+ process.exit(1);
171
+ }
172
+ }
173
+ catch (error) {
174
+ spinner.stop();
175
+ formatter.error(error.message);
176
+ process.exit(1);
177
+ }
178
+ });
179
+ // Logout (remove credentials)
180
+ account
181
+ .command('logout')
182
+ .description('Remove credentials from .env file')
183
+ .option('-f, --force', 'Skip confirmation prompt')
184
+ .action(async (options) => {
185
+ // Interactive confirmation (unless --force is used)
186
+ if (!options.force) {
187
+ const confirmed = await confirmAction('Log out and remove credentials?', [
188
+ 'Credentials will be removed from .env file',
189
+ 'You will need to re-authenticate'
190
+ ], 'low');
191
+ if (!confirmed) {
192
+ formatter.info('Logout cancelled');
193
+ return;
194
+ }
195
+ }
196
+ try {
197
+ const envPath = join(process.cwd(), '.env');
198
+ if (!existsSync(envPath)) {
199
+ formatter.info('No .env file found');
200
+ return;
201
+ }
202
+ const envContent = readFileSync(envPath, 'utf-8');
203
+ const envLines = envContent.split('\n');
204
+ const envVars = {};
205
+ envLines.forEach(line => {
206
+ const match = line.match(/^([^=]+)=(.*)$/);
207
+ if (match) {
208
+ envVars[match[1].trim()] = match[2].trim();
209
+ }
210
+ });
211
+ // Remove auth-related variables
212
+ delete envVars['CAKEMAIL_EMAIL'];
213
+ delete envVars['CAKEMAIL_PASSWORD'];
214
+ delete envVars['CAKEMAIL_ACCESS_TOKEN'];
215
+ delete envVars['CAKEMAIL_CURRENT_ACCOUNT_ID'];
216
+ // Rebuild .env content
217
+ const newEnvContent = Object.entries(envVars)
218
+ .map(([key, value]) => `${key}=${value}`)
219
+ .join('\n') + '\n';
220
+ writeFileSync(envPath, newEnvContent, 'utf-8');
221
+ formatter.success('Logged out successfully');
222
+ formatter.info('Credentials removed from .env file');
223
+ }
224
+ catch (error) {
225
+ formatter.error(error.message);
226
+ process.exit(1);
227
+ }
228
+ });
229
+ return account;
230
+ }
231
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/commands/account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Command } from 'commander';
2
+ import { CakemailClient } from '../client.js';
3
+ import { OutputFormatter } from '../utils/output.js';
4
+ export declare function createAttributesCommand(client: CakemailClient, formatter: OutputFormatter): Command;
5
+ //# sourceMappingURL=attributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../../src/commands/attributes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKrD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,eAAe,GAAG,OAAO,CAmInG"}
@@ -0,0 +1,126 @@
1
+ import { Command } from 'commander';
2
+ import ora from 'ora';
3
+ import { confirmDelete } from '../utils/confirm.js';
4
+ import { autoDetectList } from '../utils/defaults.js';
5
+ export function createAttributesCommand(client, formatter) {
6
+ const attributes = new Command('attributes')
7
+ .description('Manage custom attributes (custom fields)');
8
+ // List attributes
9
+ attributes
10
+ .command('list [list-id]')
11
+ .description('List all custom attributes for a list (auto-detects if only one list exists)')
12
+ .action(async (listId) => {
13
+ // Auto-detect list ID if not provided
14
+ const detectedListId = await autoDetectList(client, formatter, listId, { useCache: true });
15
+ if (!detectedListId) {
16
+ process.exit(1);
17
+ }
18
+ const spinner = ora('Fetching custom attributes...').start();
19
+ try {
20
+ const data = await client.sdk.customAttributeService.listCustomAttributes({
21
+ listId: detectedListId
22
+ });
23
+ spinner.stop();
24
+ formatter.output(data);
25
+ }
26
+ catch (error) {
27
+ spinner.stop();
28
+ formatter.error(error.message);
29
+ process.exit(1);
30
+ }
31
+ });
32
+ // Get attribute
33
+ attributes
34
+ .command('get [list-id] <name>')
35
+ .description('Get custom attribute details (auto-detects if only one list exists)')
36
+ .action(async (listId, name) => {
37
+ // Auto-detect list ID if not provided
38
+ const detectedListId = await autoDetectList(client, formatter, listId, { useCache: true });
39
+ if (!detectedListId) {
40
+ process.exit(1);
41
+ }
42
+ const spinner = ora(`Fetching attribute ${name}...`).start();
43
+ try {
44
+ const data = await client.sdk.customAttributeService.getCustomAttribute({
45
+ listId: detectedListId,
46
+ name
47
+ });
48
+ spinner.stop();
49
+ formatter.output(data);
50
+ }
51
+ catch (error) {
52
+ spinner.stop();
53
+ formatter.error(error.message);
54
+ process.exit(1);
55
+ }
56
+ });
57
+ // Create attribute
58
+ attributes
59
+ .command('create [list-id]')
60
+ .description('Create a new custom attribute (auto-detects if only one list exists)')
61
+ .requiredOption('-n, --name <name>', 'Attribute name')
62
+ .requiredOption('-t, --type <type>', 'Attribute type (text, number, date, boolean)')
63
+ .action(async (listId, options) => {
64
+ // Auto-detect list ID if not provided
65
+ const detectedListId = await autoDetectList(client, formatter, listId, { useCache: true });
66
+ if (!detectedListId) {
67
+ process.exit(1);
68
+ }
69
+ const spinner = ora('Creating custom attribute...').start();
70
+ try {
71
+ const data = await client.sdk.customAttributeService.createCustomAttribute({
72
+ listId: detectedListId,
73
+ requestBody: {
74
+ name: options.name,
75
+ type: options.type
76
+ }
77
+ });
78
+ spinner.stop();
79
+ formatter.success(`Custom attribute created: ${options.name}`);
80
+ formatter.output(data);
81
+ }
82
+ catch (error) {
83
+ spinner.stop();
84
+ formatter.error(error.message);
85
+ process.exit(1);
86
+ }
87
+ });
88
+ // Delete attribute
89
+ attributes
90
+ .command('delete [list-id] <name>')
91
+ .description('Delete a custom attribute (auto-detects if only one list exists)')
92
+ .option('-f, --force', 'Skip confirmation prompt')
93
+ .action(async (listId, name, options) => {
94
+ // Auto-detect list ID if not provided
95
+ const detectedListId = await autoDetectList(client, formatter, listId, { useCache: true });
96
+ if (!detectedListId) {
97
+ process.exit(1);
98
+ }
99
+ // Interactive confirmation (unless --force is used)
100
+ if (!options.force) {
101
+ const confirmed = await confirmDelete('custom attribute', name, [
102
+ 'Attribute and all its data will be deleted from all contacts'
103
+ ]);
104
+ if (!confirmed) {
105
+ formatter.info('Deletion cancelled');
106
+ return;
107
+ }
108
+ }
109
+ const spinner = ora(`Deleting attribute ${name}...`).start();
110
+ try {
111
+ await client.sdk.customAttributeService.deleteCustomAttribute({
112
+ listId: detectedListId,
113
+ name
114
+ });
115
+ spinner.stop();
116
+ formatter.success(`Attribute ${name} deleted`);
117
+ }
118
+ catch (error) {
119
+ spinner.stop();
120
+ formatter.error(error.message);
121
+ process.exit(1);
122
+ }
123
+ });
124
+ return attributes;
125
+ }
126
+ //# sourceMappingURL=attributes.js.map