@cakemail-org/cakemail-cli 1.7.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 (198) 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 +41 -37
  6. package/audit-formats.js +128 -0
  7. package/cakemail.rb +20 -0
  8. package/dist/client.js +1 -1
  9. package/dist/client.js.map +1 -1
  10. package/dist/commands/account.js +1 -1
  11. package/dist/commands/account.js.map +1 -1
  12. package/dist/commands/attributes.js +1 -1
  13. package/dist/commands/attributes.js.map +1 -1
  14. package/dist/commands/campaigns.js +1 -1
  15. package/dist/commands/campaigns.js.map +1 -1
  16. package/dist/commands/contacts.js +1 -1
  17. package/dist/commands/contacts.js.map +1 -1
  18. package/dist/commands/emails.js +1 -1
  19. package/dist/commands/emails.js.map +1 -1
  20. package/dist/commands/interests.js +1 -1
  21. package/dist/commands/interests.js.map +1 -1
  22. package/dist/commands/lists.js +1 -1
  23. package/dist/commands/lists.js.map +1 -1
  24. package/dist/commands/logs.js +1 -1
  25. package/dist/commands/logs.js.map +1 -1
  26. package/dist/commands/reports.js +1 -1
  27. package/dist/commands/reports.js.map +1 -1
  28. package/dist/commands/segments.js +1 -1
  29. package/dist/commands/segments.js.map +1 -1
  30. package/dist/commands/senders.js +1 -1
  31. package/dist/commands/senders.js.map +1 -1
  32. package/dist/commands/suppressed.js +1 -1
  33. package/dist/commands/suppressed.js.map +1 -1
  34. package/dist/commands/tags.js +1 -1
  35. package/dist/commands/tags.js.map +1 -1
  36. package/dist/commands/templates.js +1 -1
  37. package/dist/commands/templates.js.map +1 -1
  38. package/dist/commands/transactional-templates.js +1 -1
  39. package/dist/commands/transactional-templates.js.map +1 -1
  40. package/dist/commands/webhooks.js +1 -1
  41. package/dist/commands/webhooks.js.map +1 -1
  42. package/dist/utils/config.js +2 -2
  43. package/dist/utils/config.js.map +1 -1
  44. package/dist/utils/errors.js +1 -1
  45. package/dist/utils/errors.js.map +1 -1
  46. package/dist/utils/progress.d.ts.map +1 -1
  47. package/dist/utils/progress.js +32 -4
  48. package/dist/utils/progress.js.map +1 -1
  49. package/dist/utils/spinner.d.ts +17 -0
  50. package/dist/utils/spinner.d.ts.map +1 -0
  51. package/dist/utils/spinner.js +43 -0
  52. package/dist/utils/spinner.js.map +1 -0
  53. package/docs/DOCUMENTATION-STANDARD.md +1068 -0
  54. package/docs/README.md +161 -0
  55. package/docs/developer/ARCHITECTURE.md +516 -0
  56. package/docs/developer/AUTH.md +204 -0
  57. package/docs/developer/CONTRIBUTING.md +227 -0
  58. package/docs/developer/DOCUMENTATION_SUMMARY.md +346 -0
  59. package/docs/developer/PROJECT_INDEX.md +365 -0
  60. package/docs/planning/API_COVERAGE.md +1045 -0
  61. package/docs/planning/BACKLOG.md +1159 -0
  62. package/docs/planning/PROFILE_SYSTEM_TASKS.md +287 -0
  63. package/docs/planning/UX_IMPLEMENTATION_PLAN.md +691 -0
  64. package/docs/planning/archive/RELEASE_CHECKLIST_v1.3.0.md +332 -0
  65. package/docs/planning/archive/RELEASE_v1.3.0.md +428 -0
  66. package/docs/planning/archive/cakemail-cli-ux-improvements.md +438 -0
  67. package/docs/planning/cakemail-profile-system-plan.md +1121 -0
  68. package/docs/testing/AI_USER_SIMULATION_DESIGN.md +1342 -0
  69. package/docs/testing/KENOGAMI_BIDIRECTIONAL_FLOW.md +1517 -0
  70. package/docs/testing/KENOGAMI_TRUTH_RECONCILIATION_SYSTEM.md +1369 -0
  71. package/docs/user-manual/.obsidian/app.json +1 -0
  72. package/docs/user-manual/.obsidian/appearance.json +1 -0
  73. package/docs/user-manual/.obsidian/core-plugins.json +33 -0
  74. package/docs/user-manual/.obsidian/workspace.json +167 -0
  75. package/docs/user-manual/01-getting-started/01-installation.md +214 -0
  76. package/docs/user-manual/01-getting-started/02-quick-start.md +432 -0
  77. package/docs/user-manual/01-getting-started/03-authentication.md +448 -0
  78. package/docs/user-manual/01-getting-started/04-configuration.md +430 -0
  79. package/docs/user-manual/01-getting-started/05-output-formats.md +447 -0
  80. package/docs/user-manual/02-core-concepts/01-accounts.md +514 -0
  81. package/docs/user-manual/02-core-concepts/02-profile-system.md +771 -0
  82. package/docs/user-manual/02-core-concepts/03-smart-defaults.md +485 -0
  83. package/docs/user-manual/02-core-concepts/04-authentication-methods.md +435 -0
  84. package/docs/user-manual/02-core-concepts/05-pagination-filtering.md +600 -0
  85. package/docs/user-manual/02-core-concepts/06-error-handling.md +718 -0
  86. package/docs/user-manual/02-core-concepts/07-api-coverage.md +483 -0
  87. package/docs/user-manual/03-email-operations/01-senders.md +490 -0
  88. package/docs/user-manual/03-email-operations/02-templates.md +444 -0
  89. package/docs/user-manual/03-email-operations/03-transactional-emails.md +706 -0
  90. package/docs/user-manual/03-email-operations/04-email-tracking.md +407 -0
  91. package/docs/user-manual/04-campaign-management/01-campaigns-basics.md +394 -0
  92. package/docs/user-manual/04-campaign-management/02-campaign-scheduling.md +630 -0
  93. package/docs/user-manual/04-campaign-management/03-campaign-testing.md +997 -0
  94. package/docs/user-manual/04-campaign-management/04-campaign-lifecycle.md +709 -0
  95. package/docs/user-manual/04-campaign-management/05-campaign-links.md +934 -0
  96. package/docs/user-manual/05-contact-management/01-lists.md +836 -0
  97. package/docs/user-manual/05-contact-management/02-contacts.md +1035 -0
  98. package/docs/user-manual/05-contact-management/03-custom-attributes.md +788 -0
  99. package/docs/user-manual/05-contact-management/04-segments.md +1028 -0
  100. package/docs/user-manual/05-contact-management/05-contact-import-export.md +1031 -0
  101. package/docs/user-manual/06-analytics-reporting/01-campaign-analytics.md +867 -0
  102. package/docs/user-manual/06-analytics-reporting/02-account-reports.md +227 -0
  103. package/docs/user-manual/07-integrations/01-webhooks-integration.md +259 -0
  104. package/docs/user-manual/07-integrations/02-automation.md +326 -0
  105. package/docs/user-manual/08-advanced-usage/01-scripting-patterns.md +672 -0
  106. package/docs/user-manual/08-advanced-usage/02-bulk-operations.md +932 -0
  107. package/docs/user-manual/08-advanced-usage/03-ci-cd-integration.md +892 -0
  108. package/docs/user-manual/08-advanced-usage/04-performance-optimization.md +766 -0
  109. package/docs/user-manual/09-command-reference/01-config.md +776 -0
  110. package/docs/user-manual/09-command-reference/02-account.md +652 -0
  111. package/docs/user-manual/09-command-reference/03-lists.md +958 -0
  112. package/docs/user-manual/09-command-reference/04-contacts.md +1408 -0
  113. package/docs/user-manual/09-command-reference/05-attributes.md +617 -0
  114. package/docs/user-manual/09-command-reference/06-segments.md +894 -0
  115. package/docs/user-manual/09-command-reference/07-senders.md +803 -0
  116. package/docs/user-manual/09-command-reference/08-templates.md +818 -0
  117. package/docs/user-manual/09-command-reference/09-campaigns.md +1250 -0
  118. package/docs/user-manual/09-command-reference/10-emails.md +807 -0
  119. package/docs/user-manual/09-command-reference/11-reports.md +1135 -0
  120. package/docs/user-manual/09-command-reference/12-webhooks.md +773 -0
  121. package/docs/user-manual/09-command-reference/13-suppressed.md +797 -0
  122. package/docs/user-manual/09-command-reference/14-interests.md +630 -0
  123. package/docs/user-manual/09-command-reference/15-tags.md +584 -0
  124. package/docs/user-manual/09-command-reference/16-logs.md +656 -0
  125. package/docs/user-manual/09-command-reference/17-transactional-templates.md +850 -0
  126. package/docs/user-manual/10-troubleshooting/01-common-errors.md +457 -0
  127. package/docs/user-manual/10-troubleshooting/02-authentication-issues.md +558 -0
  128. package/docs/user-manual/10-troubleshooting/03-connection-problems.md +634 -0
  129. package/docs/user-manual/10-troubleshooting/04-debugging.md +725 -0
  130. package/docs/user-manual/11-appendix/04-faq.md +484 -0
  131. package/docs/user-manual/11-appendix/05-glossary.md +250 -0
  132. package/docs/user-manual/README.md +0 -0
  133. package/package.json +13 -61
  134. package/src/cli.ts +125 -0
  135. package/src/client.ts +16 -0
  136. package/src/commands/account.ts +267 -0
  137. package/src/commands/accounts.ts +78 -0
  138. package/src/commands/actions.ts +249 -0
  139. package/src/commands/attributes.ts +139 -0
  140. package/src/commands/campaign-blueprints.ts +106 -0
  141. package/src/commands/campaigns.ts +469 -0
  142. package/src/commands/config.ts +77 -0
  143. package/src/commands/contacts.ts +612 -0
  144. package/src/commands/custom-attributes.ts +127 -0
  145. package/src/commands/dkims.ts +117 -0
  146. package/src/commands/domains.ts +82 -0
  147. package/src/commands/email-apis.ts +569 -0
  148. package/src/commands/emails.ts +197 -0
  149. package/src/commands/forms.ts +283 -0
  150. package/src/commands/interests.ts +155 -0
  151. package/src/commands/links.ts +38 -0
  152. package/src/commands/lists.ts +406 -0
  153. package/src/commands/logos.ts +71 -0
  154. package/src/commands/logs.ts +386 -0
  155. package/src/commands/reports.ts +306 -0
  156. package/src/commands/segments.ts +158 -0
  157. package/src/commands/senders.ts +204 -0
  158. package/src/commands/sub-accounts.ts +271 -0
  159. package/src/commands/suppressed-emails.ts +234 -0
  160. package/src/commands/suppressed.ts +198 -0
  161. package/src/commands/system-emails.ts +85 -0
  162. package/src/commands/tags.ts +146 -0
  163. package/src/commands/tasks.ts +116 -0
  164. package/src/commands/templates.ts +189 -0
  165. package/src/commands/tokens.ts +83 -0
  166. package/src/commands/transactional-emails.ts +374 -0
  167. package/src/commands/transactional-templates.ts +385 -0
  168. package/src/commands/users.ts +506 -0
  169. package/src/commands/webhooks.ts +172 -0
  170. package/src/commands/workflow-blueprints.ts +123 -0
  171. package/src/commands/workflows.ts +265 -0
  172. package/src/types/profile.ts +93 -0
  173. package/src/utils/auth.ts +272 -0
  174. package/src/utils/config-file.ts +96 -0
  175. package/src/utils/config.ts +134 -0
  176. package/src/utils/confirm.ts +32 -0
  177. package/src/utils/defaults.ts +99 -0
  178. package/src/utils/errors.ts +116 -0
  179. package/src/utils/interactive.ts +91 -0
  180. package/src/utils/list-defaults.ts +74 -0
  181. package/src/utils/output.ts +190 -0
  182. package/src/utils/progress.ts +320 -0
  183. package/src/utils/spinner.ts +22 -0
  184. package/tests/IMPLEMENTATION_STATUS.md +258 -0
  185. package/tests/PTY_SETUP.md +118 -0
  186. package/tests/PTY_TESTING_GUIDE.md +507 -0
  187. package/tests/README.md +244 -0
  188. package/tests/fixtures/api-responses/campaigns.json +34 -0
  189. package/tests/fixtures/test-config.json +13 -0
  190. package/tests/helpers/cli-runner.ts +128 -0
  191. package/tests/helpers/mock-server.ts +301 -0
  192. package/tests/helpers/pty-runner.ts +181 -0
  193. package/tests/integration/campaigns-real-api.test.ts +196 -0
  194. package/tests/integration/setup-integration.ts +50 -0
  195. package/tests/pty/campaigns.test.ts +241 -0
  196. package/tests/setup.ts +34 -0
  197. package/tsconfig.json +15 -0
  198. package/vitest.config.ts +28 -0
