@company-semantics/contracts 27.13.0 → 27.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/email/render/__tests__/__snapshots__/render-snapshot.test.ts.snap +155 -146
- package/src/email/render/__tests__/render-snapshot.test.ts +3 -1
- package/src/email/render/auth-otp.ts +8 -9
- package/src/email/render/blocks.ts +115 -97
- package/src/email/render/chat-shared.ts +8 -23
- package/src/email/render/company-md-access-approved.ts +2 -2
- package/src/email/render/company-md-access-denied.ts +6 -11
- package/src/email/render/company-md-access-requested.ts +8 -13
- package/src/email/render/constants.ts +0 -6
- package/src/email/render/index.ts +6 -13
- package/src/email/render/org-invite.ts +11 -11
- package/src/email/render/ownership-transfer.ts +2 -2
- package/src/email/render/render-email.ts +13 -5
- package/src/email/render/share-granted.ts +8 -13
- package/src/email/render/unit-owner-granted.ts +8 -13
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type { EmailPayloads } from "../types";
|
|
6
6
|
|
|
7
7
|
import { baseTextLayout } from "./base-text";
|
|
8
|
-
import {
|
|
8
|
+
import { chatUserBoxText } from "./blocks";
|
|
9
9
|
|
|
10
10
|
export type OwnershipTransferPayload = EmailPayloads["org.ownership_transfer"];
|
|
11
11
|
|
|
@@ -19,7 +19,7 @@ export function renderOwnershipTransferBody(
|
|
|
19
19
|
|
|
20
20
|
if (note) {
|
|
21
21
|
sections.push("");
|
|
22
|
-
sections.push(
|
|
22
|
+
sections.push(chatUserBoxText(note, "Message from the current owner"));
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
sections.push("");
|
|
@@ -68,15 +68,22 @@ export const IMPLEMENTED_EMAIL_KINDS = [
|
|
|
68
68
|
|
|
69
69
|
export type ImplementedEmailKind = (typeof IMPLEMENTED_EMAIL_KINDS)[number];
|
|
70
70
|
|
|
71
|
+
/** Payload type for a kind (or `never` for kinds without a payload). */
|
|
72
|
+
type PayloadFor<K extends EmailKind> = K extends keyof EmailPayloads
|
|
73
|
+
? EmailPayloads[K]
|
|
74
|
+
: never;
|
|
75
|
+
|
|
71
76
|
/**
|
|
72
77
|
* Render an email by kind. Subject comes from `EMAIL_KINDS`; `html` is present
|
|
73
|
-
* only when the template emits an HTML variant.
|
|
78
|
+
* only when the template emits an HTML variant. Accepts the full `EmailKind`
|
|
79
|
+
* union so callers with a generic kind (e.g. the backend `EmailService`) type
|
|
80
|
+
* cleanly; unimplemented kinds throw at runtime.
|
|
74
81
|
*
|
|
75
82
|
* @throws if the kind has no implementation.
|
|
76
83
|
*/
|
|
77
|
-
export function renderEmail<K extends
|
|
84
|
+
export function renderEmail<K extends EmailKind>(
|
|
78
85
|
kind: K,
|
|
79
|
-
payload:
|
|
86
|
+
payload: PayloadFor<K>,
|
|
80
87
|
options?: RenderEmailOptions,
|
|
81
88
|
): RenderedEmail {
|
|
82
89
|
const subject = EMAIL_KINDS[kind].subject;
|
|
@@ -159,8 +166,9 @@ export function renderEmail<K extends ImplementedEmailKind>(
|
|
|
159
166
|
};
|
|
160
167
|
}
|
|
161
168
|
default: {
|
|
162
|
-
|
|
163
|
-
|
|
169
|
+
// Reachable for registered-but-unimplemented kinds (e.g. auth.magic_link).
|
|
170
|
+
const unimplemented: string = kind;
|
|
171
|
+
throw new Error(`Email kind not implemented: ${unimplemented}`);
|
|
164
172
|
}
|
|
165
173
|
}
|
|
166
174
|
}
|
|
@@ -8,15 +8,15 @@ import { baseTextLayout } from "./base-text";
|
|
|
8
8
|
import {
|
|
9
9
|
ACCESS_PHRASE,
|
|
10
10
|
asciiCtaBox,
|
|
11
|
-
|
|
11
|
+
paragraph,
|
|
12
12
|
ctaBox,
|
|
13
13
|
footer,
|
|
14
14
|
greeting,
|
|
15
15
|
htmlShell,
|
|
16
16
|
NOTICE,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
chatUserBubble,
|
|
18
|
+
chatUserBoxText,
|
|
19
|
+
signature,
|
|
20
20
|
} from "./blocks";
|
|
21
21
|
import { COMPANY_NAME } from "./constants";
|
|
22
22
|
import { escapeHtml } from "./escape-html";
|
|
@@ -42,7 +42,7 @@ export function renderShareGrantedBody(payload: ShareGrantedPayload): string {
|
|
|
42
42
|
|
|
43
43
|
if (message) {
|
|
44
44
|
sections.push("");
|
|
45
|
-
sections.push(
|
|
45
|
+
sections.push(chatUserBoxText(message, `Message from ${granterName}`));
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
sections.push("");
|
|
@@ -73,15 +73,10 @@ export function renderShareGrantedHtml(payload: ShareGrantedPayload): string {
|
|
|
73
73
|
|
|
74
74
|
return htmlShell([
|
|
75
75
|
greeting(recipientName),
|
|
76
|
-
|
|
76
|
+
paragraph(
|
|
77
77
|
`<b>${escapeHtml(granterName)}</b> shared ${entityHtml} with you — you ${ACCESS_PHRASE[accessLevel]}.`,
|
|
78
78
|
),
|
|
79
|
-
message
|
|
80
|
-
? quoteBlock(
|
|
81
|
-
`Message from ${escapeHtml(granterName)}:`,
|
|
82
|
-
escapeHtml(message),
|
|
83
|
-
)
|
|
84
|
-
: "",
|
|
79
|
+
message ? chatUserBubble(message, `Message from ${granterName}`) : "",
|
|
85
80
|
ctaBox({
|
|
86
81
|
label: "OPEN",
|
|
87
82
|
href: ctaUrl,
|
|
@@ -90,6 +85,6 @@ export function renderShareGrantedHtml(payload: ShareGrantedPayload): string {
|
|
|
90
85
|
maxWidth: "220px",
|
|
91
86
|
}),
|
|
92
87
|
footer(`This notification was sent via ${COMPANY_NAME}.`, NOTICE),
|
|
93
|
-
|
|
88
|
+
signature(),
|
|
94
89
|
]);
|
|
95
90
|
}
|
|
@@ -7,15 +7,15 @@ import type { EmailPayloads } from "../types";
|
|
|
7
7
|
import { baseTextLayout } from "./base-text";
|
|
8
8
|
import {
|
|
9
9
|
asciiCtaBox,
|
|
10
|
-
|
|
10
|
+
paragraph,
|
|
11
11
|
ctaBox,
|
|
12
12
|
footer,
|
|
13
13
|
greeting,
|
|
14
14
|
htmlShell,
|
|
15
15
|
NOTICE,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
chatUserBubble,
|
|
17
|
+
chatUserBoxText,
|
|
18
|
+
signature,
|
|
19
19
|
} from "./blocks";
|
|
20
20
|
import { COMPANY_NAME } from "./constants";
|
|
21
21
|
import { escapeHtml } from "./escape-html";
|
|
@@ -35,7 +35,7 @@ export function renderUnitOwnerGrantedBody(
|
|
|
35
35
|
|
|
36
36
|
if (message) {
|
|
37
37
|
sections.push("");
|
|
38
|
-
sections.push(
|
|
38
|
+
sections.push(chatUserBoxText(message, `Message from ${granterName}`));
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
sections.push("");
|
|
@@ -57,15 +57,10 @@ export function renderUnitOwnerGrantedHtml(
|
|
|
57
57
|
|
|
58
58
|
return htmlShell([
|
|
59
59
|
greeting(recipientName),
|
|
60
|
-
|
|
60
|
+
paragraph(
|
|
61
61
|
`<b>${escapeHtml(granterName)}</b> added you as a <b>${escapeHtml(roleLabel)}</b> of <b>${escapeHtml(unitName)}</b>.`,
|
|
62
62
|
),
|
|
63
|
-
message
|
|
64
|
-
? quoteBlock(
|
|
65
|
-
`Message from ${escapeHtml(granterName)}:`,
|
|
66
|
-
escapeHtml(message),
|
|
67
|
-
)
|
|
68
|
-
: "",
|
|
63
|
+
message ? chatUserBubble(message, `Message from ${granterName}`) : "",
|
|
69
64
|
ctaBox({
|
|
70
65
|
label: "VIEW TEAM",
|
|
71
66
|
href: ctaUrl,
|
|
@@ -74,6 +69,6 @@ export function renderUnitOwnerGrantedHtml(
|
|
|
74
69
|
maxWidth: "220px",
|
|
75
70
|
}),
|
|
76
71
|
footer(`This notification was sent via ${COMPANY_NAME}.`, NOTICE),
|
|
77
|
-
|
|
72
|
+
signature(),
|
|
78
73
|
]);
|
|
79
74
|
}
|