@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.
- package/README.md +140 -0
- package/dist/cli.js +48 -6
- package/dist/cli.js.map +1 -1
- package/dist/client.js +0 -2
- package/dist/client.js.map +1 -1
- package/dist/commands/account.d.ts +5 -0
- package/dist/commands/account.d.ts.map +1 -0
- package/dist/commands/account.js +231 -0
- package/dist/commands/account.js.map +1 -0
- package/dist/commands/attributes.d.ts +5 -0
- package/dist/commands/attributes.d.ts.map +1 -0
- package/dist/commands/attributes.js +126 -0
- package/dist/commands/attributes.js.map +1 -0
- package/dist/commands/campaigns.d.ts.map +1 -1
- package/dist/commands/campaigns.js +153 -19
- package/dist/commands/campaigns.js.map +1 -1
- package/dist/commands/config.d.ts +8 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +235 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/contacts.d.ts.map +1 -1
- package/dist/commands/contacts.js +436 -14
- package/dist/commands/contacts.js.map +1 -1
- package/dist/commands/emails.d.ts.map +1 -1
- package/dist/commands/emails.js +53 -0
- package/dist/commands/emails.js.map +1 -1
- package/dist/commands/lists.d.ts.map +1 -1
- package/dist/commands/lists.js +282 -11
- package/dist/commands/lists.js.map +1 -1
- package/dist/commands/reports.d.ts +5 -0
- package/dist/commands/reports.d.ts.map +1 -0
- package/dist/commands/reports.js +334 -0
- package/dist/commands/reports.js.map +1 -0
- package/dist/commands/segments.d.ts +5 -0
- package/dist/commands/segments.d.ts.map +1 -0
- package/dist/commands/segments.js +203 -0
- package/dist/commands/segments.js.map +1 -0
- package/dist/commands/senders.d.ts.map +1 -1
- package/dist/commands/senders.js +36 -5
- package/dist/commands/senders.js.map +1 -1
- package/dist/commands/suppressed.d.ts +5 -0
- package/dist/commands/suppressed.d.ts.map +1 -0
- package/dist/commands/suppressed.js +193 -0
- package/dist/commands/suppressed.js.map +1 -0
- package/dist/commands/templates.d.ts.map +1 -1
- package/dist/commands/templates.js +11 -3
- package/dist/commands/templates.js.map +1 -1
- package/dist/types/profile.d.ts +92 -0
- package/dist/types/profile.d.ts.map +1 -0
- package/dist/types/profile.js +119 -0
- package/dist/types/profile.js.map +1 -0
- package/dist/utils/auth.d.ts +26 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +198 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/config-file.d.ts +92 -0
- package/dist/utils/config-file.d.ts.map +1 -0
- package/dist/utils/config-file.js +244 -0
- package/dist/utils/config-file.js.map +1 -0
- package/dist/utils/config.d.ts +11 -2
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +74 -8
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/confirm.d.ts +38 -0
- package/dist/utils/confirm.d.ts.map +1 -0
- package/dist/utils/confirm.js +124 -0
- package/dist/utils/confirm.js.map +1 -0
- package/dist/utils/defaults.d.ts +39 -0
- package/dist/utils/defaults.d.ts.map +1 -0
- package/dist/utils/defaults.js +195 -0
- package/dist/utils/defaults.js.map +1 -0
- package/dist/utils/errors.d.ts +67 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +395 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/interactive.d.ts +97 -0
- package/dist/utils/interactive.d.ts.map +1 -0
- package/dist/utils/interactive.js +265 -0
- package/dist/utils/interactive.js.map +1 -0
- package/dist/utils/output.d.ts +72 -2
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +383 -37
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/progress.d.ts +139 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +216 -0
- package/dist/utils/progress.js.map +1 -0
- 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.
|
|
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
|
-
//
|
|
26
|
-
const
|
|
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
|
-
|
|
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":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAgB,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,UAAU,CAAC;SAChB,WAAW,CAAC,qEAAqE,CAAC;SAClF,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CAAC,uBAAuB,EAAE,oCAAoC,CAAC;SACrE,MAAM,CAAC,wBAAwB,EAAE,uCAAuC,CAAC;SACzE,MAAM,CAAC,iBAAiB,EAAE,wCAAwC,CAAC;SACnE,MAAM,CAAC,uBAAuB,EAAE,2CAA2C,CAAC,CAAC;
|
|
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
|
package/dist/client.js.map
CHANGED
|
@@ -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;
|
|
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
|