@technomoron/mail-magic 1.0.40 → 1.0.42
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 +45 -2
- package/README.md +5 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/esm/api/assets.d.ts +11 -0
- package/dist/esm/api/assets.js +48 -18
- package/dist/esm/api/auth.d.ts +2 -0
- package/dist/esm/api/auth.js +18 -9
- package/dist/esm/api/forms.d.ts +9 -0
- package/dist/esm/api/forms.js +42 -7
- package/dist/esm/api/mailer.d.ts +11 -0
- package/dist/esm/api/mailer.js +37 -8
- package/dist/esm/bin/mail-magic.d.ts +2 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +5 -4
- package/dist/esm/models/db.d.ts +5 -0
- package/dist/esm/models/domain.d.ts +24 -0
- package/dist/esm/models/form.d.ts +50 -0
- package/dist/esm/models/form.js +16 -13
- package/dist/esm/models/init.d.ts +12 -0
- package/dist/esm/models/recipient.d.ts +24 -0
- package/dist/esm/models/txmail.d.ts +42 -0
- package/dist/esm/models/user.d.ts +33 -0
- package/dist/esm/server.d.ts +8 -0
- package/dist/esm/store/envloader.d.ts +188 -0
- package/dist/esm/store/envloader.js +9 -4
- package/dist/esm/store/store.d.ts +38 -0
- package/dist/esm/store/store.js +20 -16
- package/dist/esm/swagger.d.ts +10 -0
- package/dist/esm/types.d.ts +36 -0
- package/dist/esm/util/captcha.d.ts +7 -0
- package/dist/esm/util/captcha.js +4 -1
- package/dist/esm/util/email.d.ts +3 -0
- package/dist/esm/util/form-replyto.d.ts +6 -0
- package/dist/esm/util/form-submission.d.ts +24 -0
- package/dist/esm/util/forms.d.ts +140 -0
- package/dist/esm/util/forms.js +42 -39
- package/dist/esm/util/paths.d.ts +15 -0
- package/dist/esm/util/paths.js +17 -0
- package/dist/esm/util/ratelimit.d.ts +7 -0
- package/dist/esm/util/ratelimit.js +10 -41
- package/dist/esm/util/route.d.ts +1 -0
- package/dist/esm/util/shared-template-flatten.d.ts +17 -0
- package/dist/esm/util/uploads.d.ts +11 -0
- package/dist/esm/util/uploads.js +16 -11
- package/dist/esm/util/utils.d.ts +25 -0
- package/dist/esm/util/utils.js +0 -18
- package/dist/esm/util.d.ts +7 -0
- package/docs/swagger/openapi.json +16 -12
- package/examples/.env-dist +21 -0
- package/examples/README.md +74 -0
- package/examples/data/example.test/form-template/base.njk +4 -0
- package/examples/data/example.test/form-template/en/base.njk +1 -0
- package/examples/data/example.test/form-template/en/change-password.njk +5 -0
- package/examples/data/example.test/form-template/en/confirm-account.njk +5 -0
- package/examples/data/example.test/form-template/en/contact.njk +5 -0
- package/examples/data/example.test/form-template/en/partials/fields.njk +5 -0
- package/examples/data/example.test/form-template/en/welcome-signup.njk +5 -0
- package/examples/data/example.test/form-template/nb/base.njk +1 -0
- package/examples/data/example.test/form-template/nb/change-password.njk +5 -0
- package/examples/data/example.test/form-template/nb/confirm-account.njk +5 -0
- package/examples/data/example.test/form-template/nb/contact.njk +5 -0
- package/examples/data/example.test/form-template/nb/partials/fields.njk +5 -0
- package/examples/data/example.test/form-template/nb/welcome-signup.njk +5 -0
- package/examples/data/example.test/form-template/partials/header.njk +1 -0
- package/examples/data/example.test/tx-template/base.njk +16 -0
- package/examples/data/example.test/tx-template/en/base.njk +1 -0
- package/examples/data/example.test/tx-template/en/change-password.njk +7 -0
- package/examples/data/example.test/tx-template/en/confirm.njk +6 -0
- package/examples/data/example.test/tx-template/en/invoice.njk +8 -0
- package/examples/data/example.test/tx-template/en/partials/header.njk +1 -0
- package/examples/data/example.test/tx-template/en/partials/line-items.njk +14 -0
- package/examples/data/example.test/tx-template/en/receipt.njk +7 -0
- package/examples/data/example.test/tx-template/en/welcome.njk +5 -0
- package/examples/data/example.test/tx-template/nb/base.njk +1 -0
- package/examples/data/example.test/tx-template/nb/change-password.njk +6 -0
- package/examples/data/example.test/tx-template/nb/confirm.njk +6 -0
- package/examples/data/example.test/tx-template/nb/invoice.njk +7 -0
- package/examples/data/example.test/tx-template/nb/partials/header.njk +1 -0
- package/examples/data/example.test/tx-template/nb/receipt.njk +6 -0
- package/examples/data/example.test/tx-template/nb/welcome.njk +5 -0
- package/examples/data/example.test/tx-template/partials/header.njk +7 -0
- package/examples/data/init-data.json +213 -0
- package/examples/scripts/mm-api.ts +206 -0
- package/examples/scripts/public-form.ts +100 -0
- package/examples/scripts/send-messages.ts +114 -0
- package/package.json +7 -5
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Mail Magic Examples
|
|
2
|
+
|
|
3
|
+
The canonical example setup for Mail Magic. Shipped inside the `@technomoron/mail-magic` package so it is accessible
|
|
4
|
+
without a private repo clone:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
ls node_modules/@technomoron/mail-magic/examples/
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
It contains:
|
|
11
|
+
|
|
12
|
+
- `data/` — runnable server config: `init-data.json` + `example.test/` domain with transactional and form templates
|
|
13
|
+
- `scripts/` — helper TypeScript scripts for sending messages and testing the API
|
|
14
|
+
- `.env-dist` — example environment file for local development
|
|
15
|
+
|
|
16
|
+
Template families: welcome, confirm, change-password, receipt, invoice (tx) and contact, welcome-signup,
|
|
17
|
+
confirm-account, change-password (form). Locale variants: `en`, `nb`.
|
|
18
|
+
|
|
19
|
+
## Run The Example Server
|
|
20
|
+
|
|
21
|
+
From repo root:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pnpm examples
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
This runs the `mail-magic` server bin with:
|
|
28
|
+
|
|
29
|
+
- env file: `packages/server/examples/.env-dist`
|
|
30
|
+
- config dir: `packages/server/examples/data`
|
|
31
|
+
- default API host: `http://127.0.0.1:3776`
|
|
32
|
+
|
|
33
|
+
## Default Demo Credentials
|
|
34
|
+
|
|
35
|
+
Defined in `data/init-data.json`:
|
|
36
|
+
|
|
37
|
+
- domain: `example.test`
|
|
38
|
+
- token: `example-token`
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
Authorization: Bearer apikey-example-token
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Validate Templates With `mm-cli compile`
|
|
45
|
+
|
|
46
|
+
From repo root:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
node packages/cli/dist/cli.js compile \
|
|
50
|
+
--input ./packages/server/examples/data \
|
|
51
|
+
--output /tmp/mm-compiled-examples \
|
|
52
|
+
--domain example.test
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Helper Scripts
|
|
56
|
+
|
|
57
|
+
From repo root (requires `tsx`):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
tsx packages/server/examples/scripts/send-messages.ts
|
|
61
|
+
tsx packages/server/examples/scripts/public-form.ts
|
|
62
|
+
tsx packages/server/examples/scripts/mm-api.ts template \
|
|
63
|
+
--file packages/server/examples/data/example.test/tx-template/en/welcome.njk \
|
|
64
|
+
--name welcome --domain example.test
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Production Adaptation
|
|
68
|
+
|
|
69
|
+
Copy the `data/` directory and `.env-dist` to your project and adapt:
|
|
70
|
+
|
|
71
|
+
1. `.env-dist` → `.env`: set `API_TOKEN_PEPPER`, SMTP settings, `API_URL`, DB path.
|
|
72
|
+
2. `data/init-data.json`: users, domains, tokens, sender/recipient addresses.
|
|
73
|
+
3. `data/<your-domain>/tx-template/*`: brand, content, locale text, assets.
|
|
74
|
+
4. `data/<your-domain>/form-template/*`: subjects, recipient routing, exposed fields.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends '../base.njk' %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends '../base.njk' %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p><strong>{{ brand_name or 'Mail Magic Forms' }}</strong></p>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="{{ locale or 'en' }}">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
6
|
+
<title>{{ subject or 'Mail Magic' }}</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body style="font-family: Arial, Helvetica, sans-serif; color: #102030;">
|
|
9
|
+
{% include 'partials/header.njk' %}
|
|
10
|
+
<main>
|
|
11
|
+
{% block content %}{% endblock %}
|
|
12
|
+
</main>
|
|
13
|
+
<hr />
|
|
14
|
+
<p style="font-size: 12px; color: #666;">{{ company_name or 'Example Inc.' }} - {{ support_email or 'support@example.test' }}</p>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends '../base.njk' %}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{% extends 'base.njk' %}
|
|
2
|
+
{% block content %}
|
|
3
|
+
<h1>Change your password</h1>
|
|
4
|
+
<p>Use this secure link to set a new password:</p>
|
|
5
|
+
<p><a href="{{ reset_url }}">Reset password</a></p>
|
|
6
|
+
<p style="font-size: 12px; color: #666;">Link expires in {{ expires_minutes or 30 }} minutes.</p>
|
|
7
|
+
{% endblock %}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{% extends 'base.njk' %}
|
|
2
|
+
{% block content %}
|
|
3
|
+
<h1>Invoice {{ invoice_no }}</h1>
|
|
4
|
+
<p>Hello {{ name }}, here is your invoice summary.</p>
|
|
5
|
+
{% include 'partials/line-items.njk' %}
|
|
6
|
+
<p><strong>Total:</strong> {{ currency or 'USD' }} {{ total }}</p>
|
|
7
|
+
<p>Due: {{ due_date }}</p>
|
|
8
|
+
{% endblock %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% include '../../partials/header.njk' %}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<table role="presentation" width="100%" cellpadding="6" cellspacing="0" style="border-collapse: collapse; margin-top: 12px;">
|
|
2
|
+
<tr style="background: #f5f7fb;">
|
|
3
|
+
<th align="left">Item</th>
|
|
4
|
+
<th align="right">Qty</th>
|
|
5
|
+
<th align="right">Price</th>
|
|
6
|
+
</tr>
|
|
7
|
+
{% for item in items or [] %}
|
|
8
|
+
<tr>
|
|
9
|
+
<td>{{ item.name }}</td>
|
|
10
|
+
<td align="right">{{ item.qty }}</td>
|
|
11
|
+
<td align="right">{{ currency or 'USD' }} {{ item.price }}</td>
|
|
12
|
+
</tr>
|
|
13
|
+
{% endfor %}
|
|
14
|
+
</table>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% extends '../base.njk' %}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{% include '../../partials/header.njk' %}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
{
|
|
2
|
+
"user": [
|
|
3
|
+
{
|
|
4
|
+
"user_id": 1,
|
|
5
|
+
"idname": "example",
|
|
6
|
+
"token": "example-token",
|
|
7
|
+
"name": "Example User",
|
|
8
|
+
"email": "noreply@example.test",
|
|
9
|
+
"domain": 1,
|
|
10
|
+
"locale": "en"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"domain": [
|
|
14
|
+
{
|
|
15
|
+
"domain_id": 1,
|
|
16
|
+
"user_id": 1,
|
|
17
|
+
"name": "example.test",
|
|
18
|
+
"sender": "Example <noreply@example.test>",
|
|
19
|
+
"locale": "en",
|
|
20
|
+
"is_default": true
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"template": [
|
|
24
|
+
{
|
|
25
|
+
"template_id": 1,
|
|
26
|
+
"user_id": 1,
|
|
27
|
+
"domain_id": 1,
|
|
28
|
+
"name": "welcome",
|
|
29
|
+
"locale": "en",
|
|
30
|
+
"sender": "Example <noreply@example.test>",
|
|
31
|
+
"subject": "Welcome"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"template_id": 2,
|
|
35
|
+
"user_id": 1,
|
|
36
|
+
"domain_id": 1,
|
|
37
|
+
"name": "confirm",
|
|
38
|
+
"locale": "en",
|
|
39
|
+
"sender": "Example <noreply@example.test>",
|
|
40
|
+
"subject": "Confirm your account"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"template_id": 3,
|
|
44
|
+
"user_id": 1,
|
|
45
|
+
"domain_id": 1,
|
|
46
|
+
"name": "change-password",
|
|
47
|
+
"locale": "en",
|
|
48
|
+
"sender": "Example <noreply@example.test>",
|
|
49
|
+
"subject": "Change password"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"template_id": 4,
|
|
53
|
+
"user_id": 1,
|
|
54
|
+
"domain_id": 1,
|
|
55
|
+
"name": "receipt",
|
|
56
|
+
"locale": "en",
|
|
57
|
+
"sender": "Example <noreply@example.test>",
|
|
58
|
+
"subject": "Your receipt"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"template_id": 5,
|
|
62
|
+
"user_id": 1,
|
|
63
|
+
"domain_id": 1,
|
|
64
|
+
"name": "invoice",
|
|
65
|
+
"locale": "en",
|
|
66
|
+
"sender": "Example <noreply@example.test>",
|
|
67
|
+
"subject": "Your invoice"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"template_id": 6,
|
|
71
|
+
"user_id": 1,
|
|
72
|
+
"domain_id": 1,
|
|
73
|
+
"name": "welcome",
|
|
74
|
+
"locale": "nb",
|
|
75
|
+
"sender": "Example <noreply@example.test>",
|
|
76
|
+
"subject": "Velkommen"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"template_id": 7,
|
|
80
|
+
"user_id": 1,
|
|
81
|
+
"domain_id": 1,
|
|
82
|
+
"name": "confirm",
|
|
83
|
+
"locale": "nb",
|
|
84
|
+
"sender": "Example <noreply@example.test>",
|
|
85
|
+
"subject": "Bekreft konto"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"template_id": 8,
|
|
89
|
+
"user_id": 1,
|
|
90
|
+
"domain_id": 1,
|
|
91
|
+
"name": "change-password",
|
|
92
|
+
"locale": "nb",
|
|
93
|
+
"sender": "Example <noreply@example.test>",
|
|
94
|
+
"subject": "Endre passord"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"template_id": 9,
|
|
98
|
+
"user_id": 1,
|
|
99
|
+
"domain_id": 1,
|
|
100
|
+
"name": "receipt",
|
|
101
|
+
"locale": "nb",
|
|
102
|
+
"sender": "Example <noreply@example.test>",
|
|
103
|
+
"subject": "Kvittering"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"template_id": 10,
|
|
107
|
+
"user_id": 1,
|
|
108
|
+
"domain_id": 1,
|
|
109
|
+
"name": "invoice",
|
|
110
|
+
"locale": "nb",
|
|
111
|
+
"sender": "Example <noreply@example.test>",
|
|
112
|
+
"subject": "Faktura"
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"form": [
|
|
116
|
+
{
|
|
117
|
+
"form_id": 1,
|
|
118
|
+
"form_key": "example-contact-en",
|
|
119
|
+
"user_id": 1,
|
|
120
|
+
"domain_id": 1,
|
|
121
|
+
"idname": "contact",
|
|
122
|
+
"locale": "en",
|
|
123
|
+
"sender": "Example Forms <forms@example.test>",
|
|
124
|
+
"recipient": "owner@example.test",
|
|
125
|
+
"subject": "Contact form",
|
|
126
|
+
"secret": "form-secret"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"form_id": 2,
|
|
130
|
+
"form_key": "example-welcome-signup-en",
|
|
131
|
+
"user_id": 1,
|
|
132
|
+
"domain_id": 1,
|
|
133
|
+
"idname": "welcome-signup",
|
|
134
|
+
"locale": "en",
|
|
135
|
+
"sender": "Example Forms <forms@example.test>",
|
|
136
|
+
"recipient": "owner@example.test",
|
|
137
|
+
"subject": "Welcome signup",
|
|
138
|
+
"secret": "form-secret"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"form_id": 3,
|
|
142
|
+
"form_key": "example-confirm-account-en",
|
|
143
|
+
"user_id": 1,
|
|
144
|
+
"domain_id": 1,
|
|
145
|
+
"idname": "confirm-account",
|
|
146
|
+
"locale": "en",
|
|
147
|
+
"sender": "Example Forms <forms@example.test>",
|
|
148
|
+
"recipient": "owner@example.test",
|
|
149
|
+
"subject": "Confirm account form",
|
|
150
|
+
"secret": "form-secret"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"form_id": 4,
|
|
154
|
+
"form_key": "example-change-password-en",
|
|
155
|
+
"user_id": 1,
|
|
156
|
+
"domain_id": 1,
|
|
157
|
+
"idname": "change-password",
|
|
158
|
+
"locale": "en",
|
|
159
|
+
"sender": "Example Forms <forms@example.test>",
|
|
160
|
+
"recipient": "owner@example.test",
|
|
161
|
+
"subject": "Change password form",
|
|
162
|
+
"secret": "form-secret"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"form_id": 5,
|
|
166
|
+
"form_key": "example-contact-nb",
|
|
167
|
+
"user_id": 1,
|
|
168
|
+
"domain_id": 1,
|
|
169
|
+
"idname": "contact",
|
|
170
|
+
"locale": "nb",
|
|
171
|
+
"sender": "Example Forms <forms@example.test>",
|
|
172
|
+
"recipient": "owner@example.test",
|
|
173
|
+
"subject": "Kontakt",
|
|
174
|
+
"secret": "form-secret"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"form_id": 6,
|
|
178
|
+
"form_key": "example-welcome-signup-nb",
|
|
179
|
+
"user_id": 1,
|
|
180
|
+
"domain_id": 1,
|
|
181
|
+
"idname": "welcome-signup",
|
|
182
|
+
"locale": "nb",
|
|
183
|
+
"sender": "Example Forms <forms@example.test>",
|
|
184
|
+
"recipient": "owner@example.test",
|
|
185
|
+
"subject": "Registrering",
|
|
186
|
+
"secret": "form-secret"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"form_id": 7,
|
|
190
|
+
"form_key": "example-confirm-account-nb",
|
|
191
|
+
"user_id": 1,
|
|
192
|
+
"domain_id": 1,
|
|
193
|
+
"idname": "confirm-account",
|
|
194
|
+
"locale": "nb",
|
|
195
|
+
"sender": "Example Forms <forms@example.test>",
|
|
196
|
+
"recipient": "owner@example.test",
|
|
197
|
+
"subject": "Bekreft konto form",
|
|
198
|
+
"secret": "form-secret"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"form_id": 8,
|
|
202
|
+
"form_key": "example-change-password-nb",
|
|
203
|
+
"user_id": 1,
|
|
204
|
+
"domain_id": 1,
|
|
205
|
+
"idname": "change-password",
|
|
206
|
+
"locale": "nb",
|
|
207
|
+
"sender": "Example Forms <forms@example.test>",
|
|
208
|
+
"recipient": "owner@example.test",
|
|
209
|
+
"subject": "Endre passord form",
|
|
210
|
+
"secret": "form-secret"
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
}
|