mailery 0.7.0 → 0.8.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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RunnerContext, N as NormalizedEvent, C as ContactAdapter, a as Contact, A as AdapterFilter, M as MailProvider, S as SendArgs, b as SendResult, c as MailTesterFeedback, d as Mailer, T as TemplateDoc, e as SuppressionScope, D as DeliveryWindow, F as FlowStep, f as SegmentFilter, P as Predicate } from './null-B0rPgE5_.cjs';
2
- export { g as AuditLogDoc, B as BroadcastDoc, h as BroadcastStatus, i as CircuitBreakerThresholds, j as Collections, k as ContactTagDoc, E as EventDoc, l as FlowDoc, m as FlowGoal, n as FlowRunDoc, o as FlowRunStatus, p as FlowVersionDoc, H as HealthDoc, q as HealthStatus, L as LeadDoc, r as MailerConfig, s as NullProvider, O as OutboxDoc, t as RESERVED_VAR_KEYS, u as RedisOptions, v as SegmentDefinition, w as SendDoc, x as SendStatus, y as SenderDomainConfig, z as SenderDomainRegistry, G as SenderDomainValidation, I as SubscriptionDoc, J as SubscriptionStatus, K as SuppressionDoc, Q as SuppressionReason, U as TemplateKind, V as TemplateVersionDoc, W as VarsAdapter, X as VarsResolveInfo, Y as WebhookEventDoc, Z as defineVars, _ as ensureIndexes, $ as getCollections, a0 as validateSenderDomain, a1 as varsJsonSchema } from './null-B0rPgE5_.cjs';
1
+ import { R as RunnerContext, N as NormalizedEvent, C as ContactAdapter, a as Contact, A as AdapterFilter, M as MailProvider, S as SendArgs, b as SendResult, c as MailTesterFeedback, d as Mailer, T as TemplateDoc, e as SuppressionScope, D as DeliveryWindow, F as FlowStep, f as SegmentFilter, P as Predicate } from './null-BCxlHRJ0.cjs';
2
+ export { g as AuditLogDoc, B as BroadcastDoc, h as BroadcastStatus, i as CircuitBreakerThresholds, j as Collections, k as ContactTagDoc, E as EventDoc, l as FlowDoc, m as FlowGoal, n as FlowRunDoc, o as FlowRunStatus, p as FlowVersionDoc, H as HealthDoc, q as HealthStatus, L as LeadDoc, r as MailerConfig, s as NullProvider, O as OutboxDoc, t as RESERVED_VAR_KEYS, u as RedisOptions, v as SegmentDefinition, w as SendDoc, x as SendStatus, y as SenderDomainConfig, z as SenderDomainRegistry, G as SenderDomainValidation, I as SubscriptionDoc, J as SubscriptionStatus, K as SuppressionDoc, Q as SuppressionReason, U as TemplateKind, V as TemplateVersionDoc, W as VarsAdapter, X as VarsResolveInfo, Y as WebhookEventDoc, Z as defineVars, _ as ensureIndexes, $ as getCollections, a0 as validateSenderDomain, a1 as varsJsonSchema } from './null-BCxlHRJ0.cjs';
3
3
  import { ObjectId, Db, Filter } from 'mongodb';
4
4
  import { Request, Router } from 'express';
5
5
  import Handlebars from 'handlebars';
@@ -398,6 +398,6 @@ declare const DEDUPE_POLICIES: readonly DedupePolicyOption[];
398
398
  /**
399
399
  * Public exports for the `mailery` package.
400
400
  */
401
- declare const VERSION = "0.7.0";
401
+ declare const VERSION = "0.8.0";
402
402
 
