@ainsleydev/payload-helper 0.0.39 → 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.
Files changed (39) hide show
  1. package/README.md +163 -0
  2. package/dist/admin/components/Icon.d.ts +16 -0
  3. package/dist/admin/components/Icon.js +26 -0
  4. package/dist/admin/components/Icon.js.map +1 -0
  5. package/dist/cli/bin.js +20 -0
  6. package/dist/cli/bin.js.map +1 -1
  7. package/dist/cli/commands/preview-emails.d.ts +5 -0
  8. package/dist/cli/commands/preview-emails.js +123 -0
  9. package/dist/cli/commands/preview-emails.js.map +1 -0
  10. package/dist/email/ForgotPasswordEmail.d.ts +38 -0
  11. package/dist/email/ForgotPasswordEmail.js +61 -0
  12. package/dist/email/ForgotPasswordEmail.js.map +1 -0
  13. package/dist/email/ForgotPasswordEmail.test.d.ts +1 -0
  14. package/dist/email/ForgotPasswordEmail.test.js +202 -0
  15. package/dist/email/ForgotPasswordEmail.test.js.map +1 -0
  16. package/dist/email/VerifyAccountEmail.d.ts +38 -0
  17. package/dist/email/VerifyAccountEmail.js +61 -0
  18. package/dist/email/VerifyAccountEmail.js.map +1 -0
  19. package/dist/email/VerifyAccountEmail.test.d.ts +1 -0
  20. package/dist/email/VerifyAccountEmail.test.js +212 -0
  21. package/dist/email/VerifyAccountEmail.test.js.map +1 -0
  22. package/dist/index.d.ts +7 -1
  23. package/dist/index.js +21 -4
  24. package/dist/index.js.map +1 -1
  25. package/dist/plugin/admin.d.ts +10 -0
  26. package/dist/plugin/admin.js +50 -0
  27. package/dist/plugin/admin.js.map +1 -0
  28. package/dist/plugin/email.d.ts +10 -0
  29. package/dist/plugin/email.js +98 -0
  30. package/dist/plugin/email.js.map +1 -0
  31. package/dist/plugin/email.test.js +265 -0
  32. package/dist/plugin/email.test.js.map +1 -0
  33. package/dist/types.d.ts +147 -1
  34. package/dist/types.js +3 -1
  35. package/dist/types.js.map +1 -1
  36. package/package.json +28 -15
  37. package/dist/plugin/logo.d.ts +0 -6
  38. package/dist/plugin/logo.js +0 -26
  39. package/dist/plugin/logo.js.map +0 -1
