@endora-commerce/mod-email 0.100.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/dist/backend/entities/email-delivery.entity.d.ts +53 -0
  4. package/dist/backend/entities/email-delivery.entity.d.ts.map +1 -0
  5. package/dist/backend/entities/email-delivery.entity.js +136 -0
  6. package/dist/backend/entities/email-delivery.entity.js.map +1 -0
  7. package/dist/backend/index.d.ts +63 -0
  8. package/dist/backend/index.d.ts.map +1 -0
  9. package/dist/backend/index.js +43 -0
  10. package/dist/backend/index.js.map +1 -0
  11. package/dist/backend/resolve-smtp-url.d.ts +6 -0
  12. package/dist/backend/resolve-smtp-url.d.ts.map +1 -0
  13. package/dist/backend/resolve-smtp-url.js +24 -0
  14. package/dist/backend/resolve-smtp-url.js.map +1 -0
  15. package/dist/backend/services/email-delivery-recorder.d.ts +19 -0
  16. package/dist/backend/services/email-delivery-recorder.d.ts.map +1 -0
  17. package/dist/backend/services/email-delivery-recorder.js +51 -0
  18. package/dist/backend/services/email-delivery-recorder.js.map +1 -0
  19. package/dist/backend/services/mailer.d.ts +34 -0
  20. package/dist/backend/services/mailer.d.ts.map +1 -0
  21. package/dist/backend/services/mailer.js +29 -0
  22. package/dist/backend/services/mailer.js.map +1 -0
  23. package/dist/backend/services/recording-mailer.d.ts +35 -0
  24. package/dist/backend/services/recording-mailer.d.ts.map +1 -0
  25. package/dist/backend/services/recording-mailer.js +77 -0
  26. package/dist/backend/services/recording-mailer.js.map +1 -0
  27. package/dist/backend/services/smtp-mailer.d.ts +16 -0
  28. package/dist/backend/services/smtp-mailer.d.ts.map +1 -0
  29. package/dist/backend/services/smtp-mailer.js +40 -0
  30. package/dist/backend/services/smtp-mailer.js.map +1 -0
  31. package/dist/manifest.d.ts +169 -0
  32. package/dist/manifest.d.ts.map +1 -0
  33. package/dist/manifest.js +190 -0
  34. package/dist/manifest.js.map +1 -0
  35. package/dist/migrations/20260817T070014_email_delivery_record.d.ts +14 -0
  36. package/dist/migrations/20260817T070014_email_delivery_record.d.ts.map +1 -0
  37. package/dist/migrations/20260817T070014_email_delivery_record.js +44 -0
  38. package/dist/migrations/20260817T070014_email_delivery_record.js.map +1 -0
  39. package/dist/migrations/index.d.ts +27 -0
  40. package/dist/migrations/index.d.ts.map +1 -0
  41. package/dist/migrations/index.js +29 -0
  42. package/dist/migrations/index.js.map +1 -0
  43. package/package.json +66 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The mailer every sending module resolves: a driver plus its delivery record