403
403
  export { AdapterFilter, type AdminRouterOptions, Contact, ContactAdapter, DEDUPE_POLICIES, type DedupePolicyOption, DeliveryWindow, FLOW_STEP_KINDS, FlowStep, type FlowStepKindOption, MailProvider, Mailer, MongoContactAdapter, type MongoContactAdapterOptions, NormalizedEvent, PREDICATE_KINDS, Predicate, type PredicateKind, type PredicateKindOption, type PublicRouterOptions, SEGMENT_FILTER_KINDS, SegmentFilter, type SegmentFilterKind, type SegmentFilterKindOption, SendArgs, SendGridProvider, type SendGridProviderOptions, SendResult, SuppressionScope, TemplateDoc, VERSION, applyTracking, applyWebhookEvent, compileMailyTemplate, compileTemplate, computeDeliveryTime, createAdminRouter, createPublicRouter, defaultFlowStep, defaultPredicate, defaultSegmentFilter, derivePlaintext, dispatchSend, predicateKind, processNewlyFiredEventTriggers, processOneRunStep, renderTemplate, runTick, sha256Hex, signUnsubscribeToken, sweepStrandedFlowRuns, verifyUnsubscribeToken };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RunnerContext, N as NormalizedEvent, C as ContactAdapter, a as Contact, A as AdapterFilter, M as MailProvider, S as SendArgs, b as SendResult, c as MailTesterFeedback, d as Mailer, T as TemplateDoc, e as SuppressionScope, D as DeliveryWindow, F as FlowStep, f as SegmentFilter, P as Predicate } from './null-B0rPgE5_.js';
2
- export { g as AuditLogDoc, B as BroadcastDoc, h as BroadcastStatus, i as CircuitBreakerThresholds, j as Collections, k as ContactTagDoc, E as EventDoc, l as FlowDoc, m as FlowGoal, n as FlowRunDoc, o as FlowRunStatus, p as FlowVersionDoc, H as HealthDoc, q as HealthStatus, L as LeadDoc, r as MailerConfig, s as NullProvider, O as OutboxDoc, t as RESERVED_VAR_KEYS, u as RedisOptions, v as SegmentDefinition, w as SendDoc, x as SendStatus, y as SenderDomainConfig, z as SenderDomainRegistry, G as SenderDomainValidation, I as SubscriptionDoc, J as SubscriptionStatus, K as SuppressionDoc, Q as SuppressionReason, U as TemplateKind, V as TemplateVersionDoc, W as VarsAdapter, X as VarsResolveInfo, Y as WebhookEventDoc, Z as defineVars, _ as ensureIndexes, $ as getCollections, a0 as validateSenderDomain, a1 as varsJsonSchema } from './null-B0rPgE5_.js';
1
+ import { R as RunnerContext, N as NormalizedEvent, C as ContactAdapter, a as Contact, A as AdapterFilter, M as MailProvider, S as SendArgs, b as SendResult, c as MailTesterFeedback, d as Mailer, T as TemplateDoc, e as SuppressionScope, D as DeliveryWindow, F as FlowStep, f as SegmentFilter, P as Predicate } from './null-BCxlHRJ0.js';
2
+ export { g as AuditLogDoc, B as BroadcastDoc, h as BroadcastStatus, i as CircuitBreakerThresholds, j as Collections, k as ContactTagDoc, E as EventDoc, l as FlowDoc, m as FlowGoal, n as FlowRunDoc, o as FlowRunStatus, p as FlowVersionDoc, H as HealthDoc, q as HealthStatus, L as LeadDoc, r as MailerConfig, s as NullProvider, O as OutboxDoc, t as RESERVED_VAR_KEYS, u as RedisOptions, v as SegmentDefinition, w as SendDoc, x as SendStatus, y as SenderDomainConfig, z as SenderDomainRegistry, G as SenderDomainValidation, I as SubscriptionDoc, J as SubscriptionStatus, K as SuppressionDoc, Q as SuppressionReason, U as TemplateKind, V as TemplateVersionDoc, W as VarsAdapter, X as VarsResolveInfo, Y as WebhookEventDoc, Z as defineVars, _ as ensureIndexes, $ as getCollections, a0 as validateSenderDomain, a1 as varsJsonSchema } from './null-BCxlHRJ0.js';
3
3
  import { ObjectId, Db, Filter } from 'mongodb';
