@softure-ai/mailing 0.1.11 → 0.1.12

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.
Files changed (91) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +173 -6
  3. package/dist/cli/run.d.ts +1 -1
  4. package/dist/cli/run.d.ts.map +1 -1
  5. package/dist/cli/run.js +176 -24
  6. package/dist/cli/run.js.map +1 -1
  7. package/dist/contract.d.ts +5 -3
  8. package/dist/contract.d.ts.map +1 -1
  9. package/dist/index.d.ts +3 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/next/index.d.ts +3 -1
  13. package/dist/next/index.d.ts.map +1 -1
  14. package/dist/next/index.js +3 -1
  15. package/dist/next/index.js.map +1 -1
  16. package/dist/next/pages.d.ts +25 -0
  17. package/dist/next/pages.d.ts.map +1 -1
  18. package/dist/next/pages.js +33 -10
  19. package/dist/next/pages.js.map +1 -1
  20. package/dist/next/preview-mail.d.ts +5 -0
  21. package/dist/next/preview-mail.d.ts.map +1 -0
  22. package/dist/next/preview-mail.js +8 -0
  23. package/dist/next/preview-mail.js.map +1 -0
  24. package/dist/next/run-deliveries.d.ts +4 -0
  25. package/dist/next/run-deliveries.d.ts.map +1 -0
  26. package/dist/next/run-deliveries.js +7 -0
  27. package/dist/next/run-deliveries.js.map +1 -0
  28. package/dist/options.d.ts +3 -1
  29. package/dist/options.d.ts.map +1 -1
  30. package/dist/options.js +16 -1
  31. package/dist/options.js.map +1 -1
  32. package/dist/server/campaign-file.d.ts +7 -2
  33. package/dist/server/campaign-file.d.ts.map +1 -1
  34. package/dist/server/campaign-file.js +35 -15
  35. package/dist/server/campaign-file.js.map +1 -1
  36. package/dist/server/campaigns.d.ts.map +1 -1
  37. package/dist/server/campaigns.js +4 -4
  38. package/dist/server/campaigns.js.map +1 -1
  39. package/dist/server/deliveries.d.ts +19 -0
  40. package/dist/server/deliveries.d.ts.map +1 -1
  41. package/dist/server/deliveries.js +29 -0
  42. package/dist/server/deliveries.js.map +1 -1
  43. package/dist/server/dns.d.ts +15 -1
  44. package/dist/server/dns.d.ts.map +1 -1
  45. package/dist/server/dns.js +45 -4
  46. package/dist/server/dns.js.map +1 -1
  47. package/dist/server/index.d.ts +6 -4
  48. package/dist/server/index.d.ts.map +1 -1
  49. package/dist/server/index.js +6 -4
  50. package/dist/server/index.js.map +1 -1
  51. package/dist/server/operator-output.d.ts +5 -0
  52. package/dist/server/operator-output.d.ts.map +1 -0
  53. package/dist/server/operator-output.js +19 -0
  54. package/dist/server/operator-output.js.map +1 -0
  55. package/dist/server/options.d.ts +2 -0
  56. package/dist/server/options.d.ts.map +1 -1
  57. package/dist/server/options.js +5 -0
  58. package/dist/server/options.js.map +1 -1
  59. package/dist/server/run-deliveries.d.ts +55 -0
  60. package/dist/server/run-deliveries.d.ts.map +1 -0
  61. package/dist/server/run-deliveries.js +132 -0
  62. package/dist/server/run-deliveries.js.map +1 -0
  63. package/dist/server/send-mail.d.ts +21 -2
  64. package/dist/server/send-mail.d.ts.map +1 -1
  65. package/dist/server/send-mail.js +50 -30
  66. package/dist/server/send-mail.js.map +1 -1
  67. package/dist/server/suppressions.d.ts +5 -0
  68. package/dist/server/suppressions.d.ts.map +1 -1
  69. package/dist/server/suppressions.js +27 -1
  70. package/dist/server/suppressions.js.map +1 -1
  71. package/migrations/0005_add_sql_surface.sql +44 -0
  72. package/module.json +1 -1
  73. package/package.json +1 -1
  74. package/src/cli/run.ts +179 -24
  75. package/src/contract.ts +9 -3
  76. package/src/index.ts +1 -1
  77. package/src/next/index.ts +3 -1
  78. package/src/next/pages.tsx +69 -14
  79. package/src/next/preview-mail.ts +9 -0
  80. package/src/next/run-deliveries.ts +10 -0
  81. package/src/options.ts +18 -1
  82. package/src/server/campaign-file.ts +36 -2
  83. package/src/server/campaigns.ts +5 -5
  84. package/src/server/deliveries.ts +33 -0
  85. package/src/server/dns.ts +60 -4
  86. package/src/server/index.ts +7 -3
  87. package/src/server/operator-output.ts +20 -0
  88. package/src/server/options.ts +6 -0
  89. package/src/server/run-deliveries.ts +184 -0
  90. package/src/server/send-mail.ts +63 -37
  91. package/src/server/suppressions.ts +28 -1