@@ -0,0 +1,202 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, expect, test, vi } from 'vitest';
3
+ import { ForgotPasswordEmail } from './ForgotPasswordEmail.js';
4
+ // Mock the email templates module
5
+ vi.mock('@ainsleydev/email-templates', ()=>({
6
+ BaseEmail: ({ children })=>children,
7
+ Button: ({ children, href })=>/*#__PURE__*/ _jsx("a", {
8
+ href: href,
9
+ children: children
10
+ }),
11
+ Heading: ({ children })=>/*#__PURE__*/ _jsx("h1", {
12
+ children: children
13
+ }),
14
+ Section: ({ children })=>/*#__PURE__*/ _jsx("section", {
15
+ children: children
16
+ }),
17
+ Text: ({ children })=>/*#__PURE__*/ _jsx("p", {
18
+ children: children
19
+ })
20
+ }));
21
+ const mockTheme = {
22
+ colours: {
23
+ text: {
24
+ heading: '#000000',
25
+ body: '#333333',
26
+ action: '#007bff',
27
+ negative: '#ffffff'
28
+ },
29
+ background: {
30
+ white: '#ffffff',
31
+ dark: '#000000',
32
+ darker: '#0f0f0f',
33
+ highlight: '#f5f5f5',
34
+ accent: '#007bff'
35
+ },
36
+ border: {
37
+ light: '#e0e0e0',
38
+ medium: '#cccccc',
39
+ dark: '#000000',
40
+ inverse: '#ffffff'
41
+ }
42
+ },
43
+ branding: {
44
+ companyName: 'Test Company',
45
+ logoUrl: 'https://example.com/logo.png',
46
+ logoWidth: 120,
47
+ websiteUrl: 'https://example.com'
48
+ }
49
+ };
50
+ describe('ForgotPasswordEmail', ()=>{
51
+ test('should render with default content when no overrides provided', ()=>{
52
+ const props = {
53
+ theme: mockTheme,
54
+ user: {
55
+ firstName: 'John',
56
+ email: 'john@example.com'
57
+ },
58
+ resetUrl: 'https://example.com/reset/token123'
59
+ };
60
+ const result = ForgotPasswordEmail(props);
61
+ // Component should render without errors
62
+ expect(result).toBeDefined();
63
+ });
64
+ test('should use firstName when available', ()=>{
65
+ const props = {
66
+ theme: mockTheme,
67
+ user: {
68
+ firstName: 'Jane',
69
+ email: 'jane@example.com'
70
+ },
71
+ resetUrl: 'https://example.com/reset/token123'
72
+ };
73
+ const result = ForgotPasswordEmail(props);
74
+ // The userName should be set to firstName
75
+ // This is tested through the default heading which uses userName
76
+ expect(result).toBeDefined();
77
+ });
78
+ test('should use email when firstName is not available', ()=>{
79
+ const props = {
80
+ theme: mockTheme,
81
+ user: {
82
+ email: 'john@example.com'
83
+ },
84
+ resetUrl: 'https://example.com/reset/token123'
85
+ };
86
+ const result = ForgotPasswordEmail(props);
87
+ // The userName should be set to email
88
+ expect(result).toBeDefined();
89
+ });
90
+ test('should use "there" when neither firstName nor email is available', ()=>{
91
+ const props = {
92
+ theme: mockTheme,
93
+ user: {},
94
+ resetUrl: 'https://example.com/reset/token123'
95
+ };
96
+ const result = ForgotPasswordEmail(props);
97
+ // The userName should default to "there"
98
+ expect(result).toBeDefined();
99
+ });
100
+ test('should use custom content overrides when provided', ()=>{
101
+ const props = {
102
+ theme: mockTheme,
103
+ user: {
104
+ firstName: 'John'
105
+ },
106
+ resetUrl: 'https://example.com/reset/token123',
107
+ content: {
108
+ previewText: 'Custom preview text',
109
+ heading: 'Custom Heading',
110
+ bodyText: 'Custom body text',
111
+ buttonText: 'Custom Button'
112
+ }
113
+ };
114
+ const result = ForgotPasswordEmail(props);
115
+ // Component should use custom content
116
+ expect(result).toBeDefined();
117
+ });
118
+ test('should use partial content overrides with defaults', ()=>{
119
+ const props = {
120
+ theme: mockTheme,
121
+ user: {
122
+ firstName: 'John'
123
+ },
124
+ resetUrl: 'https://example.com/reset/token123',
125
+ content: {
126
+ heading: 'Custom Heading Only'
127
+ }
128
+ };
129
+ const result = ForgotPasswordEmail(props);
130
+ // Component should use custom heading and default for others
131
+ expect(result).toBeDefined();
132
+ });
133
+ test('should pass resetUrl to the button', ()=>{
134
+ const resetUrl = 'https://example.com/reset/abc123xyz';
135
+ const props = {
136
+ theme: mockTheme,
137
+ user: {
138
+ firstName: 'John'
139
+ },
140
+ resetUrl
141
+ };
142
+ const result = ForgotPasswordEmail(props);
143
+ // The resetUrl should be used in the button href
144
+ expect(result).toBeDefined();
145
+ });
146
+ test('should apply theme colors correctly', ()=>{
147
+ const customTheme = {
148
+ colours: {
149
+ text: {
150
+ heading: '#ff0000',
151
+ body: '#00ff00',
152
+ action: '#0000ff',
153
+ negative: '#ffffff'
154
+ },
155
+ background: {
156
+ white: '#ffffff',
157
+ dark: '#000000',
158
+ darker: '#0f0f0f',
159
+ highlight: '#f5f5f5',
160
+ accent: '#0000ff'
161
+ },
162
+ border: {
163
+ light: '#e0e0e0',
164
+ medium: '#cccccc',
165
+ dark: '#000000',
166
+ inverse: '#ffffff'
167
+ }
168
+ },
169
+ branding: {
170
+ companyName: 'Custom Company',
171
+ logoUrl: 'https://custom.com/logo.png',
172
+ logoWidth: 150,
173
+ websiteUrl: 'https://custom.com'
174
+ }
175
+ };
176
+ const props = {
177
+ theme: customTheme,
178
+ user: {
179
+ firstName: 'John'
180
+ },
181
+ resetUrl: 'https://example.com/reset/token123'
182
+ };
183
+ const result = ForgotPasswordEmail(props);
184
+ // Component should use custom theme colors
185
+ expect(result).toBeDefined();
186
+ });
187
+ test('should handle empty content object', ()=>{
188
+ const props = {
189
+ theme: mockTheme,
190
+ user: {
191
+ firstName: 'John'
192
+ },
193
+ resetUrl: 'https://example.com/reset/token123',
194
+ content: {}
195
+ };
196
+ const result = ForgotPasswordEmail(props);
197
+ // Should use all defaults when content is empty object
198
+ expect(result).toBeDefined();
199
+ });
200
+ });
201
+
202
+ //# sourceMappingURL=ForgotPasswordEmail.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/email/ForgotPasswordEmail.test.tsx"],"sourcesContent":["import type { EmailTheme } from '@ainsleydev/email-templates';\nimport { describe, expect, test, vi } from 'vitest';\nimport { ForgotPasswordEmail } from './ForgotPasswordEmail.js';\nimport type { ForgotPasswordEmailProps } from './ForgotPasswordEmail.js';\n\n// Mock the email templates module\nvi.mock('@ainsleydev/email-templates', () => ({\n\tBaseEmail: ({ children }: { children: React.ReactNode }) => children,\n\tButton: ({ children, href }: { children: React.ReactNode; href: string }) => (\n\t\t<a href={href}>{children}</a>\n\t),\n\tHeading: ({ children }: { children: React.ReactNode }) => <h1>{children}</h1>,\n\tSection: ({ children }: { children: React.ReactNode }) => <section>{children}</section>,\n\tText: ({ children }: { children: React.ReactNode }) => <p>{children}</p>,\n}));\n\nconst mockTheme: EmailTheme = {\n\tcolours: {\n\t\ttext: {\n\t\t\theading: '#000000',\n\t\t\tbody: '#333333',\n\t\t\taction: '#007bff',\n\t\t\tnegative: '#ffffff',\n\t\t},\n\t\tbackground: {\n\t\t\twhite: '#ffffff',\n\t\t\tdark: '#000000',\n\t\t\tdarker: '#0f0f0f',\n\t\t\thighlight: '#f5f5f5',\n\t\t\taccent: '#007bff',\n\t\t},\n\t\tborder: {\n\t\t\tlight: '#e0e0e0',\n\t\t\tmedium: '#cccccc',\n\t\t\tdark: '#000000',\n\t\t\tinverse: '#ffffff',\n\t\t},\n\t},\n\tbranding: {\n\t\tcompanyName: 'Test Company',\n\t\tlogoUrl: 'https://example.com/logo.png',\n\t\tlogoWidth: 120,\n\t\twebsiteUrl: 'https://example.com',\n\t},\n};\n\ndescribe('ForgotPasswordEmail', () => {\n\ttest('should render with default content when no overrides provided', () => {\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t\temail: 'john@example.com',\n\t\t\t},\n\t\t\tresetUrl: 'https://example.com/reset/token123',\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// Component should render without errors\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use firstName when available', () => {\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'Jane',\n\t\t\t\temail: 'jane@example.com',\n\t\t\t},\n\t\t\tresetUrl: 'https://example.com/reset/token123',\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// The userName should be set to firstName\n\t\t// This is tested through the default heading which uses userName\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use email when firstName is not available', () => {\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\temail: 'john@example.com',\n\t\t\t},\n\t\t\tresetUrl: 'https://example.com/reset/token123',\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// The userName should be set to email\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use \"there\" when neither firstName nor email is available', () => {\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {},\n\t\t\tresetUrl: 'https://example.com/reset/token123',\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// The userName should default to \"there\"\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use custom content overrides when provided', () => {\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tresetUrl: 'https://example.com/reset/token123',\n\t\t\tcontent: {\n\t\t\t\tpreviewText: 'Custom preview text',\n\t\t\t\theading: 'Custom Heading',\n\t\t\t\tbodyText: 'Custom body text',\n\t\t\t\tbuttonText: 'Custom Button',\n\t\t\t},\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// Component should use custom content\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use partial content overrides with defaults', () => {\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tresetUrl: 'https://example.com/reset/token123',\n\t\t\tcontent: {\n\t\t\t\theading: 'Custom Heading Only',\n\t\t\t\t// Other fields should use defaults\n\t\t\t},\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// Component should use custom heading and default for others\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should pass resetUrl to the button', () => {\n\t\tconst resetUrl = 'https://example.com/reset/abc123xyz';\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tresetUrl,\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// The resetUrl should be used in the button href\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should apply theme colors correctly', () => {\n\t\tconst customTheme: EmailTheme = {\n\t\t\tcolours: {\n\t\t\t\ttext: {\n\t\t\t\t\theading: '#ff0000',\n\t\t\t\t\tbody: '#00ff00',\n\t\t\t\t\taction: '#0000ff',\n\t\t\t\t\tnegative: '#ffffff',\n\t\t\t\t},\n\t\t\t\tbackground: {\n\t\t\t\t\twhite: '#ffffff',\n\t\t\t\t\tdark: '#000000',\n\t\t\t\t\tdarker: '#0f0f0f',\n\t\t\t\t\thighlight: '#f5f5f5',\n\t\t\t\t\taccent: '#0000ff',\n\t\t\t\t},\n\t\t\t\tborder: {\n\t\t\t\t\tlight: '#e0e0e0',\n\t\t\t\t\tmedium: '#cccccc',\n\t\t\t\t\tdark: '#000000',\n\t\t\t\t\tinverse: '#ffffff',\n\t\t\t\t},\n\t\t\t},\n\t\t\tbranding: {\n\t\t\t\tcompanyName: 'Custom Company',\n\t\t\t\tlogoUrl: 'https://custom.com/logo.png',\n\t\t\t\tlogoWidth: 150,\n\t\t\t\twebsiteUrl: 'https://custom.com',\n\t\t\t},\n\t\t};\n\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: customTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tresetUrl: 'https://example.com/reset/token123',\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// Component should use custom theme colors\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should handle empty content object', () => {\n\t\tconst props: ForgotPasswordEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tresetUrl: 'https://example.com/reset/token123',\n\t\t\tcontent: {},\n\t\t};\n\n\t\tconst result = ForgotPasswordEmail(props);\n\n\t\t// Should use all defaults when content is empty object\n\t\texpect(result).toBeDefined();\n\t});\n});\n"],"names":["describe","expect","test","vi","ForgotPasswordEmail","mock","BaseEmail","children","Button","href","a","Heading","h1","Section","section","Text","p","mockTheme","colours","text","heading","body","action","negative","background","white","dark","darker","highlight","accent","border","light","medium","inverse","branding","companyName","logoUrl","logoWidth","websiteUrl","props","theme","user","firstName","email","resetUrl","result","toBeDefined","content","previewText","bodyText","buttonText","customTheme"],"mappings":";AACA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,IAAI,EAAEC,EAAE,QAAQ,SAAS;AACpD,SAASC,mBAAmB,QAAQ,2BAA2B;AAG/D,kCAAkC;AAClCD,GAAGE,IAAI,CAAC,+BAA+B,IAAO,CAAA;QAC7CC,WAAW,CAAC,EAAEC,QAAQ,EAAiC,GAAKA;QAC5DC,QAAQ,CAAC,EAAED,QAAQ,EAAEE,IAAI,EAA+C,iBACvE,KAACC;gBAAED,MAAMA;0BAAOF;;QAEjBI,SAAS,CAAC,EAAEJ,QAAQ,EAAiC,iBAAK,KAACK;0BAAIL;;QAC/DM,SAAS,CAAC,EAAEN,QAAQ,EAAiC,iBAAK,KAACO;0BAASP;;QACpEQ,MAAM,CAAC,EAAER,QAAQ,EAAiC,iBAAK,KAACS;0BAAGT;;IAC5D,CAAA;AAEA,MAAMU,YAAwB;IAC7BC,SAAS;QACRC,MAAM;YACLC,SAAS;YACTC,MAAM;YACNC,QAAQ;YACRC,UAAU;QACX;QACAC,YAAY;YACXC,OAAO;YACPC,MAAM;YACNC,QAAQ;YACRC,WAAW;YACXC,QAAQ;QACT;QACAC,QAAQ;YACPC,OAAO;YACPC,QAAQ;YACRN,MAAM;YACNO,SAAS;QACV;IACD;IACAC,UAAU;QACTC,aAAa;QACbC,SAAS;QACTC,WAAW;QACXC,YAAY;IACb;AACD;AAEAtC,SAAS,uBAAuB;IAC/BE,KAAK,iEAAiE;QACrE,MAAMqC,QAAkC;YACvCC,OAAOvB;YACPwB,MAAM;gBACLC,WAAW;gBACXC,OAAO;YACR;YACAC,UAAU;QACX;QAEA,MAAMC,SAASzC,oBAAoBmC;QAEnC,yCAAyC;QACzCtC,OAAO4C,QAAQC,WAAW;IAC3B;IAEA5C,KAAK,uCAAuC;QAC3C,MAAMqC,QAAkC;YACvCC,OAAOvB;YACPwB,MAAM;gBACLC,WAAW;gBACXC,OAAO;YACR;YACAC,UAAU;QACX;QAEA,MAAMC,SAASzC,oBAAoBmC;QAEnC,0CAA0C;QAC1C,iEAAiE;QACjEtC,OAAO4C,QAAQC,WAAW;IAC3B;IAEA5C,KAAK,oDAAoD;QACxD,MAAMqC,QAAkC;YACvCC,OAAOvB;YACPwB,MAAM;gBACLE,OAAO;YACR;YACAC,UAAU;QACX;QAEA,MAAMC,SAASzC,oBAAoBmC;QAEnC,sCAAsC;QACtCtC,OAAO4C,QAAQC,WAAW;IAC3B;IAEA5C,KAAK,oEAAoE;QACxE,MAAMqC,QAAkC;YACvCC,OAAOvB;YACPwB,MAAM,CAAC;YACPG,UAAU;QACX;QAEA,MAAMC,SAASzC,oBAAoBmC;QAEnC,yCAAyC;QACzCtC,OAAO4C,QAAQC,WAAW;IAC3B;IAEA5C,KAAK,qDAAqD;QACzD,MAAMqC,QAAkC;YACvCC,OAAOvB;YACPwB,MAAM;gBACLC,WAAW;YACZ;YACAE,UAAU;YACVG,SAAS;gBACRC,aAAa;gBACb5B,SAAS;gBACT6B,UAAU;gBACVC,YAAY;YACb;QACD;QAEA,MAAML,SAASzC,oBAAoBmC;QAEnC,sCAAsC;QACtCtC,OAAO4C,QAAQC,WAAW;IAC3B;IAEA5C,KAAK,sDAAsD;QAC1D,MAAMqC,QAAkC;YACvCC,OAAOvB;YACPwB,MAAM;gBACLC,WAAW;YACZ;YACAE,UAAU;YACVG,SAAS;gBACR3B,SAAS;YAEV;QACD;QAEA,MAAMyB,SAASzC,oBAAoBmC;QAEnC,6DAA6D;QAC7DtC,OAAO4C,QAAQC,WAAW;IAC3B;IAEA5C,KAAK,sCAAsC;QAC1C,MAAM0C,WAAW;QACjB,MAAML,QAAkC;YACvCC,OAAOvB;YACPwB,MAAM;gBACLC,WAAW;YACZ;YACAE;QACD;QAEA,MAAMC,SAASzC,oBAAoBmC;QAEnC,iDAAiD;QACjDtC,OAAO4C,QAAQC,WAAW;IAC3B;IAEA5C,KAAK,uCAAuC;QAC3C,MAAMiD,cAA0B;YAC/BjC,SAAS;gBACRC,MAAM;oBACLC,SAAS;oBACTC,MAAM;oBACNC,QAAQ;oBACRC,UAAU;gBACX;gBACAC,YAAY;oBACXC,OAAO;oBACPC,MAAM;oBACNC,QAAQ;oBACRC,WAAW;oBACXC,QAAQ;gBACT;gBACAC,QAAQ;oBACPC,OAAO;oBACPC,QAAQ;oBACRN,MAAM;oBACNO,SAAS;gBACV;YACD;YACAC,UAAU;gBACTC,aAAa;gBACbC,SAAS;gBACTC,WAAW;gBACXC,YAAY;YACb;QACD;QAEA,MAAMC,QAAkC;YACvCC,OAAOW;YACPV,MAAM;gBACLC,WAAW;YACZ;YACAE,UAAU;QACX;QAEA,MAAMC,SAASzC,oBAAoBmC;QAEnC,2CAA2C;QAC3CtC,OAAO4C,QAAQC,WAAW;IAC3B;IAEA5C,KAAK,sCAAsC;QAC1C,MAAMqC,QAAkC;YACvCC,OAAOvB;YACPwB,MAAM;gBACLC,WAAW;YACZ;YACAE,UAAU;YACVG,SAAS,CAAC;QACX;QAEA,MAAMF,SAASzC,oBAAoBmC;QAEnC,uDAAuD;QACvDtC,OAAO4C,QAAQC,WAAW;IAC3B;AACD"}
@@ -0,0 +1,38 @@
1
+ import type { EmailTheme } from '@ainsleydev/email-templates';
2
+ import * as React from 'react';
3
+ /**
4
+ * Props for the VerifyAccountEmail component.
5
+ */
6
+ export interface VerifyAccountEmailProps {
7
+ /**
8
+ * The email theme (required by renderEmail).
9
+ */
10
+ theme: EmailTheme;
11
+ /**
12
+ * The user object containing user information.
13
+ */
14
+ user: {
15
+ firstName?: string;
16
+ email?: string;
17
+ };
18
+ /**
19
+ * The URL for verifying the account.
20
+ */
21
+ verifyUrl: string;
22
+ /**
23
+ * Optional content overrides.
24
+ */
25
+ content?: {
26
+ previewText?: string;
27
+ heading?: string;
28
+ bodyText?: string;
29
+ buttonText?: string;
30
+ };
31
+ }
32
+ /**
33
+ * Email template for account verification in Payload CMS.
34
+ *
35
+ * @param props - The component props
36
+ * @returns The rendered email component
37
+ */
38
+ export declare const VerifyAccountEmail: ({ theme, user, verifyUrl, content, }: VerifyAccountEmailProps) => React.JSX.Element;
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { BaseEmail, Button, Heading, Section, Text } from '@ainsleydev/email-templates';
3
+ import * as React from 'react';
4
+ /**
5
+ * Email template for account verification in Payload CMS.
6
+ *
7
+ * @param props - The component props
8
+ * @returns The rendered email component
9
+ */ export const VerifyAccountEmail = ({ theme, user, verifyUrl, content })=>{
10
+ const userName = user.firstName || user.email || 'there';
11
+ const previewText = content?.previewText || 'Verify your email';
12
+ const heading = content?.heading || `Welcome, ${userName}!`;
13
+ const bodyText = content?.bodyText || 'Please verify your email by clicking the button below. If you did not request a password reset, you can safely ignore this email.';
14
+ const buttonText = content?.buttonText || 'Verify Email';
15
+ return /*#__PURE__*/ _jsxs(BaseEmail, {
16
+ theme: theme,
17
+ previewText: previewText,
18
+ children: [
19
+ /*#__PURE__*/ _jsx(Heading, {
20
+ style: {
21
+ color: theme.colours.text.heading,
22
+ fontSize: '24px',
23
+ fontWeight: 'bold',
24
+ marginBottom: '20px'
25
+ },
26
+ children: heading
27
+ }),
28
+ /*#__PURE__*/ _jsx(Text, {
29
+ style: {
30
+ color: theme.colours.text.body,
31
+ fontSize: '16px',
32
+ lineHeight: '24px',
33
+ marginBottom: '30px'
34
+ },
35
+ children: bodyText
36
+ }),
37
+ /*#__PURE__*/ _jsx(Section, {
38
+ style: {
39
+ textAlign: 'center',
40
+ marginBottom: '30px'
41
+ },
42
+ children: /*#__PURE__*/ _jsx(Button, {
43
+ href: verifyUrl,
44
+ style: {
45
+ backgroundColor: theme.colours.background.accent,
46
+ color: theme.colours.text.heading,
47
+ padding: '12px 32px',
48
+ borderRadius: '5px',
49
+ fontSize: '16px',
50
+ fontWeight: 'bold',
51
+ textDecoration: 'none',
52
+ display: 'inline-block'
53
+ },
54
+ children: buttonText
55
+ })
56
+ })
57
+ ]
58
+ });
59
+ };
60
+
61
+ //# sourceMappingURL=VerifyAccountEmail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/email/VerifyAccountEmail.tsx"],"sourcesContent":["import { BaseEmail, Button, Heading, Section, Text } from '@ainsleydev/email-templates';\nimport type { EmailTheme } from '@ainsleydev/email-templates';\nimport * as React from 'react';\n\n/**\n * Props for the VerifyAccountEmail component.\n */\nexport interface VerifyAccountEmailProps {\n\t/**\n\t * The email theme (required by renderEmail).\n\t */\n\ttheme: EmailTheme;\n\n\t/**\n\t * The user object containing user information.\n\t */\n\tuser: {\n\t\tfirstName?: string;\n\t\temail?: string;\n\t};\n\n\t/**\n\t * The URL for verifying the account.\n\t */\n\tverifyUrl: string;\n\n\t/**\n\t * Optional content overrides.\n\t */\n\tcontent?: {\n\t\tpreviewText?: string;\n\t\theading?: string;\n\t\tbodyText?: string;\n\t\tbuttonText?: string;\n\t};\n}\n\n/**\n * Email template for account verification in Payload CMS.\n *\n * @param props - The component props\n * @returns The rendered email component\n */\nexport const VerifyAccountEmail = ({\n\ttheme,\n\tuser,\n\tverifyUrl,\n\tcontent,\n}: VerifyAccountEmailProps) => {\n\tconst userName = user.firstName || user.email || 'there';\n\tconst previewText = content?.previewText || 'Verify your email';\n\tconst heading = content?.heading || `Welcome, ${userName}!`;\n\tconst bodyText =\n\t\tcontent?.bodyText ||\n\t\t'Please verify your email by clicking the button below. If you did not request a password reset, you can safely ignore this email.';\n\tconst buttonText = content?.buttonText || 'Verify Email';\n\n\treturn (\n\t\t<BaseEmail theme={theme} previewText={previewText}>\n\t\t\t<Heading\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: theme.colours.text.heading,\n\t\t\t\t\tfontSize: '24px',\n\t\t\t\t\tfontWeight: 'bold',\n\t\t\t\t\tmarginBottom: '20px',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{heading}\n\t\t\t</Heading>\n\t\t\t<Text\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: theme.colours.text.body,\n\t\t\t\t\tfontSize: '16px',\n\t\t\t\t\tlineHeight: '24px',\n\t\t\t\t\tmarginBottom: '30px',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{bodyText}\n\t\t\t</Text>\n\t\t\t<Section style={{ textAlign: 'center', marginBottom: '30px' }}>\n\t\t\t\t<Button\n\t\t\t\t\thref={verifyUrl}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackgroundColor: theme.colours.background.accent,\n\t\t\t\t\t\tcolor: theme.colours.text.heading,\n\t\t\t\t\t\tpadding: '12px 32px',\n\t\t\t\t\t\tborderRadius: '5px',\n\t\t\t\t\t\tfontSize: '16px',\n\t\t\t\t\t\tfontWeight: 'bold',\n\t\t\t\t\t\ttextDecoration: 'none',\n\t\t\t\t\t\tdisplay: 'inline-block',\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{buttonText}\n\t\t\t\t</Button>\n\t\t\t</Section>\n\t\t</BaseEmail>\n\t);\n};\n"],"names":["BaseEmail","Button","Heading","Section","Text","React","VerifyAccountEmail","theme","user","verifyUrl","content","userName","firstName","email","previewText","heading","bodyText","buttonText","style","color","colours","text","fontSize","fontWeight","marginBottom","body","lineHeight","textAlign","href","backgroundColor","background","accent","padding","borderRadius","textDecoration","display"],"mappings":";AAAA,SAASA,SAAS,EAAEC,MAAM,EAAEC,OAAO,EAAEC,OAAO,EAAEC,IAAI,QAAQ,8BAA8B;AAExF,YAAYC,WAAW,QAAQ;AAmC/B;;;;;CAKC,GACD,OAAO,MAAMC,qBAAqB,CAAC,EAClCC,KAAK,EACLC,IAAI,EACJC,SAAS,EACTC,OAAO,EACkB;IACzB,MAAMC,WAAWH,KAAKI,SAAS,IAAIJ,KAAKK,KAAK,IAAI;IACjD,MAAMC,cAAcJ,SAASI,eAAe;IAC5C,MAAMC,UAAUL,SAASK,WAAW,CAAC,SAAS,EAAEJ,SAAS,CAAC,CAAC;IAC3D,MAAMK,WACLN,SAASM,YACT;IACD,MAAMC,aAAaP,SAASO,cAAc;IAE1C,qBACC,MAACjB;QAAUO,OAAOA;QAAOO,aAAaA;;0BACrC,KAACZ;gBACAgB,OAAO;oBACNC,OAAOZ,MAAMa,OAAO,CAACC,IAAI,CAACN,OAAO;oBACjCO,UAAU;oBACVC,YAAY;oBACZC,cAAc;gBACf;0BAECT;;0BAEF,KAACX;gBACAc,OAAO;oBACNC,OAAOZ,MAAMa,OAAO,CAACC,IAAI,CAACI,IAAI;oBAC9BH,UAAU;oBACVI,YAAY;oBACZF,cAAc;gBACf;0BAECR;;0BAEF,KAACb;gBAAQe,OAAO;oBAAES,WAAW;oBAAUH,cAAc;gBAAO;0BAC3D,cAAA,KAACvB;oBACA2B,MAAMnB;oBACNS,OAAO;wBACNW,iBAAiBtB,MAAMa,OAAO,CAACU,UAAU,CAACC,MAAM;wBAChDZ,OAAOZ,MAAMa,OAAO,CAACC,IAAI,CAACN,OAAO;wBACjCiB,SAAS;wBACTC,cAAc;wBACdX,UAAU;wBACVC,YAAY;wBACZW,gBAAgB;wBAChBC,SAAS;oBACV;8BAEClB;;;;;AAKN,EAAE"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,212 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, expect, test, vi } from 'vitest';
3
+ import { VerifyAccountEmail } from './VerifyAccountEmail.js';
4
+ // Mock the email templates module
5
+ vi.mock('@ainsleydev/email-templates', ()=>({
6
+ BaseEmail: ({ children })=>children,
7
+ Button: ({ children, href })=>/*#__PURE__*/ _jsx("a", {
8
+ href: href,
9
+ children: children
10
+ }),
11
+ Heading: ({ children })=>/*#__PURE__*/ _jsx("h1", {
12
+ children: children
13
+ }),
14
+ Section: ({ children })=>/*#__PURE__*/ _jsx("section", {
15
+ children: children
16
+ }),
17
+ Text: ({ children })=>/*#__PURE__*/ _jsx("p", {
18
+ children: children
19
+ })
20
+ }));
21
+ const mockTheme = {
22
+ colours: {
23
+ text: {
24
+ heading: '#000000',
25
+ body: '#333333',
26
+ action: '#007bff',
27
+ negative: '#ffffff'
28
+ },
29
+ background: {
30
+ white: '#ffffff',
31
+ dark: '#000000',
32
+ darker: '#0f0f0f',
33
+ highlight: '#f5f5f5',
34
+ accent: '#007bff'
35
+ },
36
+ border: {
37
+ light: '#e0e0e0',
38
+ medium: '#cccccc',
39
+ dark: '#000000',
40
+ inverse: '#ffffff'
41
+ }
42
+ },
43
+ branding: {
44
+ companyName: 'Test Company',
45
+ logoUrl: 'https://example.com/logo.png',
46
+ logoWidth: 120,
47
+ websiteUrl: 'https://example.com'
48
+ }
49
+ };
50
+ describe('VerifyAccountEmail', ()=>{
51
+ test('should render with default content when no overrides provided', ()=>{
52
+ const props = {
53
+ theme: mockTheme,
54
+ user: {
55
+ firstName: 'John',
56
+ email: 'john@example.com'
57
+ },
58
+ verifyUrl: 'https://example.com/verify/token123'
59
+ };
60
+ const result = VerifyAccountEmail(props);
61
+ // Component should render without errors
62
+ expect(result).toBeDefined();
63
+ });
64
+ test('should use firstName when available', ()=>{
65
+ const props = {
66
+ theme: mockTheme,
67
+ user: {
68
+ firstName: 'Jane',
69
+ email: 'jane@example.com'
70
+ },
71
+ verifyUrl: 'https://example.com/verify/token123'
72
+ };
73
+ const result = VerifyAccountEmail(props);
74
+ // The userName should be set to firstName
75
+ // This is tested through the default heading which uses userName
76
+ expect(result).toBeDefined();
77
+ });
78
+ test('should use email when firstName is not available', ()=>{
79
+ const props = {
80
+ theme: mockTheme,
81
+ user: {
82
+ email: 'john@example.com'
83
+ },
84
+ verifyUrl: 'https://example.com/verify/token123'
85
+ };
86
+ const result = VerifyAccountEmail(props);
87
+ // The userName should be set to email
88
+ expect(result).toBeDefined();
89
+ });
90
+ test('should use "there" when neither firstName nor email is available', ()=>{
91
+ const props = {
92
+ theme: mockTheme,
93
+ user: {},
94
+ verifyUrl: 'https://example.com/verify/token123'
95
+ };
96
+ const result = VerifyAccountEmail(props);
97
+ // The userName should default to "there"
98
+ expect(result).toBeDefined();
99
+ });
100
+ test('should use custom content overrides when provided', ()=>{
101
+ const props = {
102
+ theme: mockTheme,
103
+ user: {
104
+ firstName: 'John'
105
+ },
106
+ verifyUrl: 'https://example.com/verify/token123',
107
+ content: {
108
+ previewText: 'Custom preview text',
109
+ heading: 'Custom Welcome Heading',
110
+ bodyText: 'Custom verification message',
111
+ buttonText: 'Custom Verify Button'
112
+ }
113
+ };
114
+ const result = VerifyAccountEmail(props);
115
+ // Component should use custom content
116
+ expect(result).toBeDefined();
117
+ });
118
+ test('should use partial content overrides with defaults', ()=>{
119
+ const props = {
120
+ theme: mockTheme,
121
+ user: {
122
+ firstName: 'John'
123
+ },
124
+ verifyUrl: 'https://example.com/verify/token123',
125
+ content: {
126
+ buttonText: 'Confirm Email'
127
+ }
128
+ };
129
+ const result = VerifyAccountEmail(props);
130
+ // Component should use custom button text and defaults for others
131
+ expect(result).toBeDefined();
132
+ });
133
+ test('should pass verifyUrl to the button', ()=>{
134
+ const verifyUrl = 'https://example.com/verify/xyz789abc';
135
+ const props = {
136
+ theme: mockTheme,
137
+ user: {
138
+ firstName: 'John'
139
+ },
140
+ verifyUrl
141
+ };
142
+ const result = VerifyAccountEmail(props);
143
+ // The verifyUrl should be used in the button href
144
+ expect(result).toBeDefined();
145
+ });
146
+ test('should apply theme colors correctly', ()=>{
147
+ const customTheme = {
148
+ colours: {
149
+ text: {
150
+ heading: '#ff0000',
151
+ body: '#00ff00',
152
+ action: '#0000ff',
153
+ negative: '#ffffff'
154
+ },
155
+ background: {
156
+ white: '#ffffff',
157
+ dark: '#000000',
158
+ darker: '#0f0f0f',
159
+ highlight: '#f5f5f5',
160
+ accent: '#0000ff'
161
+ },
162
+ border: {
163
+ light: '#e0e0e0',
164
+ medium: '#cccccc',
165
+ dark: '#000000',
166
+ inverse: '#ffffff'
167
+ }
168
+ },
169
+ branding: {
170
+ companyName: 'Custom Company',
171
+ logoUrl: 'https://custom.com/logo.png',
172
+ logoWidth: 150,
173
+ websiteUrl: 'https://custom.com'
174
+ }
175
+ };
176
+ const props = {
177
+ theme: customTheme,
178
+ user: {
179
+ firstName: 'John'
180
+ },
181
+ verifyUrl: 'https://example.com/verify/token123'
182
+ };
183
+ const result = VerifyAccountEmail(props);
184
+ // Component should use custom theme colors
185
+ expect(result).toBeDefined();
186
+ });
187
+ test('should handle empty content object', ()=>{
188
+ const props = {
189
+ theme: mockTheme,
190
+ user: {
191
+ firstName: 'John'
192
+ },
193
+ verifyUrl: 'https://example.com/verify/token123',
194
+ content: {}
195
+ };
196
+ const result = VerifyAccountEmail(props);
197
+ // Should use all defaults when content is empty object
198
+ expect(result).toBeDefined();
199
+ });
200
+ test('should render with minimal props', ()=>{
201
+ const props = {
202
+ theme: mockTheme,
203
+ user: {},
204
+ verifyUrl: 'https://example.com/verify/token123'
205
+ };
206
+ const result = VerifyAccountEmail(props);
207
+ // Should handle minimal props gracefully
208
+ expect(result).toBeDefined();
209
+ });
210
+ });
211
+
212
+ //# sourceMappingURL=VerifyAccountEmail.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/email/VerifyAccountEmail.test.tsx"],"sourcesContent":["import type { EmailTheme } from '@ainsleydev/email-templates';\nimport { describe, expect, test, vi } from 'vitest';\nimport { VerifyAccountEmail } from './VerifyAccountEmail.js';\nimport type { VerifyAccountEmailProps } from './VerifyAccountEmail.js';\n\n// Mock the email templates module\nvi.mock('@ainsleydev/email-templates', () => ({\n\tBaseEmail: ({ children }: { children: React.ReactNode }) => children,\n\tButton: ({ children, href }: { children: React.ReactNode; href: string }) => (\n\t\t<a href={href}>{children}</a>\n\t),\n\tHeading: ({ children }: { children: React.ReactNode }) => <h1>{children}</h1>,\n\tSection: ({ children }: { children: React.ReactNode }) => <section>{children}</section>,\n\tText: ({ children }: { children: React.ReactNode }) => <p>{children}</p>,\n}));\n\nconst mockTheme: EmailTheme = {\n\tcolours: {\n\t\ttext: {\n\t\t\theading: '#000000',\n\t\t\tbody: '#333333',\n\t\t\taction: '#007bff',\n\t\t\tnegative: '#ffffff',\n\t\t},\n\t\tbackground: {\n\t\t\twhite: '#ffffff',\n\t\t\tdark: '#000000',\n\t\t\tdarker: '#0f0f0f',\n\t\t\thighlight: '#f5f5f5',\n\t\t\taccent: '#007bff',\n\t\t},\n\t\tborder: {\n\t\t\tlight: '#e0e0e0',\n\t\t\tmedium: '#cccccc',\n\t\t\tdark: '#000000',\n\t\t\tinverse: '#ffffff',\n\t\t},\n\t},\n\tbranding: {\n\t\tcompanyName: 'Test Company',\n\t\tlogoUrl: 'https://example.com/logo.png',\n\t\tlogoWidth: 120,\n\t\twebsiteUrl: 'https://example.com',\n\t},\n};\n\ndescribe('VerifyAccountEmail', () => {\n\ttest('should render with default content when no overrides provided', () => {\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t\temail: 'john@example.com',\n\t\t\t},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// Component should render without errors\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use firstName when available', () => {\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'Jane',\n\t\t\t\temail: 'jane@example.com',\n\t\t\t},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// The userName should be set to firstName\n\t\t// This is tested through the default heading which uses userName\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use email when firstName is not available', () => {\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\temail: 'john@example.com',\n\t\t\t},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// The userName should be set to email\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use \"there\" when neither firstName nor email is available', () => {\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// The userName should default to \"there\"\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use custom content overrides when provided', () => {\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t\tcontent: {\n\t\t\t\tpreviewText: 'Custom preview text',\n\t\t\t\theading: 'Custom Welcome Heading',\n\t\t\t\tbodyText: 'Custom verification message',\n\t\t\t\tbuttonText: 'Custom Verify Button',\n\t\t\t},\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// Component should use custom content\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should use partial content overrides with defaults', () => {\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t\tcontent: {\n\t\t\t\tbuttonText: 'Confirm Email',\n\t\t\t\t// Other fields should use defaults\n\t\t\t},\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// Component should use custom button text and defaults for others\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should pass verifyUrl to the button', () => {\n\t\tconst verifyUrl = 'https://example.com/verify/xyz789abc';\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tverifyUrl,\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// The verifyUrl should be used in the button href\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should apply theme colors correctly', () => {\n\t\tconst customTheme: EmailTheme = {\n\t\t\tcolours: {\n\t\t\t\ttext: {\n\t\t\t\t\theading: '#ff0000',\n\t\t\t\t\tbody: '#00ff00',\n\t\t\t\t\taction: '#0000ff',\n\t\t\t\t\tnegative: '#ffffff',\n\t\t\t\t},\n\t\t\t\tbackground: {\n\t\t\t\t\twhite: '#ffffff',\n\t\t\t\t\tdark: '#000000',\n\t\t\t\t\tdarker: '#0f0f0f',\n\t\t\t\t\thighlight: '#f5f5f5',\n\t\t\t\t\taccent: '#0000ff',\n\t\t\t\t},\n\t\t\t\tborder: {\n\t\t\t\t\tlight: '#e0e0e0',\n\t\t\t\t\tmedium: '#cccccc',\n\t\t\t\t\tdark: '#000000',\n\t\t\t\t\tinverse: '#ffffff',\n\t\t\t\t},\n\t\t\t},\n\t\t\tbranding: {\n\t\t\t\tcompanyName: 'Custom Company',\n\t\t\t\tlogoUrl: 'https://custom.com/logo.png',\n\t\t\t\tlogoWidth: 150,\n\t\t\t\twebsiteUrl: 'https://custom.com',\n\t\t\t},\n\t\t};\n\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: customTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// Component should use custom theme colors\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should handle empty content object', () => {\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {\n\t\t\t\tfirstName: 'John',\n\t\t\t},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t\tcontent: {},\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// Should use all defaults when content is empty object\n\t\texpect(result).toBeDefined();\n\t});\n\n\ttest('should render with minimal props', () => {\n\t\tconst props: VerifyAccountEmailProps = {\n\t\t\ttheme: mockTheme,\n\t\t\tuser: {},\n\t\t\tverifyUrl: 'https://example.com/verify/token123',\n\t\t};\n\n\t\tconst result = VerifyAccountEmail(props);\n\n\t\t// Should handle minimal props gracefully\n\t\texpect(result).toBeDefined();\n\t});\n});\n"],"names":["describe","expect","test","vi","VerifyAccountEmail","mock","BaseEmail","children","Button","href","a","Heading","h1","Section","section","Text","p","mockTheme","colours","text","heading","body","action","negative","background","white","dark","darker","highlight","accent","border","light","medium","inverse","branding","companyName","logoUrl","logoWidth","websiteUrl","props","theme","user","firstName","email","verifyUrl","result","toBeDefined","content","previewText","bodyText","buttonText","customTheme"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,5 +7,11 @@ import type { PayloadHelperPluginConfig } from './types.js';
7
7
  * @param pluginOptions