4
4
  import { Request, Router } from 'express';
5
5
  import Handlebars from 'handlebars';
@@ -398,6 +398,6 @@ declare const DEDUPE_POLICIES: readonly DedupePolicyOption[];
398
398
  /**
399
399
  * Public exports for the `mailery` package.
400
400
  */
401
- declare const VERSION = "0.7.0";
401
+ declare const VERSION = "0.8.0";
402
402
 
403
403
  export { AdapterFilter, type AdminRouterOptions, Contact, ContactAdapter, DEDUPE_POLICIES, type DedupePolicyOption, DeliveryWindow, FLOW_STEP_KINDS, FlowStep, type FlowStepKindOption, MailProvider, Mailer, MongoContactAdapter, type MongoContactAdapterOptions, NormalizedEvent, PREDICATE_KINDS, Predicate, type PredicateKind, type PredicateKindOption, type PublicRouterOptions, SEGMENT_FILTER_KINDS, SegmentFilter, type SegmentFilterKind, type SegmentFilterKindOption, SendArgs, SendGridProvider, type SendGridProviderOptions, SendResult, SuppressionScope, TemplateDoc, VERSION, applyTracking, applyWebhookEvent, compileMailyTemplate, compileTemplate, computeDeliveryTime, createAdminRouter, createPublicRouter, defaultFlowStep, defaultPredicate, defaultSegmentFilter, derivePlaintext, dispatchSend, predicateKind, processNewlyFiredEventTriggers, processOneRunStep, renderTemplate, runTick, sha256Hex, signUnsubscribeToken, sweepStrandedFlowRuns, verifyUnsubscribeToken };
package/dist/index.js CHANGED
@@ -1914,6 +1914,10 @@ async function dispatchSend(sendId, ctx) {
1914
1914
  await markFailed(send._id, `provider_unknown: ${send.provider}`, ctx);
1915
1915
  return;
1916
1916
  }