@@ -5,8 +5,10 @@ export { unsubscribeAction } from "./actions.js";
5
5
  export { deliverOnce } from "./deliver-once.js";
6
6
  export { importDeliveries } from "./import-deliveries.js";
7
7
  export { getMailingMessages } from "./messages.js";
8
- export { UnsubscribePage } from "./pages.js";
8
+ export { createUnsubscribePage, UnsubscribePage } from "./pages.js";
9
+ export { previewMail } from "./preview-mail.js";
9
10
  export { UNSUBSCRIBE_STATUS_PARAM } from "./params.js";
10
11
  export { getUnsubscribeRoute, postUnsubscribeRoute } from "./route.js";
12
+ export { runDeliveries } from "./run-deliveries.js";
11
13
  export { sendMail } from "./send-mail.js";
12
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,0FAA0F;AAC1F,mCAAmC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAA6B,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAA0B,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,0FAA0F;AAC1F,mCAAmC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAiH,MAAM,YAAY,CAAC;AACnL,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAA0B,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,7 +1,32 @@
1
+ import { type ClassNames } from "@softure-ai/ui";
2
+ import type { ComponentType, ReactNode } from "react";
1
3
  type SearchParams = Promise<Record<string, string | string[] | undefined>>;
2
4
  export interface UnsubscribePageProps {
3
5
  readonly searchParams?: SearchParams;
4
6
  }
7
+ /** The page's parts an app can style: the `main` wrapper, the card, the form and the submit button. */
8
+ export type UnsubscribePageSlot = "root" | "card" | "form" | "submit";
9
+ /** What a custom layout receives: the page's copy, and the form (none on the outcome pages). */
10
+ export interface UnsubscribeLayoutProps {
11
+ readonly title: string;
12
+ readonly lead: string;
13
+ readonly children?: ReactNode;
14
+ }
15
+ export interface UnsubscribePageOptions {
16
+ /** Classes per slot, added to the defaults (or alone with `unstyled`). */
17
+ readonly classNames?: ClassNames<UnsubscribePageSlot>;
18
+ readonly unstyled?: boolean;
19
+ /**
20
+ * Replaces the `main` wrapper and the card, e.g. with the app's header and footer around the copy; the `root` and
21
+ * `card` classes then do not apply. The form inside stays the module's.
22
+ */
23
+ readonly Layout?: ComponentType<UnsubscribeLayoutProps>;
24
+ }
25
+ /**
26
+ * The unsubscribe page with the app's classes or layout:
27
+ * `export default createUnsubscribePage({ classNames: { root: "app-narrow" }, Layout: AppShell })`.
28
+ */
29
+ export declare function createUnsubscribePage(options?: UnsubscribePageOptions): ({ searchParams }: UnsubscribePageProps) => Promise<import("react").JSX.Element>;
5
30
  export declare function UnsubscribePage({ searchParams }: UnsubscribePageProps): Promise<import("react").JSX.Element>;
6
31
  export {};
7
32
  //# sourceMappingURL=pages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/next/pages.tsx"],"names":[],"mappings":"AAeA,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC;AAyBD,wBAAsB,eAAe,CAAC,EAAE,YAAY,EAAE,EAAE,oBAAoB,wCA2B3E"}