@@ -0,0 +1,386 @@
1
+ // ABOUTME: CLI commands for Log.
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 createLogsCommand(
8
+ client: any,
9
+ formatter: any
10
+ ): Command {
11
+ const cmd = new Command('logs')
12
+ .description('Access detailed activity logs for campaigns and lists. Logs track individual email events (sends, opens, clicks, bounces, unsubscribes). Log data can be exported to CSV files.');
13
+
14
+
15
+ cmd
16
+ .command('get-list <list-id>')
17
+ .description('Show list logs')
18
+ .option('--start-time <value>', 'start_time')
19
+ .option('--end-time <value>', 'end_time')
20
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
21
+ .option('--page <value>', 'page')
22
+ .option('--per-page <value>', 'per_page')
23
+ .option('--with-count <value>', 'Include count in the response')
24
+ .option('--filter <value>', 'Valid Terms:
25
+ - `additional_info`
26
+ - `contact_id`
27
+ - `email`
28
+ - `uniques`
29
+ - `group_by_contact`
30
+ - `track_id`
31
+ - `log_id`
32
+ - `start_id`
33
+ - `end_id`
34
+ - `totals`
35
+ - `type`
36
+
37
+ Valid Operators:
38
+ - `==`
39
+
40
+ Query separator:
41
+ - `;`')
42
+ .action(async (list_id, options) => {
43
+ const spinner = createSpinner('Fetching log...').start();
44
+ try {
45
+ const data = await client.getListLogs({
46
+ list_id: Number(list_id),
47
+ startTime: options.startTime != null ? Number(options.startTime) : undefined,
48
+ endTime: options.endTime != null ? Number(options.endTime) : undefined,
49
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
50
+ page: options.page != null ? Number(options.page) : undefined,
51
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
52
+ withCount: options.withCount,
53
+ filter: options.filter,
54
+ });
55
+
56
+ spinner.stop();
57
+ formatter.output(data);
58
+ } catch (error: any) {
59
+ spinner.stop();
60
+ formatter.error(error.message);
61
+ process.exit(1);
62
+ }
63
+ });
64
+
65
+
66
+ cmd
67
+ .command('get-campaign <campaign-id>')
68
+ .description('Show campaign logs')
69
+ .option('--start-time <value>', 'start_time')
70
+ .option('--end-time <value>', 'end_time')
71
+ .option('--cursor <value>', 'cursor')
72
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
73
+ .option('--page <value>', 'page')
74
+ .option('--per-page <value>', 'per_page')
75
+ .option('--with-count <value>', 'Include count in the response')
76
+ .option('--filter <value>', 'Valid Terms:
77
+ - `additional_info`
78
+ - `link_id`
79
+ - `contact_id`
80
+ - `email`
81
+ - `uniques`
82
+ - `group_by_contact`
83
+ - `log_id`
84
+ - `totals`
85
+ - `type`
86
+
87
+ Valid Operators:
88
+ - `==`
89
+
90
+ Query separator:
91
+ - `;`')
92
+ .option('--sort <value>', 'Sort term and direction, using syntax `[-|+]term`.
93
+
94
+ Valid terms:
95
+ - `time`
96
+ - `log_id`')
97
+ .action(async (campaign_id, options) => {
98
+ const spinner = createSpinner('Fetching log...').start();
99
+ try {
100
+ const data = await client.getCampaignLogs({
101
+ campaign_id: Number(campaign_id),
102
+ startTime: options.startTime != null ? Number(options.startTime) : undefined,
103
+ endTime: options.endTime != null ? Number(options.endTime) : undefined,
104
+ cursor: options.cursor,
105
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
106
+ page: options.page != null ? Number(options.page) : undefined,
107
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
108
+ withCount: options.withCount,
109
+ filter: options.filter,
110
+ sort: options.sort,
111
+ });
112
+
113
+ spinner.stop();
114
+ formatter.output(data);
115
+ } catch (error: any) {
116
+ spinner.stop();
117
+ formatter.error(error.message);
118
+ process.exit(1);
119
+ }
120
+ });
121
+
122
+
123
+ cmd
124
+ .command('get-action <workflow-id> <action-id>')
125
+ .description('Show action logs')
126
+ .option('--start-time <value>', 'start_time')
127
+ .option('--end-time <value>', 'end_time')
128
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
129
+ .option('--page <value>', 'page')
130
+ .option('--per-page <value>', 'per_page')
131
+ .option('--with-count <value>', 'Include count in the response')
132
+ .option('--filter <value>', 'Valid Terms:
133
+ - `additional_info`
134
+ - `link_id`
135
+ - `contact_id`
136
+ - `email`
137
+ - `log_id`
138
+ - `track_id`
139
+ - `type`
140
+ - `group_by_contact`
141
+
142
+ Valid Operators:
143
+ - `==`
144
+
145
+ Query separator:
146
+ - `;`')
147
+ .option('--sort <value>', 'Sort term and direction, using syntax `[-|+]term`.
148
+
149
+ Valid terms:
150
+ - `time`
151
+ - `log_id`')
152
+ .action(async (workflow_id, action_id, options) => {
153
+ const spinner = createSpinner('Fetching log...').start();
154
+ try {
155
+ const data = await client.getActionLogs({
156
+ workflow_id,
157
+ action_id,
158
+ startTime: options.startTime != null ? Number(options.startTime) : undefined,
159
+ endTime: options.endTime != null ? Number(options.endTime) : undefined,
160
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
161
+ page: options.page != null ? Number(options.page) : undefined,
162
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
163
+ withCount: options.withCount,
164
+ filter: options.filter,
165
+ sort: options.sort,
166
+ });
167
+
168
+ spinner.stop();
169
+ formatter.output(data);
170
+ } catch (error: any) {
171
+ spinner.stop();
172
+ formatter.error(error.message);
173
+ process.exit(1);
174
+ }
175
+ });
176
+
177
+
178
+ cmd
179
+ .command('list-campaign-log-exports <campaign-id>')
180
+ .description('Show all campaign log exports')
181
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
182
+ .option('--page <value>', 'page')
183
+ .option('--per-page <value>', 'per_page')
184
+ .option('--with-count <value>', 'Include count in the response')
185
+ .action(async (campaign_id, options) => {
186
+ const spinner = createSpinner('Fetching log...').start();
187
+ try {
188
+ const data = await client.listCampaignLogExports({
189
+ campaign_id: Number(campaign_id),
190
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
191
+ page: options.page != null ? Number(options.page) : undefined,
192
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
193
+ withCount: options.withCount,
194
+ });
195
+
196
+ spinner.stop();
197
+ formatter.output(data);
198
+ } catch (error: any) {
199
+ spinner.stop();
200
+ formatter.error(error.message);
201
+ process.exit(1);
202
+ }
203
+ });
204
+
205
+
206
+ cmd
207
+ .command('campaign-log-export-create <campaign-id>')
208
+ .description('Create a campaign log export')
209
+ .option('--description <value>', 'description')
210
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
211
+ .option('--filter <value>', 'Valid Terms:
212
+ - `additional_info`
213
+ - `link_id`
214
+ - `contact_id`
215
+ - `email`
216
+ - `uniques`
217
+ - `group_by_contact`
218
+ - `log_id`
219
+ - `totals`
220
+ - `type`
221
+
222
+ Valid Operators:
223
+ - `==`
224
+
225
+ Query separator:
226
+ - `;`')
227
+ .option('--description <value>', 'description')
228
+ .option('--filter <value>', 'Valid Terms:
229
+ - `additional_info`
230
+ - `link_id`
231
+ - `contact_id`
232
+ - `email`
233
+ - `uniques`
234
+ - `group_by_contact`
235
+ - `log_id`
236
+ - `totals`
237
+ - `type`
238
+
239
+ Valid Operators:
240
+ - `==`
241
+
242
+ Query separator:
243
+ - `;`')
244
+ .action(async (campaign_id, options) => {
245
+ const spinner = createSpinner('Creating log...').start();
246
+ try {
247
+ const data = await client.campaignLogExportCreate({
248
+ campaign_id: Number(campaign_id),
249
+ description: options.description,
250
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
251
+ filter: options.filter,
252
+ description: options.description,
253
+ filter: options.filter,
254
+ });
255
+
256
+ spinner.stop();
257
+ formatter.success('Log created successfully');
258
+ formatter.output(data);
259
+ } catch (error: any) {
260
+ spinner.stop();
261
+ formatter.error(error.message);
262
+ process.exit(1);
263
+ }
264
+ });
265
+
266
+
267
+ cmd
268
+ .command('campaign-log-export-download <campaign-log-export-id> <campaign-id>')
269
+ .description('Download a campaign log export')
270
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
271
+ .action(async (campaign_log_export_id, campaign_id, options) => {
272
+ const spinner = createSpinner('Fetching log...').start();
273
+ try {
274
+ const data = await client.campaignLogExportDownload({
275
+ campaign_log_export_id,
276
+ campaign_id: Number(campaign_id),
277
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
278
+ });
279
+
280
+ spinner.stop();
281
+ formatter.output(data);
282
+ } catch (error: any) {
283
+ spinner.stop();
284
+ formatter.error(error.message);
285
+ process.exit(1);
286
+ }
287
+ });
288
+
289
+
290
+ cmd
291
+ .command('list-list-logs-exports <list-id>')
292
+ .description('Show all list logs exports')
293
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
294
+ .option('--page <value>', 'page')
295
+ .option('--per-page <value>', 'per_page')
296
+ .option('--with-count <value>', 'Include count in the response')
297
+ .action(async (list_id, options) => {
298
+ const spinner = createSpinner('Fetching log...').start();
299
+ try {
300
+ const data = await client.listListLogsExports({
301
+ list_id: Number(list_id),
302
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
303
+ page: options.page != null ? Number(options.page) : undefined,
304
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
305
+ withCount: options.withCount,
306
+ });
307
+
308
+ spinner.stop();
309
+ formatter.output(data);
310
+ } catch (error: any) {
311
+ spinner.stop();
312
+ formatter.error(error.message);
313
+ process.exit(1);
314
+ }
315
+ });
316
+
317
+
318
+ cmd
319
+ .command('list-logs-export-create <list-id>')
320
+ .description('Create a list log export')
321
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
322
+ .option('--description <value>', 'description')
323
+ .option('--filter <value>', 'Valid Terms:
324
+ - `additional_info`
325
+ - `contact_id`
326
+ - `email`
327
+ - `uniques`
328
+ - `group_by_contact`
329
+ - `track_id`
330
+ - `log_id`
331
+ - `start_id`
332
+ - `end_id`
333
+ - `totals`
334
+ - `type`
335
+
336
+ Valid Operators:
337
+ - `==`
338
+
339
+ Query separator:
340
+ - `;`')
341
+ .action(async (list_id, options) => {
342
+ const spinner = createSpinner('Creating log...').start();
343
+ try {
344
+ const data = await client.listLogsExportCreate({
345
+ list_id: Number(list_id),
346
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
347
+ description: options.description,
348
+ filter: options.filter,
349
+ });
350
+
351
+ spinner.stop();
352
+ formatter.success('Log created successfully');
353
+ formatter.output(data);
354
+ } catch (error: any) {
355
+ spinner.stop();
356
+ formatter.error(error.message);
357
+ process.exit(1);
358
+ }
359
+ });
360
+
361
+
362
+ cmd
363
+ .command('list-logs-export-download <list-logs-export-id> <list-id>')
364
+ .description('Download a list logs export')
365
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
366
+ .action(async (list_logs_export_id, list_id, options) => {
367
+ const spinner = createSpinner('Fetching log...').start();
368
+ try {
369
+ const data = await client.listLogsExportDownload({
370
+ list_logs_export_id,
371
+ list_id: Number(list_id),
372
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
373
+ });
374
+
375
+ spinner.stop();
376
+ formatter.output(data);
377
+ } catch (error: any) {
378
+ spinner.stop();
379
+ formatter.error(error.message);
380
+ process.exit(1);
381
+ }
382
+ });
383
+
384
+
385
+ return cmd;
386
+ }
@@ -0,0 +1,306 @@
1
+ // ABOUTME: CLI commands for Report.
2
+ // ABOUTME: Generated by api-kit from the OpenAPI spec.
3
+
4
+ import { Command } from 'commander';
5
+ import { createSpinner } from '../utils/spinner.js';
6
+ import { confirmDelete } from '../utils/confirm.js';
7
+
8
+ export function createReportsCommand(
9
+ client: any,
10
+ formatter: any
11
+ ): Command {
12
+ const cmd = new Command('reports')
13
+ .description('Access campaign, list, and account performance statistics. Includes open rates, click rates, bounce rates, and other delivery metrics. Campaign report data can be exported to CSV files.');
14
+
15
+
16
+ cmd
17
+ .command('get-list-stats <list-id>')
18
+ .description('Show list report')
19
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
20
+ .action(async (list_id, options) => {
21
+ const spinner = createSpinner('Fetching report...').start();
22
+ try {
23
+ const data = await client.getListStats({
24
+ list_id: Number(list_id),
25
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
26
+ });
27
+
28
+ spinner.stop();
29
+ formatter.output(data);
30
+ } catch (error: any) {
31
+ spinner.stop();
32
+ formatter.error(error.message);
33
+ process.exit(1);
34
+ }
35
+ });
36
+
37
+
38
+ cmd
39
+ .command('get-campaign-stats <campaign-id>')
40
+ .description('Show campaign report')
41
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
42
+ .action(async (campaign_id, options) => {
43
+ const spinner = createSpinner('Fetching report...').start();
44
+ try {
45
+ const data = await client.getCampaignStats({
46
+ campaign_id: Number(campaign_id),
47
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
48
+ });
49
+
50
+ spinner.stop();
51
+ formatter.output(data);
52
+ } catch (error: any) {
53
+ spinner.stop();
54
+ formatter.error(error.message);
55
+ process.exit(1);
56
+ }
57
+ });
58
+
59
+
60
+ cmd
61
+ .command('get-campaign-links-stats <campaign-id>')
62
+ .description('Show campaign links report')
63
+ .option('--start-time <value>', 'start_time')
64
+ .option('--end-time <value>', 'end_time')
65
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
66
+ .option('--page <value>', 'page')
67
+ .option('--per-page <value>', 'per_page')
68
+ .option('--with-count <value>', 'Include count in the response')
69
+ .option('--sort <value>', 'Sort term and direction, using syntax `[-|+]term`.
70
+
71
+ Valid terms:
72
+ - `unique`
73
+ - `total`
74
+ - `link`')
75
+ .action(async (campaign_id, options) => {
76
+ const spinner = createSpinner('Fetching report...').start();
77
+ try {
78
+ const data = await client.getCampaignLinksStats({
79
+ campaign_id: Number(campaign_id),
80
+ startTime: options.startTime != null ? Number(options.startTime) : undefined,
81
+ endTime: options.endTime != null ? Number(options.endTime) : undefined,
82
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
83
+ page: options.page != null ? Number(options.page) : undefined,
84
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
85
+ withCount: options.withCount,
86
+ sort: options.sort,
87
+ });
88
+
89
+ spinner.stop();
90
+ formatter.output(data);
91
+ } catch (error: any) {
92
+ spinner.stop();
93
+ formatter.error(error.message);
94
+ process.exit(1);
95
+ }
96
+ });
97
+
98
+
99
+ cmd
100
+ .command('get-self-account-stats')
101
+ .description('Show my account report')
102
+ .option('--start-time <value>', 'start_time')
103
+ .option('--end-time <value>', 'end_time')
104
+ .action(async (options) => {
105
+ const spinner = createSpinner('Fetching report...').start();
106
+ try {
107
+ const data = await client.getSelfAccountStats({
108
+ startTime: options.startTime != null ? Number(options.startTime) : undefined,
109
+ endTime: options.endTime != null ? Number(options.endTime) : undefined,
110
+ });
111
+
112
+ spinner.stop();
113
+ formatter.output(data);
114
+ } catch (error: any) {
115
+ spinner.stop();
116
+ formatter.error(error.message);
117
+ process.exit(1);
118
+ }
119
+ });
120
+
121
+
122
+ cmd
123
+ .command('get-account-stats <account-id>')
124
+ .description('Show account report')
125
+ .option('--start-time <value>', 'start_time')
126
+ .option('--end-time <value>', 'end_time')
127
+ .action(async (account_id, options) => {
128
+ const spinner = createSpinner('Fetching report...').start();
129
+ try {
130
+ const data = await client.getAccountStats({
131
+ account_id: Number(account_id),
132
+ startTime: options.startTime != null ? Number(options.startTime) : undefined,
133
+ endTime: options.endTime != null ? Number(options.endTime) : undefined,
134
+ });
135
+
136
+ spinner.stop();
137
+ formatter.output(data);
138
+ } catch (error: any) {
139
+ spinner.stop();
140
+ formatter.error(error.message);
141
+ process.exit(1);
142
+ }
143
+ });
144
+
145
+
146
+ cmd
147
+ .command('get-action-stats <workflow-id> <action-id>')
148
+ .description('Show action report')
149
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
150
+ .action(async (workflow_id, action_id, options) => {
151
+ const spinner = createSpinner('Fetching report...').start();
152
+ try {
153
+ const data = await client.getActionStats({
154
+ workflow_id,
155
+ action_id,
156
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
157
+ });
158
+
159
+ spinner.stop();
160
+ formatter.output(data);
161
+ } catch (error: any) {
162
+ spinner.stop();
163
+ formatter.error(error.message);
164
+ process.exit(1);
165
+ }
166
+ });
167
+
168
+
169
+ cmd
170
+ .command('list-campaigns-reports-exports')
171
+ .description('List campaigns reports exports')
172
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
173
+ .option('--page <value>', 'page')
174
+ .option('--per-page <value>', 'per_page')
175
+ .option('--with-count <value>', 'Include count in the response')
176
+ .option('--filter <value>', 'Valid Terms:
177
+ - `status`
178
+ - `progress`
179
+
180
+ Valid Operators:
181
+ - `==`
182
+
183
+ Query separator:
184
+ - `;`')
185
+ .action(async (options) => {
186
+ const spinner = createSpinner('Fetching report...').start();
187
+ try {
188
+ const data = await client.listCampaignsReportsExports({
189
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
190
+ page: options.page != null ? Number(options.page) : undefined,
191
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
192
+ withCount: options.withCount,
193
+ filter: options.filter,
194
+ });
195
+
196
+ spinner.stop();
197
+ formatter.output(data);
198
+ } catch (error: any) {
199
+ spinner.stop();
200
+ formatter.error(error.message);
201
+ process.exit(1);
202
+ }
203
+ });
204
+
205
+
206
+ cmd
207
+ .command('create-campaigns-reports-export')
208
+ .description('Create a campaigns reports export')
209
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
210
+ .option('--description <value>', 'description')
211
+ .action(async (options) => {
212
+ const spinner = createSpinner('Creating report...').start();
213
+ try {
214
+ const data = await client.createCampaignsReportsExport({
215
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
216
+ description: options.description,
217
+ });
218
+
219
+ spinner.stop();
220
+ formatter.success('Report created successfully');
221
+ formatter.output(data);
222
+ } catch (error: any) {
223
+ spinner.stop();
224
+ formatter.error(error.message);
225
+ process.exit(1);
226
+ }
227
+ });
228
+
229
+
230
+ cmd
231
+ .command('get-campaigns-reports-export <export-id>')
232
+ .description('Get a campaigns reports export')
233
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
234
+ .action(async (export_id, options) => {
235
+ const spinner = createSpinner('Fetching report...').start();
236
+ try {
237
+ const data = await client.getCampaignsReportsExport({
238
+ export_id,
239
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
240
+ });
241
+
242
+ spinner.stop();
243
+ formatter.output(data);
244
+ } catch (error: any) {
245
+ spinner.stop();
246
+ formatter.error(error.message);
247
+ process.exit(1);
248
+ }
249
+ });
250
+
251
+
252
+ cmd
253
+ .command('delete-campaigns-reports-export <export-id>')
254
+ .description('Delete a campaigns report export')
255
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
256
+ .option('-f, --force', 'Skip confirmation prompt')
257
+ .action(async (export_id, options) => {
258
+ if (!options.force) {
259
+ const confirmed = await confirmDelete('report', export_id);
260
+ if (!confirmed) {
261
+ formatter.info('Deletion cancelled');
262
+ return;
263
+ }
264
+ }
265
+
266
+ const spinner = createSpinner('Deleting report...').start();
267
+ try {
268
+ const data = await client.deleteCampaignsReportsExport({
269
+ export_id,
270
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
271
+ });
272
+
273
+ spinner.stop();
274
+ formatter.success('Report deleted successfully');
275
+ } catch (error: any) {
276
+ spinner.stop();
277
+ formatter.error(error.message);
278
+ process.exit(1);
279
+ }
280
+ });
281
+
282
+
283
+ cmd
284
+ .command('download-campaigns-reports-export <export-id>')
285
+ .description('Download a campaigns reports export')
286
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
287
+ .action(async (export_id, options) => {
288
+ const spinner = createSpinner('Fetching report...').start();
289
+ try {
290
+ const data = await client.downloadCampaignsReportsExport({
291
+ export_id,
292
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
293
+ });
294
+
295
+ spinner.stop();
296
+ formatter.output(data);
297
+ } catch (error: any) {
298
+ spinner.stop();
299
+ formatter.error(error.message);
300
+ process.exit(1);
301
+ }
302
+ });
303
+
304
+
305
+ return cmd;
306
+ }