@easybits.cloud/mailmask 0.8.0 → 0.9.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/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,13 +847,25 @@ 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",
@@ -896,6 +912,8 @@ var PARTNER_ROUTES = {
896
912
  balance: { method: "GET", path: "/balance" },
897
913
  balanceMovements: { method: "GET", path: "/balance/movements" },
898
914
  topup: { method: "POST", path: "/topup" },
915
+ getAutoTopup: { method: "GET", path: "/auto-topup" },
916
+ setAutoTopup: { method: "PUT", path: "/auto-topup" },
899
917
  getWebhook: { method: "GET", path: "/webhook" },
900
918
  setWebhook: { method: "PUT", path: "/webhook" },
901
919
  testWebhook: { method: "POST", path: "/webhook/test" },
@@ -917,6 +935,10 @@ var PARTNER_ADMIN_ROUTES = {
917
935
  adjustBalance: { method: "POST", path: "/api/partners/:partnerId/balance/adjust" },
918
936
  /** Recarga con MercadoPago desde la sesión del dueño (misma respuesta que `POST /topup`). */
919
937
  topup: { method: "POST", path: "/api/partners/:partnerId/topup" },
938
+ getAutoTopup: { method: "GET", path: "/api/partners/:partnerId/auto-topup" },
939
+ setAutoTopup: { method: "PUT", path: "/api/partners/:partnerId/auto-topup" },
940
+ /** Sólo MailMask: moneda del saldo, mientras no haya más movimientos que la bienvenida. */
941
+ setCurrency: { method: "PUT", path: "/api/partners/:partnerId/currency" },
920
942
  /** Sólo MailMask: fija (o quita, con `null`) el límite diario de un tenant. Devuelve el `Tenant`. */
921
943
  setTenantDailyLimit: { method: "PUT", path: "/api/partners/:partnerId/tenants/:externalId/daily-limit" },
922
944
  listCredentials: { method: "GET", path: "/api/partners/:partnerId/credentials" },
@@ -1058,6 +1080,10 @@ var InsufficientBalanceError = class extends PartnerApiError {
1058
1080
  get requiredCents() {
1059
1081
  return this.body.requiredCents;
1060
1082
  }
1083
+ /** Moneda de los dos montos de arriba. */
1084
+ get currency() {
1085
+ return this.body.currency;
1086
+ }
1061
1087
  };
1062
1088
  var NetworkError = class extends PartnerApiError {
1063
1089
  constructor(message, cause) {
@@ -1298,12 +1324,24 @@ var MailMaskPartner = class {
1298
1324
  return (await this.request("GET", `${PARTNER_ROUTES.balanceMovements.path}${qs ? `?${qs}` : ""}`)).data;
1299
1325
  }
1300
1326
  /**
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.
1327
+ * Liga de MercadoPago para recargar saldo (pago único; `amount` en unidades enteras de tu moneda:
1328
+ * MXN 500 a 100,000, USD 29 a 5,500). El saldo sube cuando MercadoPago confirma el pago, no al
1329
+ * crear la liga. Abre `initPoint` en el navegador de quien paga.
1303
1330
  */
1304
1331
  async topup(input) {
1305
1332
  return (await this.request("POST", PARTNER_ROUTES.topup.path, input)).data;
1306
1333
  }
1334
+ /** La recarga automática mensual: `off`, `pending` (falta autorizarla) o `active`. */
1335
+ async autoTopup() {
1336
+ return (await this.request("GET", PARTNER_ROUTES.getAutoTopup.path)).data;
1337
+ }
1338
+ /**
1339
+ * Prende o cambia (`amount` entero de tu moneda) la recarga automática mensual, o la apaga
1340
+ * (`amount: null`). Al prenderla o cambiarla devuelve `initPoint`: ábrelo para autorizar el cobro.
1341
+ */
1342
+ async setAutoTopup(input) {
1343
+ return (await this.request("PUT", PARTNER_ROUTES.setAutoTopup.path, input)).data;
1344
+ }
1307
1345
  /** Uso del mes (`YYYY-MM`, default el mes en curso UTC): tenants activos y envíos. */
1308
1346
  async usage(opts = {}) {
1309
1347
  const q = opts.month ? `?month=${encodeURIComponent(opts.month)}` : "";
@@ -1504,6 +1542,10 @@ var MailMaskPartnerAdmin = class {
1504
1542
  setReputationPolicy(partnerId, policy) {
1505
1543
  return this.req("setReputationPolicy", { partnerId }, { policy });
1506
1544
  }
1545
+ /** Sólo MailMask (admin): moneda del saldo (MXN o USD); sólo antes de cualquier movimiento aparte de la bienvenida. */
1546
+ setCurrency(partnerId, currency) {
1547
+ return this.req("setCurrency", { partnerId }, { currency });
1548
+ }
1507
1549
  /** Sólo MailMask (admin): levanta cualquier pausa, también la de reputación. */
1508
1550
  resumeTenant(partnerId, externalId) {
1509
1551
  return this.req("resumeTenant", { partnerId, externalId });
@@ -1535,6 +1577,14 @@ var MailMaskPartnerAdmin = class {
1535
1577
  topup(partnerId, input) {
1536
1578
  return this.req("topup", { partnerId }, input);
1537
1579
  }
1580
+ /** La recarga automática mensual del partner (dueño o MailMask). */
1581
+ getAutoTopup(partnerId) {
1582
+ return this.req("getAutoTopup", { partnerId });
1583
+ }
1584
+ /** Prende, cambia (`amount`) o apaga (`null`) la recarga automática; trae `initPoint` al prenderla. */
1585
+ setAutoTopup(partnerId, input) {
1586
+ return this.req("setAutoTopup", { partnerId }, input);
1587
+ }
1538
1588
  listCredentials(partnerId) {
1539
1589
  return this.req("listCredentials", { partnerId });
1540
1590
  }
@@ -1553,6 +1603,7 @@ var MailMaskPartnerAdmin = class {
1553
1603
  };
1554
1604
  // Annotate the CommonJS export names for ESM import in node:
1555
1605
  0 && (module.exports = {
1606
+ AUTO_TOPUP_SUGGESTIONS,
1556
1607
  AuthError,
1557
1608
  BALANCE_LOW_FRACTION,
1558
1609
  BALANCE_MOVEMENT_KINDS,
@@ -1577,8 +1628,10 @@ var MailMaskPartnerAdmin = class {
1577
1628
  NotFoundError,
1578
1629
  PARTNER_ADMIN_ROUTES,
1579
1630
  PARTNER_API_PREFIX,
1631
+ PARTNER_CURRENCIES,
1580
1632
  PARTNER_ERROR_STATUS,
1581
1633
  PARTNER_HEADERS,
1634
+ PARTNER_PRICES,
1582
1635
  PARTNER_PRICE_PER_EMAIL_CENTS,
1583
1636
  PARTNER_ROUTES,
1584
1637
  PARTNER_SIGNATURE_TOLERANCE_S,
@@ -1607,6 +1660,7 @@ var MailMaskPartnerAdmin = class {
1607
1660
  WEBHOOK_TOLERANCE_MS,
1608
1661
  createWebhookHandler,
1609
1662
  estimateSendDays,
1663
+ formatMoney,
1610
1664
  isValidExternalId,
1611
1665
  isValidFallbackLabel,
1612
1666
  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,13 +750,25 @@ 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",
@@ -803,6 +815,8 @@ var PARTNER_ROUTES = {
803
815
  balance: { method: "GET", path: "/balance" },
804
816
  balanceMovements: { method: "GET", path: "/balance/movements" },
805
817
  topup: { method: "POST", path: "/topup" },
818
+ getAutoTopup: { method: "GET", path: "/auto-topup" },
819
+ setAutoTopup: { method: "PUT", path: "/auto-topup" },
806
820
  getWebhook: { method: "GET", path: "/webhook" },
807
821
  setWebhook: { method: "PUT", path: "/webhook" },
808
822
  testWebhook: { method: "POST", path: "/webhook/test" },
@@ -824,6 +838,10 @@ var PARTNER_ADMIN_ROUTES = {
824
838
  adjustBalance: { method: "POST", path: "/api/partners/:partnerId/balance/adjust" },
825
839
  /** Recarga con MercadoPago desde la sesión del dueño (misma respuesta que `POST /topup`). */
826
840
  topup: { method: "POST", path: "/api/partners/:partnerId/topup" },
841
+ getAutoTopup: { method: "GET", path: "/api/partners/:partnerId/auto-topup" },
842
+ setAutoTopup: { method: "PUT", path: "/api/partners/:partnerId/auto-topup" },
843
+ /** Sólo MailMask: moneda del saldo, mientras no haya más movimientos que la bienvenida. */
844
+ setCurrency: { method: "PUT", path: "/api/partners/:partnerId/currency" },
827
845
  /** Sólo MailMask: fija (o quita, con `null`) el límite diario de un tenant. Devuelve el `Tenant`. */
828
846
  setTenantDailyLimit: { method: "PUT", path: "/api/partners/:partnerId/tenants/:externalId/daily-limit" },
829
847
  listCredentials: { method: "GET", path: "/api/partners/:partnerId/credentials" },
@@ -965,6 +983,10 @@ var InsufficientBalanceError = class extends PartnerApiError {
965
983
  get requiredCents() {
966
984
  return this.body.requiredCents;
967
985
  }
986
+ /** Moneda de los dos montos de arriba. */
987
+ get currency() {
988
+ return this.body.currency;
989
+ }
968
990
  };
969
991
  var NetworkError = class extends PartnerApiError {
970
992
  constructor(message, cause) {
@@ -1205,12 +1227,24 @@ var MailMaskPartner = class {
1205
1227
  return (await this.request("GET", `${PARTNER_ROUTES.balanceMovements.path}${qs ? `?${qs}` : ""}`)).data;
1206
1228
  }
1207
1229
  /**
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.
1230
+ * Liga de MercadoPago para recargar saldo (pago único; `amount` en unidades enteras de tu moneda:
1231
+ * MXN 500 a 100,000, USD 29 a 5,500). El saldo sube cuando MercadoPago confirma el pago, no al
1232
+ * crear la liga. Abre `initPoint` en el navegador de quien paga.
1210
1233
  */
1211
1234
  async topup(input) {
1212
1235
  return (await this.request("POST", PARTNER_ROUTES.topup.path, input)).data;
1213
1236
  }
1237
+ /** La recarga automática mensual: `off`, `pending` (falta autorizarla) o `active`. */
1238
+ async autoTopup() {
1239
+ return (await this.request("GET", PARTNER_ROUTES.getAutoTopup.path)).data;
1240
+ }
1241
+ /**
1242
+ * Prende o cambia (`amount` entero de tu moneda) la recarga automática mensual, o la apaga
1243
+ * (`amount: null`). Al prenderla o cambiarla devuelve `initPoint`: ábrelo para autorizar el cobro.
1244
+ */
1245
+ async setAutoTopup(input) {
1246
+ return (await this.request("PUT", PARTNER_ROUTES.setAutoTopup.path, input)).data;
1247
+ }
1214
1248
  /** Uso del mes (`YYYY-MM`, default el mes en curso UTC): tenants activos y envíos. */
1215
1249
  async usage(opts = {}) {
1216
1250
  const q = opts.month ? `?month=${encodeURIComponent(opts.month)}` : "";
@@ -1411,6 +1445,10 @@ var MailMaskPartnerAdmin = class {
1411
1445
  setReputationPolicy(partnerId, policy) {
1412
1446
  return this.req("setReputationPolicy", { partnerId }, { policy });
1413
1447
  }
1448
+ /** Sólo MailMask (admin): moneda del saldo (MXN o USD); sólo antes de cualquier movimiento aparte de la bienvenida. */
1449
+ setCurrency(partnerId, currency) {
1450
+ return this.req("setCurrency", { partnerId }, { currency });
1451
+ }
1414
1452
  /** Sólo MailMask (admin): levanta cualquier pausa, también la de reputación. */
1415
1453
  resumeTenant(partnerId, externalId) {
1416
1454
  return this.req("resumeTenant", { partnerId, externalId });
@@ -1442,6 +1480,14 @@ var MailMaskPartnerAdmin = class {
1442
1480
  topup(partnerId, input) {
1443
1481
  return this.req("topup", { partnerId }, input);
1444
1482
  }
1483
+ /** La recarga automática mensual del partner (dueño o MailMask). */
1484
+ getAutoTopup(partnerId) {
1485
+ return this.req("getAutoTopup", { partnerId });
1486
+ }
1487
+ /** Prende, cambia (`amount`) o apaga (`null`) la recarga automática; trae `initPoint` al prenderla. */
1488
+ setAutoTopup(partnerId, input) {
1489
+ return this.req("setAutoTopup", { partnerId }, input);
1490
+ }
1445
1491
  listCredentials(partnerId) {
1446
1492
  return this.req("listCredentials", { partnerId });
1447
1493
  }
@@ -1459,6 +1505,7 @@ var MailMaskPartnerAdmin = class {
1459
1505
  }
1460
1506
  };
1461
1507
  export {
1508
+ AUTO_TOPUP_SUGGESTIONS,
1462
1509
  AuthError,
1463
1510
  BALANCE_LOW_FRACTION,
1464
1511
  BALANCE_MOVEMENT_KINDS,
@@ -1483,8 +1530,10 @@ export {
1483
1530
  NotFoundError,
1484
1531
  PARTNER_ADMIN_ROUTES,
1485
1532
  PARTNER_API_PREFIX,
1533
+ PARTNER_CURRENCIES,
1486
1534
  PARTNER_ERROR_STATUS,
1487
1535
  PARTNER_HEADERS,
1536
+ PARTNER_PRICES,
1488
1537
  PARTNER_PRICE_PER_EMAIL_CENTS,
1489
1538
  PARTNER_ROUTES,
1490
1539
  PARTNER_SIGNATURE_TOLERANCE_S,
@@ -1513,6 +1562,7 @@ export {
1513
1562
  WEBHOOK_TOLERANCE_MS,
1514
1563
  createWebhookHandler,
1515
1564
  estimateSendDays,
1565
+ formatMoney,
1516
1566
  isValidExternalId,
1517
1567
  isValidFallbackLabel,
1518
1568
  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;
@@ -422,20 +424,37 @@ export interface UsageResponse {
422
424
  }
423
425
  /**
424
426
  * 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.
427
+ * descuentan de un saldo que se recarga con MercadoPago (`POST /topup`). El saldo es en la moneda
428
+ * del partner (MXN o USD) y es la única unidad: no hay «créditos». Todos los montos `*Cents` son
429
+ * centavos de esa moneda y pueden traer decimales (en USD un correo cuesta 0.35 centavos; por
430
+ * dentro se lleva en milésimas de centavo). Se muestran con 2 decimales.
426
431
  */
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;
432
+ export type PartnerCurrency = "MXN" | "USD";
433
+ export declare const PARTNER_CURRENCIES: readonly PartnerCurrency[];
434
+ export interface PartnerPrices {
435
+ /** Por correo enviado (por destinatario). */
436
+ perEmailCents: number;
437
+ /**
438
+ * Cuota mensual por tenant activo. Activo = envía ese mes: se descuenta con su primer envío del
439
+ * mes (UTC), una sola vez, así que un tenant dormido no cuesta nada.
440
+ */
441
+ tenantMonthCents: number;
442
+ /** Saldo de bienvenida con el que nace el partner (`adjust`, idemKey `welcome:<partnerId>`). */
443
+ welcomeCents: number;
444
+ /** Recarga mínima y máxima por pago (enteros de la moneda × 100). */
445
+ topupMinCents: number;
446
+ topupMaxCents: number;
447
+ }
448
+ /** Precios por moneda. USD = MXN redondeado; se cobra en MXN por MercadoPago con el tipo de cambio. */
449
+ export declare const PARTNER_PRICES: Record<PartnerCurrency, PartnerPrices>;
450
+ /** Los de MXN, con su nombre de antes (0.7). */
451
+ export declare const PARTNER_PRICE_PER_EMAIL_CENTS: number;
452
+ export declare const PARTNER_TENANT_MONTH_CENTS: number;
453
+ export declare const PARTNER_WELCOME_CENTS: number;
454
+ export declare const PARTNER_TOPUP_MIN_CENTS: number;
455
+ export declare const PARTNER_TOPUP_MAX_CENTS: number;
456
+ /** `$1,234.50 USD`: 2 decimales (4 si el monto es menor a un centavo, como el precio por correo en USD). */
457
+ export declare function formatMoney(cents: number, currency: PartnerCurrency): string;
439
458
  /** `balance.low` sale cuando el saldo baja del 20 % de la última recarga (una vez por recarga). */
440
459
  export declare const BALANCE_LOW_FRACTION = 0.2;
441
460
  export type BalanceMovementKind = "topup" | "send" | "tenant_fee" | "refund" | "adjust";
@@ -455,14 +474,11 @@ export interface BalanceMovement {
455
474
  }
456
475
  /** `GET /balance` */
457
476
  export interface BalanceResponse {
458
- currency: "MXN";
477
+ /** La moneda del saldo y de todos los montos de esta respuesta. */
478
+ currency: PartnerCurrency;
459
479
  /** Sin saldo suficiente el envío se rechaza (402 `insufficient_balance`) y el lote espera. Siempre. */
460
480
  balanceCents: number;
461
- prices: {
462
- perEmailCents: number;
463
- tenantMonthCents: number;
464
- topupMinCents: number;
465
- };
481
+ prices: PartnerPrices;
466
482
  lastTopup: {
467
483
  amountCents: number;
468
484
  at: string;
@@ -486,6 +502,8 @@ export interface BalanceMovementsQuery {
486
502
  kind?: BalanceMovementKind[];
487
503
  }
488
504
  export interface BalanceMovementsResponse {
505
+ /** La moneda de los montos. */
506
+ currency: PartnerCurrency;
489
507
  movements: BalanceMovement[];
490
508
  nextCursor: string | null;
491
509
  }
@@ -494,16 +512,57 @@ export interface BalanceMovementsResponse {
494
512
  * el pago (webhook), no al crear la liga. `returnUrl` (https) es a dónde regresa el navegador.
495
513
  */
496
514
  export interface TopupRequest {
497
- /** Pesos MXN enteros, 500 a 100,000. */
498
- amountMxn: number;
515
+ /**
516
+ * Unidades enteras de la moneda del partner (MXN: 500 a 100,000; USD: 29 a 5,500). En USD
517
+ * MercadoPago cobra el equivalente en MXN con el tipo de cambio de MailMask y se abona lo pedido
518
+ * en USD.
519
+ */
520
+ amount?: number;
521
+ /** Lo mismo que `amount`, sólo para partners en MXN (0.7). */
522
+ amountMxn?: number;
499
523
  returnUrl?: string;
500
524
  }
501
525
  export interface TopupResponse {
502
526
  topupId: string;
527
+ /** Lo que se abona al saldo, en la moneda del partner. */
503
528
  amountCents: number;
529
+ currency: PartnerCurrency;
530
+ /** Lo que cobra MercadoPago, en centavos MXN (igual a `amountCents` si el partner es MXN). */
531
+ chargeMxnCents: number;
532
+ /** MXN por USD con que se cotizó; null en MXN. */
533
+ fxRate: number | null;
504
534
  /** Abre esto en el navegador de quien paga. */
505
535
  initPoint: string;
506
536
  }
537
+ /**
538
+ * Recarga automática mensual: un cobro de MercadoPago cada mes (preapproval con la tarjeta del
539
+ * dueño) que abona `amountCents` al saldo con nota «Recarga automática». En USD MercadoPago cobra
540
+ * `chargeMxnCents` (fijado al activarla) y se abona lo elegido en USD.
541
+ */
542
+ export interface AutoTopup {
543
+ /** off = apagada; pending = falta autorizarla en MercadoPago (`initPoint`); active = cobra cada mes. */
544
+ status: "off" | "pending" | "active";
545
+ currency: PartnerCurrency;
546
+ amountCents: number | null;
547
+ chargeMxnCents: number | null;
548
+ nextChargeAt: string | null;
549
+ lastChargeAt: string | null;
550
+ /** Cobros rechazados seguidos (se reinicia con uno aprobado). */
551
+ failedCharges: number;
552
+ lastError: string | null;
553
+ /** Sólo en la respuesta de prenderla o cambiarla: ábrelo para autorizar el cobro mensual. */
554
+ initPoint?: string;
555
+ }
556
+ /**
557
+ * `PUT /auto-topup` — `amount` en unidades enteras de la moneda (mismo rango que `/topup`) la prende
558
+ * o cambia (cancela la anterior y crea otra); `null` la apaga.
559
+ */
560
+ export interface SetAutoTopupRequest {
561
+ amount: number | null;
562
+ returnUrl?: string;
563
+ }
564
+ /** Montos sugeridos para la recarga automática (unidades enteras). */
565
+ export declare const AUTO_TOPUP_SUGGESTIONS: Record<PartnerCurrency, readonly number[]>;
507
566
  /**
508
567
  * `GET /api/partners/:partnerId/balance` (dueño o MailMask): el saldo, sus últimos 20 movimientos,
509
568
  * el partner (con `tenants` y `ownerEmail`) y si quien mira es de MailMask (ve abonar y el cobro).
@@ -520,6 +579,8 @@ export type PartnerBalanceDetail = BalanceResponse & {
520
579
  movements: BalanceMovement[];
521
580
  partner: PartnerSummary;
522
581
  tenants: PartnerDetailTenant[];
582
+ /** La recarga automática mensual. */
583
+ autoTopup: AutoTopup;
523
584
  staff: boolean;
524
585
  };
525
586
  /** `PUT /api/partners/:partnerId/tenants/:externalId/daily-limit` — sólo MailMask: tope fijo o `null` (vuelve al calentamiento). */
@@ -528,7 +589,7 @@ export interface SetTenantDailyLimitRequest {
528
589
  }
529
590
  /** `POST /api/partners/:partnerId/balance/adjust` — sólo MailMask (admin): abono o cargo manual. */
530
591
  export interface AdjustBalanceRequest {
531
- /** Centavos MXN, distinto de 0 (negativo = cargo). */
592
+ /** Centavos enteros de la moneda del partner, distinto de 0 (negativo = cargo). */
532
593
  amountCents: number;
533
594
  note: string;
534
595
  /** Repetir con la misma llave no vuelve a abonar. */
@@ -650,6 +711,7 @@ export interface PartnerEventData {
650
711
  balanceCents: number;
651
712
  thresholdCents: number;
652
713
  lastTopupCents: number;
714
+ currency: PartnerCurrency;
653
715
  };
654
716
  /** Un lote llegó al límite diario del tenant: sigue solo en `resumesAt`. Una vez por lote. */
655
717
  "batch.throttled": {
@@ -696,8 +758,9 @@ export interface PartnerSummary {
696
758
  effectiveReputationPolicy: ReputationPolicy;
697
759
  /** Zona de respaldo (`marketing.denik.me`); null = sin zona. Ver `FallbackZone`. */
698
760
  fallbackZone: string | null;
699
- /** Saldo prepagado (centavos MXN). Ver `BalanceResponse`. */
761
+ /** Saldo prepagado, en centavos de `currency`. Ver `BalanceResponse`. */
700
762
  balanceCents: number;
763
+ currency: PartnerCurrency;
701
764
  /** Sólo en `GET /api/partners?all=1` (MailMask, admin): tenants totales y activos del mes. */
702
765
  tenants?: {
703
766
  total: number;
@@ -713,6 +776,15 @@ export interface CreatePartnerRequest {
713
776
  ownerEmail: string;
714
777
  plan?: Partial<PartnerSummary["plan"]>;
715
778
  reputationPolicy?: ReputationPolicy | null;
779
+ /** Moneda del saldo; default MXN. Nace con la bienvenida de esa moneda. */
780
+ currency?: PartnerCurrency;
781
+ }
782
+ /**
783
+ * `PUT /api/partners/:partnerId/currency` — sólo MailMask, y sólo mientras el partner no tenga más
784
+ * movimientos que la bienvenida (que se cambia por la de la nueva moneda).
785
+ */
786
+ export interface SetPartnerCurrencyRequest {
787
+ currency: PartnerCurrency;
716
788
  }
717
789
  /** `PUT /api/partners/:partnerId/reputation-policy` — sólo MailMask (admin); null = automática. */
718
790
  export interface SetReputationPolicyRequest {
@@ -832,6 +904,14 @@ export declare const PARTNER_ROUTES: {
832
904
  readonly method: "POST";
833
905
  readonly path: "/topup";
834
906
  };
907
+ readonly getAutoTopup: {
908
+ readonly method: "GET";
909
+ readonly path: "/auto-topup";
910
+ };
911
+ readonly setAutoTopup: {
912
+ readonly method: "PUT";
913
+ readonly path: "/auto-topup";
914
+ };
835
915
  readonly getWebhook: {
836
916
  readonly method: "GET";
837
917
  readonly path: "/webhook";
@@ -893,6 +973,19 @@ export declare const PARTNER_ADMIN_ROUTES: {
893
973
  readonly method: "POST";
894
974
  readonly path: "/api/partners/:partnerId/topup";
895
975
  };
976
+ readonly getAutoTopup: {
977
+ readonly method: "GET";
978
+ readonly path: "/api/partners/:partnerId/auto-topup";
979
+ };
980
+ readonly setAutoTopup: {
981
+ readonly method: "PUT";
982
+ readonly path: "/api/partners/:partnerId/auto-topup";
983
+ };
984
+ /** Sólo MailMask: moneda del saldo, mientras no haya más movimientos que la bienvenida. */
985
+ readonly setCurrency: {
986
+ readonly method: "PUT";
987
+ readonly path: "/api/partners/:partnerId/currency";
988
+ };
896
989
  /** Sólo MailMask: fija (o quita, con `null`) el límite diario de un tenant. Devuelve el `Tenant`. */
897
990
  readonly setTenantDailyLimit: {
898
991
  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 {
@@ -242,10 +244,18 @@ export declare class MailMaskPartner {
242
244
  /** Movimientos del saldo, del más nuevo al más viejo; pagina con `nextCursor`. */
243
245
  balanceMovements(query?: BalanceMovementsQuery): Promise<BalanceMovementsResponse>;
244
246
  /**
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.
247
+ * Liga de MercadoPago para recargar saldo (pago único; `amount` en unidades enteras de tu moneda:
248
+ * MXN 500 a 100,000, USD 29 a 5,500). El saldo sube cuando MercadoPago confirma el pago, no al
249
+ * crear la liga. Abre `initPoint` en el navegador de quien paga.
247
250
  */
248
251
  topup(input: TopupRequest): Promise<TopupResponse>;
252
+ /** La recarga automática mensual: `off`, `pending` (falta autorizarla) o `active`. */
253
+ autoTopup(): Promise<AutoTopup>;
254
+ /**
255
+ * Prende o cambia (`amount` entero de tu moneda) la recarga automática mensual, o la apaga
256
+ * (`amount: null`). Al prenderla o cambiarla devuelve `initPoint`: ábrelo para autorizar el cobro.
257
+ */
258
+ setAutoTopup(input: SetAutoTopupRequest): Promise<AutoTopup>;
249
259
  /** Uso del mes (`YYYY-MM`, default el mes en curso UTC): tenants activos y envíos. */
250
260
  usage(opts?: {
251
261
  month?: string;
@@ -380,6 +390,8 @@ export declare class MailMaskPartnerAdmin {
380
390
  createPartner(input: CreatePartnerRequest): Promise<PartnerSummary>;
381
391
  /** Sólo MailMask (admin); null = automática (Strict el primer mes, Standard después). */
382
392
  setReputationPolicy(partnerId: string, policy: ReputationPolicy | null): Promise<PartnerSummary>;
393
+ /** Sólo MailMask (admin): moneda del saldo (MXN o USD); sólo antes de cualquier movimiento aparte de la bienvenida. */
394
+ setCurrency(partnerId: string, currency: PartnerCurrency): Promise<PartnerSummary>;
383
395
  /** Sólo MailMask (admin): levanta cualquier pausa, también la de reputación. */
384
396
  resumeTenant(partnerId: string, externalId: string): Promise<Tenant>;
385
397
  /** Sólo MailMask: tope diario fijo del tenant, o `null` para volver al calentamiento. */
@@ -397,6 +409,10 @@ export declare class MailMaskPartnerAdmin {
397
409
  adjustBalance(partnerId: string, input: AdjustBalanceRequest): Promise<PartnerBalanceDetail>;
398
410
  /** Liga de MercadoPago para recargar, con la llave del dueño. */
399
411
  topup(partnerId: string, input: TopupRequest): Promise<TopupResponse>;
412
+ /** La recarga automática mensual del partner (dueño o MailMask). */
413
+ getAutoTopup(partnerId: string): Promise<AutoTopup>;
414
+ /** Prende, cambia (`amount`) o apaga (`null`) la recarga automática; trae `initPoint` al prenderla. */
415
+ setAutoTopup(partnerId: string, input: SetAutoTopupRequest): Promise<AutoTopup>;
400
416
  listCredentials(partnerId: string): Promise<ListCredentialsResponse>;
401
417
  /** El secreto `mms_…` viene UNA vez en la respuesta. */
402
418
  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.0",
4
4
  "description": "Official SDK for the MailMask email alias/forwarding API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",