@aglyn/shared-util-email 1.0.0-beta.285 → 1.0.0-beta.287

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aglyn/shared-util-email",
3
- "version": "1.0.0-beta.285",
3
+ "version": "1.0.0-beta.287",
4
4
  "license": "Apache-2.0",
5
5
  "homepage": "https://aglyn.com",
6
6
  "repository": {
@@ -25,8 +25,8 @@
25
25
  "./package.json": "./package.json"
26
26
  },
27
27
  "dependencies": {
28
- "@aglyn/shared-data-enums": "1.0.0-beta.285",
29
- "@aglyn/shared-util-http": "1.0.0-beta.285",
28
+ "@aglyn/shared-data-enums": "1.0.0-beta.287",
29
+ "@aglyn/shared-util-http": "1.0.0-beta.287",
30
30
  "@msgpack/msgpack": "^3.1.3",
31
31
  "@swc/helpers": "0.5.23"
32
32
  },
package/src/index.d.ts CHANGED
@@ -32,6 +32,7 @@ export * from './lib/site-care-emails';
32
32
  export * from './lib/site-care-project-emails';
33
33
  export * from './lib/domain-emails';
34
34
  export * from './lib/pos-hardware-emails';
35
+ export * from './lib/pos-cellular-emails';
35
36
  export * from './lib/welcome-email';
36
37
  export * from './lib/tenant-email-catalog';
37
38
  export * from './lib/host-email-render';
package/src/index.js CHANGED
@@ -36,6 +36,7 @@ export * from "./lib/site-care-emails.js";
36
36
  export * from "./lib/site-care-project-emails.js";
37
37
  export * from "./lib/domain-emails.js";
38
38
  export * from "./lib/pos-hardware-emails.js";
39
+ export * from "./lib/pos-cellular-emails.js";
39
40
  export * from "./lib/welcome-email.js";
40
41
  export * from "./lib/tenant-email-catalog.js";
