@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,374 @@
1
+ // ABOUTME: CLI commands for Transactional Email.
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 createTransactionalEmailsCommand(
9
+ client: any,
10
+ formatter: any
11
+ ): Command {
12
+ const cmd = new Command('transactional-emails')
13
+ .description('Send transactional emails using templates. Transactional emails are one-to-one messages triggered by user actions (order confirmations, password resets, notifications). Create reusable templates with merge tags, then send them to individual contacts. Includes deprecated template-based endpoints — for new integrations, use the Email API.');
14
+
15
+
16
+ cmd
17
+ .command('send-email')
18
+ .description('Send an email')
19
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
20
+ .requiredOption('--data <value>', 'Request body as JSON string')
21
+ .action(async (options) => {
22
+ const spinner = createSpinner('Creating transactional email...').start();
23
+ try {
24
+ const body = JSON.parse(options.data);
25
+ const data = await client.sendEmail({
26
+ ...body,
27
+ });
28
+
29
+ spinner.stop();
30
+ formatter.success('Transactional Email created successfully');
31
+ formatter.output(data);
32
+ } catch (error: any) {
33
+ spinner.stop();
34
+ formatter.error(error.message);
35
+ process.exit(1);
36
+ }
37
+ });
38
+
39
+
40
+ cmd
41
+ .command('get-emails-stats')
42
+ .description('Show email stats')
43
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
44
+ .requiredOption('--start-time <value>', 'Start time for the report.')
45
+ .requiredOption('--end-time <value>', 'End time for the report.')
46
+ .action(async (options) => {
47
+ const spinner = createSpinner('Fetching transactional email...').start();
48
+ try {
49
+ const data = await client.getEmailsStats({
50
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
51
+ startTime: options.startTime != null ? Number(options.startTime) : undefined,
52
+ endTime: options.endTime != null ? Number(options.endTime) : undefined,
53
+ });
54
+
55
+ spinner.stop();
56
+ formatter.output(data);
57
+ } catch (error: any) {
58
+ spinner.stop();
59
+ formatter.error(error.message);
60
+ process.exit(1);
61
+ }
62
+ });
63
+
64
+
65
+ cmd
66
+ .command('get-email-logs')
67
+ .description('Show email activity logs')
68
+ .requiredOption('--log-type <value>', 'log_type')
69
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
70
+ .option('--page <value>', 'page')
71
+ .option('--per-page <value>', 'per_page')
72
+ .option('--with-count <value>', 'Include count in the response')
73
+ .option('--start-time <value>', 'Start time for the report.')
74
+ .option('--end-time <value>', 'End time for the report.')
75
+ .option('--filter <value>', 'Valid Terms:
76
+ - `group_id`
77
+ - `email`
78
+ - `email_id`
79
+
80
+ Valid Operators:
81
+ - `==`
82
+
83
+ Query separator:
84
+ - `;`')
85
+ .action(async (options) => {
86
+ const spinner = createSpinner('Fetching transactional email...').start();
87
+ try {
88
+ const data = await client.getEmailLogs({
89
+ logType: options.logType,
90
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
91
+ page: options.page != null ? Number(options.page) : undefined,
92
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
93
+ withCount: options.withCount,
94
+ startTime: options.startTime != null ? Number(options.startTime) : undefined,
95
+ endTime: options.endTime != null ? Number(options.endTime) : undefined,
96
+ filter: options.filter,
97
+ });
98
+
99
+ spinner.stop();
100
+ formatter.output(data);
101
+ } catch (error: any) {
102
+ spinner.stop();
103
+ formatter.error(error.message);
104
+ process.exit(1);
105
+ }
106
+ });
107
+
108
+
109
+ cmd
110
+ .command('list-email-group-ids')
111
+ .description('List Email Group Ids')
112
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
113
+ .option('--page <value>', 'page')
114
+ .option('--per-page <value>', 'per_page')
115
+ .option('--with-count <value>', 'Include count in the response')
116
+ .action(async (options) => {
117
+ const spinner = createSpinner('Fetching transactional email...').start();
118
+ try {
119
+ const data = await client.listEmailGroupIds({
120
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
121
+ page: options.page != null ? Number(options.page) : undefined,
122
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
123
+ withCount: options.withCount,
124
+ });
125
+
126
+ spinner.stop();
127
+ formatter.output(data);
128
+ } catch (error: any) {
129
+ spinner.stop();
130
+ formatter.error(error.message);
131
+ process.exit(1);
132
+ }
133
+ });
134
+
135
+
136
+ cmd
137
+ .command('patch-email-group-id <group-id>')
138
+ .description('Edit an Email Group Id')
139
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
140
+ .requiredOption('--description <value>', 'description')
141
+ .action(async (group_id, options) => {
142
+ const spinner = createSpinner('Updating transactional email...').start();
143
+ try {
144
+ const data = await client.patchEmailGroupId({
145
+ group_id: Number(group_id),
146
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
147
+ description: options.description,
148
+ });
149
+
150
+ spinner.stop();
151
+ formatter.success('Transactional Email updated successfully');
152
+ formatter.output(data);
153
+ } catch (error: any) {
154
+ spinner.stop();
155
+ formatter.error(error.message);
156
+ process.exit(1);
157
+ }
158
+ });
159
+
160
+
161
+ cmd
162
+ .command('list-transactional-email-templates <list-id>')
163
+ .description('List Transactional Email Templates')
164
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
165
+ .option('--page <value>', 'page')
166
+ .option('--per-page <value>', 'per_page')
167
+ .option('--with-count <value>', 'Include count in the response')
168
+ .action(async (list_id, options) => {
169
+ const spinner = createSpinner('Fetching transactional email...').start();
170
+ try {
171
+ const data = await client.listTransactionalEmailTemplates({
172
+ list_id: Number(list_id),
173
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
174
+ page: options.page != null ? Number(options.page) : undefined,
175
+ perPage: options.perPage != null ? Number(options.perPage) : undefined,
176
+ withCount: options.withCount,
177
+ });
178
+
179
+ spinner.stop();
180
+ formatter.output(data);
181
+ } catch (error: any) {
182
+ spinner.stop();
183
+ formatter.error(error.message);
184
+ process.exit(1);
185
+ }
186
+ });
187
+
188
+
189
+ cmd
190
+ .command('create-transactional-email-template <list-id>')
191
+ .description('Create a Transactional Email Template')
192
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
193
+ .requiredOption('--data <value>', 'Request body as JSON string')
194
+ .action(async (list_id, options) => {
195
+ const spinner = createSpinner('Creating transactional email...').start();
196
+ try {
197
+ const body = JSON.parse(options.data);
198
+ const data = await client.createTransactionalEmailTemplate({
199
+ list_id: Number(list_id),
200
+ ...body,
201
+ });
202
+
203
+ spinner.stop();
204
+ formatter.success('Transactional Email created successfully');
205
+ formatter.output(data);
206
+ } catch (error: any) {
207
+ spinner.stop();
208
+ formatter.error(error.message);
209
+ process.exit(1);
210
+ }
211
+ });
212
+
213
+
214
+ cmd
215
+ .command('show-transactional-email-template <list-id> <transactional-email-template-id>')
216
+ .description('Show a Transactional Email Template')
217
+ .option('--account-id <value>', 'account_id')
218
+ .action(async (list_id, transactional_email_template_id, options) => {
219
+ const spinner = createSpinner('Fetching transactional email...').start();
220
+ try {
221
+ const data = await client.showTransactionalEmailTemplate({
222
+ list_id: Number(list_id),
223
+ transactional_email_template_id: Number(transactional_email_template_id),
224
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
225
+ });
226
+
227
+ spinner.stop();
228
+ formatter.output(data);
229
+ } catch (error: any) {
230
+ spinner.stop();
231
+ formatter.error(error.message);
232
+ process.exit(1);
233
+ }
234
+ });
235
+
236
+
237
+ cmd
238
+ .command('update-transactional-email-template <list-id> <transactional-email-template-id>')
239
+ .description('Update a Transactional Email Template')
240
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
241
+ .requiredOption('--data <value>', 'Request body as JSON string')
242
+ .action(async (list_id, transactional_email_template_id, options) => {
243
+ const spinner = createSpinner('Updating transactional email...').start();
244
+ try {
245
+ const body = JSON.parse(options.data);
246
+ const data = await client.updateTransactionalEmailTemplate({
247
+ list_id: Number(list_id),
248
+ transactional_email_template_id: Number(transactional_email_template_id),
249
+ ...body,
250
+ });
251
+
252
+ spinner.stop();
253
+ formatter.success('Transactional Email updated successfully');
254
+ formatter.output(data);
255
+ } catch (error: any) {
256
+ spinner.stop();
257
+ formatter.error(error.message);
258
+ process.exit(1);
259
+ }
260
+ });
261
+
262
+
263
+ cmd
264
+ .command('delete-transactional-email-template <list-id> <transactional-email-template-id>')
265
+ .description('Delete a Transactional Email Template')
266
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
267
+ .option('-f, --force', 'Skip confirmation prompt')
268
+ .action(async (list_id, transactional_email_template_id, options) => {
269
+ if (!options.force) {
270
+ const confirmed = await confirmDelete('transactional email', list_id);
271
+ if (!confirmed) {
272
+ formatter.info('Deletion cancelled');
273
+ return;
274
+ }
275
+ }
276
+
277
+ const spinner = createSpinner('Deleting transactional email...').start();
278
+ try {
279
+ const data = await client.deleteTransactionalEmailTemplate({
280
+ list_id: Number(list_id),
281
+ transactional_email_template_id: Number(transactional_email_template_id),
282
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
283
+ });
284
+
285
+ spinner.stop();
286
+ formatter.success('Transactional Email deleted successfully');
287
+ } catch (error: any) {
288
+ spinner.stop();
289
+ formatter.error(error.message);
290
+ process.exit(1);
291
+ }
292
+ });
293
+
294
+
295
+ cmd
296
+ .command('send-transactional-email <list-id> <transactional-email-template-id>')
297
+ .description('Send a Transactional Email from a Template to a contact')
298
+ .option('--account-id <value>', 'account_id')
299
+ .requiredOption('--data <value>', 'Request body as JSON string')
300
+ .action(async (list_id, transactional_email_template_id, options) => {
301
+ const spinner = createSpinner('Creating transactional email...').start();
302
+ try {
303
+ const body = JSON.parse(options.data);
304
+ const data = await client.sendTransactionalEmail({
305
+ list_id: Number(list_id),
306
+ transactional_email_template_id: Number(transactional_email_template_id),
307
+ ...body,
308
+ });
309
+
310
+ spinner.stop();
311
+ formatter.success('Transactional Email created successfully');
312
+ formatter.output(data);
313
+ } catch (error: any) {
314
+ spinner.stop();
315
+ formatter.error(error.message);
316
+ process.exit(1);
317
+ }
318
+ });
319
+
320
+
321
+ cmd
322
+ .command('send-test-transactional-email <list-id> <transactional-email-template-id>')
323
+ .description('Send a Test Transactional Email from a Template')
324
+ .option('--account-id <value>', 'Optional Account ID to be used for the request')
325
+ .requiredOption('--email <value>', 'email')
326
+ .action(async (list_id, transactional_email_template_id, options) => {
327
+ const spinner = createSpinner('Creating transactional email...').start();
328
+ try {
329
+ const data = await client.sendTestTransactionalEmail({
330
+ list_id: Number(list_id),
331
+ transactional_email_template_id: Number(transactional_email_template_id),
332
+ accountId: options.accountId != null ? Number(options.accountId) : undefined,
333
+ email: options.email,
334
+ });
335
+
336
+ spinner.stop();
337
+ formatter.success('Transactional Email created successfully');
338
+ formatter.output(data);
339
+ } catch (error: any) {
340
+ spinner.stop();
341
+ formatter.error(error.message);
342
+ process.exit(1);
343
+ }
344
+ });
345
+
346
+
347
+ cmd
348
+ .command('render-transactional-email-template <list-id> <transactional-email-template-id>')
349
+ .description('Render a Transactional Email Template')
350
+ .option('--account-id <value>', 'account_id')
351
+ .requiredOption('--data <value>', 'Request body as JSON string')
352
+ .action(async (list_id, transactional_email_template_id, options) => {
353
+ const spinner = createSpinner('Creating transactional email...').start();
354
+ try {
355
+ const body = JSON.parse(options.data);
356
+ const data = await client.renderTransactionalEmailTemplate({
357
+ list_id: Number(list_id),
358
+ transactional_email_template_id: Number(transactional_email_template_id),
359
+ ...body,
360
+ });
361
+
362
+ spinner.stop();
363
+ formatter.success('Transactional Email created successfully');
364
+ formatter.output(data);
365
+ } catch (error: any) {
366
+ spinner.stop();
367
+ formatter.error(error.message);
368
+ process.exit(1);
369
+ }
370
+ });
371
+
372
+
373
+ return cmd;
374
+ }