@mailmodo/cli 0.0.12-beta.pr15.19 → 0.0.13-beta.pr14.22
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/domain/index.js +29 -15
- package/dist/commands/init/index.js +1 -1
- package/dist/commands/settings/index.js +1 -1
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/constants.d.ts +1 -1
- package/dist/lib/constants.js +2 -1
- package/oclif.manifest.json +1 -1
- package/package.json +16 -4
|
@@ -3,6 +3,7 @@ import { input } from '@inquirer/prompts';
|
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { BaseCommand } from '../../lib/base-command.js';
|
|
5
5
|
import { API_ENDPOINTS, DNS_GUIDE_URL } from '../../lib/constants.js';
|
|
6
|
+
import { saveConfig } from '../../lib/config.js';
|
|
6
7
|
import { saveYaml } from '../../lib/yaml-config.js';
|
|
7
8
|
export default class Domain extends BaseCommand {
|
|
8
9
|
static description = 'Set up and verify your sending domain';
|
|
@@ -24,22 +25,22 @@ export default class Domain extends BaseCommand {
|
|
|
24
25
|
};
|
|
25
26
|
async run() {
|
|
26
27
|
const { flags } = await this.parse(Domain);
|
|
27
|
-
await this.ensureAuth();
|
|
28
|
+
const config = await this.ensureAuth();
|
|
28
29
|
if (flags.verify) {
|
|
29
|
-
await this.verifyDomain(flags.json);
|
|
30
|
+
await this.verifyDomain(flags.json, config);
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
32
33
|
if (flags.status) {
|
|
33
|
-
await this.showDomainStatus(flags.json);
|
|
34
|
+
await this.showDomainStatus(flags.json, config);
|
|
34
35
|
return;
|
|
35
36
|
}
|
|
36
|
-
await this.setupDomain(flags);
|
|
37
|
+
await this.setupDomain(flags, config);
|
|
37
38
|
}
|
|
38
39
|
/**
|
|
39
40
|
* Interactive domain setup: collects domain, sender email, and business address,
|
|
40
41
|
* then calls the API to retrieve the required DNS records.
|
|
41
42
|
*/
|
|
42
|
-
async setupDomain(flags) {
|
|
43
|
+
async setupDomain(flags, config) {
|
|
43
44
|
const yamlConfig = await this.ensureYaml();
|
|
44
45
|
this.log(`\n ${'─'.repeat(53)}`);
|
|
45
46
|
this.log(` ${chalk.bold('DOMAIN SETUP')}`);
|
|
@@ -84,6 +85,7 @@ export default class Domain extends BaseCommand {
|
|
|
84
85
|
yamlConfig.project.fromEmail = senderEmail;
|
|
85
86
|
yamlConfig.project.address = address;
|
|
86
87
|
await saveYaml(yamlConfig);
|
|
88
|
+
await saveConfig({ ...config, domain });
|
|
87
89
|
const records = response.data?.dnsRecords || [];
|
|
88
90
|
if (flags.json) {
|
|
89
91
|
this.log(JSON.stringify({ dnsRecords: records, domain }, null, 2));
|
|
@@ -104,15 +106,21 @@ export default class Domain extends BaseCommand {
|
|
|
104
106
|
message: "Press Enter once you've added the records, or 'skip'.",
|
|
105
107
|
});
|
|
106
108
|
if (action.toLowerCase() !== 'skip') {
|
|
107
|
-
await this.verifyDomain(false);
|
|
109
|
+
await this.verifyDomain(false, { ...config, domain });
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
/**
|
|
112
114
|
* Calls the domain verification API and displays pass/fail for each DNS record.
|
|
113
115
|
*/
|
|
114
|
-
async verifyDomain(jsonOutput) {
|
|
115
|
-
|
|
116
|
+
async verifyDomain(jsonOutput, config) {
|
|
117
|
+
if (!config.domain) {
|
|
118
|
+
this.error(`No domain configured. Run ${chalk.cyan('mailmodo domain')} to set up your sending domain.`);
|
|
119
|
+
}
|
|
120
|
+
const domain = config.domain;
|
|
121
|
+
const response = await this.withApiSpinner({ json: jsonOutput, text: ' Checking DNS...' }, () => this.apiClient.get(API_ENDPOINTS.DOMAIN_VERIFY, {
|
|
122
|
+
domain,
|
|
123
|
+
}));
|
|
116
124
|
if (!response.ok) {
|
|
117
125
|
this.handleApiError(response);
|
|
118
126
|
}
|
|
@@ -121,16 +129,16 @@ export default class Domain extends BaseCommand {
|
|
|
121
129
|
this.log(JSON.stringify({ dkim, dmarc, spf }, null, 2));
|
|
122
130
|
return;
|
|
123
131
|
}
|
|
124
|
-
this.log(` SPF ${spf
|
|
125
|
-
this.log(` DKIM ${dkim
|
|
126
|
-
this.log(` DMARC ${dmarc
|
|
127
|
-
const allPassed = spf
|
|
132
|
+
this.log(` SPF ${spf ? chalk.green('✓') : chalk.red('✗ Not found')}`);
|
|
133
|
+
this.log(` DKIM ${dkim ? chalk.green('✓') : chalk.red('✗ Not found')}`);
|
|
134
|
+
this.log(` DMARC ${dmarc ? chalk.green('✓') : chalk.red('✗ Not found')}`);
|
|
135
|
+
const allPassed = spf && dkim && dmarc;
|
|
128
136
|
if (allPassed) {
|
|
129
137
|
this.log(`\n ${chalk.green('✓')} Domain verified.\n`);
|
|
130
138
|
}
|
|
131
139
|
else {
|
|
132
140
|
this.log(`\n ${chalk.yellow('Some records failed.')}`);
|
|
133
|
-
if (dkim
|
|
141
|
+
if (!dkim) {
|
|
134
142
|
this.log(`\n DKIM common mistakes:`);
|
|
135
143
|
this.log(` - Using TXT instead of CNAME record type`);
|
|
136
144
|
this.log(` - Including the full domain in the Host field`);
|
|
@@ -144,8 +152,14 @@ export default class Domain extends BaseCommand {
|
|
|
144
152
|
* Displays domain health metrics including verification status,
|
|
145
153
|
* bounce rate, and spam complaint rate.
|
|
146
154
|
*/
|
|
147
|
-
async showDomainStatus(jsonOutput) {
|
|
148
|
-
|
|
155
|
+
async showDomainStatus(jsonOutput, config) {
|
|
156
|
+
if (!config.domain) {
|
|
157
|
+
this.error(`No domain configured. Run ${chalk.cyan('mailmodo domain')} to set up your sending domain.`);
|
|
158
|
+
}
|
|
159
|
+
const domain = config.domain;
|
|
160
|
+
const response = await this.withApiSpinner({ json: jsonOutput, text: ' Loading domain status...' }, () => this.apiClient.get(API_ENDPOINTS.DOMAIN_STATUS, {
|
|
161
|
+
domain,
|
|
162
|
+
}));
|
|
149
163
|
if (!response.ok) {
|
|
150
164
|
this.handleApiError(response);
|
|
151
165
|
}
|
|
@@ -2,7 +2,7 @@ import { Flags } from '@oclif/core';
|
|
|
2
2
|
import { editor, input, select } from '@inquirer/prompts';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { BaseCommand } from '../../lib/base-command.js';
|
|
5
|
-
import { API_ENDPOINTS, DEFAULT_BRAND_COLOR, DEFAULT_MONTHLY_CAP } from '../../lib/constants.js';
|
|
5
|
+
import { API_ENDPOINTS, DEFAULT_BRAND_COLOR, DEFAULT_MONTHLY_CAP, } from '../../lib/constants.js';
|
|
6
6
|
import { saveTemplate, saveYaml, } from '../../lib/yaml-config.js';
|
|
7
7
|
function isValidUrl(value) {
|
|
8
8
|
try {
|
|
@@ -199,7 +199,7 @@ export default class Settings extends BaseCommand {
|
|
|
199
199
|
const newFromEmail = await input({
|
|
200
200
|
default: yamlConfig.project.fromEmail || '',
|
|
201
201
|
message: 'Sender email (from address):',
|
|
202
|
-
validate: (v) => v?.includes('@') ? true : 'Please enter a valid email',
|
|
202
|
+
validate: (v) => (v?.includes('@') ? true : 'Please enter a valid email'),
|
|
203
203
|
});
|
|
204
204
|
const newAddress = await input({
|
|
205
205
|
default: yamlConfig.project.address || '',
|
package/dist/lib/config.d.ts
CHANGED
package/dist/lib/constants.d.ts
CHANGED
package/dist/lib/constants.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Set by `bin/dev.js` when running the CLI locally (tsx bootstrap). */
|
|
2
2
|
const DEV_API_BASE_URL = 'https://app-vertex-debug.azurewebsites.net';
|
|
3
|
-
const PRODUCTION_API_BASE_URL = 'https://api.mailmodo.com';
|
|
3
|
+
// const PRODUCTION_API_BASE_URL = 'https://api.mailmodo.com';
|
|
4
|
+
const PRODUCTION_API_BASE_URL = 'https://app-vertex-debug.azurewebsites.net';
|
|
4
5
|
export const API_BASE_URL = process.env.MAILMODO_DEV_TSX
|
|
5
6
|
? DEV_API_BASE_URL
|
|
6
7
|
: PRODUCTION_API_BASE_URL;
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mailmodo/cli",
|
|
3
3
|
"description": "Email lifecycle automation for the AI-native builder generation.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.13-beta.pr14.22",
|
|
5
5
|
"author": "provishalk",
|
|
6
6
|
"bin": {
|
|
7
7
|
"mailmodo": "bin/run.js"
|
|
@@ -24,13 +24,17 @@
|
|
|
24
24
|
"@types/chai": "^4",
|
|
25
25
|
"@types/js-yaml": "^4.0.9",
|
|
26
26
|
"@types/mocha": "^10",
|
|
27
|
-
"@types/node": "^18",
|
|
27
|
+
"@types/node": "^18.19.130",
|
|
28
28
|
"chai": "^4",
|
|
29
29
|
"eslint": "^9",
|
|
30
30
|
"eslint-config-oclif": "^6",
|
|
31
31
|
"eslint-config-prettier": "^10",
|
|
32
|
+
"eslint-plugin-unused-imports": "^4.4.1",
|
|
33
|
+
"husky": "^9.1.7",
|
|
34
|
+
"lint-staged": "^16.4.0",
|
|
32
35
|
"mocha": "^11",
|
|
33
36
|
"oclif": "^4",
|
|
37
|
+
"prettier": "^3.8.2",
|
|
34
38
|
"shx": "^0.3.3",
|
|
35
39
|
"ts-node": "^10",
|
|
36
40
|
"tsx": "^4.21.0",
|
|
@@ -69,7 +73,15 @@
|
|
|
69
73
|
"posttest": "npm run lint",
|
|
70
74
|
"prepack": "oclif manifest && oclif readme",
|
|
71
75
|
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
|
72
|
-
"version": "oclif readme && git add README.md"
|
|
76
|
+
"version": "oclif readme && git add README.md",
|
|
77
|
+
"prepare": "husky"
|
|
73
78
|
},
|
|
74
|
-
"types": "dist/index.d.ts"
|
|
79
|
+
"types": "dist/index.d.ts",
|
|
80
|
+
"lint-staged": {
|
|
81
|
+
"*.{ts,tsx,js,jsx,mjs,cjs}": [
|
|
82
|
+
"prettier --write",
|
|
83
|
+
"eslint --fix"
|
|
84
|
+
],
|
|
85
|
+
"*.{json,md,yaml,yml}": "prettier --write"
|
|
86
|
+
}
|
|
75
87
|
}
|