@easybits.cloud/mailmask 0.1.4 → 0.2.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.
package/README.md CHANGED
@@ -13,7 +13,7 @@ npm i @easybits.cloud/mailmask
13
13
  ```ts
14
14
  import { MailMask } from "@easybits.cloud/mailmask";
15
15
 
16
- const mm = new MailMask({ apiKey: "mm_live_..." });
16
+ const mm = new MailMask({ apiKey: "mk_..." });
17
17
 
18
18
  // Get your domains
19
19
  const domains = await mm.domains.list();
@@ -21,13 +21,14 @@ const domainId = domains[0].id;
21
21
 
22
22
  // Create an alias — emails to hello@yourdomain.com forward to your inbox
23
23
  const alias = await mm.aliases.create(domainId, {
24
- local: "hello",
24
+ alias: "hello",
25
25
  destinations: ["you@example.com"],
26
26
  });
27
27
 
28
28
  // Send an email (routed through MailMask for high deliverability)
29
29
  await mm.send.send(domainId, {
30
- from: "hello",
30
+ from: "hello", // must be an active alias; defaults to `noreply`
31
+ fromName: "Acme", // optional display name: Acme <hello@yourdomain.com>
31
32
  to: "client@example.com",
32
33
  subject: "Welcome!",
33
34
  html: "<p>Thanks for signing up.</p>",
package/dist/index.cjs CHANGED
@@ -33,8 +33,8 @@ var MailMaskError = class extends Error {
33
33
  this.name = "MailMaskError";
34
34
  }
35
35
  };
36
- async function request(baseUrl, apiKey, path, opts) {
37
- const res = await fetch(`${baseUrl}${path}`, {
36
+ async function request(baseUrl, apiKey, path, opts, doFetch = fetch) {
37
+ const res = await doFetch(`${baseUrl}${path}`, {
38
38
  ...opts,
39
39
  headers: {
40
40
  "Authorization": `Bearer ${apiKey}`,
@@ -52,7 +52,8 @@ var MailMask = class {
52
52
  constructor(config) {
53
53
  this.apiKey = config.apiKey;
54
54
  this.baseUrl = (config.baseUrl || "https://www.mailmask.studio").replace(/\/$/, "");
55
- const req = (path, opts) => request(this.baseUrl, this.apiKey, path, opts);
55
+ const doFetch = config.fetch ? config.fetch : fetch;
56
+ const req = (path, opts) => request(this.baseUrl, this.apiKey, path, opts, doFetch);
56
57
  this.domains = new DomainsResource(req);
57
58
  this.aliases = new AliasesResource(req);
58
59
  this.rules = new RulesResource(req);
@@ -90,16 +91,16 @@ var AliasesResource = class {
90
91
  this.req = req;
91
92
  }
92
93
  list(domainId) {
93
- return this.req(`/api/domains/${domainId}/aliases`);
94
+ return this.req(`/api/domains/${domainId}/alias`);
94
95
  }
95
96
  create(domainId, input) {
96
- return this.req(`/api/domains/${domainId}/aliases`, { method: "POST", body: JSON.stringify(input) });
97
+ return this.req(`/api/domains/${domainId}/alias`, { method: "POST", body: JSON.stringify(input) });
97
98
  }
98
99
  update(domainId, alias, input) {
99
- return this.req(`/api/domains/${domainId}/aliases/${alias}`, { method: "PUT", body: JSON.stringify(input) });
100
+ return this.req(`/api/domains/${domainId}/alias/${alias}`, { method: "PUT", body: JSON.stringify(input) });
100
101
  }
101
102
  delete(domainId, alias) {
102
- return this.req(`/api/domains/${domainId}/aliases/${alias}`, { method: "DELETE" });
103
+ return this.req(`/api/domains/${domainId}/alias/${alias}`, { method: "DELETE" });
103
104
  }
104
105
  };
105
106
  var RulesResource = class {
@@ -135,10 +136,10 @@ var SendResource = class {
135
136
  return this.req(`/api/domains/${domainId}/send`, { method: "POST", body: JSON.stringify(input) });
136
137
  }
137
138
  bulkSend(domainId, input) {
138
- return this.req(`/api/domains/${domainId}/bulk-send`, { method: "POST", body: JSON.stringify(input) });
139
+ return this.req(`/api/domains/${domainId}/send-bulk`, { method: "POST", body: JSON.stringify(input) });
139
140
  }
140
141
  bulkStatus(domainId, jobId) {
141
- return this.req(`/api/domains/${domainId}/bulk-send/${jobId}`);
142
+ return this.req(`/api/domains/${domainId}/bulk/${jobId}`);
142
143
  }
143
144
  };
144
145
  var SmtpResource = class {
package/dist/index.d.cts CHANGED
@@ -1,6 +1,12 @@
1
1
  interface MailMaskConfig {
2
2
  apiKey: string;
3
3
  baseUrl?: string;
4
+ /**
5
+ * `fetch` alterno. Sirve para poner un timeout por llamada
6
+ * (`AbortSignal.timeout`), reintentos o un proxy, y para probar el SDK
7
+ * contra el servidor en proceso sin levantar un puerto.
8
+ */
9
+ fetch?: typeof fetch;
4
10
  }
5
11
  interface Domain {
6
12
  id: string;
@@ -18,8 +24,9 @@ interface Alias {
18
24
  createdAt: string;
19
25
  }
20
26
  interface CreateAliasInput {
21
- local: string;
22
- forwardTo: string | string[];
27
+ /** Parte local, sin el dominio: "hola" para hola@tudominio.com. `*` para catch-all. */
28
+ alias: string;
29
+ destinations: string[];
23
30
  }
24
31
  interface UpdateAliasInput {
25
32
  enabled?: boolean;
@@ -66,23 +73,49 @@ interface EmailLog {
66
73
  error?: string;
67
74
  }
68
75
  interface SendEmailInput {
69
- fromLocal: string;
70
76
  to: string;
71
77
  subject: string;
72
- html: string;
78
+ /** Al menos uno de `html` o `body`. Con los dos se manda multipart. */
79
+ html?: string;
80
+ body?: string;
81
+ replyTo?: string;
82
+ /**
83
+ * Parte local de un alias **activo** del dominio. Sin esto el correo sale
84
+ * desde `noreply@tudominio.com`.
85
+ */
86
+ from?: string;
87
+ /** Nombre visible del remitente: `Libretas <hola@tudominio.com>`. */
88
+ fromName?: string;
73
89
  }
74
90
  interface BulkSendInput {
75
- from: string;
76
91
  recipients: string[];
77
92
  subject: string;
78
93
  html: string;
94
+ /** Alias activo del dominio; por omisión `noreply`. */
95
+ from?: string;
96
+ }
97
+ /** Lo que devuelve `bulkSend`: el job se encola, todavía no hay estado que leer. */
98
+ interface BulkJobCreated {
99
+ ok: boolean;
100
+ jobId: string;
79
101
  }
80
102
  interface BulkJob {
81
103
  id: string;
104
+ domainId: string;
105
+ recipients: string[];
106
+ subject: string;
107
+ html: string;
108
+ from: string;
82
109
  status: string;
83
110
  totalRecipients: number;
84
111
  sent: number;
85
112
  failed: number;
113
+ /** Destinatarios saltados por bounce o queja previa: total = sent + failed + skippedSuppressed. */
114
+ skippedSuppressed: number;
115
+ lastError?: string | null;
116
+ createdAt: string;
117
+ completedAt?: string | null;
118
+ expiresAt: string;
86
119
  }
87
120
  interface SmtpCredential {
88
121
  id: string;
@@ -91,6 +124,20 @@ interface SmtpCredential {
91
124
  iamUsername: string;
92
125
  createdAt: string;
93
126
  }
127
+ /**
128
+ * Lo que devuelve `smtp.create`. La contraseña se muestra **una sola vez**: no
129
+ * se puede volver a consultar, sólo revocar la credencial y crear otra.
130
+ */
131
+ interface SmtpCredentialCreated {
132
+ id: string;
133
+ label: string;
134
+ server: string;
135
+ port: number;
136
+ encryption: string;
137
+ username: string;
138
+ password: string;
139
+ createdAt: string;
140
+ }
94
141
  interface ApiKey {
95
142
  id: string;
96
143
  name: string;
@@ -160,16 +207,14 @@ declare class SendResource {
160
207
  send(domainId: string, input: SendEmailInput): Promise<{
161
208
  messageId: string;
162
209
  }>;
163
- bulkSend(domainId: string, input: BulkSendInput): Promise<BulkJob>;
210
+ bulkSend(domainId: string, input: BulkSendInput): Promise<BulkJobCreated>;
164
211
  bulkStatus(domainId: string, jobId: string): Promise<BulkJob>;
165
212
  }
166
213
  declare class SmtpResource {
167
214
  private req;
168
215
  constructor(req: Req);
169
216
  list(domainId: string): Promise<SmtpCredential[]>;
170
- create(domainId: string, label: string): Promise<SmtpCredential & {
171
- smtpPassword: string;
172
- }>;
217
+ create(domainId: string, label: string): Promise<SmtpCredentialCreated>;
173
218
  revoke(domainId: string, credId: string): Promise<{
174
219
  ok: boolean;
175
220
  }>;
@@ -186,4 +231,4 @@ declare class ApiKeysResource {
186
231
  }>;
187
232
  }
188
233
 
189
- export { type Alias, type ApiKey, type BulkJob, type BulkSendInput, type CreateAliasInput, type CreateRuleInput, type Domain, type EmailLog, MailMask, type MailMaskConfig, MailMaskError, type Rule, type SendEmailInput, type SmtpCredential, type UpdateAliasInput, type UpdateRuleInput };
234
+ export { type Alias, type ApiKey, type BulkJob, type BulkJobCreated, type BulkSendInput, type CreateAliasInput, type CreateRuleInput, type Domain, type EmailLog, MailMask, type MailMaskConfig, MailMaskError, type Rule, type SendEmailInput, type SmtpCredential, type SmtpCredentialCreated, type UpdateAliasInput, type UpdateRuleInput };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,12 @@
1
1
  interface MailMaskConfig {
2
2
  apiKey: string;
3
3
  baseUrl?: string;
4
+ /**
5
+ * `fetch` alterno. Sirve para poner un timeout por llamada
6
+ * (`AbortSignal.timeout`), reintentos o un proxy, y para probar el SDK
7
+ * contra el servidor en proceso sin levantar un puerto.
8
+ */
9
+ fetch?: typeof fetch;
4
10
  }
5
11
  interface Domain {
6
12
  id: string;
@@ -18,8 +24,9 @@ interface Alias {
18
24
  createdAt: string;
19
25
  }
20
26
  interface CreateAliasInput {
21
- local: string;
22
- forwardTo: string | string[];
27
+ /** Parte local, sin el dominio: "hola" para hola@tudominio.com. `*` para catch-all. */
28
+ alias: string;
29
+ destinations: string[];
23
30
  }
24
31
  interface UpdateAliasInput {
25
32
  enabled?: boolean;
@@ -66,23 +73,49 @@ interface EmailLog {
66
73
  error?: string;
67
74
  }
68
75
  interface SendEmailInput {
69
- fromLocal: string;
70
76
  to: string;
71
77
  subject: string;
72
- html: string;
78
+ /** Al menos uno de `html` o `body`. Con los dos se manda multipart. */
79
+ html?: string;
80
+ body?: string;
81
+ replyTo?: string;
82
+ /**
83
+ * Parte local de un alias **activo** del dominio. Sin esto el correo sale
84
+ * desde `noreply@tudominio.com`.
85
+ */
86
+ from?: string;
87
+ /** Nombre visible del remitente: `Libretas <hola@tudominio.com>`. */
88
+ fromName?: string;
73
89
  }
74
90
  interface BulkSendInput {
75
- from: string;
76
91
  recipients: string[];
77
92
  subject: string;
78
93
  html: string;
94
+ /** Alias activo del dominio; por omisión `noreply`. */
95
+ from?: string;
96
+ }
97
+ /** Lo que devuelve `bulkSend`: el job se encola, todavía no hay estado que leer. */
98
+ interface BulkJobCreated {
99
+ ok: boolean;
100
+ jobId: string;
79
101
  }
80
102
  interface BulkJob {
81
103
  id: string;
104
+ domainId: string;
105
+ recipients: string[];
106
+ subject: string;
107
+ html: string;
108
+ from: string;
82
109
  status: string;
83
110
  totalRecipients: number;
84
111
  sent: number;
85
112
  failed: number;
113
+ /** Destinatarios saltados por bounce o queja previa: total = sent + failed + skippedSuppressed. */
114
+ skippedSuppressed: number;
115
+ lastError?: string | null;
116
+ createdAt: string;
117
+ completedAt?: string | null;
118
+ expiresAt: string;
86
119
  }
87
120
  interface SmtpCredential {
88
121
  id: string;
@@ -91,6 +124,20 @@ interface SmtpCredential {
91
124
  iamUsername: string;
92
125
  createdAt: string;
93
126
  }
127
+ /**
128
+ * Lo que devuelve `smtp.create`. La contraseña se muestra **una sola vez**: no
129
+ * se puede volver a consultar, sólo revocar la credencial y crear otra.
130
+ */
131
+ interface SmtpCredentialCreated {
132
+ id: string;
133
+ label: string;
134
+ server: string;
135
+ port: number;
136
+ encryption: string;
137
+ username: string;
138
+ password: string;
139
+ createdAt: string;
140
+ }
94
141
  interface ApiKey {
95
142
  id: string;
96
143
  name: string;
@@ -160,16 +207,14 @@ declare class SendResource {
160
207
  send(domainId: string, input: SendEmailInput): Promise<{
161
208
  messageId: string;
162
209
  }>;
163
- bulkSend(domainId: string, input: BulkSendInput): Promise<BulkJob>;
210
+ bulkSend(domainId: string, input: BulkSendInput): Promise<BulkJobCreated>;
164
211
  bulkStatus(domainId: string, jobId: string): Promise<BulkJob>;
165
212
  }
166
213
  declare class SmtpResource {
167
214
  private req;
168
215
  constructor(req: Req);
169
216
  list(domainId: string): Promise<SmtpCredential[]>;
170
- create(domainId: string, label: string): Promise<SmtpCredential & {
171
- smtpPassword: string;
172
- }>;
217
+ create(domainId: string, label: string): Promise<SmtpCredentialCreated>;
173
218
  revoke(domainId: string, credId: string): Promise<{
174
219
  ok: boolean;
175
220
  }>;
@@ -186,4 +231,4 @@ declare class ApiKeysResource {
186
231
  }>;
187
232
  }
188
233
 
189
- export { type Alias, type ApiKey, type BulkJob, type BulkSendInput, type CreateAliasInput, type CreateRuleInput, type Domain, type EmailLog, MailMask, type MailMaskConfig, MailMaskError, type Rule, type SendEmailInput, type SmtpCredential, type UpdateAliasInput, type UpdateRuleInput };
234
+ export { type Alias, type ApiKey, type BulkJob, type BulkJobCreated, type BulkSendInput, type CreateAliasInput, type CreateRuleInput, type Domain, type EmailLog, MailMask, type MailMaskConfig, MailMaskError, type Rule, type SendEmailInput, type SmtpCredential, type SmtpCredentialCreated, type UpdateAliasInput, type UpdateRuleInput };
package/dist/index.js CHANGED
@@ -6,8 +6,8 @@ var MailMaskError = class extends Error {
6
6
  this.name = "MailMaskError";
7
7
  }
8
8
  };
9
- async function request(baseUrl, apiKey, path, opts) {
10
- const res = await fetch(`${baseUrl}${path}`, {
9
+ async function request(baseUrl, apiKey, path, opts, doFetch = fetch) {
10
+ const res = await doFetch(`${baseUrl}${path}`, {
11
11
  ...opts,
12
12
  headers: {
13
13
  "Authorization": `Bearer ${apiKey}`,
@@ -25,7 +25,8 @@ var MailMask = class {
25
25
  constructor(config) {
26
26
  this.apiKey = config.apiKey;
27
27
  this.baseUrl = (config.baseUrl || "https://www.mailmask.studio").replace(/\/$/, "");
28
- const req = (path, opts) => request(this.baseUrl, this.apiKey, path, opts);
28
+ const doFetch = config.fetch ? config.fetch : fetch;
29
+ const req = (path, opts) => request(this.baseUrl, this.apiKey, path, opts, doFetch);
29
30
  this.domains = new DomainsResource(req);
30
31
  this.aliases = new AliasesResource(req);
31
32
  this.rules = new RulesResource(req);
@@ -63,16 +64,16 @@ var AliasesResource = class {
63
64
  this.req = req;
64
65
  }
65
66
  list(domainId) {
66
- return this.req(`/api/domains/${domainId}/aliases`);
67
+ return this.req(`/api/domains/${domainId}/alias`);
67
68
  }
68
69
  create(domainId, input) {
69
- return this.req(`/api/domains/${domainId}/aliases`, { method: "POST", body: JSON.stringify(input) });
70
+ return this.req(`/api/domains/${domainId}/alias`, { method: "POST", body: JSON.stringify(input) });
70
71
  }
71
72
  update(domainId, alias, input) {
72
- return this.req(`/api/domains/${domainId}/aliases/${alias}`, { method: "PUT", body: JSON.stringify(input) });
73
+ return this.req(`/api/domains/${domainId}/alias/${alias}`, { method: "PUT", body: JSON.stringify(input) });
73
74
  }
74
75
  delete(domainId, alias) {
75
- return this.req(`/api/domains/${domainId}/aliases/${alias}`, { method: "DELETE" });
76
+ return this.req(`/api/domains/${domainId}/alias/${alias}`, { method: "DELETE" });
76
77
  }
77
78
  };
78
79
  var RulesResource = class {
@@ -108,10 +109,10 @@ var SendResource = class {
108
109
  return this.req(`/api/domains/${domainId}/send`, { method: "POST", body: JSON.stringify(input) });
109
110
  }
110
111
  bulkSend(domainId, input) {
111
- return this.req(`/api/domains/${domainId}/bulk-send`, { method: "POST", body: JSON.stringify(input) });
112
+ return this.req(`/api/domains/${domainId}/send-bulk`, { method: "POST", body: JSON.stringify(input) });
112
113
  }
113
114
  bulkStatus(domainId, jobId) {
114
- return this.req(`/api/domains/${domainId}/bulk-send/${jobId}`);
115
+ return this.req(`/api/domains/${domainId}/bulk/${jobId}`);
115
116
  }
116
117
  };
117
118
  var SmtpResource = class {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easybits.cloud/mailmask",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "Official SDK for the MailMask email alias/forwarding API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",