@mailmodo/cli 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/settings/index.d.ts +18 -1
- package/dist/commands/settings/index.js +159 -40
- package/oclif.manifest.json +90 -90
- package/package.json +1 -1
|
@@ -8,13 +8,30 @@ export default class Settings extends BaseCommand {
|
|
|
8
8
|
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
9
|
};
|
|
10
10
|
run(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Prompts the user to pick a setting key to edit and dispatches
|
|
13
|
+
* to the appropriate handler for that key.
|
|
14
|
+
*/
|
|
15
|
+
private promptEditSetting;
|
|
16
|
+
/**
|
|
17
|
+
* Fetches the domain verification status from the API.
|
|
18
|
+
* Returns true/false for verified/unverified, or null if unavailable.
|
|
19
|
+
*/
|
|
20
|
+
private fetchDomainVerified;
|
|
21
|
+
/**
|
|
22
|
+
* Handles domain change: collects the new domain, sender email, and
|
|
23
|
+
* business address, calls the API to register them, displays the required
|
|
24
|
+
* DNS records, and saves the updated config. Emails won't send until the
|
|
25
|
+
* domain is re-verified.
|
|
26
|
+
*/
|
|
27
|
+
private handleDomainChange;
|
|
28
|
+
private recordLabel;
|
|
11
29
|
/**
|
|
12
30
|
* Handles the logo file upload flow: validates the local file exists,
|
|
13
31
|
* reads it, uploads to Mailmodo CDN via API, and updates both logoFile
|
|
14
32
|
* and logoUrl in the project config.
|
|
15
33
|
*
|
|
16
34
|
* @param {import('../../lib/yaml-config.js').MailmodoYaml} yamlConfig - The full YAML config to update and save.
|
|
17
|
-
* @param {boolean} jsonOutput - When true, spinner uses stderr so stdout stays clean.
|
|
18
35
|
*/
|
|
19
36
|
private handleLogoUpload;
|
|
20
37
|
}
|
|
@@ -5,7 +5,7 @@ import { existsSync } from 'node:fs';
|
|
|
5
5
|
import { readFile } from 'node:fs/promises';
|
|
6
6
|
import { resolve } from 'node:path';
|
|
7
7
|
import { BaseCommand } from '../../lib/base-command.js';
|
|
8
|
-
import { API_ENDPOINTS } from '../../lib/constants.js';
|
|
8
|
+
import { API_ENDPOINTS, DNS_GUIDE_URL } from '../../lib/constants.js';
|
|
9
9
|
import { saveYaml } from '../../lib/yaml-config.js';
|
|
10
10
|
const SETTINGS_GROUPS = Object.freeze({
|
|
11
11
|
billing: ['monthly_cap'],
|
|
@@ -14,6 +14,11 @@ const SETTINGS_GROUPS = Object.freeze({
|
|
|
14
14
|
identity: ['from_name', 'from_email', 'reply_to'],
|
|
15
15
|
integrations: ['webhook_url'],
|
|
16
16
|
});
|
|
17
|
+
const SETUP_HINTS = {
|
|
18
|
+
address: "'mailmodo domain'",
|
|
19
|
+
domain: "'mailmodo domain'",
|
|
20
|
+
monthlyCap: "'mailmodo billing --cap <n>'",
|
|
21
|
+
};
|
|
17
22
|
/**
|
|
18
23
|
* Converts a user-facing snake_case YAML setting key to its
|
|
19
24
|
* corresponding camelCase TypeScript property name.
|
|
@@ -65,66 +70,180 @@ export default class Settings extends BaseCommand {
|
|
|
65
70
|
this.log(JSON.stringify({ settings: project }, null, 2));
|
|
66
71
|
return;
|
|
67
72
|
}
|
|
73
|
+
const domainVerified = await this.fetchDomainVerified(project.domain);
|
|
68
74
|
this.log(`\n Current settings for ${chalk.bold(project.name || 'project')}:\n`);
|
|
69
75
|
for (const [group, keys] of Object.entries(SETTINGS_GROUPS)) {
|
|
76
|
+
const availableKeys = keys.filter((key) => settingKeyToProp(key) in project);
|
|
77
|
+
if (availableKeys.length === 0) {
|
|
78
|
+
const hint = SETUP_HINTS[settingKeyToProp(keys[0])];
|
|
79
|
+
if (hint) {
|
|
80
|
+
this.log(` ${chalk.bold(group.charAt(0).toUpperCase() + group.slice(1))}`);
|
|
81
|
+
this.log(` ${'─'.repeat(49)}`);
|
|
82
|
+
this.log(` ${chalk.dim(`Run ${hint} to configure.`)}`);
|
|
83
|
+
this.log('');
|
|
84
|
+
}
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
70
87
|
this.log(` ${chalk.bold(group.charAt(0).toUpperCase() + group.slice(1))}`);
|
|
71
88
|
this.log(` ${'─'.repeat(49)}`);
|
|
72
|
-
for (const key of
|
|
89
|
+
for (const key of availableKeys) {
|
|
73
90
|
const propKey = settingKeyToProp(key);
|
|
74
91
|
const value = project[propKey];
|
|
75
|
-
|
|
92
|
+
let displayValue = value ? String(value) : chalk.dim('(not set)');
|
|
93
|
+
if (key === 'domain' && value && domainVerified === true) {
|
|
94
|
+
displayValue += ` ${chalk.green('✓ verified')}`;
|
|
95
|
+
}
|
|
96
|
+
else if (key === 'domain' && value && domainVerified === false) {
|
|
97
|
+
displayValue += ` ${chalk.red('✗ not verified')}`;
|
|
98
|
+
}
|
|
76
99
|
this.log(` ${key.padEnd(16)} ${displayValue}`);
|
|
77
100
|
}
|
|
101
|
+
const missingKeys = keys.filter((key) => !(settingKeyToProp(key) in project));
|
|
102
|
+
for (const key of missingKeys) {
|
|
103
|
+
const hint = SETUP_HINTS[settingKeyToProp(key)];
|
|
104
|
+
if (hint) {
|
|
105
|
+
this.log(` ${key.padEnd(16)} ${chalk.dim(`(run ${hint} to set up)`)}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
78
108
|
this.log('');
|
|
79
109
|
}
|
|
80
110
|
if (!flags.yes) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
111
|
+
await this.promptEditSetting(yamlConfig);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Prompts the user to pick a setting key to edit and dispatches
|
|
116
|
+
* to the appropriate handler for that key.
|
|
117
|
+
*/
|
|
118
|
+
async promptEditSetting(yamlConfig) {
|
|
119
|
+
const { project } = yamlConfig;
|
|
120
|
+
const editKey = await input({
|
|
121
|
+
default: 'n',
|
|
122
|
+
message: "Edit a setting? (key or 'n'):",
|
|
123
|
+
});
|
|
124
|
+
if (editKey === 'n')
|
|
125
|
+
return;
|
|
126
|
+
const editPropKey = settingKeyToProp(editKey);
|
|
127
|
+
if (!(editPropKey in project)) {
|
|
128
|
+
const hint = SETUP_HINTS[editPropKey];
|
|
129
|
+
if (hint) {
|
|
130
|
+
this.log(`\n ${editKey} is not configured yet. Run ${chalk.cyan(hint)} to set it up.\n`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
this.log(`\n Unknown setting: ${editKey}\n`);
|
|
134
|
+
}
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (editKey === 'logo_file') {
|
|
138
|
+
await this.handleLogoUpload(yamlConfig);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (editKey === 'domain') {
|
|
142
|
+
await this.handleDomainChange(yamlConfig);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (editKey === 'email_style') {
|
|
146
|
+
const style = await select({
|
|
147
|
+
choices: [
|
|
148
|
+
{ name: 'plain', value: 'plain' },
|
|
149
|
+
{ name: 'branded', value: 'branded' },
|
|
150
|
+
],
|
|
151
|
+
message: 'Email style:',
|
|
84
152
|
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
project[editPropKey] =
|
|
113
|
-
editPropKey === 'monthlyCap' ? Number(newValue) : newValue;
|
|
114
|
-
await saveYaml(yamlConfig);
|
|
115
|
-
this.log(`\n ${chalk.green('✓')} Updated. Run ${chalk.cyan("'mailmodo deploy'")} to apply.\n`);
|
|
153
|
+
project.emailStyle = style;
|
|
154
|
+
await saveYaml(yamlConfig);
|
|
155
|
+
this.log(`\n ${chalk.green('✓')} email_style updated to ${chalk.cyan(style)}`);
|
|
156
|
+
this.log(` Run ${chalk.cyan("'mailmodo deploy'")} to apply.\n`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const newValue = await input({
|
|
160
|
+
message: `New value for ${editKey}:`,
|
|
161
|
+
});
|
|
162
|
+
project[editPropKey] =
|
|
163
|
+
editPropKey === 'monthlyCap' ? Number(newValue) : newValue;
|
|
164
|
+
await saveYaml(yamlConfig);
|
|
165
|
+
this.log(`\n ${chalk.green('✓')} Updated. Run ${chalk.cyan("'mailmodo deploy'")} to apply.\n`);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Fetches the domain verification status from the API.
|
|
169
|
+
* Returns true/false for verified/unverified, or null if unavailable.
|
|
170
|
+
*/
|
|
171
|
+
async fetchDomainVerified(domain) {
|
|
172
|
+
if (!domain)
|
|
173
|
+
return null;
|
|
174
|
+
try {
|
|
175
|
+
await this.ensureAuth();
|
|
176
|
+
const response = await this.apiClient.get(API_ENDPOINTS.DOMAIN_STATUS, { domain });
|
|
177
|
+
if (!response.ok) {
|
|
178
|
+
this.log(` ${chalk.dim('Could not fetch domain status. Run')} ${chalk.cyan("'mailmodo domain --status'")} ${chalk.dim('to check manually.')}`);
|
|
179
|
+
return null;
|
|
116
180
|
}
|
|
181
|
+
return response.data?.verified === true;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
this.log(` ${chalk.dim('Could not reach API for domain status. Skipping verification check.')}`);
|
|
185
|
+
return null;
|
|
117
186
|
}
|
|
118
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Handles domain change: collects the new domain, sender email, and
|
|
190
|
+
* business address, calls the API to register them, displays the required
|
|
191
|
+
* DNS records, and saves the updated config. Emails won't send until the
|
|
192
|
+
* domain is re-verified.
|
|
193
|
+
*/
|
|
194
|
+
async handleDomainChange(yamlConfig) {
|
|
195
|
+
const newDomain = await input({
|
|
196
|
+
message: 'New domain:',
|
|
197
|
+
validate: (v) => (v?.trim() ? true : 'Domain is required'),
|
|
198
|
+
});
|
|
199
|
+
const newFromEmail = await input({
|
|
200
|
+
default: yamlConfig.project.fromEmail || '',
|
|
201
|
+
message: 'Sender email (from address):',
|
|
202
|
+
validate: (v) => v?.includes('@') ? true : 'Please enter a valid email',
|
|
203
|
+
});
|
|
204
|
+
const newAddress = await input({
|
|
205
|
+
default: yamlConfig.project.address || '',
|
|
206
|
+
message: 'Business address (required by law):',
|
|
207
|
+
validate: (v) => (v?.trim() ? true : 'Address is required'),
|
|
208
|
+
});
|
|
209
|
+
await this.ensureAuth();
|
|
210
|
+
const response = await this.apiClient.post(API_ENDPOINTS.DOMAIN, {
|
|
211
|
+
address: newAddress,
|
|
212
|
+
domain: newDomain,
|
|
213
|
+
fromEmail: newFromEmail,
|
|
214
|
+
});
|
|
215
|
+
if (!response.ok) {
|
|
216
|
+
this.handleApiError(response);
|
|
217
|
+
}
|
|
218
|
+
const records = response.data?.dnsRecords || [];
|
|
219
|
+
yamlConfig.project.domain = newDomain;
|
|
220
|
+
yamlConfig.project.fromEmail = newFromEmail;
|
|
221
|
+
yamlConfig.project.address = newAddress;
|
|
222
|
+
await saveYaml(yamlConfig);
|
|
223
|
+
this.log(`\n Domain, sender email, and business address updated. You will need to re-verify.`);
|
|
224
|
+
this.log(` New DNS records:\n`);
|
|
225
|
+
for (const [i, record] of records.entries()) {
|
|
226
|
+
this.log(` ${chalk.bold(`RECORD ${i + 1} — ${this.recordLabel(i)}`)}`);
|
|
227
|
+
this.log(` Type: ${record.type}`);
|
|
228
|
+
this.log(` Host: ${record.host}`);
|
|
229
|
+
this.log(` Value: ${record.value}\n`);
|
|
230
|
+
}
|
|
231
|
+
this.log(` Run ${chalk.cyan("'mailmodo domain --verify'")} once records are added.`);
|
|
232
|
+
this.log(` Emails will not send until the new domain is verified.`);
|
|
233
|
+
this.log(` Help: ${chalk.cyan(DNS_GUIDE_URL)}\n`);
|
|
234
|
+
}
|
|
235
|
+
recordLabel(index) {
|
|
236
|
+
const labels = ['SPF', 'DKIM', 'DMARC'];
|
|
237
|
+
return labels[index] || `Record ${index + 1}`;
|
|
238
|
+
}
|
|
119
239
|
/**
|
|
120
240
|
* Handles the logo file upload flow: validates the local file exists,
|
|
121
241
|
* reads it, uploads to Mailmodo CDN via API, and updates both logoFile
|
|
122
242
|
* and logoUrl in the project config.
|
|
123
243
|
*
|
|
124
244
|
* @param {import('../../lib/yaml-config.js').MailmodoYaml} yamlConfig - The full YAML config to update and save.
|
|
125
|
-
* @param {boolean} jsonOutput - When true, spinner uses stderr so stdout stays clean.
|
|
126
245
|
*/
|
|
127
|
-
async handleLogoUpload(yamlConfig
|
|
246
|
+
async handleLogoUpload(yamlConfig) {
|
|
128
247
|
const logoPath = await input({ message: 'Path to logo file:' });
|
|
129
248
|
const resolvedPath = resolve(logoPath);
|
|
130
249
|
if (!existsSync(resolvedPath)) {
|
|
@@ -135,7 +254,7 @@ export default class Settings extends BaseCommand {
|
|
|
135
254
|
const fileBuffer = await readFile(resolvedPath);
|
|
136
255
|
const formData = new FormData();
|
|
137
256
|
formData.append('logo', new Blob([new Uint8Array(fileBuffer)]), logoPath.split(/[/\\]/).pop() || 'logo.png');
|
|
138
|
-
const response = await this.
|
|
257
|
+
const response = await this.apiClient.postFormData(API_ENDPOINTS.ASSETS_LOGO, formData);
|
|
139
258
|
if (!response.ok) {
|
|
140
259
|
this.handleApiError(response);
|
|
141
260
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -205,19 +205,13 @@
|
|
|
205
205
|
"index.js"
|
|
206
206
|
]
|
|
207
207
|
},
|
|
208
|
-
"
|
|
208
|
+
"emails": {
|
|
209
209
|
"aliases": [],
|
|
210
|
-
"args": {
|
|
211
|
-
|
|
212
|
-
"description": "Email ID to edit",
|
|
213
|
-
"name": "id",
|
|
214
|
-
"required": true
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
"description": "Edit an email using AI-assisted natural language changes",
|
|
210
|
+
"args": {},
|
|
211
|
+
"description": "List and view configured email sequences",
|
|
218
212
|
"examples": [
|
|
219
|
-
"<%= config.bin %>
|
|
220
|
-
"<%= config.bin %>
|
|
213
|
+
"<%= config.bin %> emails",
|
|
214
|
+
"<%= config.bin %> emails --json"
|
|
221
215
|
],
|
|
222
216
|
"flags": {
|
|
223
217
|
"json": {
|
|
@@ -232,18 +226,11 @@
|
|
|
232
226
|
"name": "yes",
|
|
233
227
|
"allowNo": false,
|
|
234
228
|
"type": "boolean"
|
|
235
|
-
},
|
|
236
|
-
"change": {
|
|
237
|
-
"description": "Natural language description of the change",
|
|
238
|
-
"name": "change",
|
|
239
|
-
"hasDynamicHelp": false,
|
|
240
|
-
"multiple": false,
|
|
241
|
-
"type": "option"
|
|
242
229
|
}
|
|
243
230
|
},
|
|
244
231
|
"hasDynamicHelp": false,
|
|
245
232
|
"hiddenAliases": [],
|
|
246
|
-
"id": "
|
|
233
|
+
"id": "emails",
|
|
247
234
|
"pluginAlias": "@mailmodo/cli",
|
|
248
235
|
"pluginName": "@mailmodo/cli",
|
|
249
236
|
"pluginType": "core",
|
|
@@ -253,17 +240,23 @@
|
|
|
253
240
|
"relativePath": [
|
|
254
241
|
"dist",
|
|
255
242
|
"commands",
|
|
256
|
-
"
|
|
243
|
+
"emails",
|
|
257
244
|
"index.js"
|
|
258
245
|
]
|
|
259
246
|
},
|
|
260
|
-
"
|
|
247
|
+
"edit": {
|
|
261
248
|
"aliases": [],
|
|
262
|
-
"args": {
|
|
263
|
-
|
|
249
|
+
"args": {
|
|
250
|
+
"id": {
|
|
251
|
+
"description": "Email ID to edit",
|
|
252
|
+
"name": "id",
|
|
253
|
+
"required": true
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
"description": "Edit an email using AI-assisted natural language changes",
|
|
264
257
|
"examples": [
|
|
265
|
-
"<%= config.bin %>
|
|
266
|
-
"<%= config.bin %>
|
|
258
|
+
"<%= config.bin %> edit welcome",
|
|
259
|
+
"<%= config.bin %> edit welcome --change \"make subject more urgent\" --yes"
|
|
267
260
|
],
|
|
268
261
|
"flags": {
|
|
269
262
|
"json": {
|
|
@@ -278,11 +271,18 @@
|
|
|
278
271
|
"name": "yes",
|
|
279
272
|
"allowNo": false,
|
|
280
273
|
"type": "boolean"
|
|
274
|
+
},
|
|
275
|
+
"change": {
|
|
276
|
+
"description": "Natural language description of the change",
|
|
277
|
+
"name": "change",
|
|
278
|
+
"hasDynamicHelp": false,
|
|
279
|
+
"multiple": false,
|
|
280
|
+
"type": "option"
|
|
281
281
|
}
|
|
282
282
|
},
|
|
283
283
|
"hasDynamicHelp": false,
|
|
284
284
|
"hiddenAliases": [],
|
|
285
|
-
"id": "
|
|
285
|
+
"id": "edit",
|
|
286
286
|
"pluginAlias": "@mailmodo/cli",
|
|
287
287
|
"pluginName": "@mailmodo/cli",
|
|
288
288
|
"pluginType": "core",
|
|
@@ -292,7 +292,7 @@
|
|
|
292
292
|
"relativePath": [
|
|
293
293
|
"dist",
|
|
294
294
|
"commands",
|
|
295
|
-
"
|
|
295
|
+
"edit",
|
|
296
296
|
"index.js"
|
|
297
297
|
]
|
|
298
298
|
},
|
|
@@ -342,13 +342,12 @@
|
|
|
342
342
|
"index.js"
|
|
343
343
|
]
|
|
344
344
|
},
|
|
345
|
-
"
|
|
345
|
+
"logout": {
|
|
346
346
|
"aliases": [],
|
|
347
347
|
"args": {},
|
|
348
|
-
"description": "
|
|
348
|
+
"description": "Sign out by removing saved credentials from this machine",
|
|
349
349
|
"examples": [
|
|
350
|
-
"<%= config.bin %>
|
|
351
|
-
"MAILMODO_API_KEY=mm_live_xxx <%= config.bin %> login"
|
|
350
|
+
"<%= config.bin %> logout"
|
|
352
351
|
],
|
|
353
352
|
"flags": {
|
|
354
353
|
"json": {
|
|
@@ -367,7 +366,7 @@
|
|
|
367
366
|
},
|
|
368
367
|
"hasDynamicHelp": false,
|
|
369
368
|
"hiddenAliases": [],
|
|
370
|
-
"id": "
|
|
369
|
+
"id": "logout",
|
|
371
370
|
"pluginAlias": "@mailmodo/cli",
|
|
372
371
|
"pluginName": "@mailmodo/cli",
|
|
373
372
|
"pluginType": "core",
|
|
@@ -377,16 +376,19 @@
|
|
|
377
376
|
"relativePath": [
|
|
378
377
|
"dist",
|
|
379
378
|
"commands",
|
|
380
|
-
"
|
|
379
|
+
"logout",
|
|
381
380
|
"index.js"
|
|
382
381
|
]
|
|
383
382
|
},
|
|
384
|
-
"
|
|
383
|
+
"logs": {
|
|
385
384
|
"aliases": [],
|
|
386
385
|
"args": {},
|
|
387
|
-
"description": "
|
|
386
|
+
"description": "View email send logs and delivery events",
|
|
388
387
|
"examples": [
|
|
389
|
-
"<%= config.bin %>
|
|
388
|
+
"<%= config.bin %> logs",
|
|
389
|
+
"<%= config.bin %> logs --email sarah@example.com",
|
|
390
|
+
"<%= config.bin %> logs --failed",
|
|
391
|
+
"<%= config.bin %> logs --json"
|
|
390
392
|
],
|
|
391
393
|
"flags": {
|
|
392
394
|
"json": {
|
|
@@ -401,11 +403,24 @@
|
|
|
401
403
|
"name": "yes",
|
|
402
404
|
"allowNo": false,
|
|
403
405
|
"type": "boolean"
|
|
406
|
+
},
|
|
407
|
+
"email": {
|
|
408
|
+
"description": "Filter logs by contact email",
|
|
409
|
+
"name": "email",
|
|
410
|
+
"hasDynamicHelp": false,
|
|
411
|
+
"multiple": false,
|
|
412
|
+
"type": "option"
|
|
413
|
+
},
|
|
414
|
+
"failed": {
|
|
415
|
+
"description": "Show only failed/bounced events",
|
|
416
|
+
"name": "failed",
|
|
417
|
+
"allowNo": false,
|
|
418
|
+
"type": "boolean"
|
|
404
419
|
}
|
|
405
420
|
},
|
|
406
421
|
"hasDynamicHelp": false,
|
|
407
422
|
"hiddenAliases": [],
|
|
408
|
-
"id": "
|
|
423
|
+
"id": "logs",
|
|
409
424
|
"pluginAlias": "@mailmodo/cli",
|
|
410
425
|
"pluginName": "@mailmodo/cli",
|
|
411
426
|
"pluginType": "core",
|
|
@@ -415,19 +430,23 @@
|
|
|
415
430
|
"relativePath": [
|
|
416
431
|
"dist",
|
|
417
432
|
"commands",
|
|
418
|
-
"
|
|
433
|
+
"logs",
|
|
419
434
|
"index.js"
|
|
420
435
|
]
|
|
421
436
|
},
|
|
422
|
-
"
|
|
437
|
+
"preview": {
|
|
423
438
|
"aliases": [],
|
|
424
|
-
"args": {
|
|
425
|
-
|
|
439
|
+
"args": {
|
|
440
|
+
"id": {
|
|
441
|
+
"description": "Email ID to preview",
|
|
442
|
+
"name": "id"
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
"description": "Preview an email in browser, as text, or send a test",
|
|
426
446
|
"examples": [
|
|
427
|
-
"<%= config.bin %>
|
|
428
|
-
"<%= config.bin %>
|
|
429
|
-
"<%= config.bin %>
|
|
430
|
-
"<%= config.bin %> logs --json"
|
|
447
|
+
"<%= config.bin %> preview welcome",
|
|
448
|
+
"<%= config.bin %> preview welcome --text",
|
|
449
|
+
"<%= config.bin %> preview welcome --send me@example.com"
|
|
431
450
|
],
|
|
432
451
|
"flags": {
|
|
433
452
|
"json": {
|
|
@@ -443,23 +462,23 @@
|
|
|
443
462
|
"allowNo": false,
|
|
444
463
|
"type": "boolean"
|
|
445
464
|
},
|
|
446
|
-
"
|
|
447
|
-
"description": "
|
|
448
|
-
"name": "
|
|
465
|
+
"send": {
|
|
466
|
+
"description": "Send test email to this address",
|
|
467
|
+
"name": "send",
|
|
449
468
|
"hasDynamicHelp": false,
|
|
450
469
|
"multiple": false,
|
|
451
470
|
"type": "option"
|
|
452
471
|
},
|
|
453
|
-
"
|
|
454
|
-
"description": "
|
|
455
|
-
"name": "
|
|
472
|
+
"text": {
|
|
473
|
+
"description": "Output plain text version (for AI agents)",
|
|
474
|
+
"name": "text",
|
|
456
475
|
"allowNo": false,
|
|
457
476
|
"type": "boolean"
|
|
458
477
|
}
|
|
459
478
|
},
|
|
460
479
|
"hasDynamicHelp": false,
|
|
461
480
|
"hiddenAliases": [],
|
|
462
|
-
"id": "
|
|
481
|
+
"id": "preview",
|
|
463
482
|
"pluginAlias": "@mailmodo/cli",
|
|
464
483
|
"pluginName": "@mailmodo/cli",
|
|
465
484
|
"pluginType": "core",
|
|
@@ -469,18 +488,17 @@
|
|
|
469
488
|
"relativePath": [
|
|
470
489
|
"dist",
|
|
471
490
|
"commands",
|
|
472
|
-
"
|
|
491
|
+
"preview",
|
|
473
492
|
"index.js"
|
|
474
493
|
]
|
|
475
494
|
},
|
|
476
|
-
"
|
|
495
|
+
"login": {
|
|
477
496
|
"aliases": [],
|
|
478
497
|
"args": {},
|
|
479
|
-
"description": "
|
|
498
|
+
"description": "Authenticate with Mailmodo using your API key",
|
|
480
499
|
"examples": [
|
|
481
|
-
"<%= config.bin %>
|
|
482
|
-
"<%= config.bin %>
|
|
483
|
-
"<%= config.bin %> settings --json"
|
|
500
|
+
"<%= config.bin %> login",
|
|
501
|
+
"MAILMODO_API_KEY=mm_live_xxx <%= config.bin %> login"
|
|
484
502
|
],
|
|
485
503
|
"flags": {
|
|
486
504
|
"json": {
|
|
@@ -495,18 +513,11 @@
|
|
|
495
513
|
"name": "yes",
|
|
496
514
|
"allowNo": false,
|
|
497
515
|
"type": "boolean"
|
|
498
|
-
},
|
|
499
|
-
"set": {
|
|
500
|
-
"description": "Set a setting (format: key=value)",
|
|
501
|
-
"name": "set",
|
|
502
|
-
"hasDynamicHelp": false,
|
|
503
|
-
"multiple": false,
|
|
504
|
-
"type": "option"
|
|
505
516
|
}
|
|
506
517
|
},
|
|
507
518
|
"hasDynamicHelp": false,
|
|
508
519
|
"hiddenAliases": [],
|
|
509
|
-
"id": "
|
|
520
|
+
"id": "login",
|
|
510
521
|
"pluginAlias": "@mailmodo/cli",
|
|
511
522
|
"pluginName": "@mailmodo/cli",
|
|
512
523
|
"pluginType": "core",
|
|
@@ -516,23 +527,18 @@
|
|
|
516
527
|
"relativePath": [
|
|
517
528
|
"dist",
|
|
518
529
|
"commands",
|
|
519
|
-
"
|
|
530
|
+
"login",
|
|
520
531
|
"index.js"
|
|
521
532
|
]
|
|
522
533
|
},
|
|
523
|
-
"
|
|
534
|
+
"settings": {
|
|
524
535
|
"aliases": [],
|
|
525
|
-
"args": {
|
|
526
|
-
|
|
527
|
-
"description": "Email ID to preview",
|
|
528
|
-
"name": "id"
|
|
529
|
-
}
|
|
530
|
-
},
|
|
531
|
-
"description": "Preview an email in browser, as text, or send a test",
|
|
536
|
+
"args": {},
|
|
537
|
+
"description": "View and update project settings",
|
|
532
538
|
"examples": [
|
|
533
|
-
"<%= config.bin %>
|
|
534
|
-
"<%= config.bin %>
|
|
535
|
-
"<%= config.bin %>
|
|
539
|
+
"<%= config.bin %> settings",
|
|
540
|
+
"<%= config.bin %> settings --set brand_color=#0F3460",
|
|
541
|
+
"<%= config.bin %> settings --json"
|
|
536
542
|
],
|
|
537
543
|
"flags": {
|
|
538
544
|
"json": {
|
|
@@ -548,23 +554,17 @@
|
|
|
548
554
|
"allowNo": false,
|
|
549
555
|
"type": "boolean"
|
|
550
556
|
},
|
|
551
|
-
"
|
|
552
|
-
"description": "
|
|
553
|
-
"name": "
|
|
557
|
+
"set": {
|
|
558
|
+
"description": "Set a setting (format: key=value)",
|
|
559
|
+
"name": "set",
|
|
554
560
|
"hasDynamicHelp": false,
|
|
555
561
|
"multiple": false,
|
|
556
562
|
"type": "option"
|
|
557
|
-
},
|
|
558
|
-
"text": {
|
|
559
|
-
"description": "Output plain text version (for AI agents)",
|
|
560
|
-
"name": "text",
|
|
561
|
-
"allowNo": false,
|
|
562
|
-
"type": "boolean"
|
|
563
563
|
}
|
|
564
564
|
},
|
|
565
565
|
"hasDynamicHelp": false,
|
|
566
566
|
"hiddenAliases": [],
|
|
567
|
-
"id": "
|
|
567
|
+
"id": "settings",
|
|
568
568
|
"pluginAlias": "@mailmodo/cli",
|
|
569
569
|
"pluginName": "@mailmodo/cli",
|
|
570
570
|
"pluginType": "core",
|
|
@@ -574,7 +574,7 @@
|
|
|
574
574
|
"relativePath": [
|
|
575
575
|
"dist",
|
|
576
576
|
"commands",
|
|
577
|
-
"
|
|
577
|
+
"settings",
|
|
578
578
|
"index.js"
|
|
579
579
|
]
|
|
580
580
|
},
|
|
@@ -618,5 +618,5 @@
|
|
|
618
618
|
]
|
|
619
619
|
}
|
|
620
620
|
},
|
|
621
|
-
"version": "0.0.
|
|
621
|
+
"version": "0.0.13"
|
|
622
622
|
}
|