@cakemail-org/cakemail-cli 1.5.0 → 2.0.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/.claude/settings.local.json +12 -0
- package/.env.example +40 -0
- package/.env.test.example +45 -0
- package/CHANGELOG.md +1031 -0
- package/README.md +319 -15
- package/audit-formats.js +128 -0
- package/cakemail.rb +20 -0
- package/dist/cli.js +27 -10
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +16 -6
- package/dist/client.js.map +1 -1
- package/dist/commands/account.js +1 -1
- package/dist/commands/account.js.map +1 -1
- package/dist/commands/attributes.js +1 -1
- package/dist/commands/attributes.js.map +1 -1
- package/dist/commands/campaigns.d.ts.map +1 -1
- package/dist/commands/campaigns.js +103 -8
- package/dist/commands/campaigns.js.map +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +63 -4
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contacts.d.ts.map +1 -1
- package/dist/commands/contacts.js +91 -12
- package/dist/commands/contacts.js.map +1 -1
- package/dist/commands/emails.js +1 -1
- package/dist/commands/emails.js.map +1 -1
- package/dist/commands/interests.d.ts +5 -0
- package/dist/commands/interests.d.ts.map +1 -0
- package/dist/commands/interests.js +172 -0
- package/dist/commands/interests.js.map +1 -0
- package/dist/commands/lists.d.ts.map +1 -1
- package/dist/commands/lists.js +6 -8
- package/dist/commands/lists.js.map +1 -1
- package/dist/commands/logs.d.ts +5 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +237 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/reports.js +1 -1
- package/dist/commands/reports.js.map +1 -1
- package/dist/commands/segments.js +1 -1
- package/dist/commands/segments.js.map +1 -1
- package/dist/commands/senders.d.ts.map +1 -1
- package/dist/commands/senders.js +11 -8
- package/dist/commands/senders.js.map +1 -1
- package/dist/commands/suppressed.js +1 -1
- package/dist/commands/suppressed.js.map +1 -1
- package/dist/commands/tags.d.ts +5 -0
- package/dist/commands/tags.d.ts.map +1 -0
- package/dist/commands/tags.js +124 -0
- package/dist/commands/tags.js.map +1 -0
- package/dist/commands/templates.js +1 -1
- package/dist/commands/templates.js.map +1 -1
- package/dist/commands/transactional-templates.d.ts +5 -0
- package/dist/commands/transactional-templates.d.ts.map +1 -0
- package/dist/commands/transactional-templates.js +354 -0
- package/dist/commands/transactional-templates.js.map +1 -0
- package/dist/commands/webhooks.js +1 -1
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/utils/auth.d.ts +8 -1
- package/dist/utils/auth.d.ts.map +1 -1
- package/dist/utils/auth.js +39 -11
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/config-file.d.ts +7 -0
- package/dist/utils/config-file.d.ts.map +1 -1
- package/dist/utils/config-file.js +15 -0
- package/dist/utils/config-file.js.map +1 -1
- package/dist/utils/config.d.ts +2 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +12 -4
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/errors.js +1 -1
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/list-defaults.d.ts +33 -0
- package/dist/utils/list-defaults.d.ts.map +1 -0
- package/dist/utils/list-defaults.js +52 -0
- package/dist/utils/list-defaults.js.map +1 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +36 -13
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/progress.d.ts.map +1 -1
- package/dist/utils/progress.js +32 -4
- package/dist/utils/progress.js.map +1 -1
- package/dist/utils/spinner.d.ts +17 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +43 -0
- package/dist/utils/spinner.js.map +1 -0
- package/docs/DOCUMENTATION-STANDARD.md +1068 -0
- package/docs/README.md +161 -0
- package/docs/developer/ARCHITECTURE.md +516 -0
- package/docs/developer/AUTH.md +204 -0
- package/docs/developer/CONTRIBUTING.md +227 -0
- package/docs/developer/DOCUMENTATION_SUMMARY.md +346 -0
- package/docs/developer/PROJECT_INDEX.md +365 -0
- package/docs/planning/API_COVERAGE.md +1045 -0
- package/docs/planning/BACKLOG.md +1159 -0
- package/docs/planning/PROFILE_SYSTEM_TASKS.md +287 -0
- package/docs/planning/UX_IMPLEMENTATION_PLAN.md +691 -0
- package/docs/planning/archive/RELEASE_CHECKLIST_v1.3.0.md +332 -0
- package/docs/planning/archive/RELEASE_v1.3.0.md +428 -0
- package/docs/planning/archive/cakemail-cli-ux-improvements.md +438 -0
- package/docs/planning/cakemail-profile-system-plan.md +1121 -0
- package/docs/testing/AI_USER_SIMULATION_DESIGN.md +1342 -0
- package/docs/testing/KENOGAMI_BIDIRECTIONAL_FLOW.md +1517 -0
- package/docs/testing/KENOGAMI_TRUTH_RECONCILIATION_SYSTEM.md +1369 -0
- package/docs/user-manual/.obsidian/app.json +1 -0
- package/docs/user-manual/.obsidian/appearance.json +1 -0
- package/docs/user-manual/.obsidian/core-plugins.json +33 -0
- package/docs/user-manual/.obsidian/workspace.json +167 -0
- package/docs/user-manual/01-getting-started/01-installation.md +214 -0
- package/docs/user-manual/01-getting-started/02-quick-start.md +432 -0
- package/docs/user-manual/01-getting-started/03-authentication.md +448 -0
- package/docs/user-manual/01-getting-started/04-configuration.md +430 -0
- package/docs/user-manual/01-getting-started/05-output-formats.md +447 -0
- package/docs/user-manual/02-core-concepts/01-accounts.md +514 -0
- package/docs/user-manual/02-core-concepts/02-profile-system.md +771 -0
- package/docs/user-manual/02-core-concepts/03-smart-defaults.md +485 -0
- package/docs/user-manual/02-core-concepts/04-authentication-methods.md +435 -0
- package/docs/user-manual/02-core-concepts/05-pagination-filtering.md +600 -0
- package/docs/user-manual/02-core-concepts/06-error-handling.md +718 -0
- package/docs/user-manual/02-core-concepts/07-api-coverage.md +483 -0
- package/docs/user-manual/03-email-operations/01-senders.md +490 -0
- package/docs/user-manual/03-email-operations/02-templates.md +444 -0
- package/docs/user-manual/03-email-operations/03-transactional-emails.md +706 -0
- package/docs/user-manual/03-email-operations/04-email-tracking.md +407 -0
- package/docs/user-manual/04-campaign-management/01-campaigns-basics.md +394 -0
- package/docs/user-manual/04-campaign-management/02-campaign-scheduling.md +630 -0
- package/docs/user-manual/04-campaign-management/03-campaign-testing.md +997 -0
- package/docs/user-manual/04-campaign-management/04-campaign-lifecycle.md +709 -0
- package/docs/user-manual/04-campaign-management/05-campaign-links.md +934 -0
- package/docs/user-manual/05-contact-management/01-lists.md +836 -0
- package/docs/user-manual/05-contact-management/02-contacts.md +1035 -0
- package/docs/user-manual/05-contact-management/03-custom-attributes.md +788 -0
- package/docs/user-manual/05-contact-management/04-segments.md +1028 -0
- package/docs/user-manual/05-contact-management/05-contact-import-export.md +1031 -0
- package/docs/user-manual/06-analytics-reporting/01-campaign-analytics.md +867 -0
- package/docs/user-manual/06-analytics-reporting/02-account-reports.md +227 -0
- package/docs/user-manual/07-integrations/01-webhooks-integration.md +259 -0
- package/docs/user-manual/07-integrations/02-automation.md +326 -0
- package/docs/user-manual/08-advanced-usage/01-scripting-patterns.md +672 -0
- package/docs/user-manual/08-advanced-usage/02-bulk-operations.md +932 -0
- package/docs/user-manual/08-advanced-usage/03-ci-cd-integration.md +892 -0
- package/docs/user-manual/08-advanced-usage/04-performance-optimization.md +766 -0
- package/docs/user-manual/09-command-reference/01-config.md +776 -0
- package/docs/user-manual/09-command-reference/02-account.md +652 -0
- package/docs/user-manual/09-command-reference/03-lists.md +958 -0
- package/docs/user-manual/09-command-reference/04-contacts.md +1408 -0
- package/docs/user-manual/09-command-reference/05-attributes.md +617 -0
- package/docs/user-manual/09-command-reference/06-segments.md +894 -0
- package/docs/user-manual/09-command-reference/07-senders.md +803 -0
- package/docs/user-manual/09-command-reference/08-templates.md +818 -0
- package/docs/user-manual/09-command-reference/09-campaigns.md +1250 -0
- package/docs/user-manual/09-command-reference/10-emails.md +807 -0
- package/docs/user-manual/09-command-reference/11-reports.md +1135 -0
- package/docs/user-manual/09-command-reference/12-webhooks.md +773 -0
- package/docs/user-manual/09-command-reference/13-suppressed.md +797 -0
- package/docs/user-manual/09-command-reference/14-interests.md +630 -0
- package/docs/user-manual/09-command-reference/15-tags.md +584 -0
- package/docs/user-manual/09-command-reference/16-logs.md +656 -0
- package/docs/user-manual/09-command-reference/17-transactional-templates.md +850 -0
- package/docs/user-manual/10-troubleshooting/01-common-errors.md +457 -0
- package/docs/user-manual/10-troubleshooting/02-authentication-issues.md +558 -0
- package/docs/user-manual/10-troubleshooting/03-connection-problems.md +634 -0
- package/docs/user-manual/10-troubleshooting/04-debugging.md +725 -0
- package/docs/user-manual/11-appendix/04-faq.md +484 -0
- package/docs/user-manual/11-appendix/05-glossary.md +250 -0
- package/docs/user-manual/README.md +0 -0
- package/package.json +13 -47
- package/src/cli.ts +125 -0
- package/src/client.ts +16 -0
- package/src/commands/account.ts +267 -0
- package/src/commands/accounts.ts +78 -0
- package/src/commands/actions.ts +249 -0
- package/src/commands/attributes.ts +139 -0
- package/src/commands/campaign-blueprints.ts +106 -0
- package/src/commands/campaigns.ts +469 -0
- package/src/commands/config.ts +77 -0
- package/src/commands/contacts.ts +612 -0
- package/src/commands/custom-attributes.ts +127 -0
- package/src/commands/dkims.ts +117 -0
- package/src/commands/domains.ts +82 -0
- package/src/commands/email-apis.ts +569 -0
- package/src/commands/emails.ts +197 -0
- package/src/commands/forms.ts +283 -0
- package/src/commands/interests.ts +155 -0
- package/src/commands/links.ts +38 -0
- package/src/commands/lists.ts +406 -0
- package/src/commands/logos.ts +71 -0
- package/src/commands/logs.ts +386 -0
- package/src/commands/reports.ts +306 -0
- package/src/commands/segments.ts +158 -0
- package/src/commands/senders.ts +204 -0
- package/src/commands/sub-accounts.ts +271 -0
- package/src/commands/suppressed-emails.ts +234 -0
- package/src/commands/suppressed.ts +198 -0
- package/src/commands/system-emails.ts +85 -0
- package/src/commands/tags.ts +146 -0
- package/src/commands/tasks.ts +116 -0
- package/src/commands/templates.ts +189 -0
- package/src/commands/tokens.ts +83 -0
- package/src/commands/transactional-emails.ts +374 -0
- package/src/commands/transactional-templates.ts +385 -0
- package/src/commands/users.ts +506 -0
- package/src/commands/webhooks.ts +172 -0
- package/src/commands/workflow-blueprints.ts +123 -0
- package/src/commands/workflows.ts +265 -0
- package/src/types/profile.ts +93 -0
- package/src/utils/auth.ts +272 -0
- package/src/utils/config-file.ts +96 -0
- package/src/utils/config.ts +134 -0
- package/src/utils/confirm.ts +32 -0
- package/src/utils/defaults.ts +99 -0
- package/src/utils/errors.ts +116 -0
- package/src/utils/interactive.ts +91 -0
- package/src/utils/list-defaults.ts +74 -0
- package/src/utils/output.ts +190 -0
- package/src/utils/progress.ts +320 -0
- package/src/utils/spinner.ts +22 -0
- package/tests/IMPLEMENTATION_STATUS.md +258 -0
- package/tests/PTY_SETUP.md +118 -0
- package/tests/PTY_TESTING_GUIDE.md +507 -0
- package/tests/README.md +244 -0
- package/tests/fixtures/api-responses/campaigns.json +34 -0
- package/tests/fixtures/test-config.json +13 -0
- package/tests/helpers/cli-runner.ts +128 -0
- package/tests/helpers/mock-server.ts +301 -0
- package/tests/helpers/pty-runner.ts +181 -0
- package/tests/integration/campaigns-real-api.test.ts +196 -0
- package/tests/integration/setup-integration.ts +50 -0
- package/tests/pty/campaigns.test.ts +241 -0
- package/tests/setup.ts +34 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +28 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
// ABOUTME: CLI commands for Email API.
|
|
2
|
+
// ABOUTME: Generated by api-kit from the OpenAPI spec.
|
|
3
|
+
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { createSpinner } from '../utils/spinner.js';
|
|
6
|
+
|
|
7
|
+
export function createEmailApisCommand(
|
|
8
|
+
client: any,
|
|
9
|
+
formatter: any
|
|
10
|
+
): Command {
|
|
11
|
+
const cmd = new Command('email-apis')
|
|
12
|
+
.description('Submit and track individual transactional emails. The Email API provides full control over email content, tracking, and delivery. Each email goes through a lifecycle: submitted, queued, delivered, with events for opens, clicks, bounces, and unsubscribes. Includes statistics, activity logs, and tag-based organization.');
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
cmd
|
|
16
|
+
.command('submit-email')
|
|
17
|
+
.description('Submit an email')
|
|
18
|
+
.option('--account-id <value>', 'Optional Account ID to be used for the request')
|
|
19
|
+
.requiredOption('--data <value>', 'Request body as JSON string')
|
|
20
|
+
.action(async (options) => {
|
|
21
|
+
const spinner = createSpinner('Creating email api...').start();
|
|
22
|
+
try {
|
|
23
|
+
const body = JSON.parse(options.data);
|
|
24
|
+
const data = await client.submitEmail({
|
|
25
|
+
...body,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
spinner.stop();
|
|
29
|
+
formatter.success('Email API created successfully');
|
|
30
|
+
formatter.output(data);
|
|
31
|
+
} catch (error: any) {
|
|
32
|
+
spinner.stop();
|
|
33
|
+
formatter.error(error.message);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
cmd
|
|
40
|
+
.command('show-email <email-id>')
|
|
41
|
+
.description('Retrieve a submitted email')
|
|
42
|
+
.option('--account-id <value>', 'Optional Account ID to be used for the request')
|
|
43
|
+
.action(async (email_id, options) => {
|
|
44
|
+
const spinner = createSpinner('Fetching email api...').start();
|
|
45
|
+
try {
|
|
46
|
+
const data = await client.showEmail({
|
|
47
|
+
email_id,
|
|
48
|
+
accountId: options.accountId != null ? Number(options.accountId) : undefined,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
spinner.stop();
|
|
52
|
+
formatter.output(data);
|
|
53
|
+
} catch (error: any) {
|
|
54
|
+
spinner.stop();
|
|
55
|
+
formatter.error(error.message);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
cmd
|
|
62
|
+
.command('render-email <email-id>')
|
|
63
|
+
.description('Render a submitted email')
|
|
64
|
+
.option('--as-submitted <value>', 'Render the original submitted content of the email')
|
|
65
|
+
.option('--tracking <value>', 'Enable tracking')
|
|
66
|
+
.option('--account-id <value>', 'Optional Account ID to be used for the request')
|
|
67
|
+
.action(async (email_id, options) => {
|
|
68
|
+
const spinner = createSpinner('Fetching email api...').start();
|
|
69
|
+
try {
|
|
70
|
+
const data = await client.renderEmail({
|
|
71
|
+
email_id,
|
|
72
|
+
asSubmitted: options.asSubmitted,
|
|
73
|
+
tracking: options.tracking,
|
|
74
|
+
accountId: options.accountId != null ? Number(options.accountId) : undefined,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
spinner.stop();
|
|
78
|
+
formatter.output(data);
|
|
79
|
+
} catch (error: any) {
|
|
80
|
+
spinner.stop();
|
|
81
|
+
formatter.error(error.message);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
cmd
|
|
88
|
+
.command('list-email-tags')
|
|
89
|
+
.description('List Email Tags')
|
|
90
|
+
.option('--type <value>', 'Query tags from the `emails` or `events` table. Required when using `start_time`, `end_time`, or `tags` filters.')
|
|
91
|
+
.option('--start-time <value>', 'start_time')
|
|
92
|
+
.option('--end-time <value>', 'end_time')
|
|
93
|
+
.option('--account-id <value>', 'Optional Account ID to be used for the request')
|
|
94
|
+
.option('--page <value>', 'page')
|
|
95
|
+
.option('--per-page <value>', 'per_page')
|
|
96
|
+
.option('--with-count <value>', 'Include count in the response')
|
|
97
|
+
.option('--name <value>', 'Tag name to filter by, with optional operator.
|
|
98
|
+
|
|
99
|
+
#### Operators:
|
|
100
|
+
==: Exact match (default)
|
|
101
|
+
!=: Not equal
|
|
102
|
+
~~: Like (anywhere in the email)
|
|
103
|
+
!~: Not like (anywhere in the email)
|
|
104
|
+
')
|
|
105
|
+
.option('--tags <value>', '### Recursive Filter Query Language
|
|
106
|
+
|
|
107
|
+
The filter is a JSON object that represents a recursive query structure. It uses the logical operators `and`, `or`, `not` and `is` as keys, with the following types of values:
|
|
108
|
+
|
|
109
|
+
1. **`object`**: A nested filter object that defines additional conditions.
|
|
110
|
+
|
|
111
|
+
2. **`string`**: A condition expressed as a single string.
|
|
112
|
+
|
|
113
|
+
3. **`array`**: An array of strings (conditions) or nested filter objects.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
- The `and` and `or` operators accept `object` and `array`
|
|
117
|
+
|
|
118
|
+
- The `not` operator accepts `object` and `string`
|
|
119
|
+
|
|
120
|
+
- The `is` operator accepts `object` and `string`
|
|
121
|
+
|
|
122
|
+
### Examples
|
|
123
|
+
|
|
124
|
+
#### 1. Simple condition with a string
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{ "is": "condition1" }
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### 2. Array of strings
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{ "or": ["condition1", "condition2"] }
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### 3. Nested filter object
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{ "not": { "and": ["condition1", "condition2"] } }
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### 4. Complex recursive query
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{ "and": [ { "or": ["condition1", "condition2"] }, { "not": { "and": ["condition3", "condition4"] } } ] }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
')
|
|
149
|
+
.action(async (options) => {
|
|
150
|
+
const spinner = createSpinner('Fetching email api...').start();
|
|
151
|
+
try {
|
|
152
|
+
const data = await client.listEmailTags({
|
|
153
|
+
type: options.type,
|
|
154
|
+
startTime: options.startTime != null ? Number(options.startTime) : undefined,
|
|
155
|
+
endTime: options.endTime != null ? Number(options.endTime) : undefined,
|
|
156
|
+
accountId: options.accountId != null ? Number(options.accountId) : undefined,
|
|
157
|
+
page: options.page != null ? Number(options.page) : undefined,
|
|
158
|
+
perPage: options.perPage != null ? Number(options.perPage) : undefined,
|
|
159
|
+
withCount: options.withCount,
|
|
160
|
+
name: options.name,
|
|
161
|
+
tags: options.tags,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
spinner.stop();
|
|
165
|
+
formatter.output(data);
|
|
166
|
+
} catch (error: any) {
|
|
167
|
+
spinner.stop();
|
|
168
|
+
formatter.error(error.message);
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
cmd
|
|
175
|
+
.command('get-email-apilogs')
|
|
176
|
+
.description('Show Email API activity logs')
|
|
177
|
+
.option('--log-type <value>', 'log_type')
|
|
178
|
+
.option('--email-id <value>', 'email_id')
|
|
179
|
+
.option('--iso-time <value>', 'Convert timestamps to human readable ISO format')
|
|
180
|
+
.option('--account-id <value>', 'Optional Account ID to be used for the request')
|
|
181
|
+
.option('--page <value>', 'page')
|
|
182
|
+
.option('--per-page <value>', 'per_page')
|
|
183
|
+
.option('--start-time <value>', 'Start time for the report, defaults to 7 days ago.')
|
|
184
|
+
.option('--end-time <value>', 'End time for the report, defaults to the current time.')
|
|
185
|
+
.option('--tags <value>', '### Recursive Filter Query Language
|
|
186
|
+
|
|
187
|
+
The filter is a JSON object that represents a recursive query structure. It uses the logical operators `and`, `or`, `not` and `is` as keys, with the following types of values:
|
|
188
|
+
|
|
189
|
+
1. **`object`**: A nested filter object that defines additional conditions.
|
|
190
|
+
|
|
191
|
+
2. **`string`**: A condition expressed as a single string.
|
|
192
|
+
|
|
193
|
+
3. **`array`**: An array of strings (conditions) or nested filter objects.
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
- The `and` and `or` operators accept `object` and `array`
|
|
197
|
+
|
|
198
|
+
- The `not` operator accepts `object` and `string`
|
|
199
|
+
|
|
200
|
+
- The `is` operator accepts `object` and `string`
|
|
201
|
+
|
|
202
|
+
### Examples
|
|
203
|
+
|
|
204
|
+
#### 1. Simple condition with a string
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{ "is": "condition1" }
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### 2. Array of strings
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{ "or": ["condition1", "condition2"] }
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### 3. Nested filter object
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{ "not": { "and": ["condition1", "condition2"] } }
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### 4. Complex recursive query
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{ "and": [ { "or": ["condition1", "condition2"] }, { "not": { "and": ["condition3", "condition4"] } } ] }
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
')
|
|
229
|
+
.option('--providers <value>', '### Recursive Filter Query Language
|
|
230
|
+
|
|
231
|
+
The filter is a JSON object that represents a recursive query structure. It uses the logical operators `and`, `or`, `not` and `is` as keys, with the following types of values:
|
|
232
|
+
|
|
233
|
+
1. **`object`**: A nested filter object that defines additional conditions.
|
|
234
|
+
|
|
235
|
+
2. **`string`**: A condition expressed as a single string.
|
|
236
|
+
|
|
237
|
+
3. **`array`**: An array of strings (conditions) or nested filter objects.
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
- The `and` and `or` operators accept `object` and `array`
|
|
241
|
+
|
|
242
|
+
- The `not` operator accepts `object` and `string`
|
|
243
|
+
|
|
244
|
+
- The `is` operator accepts `object` and `string`
|
|
245
|
+
|
|
246
|
+
### Examples
|
|
247
|
+
|
|
248
|
+
#### 1. Simple condition with a string
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{ "is": "condition1" }
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
#### 2. Array of strings
|
|
255
|
+
|
|
256
|
+
```json
|
|
257
|
+
{ "or": ["condition1", "condition2"] }
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### 3. Nested filter object
|
|
261
|
+
|
|
262
|
+
```json
|
|
263
|
+
{ "not": { "and": ["condition1", "condition2"] } }
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### 4. Complex recursive query
|
|
267
|
+
|
|
268
|
+
```json
|
|
269
|
+
{ "and": [ { "or": ["condition1", "condition2"] }, { "not": { "and": ["condition3", "condition4"] } } ] }
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
')
|
|
273
|
+
.option('--sort <value>', 'Sort term and direction, using syntax `[-|+]term`.
|
|
274
|
+
|
|
275
|
+
Valid terms:
|
|
276
|
+
- `id`
|
|
277
|
+
- `time`
|
|
278
|
+
- `submitted_time`
|
|
279
|
+
- `type`
|
|
280
|
+
- `provider`')
|
|
281
|
+
.action(async (options) => {
|
|
282
|
+
const spinner = createSpinner('Fetching email api...').start();
|
|
283
|
+
try {
|
|
284
|
+
const data = await client.getEmailAPILogs({
|
|
285
|
+
logType: options.logType,
|
|
286
|
+
emailId: options.emailId,
|
|
287
|
+
isoTime: options.isoTime,
|
|
288
|
+
accountId: options.accountId != null ? Number(options.accountId) : undefined,
|
|
289
|
+
page: options.page != null ? Number(options.page) : undefined,
|
|
290
|
+
perPage: options.perPage != null ? Number(options.perPage) : undefined,
|
|
291
|
+
startTime: options.startTime != null ? Number(options.startTime) : undefined,
|
|
292
|
+
endTime: options.endTime != null ? Number(options.endTime) : undefined,
|
|
293
|
+
tags: options.tags,
|
|
294
|
+
providers: options.providers,
|
|
295
|
+
sort: options.sort,
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
spinner.stop();
|
|
299
|
+
formatter.output(data);
|
|
300
|
+
} catch (error: any) {
|
|
301
|
+
spinner.stop();
|
|
302
|
+
formatter.error(error.message);
|
|
303
|
+
process.exit(1);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
cmd
|
|
309
|
+
.command('get-email-apisummary')
|
|
310
|
+
.description('Show Email API activity summary')
|
|
311
|
+
.option('--email-id <value>', 'email_id')
|
|
312
|
+
.option('--engagement <value>', 'engagement')
|
|
313
|
+
.option('--status <value>', 'status')
|
|
314
|
+
.option('--iso-time <value>', 'Convert timestamps to human readable ISO format')
|
|
315
|
+
.option('--account-id <value>', 'Optional Account ID to be used for the request')
|
|
316
|
+
.option('--page <value>', 'page')
|
|
317
|
+
.option('--per-page <value>', 'per_page')
|
|
318
|
+
.option('--start-time <value>', 'Start time for the report, defaults to 7 days ago.')
|
|
319
|
+
.option('--end-time <value>', 'End time for the report, defaults to the current time.')
|
|
320
|
+
.option('--tags <value>', '### Recursive Filter Query Language
|
|
321
|
+
|
|
322
|
+
The filter is a JSON object that represents a recursive query structure. It uses the logical operators `and`, `or`, `not` and `is` as keys, with the following types of values:
|
|
323
|
+
|
|
324
|
+
1. **`object`**: A nested filter object that defines additional conditions.
|
|
325
|
+
|
|
326
|
+
2. **`string`**: A condition expressed as a single string.
|
|
327
|
+
|
|
328
|
+
3. **`array`**: An array of strings (conditions) or nested filter objects.
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
- The `and` and `or` operators accept `object` and `array`
|
|
332
|
+
|
|
333
|
+
- The `not` operator accepts `object` and `string`
|
|
334
|
+
|
|
335
|
+
- The `is` operator accepts `object` and `string`
|
|
336
|
+
|
|
337
|
+
### Examples
|
|
338
|
+
|
|
339
|
+
#### 1. Simple condition with a string
|
|
340
|
+
|
|
341
|
+
```json
|
|
342
|
+
{ "is": "condition1" }
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
#### 2. Array of strings
|
|
346
|
+
|
|
347
|
+
```json
|
|
348
|
+
{ "or": ["condition1", "condition2"] }
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
#### 3. Nested filter object
|
|
352
|
+
|
|
353
|
+
```json
|
|
354
|
+
{ "not": { "and": ["condition1", "condition2"] } }
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### 4. Complex recursive query
|
|
358
|
+
|
|
359
|
+
```json
|
|
360
|
+
{ "and": [ { "or": ["condition1", "condition2"] }, { "not": { "and": ["condition3", "condition4"] } } ] }
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
')
|
|
364
|
+
.option('--providers <value>', '### Recursive Filter Query Language
|
|
365
|
+
|
|
366
|
+
The filter is a JSON object that represents a recursive query structure. It uses the logical operators `and`, `or`, `not` and `is` as keys, with the following types of values:
|
|
367
|
+
|
|
368
|
+
1. **`object`**: A nested filter object that defines additional conditions.
|
|
369
|
+
|
|
370
|
+
2. **`string`**: A condition expressed as a single string.
|
|
371
|
+
|
|
372
|
+
3. **`array`**: An array of strings (conditions) or nested filter objects.
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
- The `and` and `or` operators accept `object` and `array`
|
|
376
|
+
|
|
377
|
+
- The `not` operator accepts `object` and `string`
|
|
378
|
+
|
|
379
|
+
- The `is` operator accepts `object` and `string`
|
|
380
|
+
|
|
381
|
+
### Examples
|
|
382
|
+
|
|
383
|
+
#### 1. Simple condition with a string
|
|
384
|
+
|
|
385
|
+
```json
|
|
386
|
+
{ "is": "condition1" }
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
#### 2. Array of strings
|
|
390
|
+
|
|
391
|
+
```json
|
|
392
|
+
{ "or": ["condition1", "condition2"] }
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
#### 3. Nested filter object
|
|
396
|
+
|
|
397
|
+
```json
|
|
398
|
+
{ "not": { "and": ["condition1", "condition2"] } }
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
#### 4. Complex recursive query
|
|
402
|
+
|
|
403
|
+
```json
|
|
404
|
+
{ "and": [ { "or": ["condition1", "condition2"] }, { "not": { "and": ["condition3", "condition4"] } } ] }
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
')
|
|
408
|
+
.option('--sort <value>', 'Sort term and direction, using syntax `[-|+]term`.
|
|
409
|
+
|
|
410
|
+
Valid terms:
|
|
411
|
+
- `submitted_time`')
|
|
412
|
+
.option('--email <value>', 'Email address to filter by, with optional operator.
|
|
413
|
+
|
|
414
|
+
#### Operators:
|
|
415
|
+
==: Exact match (default)
|
|
416
|
+
!=: Not equal
|
|
417
|
+
~~: Like (anywhere in the email)
|
|
418
|
+
!~: Not like (anywhere in the email)
|
|
419
|
+
')
|
|
420
|
+
.action(async (options) => {
|
|
421
|
+
const spinner = createSpinner('Fetching email api...').start();
|
|
422
|
+
try {
|
|
423
|
+
const data = await client.getEmailAPISummary({
|
|
424
|
+
emailId: options.emailId,
|
|
425
|
+
engagement: options.engagement,
|
|
426
|
+
status: options.status,
|
|
427
|
+
isoTime: options.isoTime,
|
|
428
|
+
accountId: options.accountId != null ? Number(options.accountId) : undefined,
|
|
429
|
+
page: options.page != null ? Number(options.page) : undefined,
|
|
430
|
+
perPage: options.perPage != null ? Number(options.perPage) : undefined,
|
|
431
|
+
startTime: options.startTime != null ? Number(options.startTime) : undefined,
|
|
432
|
+
endTime: options.endTime != null ? Number(options.endTime) : undefined,
|
|
433
|
+
tags: options.tags,
|
|
434
|
+
providers: options.providers,
|
|
435
|
+
sort: options.sort,
|
|
436
|
+
email: options.email,
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
spinner.stop();
|
|
440
|
+
formatter.output(data);
|
|
441
|
+
} catch (error: any) {
|
|
442
|
+
spinner.stop();
|
|
443
|
+
formatter.error(error.message);
|
|
444
|
+
process.exit(1);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
cmd
|
|
450
|
+
.command('get-email-apistats')
|
|
451
|
+
.description('Show Email API statistics')
|
|
452
|
+
.option('--interval <value>', 'interval')
|
|
453
|
+
.option('--iso-time <value>', 'Convert timestamps to human readable ISO format')
|
|
454
|
+
.option('--account-id <value>', 'Optional Account ID to be used for the request')
|
|
455
|
+
.option('--start-time <value>', 'Start time for the report.')
|
|
456
|
+
.option('--end-time <value>', 'End time for the report.')
|
|
457
|
+
.option('--providers <value>', '### Recursive Filter Query Language
|
|
458
|
+
|
|
459
|
+
The filter is a JSON object that represents a recursive query structure. It uses the logical operators `and`, `or`, `not` and `is` as keys, with the following types of values:
|
|
460
|
+
|
|
461
|
+
1. **`object`**: A nested filter object that defines additional conditions.
|
|
462
|
+
|
|
463
|
+
2. **`string`**: A condition expressed as a single string.
|
|
464
|
+
|
|
465
|
+
3. **`array`**: An array of strings (conditions) or nested filter objects.
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
- The `and` and `or` operators accept `object` and `array`
|
|
469
|
+
|
|
470
|
+
- The `not` operator accepts `object` and `string`
|
|
471
|
+
|
|
472
|
+
- The `is` operator accepts `object` and `string`
|
|
473
|
+
|
|
474
|
+
### Examples
|
|
475
|
+
|
|
476
|
+
#### 1. Simple condition with a string
|
|
477
|
+
|
|
478
|
+
```json
|
|
479
|
+
{ "is": "condition1" }
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
#### 2. Array of strings
|
|
483
|
+
|
|
484
|
+
```json
|
|
485
|
+
{ "or": ["condition1", "condition2"] }
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
#### 3. Nested filter object
|
|
489
|
+
|
|
490
|
+
```json
|
|
491
|
+
{ "not": { "and": ["condition1", "condition2"] } }
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
#### 4. Complex recursive query
|
|
495
|
+
|
|
496
|
+
```json
|
|
497
|
+
{ "and": [ { "or": ["condition1", "condition2"] }, { "not": { "and": ["condition3", "condition4"] } } ] }
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
')
|
|
501
|
+
.option('--tags <value>', '### Recursive Filter Query Language
|
|
502
|
+
|
|
503
|
+
The filter is a JSON object that represents a recursive query structure. It uses the logical operators `and`, `or`, `not` and `is` as keys, with the following types of values:
|
|
504
|
+
|
|
505
|
+
1. **`object`**: A nested filter object that defines additional conditions.
|
|
506
|
+
|
|
507
|
+
2. **`string`**: A condition expressed as a single string.
|
|
508
|
+
|
|
509
|
+
3. **`array`**: An array of strings (conditions) or nested filter objects.
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
- The `and` and `or` operators accept `object` and `array`
|
|
513
|
+
|
|
514
|
+
- The `not` operator accepts `object` and `string`
|
|
515
|
+
|
|
516
|
+
- The `is` operator accepts `object` and `string`
|
|
517
|
+
|
|
518
|
+
### Examples
|
|
519
|
+
|
|
520
|
+
#### 1. Simple condition with a string
|
|
521
|
+
|
|
522
|
+
```json
|
|
523
|
+
{ "is": "condition1" }
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
#### 2. Array of strings
|
|
527
|
+
|
|
528
|
+
```json
|
|
529
|
+
{ "or": ["condition1", "condition2"] }
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
#### 3. Nested filter object
|
|
533
|
+
|
|
534
|
+
```json
|
|
535
|
+
{ "not": { "and": ["condition1", "condition2"] } }
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
#### 4. Complex recursive query
|
|
539
|
+
|
|
540
|
+
```json
|
|
541
|
+
{ "and": [ { "or": ["condition1", "condition2"] }, { "not": { "and": ["condition3", "condition4"] } } ] }
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
')
|
|
545
|
+
.action(async (options) => {
|
|
546
|
+
const spinner = createSpinner('Fetching email api...').start();
|
|
547
|
+
try {
|
|
548
|
+
const data = await client.getEmailAPIStats({
|
|
549
|
+
interval: options.interval,
|
|
550
|
+
isoTime: options.isoTime,
|
|
551
|
+
accountId: options.accountId != null ? Number(options.accountId) : undefined,
|
|
552
|
+
startTime: options.startTime != null ? Number(options.startTime) : undefined,
|
|
553
|
+
endTime: options.endTime != null ? Number(options.endTime) : undefined,
|
|
554
|
+
providers: options.providers,
|
|
555
|
+
tags: options.tags,
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
spinner.stop();
|
|
559
|
+
formatter.output(data);
|
|
560
|
+
} catch (error: any) {
|
|
561
|
+
spinner.stop();
|
|
562
|
+
formatter.error(error.message);
|
|
563
|
+
process.exit(1);
|
|
564
|
+
}
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
return cmd;
|
|
569
|
+
}
|