1917
+ const headers = send.kind === "marketing" ? {
1918
+ "List-Unsubscribe": `<${renderCtx.unsubscribeUrl}>`,
1919
+ "List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
1920
+ } : {};
1917
1921
  try {
1918
1922
  const result = await provider.send({
1919
1923
  to: send.emailAtSend,
@@ -1923,10 +1927,7 @@ async function dispatchSend(sendId, ctx) {
1923
1927
  subject: rendered.subject,
1924
1928
  html: tracking.html,
1925
1929
  text: rendered.plainText,
1926
- headers: {
1927
- "List-Unsubscribe": `<${renderCtx.unsubscribeUrl}>`,
1928
- "List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
1929
- },
1930
+ headers,
1930
1931
  messageMeta: { sendId: String(send._id) }
1931
1932
  });
1932
1933
  await ctx.collections.sends.updateOne(
@@ -5053,7 +5054,7 @@ async function checkPostalAddress(mailer) {
5053
5054
  label: "CAN-SPAM postal address",
5054
5055
  severity: "warn",
5055
5056
  message: `${marketingCount} published marketing template${marketingCount === 1 ? "" : "s"} but senderAddress is unset`,
5056
- hint: "CAN-SPAM requires a postal address in marketing emails. Set `senderAddress` in your Mailer config and reference it via `{{senderAddress}}` in your templates."
5057
+ hint: "CAN-SPAM requires a postal address in marketing emails. Set `senderAddress` in your Mailer config and reference the `{{senderAddress}}` render variable in your templates."
5057
5058
  };
5058
5059
  }
5059
5060
  async function checkDoiTemplate(mailer) {
@@ -5347,19 +5348,30 @@ async function persistScore(ctx, input) {
5347
5348
  }
5348
5349
  async function evaluateMailTesterGate(ctx, input) {
5349
5350
  const cfg = ctx.config.mailTester;
5350
- if (!cfg?.apiKey) return { allowed: true, reason: null, score: null };
5351
+ if (!cfg?.apiKey) return { allowed: true, reason: null, score: null, code: null };
5351
5352
  const minScore = cfg.minScore ?? 8;
5352
5353
  const key = mailTesterContentKey(input);
5353
5354
  const cached = await findCachedScore(ctx, key);
5354
- if (!cached) return { allowed: true, reason: null, score: null };
5355
+ if (!cached) {
5356
+ if (cfg.requireScore) {
5357
+ return {
5358
+ allowed: false,
5359
+ reason: "No Mail-Tester score for this exact content. Run a deliverability check before publishing.",
5360
+ score: null,
5361
+ code: "no_score"
5362
+ };
5363
+ }
5364
+ return { allowed: true, reason: null, score: null, code: null };
5365
+ }
5355
5366
  if (cached.score < minScore) {
5356
5367
  return {
5357
5368
  allowed: false,
5358
5369
  reason: `Mail-Tester score ${cached.score.toFixed(1)} is below minimum ${minScore.toFixed(1)}`,
5359
- score: cached
5370
+ score: cached,
5371
+ code: "low_score"
5360
5372
  };
5361
5373
  }
5362
- return { allowed: true, reason: null, score: cached };
5374
+ return { allowed: true, reason: null, score: cached, code: null };
5363
5375
  }
5364
5376
 
5365
5377
  // src/server/api/admin.ts
@@ -6353,6 +6365,7 @@ function apiRouter(mailer, opts = {}) {
6353
6365
  res.json({
6354
6366
  configured,
6355
6367
  minScore: cfg?.minScore ?? 8,
6368
+ requireScore: !!cfg?.requireScore,
6356
6369
  cacheHours: cfg?.cacheHours ?? 24,
6357
6370
  score: cached
6358
6371
  });
@@ -6567,9 +6580,10 @@ function apiRouter(mailer, opts = {}) {
6567
6580
  if (!gate.allowed) {
6568
6581
  return res.status(422).json({
6569
6582
  error: "mail_tester_blocked",
6583
+ code: gate.code,
6570
6584
  message: gate.reason,
6571
6585
  score: gate.score,
6572
- hint: "Re-run the deliverability check after fixing the feedback, or POST `bypassMailTester: true` to publish anyway."
6586
+ hint: gate.code === "no_score" ? "POST to `/templates/:slug/mail-tester-check`, poll `/mail-tester-result`, then publish \u2014 or POST `bypassMailTester: true` to publish anyway." : "Re-run the deliverability check after fixing the feedback, or POST `bypassMailTester: true` to publish anyway."
6573
6587
  });
6574
6588
  }
6575
6589
  }
@@ -7377,7 +7391,7 @@ var DEDUPE_POLICIES = [
7377
7391
  ];
7378
7392
 
7379
7393
  // src/server/index.ts
7380
- var VERSION = "0.7.0";
7394
+ var VERSION = "0.8.0";
7381
7395
 
7382
7396
  export { DEDUPE_POLICIES, FLOW_STEP_KINDS, Mailer, MongoContactAdapter, NullProvider, PREDICATE_KINDS, RESERVED_VAR_KEYS, SEGMENT_FILTER_KINDS, SendGridProvider, VERSION, applyTracking, applyWebhookEvent, compileMailyTemplate, compileTemplate, computeDeliveryTime, createAdminRouter, createPublicRouter, defaultFlowStep, defaultPredicate, defaultSegmentFilter, defineVars, derivePlaintext, dispatchSend, ensureIndexes, getCollections, predicateKind, processNewlyFiredEventTriggers, processOneRunStep, renderTemplate, runTick, sha256Hex, signUnsubscribeToken, sweepStrandedFlowRuns, validateSenderDomain, varsJsonSchema, verifyUnsubscribeToken };
7383
7397
  //# sourceMappingURL=index.js.map