@tracked/emails 0.1.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/LICENSE +21 -0
- package/README.md +211 -0
- package/dist/emails/bodyweight-goal-reached.d.ts +14 -0
- package/dist/emails/bodyweight-goal-reached.d.ts.map +1 -0
- package/dist/emails/bodyweight-goal-reached.js +177 -0
- package/dist/emails/bodyweight-goal-reached.js.map +1 -0
- package/dist/emails/client-accepted-invitation.d.ts +10 -0
- package/dist/emails/client-accepted-invitation.d.ts.map +1 -0
- package/dist/emails/client-accepted-invitation.js +99 -0
- package/dist/emails/client-accepted-invitation.js.map +1 -0
- package/dist/emails/coach-invite.d.ts +10 -0
- package/dist/emails/coach-invite.d.ts.map +1 -0
- package/dist/emails/coach-invite.js +126 -0
- package/dist/emails/coach-invite.js.map +1 -0
- package/dist/emails/coach-removed-client.d.ts +8 -0
- package/dist/emails/coach-removed-client.d.ts.map +1 -0
- package/dist/emails/coach-removed-client.js +80 -0
- package/dist/emails/coach-removed-client.js.map +1 -0
- package/dist/emails/direct-message.d.ts +11 -0
- package/dist/emails/direct-message.d.ts.map +1 -0
- package/dist/emails/direct-message.js +103 -0
- package/dist/emails/direct-message.js.map +1 -0
- package/dist/emails/feature-discovery.d.ts +11 -0
- package/dist/emails/feature-discovery.d.ts.map +1 -0
- package/dist/emails/feature-discovery.js +121 -0
- package/dist/emails/feature-discovery.js.map +1 -0
- package/dist/emails/first-workout-assigned.d.ts +10 -0
- package/dist/emails/first-workout-assigned.d.ts.map +1 -0
- package/dist/emails/first-workout-assigned.js +98 -0
- package/dist/emails/first-workout-assigned.js.map +1 -0
- package/dist/emails/first-workout-completed.d.ts +11 -0
- package/dist/emails/first-workout-completed.d.ts.map +1 -0
- package/dist/emails/first-workout-completed.js +129 -0
- package/dist/emails/first-workout-completed.js.map +1 -0
- package/dist/emails/index.d.ts +7 -0
- package/dist/emails/index.d.ts.map +1 -0
- package/dist/emails/index.js +7 -0
- package/dist/emails/index.js.map +1 -0
- package/dist/emails/new-follower.d.ts +11 -0
- package/dist/emails/new-follower.d.ts.map +1 -0
- package/dist/emails/new-follower.js +98 -0
- package/dist/emails/new-follower.js.map +1 -0
- package/dist/emails/subscription-canceled.d.ts +10 -0
- package/dist/emails/subscription-canceled.d.ts.map +1 -0
- package/dist/emails/subscription-canceled.js +131 -0
- package/dist/emails/subscription-canceled.js.map +1 -0
- package/dist/emails/support-email.d.ts +8 -0
- package/dist/emails/support-email.d.ts.map +1 -0
- package/dist/emails/support-email.js +40 -0
- package/dist/emails/support-email.js.map +1 -0
- package/dist/emails/team-invite.d.ts +11 -0
- package/dist/emails/team-invite.d.ts.map +1 -0
- package/dist/emails/team-invite.js +100 -0
- package/dist/emails/team-invite.js.map +1 -0
- package/dist/emails/team-member-removed-email.d.ts +8 -0
- package/dist/emails/team-member-removed-email.d.ts.map +1 -0
- package/dist/emails/team-member-removed-email.js +97 -0
- package/dist/emails/team-member-removed-email.js.map +1 -0
- package/dist/emails/tracked-magic-link-activate.d.ts +7 -0
- package/dist/emails/tracked-magic-link-activate.d.ts.map +1 -0
- package/dist/emails/tracked-magic-link-activate.js +93 -0
- package/dist/emails/tracked-magic-link-activate.js.map +1 -0
- package/dist/emails/tracked-magic-link.d.ts +7 -0
- package/dist/emails/tracked-magic-link.d.ts.map +1 -0
- package/dist/emails/tracked-magic-link.js +101 -0
- package/dist/emails/tracked-magic-link.js.map +1 -0
- package/dist/emails/week-one-checkin.d.ts +10 -0
- package/dist/emails/week-one-checkin.d.ts.map +1 -0
- package/dist/emails/week-one-checkin.js +141 -0
- package/dist/emails/week-one-checkin.js.map +1 -0
- package/dist/emails/welcome.d.ts +8 -0
- package/dist/emails/welcome.d.ts.map +1 -0
- package/dist/emails/welcome.js +146 -0
- package/dist/emails/welcome.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/email-validation.d.ts +48 -0
- package/dist/utils/email-validation.d.ts.map +1 -0
- package/dist/utils/email-validation.js +72 -0
- package/dist/utils/email-validation.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/username-validation.d.ts +54 -0
- package/dist/utils/username-validation.d.ts.map +1 -0
- package/dist/utils/username-validation.js +76 -0
- package/dist/utils/username-validation.js.map +1 -0
- package/package.json +78 -0
- package/src/emails/bodyweight-goal-reached.tsx +396 -0
- package/src/emails/client-accepted-invitation.tsx +258 -0
- package/src/emails/coach-invite.tsx +270 -0
- package/src/emails/coach-removed-client.tsx +212 -0
- package/src/emails/direct-message.tsx +249 -0
- package/src/emails/feature-discovery.tsx +289 -0
- package/src/emails/first-workout-assigned.tsx +255 -0
- package/src/emails/first-workout-completed.tsx +312 -0
- package/src/emails/index.tsx +6 -0
- package/src/emails/new-follower.tsx +260 -0
- package/src/emails/subscription-canceled.tsx +311 -0
- package/src/emails/support-email.tsx +80 -0
- package/src/emails/team-invite.tsx +262 -0
- package/src/emails/team-member-removed-email.tsx +240 -0
- package/src/emails/tracked-magic-link-activate.tsx +252 -0
- package/src/emails/tracked-magic-link.tsx +264 -0
- package/src/emails/week-one-checkin.tsx +353 -0
- package/src/emails/welcome.tsx +341 -0
- package/src/index.ts +57 -0
- package/src/utils/email-validation.test.ts +78 -0
- package/src/utils/email-validation.ts +80 -0
- package/src/utils/index.ts +13 -0
- package/src/utils/username-validation.test.ts +118 -0
- package/src/utils/username-validation.ts +89 -0
- package/static/tracked-logo.png +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Username Validation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles validation for usernames to determine if they're user-chosen or
|
|
5
|
+
* auto-generated UUIDs. Auto-generated usernames should not be displayed in emails.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Check if username is a generated UUID (not user-chosen)
|
|
10
|
+
*
|
|
11
|
+
* The database schema uses UUIDv7 as the default for usernames when users
|
|
12
|
+
* don't provide one. Format: 01944f9e-8e64-7a78-9e1e-3daba7b13e9f
|
|
13
|
+
*
|
|
14
|
+
* UUIDv7/v4 pattern: 8-4-4-4-12 hex characters separated by hyphens
|
|
15
|
+
*
|
|
16
|
+
* @param username - The username to check
|
|
17
|
+
* @returns true if the username is an auto-generated UUID
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* isAnonymousUsername("01944f9e-8e64-7a78-9e1e-3daba7b13e9f") // true
|
|
22
|
+
* isAnonymousUsername("john_doe") // false
|
|
23
|
+
* isAnonymousUsername(null) // true
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function isAnonymousUsername(
|
|
27
|
+
username: string | null | undefined,
|
|
28
|
+
): boolean {
|
|
29
|
+
if (!username) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// UUIDv7/v4 pattern: 8-4-4-4-12 hex characters
|
|
34
|
+
const uuidRegex =
|
|
35
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
36
|
+
return uuidRegex.test(username);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get safe display name for emails with intelligent fallback
|
|
41
|
+
*
|
|
42
|
+
* Tries to find a user-friendly display name by checking multiple sources
|
|
43
|
+
* in order of preference:
|
|
44
|
+
* 1. Real username (non-UUID)
|
|
45
|
+
* 2. Given name / First name
|
|
46
|
+
* 3. Full name
|
|
47
|
+
* 4. Generic fallback ("there")
|
|
48
|
+
*
|
|
49
|
+
* This ensures we never show auto-generated UUIDs in emails.
|
|
50
|
+
*
|
|
51
|
+
* @param username - The user's username (may be UUID)
|
|
52
|
+
* @param givenName - The user's first/given name
|
|
53
|
+
* @param name - The user's full name
|
|
54
|
+
* @param fallback - Default fallback if no good name is found (default: "there")
|
|
55
|
+
* @returns A safe, user-friendly display name
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* getSafeDisplayName("john_doe", "John", "John Doe") // "john_doe"
|
|
60
|
+
* getSafeDisplayName("01944f9e...", "John", "John Doe") // "John"
|
|
61
|
+
* getSafeDisplayName("01944f9e...", null, "John Doe") // "John Doe"
|
|
62
|
+
* getSafeDisplayName("01944f9e...", null, null) // "there"
|
|
63
|
+
* getSafeDisplayName(null, null, null, "friend") // "friend"
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export function getSafeDisplayName(
|
|
67
|
+
username: string | null | undefined,
|
|
68
|
+
givenName: string | null | undefined,
|
|
69
|
+
name: string | null | undefined,
|
|
70
|
+
fallback: string = "there",
|
|
71
|
+
): string {
|
|
72
|
+
// Try real username first (skip if it's a UUID)
|
|
73
|
+
if (username && !isAnonymousUsername(username)) {
|
|
74
|
+
return username;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Try given name
|
|
78
|
+
if (givenName && givenName.trim().length > 0) {
|
|
79
|
+
return givenName;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Try full name
|
|
83
|
+
if (name && name.trim().length > 0) {
|
|
84
|
+
return name;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Use fallback
|
|
88
|
+
return fallback;
|
|
89
|
+
}
|
|
Binary file
|