@technomoron/mail-magic-client 1.0.23 → 1.0.25
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/CHANGES +5 -0
- package/dist/cjs/mail-magic-client.d.ts +20 -14
- package/dist/cjs/mail-magic-client.js +9 -4
- package/dist/cli.js +22 -5
- package/dist/esm/mail-magic-client.js +9 -4
- package/dist/mail-magic-client.js +9 -4
- package/dist/preprocess.js +8 -9
- package/package.json +6 -23
package/CHANGES
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
2
|
+
type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
3
|
+
[key: string]: JsonValue;
|
|
4
|
+
};
|
|
5
|
+
type RequestBody = JsonValue | object;
|
|
1
6
|
interface templateData {
|
|
2
7
|
template: string;
|
|
3
8
|
domain: string;
|
|
@@ -22,18 +27,19 @@ interface sendTemplateData {
|
|
|
22
27
|
rcpt: string;
|
|
23
28
|
domain: string;
|
|
24
29
|
locale?: string;
|
|
25
|
-
vars?:
|
|
30
|
+
vars?: Record<string, unknown>;
|
|
26
31
|
replyTo?: string;
|
|
27
32
|
headers?: Record<string, string>;
|
|
28
33
|
attachments?: AttachmentInput[];
|
|
29
34
|
}
|
|
30
35
|
interface sendFormData {
|
|
31
|
-
formid
|
|
36
|
+
formid?: string;
|
|
37
|
+
form_key?: string;
|
|
32
38
|
secret?: string;
|
|
33
39
|
recipient?: string;
|
|
34
40
|
domain?: string;
|
|
35
41
|
locale?: string;
|
|
36
|
-
vars?:
|
|
42
|
+
vars?: Record<string, unknown>;
|
|
37
43
|
replyTo?: string;
|
|
38
44
|
fields?: Record<string, unknown>;
|
|
39
45
|
attachments?: AttachmentInput[];
|
|
@@ -57,11 +63,11 @@ declare class templateClient {
|
|
|
57
63
|
private baseURL;
|
|
58
64
|
private apiKey;
|
|
59
65
|
constructor(baseURL: string, apiKey: string);
|
|
60
|
-
request<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', command: string, body?:
|
|
66
|
+
request<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', command: string, body?: RequestBody): Promise<T>;
|
|
61
67
|
get<T>(command: string): Promise<T>;
|
|
62
|
-
post<T>(command: string, body:
|
|
63
|
-
put<T>(command: string, body:
|
|
64
|
-
delete<T>(command: string, body?:
|
|
68
|
+
post<T>(command: string, body: RequestBody): Promise<T>;
|
|
69
|
+
put<T>(command: string, body: RequestBody): Promise<T>;
|
|
70
|
+
delete<T>(command: string, body?: RequestBody): Promise<T>;
|
|
65
71
|
validateEmails(list: string): {
|
|
66
72
|
valid: string[];
|
|
67
73
|
invalid: string[];
|
|
@@ -71,12 +77,12 @@ declare class templateClient {
|
|
|
71
77
|
private createAttachmentPayload;
|
|
72
78
|
private appendFields;
|
|
73
79
|
private postFormData;
|
|
74
|
-
storeTemplate(td: templateData): Promise<
|
|
75
|
-
sendTemplate(std: sendTemplateData): Promise<
|
|
76
|
-
storeTxTemplate(td: templateData): Promise<
|
|
77
|
-
sendTxMessage(std: sendTemplateData): Promise<
|
|
78
|
-
storeFormTemplate(data: formTemplateData): Promise<
|
|
79
|
-
sendFormMessage(data: sendFormData): Promise<
|
|
80
|
-
uploadAssets(data: uploadAssetsData): Promise<
|
|
80
|
+
storeTemplate(td: templateData): Promise<unknown>;
|
|
81
|
+
sendTemplate(std: sendTemplateData): Promise<unknown>;
|
|
82
|
+
storeTxTemplate(td: templateData): Promise<unknown>;
|
|
83
|
+
sendTxMessage(std: sendTemplateData): Promise<unknown>;
|
|
84
|
+
storeFormTemplate(data: formTemplateData): Promise<unknown>;
|
|
85
|
+
sendFormMessage(data: sendFormData): Promise<unknown>;
|
|
86
|
+
uploadAssets(data: uploadAssetsData): Promise<unknown>;
|
|
81
87
|
}
|
|
82
88
|
export default templateClient;
|
|
@@ -71,7 +71,7 @@ class templateClient {
|
|
|
71
71
|
validateTemplate(template) {
|
|
72
72
|
try {
|
|
73
73
|
const env = new nunjucks_1.default.Environment(new nunjucks_1.default.FileSystemLoader(['./templates']));
|
|
74
|
-
|
|
74
|
+
env.renderString(template, {});
|
|
75
75
|
}
|
|
76
76
|
catch (error) {
|
|
77
77
|
if (error instanceof Error) {
|
|
@@ -168,7 +168,7 @@ class templateClient {
|
|
|
168
168
|
if (!std.name || !std.rcpt) {
|
|
169
169
|
throw new Error('Invalid request body; name/rcpt required');
|
|
170
170
|
}
|
|
171
|
-
const {
|
|
171
|
+
const { invalid } = this.validateEmails(std.rcpt);
|
|
172
172
|
if (invalid.length > 0) {
|
|
173
173
|
throw new Error('Invalid email address(es): ' + invalid.join(','));
|
|
174
174
|
}
|
|
@@ -218,12 +218,16 @@ class templateClient {
|
|
|
218
218
|
return this.post('/api/v1/form/template', data);
|
|
219
219
|
}
|
|
220
220
|
async sendFormMessage(data) {
|
|
221
|
-
if (!data.formid) {
|
|
222
|
-
throw new Error('Invalid request body; formid required');
|
|
221
|
+
if (!data.form_key && !data.formid) {
|
|
222
|
+
throw new Error('Invalid request body; formid or form_key required');
|
|
223
|
+
}
|
|
224
|
+
if (!data.form_key && !data.domain) {
|
|
225
|
+
throw new Error('Invalid request body; domain required when sending by formid');
|
|
223
226
|
}
|
|
224
227
|
const fields = data.fields || {};
|
|
225
228
|
const baseFields = {
|
|
226
229
|
formid: data.formid,
|
|
230
|
+
form_key: data.form_key,
|
|
227
231
|
secret: data.secret,
|
|
228
232
|
recipient: data.recipient,
|
|
229
233
|
domain: data.domain,
|
|
@@ -236,6 +240,7 @@ class templateClient {
|
|
|
236
240
|
const { formData } = this.createAttachmentPayload(data.attachments);
|
|
237
241
|
this.appendFields(formData, {
|
|
238
242
|
formid: data.formid,
|
|
243
|
+
form_key: data.form_key,
|
|
239
244
|
secret: data.secret,
|
|
240
245
|
recipient: data.recipient,
|
|
241
246
|
domain: data.domain,
|
package/dist/cli.js
CHANGED
|
@@ -66,6 +66,24 @@ const getTemplateData = async () => {
|
|
|
66
66
|
return await readStdin();
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
|
+
const isPlainObject = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
70
|
+
const parseVarsOption = (input) => {
|
|
71
|
+
if (!input) {
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
let parsed;
|
|
75
|
+
try {
|
|
76
|
+
parsed = JSON.parse(input);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
80
|
+
throw new Error(`Invalid JSON for --vars: ${message}`);
|
|
81
|
+
}
|
|
82
|
+
if (!isPlainObject(parsed)) {
|
|
83
|
+
throw new Error('--vars must be a JSON object');
|
|
84
|
+
}
|
|
85
|
+
return parsed;
|
|
86
|
+
};
|
|
69
87
|
program
|
|
70
88
|
.command('template')
|
|
71
89
|
.description('Store a template on the server')
|
|
@@ -82,7 +100,7 @@ program
|
|
|
82
100
|
domain: program.opts().domain,
|
|
83
101
|
part: !!program.opts().part
|
|
84
102
|
};
|
|
85
|
-
|
|
103
|
+
await client.storeTemplate(templateData);
|
|
86
104
|
console.log('Template updated');
|
|
87
105
|
}
|
|
88
106
|
catch (error) {
|
|
@@ -101,8 +119,7 @@ program
|
|
|
101
119
|
.action(async () => {
|
|
102
120
|
const client = new mail_magic_client_1.default(program.opts().api, program.opts().token);
|
|
103
121
|
try {
|
|
104
|
-
const
|
|
105
|
-
const vars = program.opts().vars ? JSON.parse(program.opts().vars) : '{}';
|
|
122
|
+
const vars = parseVarsOption(program.opts().vars);
|
|
106
123
|
const templateData = {
|
|
107
124
|
name: program.opts().name,
|
|
108
125
|
rcpt: program.opts().rcpt,
|
|
@@ -110,7 +127,7 @@ program
|
|
|
110
127
|
locale: program.opts().locale,
|
|
111
128
|
vars
|
|
112
129
|
};
|
|
113
|
-
|
|
130
|
+
await client.sendTemplate(templateData);
|
|
114
131
|
console.log('Template sent');
|
|
115
132
|
}
|
|
116
133
|
catch (error) {
|
|
@@ -126,7 +143,7 @@ program
|
|
|
126
143
|
program
|
|
127
144
|
.command('version')
|
|
128
145
|
.description('Show current client version')
|
|
129
|
-
.action(async (
|
|
146
|
+
.action(async () => {
|
|
130
147
|
console.log('1.0.19');
|
|
131
148
|
});
|
|
132
149
|
program
|
|
@@ -66,7 +66,7 @@ class templateClient {
|
|
|
66
66
|
validateTemplate(template) {
|
|
67
67
|
try {
|
|
68
68
|
const env = new nunjucks.Environment(new nunjucks.FileSystemLoader(['./templates']));
|
|
69
|
-
|
|
69
|
+
env.renderString(template, {});
|
|
70
70
|
}
|
|
71
71
|
catch (error) {
|
|
72
72
|
if (error instanceof Error) {
|
|
@@ -163,7 +163,7 @@ class templateClient {
|
|
|
163
163
|
if (!std.name || !std.rcpt) {
|
|
164
164
|
throw new Error('Invalid request body; name/rcpt required');
|
|
165
165
|
}
|
|
166
|
-
const {
|
|
166
|
+
const { invalid } = this.validateEmails(std.rcpt);
|
|
167
167
|
if (invalid.length > 0) {
|
|
168
168
|
throw new Error('Invalid email address(es): ' + invalid.join(','));
|
|
169
169
|
}
|
|
@@ -213,12 +213,16 @@ class templateClient {
|
|
|
213
213
|
return this.post('/api/v1/form/template', data);
|
|
214
214
|
}
|
|
215
215
|
async sendFormMessage(data) {
|
|
216
|
-
if (!data.formid) {
|
|
217
|
-
throw new Error('Invalid request body; formid required');
|
|
216
|
+
if (!data.form_key && !data.formid) {
|
|
217
|
+
throw new Error('Invalid request body; formid or form_key required');
|
|
218
|
+
}
|
|
219
|
+
if (!data.form_key && !data.domain) {
|
|
220
|
+
throw new Error('Invalid request body; domain required when sending by formid');
|
|
218
221
|
}
|
|
219
222
|
const fields = data.fields || {};
|
|
220
223
|
const baseFields = {
|
|
221
224
|
formid: data.formid,
|
|
225
|
+
form_key: data.form_key,
|
|
222
226
|
secret: data.secret,
|
|
223
227
|
recipient: data.recipient,
|
|
224
228
|
domain: data.domain,
|
|
@@ -231,6 +235,7 @@ class templateClient {
|
|
|
231
235
|
const { formData } = this.createAttachmentPayload(data.attachments);
|
|
232
236
|
this.appendFields(formData, {
|
|
233
237
|
formid: data.formid,
|
|
238
|
+
form_key: data.form_key,
|
|
234
239
|
secret: data.secret,
|
|
235
240
|
recipient: data.recipient,
|
|
236
241
|
domain: data.domain,
|
|
@@ -71,7 +71,7 @@ class templateClient {
|
|
|
71
71
|
validateTemplate(template) {
|
|
72
72
|
try {
|
|
73
73
|
const env = new nunjucks_1.default.Environment(new nunjucks_1.default.FileSystemLoader(['./templates']));
|
|
74
|
-
|
|
74
|
+
env.renderString(template, {});
|
|
75
75
|
}
|
|
76
76
|
catch (error) {
|
|
77
77
|
if (error instanceof Error) {
|
|
@@ -168,7 +168,7 @@ class templateClient {
|
|
|
168
168
|
if (!std.name || !std.rcpt) {
|
|
169
169
|
throw new Error('Invalid request body; name/rcpt required');
|
|
170
170
|
}
|
|
171
|
-
const {
|
|
171
|
+
const { invalid } = this.validateEmails(std.rcpt);
|
|
172
172
|
if (invalid.length > 0) {
|
|
173
173
|
throw new Error('Invalid email address(es): ' + invalid.join(','));
|
|
174
174
|
}
|
|
@@ -218,12 +218,16 @@ class templateClient {
|
|
|
218
218
|
return this.post('/api/v1/form/template', data);
|
|
219
219
|
}
|
|
220
220
|
async sendFormMessage(data) {
|
|
221
|
-
if (!data.formid) {
|
|
222
|
-
throw new Error('Invalid request body; formid required');
|
|
221
|
+
if (!data.form_key && !data.formid) {
|
|
222
|
+
throw new Error('Invalid request body; formid or form_key required');
|
|
223
|
+
}
|
|
224
|
+
if (!data.form_key && !data.domain) {
|
|
225
|
+
throw new Error('Invalid request body; domain required when sending by formid');
|
|
223
226
|
}
|
|
224
227
|
const fields = data.fields || {};
|
|
225
228
|
const baseFields = {
|
|
226
229
|
formid: data.formid,
|
|
230
|
+
form_key: data.form_key,
|
|
227
231
|
secret: data.secret,
|
|
228
232
|
recipient: data.recipient,
|
|
229
233
|
domain: data.domain,
|
|
@@ -236,6 +240,7 @@ class templateClient {
|
|
|
236
240
|
const { formData } = this.createAttachmentPayload(data.attachments);
|
|
237
241
|
this.appendFields(formData, {
|
|
238
242
|
formid: data.formid,
|
|
243
|
+
form_key: data.form_key,
|
|
239
244
|
secret: data.secret,
|
|
240
245
|
recipient: data.recipient,
|
|
241
246
|
domain: data.domain,
|
package/dist/preprocess.js
CHANGED
|
@@ -55,7 +55,6 @@ class PreprocessExtension {
|
|
|
55
55
|
constructor() {
|
|
56
56
|
this.tags = ['process_layout'];
|
|
57
57
|
}
|
|
58
|
-
// types from nunjucks are not exported for parser/nodes; use any
|
|
59
58
|
parse(parser, nodes) {
|
|
60
59
|
const token = parser.nextToken();
|
|
61
60
|
const args = parser.parseSignature(null, true);
|
|
@@ -114,8 +113,8 @@ function process_template(tplname, writeOutput = true) {
|
|
|
114
113
|
// decodeEntities: false
|
|
115
114
|
});
|
|
116
115
|
// <container> -> <table>
|
|
117
|
-
$('container').each(
|
|
118
|
-
const $container = $(
|
|
116
|
+
$('container').each((_index, element) => {
|
|
117
|
+
const $container = $(element);
|
|
119
118
|
const $table = $('<table/>').attr({
|
|
120
119
|
align: 'center',
|
|
121
120
|
class: $container.attr('class') || '',
|
|
@@ -130,8 +129,8 @@ function process_template(tplname, writeOutput = true) {
|
|
|
130
129
|
$container.replaceWith($table);
|
|
131
130
|
});
|
|
132
131
|
// <row> -> <tr>
|
|
133
|
-
$('row').each(
|
|
134
|
-
const $row = $(
|
|
132
|
+
$('row').each((_index, element) => {
|
|
133
|
+
const $row = $(element);
|
|
135
134
|
const background = $row.attr('background') || '';
|
|
136
135
|
const $tr = $('<tr/>').attr({ class: $row.attr('class') || '' });
|
|
137
136
|
if (background)
|
|
@@ -140,8 +139,8 @@ function process_template(tplname, writeOutput = true) {
|
|
|
140
139
|
$row.replaceWith($tr);
|
|
141
140
|
});
|
|
142
141
|
// <columns> -> <td>
|
|
143
|
-
$('columns').each(
|
|
144
|
-
const $columns = $(
|
|
142
|
+
$('columns').each((_index, element) => {
|
|
143
|
+
const $columns = $(element);
|
|
145
144
|
const padding = $columns.attr('padding') || '0';
|
|
146
145
|
const $td = $('<td/>').attr({
|
|
147
146
|
class: $columns.attr('class') || '',
|
|
@@ -151,8 +150,8 @@ function process_template(tplname, writeOutput = true) {
|
|
|
151
150
|
$columns.replaceWith($td);
|
|
152
151
|
});
|
|
153
152
|
// <button> -> <a>
|
|
154
|
-
$('button').each(
|
|
155
|
-
const $button = $(
|
|
153
|
+
$('button').each((_index, element) => {
|
|
154
|
+
const $button = $(element);
|
|
156
155
|
const href = $button.attr('href') || '#';
|
|
157
156
|
const buttonClass = $button.attr('class') || '';
|
|
158
157
|
const $a = $('<a/>').attr({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@technomoron/mail-magic-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.25",
|
|
4
4
|
"description": "Client library for mail-magic",
|
|
5
5
|
"main": "dist/cjs/mail-magic-client.js",
|
|
6
6
|
"types": "dist/cjs/mail-magic-client.d.ts",
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
"build": "npm run build:cjs && npm run build:esm && npm run build:cli",
|
|
18
18
|
"test": "vitest run",
|
|
19
19
|
"test:watch": "vitest",
|
|
20
|
-
"lint": "eslint --ext .js,.ts,.vue ./src",
|
|
21
|
-
"lintfix": "eslint --fix --ext .js,.ts,.vue,.json ./src",
|
|
20
|
+
"lint": "node ../../node_modules/eslint/bin/eslint.js --config ../../eslint.config.mjs --no-error-on-unmatched-pattern --ext .js,.cjs,.mjs,.ts,.mts,.tsx,.vue,.json ./src",
|
|
21
|
+
"lintfix": "node ../../node_modules/eslint/bin/eslint.js --config ../../eslint.config.mjs --fix --no-error-on-unmatched-pattern --ext .js,.cjs,.mjs,.ts,.mts,.tsx,.vue,.json ./src",
|
|
22
22
|
"format": "npm run lintfix && npm run pretty",
|
|
23
|
-
"pretty": "prettier --write \"**/*.{js,ts,vue,json,css,scss,md}\"",
|
|
24
|
-
"cleanbuild": "rm -rf ./dist/ && npm run
|
|
23
|
+
"pretty": "node ../../node_modules/prettier/bin/prettier.cjs --config ../../.prettierrc --write \"**/*.{js,ts,vue,json,css,scss,md}\"",
|
|
24
|
+
"cleanbuild": "rm -rf ./dist/ && npm run format && npm run build"
|
|
25
25
|
},
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
@@ -40,30 +40,13 @@
|
|
|
40
40
|
"cheerio": "^1.1.2",
|
|
41
41
|
"commander": "^10.0.1",
|
|
42
42
|
"email-addresses": "^5.0.0",
|
|
43
|
-
"foundation-emails": "^2.4.0",
|
|
44
|
-
"inky": "^0.1.0",
|
|
45
43
|
"juice": "^11.0.1",
|
|
46
|
-
"node-fetch": "^3.3.2",
|
|
47
44
|
"nunjucks": "^3.2.4"
|
|
48
45
|
},
|
|
49
46
|
"devDependencies": {
|
|
50
|
-
"@types/cheerio": "^1.0.0",
|
|
51
47
|
"@types/node": "^20.19.11",
|
|
52
48
|
"@types/nunjucks": "^3.2.6",
|
|
53
|
-
"@typescript-eslint/eslint-plugin": "^8.30.1",
|
|
54
|
-
"@typescript-eslint/parser": "^8.30.1",
|
|
55
|
-
"@vue/eslint-config-prettier": "^10.2.0",
|
|
56
|
-
"@vue/eslint-config-typescript": "^14.5.0",
|
|
57
|
-
"eslint": "^9.34.0",
|
|
58
|
-
"eslint-config-prettier": "^10.1.5",
|
|
59
|
-
"eslint-import-resolver-alias": "^1.1.2",
|
|
60
|
-
"eslint-plugin-import": "^2.31.0",
|
|
61
|
-
"eslint-plugin-nuxt": "^4.0.0",
|
|
62
|
-
"eslint-plugin-prettier": "^5.4.1",
|
|
63
|
-
"eslint-plugin-vue": "^10.0.0",
|
|
64
|
-
"prettier": "^3.5.3",
|
|
65
49
|
"typescript": "^5.9.2",
|
|
66
|
-
"vitest": "^4.0.16"
|
|
67
|
-
"vue-eslint-parser": "^10.1.3"
|
|
50
|
+
"vitest": "^4.0.16"
|
|
68
51
|
}
|
|
69
52
|
}
|