41
42
  export * from "./lib/host-email-render.js";
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../libs/shared/util/email/src/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport * from './lib/send-email'\n// Who carries the mail (AGL-3080): the provider contract, and the selection\n// of the deployment's provider from the built-ins and any a plugin\n// registered. The providers themselves are imported by their own paths —\n// `@aglyn/shared-util-email/mail-provider-resend`, `…/mail-provider-webhook`\n// — because nothing outside the seam should name one.\nexport * from './lib/mail-provider'\nexport * from './lib/mail-providers'\nexport * from './lib/send-rate'\nexport * from './lib/sender-reputation'\nexport * from './lib/send-ceilings'\nexport * from './lib/sending-domain'\nexport * from './lib/tracking-host'\nexport * from './lib/sending-mailbox'\nexport * from './lib/host-sender'\nexport * from './lib/platform-sending-domain'\nexport * from './lib/email-health'\nexport * from './lib/system-email-catalog'\nexport * from './lib/retention-emails'\nexport * from './lib/site-care-emails'\nexport * from './lib/site-care-project-emails'\nexport * from './lib/domain-emails'\nexport * from './lib/pos-hardware-emails'\nexport * from './lib/welcome-email'\nexport * from './lib/tenant-email-catalog'\nexport * from './lib/host-email-render'\nexport * from './lib/email-render'\nexport * from './lib/text-email-html'\nexport * from './lib/marketing-send'\n// The List-Unsubscribe setting sequences and campaigns share (AGL-3307).\nexport * from './lib/list-unsubscribe'\nexport * from './lib/email-delivery-events'\n// Received mail in the platform's vocabulary, which the CRM's capture route\n// files from (AGL-2657); the provider reads it.\n// Its neighbor `./lib/svix-signature` is deliberately NOT re-exported here:\n// it holds a `crypto` HMAC, and this barrel is reached from the browser\n// through `@aglyn/shared-ui-email-campaigns`, so a webhook imports it by its\n// own path — `@aglyn/shared-util-email/svix-signature`.\nexport * from './lib/received-email'\nexport * from './lib/email-revenue-window'\n// Exported so the console drift guard can pin it against @aglyn/aglyn.\nexport * from './lib/email-media-src'\n// Same arrangement, same reason (AGL-1223): a copy of `decodeStoredNodes`\n// this scope:shared lib may not import, pinned by `email-nodes-drift.spec.ts`.\nexport * from './lib/stored-email-nodes'\nexport * from './lib/email-merge'\n// The deliverability engine every send path asks (AGL-3328): the gateway an\n// MX names and its ledger, the bounce reader, and the address verdicts. Pure\n// — the DNS lookup and the store are injected by `@aglyn/tenant-data-admin`,\n// so nothing here reaches `node:dns` from the browser.\nexport * from './lib/mail-gateway'\nexport * from './lib/mail-bounce'\nexport * from './lib/email-deliverability'\n// The sender's side of the same engine (AGL-3328): SPF, DKIM and DMARC for\n// the domain mail leaves from, and whether they align. Pure as well; the\n// lookups are `@aglyn/tenant-data-admin`'s.\nexport * from './lib/sender-readiness'\n// The outbound phishing screen a young workspace's campaigns and automated\n// email pass (AGL-3356). Pure; the hold it leads to is `tenant-data-admin`'s.\nexport * from './lib/outbound-phishing-screen'\n// The send seam's gate for that screen — the store a hold writes is injected\n// by `@aglyn/tenant-data-admin`, like the governor's.\nexport * from './lib/outbound-screen-gate'\n// The same screen read over a published page (AGL-3356): lookalike links and\n// embeds, author-defined credential fields, a brand's call to action.\nexport * from './lib/hosted-page-screen'\n// The reputation lookup every foreign link a page, an email or a redirect\n// points at passes (AGL-3451). Pure; the lookup is injected by\n// `@aglyn/tenant-data-admin`, which holds the credential and the cache.\nexport * from './lib/link-reputation'\n// The site's theme palette as plain data (AGL-3370), so a palette token an\n// author picked resolves in mail. Built without MUI; `shared-ui-theme`'s\n// parity spec holds it equal to the theme.\nexport * from './lib/email-palette'\nexport * from './lib/email-design-chrome'\n"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,cAAc,sBAAkB;AAChC,4EAA4E;AAC5E,mEAAmE;AACnE,yEAAyE;AACzE,6EAA6E;AAC7E,sDAAsD;AACtD,cAAc,yBAAqB;AACnC,cAAc,0BAAsB;AACpC,cAAc,qBAAiB;AAC/B,cAAc,6BAAyB;AACvC,cAAc,yBAAqB;AACnC,cAAc,0BAAsB;AACpC,cAAc,yBAAqB;AACnC,cAAc,2BAAuB;AACrC,cAAc,uBAAmB;AACjC,cAAc,mCAA+B;AAC7C,cAAc,wBAAoB;AAClC,cAAc,gCAA4B;AAC1C,cAAc,4BAAwB;AACtC,cAAc,4BAAwB;AACtC,cAAc,oCAAgC;AAC9C,cAAc,yBAAqB;AACnC,cAAc,+BAA2B;AACzC,cAAc,yBAAqB;AACnC,cAAc,gCAA4B;AAC1C,cAAc,6BAAyB;AACvC,cAAc,wBAAoB;AAClC,cAAc,2BAAuB;AACrC,cAAc,0BAAsB;AACpC,yEAAyE;AACzE,cAAc,4BAAwB;AACtC,cAAc,iCAA6B;AAC3C,4EAA4E;AAC5E,gDAAgD;AAChD,4EAA4E;AAC5E,wEAAwE;AACxE,6EAA6E;AAC7E,wDAAwD;AACxD,cAAc,0BAAsB;AACpC,cAAc,gCAA4B;AAC1C,uEAAuE;AACvE,cAAc,2BAAuB;AACrC,0EAA0E;AAC1E,+EAA+E;AAC/E,cAAc,8BAA0B;AACxC,cAAc,uBAAmB;AACjC,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,uDAAuD;AACvD,cAAc,wBAAoB;AAClC,cAAc,uBAAmB;AACjC,cAAc,gCAA4B;AAC1C,2EAA2E;AAC3E,yEAAyE;AACzE,4CAA4C;AAC5C,cAAc,4BAAwB;AACtC,2EAA2E;AAC3E,8EAA8E;AAC9E,cAAc,oCAAgC;AAC9C,6EAA6E;AAC7E,sDAAsD;AACtD,cAAc,gCAA4B;AAC1C,6EAA6E;AAC7E,sEAAsE;AACtE,cAAc,8BAA0B;AACxC,0EAA0E;AAC1E,+DAA+D;AAC/D,wEAAwE;AACxE,cAAc,2BAAuB;AACrC,2EAA2E;AAC3E,yEAAyE;AACzE,2CAA2C;AAC3C,cAAc,yBAAqB;AACnC,cAAc,+BAA2B"}
1
+ {"version":3,"sources":["../../../../../../libs/shared/util/email/src/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport * from './lib/send-email'\n// Who carries the mail (AGL-3080): the provider contract, and the selection\n// of the deployment's provider from the built-ins and any a plugin\n// registered. The providers themselves are imported by their own paths —\n// `@aglyn/shared-util-email/mail-provider-resend`, `…/mail-provider-webhook`\n// — because nothing outside the seam should name one.\nexport * from './lib/mail-provider'\nexport * from './lib/mail-providers'\nexport * from './lib/send-rate'\nexport * from './lib/sender-reputation'\nexport * from './lib/send-ceilings'\nexport * from './lib/sending-domain'\nexport * from './lib/tracking-host'\nexport * from './lib/sending-mailbox'\nexport * from './lib/host-sender'\nexport * from './lib/platform-sending-domain'\nexport * from './lib/email-health'\nexport * from './lib/system-email-catalog'\nexport * from './lib/retention-emails'\nexport * from './lib/site-care-emails'\nexport * from './lib/site-care-project-emails'\nexport * from './lib/domain-emails'\nexport * from './lib/pos-hardware-emails'\nexport * from './lib/pos-cellular-emails'\nexport * from './lib/welcome-email'\nexport * from './lib/tenant-email-catalog'\nexport * from './lib/host-email-render'\nexport * from './lib/email-render'\nexport * from './lib/text-email-html'\nexport * from './lib/marketing-send'\n// The List-Unsubscribe setting sequences and campaigns share (AGL-3307).\nexport * from './lib/list-unsubscribe'\nexport * from './lib/email-delivery-events'\n// Received mail in the platform's vocabulary, which the CRM's capture route\n// files from (AGL-2657); the provider reads it.\n// Its neighbor `./lib/svix-signature` is deliberately NOT re-exported here:\n// it holds a `crypto` HMAC, and this barrel is reached from the browser\n// through `@aglyn/shared-ui-email-campaigns`, so a webhook imports it by its\n// own path — `@aglyn/shared-util-email/svix-signature`.\nexport * from './lib/received-email'\nexport * from './lib/email-revenue-window'\n// Exported so the console drift guard can pin it against @aglyn/aglyn.\nexport * from './lib/email-media-src'\n// Same arrangement, same reason (AGL-1223): a copy of `decodeStoredNodes`\n// this scope:shared lib may not import, pinned by `email-nodes-drift.spec.ts`.\nexport * from './lib/stored-email-nodes'\nexport * from './lib/email-merge'\n// The deliverability engine every send path asks (AGL-3328): the gateway an\n// MX names and its ledger, the bounce reader, and the address verdicts. Pure\n// — the DNS lookup and the store are injected by `@aglyn/tenant-data-admin`,\n// so nothing here reaches `node:dns` from the browser.\nexport * from './lib/mail-gateway'\nexport * from './lib/mail-bounce'\nexport * from './lib/email-deliverability'\n// The sender's side of the same engine (AGL-3328): SPF, DKIM and DMARC for\n// the domain mail leaves from, and whether they align. Pure as well; the\n// lookups are `@aglyn/tenant-data-admin`'s.\nexport * from './lib/sender-readiness'\n// The outbound phishing screen a young workspace's campaigns and automated\n// email pass (AGL-3356). Pure; the hold it leads to is `tenant-data-admin`'s.\nexport * from './lib/outbound-phishing-screen'\n// The send seam's gate for that screen — the store a hold writes is injected\n// by `@aglyn/tenant-data-admin`, like the governor's.\nexport * from './lib/outbound-screen-gate'\n// The same screen read over a published page (AGL-3356): lookalike links and\n// embeds, author-defined credential fields, a brand's call to action.\nexport * from './lib/hosted-page-screen'\n// The reputation lookup every foreign link a page, an email or a redirect\n// points at passes (AGL-3451). Pure; the lookup is injected by\n// `@aglyn/tenant-data-admin`, which holds the credential and the cache.\nexport * from './lib/link-reputation'\n// The site's theme palette as plain data (AGL-3370), so a palette token an\n// author picked resolves in mail. Built without MUI; `shared-ui-theme`'s\n// parity spec holds it equal to the theme.\nexport * from './lib/email-palette'\nexport * from './lib/email-design-chrome'\n"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,cAAc,sBAAkB;AAChC,4EAA4E;AAC5E,mEAAmE;AACnE,yEAAyE;AACzE,6EAA6E;AAC7E,sDAAsD;AACtD,cAAc,yBAAqB;AACnC,cAAc,0BAAsB;AACpC,cAAc,qBAAiB;AAC/B,cAAc,6BAAyB;AACvC,cAAc,yBAAqB;AACnC,cAAc,0BAAsB;AACpC,cAAc,yBAAqB;AACnC,cAAc,2BAAuB;AACrC,cAAc,uBAAmB;AACjC,cAAc,mCAA+B;AAC7C,cAAc,wBAAoB;AAClC,cAAc,gCAA4B;AAC1C,cAAc,4BAAwB;AACtC,cAAc,4BAAwB;AACtC,cAAc,oCAAgC;AAC9C,cAAc,yBAAqB;AACnC,cAAc,+BAA2B;AACzC,cAAc,+BAA2B;AACzC,cAAc,yBAAqB;AACnC,cAAc,gCAA4B;AAC1C,cAAc,6BAAyB;AACvC,cAAc,wBAAoB;AAClC,cAAc,2BAAuB;AACrC,cAAc,0BAAsB;AACpC,yEAAyE;AACzE,cAAc,4BAAwB;AACtC,cAAc,iCAA6B;AAC3C,4EAA4E;AAC5E,gDAAgD;AAChD,4EAA4E;AAC5E,wEAAwE;AACxE,6EAA6E;AAC7E,wDAAwD;AACxD,cAAc,0BAAsB;AACpC,cAAc,gCAA4B;AAC1C,uEAAuE;AACvE,cAAc,2BAAuB;AACrC,0EAA0E;AAC1E,+EAA+E;AAC/E,cAAc,8BAA0B;AACxC,cAAc,uBAAmB;AACjC,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,uDAAuD;AACvD,cAAc,wBAAoB;AAClC,cAAc,uBAAmB;AACjC,cAAc,gCAA4B;AAC1C,2EAA2E;AAC3E,yEAAyE;AACzE,4CAA4C;AAC5C,cAAc,4BAAwB;AACtC,2EAA2E;AAC3E,8EAA8E;AAC9E,cAAc,oCAAgC;AAC9C,6EAA6E;AAC7E,sDAAsD;AACtD,cAAc,gCAA4B;AAC1C,6EAA6E;AAC7E,sEAAsE;AACtE,cAAc,8BAA0B;AACxC,0EAA0E;AAC1E,+DAA+D;AAC/D,wEAAwE;AACxE,cAAc,2BAAuB;AACrC,2EAA2E;AAC3E,yEAAyE;AACzE,2CAA2C;AAC3C,cAAc,yBAAqB;AACnC,cAAc,+BAA2B"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import type { SystemEmailTemplateDefinition } from './system-email-catalog';
18
+ export declare const POS_CELLULAR_EMAIL_KEYS: {
19
+ readonly paymentDue: "pos-cellular-payment-due";
20
+ readonly turnedOffUnpaid: "pos-cellular-turned-off-unpaid";
21
+ };
22
+ export declare function posCellularSystemEmailTemplates(origin: string): SystemEmailTemplateDefinition[];
@@ -0,0 +1,230 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /*==========================================
17
+ * 4G FOR CARD READERS, AS SYSTEM EMAILS (AGL-4038).
18
+ *
19
+ * Two emails to the people who manage a workspace's billing, about its
20
+ * monthly charge for 4G on its Stripe Reader S710s:
21
+ *
22
+ * - PAYMENT DUE, the day the charge doesn't go through: how much, for which
23
+ * month, and the day 4G turns off for its stores unless the open invoice
24
+ * is paid (pay it on the Billing page, and nothing else changes).
25
+ * - TURNED OFF, once that day comes and it is still unpaid: which month went
26
+ * unpaid and for how much, which stores lost 4G, and the way back (pay it
27
+ * on the Billing page, then turn 4G on again on the store's POS devices
28
+ * card).
29
+ *
30
+ * The platform bills the charge, so they are SYSTEM emails in the platform's
31
+ * brand (or the workspace's white label), not a store's mail.
32
+ *
33
+ * It lives here, beside the catalog, for the reason `domain-emails.ts`
34
+ * gives: system emails have no plugin seam, and the staff System emails page
35
+ * reads this registry before any plugin loads.
36
+ *
37
+ * Amounts and dates arrive formatted; a template never does arithmetic.
38
+ *=========================================*/ export const POS_CELLULAR_EMAIL_KEYS = {
39
+ paymentDue: 'pos-cellular-payment-due',
40
+ turnedOffUnpaid: 'pos-cellular-turned-off-unpaid'
41
+ };
42
+ const SOURCE = 'libs/plugins/commerce/src/lib/server/pos-cellular-notify.ts';
43
+ function tokens(origin) {
44
+ return {
45
+ org: {
46
+ name: 'org.name',
47
+ description: 'The workspace whose 4G was turned off',
48
+ sample: 'Test Org'
49
+ },
50
+ orgDue: {
51
+ name: 'org.name',
52
+ description: 'The workspace whose 4G charge is due',
53
+ sample: 'Test Org'
54
+ },
55
+ month: {
56
+ name: 'cellular.month',
57
+ description: 'The month whose 4G charge went unpaid',
58
+ sample: 'October 2026'
59
+ },
60
+ amount: {
61
+ name: 'cellular.amount',
62
+ description: 'What that month’s 4G charge came to',
63
+ sample: '$21.65'
64
+ },
65
+ readers: {
66
+ name: 'cellular.readers',
67
+ description: 'How many Stripe Reader S710s that month’s charge was for',
68
+ sample: '2 Stripe Reader S710s'
69
+ },
70
+ openedOn: {
71
+ name: 'cellular.openedOn',
72
+ description: 'The day the charge did not go through',
73
+ sample: 'November 2, 2026'
74
+ },
75
+ turnedOffOn: {
76
+ name: 'cellular.turnedOffOn',
77
+ description: 'The day 4G was turned off',
78
+ sample: 'November 16, 2026'
79
+ },
80
+ turnsOffOn: {
81
+ name: 'cellular.turnsOffOn',
82
+ description: 'The day 4G turns off for the workspace’s stores unless the charge is paid, in its time zone',
83
+ sample: 'November 16, 2026'
84
+ },
85
+ stores: {
86
+ name: 'cellular.stores',
87
+ description: 'The stores 4G was turned off for, one per line',
88
+ sample: 'Test Bakery'
89
+ },
90
+ storesWithCellular: {
91
+ name: 'cellular.stores',
92
+ description: 'The stores that have 4G now and would lose it, one per line (blank, and the row left out, when none has)',
93
+ sample: 'Test Bakery'
94
+ },
95
+ billingUrl: {
96
+ name: 'cellular.billingUrl',
97
+ description: 'The workspace’s Billing page, where the open invoice is paid',
98
+ sample: `${origin}/test-org/billing`
99
+ }
100
+ };
101
+ }
102
+ export function posCellularSystemEmailTemplates(origin) {
103
+ const t = tokens(origin);
104
+ return [
105
+ {
106
+ key: POS_CELLULAR_EMAIL_KEYS.paymentDue,
107
+ name: '4G charge unpaid: the day 4G turns off',
108
+ description: 'Sent to the people who manage a workspace’s billing the day its ' + 'monthly charge for 4G on Stripe Reader S710s doesn’t go through, ' + 'once: the amount, and the day 4G turns off for its stores unless ' + 'the open invoice is paid.',
109
+ deliveredBy: 'resend',
110
+ defaultSubject: '4G turns off on {{cellular.turnsOffOn}} unless the {{cellular.month}} charge is paid',
111
+ mergeTokens: [
112
+ t.orgDue,
113
+ t.month,
114
+ t.amount,
115
+ t.readers,
116
+ t.openedOn,
117
+ t.turnsOffOn,
118
+ t.storesWithCellular,
119
+ t.billingUrl
120
+ ],
121
+ defaultBody: [
122
+ {
123
+ block: 'text',
124
+ text: '{{org.name}} · 4G for card readers',
125
+ variant: 'eyebrow'
126
+ },
127
+ {
128
+ block: 'text',
129
+ text: 'Your 4G charge didn’t go through',
130
+ variant: 'heading'
131
+ },
132
+ {
133
+ block: 'text',
134
+ text: 'On {{cellular.openedOn}} we tried to charge {{cellular.amount}} for your card readers’ 4G in {{cellular.month}}, and the payment didn’t go through. The invoice is open on your Billing page. Unless it’s paid before {{cellular.turnsOffOn}}, 4G turns off for your stores that day.',
135
+ variant: 'body'
136
+ },
137
+ {
138
+ block: 'text',
139
+ text: 'Amount due: {{cellular.amount}} for {{cellular.month}}\n4G turns off on: {{cellular.turnsOffOn}}\nReaders: {{cellular.readers}}\nStores with 4G: {{cellular.stores}}',
140
+ variant: 'details'
141
+ },
142
+ {
143
+ block: 'text',
144
+ text: 'How to keep 4G on',
145
+ variant: 'subheading'
146
+ },
147
+ {
148
+ block: 'text',
149
+ text: 'Pay the open invoice on your Billing page. If your card has changed, update your payment method there first. Once it’s paid, 4G stays on and there’s nothing else to do. Either way, your readers keep working on Wi-Fi or Ethernet.',
150
+ variant: 'body'
151
+ },
152
+ {
153
+ block: 'button',
154
+ label: 'Pay on the Billing page',
155
+ href: '{{cellular.billingUrl}}'
156
+ },
157
+ {
158
+ block: 'text',
159
+ text: 'Questions about the charge? Contact support: {{brand.supportUrl}}',
160
+ variant: 'caption'
161
+ }
162
+ ],
163
+ footerReason: 'You’re receiving this because you manage billing for {{org.name}} on {{brand.productName}}.',
164
+ source: SOURCE
165
+ },
166
+ {
167
+ key: POS_CELLULAR_EMAIL_KEYS.turnedOffUnpaid,
168
+ name: '4G turned off: charge unpaid',
169
+ description: 'Sent to the people who manage a workspace’s billing when its monthly ' + 'charge for 4G on Stripe Reader S710s is still unpaid after the grace ' + 'period, and 4G has been turned off for its stores.',
170
+ deliveredBy: 'resend',
171
+ defaultSubject: '4G is off for your card readers: the {{cellular.month}} charge is unpaid',
172
+ mergeTokens: [
173
+ t.org,
174
+ t.month,
175
+ t.amount,
176
+ t.readers,
177
+ t.openedOn,
178
+ t.turnedOffOn,
179
+ t.stores,
180
+ t.billingUrl
181
+ ],
182
+ defaultBody: [
183
+ {
184
+ block: 'text',
185
+ text: '{{org.name}} · 4G for card readers',
186
+ variant: 'eyebrow'
187
+ },
188
+ {
189
+ block: 'text',
190
+ text: 'We turned off 4G for your card readers',
191
+ variant: 'heading'
192
+ },
193
+ {
194
+ block: 'text',
195
+ text: 'The 4G charge for {{cellular.month}} didn’t go through on {{cellular.openedOn}}, and it is still unpaid. So on {{cellular.turnedOffOn}} we turned 4G off for your stores. Your readers keep working on Wi-Fi or Ethernet.',
196
+ variant: 'body'
197
+ },
198
+ {
199
+ block: 'text',
200
+ text: 'Unpaid: {{cellular.amount}} for {{cellular.month}}\nReaders: {{cellular.readers}}\nStores with 4G turned off: {{cellular.stores}}',
201
+ variant: 'details'
202
+ },
203
+ {
204
+ block: 'text',
205
+ text: 'How to turn it back on',
206
+ variant: 'subheading'
207
+ },
208
+ {
209
+ block: 'text',
210
+ text: 'Pay the open invoice on your Billing page. 4G doesn’t come back on by itself once it’s paid: turn it on again from each store’s POS devices card, in its point of sale settings.',
211
+ variant: 'body'
212
+ },
213
+ {
214
+ block: 'button',
215
+ label: 'Pay on the Billing page',
216
+ href: '{{cellular.billingUrl}}'
217
+ },
218
+ {
219
+ block: 'text',
220
+ text: 'Questions about the charge? Contact support: {{brand.supportUrl}}',
221
+ variant: 'caption'
222
+ }
223
+ ],
224
+ footerReason: 'You’re receiving this because you manage billing for {{org.name}} on {{brand.productName}}.',
225
+ source: SOURCE
226
+ }
227
+ ];
228
+ }
229
+
230
+ //# sourceMappingURL=pos-cellular-emails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/shared/util/email/src/lib/pos-cellular-emails.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*==========================================\n * 4G FOR CARD READERS, AS SYSTEM EMAILS (AGL-4038).\n *\n * Two emails to the people who manage a workspace's billing, about its\n * monthly charge for 4G on its Stripe Reader S710s:\n *\n * - PAYMENT DUE, the day the charge doesn't go through: how much, for which\n * month, and the day 4G turns off for its stores unless the open invoice\n * is paid (pay it on the Billing page, and nothing else changes).\n * - TURNED OFF, once that day comes and it is still unpaid: which month went\n * unpaid and for how much, which stores lost 4G, and the way back (pay it\n * on the Billing page, then turn 4G on again on the store's POS devices\n * card).\n *\n * The platform bills the charge, so they are SYSTEM emails in the platform's\n * brand (or the workspace's white label), not a store's mail.\n *\n * It lives here, beside the catalog, for the reason `domain-emails.ts`\n * gives: system emails have no plugin seam, and the staff System emails page\n * reads this registry before any plugin loads.\n *\n * Amounts and dates arrive formatted; a template never does arithmetic.\n *=========================================*/\n\nimport type {\n SystemEmailMergeToken,\n SystemEmailTemplateDefinition,\n} from './system-email-catalog'\n\nexport const POS_CELLULAR_EMAIL_KEYS = {\n paymentDue: 'pos-cellular-payment-due',\n turnedOffUnpaid: 'pos-cellular-turned-off-unpaid',\n} as const\n\nconst SOURCE = 'libs/plugins/commerce/src/lib/server/pos-cellular-notify.ts'\n\nfunction tokens(origin: string): Record<string, SystemEmailMergeToken> {\n return {\n org: { name: 'org.name', description: 'The workspace whose 4G was turned off', sample: 'Test Org' },\n orgDue: { name: 'org.name', description: 'The workspace whose 4G charge is due', sample: 'Test Org' },\n month: { name: 'cellular.month', description: 'The month whose 4G charge went unpaid', sample: 'October 2026' },\n amount: { name: 'cellular.amount', description: 'What that month’s 4G charge came to', sample: '$21.65' },\n readers: {\n name: 'cellular.readers',\n description: 'How many Stripe Reader S710s that month’s charge was for',\n sample: '2 Stripe Reader S710s',\n },\n openedOn: { name: 'cellular.openedOn', description: 'The day the charge did not go through', sample: 'November 2, 2026' },\n turnedOffOn: { name: 'cellular.turnedOffOn', description: 'The day 4G was turned off', sample: 'November 16, 2026' },\n turnsOffOn: {\n name: 'cellular.turnsOffOn',\n description: 'The day 4G turns off for the workspace’s stores unless the charge is paid, in its time zone',\n sample: 'November 16, 2026',\n },\n stores: {\n name: 'cellular.stores',\n description: 'The stores 4G was turned off for, one per line',\n sample: 'Test Bakery',\n },\n storesWithCellular: {\n name: 'cellular.stores',\n description: 'The stores that have 4G now and would lose it, one per line (blank, and the row left out, when none has)',\n sample: 'Test Bakery',\n },\n billingUrl: {\n name: 'cellular.billingUrl',\n description: 'The workspace’s Billing page, where the open invoice is paid',\n sample: `${origin}/test-org/billing`,\n },\n }\n}\n\nexport function posCellularSystemEmailTemplates(origin: string): SystemEmailTemplateDefinition[] {\n const t = tokens(origin)\n return [\n {\n key: POS_CELLULAR_EMAIL_KEYS.paymentDue,\n name: '4G charge unpaid: the day 4G turns off',\n description:\n 'Sent to the people who manage a workspace’s billing the day its ' +\n 'monthly charge for 4G on Stripe Reader S710s doesn’t go through, ' +\n 'once: the amount, and the day 4G turns off for its stores unless ' +\n 'the open invoice is paid.',\n deliveredBy: 'resend',\n defaultSubject: '4G turns off on {{cellular.turnsOffOn}} unless the {{cellular.month}} charge is paid',\n mergeTokens: [t.orgDue, t.month, t.amount, t.readers, t.openedOn, t.turnsOffOn, t.storesWithCellular, t.billingUrl],\n defaultBody: [\n { block: 'text', text: '{{org.name}} · 4G for card readers', variant: 'eyebrow' },\n { block: 'text', text: 'Your 4G charge didn’t go through', variant: 'heading' },\n {\n block: 'text',\n text: 'On {{cellular.openedOn}} we tried to charge {{cellular.amount}} for your card readers’ 4G in {{cellular.month}}, and the payment didn’t go through. The invoice is open on your Billing page. Unless it’s paid before {{cellular.turnsOffOn}}, 4G turns off for your stores that day.',\n variant: 'body',\n },\n {\n block: 'text',\n text: 'Amount due: {{cellular.amount}} for {{cellular.month}}\\n4G turns off on: {{cellular.turnsOffOn}}\\nReaders: {{cellular.readers}}\\nStores with 4G: {{cellular.stores}}',\n variant: 'details',\n },\n { block: 'text', text: 'How to keep 4G on', variant: 'subheading' },\n {\n block: 'text',\n text: 'Pay the open invoice on your Billing page. If your card has changed, update your payment method there first. Once it’s paid, 4G stays on and there’s nothing else to do. Either way, your readers keep working on Wi-Fi or Ethernet.',\n variant: 'body',\n },\n { block: 'button', label: 'Pay on the Billing page', href: '{{cellular.billingUrl}}' },\n { block: 'text', text: 'Questions about the charge? Contact support: {{brand.supportUrl}}', variant: 'caption' },\n ],\n footerReason:\n 'You’re receiving this because you manage billing for {{org.name}} on {{brand.productName}}.',\n source: SOURCE,\n },\n {\n key: POS_CELLULAR_EMAIL_KEYS.turnedOffUnpaid,\n name: '4G turned off: charge unpaid',\n description:\n 'Sent to the people who manage a workspace’s billing when its monthly ' +\n 'charge for 4G on Stripe Reader S710s is still unpaid after the grace ' +\n 'period, and 4G has been turned off for its stores.',\n deliveredBy: 'resend',\n defaultSubject: '4G is off for your card readers: the {{cellular.month}} charge is unpaid',\n mergeTokens: [t.org, t.month, t.amount, t.readers, t.openedOn, t.turnedOffOn, t.stores, t.billingUrl],\n defaultBody: [\n { block: 'text', text: '{{org.name}} · 4G for card readers', variant: 'eyebrow' },\n { block: 'text', text: 'We turned off 4G for your card readers', variant: 'heading' },\n {\n block: 'text',\n text: 'The 4G charge for {{cellular.month}} didn’t go through on {{cellular.openedOn}}, and it is still unpaid. So on {{cellular.turnedOffOn}} we turned 4G off for your stores. Your readers keep working on Wi-Fi or Ethernet.',\n variant: 'body',\n },\n {\n block: 'text',\n text: 'Unpaid: {{cellular.amount}} for {{cellular.month}}\\nReaders: {{cellular.readers}}\\nStores with 4G turned off: {{cellular.stores}}',\n variant: 'details',\n },\n { block: 'text', text: 'How to turn it back on', variant: 'subheading' },\n {\n block: 'text',\n text: 'Pay the open invoice on your Billing page. 4G doesn’t come back on by itself once it’s paid: turn it on again from each store’s POS devices card, in its point of sale settings.',\n variant: 'body',\n },\n { block: 'button', label: 'Pay on the Billing page', href: '{{cellular.billingUrl}}' },\n { block: 'text', text: 'Questions about the charge? Contact support: {{brand.supportUrl}}', variant: 'caption' },\n ],\n footerReason:\n 'You’re receiving this because you manage billing for {{org.name}} on {{brand.productName}}.',\n source: SOURCE,\n },\n ]\n}\n"],"names":["POS_CELLULAR_EMAIL_KEYS","paymentDue","turnedOffUnpaid","SOURCE","tokens","origin","org","name","description","sample","orgDue","month","amount","readers","openedOn","turnedOffOn","turnsOffOn","stores","storesWithCellular","billingUrl","posCellularSystemEmailTemplates","t","key","deliveredBy","defaultSubject","mergeTokens","defaultBody","block","text","variant","label","href","footerReason","source"],"mappings":"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"}
@@ -19,5 +19,9 @@ export declare const POS_HARDWARE_EMAIL_KEYS: {
19
19
  readonly received: "pos-hardware-order-received";
20
20
  readonly shipped: "pos-hardware-order-shipped";
21
21
  readonly delivered: "pos-hardware-order-delivered";
22
+ readonly canceled: "pos-hardware-order-canceled";
23
+ readonly refunded: "pos-hardware-order-refunded";
24
+ readonly invited: "pos-hardware-sign-up-invite";
25
+ readonly returnRefunded: "pos-hardware-return-refunded";
22
26
  };
23
27
  export declare function posHardwareSystemEmailTemplates(origin: string): SystemEmailTemplateDefinition[];