1
+ {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/next/pages.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAkD,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjG,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMtD,KAAK,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC;AAED,uGAAuG;AACvG,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEtE,gGAAgG;AAChG,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,mBAAmB,CAAC,CAAC;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;CACzD;AA2CD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,IACvB,kBAAkB,oBAAoB,0CAGxF;AAED,wBAAsB,eAAe,CAAC,EAAE,YAAY,EAAE,EAAE,oBAAoB,wCAE3E"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // The unsubscribe page, ready to mount with one line:
3
3
  // `export { UnsubscribePage as default } from "@softure-ai/mailing/next"`.
4
4
  // A server component without client JavaScript: the button is a plain form posting a server
@@ -7,36 +7,59 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
7
  // module's signed links and, with `mailing({ legacyUnsubscribe })`, the app's older ones: mount it
8
8
  // at the old links' path too.
9
9
  import { getSoftureConfig } from "@softure-ai/core/next";
10
- import { Button, Card, FormError } from "@softure-ai/ui";
10
+ import { Button, Card, createSlotClassGetter, FormError } from "@softure-ai/ui";
11
11
  import { getUnsubscribeLinkParams, readUnsubscribeLink } from "../server/unsubscribe-link.js";
12
12
  import { unsubscribeAction } from "./actions.js";
13
13
  import { getMailingMessages } from "./messages.js";
14
14
  import { UNSUBSCRIBE_STATUS_PARAM } from "./params.js";
15
- const LAYOUT_CLASS = "sft:mx-auto sft:box-border sft:w-full sft:sm:max-w-md sft:px-4 sft:py-4";
16
- const FORM_CLASS = "sft:flex sft:flex-col sft:gap-3 sft:font-sans";
15
+ const DEFAULT_CLASSES = {
16
+ root: "sft:mx-auto sft:box-border sft:w-full sft:sm:max-w-md sft:px-4 sft:py-4",
17
+ card: "",
18
+ form: "sft:flex sft:flex-col sft:gap-3 sft:font-sans",
19
+ submit: "",
20
+ };
17
21
  function readParam(params, name) {
18
22
  const value = params[name];
19
23
  return Array.isArray(value) ? value[0] : value;
20
24
  }
21
25
  /**
22
26
  * The link's token stays out of other sites' Referer headers; `same-origin` (not `no-referrer`)
23
- * keeps the Origin header Next checks on server actions.
27
+ * keeps the Origin header Next checks on server actions. The tag is rendered whatever the layout.
24
28
  */
25
- function UnsubscribeLayout({ title, lead, children }) {
26
- return (_jsxs("main", { className: LAYOUT_CLASS, children: [_jsx("meta", { name: "referrer", content: "same-origin" }), _jsx(Card, { title: title, subtitle: lead, children: children })] }));
29
+ function UnsubscribeLayout({ title, lead, children, slot, options }) {
30
+ const { Layout } = options;
31
+ if (Layout !== undefined) {
32
+ return (_jsxs(_Fragment, { children: [_jsx("meta", { name: "referrer", content: "same-origin" }), _jsx(Layout, { title: title, lead: lead, children: children })] }));
33
+ }
34
+ const card = slot("card");
35
+ return (_jsxs("main", { className: slot("root"), children: [_jsx("meta", { name: "referrer", content: "same-origin" }), _jsx(Card, { title: title, subtitle: lead, unstyled: options.unstyled, ...(card === undefined ? {} : { classNames: { root: card } }), children: children })] }));
36
+ }
37
+ /**
38
+ * The unsubscribe page with the app's classes or layout:
39
+ * `export default createUnsubscribePage({ classNames: { root: "app-narrow" }, Layout: AppShell })`.
40
+ */
41
+ export function createUnsubscribePage(options = {}) {
42
+ return async function UnsubscribePageWithOptions({ searchParams }) {
43
+ return renderUnsubscribePage(searchParams, options);
44
+ };
27
45
  }
28
46
  export async function UnsubscribePage({ searchParams }) {
47
+ return renderUnsubscribePage(searchParams, {});
48
+ }
49
+ async function renderUnsubscribePage(searchParams, options) {
29
50
  const config = getSoftureConfig();
30
51
  const messages = getMailingMessages(config).unsubscribe;
52
+ const slot = createSlotClassGetter({ defaults: DEFAULT_CLASSES, classNames: options.classNames, unstyled: options.unstyled });
31
53
  const params = (await searchParams) ?? {};
32
54
  const status = readParam(params, UNSUBSCRIBE_STATUS_PARAM);
33
55
  if (status === "done")
34
- return _jsx(UnsubscribeLayout, { title: messages.doneTitle, lead: messages.doneBody });
56
+ return _jsx(UnsubscribeLayout, { title: messages.doneTitle, lead: messages.doneBody, slot: slot, options: options });
35
57
  const link = readUnsubscribeLink({ get: (name) => readParam(params, name) ?? null }, config);
36
58
  const linkParams = link === null ? {} : getUnsubscribeLinkParams(link);
37
59
  if (status === "invalid" || link === null || Object.values(linkParams).some((value) => value === "")) {
38
- return _jsx(UnsubscribeLayout, { title: messages.invalidTitle, lead: messages.invalidBody });
60
+ return _jsx(UnsubscribeLayout, { title: messages.invalidTitle, lead: messages.invalidBody, slot: slot, options: options });
39
61
  }
40
- return (_jsx(UnsubscribeLayout, { title: messages.title, lead: messages.lead, children: _jsxs("form", { action: unsubscribeAction, className: FORM_CLASS, children: [Object.entries(linkParams).map(([name, value]) => (_jsx("input", { type: "hidden", name: name, value: value }, name))), _jsx(FormError, { message: status === "failed" ? messages.failed : undefined }), _jsx("div", { children: _jsx(Button, { type: "submit", variant: "primary", children: messages.submit }) })] }) }));
62
+ const submit = slot("submit");
63
+ return (_jsx(UnsubscribeLayout, { title: messages.title, lead: messages.lead, slot: slot, options: options, children: _jsxs("form", { action: unsubscribeAction, className: slot("form"), children: [Object.entries(linkParams).map(([name, value]) => (_jsx("input", { type: "hidden", name: name, value: value }, name))), _jsx(FormError, { message: status === "failed" ? messages.failed : undefined, unstyled: options.unstyled }), _jsx("div", { children: _jsx(Button, { type: "submit", variant: "primary", unstyled: options.unstyled, ...(submit === undefined ? {} : { classNames: { root: submit } }), children: messages.submit }) })] }) }));
41
64
  }
42
65
  //# sourceMappingURL=pages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/next/pages.tsx"],"names":[],"mappings":";AAAA,sDAAsD;AACtD,2EAA2E;AAC3E,4FAA4F;AAC5F,iGAAiG;AACjG,2FAA2F;AAC3F,mGAAmG;AACnG,8BAA8B;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAQvD,MAAM,YAAY,GAAG,yEAAyE,CAAC;AAC/F,MAAM,UAAU,GAAG,+CAA+C,CAAC;AAEnE,SAAS,SAAS,CAAC,MAAqD,EAAE,IAAY;IACpF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACjD,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAyD;IACzG,OAAO,CACL,gBAAM,SAAS,EAAE,YAAY,aAC3B,eAAM,IAAI,EAAC,UAAU,EAAC,OAAO,EAAC,aAAa,GAAG,EAC9C,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,YAC/B,QAAQ,GACJ,IACF,CACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAE,YAAY,EAAwB;IAC1E,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC;IACxD,MAAM,MAAM,GAAG,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAC3D,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,KAAC,iBAAiB,IAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,GAAI,CAAC;IAExG,MAAM,IAAI,GAAG,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7F,MAAM,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC;IACvE,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,EAAE,CAAC;QACrG,OAAO,KAAC,iBAAiB,IAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,WAAW,GAAI,CAAC;IACzF,CAAC;IACD,OAAO,CACL,KAAC,iBAAiB,IAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,YAC3D,gBAAM,MAAM,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,aACnD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CACjD,gBAAkB,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,IAA5C,IAAI,CAA4C,CAC7D,CAAC,EACF,KAAC,SAAS,IAAC,OAAO,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,GAAI,EACzE,wBACE,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAC,SAAS,YACpC,QAAQ,CAAC,MAAM,GACT,GACL,IACD,GACW,CACrB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/next/pages.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { OutgoingMail } from "../contract.js";
2
+ import { type MailPreviewResult, type PreviewMailOptions } from "../server/send-mail.js";
3
+ /** What `sendMail` would hand the provider for `mail`; see `previewMail` in `@softure-ai/mailing/server`. */
4
+ export declare function previewMail(mail: OutgoingMail, options?: PreviewMailOptions): MailPreviewResult;
5
+ //# sourceMappingURL=preview-mail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-mail.d.ts","sourceRoot":"","sources":["../../src/next/preview-mail.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAwC,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE/H,6GAA6G;AAC7G,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,GAAE,kBAAuB,GAAG,iBAAiB,CAEnG"}
@@ -0,0 +1,8 @@
1
+ // `previewMail` on the app's registered configuration, e.g. for an admin page that shows a mail before it goes out.
2
+ import { getSoftureConfig } from "@softure-ai/core/next";
3
+ import { previewMail as previewMailWithConfig } from "../server/send-mail.js";
4
+ /** What `sendMail` would hand the provider for `mail`; see `previewMail` in `@softure-ai/mailing/server`. */
5
+ export function previewMail(mail, options = {}) {
6
+ return previewMailWithConfig(getSoftureConfig(), mail, options);
7
+ }
8
+ //# sourceMappingURL=preview-mail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-mail.js","sourceRoot":"","sources":["../../src/next/preview-mail.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,WAAW,IAAI,qBAAqB,EAAmD,MAAM,wBAAwB,CAAC;AAE/H,6GAA6G;AAC7G,MAAM,UAAU,WAAW,CAAC,IAAkB,EAAE,UAA8B,EAAE;IAC9E,OAAO,qBAAqB,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DeliveryRunInput, DeliveryRunSummary, RunDeliveriesOptions } from "../server/run-deliveries.js";
2
+ /** Delivers one mail per recipient through the ledger; see `runDeliveries` in `@softure-ai/mailing/server`. */
3
+ export declare function runDeliveries<Recipient>(input: DeliveryRunInput<Recipient>, options?: RunDeliveriesOptions): Promise<DeliveryRunSummary>;
4
+ //# sourceMappingURL=run-deliveries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-deliveries.d.ts","sourceRoot":"","sources":["../../src/next/run-deliveries.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAI9G,+GAA+G;AAC/G,wBAAsB,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,gBAAgB,CAAC,SAAS,CAAC,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAElJ"}
@@ -0,0 +1,7 @@
1
+ import { runDeliveries as runDeliveriesWithContext } from "../server/run-deliveries.js";
2
+ import { getMailingContext } from "./context.js";
3
+ /** Delivers one mail per recipient through the ledger; see `runDeliveries` in `@softure-ai/mailing/server`. */
4
+ export async function runDeliveries(input, options = {}) {
5
+ return runDeliveriesWithContext(await getMailingContext(), input, options);
6
+ }
7
+ //# sourceMappingURL=run-deliveries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-deliveries.js","sourceRoot":"","sources":["../../src/next/run-deliveries.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,+GAA+G;AAC/G,MAAM,CAAC,KAAK,UAAU,aAAa,CAAY,KAAkC,EAAE,UAAgC,EAAE;IACnH,OAAO,wBAAwB,CAAC,MAAM,iBAAiB,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAC7E,CAAC"}
package/dist/options.d.ts CHANGED
@@ -16,6 +16,8 @@ export declare const DEFAULT_MAX_ATTEMPTS = 5;
16
16
  export declare const mailingOptionsSchema: z.ZodObject<{
17
17
  from: z.ZodString;
18
18
  replyTo: z.ZodOptional<z.ZodString>;
19
+ testAddress: z.ZodOptional<z.ZodString>;
20
+ kindAliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
19
21
  provider: z.ZodCustom<MailProvider, MailProvider>;
20
22
  timeoutMs: z.ZodDefault<z.ZodNumber>;
21
23
  onUnsubscribed: z.ZodOptional<z.ZodCustom<OnUnsubscribedHook, OnUnsubscribedHook>>;
@@ -30,7 +32,7 @@ export declare const mailingOptionsSchema: z.ZodObject<{
30
32
  required: string[];
31
33
  optional: string[];
32
34
  }>>;
33
- verify: z.ZodCustom<(values: Readonly<Record<string, string>>, ctx: import("@softure-ai/core").ModuleContext<import("@softure-ai/db").Queryable>) => Promise<string | null>, (values: Readonly<Record<string, string>>, ctx: import("@softure-ai/core").ModuleContext<import("@softure-ai/db").Queryable>) => Promise<string | null>>;
35
+ verify: z.ZodCustom<(values: Readonly<Record<string, string>>, ctx: import("@softure-ai/core").ModuleContext<import("@softure-ai/db").Queryable>, env: Readonly<Record<string, string | undefined>>) => Promise<string | null>, (values: Readonly<Record<string, string>>, ctx: import("@softure-ai/core").ModuleContext<import("@softure-ai/db").Queryable>, env: Readonly<Record<string, string | undefined>>) => Promise<string | null>>;
34
36
  }, z.core.$strict>>;
35
37
  oneClickInvalidLinkStatus: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<200>, z.ZodLiteral<400>]>>;
36
38
  filterCampaignRecipient: z.ZodOptional<z.ZodCustom<CampaignRecipientFilter, CampaignRecipientFilter>>;
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAqB,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE3I,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,iHAAiH;AACjH,eAAO,MAAM,sBAAsB,QAAc,CAAC;AAClD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AAC3D;;;GAGG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAiCtC,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;kBA2CiH,CAAC;AAEnJ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACvE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAqB,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE3I,eAAO,MAAM,kBAAkB,QAAS,CAAC;AACzC,iHAAiH;AACjH,eAAO,MAAM,sBAAsB,QAAc,CAAC;AAClD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AAC3D;;;GAGG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAwCtC,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqDiH,CAAC;AAEnJ,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AACvE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
package/dist/options.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // The options an app passes to `mailing({ ... })` in softure.config.ts, parsed at startup.
2
2
  import { z } from "zod";
3
- import { isMailbox, isSingleAddress } from "./address.js";
3
+ import { isMailbox, isMailKind, isSingleAddress } from "./address.js";
4
4
  export const DEFAULT_TIMEOUT_MS = 10_000;
5
5
  /** How long a delivery claim may stay open before another sender may take it over (and send again, same key). */
6
6
  export const DEFAULT_STALE_CLAIM_MS = 15 * 60_000;
@@ -31,6 +31,11 @@ const legacyUnsubscribeSchema = z.strictObject({
31
31
  verify: z.custom((value) => typeof value === "function", "must be a function"),
32
32
  });
33
33
  const HOUR_MS = 60 * 60_000;
34
+ const mailKind = z.string().refine(isMailKind, "must be a kebab-case mail kind such as newsletter");
35
+ /** Alias to kind; an alias never names a kind another alias points at, so one lookup resolves it. */
36
+ const kindAliasesSchema = z
37
+ .record(mailKind, mailKind)
38
+ .refine((aliases) => Object.keys(aliases).every((alias) => !Object.values(aliases).includes(alias)), "must not use a kind as an alias: aliases resolve in one step");
34
39
  function isMailProvider(value) {
35
40
  if (typeof value !== "object" || value === null)
36
41
  return false;
@@ -45,6 +50,16 @@ export const mailingOptionsSchema = z.strictObject({
45
50
  from: z.string().trim().refine(isMailbox, "must be an address or Name <address>, e.g. Plan <hello@example.com>"),
46
51
  /** Where replies go; may sit on another domain than `from` (DMARC does not check it). */
47
52
  replyTo: z.string().trim().refine(isSingleAddress, "must be one address, e.g. support@example.com").optional(),
53
+ /**
54
+ * The only address `softure-mail test` sends to, e.g. the operator's inbox. Without it the command refuses to send,
55
+ * so a test never reaches a customer.
56
+ */
57
+ testAddress: z.string().trim().refine(isSingleAddress, "must be one address, e.g. ops@example.com").optional(),
58
+ /**
59
+ * Short names for mail kinds in campaign files and `softure-mail test --kind`, e.g. `{ news: "newsletter" }`. The
60
+ * campaign is stored and sent under the kind the alias names.
61
+ */
62
+ kindAliases: kindAliasesSchema.optional(),
48
63
  /** The adapter that delivers mail: `resend()`, or `fakeMailProvider()` from `/testing`. */
49
64
  provider: z.custom(isMailProvider, "must be a mail provider such as resend()"),
50
65
  /** How long one send may take before it reads as `mailing.unavailable`. */
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { SoftureConfig } from "@softure-ai/core";
1
2
  /** A campaign's content, as `sendCampaign` sends it. */
2
3
  export interface CampaignContent {
3
4
  /** Kebab-case, at most 64 characters, e.g. `2026-10-launch`. Never reuse an id for other content. */
@@ -21,8 +22,12 @@ export type CampaignFileResult = {
21
22
  };
22
23
  /** Parses a content file, listing every problem at once. */
23
24
  export declare function parseCampaignFile(source: string): CampaignFileResult;
24
- /** What makes `content` unsendable as a campaign; empty when it is fine. */
25
- export declare function getCampaignProblems(content: CampaignContent): string[];
25
+ /**
26
+ * What makes `content` unsendable as a campaign; empty when it is fine. With the app's config it also refuses a
27
+ * body that carries an unsubscribe link or footer pasted from a sent mail: the module adds its own to every mail,
28
+ * and a pasted link is a credential that would let every recipient unsubscribe the person it was signed for.
29
+ */
30
+ export declare function getCampaignProblems(content: CampaignContent, config?: SoftureConfig): string[];
26
31
  /** The addresses of a recipients file: one per line; blank lines and `#` comments are skipped. */
27
32
  export declare function parseRecipientList(source: string): string[];
28
33
  //# sourceMappingURL=campaign-file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"campaign-file.d.ts","sourceRoot":"","sources":["../../src/server/campaign-file.ts"],"names":[],"mappings":"AAgBA,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAOpJ,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAmCpE;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CActE;AAED,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK3D"}
1
+ {"version":3,"file":"campaign-file.d.ts","sourceRoot":"","sources":["../../src/server/campaign-file.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAOtD,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAOpJ,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAmCpE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,EAAE,CAe9F;AA2BD,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAK3D"}
@@ -1,18 +1,7 @@
1
- // The campaign content file of `softure-mail campaign`: a frontmatter block and a plain-text body.
2
- //
3
- // ---
4
- // id: 2026-10-launch
5
- // kind: newsletter
6
- // subject: Something new in Plan
7
- // html: launch.html
8
- // ---
9
- // Hello,
10
- // ...
11
- //
12
- // `html` is optional and names a file next to the content file, rendered however the operator
13
- // likes. There is no markdown: the text body is sent as written.
14
1
  import { isMailKind, MAX_SUBJECT_LENGTH } from "../address.js";
15
2
  import { TRANSACTIONAL_KIND } from "../contract.js";
3
+ import { getMailingModule, getMailingRoutes } from "./options.js";
4
+ import { RECIPIENT_PARAM, SIGNATURE_PARAM } from "./unsubscribe-link.js";
16
5
  const FENCE = "---";
17
6
  const KEYS = new Set(["id", "kind", "subject", "html"]);
18
7
  const CAMPAIGN_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
@@ -59,8 +48,12 @@ export function parseCampaignFile(source) {
59
48
  problems.push("html: give a file name or leave the key out");
60
49
  return problems.length === 0 ? { ok: true, value: file } : { ok: false, problems };
61
50
  }
62
- /** What makes `content` unsendable as a campaign; empty when it is fine. */
63
- export function getCampaignProblems(content) {
51
+ /**
52
+ * What makes `content` unsendable as a campaign; empty when it is fine. With the app's config it also refuses a
53
+ * body that carries an unsubscribe link or footer pasted from a sent mail: the module adds its own to every mail,
54
+ * and a pasted link is a credential that would let every recipient unsubscribe the person it was signed for.
55
+ */
56
+ export function getCampaignProblems(content, config) {
64
57
  const problems = [];
65
58
  if (content.id.length > MAX_CAMPAIGN_ID_LENGTH || !CAMPAIGN_ID.test(content.id)) {
66
59
  problems.push("id: kebab-case, at most 64 characters, e.g. 2026-10-launch");
@@ -75,6 +68,33 @@ export function getCampaignProblems(content) {
75
68
  problems.push("the text body under the frontmatter is empty");
76
69
  if (content.html?.trim() === "")
77
70
  problems.push("the HTML body is empty");
71
+ if (config !== undefined)
72
+ problems.push(...getPastedFooterProblems(content, config));
73
+ return problems;
74
+ }
75
+ /** A signed pair of link parameters, raw or HTML-escaped (`&amp;`). */
76
+ const SIGNED_LINK = new RegExp(`[?&](?:amp;)?${RECIPIENT_PARAM}=[A-Za-z0-9_-]{43}&(?:amp;)?${SIGNATURE_PARAM}=`);
77
+ function getPastedFooterProblems(content, config) {
78
+ const routes = getMailingRoutes(config);
79
+ // The app's own links only: a link to another site's unsubscribe page is the author's business.
80
+ const linkMarkers = [`${config.appOrigin}${routes.unsubscribe}?`, `${config.appOrigin}${routes.oneClick}?`];
81
+ // Every locale's footer copy, the app's overrides included: a mail pasted from another locale counts too.
82
+ const footers = Object.values(getMailingModule(config).messages).map((messages) => messages.footer);
83
+ const bodies = [
84
+ ["the text body", content.text],
85
+ ["the HTML body", content.html],
86
+ ];
87
+ const problems = [];
88
+ for (const [name, body] of bodies) {
89
+ if (body === null)
90
+ continue;
91
+ if (SIGNED_LINK.test(body) || linkMarkers.some((marker) => body.includes(marker))) {
92
+ problems.push(`${name} carries an unsubscribe link; the module adds a link signed for each recipient, remove the pasted one`);
93
+ }
94
+ else if (footers.some((footer) => body.includes(footer.text) || body.includes(`${footer.htmlLead} <a `))) {
95
+ problems.push(`${name} carries the unsubscribe footer; the module adds it to every mail, remove the pasted one`);
96
+ }
97
+ }
78
98
  return problems;
79
99
  }
80
100
  /** The addresses of a recipients file: one per line; blank lines and `#` comments are skipped. */
@@ -1 +1 @@
1
- {"version":3,"file":"campaign-file.js","sourceRoot":"","sources":["../../src/server/campaign-file.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"campaign-file.js","sourceRoot":"","sources":["../../src/server/campaign-file.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"campaigns.d.ts","sourceRoot":"","sources":["../../src/server/campaigns.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"campaigns.d.ts","sourceRoot":"","sources":["../../src/server/campaigns.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,7 @@ export function getCampaignContentHash(content) {
23
23
  * database failure and for content `getCampaignProblems` refuses.
24
24
  */
25
25
  export async function registerCampaign(ctx, content) {
26
- assertCampaign(content);
26
+ assertCampaign(content, ctx.config);
27
27
  const contentHash = getCampaignContentHash(content);
28
28
  await ctx.db
29
29
  .insert(campaigns)
@@ -112,7 +112,7 @@ export async function listConfiguredCampaignRecipients(ctx, campaign) {
112
112
  */
113
113
  export async function planCampaign(ctx, input, options = {}) {
114
114
  const { campaign } = input;
115
- assertCampaign(campaign);
115
+ assertCampaign(campaign, ctx.config);
116
116
  const stored = await ctx.db.select({ contentHash: campaigns.contentHash }).from(campaigns).where(eq(campaigns.id, campaign.id)).limit(1);
117
117
  const contentChanged = stored[0] !== undefined && stored[0].contentHash !== getCampaignContentHash(campaign);
118
118
  const addresses = new Map();
@@ -167,8 +167,8 @@ async function countPending(ctx, campaign, addresses, options) {
167
167
  }
168
168
  return { done: closed.size, suppressed, filtered, uncertain, toSend };
169
169
  }
170
- function assertCampaign(content) {
171
- const problems = getCampaignProblems(content);
170
+ function assertCampaign(content, config) {
171
+ const problems = getCampaignProblems(content, config);
172
172
  if (problems.length > 0)
173
173
  throw new Error(`@softure-ai/mailing: campaign "${content.id}" cannot be sent: ${problems.join("; ")}`);
174
174
  }
@@ -1 +1 @@
1
- {"version":3,"file":"campaigns.js","sourceRoot":"","sources":["../../src/server/campaigns.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"campaigns.js","sourceRoot":"","sources":["../../src/server/campaigns.ts"],"names":[],"mappings":"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"}
@@ -83,6 +83,25 @@ export type DeliveryOutcome =
83
83
  * malformed scope or kind, and when `sendMail` throws.
84
84
  */
85
85
  export declare function deliverOnce(ctx: DeliveryContext, delivery: Delivery, options?: DeliverOptions): Promise<DeliveryOutcome>;
86
+ /** What `deliverOnce` would do with a delivery now, read without writing or sending. */
87
+ export type DeliveryForecast = {
88
+ readonly status: "send";
89
+ } | {
90
+ readonly status: "rejected";
91
+ readonly reason: "mailing.invalid_input" | "mailing.suppressed";
92
+ } | {
93
+ readonly status: "done";
94
+ } | {
95
+ readonly status: "in-flight";
96
+ } | {
97
+ readonly status: "uncertain";
98
+ };
99
+ /**
100
+ * Reads the ledger, checks the mail and, for list mail, the suppression list, as `deliverOnce` would, and writes
101
+ * and sends nothing. A provider's answer cannot be foreseen: `send` means the mail would reach it. Throws like
102
+ * `deliverOnce` for a malformed scope or kind, and on a database failure.
103
+ */
104
+ export declare function forecastDelivery(ctx: DeliveryContext, delivery: Delivery, options?: DeliverOptions): Promise<DeliveryForecast>;
86
105
  /** Lowercase letters, digits and `._:-`, at most 128 characters. */
87
106
  export declare function isDeliveryScope(scope: string): boolean;
88
107
  //# sourceMappingURL=deliveries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deliveries.d.ts","sourceRoot":"","sources":["../../src/server/deliveries.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,EAA2C,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAMzG,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,CAAC;AAKpF,MAAM,WAAW,QAAQ;IACvB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,oFAAoF;AACpF,MAAM,MAAM,gBAAgB,GAAG,0BAA0B,GAAG,wBAAwB,CAAC;AAErF,MAAM,MAAM,eAAe;AACzB,mDAAmD;AACjD;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE;AAClD,4FAA4F;GAC1F;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE;AAClG,qEAAqE;GACnE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE;AACpE,4DAA4D;GAC1D;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE;AAClC;;;GAGG;GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE;AAClC,2EAA2E;GACzE;IAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE;AAClE;;;GAGG;GACD;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnG;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6BlI;AAuBD,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtD"}
1
+ {"version":3,"file":"deliveries.d.ts","sourceRoot":"","sources":["../../src/server/deliveries.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,9 @@ import { DEFAULT_MAX_ATTEMPTS, DEFAULT_STALE_CLAIM_MS, DEFAULT_UNCERTAIN_CLAIM_M
13
13
  import { deliveries } from "../schema.js";
14
14
  import { getMailingOptions } from "./options.js";
15
15
  import { sendMail } from "./send-mail.js";
16
+ import { isSuppressed } from "./suppressions.js";
16
17
  import { getRecipientKey } from "./unsubscribe-link.js";
18
+ import { validateMail } from "./validate-mail.js";
17
19
  export { DEFAULT_MAX_ATTEMPTS, DEFAULT_STALE_CLAIM_MS, DEFAULT_UNCERTAIN_CLAIM_MS };
18
20
  const MAX_SCOPE_LENGTH = 128;
19
21
  const SCOPE = /^[a-z0-9][a-z0-9._:-]*$/;
@@ -52,6 +54,33 @@ export async function deliverOnce(ctx, delivery, options = {}) {
52
54
  await closeDelivery(ctx, fence, { status: "rejected", providerMessageId: null, reason: result.error, providerStatus });
53
55
  return { status: "rejected", reason: result.error, ...httpStatus };
54
56
  }
57
+ /**
58
+ * Reads the ledger, checks the mail and, for list mail, the suppression list, as `deliverOnce` would, and writes
59
+ * and sends nothing. A provider's answer cannot be foreseen: `send` means the mail would reach it. Throws like
60
+ * `deliverOnce` for a malformed scope or kind, and on a database failure.
61
+ */
62
+ export async function forecastDelivery(ctx, delivery, options = {}) {
63
+ const windows = resolveClaimWindows(ctx, options);
64
+ const kind = delivery.mail.kind ?? TRANSACTIONAL_KIND;
65
+ assertDelivery(delivery, kind);
66
+ const key = { scope: delivery.scope, recipientKey: getRecipientKey(delivery.mail.to) };
67
+ const rows = await ctx.db.select({ status: deliveries.status, claimedAt: deliveries.claimedAt }).from(deliveries).where(matchKey(key)).limit(1);
68
+ const row = rows[0];
69
+ if (row?.status === "sent" || row?.status === "rejected")
70
+ return { status: "done" };
71
+ if (row?.status === "claimed") {
72
+ const age = ctx.clock.now().getTime() - row.claimedAt.getTime();
73
+ if (age <= windows.staleClaimMs)
74
+ return { status: "in-flight" };
75
+ if (age > windows.uncertainClaimMs && !windows.retakeUncertain)
76
+ return { status: "uncertain" };
77
+ }
78
+ if (!validateMail(delivery.mail).ok)
79
+ return { status: "rejected", reason: "mailing.invalid_input" };
80
+ if (kind !== TRANSACTIONAL_KIND && (await isSuppressed(ctx, delivery.mail.to)))
81
+ return { status: "rejected", reason: "mailing.suppressed" };
82
+ return { status: "send" };
83
+ }
55
84
  function isHaltingCode(code) {
56
85
  return HALTING_ERROR_CODES.has(code);
57
86
  }