@easybits.cloud/mailmask 0.8.0 → 0.9.1

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
@@ -156,6 +156,15 @@ const job = await mm.batch("formmy-user-42", {
156
156
  const st = await mm.batchStatus("formmy-user-42", job.batchId);
157
157
  // st.sent / failed / skippedSuppressed, then (for up to 7 days) delivered / bounced / complained / unsubscribed
158
158
 
159
+ // Opens and clicks (opt-in per send/batch): `track: true` adds SES's open pixel and rewrites the html
160
+ // links. Without it nothing is added. Unique counts + rates + top links come back in batchStatus, and
161
+ // `email.opened` / `email.clicked` fire once per message (the first time). Opens are inflated by Apple
162
+ // Mail Privacy Protection: decide by clicks.
163
+ const tracked = await mm.batch("formmy-user-42", { from: "hola@laespiga.mx", subject: "Oct", html: "<a href=\"https://laespiga.mx/menu?utm_source=mail\">Menú</a>", recipients: ["ana@example.com"], track: true });
164
+ const ts = await mm.batchStatus("formmy-user-42", tracked.batchId);
165
+ // ts.opened / clicked (unique), ts.openRate / clickRate (0–1 over delivered, or sent while delivered is 0),
166
+ // ts.topLinks: [{ url: "https://laespiga.mx/menu", clicks, uniqueClicks }] (utm_*, fbclid, gclid stripped)
167
+
159
168
  // Test mode: validates everything (signature, domain, suppression, quota) without sending or billing
160
169
  await mm.send("formmy-user-42", { from: "hola@laespiga.mx", to: "x@example.com", subject: "s", text: "t" }, { test: true });
161
170
 
@@ -208,6 +217,9 @@ export async function action({ request }: { request: Request }) {
208
217
  case "tenant.paused":
209
218
  // notify the customer
210
219
  break;
220
+ case "email.clicked":
221
+ // event.data.url, event.data.recipient, event.data.batchId, event.data.tags (first click only)
222
+ break;
211
223
  }
212
224
  return new Response("ok");
213
225
  }
package/dist/index.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ AUTO_TOPUP_SUGGESTIONS: () => AUTO_TOPUP_SUGGESTIONS,
23
24
  AuthError: () => AuthError,
24
25
  BALANCE_LOW_FRACTION: () => BALANCE_LOW_FRACTION,
25
26
  BALANCE_MOVEMENT_KINDS: () => BALANCE_MOVEMENT_KINDS,
@@ -44,8 +45,10 @@ __export(index_exports, {
44
45
  NotFoundError: () => NotFoundError,
45
46
  PARTNER_ADMIN_ROUTES: () => PARTNER_ADMIN_ROUTES,
46
47
  PARTNER_API_PREFIX: () => PARTNER_API_PREFIX,
48
+ PARTNER_CURRENCIES: () => PARTNER_CURRENCIES,
47
49
  PARTNER_ERROR_STATUS: () => PARTNER_ERROR_STATUS,
48
50
  PARTNER_HEADERS: () => PARTNER_HEADERS,
51
+ PARTNER_PRICES: () => PARTNER_PRICES,
49
52
  PARTNER_PRICE_PER_EMAIL_CENTS: () => PARTNER_PRICE_PER_EMAIL_CENTS,
50
53
  PARTNER_ROUTES: () => PARTNER_ROUTES,
51
54
  PARTNER_SIGNATURE_TOLERANCE_S: () => PARTNER_SIGNATURE_TOLERANCE_S,
@@ -74,6 +77,7 @@ __export(index_exports, {
74
77
  WEBHOOK_TOLERANCE_MS: () => WEBHOOK_TOLERANCE_MS,
75
78
  createWebhookHandler: () => createWebhookHandler,
76
79
  estimateSendDays: () => estimateSendDays,
80
+ formatMoney: () => formatMoney,
77
81
  isValidExternalId: () => isValidExternalId,
78
82
  isValidFallbackLabel: () => isValidFallbackLabel,
79
83
  partnerSignatureBase: () => partnerSignatureBase,
@@ -755,7 +759,7 @@ var MAX_BATCH_RECIPIENTS = 1e4;
755
759
  var MAX_TAGS = 10;
756
760
  var TAG_RE = /^[A-Za-z0-9_-]{1,64}$/;
757
761
  var TENANT_DAILY_LIMIT_START = 2e3;
758
- var TENANT_DAILY_LIMIT_MAX = 5e4;
762
+ var TENANT_DAILY_LIMIT_MAX = 2e4;
759
763
  var TENANT_WARMUP_STEP_DAYS = 7;
760
764
  function warmupLimit(step) {
761
765
  return Math.min(TENANT_DAILY_LIMIT_MAX, TENANT_DAILY_LIMIT_START * 2 ** Math.max(0, step));
@@ -843,18 +847,32 @@ function personalizePartnerMessage(input) {
843
847
  ...text !== void 0 ? { text: renderTemplate(text, vars) } : {}
844
848
  };
845
849
  }
846
- var PARTNER_PRICE_PER_EMAIL_CENTS = 6;
847
- var PARTNER_TENANT_MONTH_CENTS = 4900;
848
- var PARTNER_WELCOME_CENTS = 5e4;
849
- var PARTNER_TOPUP_MIN_CENTS = 5e4;
850
- var PARTNER_TOPUP_MAX_CENTS = 1e7;
850
+ var PARTNER_CURRENCIES = ["MXN", "USD"];
851
+ var PARTNER_PRICES = {
852
+ MXN: { perEmailCents: 6, tenantMonthCents: 4900, welcomeCents: 5e4, topupMinCents: 5e4, topupMaxCents: 1e7 },
853
+ USD: { perEmailCents: 0.35, tenantMonthCents: 290, welcomeCents: 2900, topupMinCents: 2900, topupMaxCents: 55e4 }
854
+ };
855
+ var PARTNER_PRICE_PER_EMAIL_CENTS = PARTNER_PRICES.MXN.perEmailCents;
856
+ var PARTNER_TENANT_MONTH_CENTS = PARTNER_PRICES.MXN.tenantMonthCents;
857
+ var PARTNER_WELCOME_CENTS = PARTNER_PRICES.MXN.welcomeCents;
858
+ var PARTNER_TOPUP_MIN_CENTS = PARTNER_PRICES.MXN.topupMinCents;
859
+ var PARTNER_TOPUP_MAX_CENTS = PARTNER_PRICES.MXN.topupMaxCents;
860
+ function formatMoney(cents, currency) {
861
+ const v = Math.abs(cents) / 100;
862
+ const decimals = v !== 0 && v < 0.01 ? 4 : 2;
863
+ const n = v.toLocaleString("en-US", { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
864
+ return `${cents < 0 ? "\u2212" : ""}$${n} ${currency}`;
865
+ }
851
866
  var BALANCE_LOW_FRACTION = 0.2;
852
867
  var BALANCE_MOVEMENT_KINDS = ["topup", "send", "tenant_fee", "refund", "adjust"];
868
+ var AUTO_TOPUP_SUGGESTIONS = { MXN: [500, 1e3, 2500], USD: [29, 59, 149] };
853
869
  var PARTNER_WEBHOOK_EVENTS = [
854
870
  "email.sent",
855
871
  "email.delivered",
856
872
  "email.bounced",
857
873
  "email.complained",
874
+ "email.opened",
875
+ "email.clicked",
858
876
  "email.received",
859
877
  "contact.unsubscribed",
860
878
  "tenant.paused",
@@ -896,6 +914,8 @@ var PARTNER_ROUTES = {
896
914
  balance: { method: "GET", path: "/balance" },
897
915
  balanceMovements: { method: "GET", path: "/balance/movements" },
898
916
  topup: { method: "POST", path: "/topup" },
917
+ getAutoTopup: { method: "GET", path: "/auto-topup" },
918
+ setAutoTopup: { method: "PUT", path: "/auto-topup" },
899
919
  getWebhook: { method: "GET", path: "/webhook" },
900
920
  setWebhook: { method: "PUT", path: "/webhook" },
901
921
  testWebhook: { method: "POST", path: "/webhook/test" },
@@ -917,6 +937,10 @@ var PARTNER_ADMIN_ROUTES = {
917
937
  adjustBalance: { method: "POST", path: "/api/partners/:partnerId/balance/adjust" },
918
938
  /** Recarga con MercadoPago desde la sesión del dueño (misma respuesta que `POST /topup`). */
919
939
  topup: { method: "POST", path: "/api/partners/:partnerId/topup" },
940
+ getAutoTopup: { method: "GET", path: "/api/partners/:partnerId/auto-topup" },
941
+ setAutoTopup: { method: "PUT", path: "/api/partners/:partnerId/auto-topup" },
942
+ /** Sólo MailMask: moneda del saldo, mientras no haya más movimientos que la bienvenida. */
943
+ setCurrency: { method: "PUT", path: "/api/partners/:partnerId/currency" },
920
944
  /** Sólo MailMask: fija (o quita, con `null`) el límite diario de un tenant. Devuelve el `Tenant`. */
921
945
  setTenantDailyLimit: { method: "PUT", path: "/api/partners/:partnerId/tenants/:externalId/daily-limit" },
922
946
  listCredentials: { method: "GET", path: "/api/partners/:partnerId/credentials" },
@@ -1058,6 +1082,10 @@ var InsufficientBalanceError = class extends PartnerApiError {
1058
1082
  get requiredCents() {
1059
1083
  return this.body.requiredCents;
1060
1084
  }
1085
+ /** Moneda de los dos montos de arriba. */
1086
+ get currency() {
1087
+ return this.body.currency;
1088
+ }
1061
1089
  };
1062
1090
  var NetworkError = class extends PartnerApiError {
1063
1091
  constructor(message, cause) {
@@ -1280,7 +1308,10 @@ var MailMaskPartner = class {
1280
1308
  );
1281
1309
  return { ...data, idempotencyKey, replayed: meta.idempotentReplayed };
1282
1310
  }
1283
- /** Estado de un lote (`batchId` del resultado de `batch`): envíos y, después, entregas, rebotes, quejas y bajas. */
1311
+ /**
1312
+ * Estado de un lote (`batchId` del resultado de `batch`): envíos y, después, entregas, rebotes, quejas
1313
+ * y bajas; con `track: true`, también aperturas, clics, tasas y `topLinks`.
1314
+ */
1284
1315
  async batchStatus(externalId, batchId) {
1285
1316
  return (await this.request("GET", routePath(PARTNER_ROUTES.getBatch.path, { externalId, batchId }))).data;
1286
1317
  }
@@ -1298,12 +1329,24 @@ var MailMaskPartner = class {
1298
1329
  return (await this.request("GET", `${PARTNER_ROUTES.balanceMovements.path}${qs ? `?${qs}` : ""}`)).data;
1299
1330
  }
1300
1331
  /**
1301
- * Liga de MercadoPago para recargar saldo (pago único, $500 a $100,000 MXN). El saldo sube cuando
1302
- * MercadoPago confirma el pago, no al crear la liga. Abre `initPoint` en el navegador de quien paga.
1332
+ * Liga de MercadoPago para recargar saldo (pago único; `amount` en unidades enteras de tu moneda:
1333
+ * MXN 500 a 100,000, USD 29 a 5,500). El saldo sube cuando MercadoPago confirma el pago, no al
1334
+ * crear la liga. Abre `initPoint` en el navegador de quien paga.
1303
1335
  */
1304
1336
  async topup(input) {
1305
1337
  return (await this.request("POST", PARTNER_ROUTES.topup.path, input)).data;
1306
1338
  }
1339
+ /** La recarga automática mensual: `off`, `pending` (falta autorizarla) o `active`. */
1340
+ async autoTopup() {
1341
+ return (await this.request("GET", PARTNER_ROUTES.getAutoTopup.path)).data;
1342
+ }
1343
+ /**
1344
+ * Prende o cambia (`amount` entero de tu moneda) la recarga automática mensual, o la apaga
1345
+ * (`amount: null`). Al prenderla o cambiarla devuelve `initPoint`: ábrelo para autorizar el cobro.
1346
+ */
1347
+ async setAutoTopup(input) {
1348
+ return (await this.request("PUT", PARTNER_ROUTES.setAutoTopup.path, input)).data;
1349
+ }
1307
1350
  /** Uso del mes (`YYYY-MM`, default el mes en curso UTC): tenants activos y envíos. */
1308
1351
  async usage(opts = {}) {
1309
1352
  const q = opts.month ? `?month=${encodeURIComponent(opts.month)}` : "";
@@ -1504,6 +1547,10 @@ var MailMaskPartnerAdmin = class {
1504
1547
  setReputationPolicy(partnerId, policy) {
1505
1548
  return this.req("setReputationPolicy", { partnerId }, { policy });
1506
1549
  }
1550
+ /** Sólo MailMask (admin): moneda del saldo (MXN o USD); sólo antes de cualquier movimiento aparte de la bienvenida. */
1551
+ setCurrency(partnerId, currency) {
1552
+ return this.req("setCurrency", { partnerId }, { currency });
1553
+ }
1507
1554
  /** Sólo MailMask (admin): levanta cualquier pausa, también la de reputación. */
1508
1555
  resumeTenant(partnerId, externalId) {
1509
1556
  return this.req("resumeTenant", { partnerId, externalId });
@@ -1535,6 +1582,14 @@ var MailMaskPartnerAdmin = class {
1535
1582
  topup(partnerId, input) {
1536
1583
  return this.req("topup", { partnerId }, input);
1537
1584
  }
1585
+ /** La recarga automática mensual del partner (dueño o MailMask). */
1586
+ getAutoTopup(partnerId) {
1587
+ return this.req("getAutoTopup", { partnerId });
1588
+ }
1589
+ /** Prende, cambia (`amount`) o apaga (`null`) la recarga automática; trae `initPoint` al prenderla. */
1590
+ setAutoTopup(partnerId, input) {
1591
+ return this.req("setAutoTopup", { partnerId }, input);
1592
+ }
1538
1593
  listCredentials(partnerId) {
1539
1594
  return this.req("listCredentials", { partnerId });
1540
1595
  }
@@ -1553,6 +1608,7 @@ var MailMaskPartnerAdmin = class {
1553
1608
  };
1554
1609
  // Annotate the CommonJS export names for ESM import in node:
1555
1610
  0 && (module.exports = {
1611
+ AUTO_TOPUP_SUGGESTIONS,
1556
1612
  AuthError,
1557
1613
  BALANCE_LOW_FRACTION,
1558
1614
  BALANCE_MOVEMENT_KINDS,
@@ -1577,8 +1633,10 @@ var MailMaskPartnerAdmin = class {
1577
1633
  NotFoundError,
1578
1634
  PARTNER_ADMIN_ROUTES,
1579
1635
  PARTNER_API_PREFIX,
1636
+ PARTNER_CURRENCIES,
1580
1637
  PARTNER_ERROR_STATUS,
1581
1638
  PARTNER_HEADERS,
1639
+ PARTNER_PRICES,
1582
1640
  PARTNER_PRICE_PER_EMAIL_CENTS,
1583
1641
  PARTNER_ROUTES,
1584
1642
  PARTNER_SIGNATURE_TOLERANCE_S,
@@ -1607,6 +1665,7 @@ var MailMaskPartnerAdmin = class {
1607
1665
  WEBHOOK_TOLERANCE_MS,
1608
1666
  createWebhookHandler,
1609
1667
  estimateSendDays,
1668
+ formatMoney,
1610
1669
  isValidExternalId,
1611
1670
  isValidFallbackLabel,
1612
1671
  partnerSignatureBase,
package/dist/index.js CHANGED
@@ -662,7 +662,7 @@ var MAX_BATCH_RECIPIENTS = 1e4;
662
662
  var MAX_TAGS = 10;
663
663
  var TAG_RE = /^[A-Za-z0-9_-]{1,64}$/;
664
664
  var TENANT_DAILY_LIMIT_START = 2e3;
665
- var TENANT_DAILY_LIMIT_MAX = 5e4;
665
+ var TENANT_DAILY_LIMIT_MAX = 2e4;
666
666
  var TENANT_WARMUP_STEP_DAYS = 7;
667
667
  function warmupLimit(step) {
668
668
  return Math.min(TENANT_DAILY_LIMIT_MAX, TENANT_DAILY_LIMIT_START * 2 ** Math.max(0, step));
@@ -750,18 +750,32 @@ function personalizePartnerMessage(input) {
750
750
  ...text !== void 0 ? { text: renderTemplate(text, vars) } : {}
751
751
  };
752
752
  }
753
- var PARTNER_PRICE_PER_EMAIL_CENTS = 6;
754
- var PARTNER_TENANT_MONTH_CENTS = 4900;
755
- var PARTNER_WELCOME_CENTS = 5e4;
756
- var PARTNER_TOPUP_MIN_CENTS = 5e4;
757
- var PARTNER_TOPUP_MAX_CENTS = 1e7;
753
+ var PARTNER_CURRENCIES = ["MXN", "USD"];
754
+ var PARTNER_PRICES = {
755
+ MXN: { perEmailCents: 6, tenantMonthCents: 4900, welcomeCents: 5e4, topupMinCents: 5e4, topupMaxCents: 1e7 },
756
+ USD: { perEmailCents: 0.35, tenantMonthCents: 290, welcomeCents: 2900, topupMinCents: 2900, topupMaxCents: 55e4 }
757
+ };
758
+ var PARTNER_PRICE_PER_EMAIL_CENTS = PARTNER_PRICES.MXN.perEmailCents;
759
+ var PARTNER_TENANT_MONTH_CENTS = PARTNER_PRICES.MXN.tenantMonthCents;
760
+ var PARTNER_WELCOME_CENTS = PARTNER_PRICES.MXN.welcomeCents;
761
+ var PARTNER_TOPUP_MIN_CENTS = PARTNER_PRICES.MXN.topupMinCents;
762
+ var PARTNER_TOPUP_MAX_CENTS = PARTNER_PRICES.MXN.topupMaxCents;
763
+ function formatMoney(cents, currency) {
764
+ const v = Math.abs(cents) / 100;
765
+ const decimals = v !== 0 && v < 0.01 ? 4 : 2;
766
+ const n = v.toLocaleString("en-US", { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
767
+ return `${cents < 0 ? "\u2212" : ""}$${n} ${currency}`;
768
+ }
758
769
  var BALANCE_LOW_FRACTION = 0.2;
759
770
  var BALANCE_MOVEMENT_KINDS = ["topup", "send", "tenant_fee", "refund", "adjust"];
771
+ var AUTO_TOPUP_SUGGESTIONS = { MXN: [500, 1e3, 2500], USD: [29, 59, 149] };
760
772
  var PARTNER_WEBHOOK_EVENTS = [
761
773
  "email.sent",
762
774
  "email.delivered",
763
775
  "email.bounced",
764
776
  "email.complained",
777
+ "email.opened",
778
+ "email.clicked",
765
779
  "email.received",
766
780
  "contact.unsubscribed",
767
781
  "tenant.paused",
@@ -803,6 +817,8 @@ var PARTNER_ROUTES = {
803
817
  balance: { method: "GET", path: "/balance" },
804
818
  balanceMovements: { method: "GET", path: "/balance/movements" },
805
819
  topup: { method: "POST", path: "/topup" },
820
+ getAutoTopup: { method: "GET", path: "/auto-topup" },
821
+ setAutoTopup: { method: "PUT", path: "/auto-topup" },
806
822
  getWebhook: { method: "GET", path: "/webhook" },
807
823
  setWebhook: { method: "PUT", path: "/webhook" },
808
824
  testWebhook: { method: "POST", path: "/webhook/test" },
@@ -824,6 +840,10 @@ var PARTNER_ADMIN_ROUTES = {
824
840
  adjustBalance: { method: "POST", path: "/api/partners/:partnerId/balance/adjust" },
825
841
  /** Recarga con MercadoPago desde la sesión del dueño (misma respuesta que `POST /topup`). */
826
842
  topup: { method: "POST", path: "/api/partners/:partnerId/topup" },
843
+ getAutoTopup: { method: "GET", path: "/api/partners/:partnerId/auto-topup" },
844
+ setAutoTopup: { method: "PUT", path: "/api/partners/:partnerId/auto-topup" },
845
+ /** Sólo MailMask: moneda del saldo, mientras no haya más movimientos que la bienvenida. */
846
+ setCurrency: { method: "PUT", path: "/api/partners/:partnerId/currency" },
827
847
  /** Sólo MailMask: fija (o quita, con `null`) el límite diario de un tenant. Devuelve el `Tenant`. */
828
848
  setTenantDailyLimit: { method: "PUT", path: "/api/partners/:partnerId/tenants/:externalId/daily-limit" },
829
849
  listCredentials: { method: "GET", path: "/api/partners/:partnerId/credentials" },
@@ -965,6 +985,10 @@ var InsufficientBalanceError = class extends PartnerApiError {
965
985
  get requiredCents() {
966
986
  return this.body.requiredCents;
967
987
  }
988
+ /** Moneda de los dos montos de arriba. */
989
+ get currency() {
990
+ return this.body.currency;
991
+ }
968
992
  };
969
993
  var NetworkError = class extends PartnerApiError {
970
994
  constructor(message, cause) {
@@ -1187,7 +1211,10 @@ var MailMaskPartner = class {
1187
1211
  );
1188
1212
  return { ...data, idempotencyKey, replayed: meta.idempotentReplayed };
1189
1213
  }
1190
- /** Estado de un lote (`batchId` del resultado de `batch`): envíos y, después, entregas, rebotes, quejas y bajas. */
1214
+ /**
1215
+ * Estado de un lote (`batchId` del resultado de `batch`): envíos y, después, entregas, rebotes, quejas
1216
+ * y bajas; con `track: true`, también aperturas, clics, tasas y `topLinks`.
1217
+ */
1191
1218
  async batchStatus(externalId, batchId) {
1192
1219
  return (await this.request("GET", routePath(PARTNER_ROUTES.getBatch.path, { externalId, batchId }))).data;
1193
1220
  }
@@ -1205,12 +1232,24 @@ var MailMaskPartner = class {
1205
1232
  return (await this.request("GET", `${PARTNER_ROUTES.balanceMovements.path}${qs ? `?${qs}` : ""}`)).data;
1206
1233
  }
1207
1234
  /**
1208
- * Liga de MercadoPago para recargar saldo (pago único, $500 a $100,000 MXN). El saldo sube cuando
1209
- * MercadoPago confirma el pago, no al crear la liga. Abre `initPoint` en el navegador de quien paga.
1235
+ * Liga de MercadoPago para recargar saldo (pago único; `amount` en unidades enteras de tu moneda:
1236
+ * MXN 500 a 100,000, USD 29 a 5,500). El saldo sube cuando MercadoPago confirma el pago, no al
1237
+ * crear la liga. Abre `initPoint` en el navegador de quien paga.
1210
1238
  */
1211
1239
  async topup(input) {
1212
1240
  return (await this.request("POST", PARTNER_ROUTES.topup.path, input)).data;
1213
1241
  }
1242
+ /** La recarga automática mensual: `off`, `pending` (falta autorizarla) o `active`. */
1243
+ async autoTopup() {
1244
+ return (await this.request("GET", PARTNER_ROUTES.getAutoTopup.path)).data;
1245
+ }
1246
+ /**
1247
+ * Prende o cambia (`amount` entero de tu moneda) la recarga automática mensual, o la apaga
1248
+ * (`amount: null`). Al prenderla o cambiarla devuelve `initPoint`: ábrelo para autorizar el cobro.
1249
+ */
1250
+ async setAutoTopup(input) {
1251
+ return (await this.request("PUT", PARTNER_ROUTES.setAutoTopup.path, input)).data;
1252
+ }
1214
1253
  /** Uso del mes (`YYYY-MM`, default el mes en curso UTC): tenants activos y envíos. */
1215
1254
  async usage(opts = {}) {
1216
1255
  const q = opts.month ? `?month=${encodeURIComponent(opts.month)}` : "";
@@ -1411,6 +1450,10 @@ var MailMaskPartnerAdmin = class {
1411
1450
  setReputationPolicy(partnerId, policy) {
1412
1451
  return this.req("setReputationPolicy", { partnerId }, { policy });
1413
1452
  }
1453
+ /** Sólo MailMask (admin): moneda del saldo (MXN o USD); sólo antes de cualquier movimiento aparte de la bienvenida. */
1454
+ setCurrency(partnerId, currency) {
1455
+ return this.req("setCurrency", { partnerId }, { currency });
1456
+ }
1414
1457
  /** Sólo MailMask (admin): levanta cualquier pausa, también la de reputación. */
1415
1458
  resumeTenant(partnerId, externalId) {
1416
1459
  return this.req("resumeTenant", { partnerId, externalId });
@@ -1442,6 +1485,14 @@ var MailMaskPartnerAdmin = class {
1442
1485
  topup(partnerId, input) {
1443
1486
  return this.req("topup", { partnerId }, input);
1444
1487
  }
1488
+ /** La recarga automática mensual del partner (dueño o MailMask). */
1489
+ getAutoTopup(partnerId) {
1490
+ return this.req("getAutoTopup", { partnerId });
1491
+ }
1492
+ /** Prende, cambia (`amount`) o apaga (`null`) la recarga automática; trae `initPoint` al prenderla. */
1493
+ setAutoTopup(partnerId, input) {
1494
+ return this.req("setAutoTopup", { partnerId }, input);
1495
+ }
1445
1496
  listCredentials(partnerId) {
1446
1497
  return this.req("listCredentials", { partnerId });
1447
1498
  }
@@ -1459,6 +1510,7 @@ var MailMaskPartnerAdmin = class {
1459
1510
  }
1460
1511
  };
1461
1512
  export {
1513
+ AUTO_TOPUP_SUGGESTIONS,
1462
1514
  AuthError,
1463
1515
  BALANCE_LOW_FRACTION,
1464
1516
  BALANCE_MOVEMENT_KINDS,
@@ -1483,8 +1535,10 @@ export {
1483
1535
  NotFoundError,
1484
1536
  PARTNER_ADMIN_ROUTES,
1485
1537
  PARTNER_API_PREFIX,
1538
+ PARTNER_CURRENCIES,
1486
1539
  PARTNER_ERROR_STATUS,
1487
1540
  PARTNER_HEADERS,
1541
+ PARTNER_PRICES,
1488
1542
  PARTNER_PRICE_PER_EMAIL_CENTS,
1489
1543
  PARTNER_ROUTES,
1490
1544
  PARTNER_SIGNATURE_TOLERANCE_S,
@@ -1513,6 +1567,7 @@ export {
1513
1567
  WEBHOOK_TOLERANCE_MS,
1514
1568
  createWebhookHandler,
1515
1569
  estimateSendDays,
1570
+ formatMoney,
1516
1571
  isValidExternalId,
1517
1572
  isValidFallbackLabel,
1518
1573
  partnerSignatureBase,
@@ -86,9 +86,11 @@ export interface PartnerErrorBody {
86
86
  limit?: number;
87
87
  sentToday?: number;
88
88
  resetsAt?: string;
89
- /** Sólo en `insufficient_balance`: saldo actual y lo que pedía el envío (centavos MXN). */
89
+ /** Sólo en `insufficient_balance`: saldo actual y lo que pedía el envío (centavos de `currency`). */
90
90
  balanceCents?: number;
91
91
  requiredCents?: number;
92
+ /** Moneda de `balanceCents` y `requiredCents`. */
93
+ currency?: PartnerCurrency;
92
94
  /** Sólo en `recipient_suppressed`. */
93
95
  reason?: SuppressionReason;
94
96
  stream?: MessageStream;
@@ -128,7 +130,7 @@ export interface Tenant {
128
130
  * regresa al inicio al reanudar. No hay tope mensual: el saldo es el otro freno.
129
131
  */
130
132
  export declare const TENANT_DAILY_LIMIT_START = 2000;
131
- export declare const TENANT_DAILY_LIMIT_MAX = 50000;
133
+ export declare const TENANT_DAILY_LIMIT_MAX = 20000;
132
134
  export declare const TENANT_WARMUP_STEP_DAYS = 7;
133
135
  /** El límite del escalón `step` (0 = inicio). */
134
136
  export declare function warmupLimit(step: number): number;
@@ -334,6 +336,8 @@ export interface SendRequest {
334
336
  vars?: TemplateVars;
335
337
  /** Reintentar con la misma llave en 24 h devuelve la respuesta guardada sin volver a enviar. */
336
338
  idempotencyKey?: string;
339
+ /** Mide aperturas y clics (ver `track` en `BatchRequest`). Default `false`. */
340
+ track?: boolean;
337
341
  }
338
342
  /** `POST /tenants/:externalId/send` — 200. Con `Idempotent-Replayed: true` si fue repetición. */
339
343
  export interface SendResponse {
@@ -366,6 +370,21 @@ export interface BatchRequest {
366
370
  /** Default `broadcast` (lleva baja de un clic por destinatario). */
367
371
  stream?: MessageStream;
368
372
  idempotencyKey?: string;
373
+ /**
374
+ * Mide aperturas y clics: SES agrega un pixel invisible y reescribe cada liga del `html` para
375
+ * pasar por su redirector (el `text` no cambia). Llegan `email.opened`/`email.clicked` (la primera
376
+ * vez por correo) y suben `opened`, `clicked` y `topLinks` del `BatchStatus`. Default `false`: sin
377
+ * él el correo sale sin pixel y con las ligas intactas.
378
+ */
379
+ track?: boolean;
380
+ }
381
+ /** Una liga del lote con sus clics. `url` va sin `utm_*`, `fbclid` ni `gclid` (agrupa variantes). */
382
+ export interface BatchTopLink {
383
+ url: string;
384
+ /** Clics totales (una persona que hace clic dos veces cuenta dos). */
385
+ clicks: number;
386
+ /** Correos distintos que hicieron clic en esta liga. */
387
+ uniqueClicks: number;
369
388
  }
370
389
  export type BatchState = "queued" | "processing" | "completed" | "failed";
371
390
  export interface BatchStatus {
@@ -385,6 +404,21 @@ export interface BatchStatus {
385
404
  bounced: number;
386
405
  complained: number;
387
406
  unsubscribed: number;
407
+ /** El lote se mandó con `track: true`. Sin él, los números de seguimiento se quedan en 0. */
408
+ track: boolean;
409
+ /**
410
+ * Correos del lote abiertos al menos una vez (únicos). Inflado: Apple Mail (Mail Privacy
411
+ * Protection) y algunos filtros abren el pixel solos. Para decidir, usa los clics.
412
+ */
413
+ opened: number;
414
+ /** Correos del lote con al menos un clic (únicos). Excluye la liga de baja. */
415
+ clicked: number;
416
+ /** `opened` / `delivered` (o / `sent` mientras `delivered` sea 0), de 0 a 1 con 4 decimales. */
417
+ openRate: number;
418
+ /** `clicked` sobre la misma base que `openRate`. */
419
+ clickRate: number;
420
+ /** Hasta 10 ligas con más clics, de más a menos. */
421
+ topLinks: BatchTopLink[];
388
422
  lastError: string | null;
389
423
  createdAt: string;
390
424
  completedAt: string | null;
@@ -422,20 +456,37 @@ export interface UsageResponse {
422
456
  }
423
457
  /**
424
458
  * El partner paga por adelantado: cada correo y la cuota mensual de cada tenant activo se
425
- * descuentan de un saldo que se recarga con MercadoPago (`POST /topup`). Todo en centavos de MXN.
459
+ * descuentan de un saldo que se recarga con MercadoPago (`POST /topup`). El saldo es en la moneda
460
+ * del partner (MXN o USD) y es la única unidad: no hay «créditos». Todos los montos `*Cents` son
461
+ * centavos de esa moneda y pueden traer decimales (en USD un correo cuesta 0.35 centavos; por
462
+ * dentro se lleva en milésimas de centavo). Se muestran con 2 decimales.
426
463
  */
427
- /** Precio por correo enviado (por destinatario). */
428
- export declare const PARTNER_PRICE_PER_EMAIL_CENTS = 6;
429
- /**
430
- * Cuota mensual por tenant activo. Activo = envía ese mes: se descuenta con su primer envío del
431
- * mes (UTC), una sola vez, así que un tenant dormido no cuesta nada.
432
- */
433
- export declare const PARTNER_TENANT_MONTH_CENTS = 4900;
434
- /** Saldo de bienvenida con el que nace todo partner (`adjust`, idemKey `welcome:<partnerId>`). */
435
- export declare const PARTNER_WELCOME_CENTS = 50000;
436
- /** Recarga mínima y máxima por pago. */
437
- export declare const PARTNER_TOPUP_MIN_CENTS = 50000;
438
- export declare const PARTNER_TOPUP_MAX_CENTS = 10000000;
464
+ export type PartnerCurrency = "MXN" | "USD";
465
+ export declare const PARTNER_CURRENCIES: readonly PartnerCurrency[];
466
+ export interface PartnerPrices {
467
+ /** Por correo enviado (por destinatario). */
468
+ perEmailCents: number;
469
+ /**
470
+ * Cuota mensual por tenant activo. Activo = envía ese mes: se descuenta con su primer envío del
471
+ * mes (UTC), una sola vez, así que un tenant dormido no cuesta nada.
472
+ */
473
+ tenantMonthCents: number;
474
+ /** Saldo de bienvenida con el que nace el partner (`adjust`, idemKey `welcome:<partnerId>`). */
475
+ welcomeCents: number;
476
+ /** Recarga mínima y máxima por pago (enteros de la moneda × 100). */
477
+ topupMinCents: number;
478
+ topupMaxCents: number;
479
+ }
480
+ /** Precios por moneda. USD = MXN redondeado; se cobra en MXN por MercadoPago con el tipo de cambio. */
481
+ export declare const PARTNER_PRICES: Record<PartnerCurrency, PartnerPrices>;
482
+ /** Los de MXN, con su nombre de antes (0.7). */
483
+ export declare const PARTNER_PRICE_PER_EMAIL_CENTS: number;
484
+ export declare const PARTNER_TENANT_MONTH_CENTS: number;
485
+ export declare const PARTNER_WELCOME_CENTS: number;
486
+ export declare const PARTNER_TOPUP_MIN_CENTS: number;
487
+ export declare const PARTNER_TOPUP_MAX_CENTS: number;
488
+ /** `$1,234.50 USD`: 2 decimales (4 si el monto es menor a un centavo, como el precio por correo en USD). */
489
+ export declare function formatMoney(cents: number, currency: PartnerCurrency): string;
439
490
  /** `balance.low` sale cuando el saldo baja del 20 % de la última recarga (una vez por recarga). */
440
491
  export declare const BALANCE_LOW_FRACTION = 0.2;
441
492
  export type BalanceMovementKind = "topup" | "send" | "tenant_fee" | "refund" | "adjust";
@@ -455,14 +506,11 @@ export interface BalanceMovement {
455
506
  }
456
507
  /** `GET /balance` */
457
508
  export interface BalanceResponse {
458
- currency: "MXN";
509
+ /** La moneda del saldo y de todos los montos de esta respuesta. */
510
+ currency: PartnerCurrency;
459
511
  /** Sin saldo suficiente el envío se rechaza (402 `insufficient_balance`) y el lote espera. Siempre. */
460
512
  balanceCents: number;
461
- prices: {
462
- perEmailCents: number;
463
- tenantMonthCents: number;
464
- topupMinCents: number;
465
- };
513
+ prices: PartnerPrices;
466
514
  lastTopup: {
467
515
  amountCents: number;
468
516
  at: string;
@@ -486,6 +534,8 @@ export interface BalanceMovementsQuery {
486
534
  kind?: BalanceMovementKind[];
487
535
  }
488
536
  export interface BalanceMovementsResponse {
537
+ /** La moneda de los montos. */
538
+ currency: PartnerCurrency;
489
539
  movements: BalanceMovement[];
490
540
  nextCursor: string | null;
491
541
  }
@@ -494,16 +544,62 @@ export interface BalanceMovementsResponse {
494
544
  * el pago (webhook), no al crear la liga. `returnUrl` (https) es a dónde regresa el navegador.
495
545
  */
496
546
  export interface TopupRequest {
497
- /** Pesos MXN enteros, 500 a 100,000. */
498
- amountMxn: number;
547
+ /**
548
+ * Unidades enteras de la moneda del partner (MXN: 500 a 100,000; USD: 29 a 5,500). En USD
549
+ * MercadoPago cobra el equivalente en MXN con el tipo de cambio de MailMask y se abona lo pedido
550
+ * en USD.
551
+ */
552
+ amount?: number;
553
+ /** Lo mismo que `amount`, sólo para partners en MXN (0.7). */
554
+ amountMxn?: number;
499
555
  returnUrl?: string;
500
556
  }
501
557
  export interface TopupResponse {
502
558
  topupId: string;
559
+ /** Lo que se abona al saldo, en la moneda del partner. */
503
560
  amountCents: number;
561
+ currency: PartnerCurrency;
562
+ /** Lo que cobra MercadoPago, en centavos MXN (igual a `amountCents` si el partner es MXN). */
563
+ chargeMxnCents: number;
564
+ /** MXN por USD con que se cotizó; null en MXN. */
565
+ fxRate: number | null;
504
566
  /** Abre esto en el navegador de quien paga. */
505
567
  initPoint: string;
506
568
  }
569
+ /**
570
+ * Recarga automática mensual: un cobro de MercadoPago cada mes (preapproval con la tarjeta del
571
+ * dueño) que abona `amountCents` al saldo con nota «Recarga automática». En USD MercadoPago cobra
572
+ * `chargeMxnCents` (fijado al activarla) y se abona lo elegido en USD.
573
+ */
574
+ export interface AutoTopup {
575
+ /** off = apagada; pending = falta autorizarla en MercadoPago (`initPoint`); active = cobra cada mes. */
576
+ status: "off" | "pending" | "active";
577
+ currency: PartnerCurrency;
578
+ amountCents: number | null;
579
+ chargeMxnCents: number | null;
580
+ nextChargeAt: string | null;
581
+ lastChargeAt: string | null;
582
+ /** Cobros rechazados seguidos (se reinicia con uno aprobado). */
583
+ failedCharges: number;
584
+ lastError: string | null;
585
+ /** Sólo en la respuesta de prenderla o cambiarla: ábrelo para autorizar el cobro mensual. */
586
+ initPoint?: string;
587
+ }
588
+ /**
589
+ * `PUT /auto-topup` — `amount` en unidades enteras de la moneda (mismo rango que `/topup`) la prende
590
+ * o cambia (cancela la anterior y crea otra); `null` la apaga.
591
+ */
592
+ export interface SetAutoTopupRequest {
593
+ amount: number | null;
594
+ /**
595
+ * Correo de la cuenta de MercadoPago con que se paga, si no es el del dueño en MailMask
596
+ * (MercadoPago rechaza el de su propia cuenta cobradora).
597
+ */
598
+ payerEmail?: string;
599
+ returnUrl?: string;
600
+ }
601
+ /** Montos sugeridos para la recarga automática (unidades enteras). */
602
+ export declare const AUTO_TOPUP_SUGGESTIONS: Record<PartnerCurrency, readonly number[]>;
507
603
  /**
508
604
  * `GET /api/partners/:partnerId/balance` (dueño o MailMask): el saldo, sus últimos 20 movimientos,
509
605
  * el partner (con `tenants` y `ownerEmail`) y si quien mira es de MailMask (ve abonar y el cobro).
@@ -520,6 +616,8 @@ export type PartnerBalanceDetail = BalanceResponse & {
520
616
  movements: BalanceMovement[];
521
617
  partner: PartnerSummary;
522
618
  tenants: PartnerDetailTenant[];
619
+ /** La recarga automática mensual. */
620
+ autoTopup: AutoTopup;
523
621
  staff: boolean;
524
622
  };
525
623
  /** `PUT /api/partners/:partnerId/tenants/:externalId/daily-limit` — sólo MailMask: tope fijo o `null` (vuelve al calentamiento). */
@@ -528,7 +626,7 @@ export interface SetTenantDailyLimitRequest {
528
626
  }
529
627
  /** `POST /api/partners/:partnerId/balance/adjust` — sólo MailMask (admin): abono o cargo manual. */
530
628
  export interface AdjustBalanceRequest {
531
- /** Centavos MXN, distinto de 0 (negativo = cargo). */
629
+ /** Centavos enteros de la moneda del partner, distinto de 0 (negativo = cargo). */
532
630
  amountCents: number;
533
631
  note: string;
534
632
  /** Repetir con la misma llave no vuelve a abonar. */
@@ -567,7 +665,7 @@ export interface RotateWebhookSecretResponse {
567
665
  export interface TestWebhookResponse {
568
666
  deliveryId: string;
569
667
  }
570
- export declare const PARTNER_WEBHOOK_EVENTS: readonly ["email.sent", "email.delivered", "email.bounced", "email.complained", "email.received", "contact.unsubscribed", "tenant.paused", "tenant.resumed", "domain.verified", "balance.low", "batch.throttled"];
668
+ export declare const PARTNER_WEBHOOK_EVENTS: readonly ["email.sent", "email.delivered", "email.bounced", "email.complained", "email.opened", "email.clicked", "email.received", "contact.unsubscribed", "tenant.paused", "tenant.resumed", "domain.verified", "balance.low", "batch.throttled"];
571
669
  export type PartnerWebhookEvent = typeof PARTNER_WEBHOOK_EVENTS[number];
572
670
  /** Headers de cada entrega al webhook del partner (los mismos que los webhooks de dominio). */
573
671
  export declare const WEBHOOK_HEADERS: {
@@ -614,6 +712,24 @@ export interface PartnerEventData {
614
712
  recipient: string;
615
713
  feedbackType: string | null;
616
714
  };
715
+ /**
716
+ * Primera apertura de un correo enviado con `track: true` (una sola vez por correo). Inflado por
717
+ * Apple Mail Privacy Protection: decide por `email.clicked`.
718
+ */
719
+ "email.opened": EmailEventBase & {
720
+ recipient: string;
721
+ batchId: string | null;
722
+ openedAt: string;
723
+ userAgent: string | null;
724
+ };
725
+ /** Primer clic de un correo enviado con `track: true` (una sola vez por correo). `url` es la liga original. */
726
+ "email.clicked": EmailEventBase & {
727
+ recipient: string;
728
+ batchId: string | null;
729
+ url: string;
730
+ clickedAt: string;
731
+ userAgent: string | null;
732
+ };
617
733
  "email.received": {
618
734
  domain: string;
619
735
  from: string;
@@ -650,6 +766,7 @@ export interface PartnerEventData {
650
766
  balanceCents: number;
651
767
  thresholdCents: number;
652
768
  lastTopupCents: number;
769
+ currency: PartnerCurrency;
653
770
  };
654
771
  /** Un lote llegó al límite diario del tenant: sigue solo en `resumesAt`. Una vez por lote. */
655
772
  "batch.throttled": {
@@ -696,8 +813,9 @@ export interface PartnerSummary {
696
813
  effectiveReputationPolicy: ReputationPolicy;
697
814
  /** Zona de respaldo (`marketing.denik.me`); null = sin zona. Ver `FallbackZone`. */
698
815
  fallbackZone: string | null;
699
- /** Saldo prepagado (centavos MXN). Ver `BalanceResponse`. */
816
+ /** Saldo prepagado, en centavos de `currency`. Ver `BalanceResponse`. */
700
817
  balanceCents: number;
818
+ currency: PartnerCurrency;
701
819
  /** Sólo en `GET /api/partners?all=1` (MailMask, admin): tenants totales y activos del mes. */
702
820
  tenants?: {
703
821
  total: number;
@@ -713,6 +831,15 @@ export interface CreatePartnerRequest {
713
831
  ownerEmail: string;
714
832
  plan?: Partial<PartnerSummary["plan"]>;
715
833
  reputationPolicy?: ReputationPolicy | null;
834
+ /** Moneda del saldo; default MXN. Nace con la bienvenida de esa moneda. */
835
+ currency?: PartnerCurrency;
836
+ }
837
+ /**
838
+ * `PUT /api/partners/:partnerId/currency` — sólo MailMask, y sólo mientras el partner no tenga más
839
+ * movimientos que la bienvenida (que se cambia por la de la nueva moneda).
840
+ */
841
+ export interface SetPartnerCurrencyRequest {
842
+ currency: PartnerCurrency;
716
843
  }
717
844
  /** `PUT /api/partners/:partnerId/reputation-policy` — sólo MailMask (admin); null = automática. */
718
845
  export interface SetReputationPolicyRequest {
@@ -832,6 +959,14 @@ export declare const PARTNER_ROUTES: {
832
959
  readonly method: "POST";
833
960
  readonly path: "/topup";
834
961
  };
962
+ readonly getAutoTopup: {
963
+ readonly method: "GET";
964
+ readonly path: "/auto-topup";
965
+ };
966
+ readonly setAutoTopup: {
967
+ readonly method: "PUT";
968
+ readonly path: "/auto-topup";
969
+ };
835
970
  readonly getWebhook: {
836
971
  readonly method: "GET";
837
972
  readonly path: "/webhook";
@@ -893,6 +1028,19 @@ export declare const PARTNER_ADMIN_ROUTES: {
893
1028
  readonly method: "POST";
894
1029
  readonly path: "/api/partners/:partnerId/topup";
895
1030
  };
1031
+ readonly getAutoTopup: {
1032
+ readonly method: "GET";
1033
+ readonly path: "/api/partners/:partnerId/auto-topup";
1034
+ };
1035
+ readonly setAutoTopup: {
1036
+ readonly method: "PUT";
1037
+ readonly path: "/api/partners/:partnerId/auto-topup";
1038
+ };
1039
+ /** Sólo MailMask: moneda del saldo, mientras no haya más movimientos que la bienvenida. */
1040
+ readonly setCurrency: {
1041
+ readonly method: "PUT";
1042
+ readonly path: "/api/partners/:partnerId/currency";
1043
+ };
896
1044
  /** Sólo MailMask: fija (o quita, con `null`) el límite diario de un tenant. Devuelve el `Tenant`. */
897
1045
  readonly setTenantDailyLimit: {
898
1046
  readonly method: "PUT";
package/dist/partner.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MailMaskError } from "./client.js";
2
- import type { TemplateVars, PartnerSummary, CreatePartnerRequest, ReputationPolicy, ListCredentialsResponse, CreateCredentialRequest, CreateCredentialResponse, RotateCredentialRequest, RotateCredentialResponse, RevokeCredentialResponse, PartnerErrorBody, PartnerErrorCode, Tenant, PutTenantRequest, ListTenantsQuery, ListTenantsResponse, DeleteTenantResponse, PartnerDomain, SendRequest, SendResponse, BatchRequest, BatchStatus, UsageResponse, WebhookConfig, SetWebhookRequest, SetWebhookResponse, TestWebhookResponse, PartnerWebhookPayload, RotateWebhookSecretRequest, RotateWebhookSecretResponse, MessageStream, SuppressionReason, FallbackZone, BalanceResponse, BalanceMovementsQuery, BalanceMovementsResponse, TopupRequest, TopupResponse, PartnerBalanceDetail, AdjustBalanceRequest } from "./partner-contract.js";
2
+ import type { TemplateVars, PartnerSummary, CreatePartnerRequest, ReputationPolicy, ListCredentialsResponse, CreateCredentialRequest, CreateCredentialResponse, RotateCredentialRequest, RotateCredentialResponse, RevokeCredentialResponse, PartnerErrorBody, PartnerErrorCode, Tenant, PutTenantRequest, ListTenantsQuery, ListTenantsResponse, DeleteTenantResponse, PartnerDomain, SendRequest, SendResponse, BatchRequest, BatchStatus, UsageResponse, WebhookConfig, SetWebhookRequest, SetWebhookResponse, TestWebhookResponse, PartnerWebhookPayload, RotateWebhookSecretRequest, RotateWebhookSecretResponse, MessageStream, SuppressionReason, FallbackZone, BalanceResponse, BalanceMovementsQuery, BalanceMovementsResponse, TopupRequest, TopupResponse, PartnerBalanceDetail, AdjustBalanceRequest, PartnerCurrency, AutoTopup, SetAutoTopupRequest } from "./partner-contract.js";
3
3
  export * from "./partner-contract.js";
4
4
  /**
5
5
  * Discriminante estable de los errores de partners, para un `switch` sin cadenas de `instanceof`.
@@ -111,13 +111,15 @@ export declare class DailyLimitError extends QuotaError {
111
111
  get sentToday(): number | undefined;
112
112
  }
113
113
  /**
114
- * 402 `insufficient_balance`: el saldo prepagado no alcanza. No se reintenta: recarga con `partner.topup()`. Trae `balanceCents` y `requiredCents`.
114
+ * 402 `insufficient_balance`: el saldo prepagado no alcanza. No se reintenta: recarga con `partner.topup()`. Trae `balanceCents`, `requiredCents` y `currency`.
115
115
  */
116
116
  export declare class InsufficientBalanceError extends PartnerApiError {
117
117
  name: string;
118
118
  kind: PartnerErrorKind;
119
119
  get balanceCents(): number | undefined;
120
120
  get requiredCents(): number | undefined;
121
+ /** Moneda de los dos montos de arriba. */
122
+ get currency(): PartnerCurrency | undefined;
121
123
  }
122
124
  /** No hubo respuesta: DNS, conexión rechazada o cortada. `status` 0. */
123
125
  export declare class NetworkError extends PartnerApiError {
@@ -235,17 +237,28 @@ export declare class MailMaskPartner {
235
237
  idempotencyKey: string;
236
238
  replayed: boolean;
237
239
  }>;
238
- /** Estado de un lote (`batchId` del resultado de `batch`): envíos y, después, entregas, rebotes, quejas y bajas. */
240
+ /**
241
+ * Estado de un lote (`batchId` del resultado de `batch`): envíos y, después, entregas, rebotes, quejas
242
+ * y bajas; con `track: true`, también aperturas, clics, tasas y `topLinks`.
243
+ */
239
244
  batchStatus(externalId: string, batchId: string): Promise<BatchStatus>;
240
245
  /** Saldo prepagado: saldo, precios, última recarga y consumo del mes (centavos MXN). */
241
246
  balance(): Promise<BalanceResponse>;
242
247
  /** Movimientos del saldo, del más nuevo al más viejo; pagina con `nextCursor`. */
243
248
  balanceMovements(query?: BalanceMovementsQuery): Promise<BalanceMovementsResponse>;
244
249
  /**
245
- * Liga de MercadoPago para recargar saldo (pago único, $500 a $100,000 MXN). El saldo sube cuando
246
- * MercadoPago confirma el pago, no al crear la liga. Abre `initPoint` en el navegador de quien paga.
250
+ * Liga de MercadoPago para recargar saldo (pago único; `amount` en unidades enteras de tu moneda:
251
+ * MXN 500 a 100,000, USD 29 a 5,500). El saldo sube cuando MercadoPago confirma el pago, no al
252
+ * crear la liga. Abre `initPoint` en el navegador de quien paga.
247
253
  */
248
254
  topup(input: TopupRequest): Promise<TopupResponse>;
255
+ /** La recarga automática mensual: `off`, `pending` (falta autorizarla) o `active`. */
256
+ autoTopup(): Promise<AutoTopup>;
257
+ /**
258
+ * Prende o cambia (`amount` entero de tu moneda) la recarga automática mensual, o la apaga
259
+ * (`amount: null`). Al prenderla o cambiarla devuelve `initPoint`: ábrelo para autorizar el cobro.
260
+ */
261
+ setAutoTopup(input: SetAutoTopupRequest): Promise<AutoTopup>;
249
262
  /** Uso del mes (`YYYY-MM`, default el mes en curso UTC): tenants activos y envíos. */
250
263
  usage(opts?: {
251
264
  month?: string;
@@ -380,6 +393,8 @@ export declare class MailMaskPartnerAdmin {
380
393
  createPartner(input: CreatePartnerRequest): Promise<PartnerSummary>;
381
394
  /** Sólo MailMask (admin); null = automática (Strict el primer mes, Standard después). */
382
395
  setReputationPolicy(partnerId: string, policy: ReputationPolicy | null): Promise<PartnerSummary>;
396
+ /** Sólo MailMask (admin): moneda del saldo (MXN o USD); sólo antes de cualquier movimiento aparte de la bienvenida. */
397
+ setCurrency(partnerId: string, currency: PartnerCurrency): Promise<PartnerSummary>;
383
398
  /** Sólo MailMask (admin): levanta cualquier pausa, también la de reputación. */
384
399
  resumeTenant(partnerId: string, externalId: string): Promise<Tenant>;
385
400
  /** Sólo MailMask: tope diario fijo del tenant, o `null` para volver al calentamiento. */
@@ -397,6 +412,10 @@ export declare class MailMaskPartnerAdmin {
397
412
  adjustBalance(partnerId: string, input: AdjustBalanceRequest): Promise<PartnerBalanceDetail>;
398
413
  /** Liga de MercadoPago para recargar, con la llave del dueño. */
399
414
  topup(partnerId: string, input: TopupRequest): Promise<TopupResponse>;
415
+ /** La recarga automática mensual del partner (dueño o MailMask). */
416
+ getAutoTopup(partnerId: string): Promise<AutoTopup>;
417
+ /** Prende, cambia (`amount`) o apaga (`null`) la recarga automática; trae `initPoint` al prenderla. */
418
+ setAutoTopup(partnerId: string, input: SetAutoTopupRequest): Promise<AutoTopup>;
400
419
  listCredentials(partnerId: string): Promise<ListCredentialsResponse>;
401
420
  /** El secreto `mms_…` viene UNA vez en la respuesta. */
402
421
  createCredential(partnerId: string, input?: CreateCredentialRequest): Promise<CreateCredentialResponse>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easybits.cloud/mailmask",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "Official SDK for the MailMask email alias/forwarding API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",