3
+ * (D-59, issue #114).
4
+ *
5
+ * A decorator rather than a line in each of the seventeen call sites, for the
6
+ * reason `providePort`'s gate is a wrapper rather than a call: a record the
7
+ * transport seam writes cannot be forgotten by the module somebody adds next
8
+ * month, and a hand-placed one demonstrably was — that is how "did the customer
9
+ * get the invoice" ended up answerable only from a log.
10
+ *
11
+ * **Ordering, which is the part with a wrong answer.** The transport is called
12
+ * first and the record written after it, in both directions:
13
+ *
14
+ * - a send that succeeded is recorded, and if that write fails the recorder
15
+ * answers `null` (it never throws) so the caller still sees `sent` — the
16
+ * message did leave, and reporting otherwise would be a lie that could
17
+ * trigger a resend;
18
+ * - a send that raised is recorded as `failed` and the error is **re-thrown
19
+ * unchanged**, so every caller's own tolerance keeps deciding what a failed
20
+ * message means for the operation it followed.
21
+ *
22
+ * The other order — record first, then send — is the outbox D-58 refused: it
23
+ * buys atomicity between a business write and an enqueue that nothing here
24
+ * promises, and it costs a row that claims a message was attempted before
25
+ * anything was.
26
+ */
27
+ export class RecordingMailer {
28
+ transport;
29
+ recorder;
30
+ constructor(transport, recorder) {
31
+ this.transport = transport;
32
+ this.recorder = recorder;
33
+ }
34
+ async send(input) {
35
+ let outcome;
36
+ try {
37
+ outcome = await this.transport.send(input);
38
+ }
39
+ catch (error) {
40
+ await this.recorder.record({
41
+ ...contextOf(input),
42
+ status: 'failed',
43
+ reason: 'transport_error',
44
+ detail: error instanceof Error ? error.message : String(error),
45
+ });
46
+ throw error;
47
+ }
48
+ await this.recorder.record({
49
+ ...contextOf(input),
50
+ ...(outcome.status === 'sent'
51
+ ? { status: 'sent' }
52
+ : { status: 'suppressed', reason: outcome.reason }),
53
+ });
54
+ return outcome;
55
+ }
56
+ }
57
+ /**
58
+ * What the row keeps about the message itself.
59
+ *
60
+ * `kind` falls back to `meta.kind` because that convention predates this record
61
+ * — ten in-code builders already write it — so the fallback covers them without
62
+ * ten edits, and `unspecified` is reserved for a sender that names itself
63
+ * nowhere at all.
64
+ */
65
+ function contextOf(input) {
66
+ const metaKind = input.meta?.['kind'];
67
+ return {
68
+ messageId: input.messageId,
69
+ recipient: input.to,
70
+ kind: input.kind ?? (typeof metaKind === 'string' ? metaKind : 'unspecified'),
71
+ subject: input.subject,
72
+ ...(input.salesChannelId !== undefined ? { salesChannelId: input.salesChannelId } : {}),
73
+ ...(input.document ? { documentType: input.document.type, documentId: input.document.id } : {}),
74
+ ...(input.meta ? { context: input.meta } : {}),
75
+ };
76
+ }
77
+ //# sourceMappingURL=recording-mailer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording-mailer.js","sourceRoot":"","sources":["../../../src/backend/services/recording-mailer.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,OAAO,eAAe;IAEP;IACA;IAFnB,YACmB,SAAiB,EACjB,QAA+B;QAD/B,cAAS,GAAT,SAAS,CAAQ;QACjB,aAAQ,GAAR,QAAQ,CAAuB;IAC/C,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,KAAsB;QAC/B,IAAI,OAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACzB,GAAG,SAAS,CAAC,KAAK,CAAC;gBACnB,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,iBAAiB;gBACzB,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC/D,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACzB,GAAG,SAAS,CAAC,KAAK,CAAC;YACnB,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM;gBAC3B,CAAC,CAAC,EAAE,MAAM,EAAE,MAAe,EAAE;gBAC7B,CAAC,CAAC,EAAE,MAAM,EAAE,YAAqB,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;SAC/D,CAAC,CAAC;QACH,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED;;;;;;;GAOG;AACH,SAAS,SAAS,CAAC,KAAsB;IACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;IACtC,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,KAAK,CAAC,EAAE;QACnB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC;QAC7E,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG,CAAC,KAAK,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvF,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/F,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Mailer, MailerSendInput, MailerSendOutcome } from './mailer.js';
2
+ /**
3
+ * Production SMTP mailer using `nodemailer`. Configure via `SMTP_URL`
4
+ * (e.g. `smtps://user:pass@smtp.example.com:465` or SendGrid SMTP relay).
5
+ */
6
+ export declare class SmtpMailer implements Mailer {
7
+ private readonly transport;
8
+ constructor(smtpUrl: string);
9
+ /**
10
+ * Answers `sent` or raises. There is no suppression an SMTP relay performs on
11
+ * our behalf: `nodemailer` either hands the message over or throws, and the
12
+ * throw is what the delivery record turns into a `failed` row (D-59).
13
+ */
14
+ send(input: MailerSendInput): Promise<MailerSendOutcome>;
15
+ }
16
+ //# sourceMappingURL=smtp-mailer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smtp-mailer.d.ts","sourceRoot":"","sources":["../../../src/backend/services/smtp-mailer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE9E;;;GAGG;AACH,qBAAa,UAAW,YAAW,MAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAEf,OAAO,EAAE,MAAM;IAI3B;;;;OAIG;IACG,IAAI,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAuB/D"}
@@ -0,0 +1,40 @@
1
+ import nodemailer from 'nodemailer';
2
+ /**
3
+ * Production SMTP mailer using `nodemailer`. Configure via `SMTP_URL`
4
+ * (e.g. `smtps://user:pass@smtp.example.com:465` or SendGrid SMTP relay).
5
+ */
6
+ export class SmtpMailer {
7
+ transport;
8
+ constructor(smtpUrl) {
9
+ this.transport = nodemailer.createTransport(smtpUrl);
10
+ }
11
+ /**
12
+ * Answers `sent` or raises. There is no suppression an SMTP relay performs on
13
+ * our behalf: `nodemailer` either hands the message over or throws, and the
14
+ * throw is what the delivery record turns into a `failed` row (D-59).
15
+ */
16
+ async send(input) {
17
+ await this.transport.sendMail({
18
+ from: process.env['SMTP_FROM'] ?? process.env['MAIL_FROM'] ?? 'noreply@localhost',
19
+ to: input.to,
20
+ subject: input.subject,
21
+ text: input.text,
22
+ // Send a multipart alternative when an HTML body is provided (feature 047).
23
+ ...(input.html ? { html: input.html } : {}),
24
+ ...(input.attachments && input.attachments.length
25
+ ? {
26
+ attachments: input.attachments.map((a) => ({
27
+ filename: a.filename,
28
+ // nodemailer wants a Buffer/string; a Buffer is already one, a
29
+ // plain Uint8Array is wrapped without copying its backing memory.
30
+ content: Buffer.isBuffer(a.content) ? a.content : Buffer.from(a.content),
31
+ ...(a.contentType ? { contentType: a.contentType } : {}),
32
+ })),
33
+ }
34
+ : {}),
35
+ messageId: input.messageId,
36
+ });
37
+ return { status: 'sent' };
38
+ }
39
+ }
40
+ //# sourceMappingURL=smtp-mailer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smtp-mailer.js","sourceRoot":"","sources":["../../../src/backend/services/smtp-mailer.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,YAAY,CAAC;AAGpC;;;GAGG;AACH,MAAM,OAAO,UAAU;IACJ,SAAS,CAAC;IAE3B,YAAY,OAAe;QACzB,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,KAAsB;QAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;YAC5B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,mBAAmB;YACjF,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,4EAA4E;YAC5E,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM;gBAC/C,CAAC,CAAC;oBACE,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACzC,QAAQ,EAAE,CAAC,CAAC,QAAQ;wBACpB,+DAA+D;wBAC/D,kEAAkE;wBAClE,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;wBACxE,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;qBACzD,CAAC,CAAC;iBACJ;gBACH,CAAC,CAAC,EAAE,CAAC;YACP,SAAS,EAAE,KAAK,CAAC,SAAS;SAC3B,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Email module — manifest backfill (Module Lifecycle, feature 018).
3
+ *
4
+ * Predates the lifecycle system; this manifest is the static record
5
+ * required so the module participates in the registry. No install /
6
+ * uninstall hook today — the module's schema is owned by earlier
7
+ * platform-wide migrations.
8
+ */
9
+ export declare const manifest: {
10
+ id: string;
11
+ name: string;
12
+ version: string;
13
+ dependencies: string[];
14
+ description?: string | undefined;
15
+ acknowledgedDependencies?: {
16
+ moduleId: string;
17
+ port: string;
18
+ reason: string;
19
+ }[] | undefined;
20
+ nonBindingDependencies?: {
21
+ moduleId: string;
22
+ name: string;
23
+ kind: "contributes-to" | "degrades-without" | "refuses-without";
24
+ reason: string;
25
+ whenAbsent?: string | undefined;
26
+ }[] | undefined;
27
+ activation?: {
28
+ settingCode: string;
29
+ default: boolean;
30
+ } | {
31
+ nonDeactivatable: true;
32
+ reason: string;
33
+ } | undefined;
34
+ settings?: {
35
+ moduleCode: string;
36
+ groups: {
37
+ code: string;
38
+ name: string;
39
+ salesChannelCodes?: string[] | undefined;
40
+ isSystemProtected?: boolean | undefined;
41
+ }[];
42
+ settings: {
43
+ code: string;
44
+ name: string;
45
+ valueType: "string" | "number" | "boolean" | "json" | "string_list" | "secret" | "credential_ref";
46
+ defaultValue: unknown;
47
+ description?: string | undefined;
48
+ groupCode?: string | undefined;
49
+ previousDefaultValues?: unknown[] | undefined;
50
+ salesChannelCodes?: string[] | undefined;
51
+ enumOptions?: string[] | undefined;
52
+ configurationType?: string | undefined;
53
+ hidden?: boolean | undefined;
54
+ }[];
55
+ } | undefined;
56
+ i18n?: {
57
+ bundlesDir: string;
58
+ } | undefined;
59
+ docs?: false | {
60
+ dir: string;
61
+ } | undefined;
62
+ demo?: false | {
63
+ summary: string;
64
+ seed: (context: import("@endora-commerce/contracts").ModuleDemoContext<never>) => Promise<import("@endora-commerce/contracts").DemoSeedResult>;
65
+ reset: (context: import("@endora-commerce/contracts").ModuleDemoContext<never>) => Promise<import("@endora-commerce/contracts").DemoResetResult>;
66
+ after?: readonly string[] | undefined;
67
+ package?: string | undefined;
68
+ } | undefined;
69
+ actions?: {
70
+ id: string;
71
+ labelKey: string;
72
+ icon: "Plus" | "Sparkles" | "Settings" | "Search" | "Boxes" | "Layers" | "Menu" | "PlusCircle" | "PlusSquare" | "FilePlus" | "FolderPlus" | "Upload" | "FileUp" | "CloudUpload" | "Download" | "FileDown" | "FileText" | "BookOpen" | "Rss" | "Package" | "Tag" | "ShoppingCart" | "Receipt" | "CreditCard" | "Users" | "UserPlus" | "Inbox" | "ListChecks" | "ClipboardList" | "Image" | "Video" | "LayoutDashboard" | "PanelLeft" | "KeyRound" | "ShieldCheck" | "Edit" | "Archive" | "Box" | "Truck" | "CircleDollarSign" | "Activity" | "LineChart" | "Smartphone" | "Webhook" | "Scale" | "PlugZap" | "PercentDiamond" | "Newspaper" | "Languages" | "Eraser" | "Warehouse" | "TrendingDown" | "Bell" | "PackageOpen" | "Building2" | "Store" | "ClipboardCheck";
73
+ targetRoute: string;
74
+ keywords: string[];
75
+ weight: number;
76
+ descriptionKey?: string | undefined;
77
+ requiredPermission?: string | undefined;
78
+ }[] | undefined;
79
+ permissions?: {
80
+ code: string;
81
+ label: string;
82
+ module?: string | undefined;
83
+ description?: string | undefined;
84
+ requires?: string[] | undefined;
85
+ }[] | undefined;
86
+ transactionalEmails?: {
87
+ code: string;
88
+ name: string;
89
+ variables: {
90
+ key: string;
91
+ label: string;
92
+ sampleValue?: string | undefined;
93
+ description?: string | undefined;
94
+ }[];
95
+ description?: string | undefined;
96
+ group?: string | undefined;
97
+ }[] | undefined;
98
+ capabilities?: string[] | undefined;
99
+ exclusiveCapabilities?: {
100
+ key: string;
101
+ errorCode: string;
102
+ }[] | undefined;
103
+ errorCodes?: {
104
+ code: string;
105
+ tokens?: string[] | undefined;
106
+ }[] | undefined;
107
+ blocks?: {
108
+ name: string;
109
+ labelKey: string;
110
+ category: string;
111
+ contexts: ("email" | "invoice" | "cms" | "newsletter")[];
112
+ fields: Record<string, {
113
+ type: "number" | "object" | "array" | "text" | "textarea" | "select" | "radio" | "external" | "uuid" | "richtext";
114
+ label?: string | undefined;
115
+ required?: boolean | undefined;
116
+ options?: {
117
+ label: string;
118
+ value: string | number;
119
+ }[] | undefined;
120
+ refKind?: string | undefined;
121
+ }>;
122
+ descriptionKey?: string | undefined;
123
+ defaultProps?: Record<string, unknown> | undefined;
124
+ responsiveFields?: string[] | undefined;
125
+ previewIcon?: string | undefined;
126
+ weight?: number | undefined;
127
+ }[] | undefined;
128
+ blockCategories?: {
129
+ key: string;
130
+ titleKey: string;
131
+ contexts: ("email" | "invoice" | "cms" | "newsletter")[];
132
+ weight?: number | undefined;
133
+ visible?: boolean | undefined;
134
+ }[] | undefined;
135
+ env?: {
136
+ name: string;
137
+ describes: {
138
+ en: string;
139
+ pl: string;
140
+ };
141
+ requirement: {
142
+ kind: "required";
143
+ } | {
144
+ kind: "requiredWhen";
145
+ input: string;
146
+ equals: string;
147
+ } | {
148
+ kind: "optional";
149
+ without: {
150
+ en: string;
151
+ pl: string;
152
+ };
153
+ };
154
+ secret: boolean;
155
+ generable: boolean;
156
+ owner: {
157
+ kind: "platform";
158
+ } | {
159
+ kind: "application";
160
+ application: "admin" | "backend" | "storefront";
161
+ } | {
162
+ kind: "module";
163
+ moduleId: string;
164
+ };
165
+ consumers: ("admin" | "backend" | "storefront")[];
166
+ addressOf: "admin" | "backend" | "storefront" | null;
167
+ }[] | undefined;
168
+ };
169
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqLnB,CAAC"}
@@ -0,0 +1,190 @@
1
+ import { defineModuleManifest } from '@endora-commerce/contracts';
2
+ /**
3
+ * Email module — manifest backfill (Module Lifecycle, feature 018).
4
+ *
5
+ * Predates the lifecycle system; this manifest is the static record
6
+ * required so the module participates in the registry. No install /
7
+ * uninstall hook today — the module's schema is owned by earlier
8
+ * platform-wide migrations.
9
+ */
10
+ export const manifest = defineModuleManifest({
11
+ id: 'email',
12
+ name: 'Email',
13
+ description: 'Mailer abstraction with Console / SMTP drivers for transactional email.',
14
+ version: '1.0.0',
15
+ /**
16
+ * What this module needs from the environment (`specs/117-instance-bring-up/`
17
+ * FR-002). Only what it **owns**: its reads of platform-owned names are
18
+ * satisfied by `packages/platform/src/env/index.ts`.
19
+ *
20
+ * Why each of these is not a Setting is its entry in
21
+ * `backend/scripts/ledgers/module-environment-inputs/email.ts`.
22
+ */
23
+ env: [
24
+ {
25
+ name: 'MAIL_DRIVER',
26
+ describes: {
27
+ en: 'How outgoing mail leaves this instance; `console` writes messages to the log instead of delivering them.',
28
+ pl: 'W jaki sposób poczta wychodząca opuszcza tę instancję; wartość `console` zapisuje wiadomości do logu zamiast je wysyłać.',
29
+ },
30
+ requirement: {
31
+ kind: 'optional',
32
+ without: {
33
+ en: 'There is no way to stop a development instance from attempting real delivery to real addresses.',
34
+ pl: 'Nie ma jak powstrzymać instancji deweloperskiej przed próbą wysyłki na prawdziwe adresy.',
35
+ },
36
+ },
37
+ secret: false,
38
+ generable: false,
39
+ owner: { kind: 'module', moduleId: 'email' },
40
+ consumers: ['backend'],
41
+ addressOf: null,
42
+ },
43
+ {
44
+ name: 'SMTP_URL',
45
+ describes: {
46
+ en: 'The whole SMTP connection as one URL, credentials included.',
47
+ pl: 'Całe połączenie SMTP jako jeden adres URL, wraz z poświadczeniami.',
48
+ },
49
+ requirement: {
50
+ kind: 'optional',
51
+ without: {
52
+ en: 'The connection has to be assembled from the separate host, port, user and password variables instead.',
53
+ pl: 'Połączenie trzeba wtedy złożyć z osobnych zmiennych: hosta, portu, użytkownika i hasła.',
54
+ },
55
+ },
56
+ secret: true,
57
+ generable: false,
58
+ owner: { kind: 'module', moduleId: 'email' },
59
+ consumers: ['backend'],
60
+ addressOf: null,
61
+ },
62
+ {
63
+ name: 'SMTP_HOST',
64
+ describes: {
65
+ en: 'The host name of the SMTP relay that delivers this shop’s mail.',
66
+ pl: 'Nazwa hosta serwera SMTP, który dostarcza pocztę tego sklepu.',
67
+ },
68
+ requirement: {
69
+ kind: 'optional',
70
+ without: {
71
+ en: 'No connection can be assembled from the separate fields, so nothing is delivered unless `SMTP_URL` carries the whole connection.',
72
+ pl: 'Z osobnych pól nie da się złożyć połączenia, więc nic nie zostanie dostarczone, o ile `SMTP_URL` nie zawiera całego połączenia.',
73
+ },
74
+ },
75
+ secret: false,
76
+ generable: false,
77
+ owner: { kind: 'module', moduleId: 'email' },
78
+ consumers: ['backend'],
79
+ addressOf: null,
80
+ },
81
+ {
82
+ name: 'SMTP_PORT',
83
+ describes: {
84
+ en: 'The port the SMTP relay listens on.',
85
+ pl: 'Port, na którym nasłuchuje serwer SMTP.',
86
+ },
87
+ requirement: {
88
+ kind: 'optional',
89
+ without: {
90
+ en: 'No connection can be assembled from the separate fields, so nothing is delivered unless `SMTP_URL` carries the whole connection.',
91
+ pl: 'Z osobnych pól nie da się złożyć połączenia, więc nic nie zostanie dostarczone, o ile `SMTP_URL` nie zawiera całego połączenia.',
92
+ },
93
+ },
94
+ secret: false,
95
+ generable: false,
96
+ owner: { kind: 'module', moduleId: 'email' },
97
+ consumers: ['backend'],
98
+ addressOf: null,
99
+ },
100
+ {
101
+ name: 'SMTP_USER',
102
+ describes: {
103
+ en: 'The account this instance authenticates to the SMTP relay as.',
104
+ pl: 'Konto, na którym ta instancja uwierzytelnia się w serwerze SMTP.',
105
+ },
106
+ requirement: {
107
+ kind: 'optional',
108
+ without: {
109
+ en: 'The relay is addressed with no credentials, which a public relay refuses.',
110
+ pl: 'Serwer jest odpytywany bez poświadczeń, czego publiczny serwer odmawia.',
111
+ },
112
+ },
113
+ secret: false,
114
+ generable: false,
115
+ owner: { kind: 'module', moduleId: 'email' },
116
+ consumers: ['backend'],
117
+ addressOf: null,
118
+ },
119
+ {
120
+ name: 'SMTP_PASSWORD',
121
+ describes: {
122
+ en: 'The password for the SMTP account.',
123
+ pl: 'Hasło do konta SMTP.',
124
+ },
125
+ requirement: {
126
+ kind: 'optional',
127
+ without: {
128
+ en: 'The relay is addressed with no credentials, which a public relay refuses.',
129
+ pl: 'Serwer jest odpytywany bez poświadczeń, czego publiczny serwer odmawia.',
130
+ },
131
+ },
132
+ secret: true,
133
+ generable: false,
134
+ owner: { kind: 'module', moduleId: 'email' },
135
+ consumers: ['backend'],
136
+ addressOf: null,
137
+ },
138
+ {
139
+ name: 'SMTP_FROM',
140
+ describes: {
141
+ en: 'The address outgoing mail is sent from.',
142
+ pl: 'Adres, z którego wychodzi poczta.',
143
+ },
144
+ requirement: {
145
+ kind: 'optional',
146
+ without: {
147
+ en: 'Mail leaves under the platform’s placeholder address, which a relay commonly rejects as unroutable.',
148
+ pl: 'Poczta wychodzi spod zastępczego adresu platformy, który serwer pocztowy zwykle odrzuca jako nieroutowalny.',
149
+ },
150
+ },
151
+ secret: false,
152
+ generable: false,
153
+ owner: { kind: 'module', moduleId: 'email' },
154
+ consumers: ['backend'],
155
+ addressOf: null,
156
+ },
157
+ {
158
+ name: 'MAIL_FROM',
159
+ describes: {
160
+ en: 'The address outgoing mail is sent from, read where `SMTP_FROM` is unset.',
161
+ pl: 'Adres, z którego wychodzi poczta, odczytywany, gdy `SMTP_FROM` nie jest ustawiony.',
162
+ },
163
+ requirement: {
164
+ kind: 'optional',
165
+ without: {
166
+ en: 'Mail leaves under the platform’s placeholder address, which a relay commonly rejects as unroutable.',
167
+ pl: 'Poczta wychodzi spod zastępczego adresu platformy, który serwer pocztowy zwykle odrzuca jako nieroutowalny.',
168
+ },
169
+ },
170
+ secret: false,
171
+ generable: false,
172
+ owner: { kind: 'module', moduleId: 'email' },
173
+ consumers: ['backend'],
174
+ addressOf: null,
175
+ },
176
+ ],
177
+ dependencies: [],
178
+ // Feature 074 (Constitution XVII), test C3 — platform primitive. This module
179
+ // had no activation declaration at all, which resolved as "always activated"
180
+ // and read as an omission. It is the outbound transport every message leaves
181
+ // through: a business configures a driver — Console, SMTP — it does not
182
+ // switch the transport off, and the per-message choice belongs to
183
+ // `transactional_emails`, which offers it per email.
184
+ activation: {
185
+ nonDeactivatable: true,
186
+ reason: 'The outbound transport every message leaves through. A business configures a driver; ' +
187
+ 'it does not switch the transport off.',
188
+ },
189
+ });
190
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+ /**
3
+ * D-59 — `email_deliveries`, the first table this module owns.
4
+ *
5
+ * One row per delivery decision, deliberately the `webhook_deliveries` shape
6
+ * (see the entity): no `pending` status, no row before something was attempted,
7
+ * no foreign key — a delivery record has to survive the deletion of whatever it
8
+ * was about, which is exactly when somebody asks about it.
9
+ */
10
+ export declare class Migration20260817T070014EmailDeliveryRecord extends Migration {
11
+ up(): Promise<void>;
12
+ down(): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=20260817T070014_email_delivery_record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260817T070014_email_delivery_record.d.ts","sourceRoot":"","sources":["../../src/migrations/20260817T070014_email_delivery_record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;GAOG;AACH,qBAAa,2CAA4C,SAAQ,SAAS;IACzD,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAGrC"}
@@ -0,0 +1,44 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+ /**
3
+ * D-59 — `email_deliveries`, the first table this module owns.
4
+ *
5
+ * One row per delivery decision, deliberately the `webhook_deliveries` shape
6
+ * (see the entity): no `pending` status, no row before something was attempted,
7
+ * no foreign key — a delivery record has to survive the deletion of whatever it
8
+ * was about, which is exactly when somebody asks about it.
9
+ */
10
+ export class Migration20260817T070014EmailDeliveryRecord extends Migration {
11
+ async up() {
12
+ this.addSql(`
13
+ create table "email_deliveries" (
14
+ "id" uuid not null,
15
+ "message_id" varchar(191) not null,
16
+ "recipient" varchar(320) not null,
17
+ "kind" varchar(64) not null,
18
+ "status" varchar(16) not null,
19
+ "reason" varchar(64) null,
20
+ "detail" varchar(4000) null,
21
+ "subject" varchar(998) null,
22
+ "sales_channel_id" uuid null,
23
+ "document_type" varchar(32) null,
24
+ "document_id" varchar(64) null,
25
+ "context" jsonb null,
26
+ "attempted_at" timestamptz not null,
27
+ "created_at" timestamptz not null,
28
+ "updated_at" timestamptz not null,
29
+ constraint "email_deliveries_pkey" primary key ("id")
30
+ );
31
+ `);
32
+ this.addSql('create index "email_deliveries_message_id_index" on "email_deliveries" ("message_id");');
33
+ this.addSql('create index "email_deliveries_recipient_index" on "email_deliveries" ("recipient");');
34
+ this.addSql('create index "email_deliveries_kind_index" on "email_deliveries" ("kind");');
35
+ this.addSql('create index "email_deliveries_status_index" on "email_deliveries" ("status");');
36
+ this.addSql('create index "email_deliveries_document_type_index" on "email_deliveries" ("document_type");');
37
+ this.addSql('create index "email_deliveries_document_id_index" on "email_deliveries" ("document_id");');
38
+ this.addSql('create index "email_deliveries_attempted_at_index" on "email_deliveries" ("attempted_at");');
39
+ }
40
+ async down() {
41
+ this.addSql('drop table if exists "email_deliveries" cascade;');
42
+ }
43
+ }
44
+ //# sourceMappingURL=20260817T070014_email_delivery_record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260817T070014_email_delivery_record.js","sourceRoot":"","sources":["../../src/migrations/20260817T070014_email_delivery_record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;GAOG;AACH,MAAM,OAAO,2CAA4C,SAAQ,SAAS;IAC/D,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;KAmBX,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,wFAAwF,CAAC,CAAC;QACtG,IAAI,CAAC,MAAM,CAAC,sFAAsF,CAAC,CAAC;QACpG,IAAI,CAAC,MAAM,CAAC,4EAA4E,CAAC,CAAC;QAC1F,IAAI,CAAC,MAAM,CAAC,gFAAgF,CAAC,CAAC;QAC9F,IAAI,CAAC,MAAM,CACT,8FAA8F,CAC/F,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,0FAA0F,CAAC,CAAC;QACxG,IAAI,CAAC,MAAM,CAAC,4FAA4F,CAAC,CAAC;IAC5G,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,kDAAkD,CAAC,CAAC;IAClE,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The `./migrations` subpath — every migration class this module owns, as one
3
+ * ordered `migrations` array.
4
+ *
5
+ * The array is what the platform reads when this module is **installed**:
6
+ * `src/packages/package-runtime.ts` takes `exported['migrations']` and refuses
7
+ * the package outright when it is absent (D-168).
8
+ *
9
+ * Listed in ascending timestamp, which is the order of this module's own
10
+ * migrations and of nothing else (feature 081): a manifest `dependencies` array
11
+ * is the only thing ordering this block against another module's.
12
+ *
13
+ * The **named** exports stay beside the array, and the asymmetry with
14
+ * `./backend` — which publishes an array and no named class (D-168) — is
15
+ * deliberate. `db/migrations-registry.generated.ts` imports each class by name
16
+ * from this specifier, and a migration class name is contract in a way an entity
17
+ * class name is not: `mikro_orm_migrations` persists it, so it is a string every
18
+ * already-migrated database holds.
19
+ *
20
+ * A class that is in neither the array nor the barrel is a migration that does
21
+ * not run: `migration:pending` reports nothing pending and the first symptom is
22
+ * a query against a table nobody created.
23
+ */
24
+ import { Migration20260817T070014EmailDeliveryRecord } from './20260817T070014_email_delivery_record.js';
25
+ export declare const migrations: (typeof Migration20260817T070014EmailDeliveryRecord)[];
26
+ export { Migration20260817T070014EmailDeliveryRecord, };
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,2CAA2C,EAAE,MAAM,4CAA4C,CAAC;AAEzG,eAAO,MAAM,UAAU,wDAEtB,CAAC;AAEF,OAAO,EACL,2CAA2C,GAC5C,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The `./migrations` subpath — every migration class this module owns, as one
3
+ * ordered `migrations` array.
4
+ *
5
+ * The array is what the platform reads when this module is **installed**:
6
+ * `src/packages/package-runtime.ts` takes `exported['migrations']` and refuses
7
+ * the package outright when it is absent (D-168).
8
+ *
9
+ * Listed in ascending timestamp, which is the order of this module's own
10
+ * migrations and of nothing else (feature 081): a manifest `dependencies` array
11
+ * is the only thing ordering this block against another module's.
12
+ *
13
+ * The **named** exports stay beside the array, and the asymmetry with
14
+ * `./backend` — which publishes an array and no named class (D-168) — is
15
+ * deliberate. `db/migrations-registry.generated.ts` imports each class by name
16
+ * from this specifier, and a migration class name is contract in a way an entity
17
+ * class name is not: `mikro_orm_migrations` persists it, so it is a string every
18
+ * already-migrated database holds.
19
+ *
20
+ * A class that is in neither the array nor the barrel is a migration that does
21
+ * not run: `migration:pending` reports nothing pending and the first symptom is
22
+ * a query against a table nobody created.
23
+ */
24
+ import { Migration20260817T070014EmailDeliveryRecord } from './20260817T070014_email_delivery_record.js';
25
+ export const migrations = [
26
+ Migration20260817T070014EmailDeliveryRecord,
27
+ ];
28
+ export { Migration20260817T070014EmailDeliveryRecord, };
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,2CAA2C,EAAE,MAAM,4CAA4C,CAAC;AAEzG,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,2CAA2C;CAC5C,CAAC;AAEF,OAAO,EACL,2CAA2C,GAC5C,CAAC"}