8
8
  */
9
9
  export declare const payloadHelper: (pluginOptions: PayloadHelperPluginConfig) => (incomingConfig: Config) => Config;
10
+ export type { IconProps } from './admin/components/Icon.js';
10
11
  export type { LogoProps } from './admin/components/Logo.js';
11
- export type { AdminLogoConfig, PayloadHelperPluginConfig } from './types.js';
12
+ export { ForgotPasswordEmail } from './email/ForgotPasswordEmail.js';
13
+ export type { ForgotPasswordEmailProps } from './email/ForgotPasswordEmail.js';
14
+ export { VerifyAccountEmail } from './email/VerifyAccountEmail.js';
15
+ export type { VerifyAccountEmailProps } from './email/VerifyAccountEmail.js';
16
+ export { default as env } from './util/env.js';
17
+ export type { AdminConfig, AdminIconConfig, AdminLogoConfig, EmailConfig, EmailContentOverrides, PayloadHelperPluginConfig, } from './types.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
+ import { injectAdminIcon, injectAdminLogo } from './plugin/admin.js';
2
+ import { injectEmailTemplates } from './plugin/email.js';
1
3
  import { cacheHookCollections, cacheHookGlobals } from './plugin/hooks.js';
2
- import { injectAdminLogo } from './plugin/logo.js';
3
4
  /**
4
5
  * Payload Helper Plugin for websites at ainsley.dev
5
6
  *
@@ -11,9 +12,17 @@ import { injectAdminLogo } from './plugin/logo.js';
11
12
  // Update typescript generation file
12
13
  config.typescript = config.typescript || {};
13
14
  config.typescript.outputFile = './src/types/payload.ts';
14
- // Inject admin Logo component if adminLogo config is provided
15
- if (pluginOptions.adminLogo) {
16
- config = injectAdminLogo(config, pluginOptions.adminLogo, pluginOptions.siteName);
15
+ // Inject admin Logo component if logo config is provided
16
+ if (pluginOptions.admin?.logo) {
17
+ config = injectAdminLogo(config, pluginOptions.admin.logo, pluginOptions.siteName);
18
+ }
19
+ // Inject admin Icon component if icon config is provided
20
+ if (pluginOptions.admin?.icon) {
21
+ config = injectAdminIcon(config, pluginOptions.admin.icon, pluginOptions.siteName);
22
+ }
23
+ // Inject email templates for auth-enabled collections if email config is provided
24
+ if (pluginOptions.email) {
25
+ config = injectEmailTemplates(config, pluginOptions.email);
17
26
  }
18
27
  // Map collections & add hooks
19
28
  config.collections = (config.collections || []).map((collection)=>{
@@ -58,7 +67,15 @@ import { injectAdminLogo } from './plugin/logo.js';
58
67
  hooks
59
68
  };
60
69
  });
70
+ // Store plugin options in config.custom for CLI access (e.g., preview-emails command)
71
+ config.custom = {
72
+ ...config.custom,
73
+ payloadHelperOptions: pluginOptions
74
+ };
61
75
  return config;
62
76
  };
77
+ export { ForgotPasswordEmail } from './email/ForgotPasswordEmail.js';
78
+ export { VerifyAccountEmail } from './email/VerifyAccountEmail.js';
79
+ export { default as env } from './util/env.js';
63
80
 
64
81
  //# sourceMappingURL=index.js.map