@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.
Files changed (234) hide show
  1. package/.claude/settings.local.json +12 -0
  2. package/.env.example +40 -0
  3. package/.env.test.example +45 -0
  4. package/CHANGELOG.md +1031 -0
  5. package/README.md +319 -15
  6. package/audit-formats.js +128 -0
  7. package/cakemail.rb +20 -0
  8. package/dist/cli.js +27 -10
  9. package/dist/cli.js.map +1 -1
  10. package/dist/client.d.ts +2 -0
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +16 -6
  13. package/dist/client.js.map +1 -1
  14. package/dist/commands/account.js +1 -1
  15. package/dist/commands/account.js.map +1 -1
  16. package/dist/commands/attributes.js +1 -1
  17. package/dist/commands/attributes.js.map +1 -1
  18. package/dist/commands/campaigns.d.ts.map +1 -1
  19. package/dist/commands/campaigns.js +103 -8
  20. package/dist/commands/campaigns.js.map +1 -1
  21. package/dist/commands/config.d.ts.map +1 -1
  22. package/dist/commands/config.js +63 -4
  23. package/dist/commands/config.js.map +1 -1
  24. package/dist/commands/contacts.d.ts.map +1 -1
  25. package/dist/commands/contacts.js +91 -12
  26. package/dist/commands/contacts.js.map +1 -1
  27. package/dist/commands/emails.js +1 -1
  28. package/dist/commands/emails.js.map +1 -1
  29. package/dist/commands/interests.d.ts +5 -0
  30. package/dist/commands/interests.d.ts.map +1 -0
  31. package/dist/commands/interests.js +172 -0
  32. package/dist/commands/interests.js.map +1 -0
  33. package/dist/commands/lists.d.ts.map +1 -1
  34. package/dist/commands/lists.js +6 -8
  35. package/dist/commands/lists.js.map +1 -1
  36. package/dist/commands/logs.d.ts +5 -0
  37. package/dist/commands/logs.d.ts.map +1 -0
  38. package/dist/commands/logs.js +237 -0
  39. package/dist/commands/logs.js.map +1 -0
  40. package/dist/commands/reports.js +1 -1
  41. package/dist/commands/reports.js.map +1 -1
  42. package/dist/commands/segments.js +1 -1
  43. package/dist/commands/segments.js.map +1 -1
  44. package/dist/commands/senders.d.ts.map +1 -1
  45. package/dist/commands/senders.js +11 -8
  46. package/dist/commands/senders.js.map +1 -1
  47. package/dist/commands/suppressed.js +1 -1
  48. package/dist/commands/suppressed.js.map +1 -1
  49. package/dist/commands/tags.d.ts +5 -0
  50. package/dist/commands/tags.d.ts.map +1 -0
  51. package/dist/commands/tags.js +124 -0
  52. package/dist/commands/tags.js.map +1 -0
  53. package/dist/commands/templates.js +1 -1
  54. package/dist/commands/templates.js.map +1 -1
  55. package/dist/commands/transactional-templates.d.ts +5 -0
  56. package/dist/commands/transactional-templates.d.ts.map +1 -0
  57. package/dist/commands/transactional-templates.js +354 -0
  58. package/dist/commands/transactional-templates.js.map +1 -0
  59. package/dist/commands/webhooks.js +1 -1
  60. package/dist/commands/webhooks.js.map +1 -1
  61. package/dist/utils/auth.d.ts +8 -1
  62. package/dist/utils/auth.d.ts.map +1 -1
  63. package/dist/utils/auth.js +39 -11
  64. package/dist/utils/auth.js.map +1 -1
  65. package/dist/utils/config-file.d.ts +7 -0
  66. package/dist/utils/config-file.d.ts.map +1 -1
  67. package/dist/utils/config-file.js +15 -0
  68. package/dist/utils/config-file.js.map +1 -1
  69. package/dist/utils/config.d.ts +2 -0
  70. package/dist/utils/config.d.ts.map +1 -1
  71. package/dist/utils/config.js +12 -4
  72. package/dist/utils/config.js.map +1 -1
  73. package/dist/utils/errors.js +1 -1
  74. package/dist/utils/errors.js.map +1 -1
  75. package/dist/utils/list-defaults.d.ts +33 -0
  76. package/dist/utils/list-defaults.d.ts.map +1 -0
  77. package/dist/utils/list-defaults.js +52 -0
  78. package/dist/utils/list-defaults.js.map +1 -0
  79. package/dist/utils/output.d.ts.map +1 -1
  80. package/dist/utils/output.js +36 -13
  81. package/dist/utils/output.js.map +1 -1
  82. package/dist/utils/progress.d.ts.map +1 -1
  83. package/dist/utils/progress.js +32 -4
  84. package/dist/utils/progress.js.map +1 -1
  85. package/dist/utils/spinner.d.ts +17 -0
  86. package/dist/utils/spinner.d.ts.map +1 -0
  87. package/dist/utils/spinner.js +43 -0
  88. package/dist/utils/spinner.js.map +1 -0
  89. package/docs/DOCUMENTATION-STANDARD.md +1068 -0
  90. package/docs/README.md +161 -0
  91. package/docs/developer/ARCHITECTURE.md +516 -0
  92. package/docs/developer/AUTH.md +204 -0
  93. package/docs/developer/CONTRIBUTING.md +227 -0
  94. package/docs/developer/DOCUMENTATION_SUMMARY.md +346 -0
  95. package/docs/developer/PROJECT_INDEX.md +365 -0
  96. package/docs/planning/API_COVERAGE.md +1045 -0
  97. package/docs/planning/BACKLOG.md +1159 -0
  98. package/docs/planning/PROFILE_SYSTEM_TASKS.md +287 -0
  99. package/docs/planning/UX_IMPLEMENTATION_PLAN.md +691 -0
  100. package/docs/planning/archive/RELEASE_CHECKLIST_v1.3.0.md +332 -0
  101. package/docs/planning/archive/RELEASE_v1.3.0.md +428 -0
  102. package/docs/planning/archive/cakemail-cli-ux-improvements.md +438 -0
  103. package/docs/planning/cakemail-profile-system-plan.md +1121 -0
  104. package/docs/testing/AI_USER_SIMULATION_DESIGN.md +1342 -0
  105. package/docs/testing/KENOGAMI_BIDIRECTIONAL_FLOW.md +1517 -0
  106. package/docs/testing/KENOGAMI_TRUTH_RECONCILIATION_SYSTEM.md +1369 -0
  107. package/docs/user-manual/.obsidian/app.json +1 -0
  108. package/docs/user-manual/.obsidian/appearance.json +1 -0
  109. package/docs/user-manual/.obsidian/core-plugins.json +33 -0
  110. package/docs/user-manual/.obsidian/workspace.json +167 -0
  111. package/docs/user-manual/01-getting-started/01-installation.md +214 -0
  112. package/docs/user-manual/01-getting-started/02-quick-start.md +432 -0
  113. package/docs/user-manual/01-getting-started/03-authentication.md +448 -0
  114. package/docs/user-manual/01-getting-started/04-configuration.md +430 -0
  115. package/docs/user-manual/01-getting-started/05-output-formats.md +447 -0
  116. package/docs/user-manual/02-core-concepts/01-accounts.md +514 -0
  117. package/docs/user-manual/02-core-concepts/02-profile-system.md +771 -0
  118. package/docs/user-manual/02-core-concepts/03-smart-defaults.md +485 -0
  119. package/docs/user-manual/02-core-concepts/04-authentication-methods.md +435 -0
  120. package/docs/user-manual/02-core-concepts/05-pagination-filtering.md +600 -0
  121. package/docs/user-manual/02-core-concepts/06-error-handling.md +718 -0
  122. package/docs/user-manual/02-core-concepts/07-api-coverage.md +483 -0
  123. package/docs/user-manual/03-email-operations/01-senders.md +490 -0
  124. package/docs/user-manual/03-email-operations/02-templates.md +444 -0
  125. package/docs/user-manual/03-email-operations/03-transactional-emails.md +706 -0
  126. package/docs/user-manual/03-email-operations/04-email-tracking.md +407 -0
  127. package/docs/user-manual/04-campaign-management/01-campaigns-basics.md +394 -0
  128. package/docs/user-manual/04-campaign-management/02-campaign-scheduling.md +630 -0
  129. package/docs/user-manual/04-campaign-management/03-campaign-testing.md +997 -0
  130. package/docs/user-manual/04-campaign-management/04-campaign-lifecycle.md +709 -0
  131. package/docs/user-manual/04-campaign-management/05-campaign-links.md +934 -0
  132. package/docs/user-manual/05-contact-management/01-lists.md +836 -0
  133. package/docs/user-manual/05-contact-management/02-contacts.md +1035 -0
  134. package/docs/user-manual/05-contact-management/03-custom-attributes.md +788 -0
  135. package/docs/user-manual/05-contact-management/04-segments.md +1028 -0
  136. package/docs/user-manual/05-contact-management/05-contact-import-export.md +1031 -0
  137. package/docs/user-manual/06-analytics-reporting/01-campaign-analytics.md +867 -0
  138. package/docs/user-manual/06-analytics-reporting/02-account-reports.md +227 -0
  139. package/docs/user-manual/07-integrations/01-webhooks-integration.md +259 -0
  140. package/docs/user-manual/07-integrations/02-automation.md +326 -0
  141. package/docs/user-manual/08-advanced-usage/01-scripting-patterns.md +672 -0
  142. package/docs/user-manual/08-advanced-usage/02-bulk-operations.md +932 -0
  143. package/docs/user-manual/08-advanced-usage/03-ci-cd-integration.md +892 -0
  144. package/docs/user-manual/08-advanced-usage/04-performance-optimization.md +766 -0
  145. package/docs/user-manual/09-command-reference/01-config.md +776 -0
  146. package/docs/user-manual/09-command-reference/02-account.md +652 -0
  147. package/docs/user-manual/09-command-reference/03-lists.md +958 -0
  148. package/docs/user-manual/09-command-reference/04-contacts.md +1408 -0
  149. package/docs/user-manual/09-command-reference/05-attributes.md +617 -0
  150. package/docs/user-manual/09-command-reference/06-segments.md +894 -0
  151. package/docs/user-manual/09-command-reference/07-senders.md +803 -0
  152. package/docs/user-manual/09-command-reference/08-templates.md +818 -0
  153. package/docs/user-manual/09-command-reference/09-campaigns.md +1250 -0
  154. package/docs/user-manual/09-command-reference/10-emails.md +807 -0
  155. package/docs/user-manual/09-command-reference/11-reports.md +1135 -0
  156. package/docs/user-manual/09-command-reference/12-webhooks.md +773 -0
  157. package/docs/user-manual/09-command-reference/13-suppressed.md +797 -0
  158. package/docs/user-manual/09-command-reference/14-interests.md +630 -0
  159. package/docs/user-manual/09-command-reference/15-tags.md +584 -0
  160. package/docs/user-manual/09-command-reference/16-logs.md +656 -0
  161. package/docs/user-manual/09-command-reference/17-transactional-templates.md +850 -0
  162. package/docs/user-manual/10-troubleshooting/01-common-errors.md +457 -0
  163. package/docs/user-manual/10-troubleshooting/02-authentication-issues.md +558 -0
  164. package/docs/user-manual/10-troubleshooting/03-connection-problems.md +634 -0
  165. package/docs/user-manual/10-troubleshooting/04-debugging.md +725 -0
  166. package/docs/user-manual/11-appendix/04-faq.md +484 -0
  167. package/docs/user-manual/11-appendix/05-glossary.md +250 -0
  168. package/docs/user-manual/README.md +0 -0
  169. package/package.json +13 -47
  170. package/src/cli.ts +125 -0
  171. package/src/client.ts +16 -0
  172. package/src/commands/account.ts +267 -0
  173. package/src/commands/accounts.ts +78 -0
  174. package/src/commands/actions.ts +249 -0
  175. package/src/commands/attributes.ts +139 -0
  176. package/src/commands/campaign-blueprints.ts +106 -0
  177. package/src/commands/campaigns.ts +469 -0
  178. package/src/commands/config.ts +77 -0
  179. package/src/commands/contacts.ts +612 -0
  180. package/src/commands/custom-attributes.ts +127 -0
  181. package/src/commands/dkims.ts +117 -0
  182. package/src/commands/domains.ts +82 -0
  183. package/src/commands/email-apis.ts +569 -0
  184. package/src/commands/emails.ts +197 -0
  185. package/src/commands/forms.ts +283 -0
  186. package/src/commands/interests.ts +155 -0
  187. package/src/commands/links.ts +38 -0
  188. package/src/commands/lists.ts +406 -0
  189. package/src/commands/logos.ts +71 -0
  190. package/src/commands/logs.ts +386 -0
  191. package/src/commands/reports.ts +306 -0
  192. package/src/commands/segments.ts +158 -0
  193. package/src/commands/senders.ts +204 -0
  194. package/src/commands/sub-accounts.ts +271 -0
  195. package/src/commands/suppressed-emails.ts +234 -0
  196. package/src/commands/suppressed.ts +198 -0
  197. package/src/commands/system-emails.ts +85 -0
  198. package/src/commands/tags.ts +146 -0
  199. package/src/commands/tasks.ts +116 -0
  200. package/src/commands/templates.ts +189 -0
  201. package/src/commands/tokens.ts +83 -0
  202. package/src/commands/transactional-emails.ts +374 -0
  203. package/src/commands/transactional-templates.ts +385 -0
  204. package/src/commands/users.ts +506 -0
  205. package/src/commands/webhooks.ts +172 -0
  206. package/src/commands/workflow-blueprints.ts +123 -0
  207. package/src/commands/workflows.ts +265 -0
  208. package/src/types/profile.ts +93 -0
  209. package/src/utils/auth.ts +272 -0
  210. package/src/utils/config-file.ts +96 -0
  211. package/src/utils/config.ts +134 -0
  212. package/src/utils/confirm.ts +32 -0
  213. package/src/utils/defaults.ts +99 -0
  214. package/src/utils/errors.ts +116 -0
  215. package/src/utils/interactive.ts +91 -0
  216. package/src/utils/list-defaults.ts +74 -0
  217. package/src/utils/output.ts +190 -0
  218. package/src/utils/progress.ts +320 -0
  219. package/src/utils/spinner.ts +22 -0
  220. package/tests/IMPLEMENTATION_STATUS.md +258 -0
  221. package/tests/PTY_SETUP.md +118 -0
  222. package/tests/PTY_TESTING_GUIDE.md +507 -0
  223. package/tests/README.md +244 -0
  224. package/tests/fixtures/api-responses/campaigns.json +34 -0
  225. package/tests/fixtures/test-config.json +13 -0
  226. package/tests/helpers/cli-runner.ts +128 -0
  227. package/tests/helpers/mock-server.ts +301 -0
  228. package/tests/helpers/pty-runner.ts +181 -0
  229. package/tests/integration/campaigns-real-api.test.ts +196 -0
  230. package/tests/integration/setup-integration.ts +50 -0
  231. package/tests/pty/campaigns.test.ts +241 -0
  232. package/tests/setup.ts +34 -0
  233. package/tsconfig.json +15 -0
  234. 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
+ }