payload-plugin-newsletter 0.3.2 → 0.4.5

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 (180) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/CLAUDE.md +31 -19
  3. package/dist/client.cjs +899 -0
  4. package/dist/client.cjs.map +1 -0
  5. package/dist/client.d.cts +52 -0
  6. package/dist/client.d.ts +52 -0
  7. package/dist/client.js +867 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/components.cjs +899 -0
  10. package/dist/components.cjs.map +1 -0
  11. package/dist/components.d.cts +4 -0
  12. package/dist/components.d.ts +4 -0
  13. package/dist/components.js +867 -0
  14. package/dist/components.js.map +1 -0
  15. package/dist/index.cjs +2004 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.cts +11 -0
  18. package/dist/index.d.ts +6 -5
  19. package/dist/index.js +1967 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/types.cjs +19 -0
  22. package/dist/types.cjs.map +1 -0
  23. package/dist/{types/index.d.ts → types.d.cts} +19 -17
  24. package/dist/types.d.ts +350 -0
  25. package/dist/types.js +1 -0
  26. package/dist/types.js.map +1 -0
  27. package/package.json +48 -25
  28. package/dist/.tsbuildinfo +0 -1
  29. package/dist/collections/NewsletterSettings.d.ts +0 -4
  30. package/dist/collections/NewsletterSettings.d.ts.map +0 -1
  31. package/dist/collections/Subscribers.d.ts +0 -4
  32. package/dist/collections/Subscribers.d.ts.map +0 -1
  33. package/dist/components/MagicLinkVerify.d.ts +0 -27
  34. package/dist/components/MagicLinkVerify.d.ts.map +0 -1
  35. package/dist/components/NewsletterForm.d.ts +0 -5
  36. package/dist/components/NewsletterForm.d.ts.map +0 -1
  37. package/dist/components/PreferencesForm.d.ts +0 -5
  38. package/dist/components/PreferencesForm.d.ts.map +0 -1
  39. package/dist/components/index.d.ts +0 -5
  40. package/dist/components/index.d.ts.map +0 -1
  41. package/dist/endpoints/index.d.ts +0 -4
  42. package/dist/endpoints/index.d.ts.map +0 -1
  43. package/dist/endpoints/preferences.d.ts +0 -5
  44. package/dist/endpoints/preferences.d.ts.map +0 -1
  45. package/dist/endpoints/subscribe.d.ts +0 -4
  46. package/dist/endpoints/subscribe.d.ts.map +0 -1
  47. package/dist/endpoints/unsubscribe.d.ts +0 -4
  48. package/dist/endpoints/unsubscribe.d.ts.map +0 -1
  49. package/dist/endpoints/verify-magic-link.d.ts +0 -4
  50. package/dist/endpoints/verify-magic-link.d.ts.map +0 -1
  51. package/dist/exports/client.d.ts +0 -6
  52. package/dist/exports/client.d.ts.map +0 -1
  53. package/dist/exports/components.d.ts +0 -2
  54. package/dist/exports/components.d.ts.map +0 -1
  55. package/dist/exports/types.d.ts +0 -2
  56. package/dist/exports/types.d.ts.map +0 -1
  57. package/dist/fields/newsletterScheduling.d.ts +0 -4
  58. package/dist/fields/newsletterScheduling.d.ts.map +0 -1
  59. package/dist/hooks/useNewsletterAuth.d.ts +0 -16
  60. package/dist/hooks/useNewsletterAuth.d.ts.map +0 -1
  61. package/dist/index.d.ts.map +0 -1
  62. package/dist/providers/broadcast.d.ts +0 -19
  63. package/dist/providers/broadcast.d.ts.map +0 -1
  64. package/dist/providers/index.d.ts +0 -23
  65. package/dist/providers/index.d.ts.map +0 -1
  66. package/dist/providers/resend.d.ts +0 -20
  67. package/dist/providers/resend.d.ts.map +0 -1
  68. package/dist/providers/types.d.ts +0 -46
  69. package/dist/providers/types.d.ts.map +0 -1
  70. package/dist/src/__tests__/fixtures/newsletter-settings.js +0 -41
  71. package/dist/src/__tests__/fixtures/newsletter-settings.js.map +0 -1
  72. package/dist/src/__tests__/fixtures/subscribers.js +0 -70
  73. package/dist/src/__tests__/fixtures/subscribers.js.map +0 -1
  74. package/dist/src/__tests__/integration/collections/subscriber-hooks.test.js +0 -356
  75. package/dist/src/__tests__/integration/collections/subscriber-hooks.test.js.map +0 -1
  76. package/dist/src/__tests__/integration/endpoints/preferences.test.js +0 -266
  77. package/dist/src/__tests__/integration/endpoints/preferences.test.js.map +0 -1
  78. package/dist/src/__tests__/integration/endpoints/subscribe.test.js +0 -280
  79. package/dist/src/__tests__/integration/endpoints/subscribe.test.js.map +0 -1
  80. package/dist/src/__tests__/integration/endpoints/unsubscribe.test.js +0 -187
  81. package/dist/src/__tests__/integration/endpoints/unsubscribe.test.js.map +0 -1
  82. package/dist/src/__tests__/integration/endpoints/verify-magic-link.test.js +0 -188
  83. package/dist/src/__tests__/integration/endpoints/verify-magic-link.test.js.map +0 -1
  84. package/dist/src/__tests__/mocks/email-providers.js +0 -153
  85. package/dist/src/__tests__/mocks/email-providers.js.map +0 -1
  86. package/dist/src/__tests__/mocks/payload.js +0 -244
  87. package/dist/src/__tests__/mocks/payload.js.map +0 -1
  88. package/dist/src/__tests__/security/csrf-protection.test.js +0 -309
  89. package/dist/src/__tests__/security/csrf-protection.test.js.map +0 -1
  90. package/dist/src/__tests__/security/settings-access.test.js +0 -204
  91. package/dist/src/__tests__/security/settings-access.test.js.map +0 -1
  92. package/dist/src/__tests__/security/subscriber-access.test.js +0 -210
  93. package/dist/src/__tests__/security/subscriber-access.test.js.map +0 -1
  94. package/dist/src/__tests__/security/xss-prevention.test.js +0 -305
  95. package/dist/src/__tests__/security/xss-prevention.test.js.map +0 -1
  96. package/dist/src/__tests__/setup/integration.setup.js +0 -38
  97. package/dist/src/__tests__/setup/integration.setup.js.map +0 -1
  98. package/dist/src/__tests__/setup/unit.setup.js +0 -41
  99. package/dist/src/__tests__/setup/unit.setup.js.map +0 -1
  100. package/dist/src/__tests__/unit/utils/access.test.js +0 -116
  101. package/dist/src/__tests__/unit/utils/access.test.js.map +0 -1
  102. package/dist/src/__tests__/unit/utils/jwt.test.js +0 -238
  103. package/dist/src/__tests__/unit/utils/jwt.test.js.map +0 -1
  104. package/dist/src/collections/NewsletterSettings.js +0 -390
  105. package/dist/src/collections/NewsletterSettings.js.map +0 -1
  106. package/dist/src/collections/Subscribers.js +0 -309
  107. package/dist/src/collections/Subscribers.js.map +0 -1
  108. package/dist/src/components/MagicLinkVerify.js +0 -180
  109. package/dist/src/components/MagicLinkVerify.js.map +0 -1
  110. package/dist/src/components/NewsletterForm.js +0 -326
  111. package/dist/src/components/NewsletterForm.js.map +0 -1
  112. package/dist/src/components/PreferencesForm.js +0 -524
  113. package/dist/src/components/PreferencesForm.js.map +0 -1
  114. package/dist/src/components/index.js +0 -5
  115. package/dist/src/components/index.js.map +0 -1
  116. package/dist/src/endpoints/index.js +0 -17
  117. package/dist/src/endpoints/index.js.map +0 -1
  118. package/dist/src/endpoints/preferences.js +0 -136
  119. package/dist/src/endpoints/preferences.js.map +0 -1
  120. package/dist/src/endpoints/subscribe.js +0 -151
  121. package/dist/src/endpoints/subscribe.js.map +0 -1
  122. package/dist/src/endpoints/unsubscribe.js +0 -105
  123. package/dist/src/endpoints/unsubscribe.js.map +0 -1
  124. package/dist/src/endpoints/verify-magic-link.js +0 -103
  125. package/dist/src/endpoints/verify-magic-link.js.map +0 -1
  126. package/dist/src/exports/client.js +0 -7
  127. package/dist/src/exports/client.js.map +0 -1
  128. package/dist/src/exports/components.js +0 -6
  129. package/dist/src/exports/components.js.map +0 -1
  130. package/dist/src/exports/types.js +0 -3
  131. package/dist/src/exports/types.js.map +0 -1
  132. package/dist/src/fields/newsletterScheduling.js +0 -195
  133. package/dist/src/fields/newsletterScheduling.js.map +0 -1
  134. package/dist/src/hooks/useNewsletterAuth.js +0 -112
  135. package/dist/src/hooks/useNewsletterAuth.js.map +0 -1
  136. package/dist/src/index.js +0 -130
  137. package/dist/src/index.js.map +0 -1
  138. package/dist/src/providers/broadcast.js +0 -158
  139. package/dist/src/providers/broadcast.js.map +0 -1
  140. package/dist/src/providers/index.js +0 -63
  141. package/dist/src/providers/index.js.map +0 -1
  142. package/dist/src/providers/resend.js +0 -122
  143. package/dist/src/providers/resend.js.map +0 -1
  144. package/dist/src/providers/types.js +0 -12
  145. package/dist/src/providers/types.js.map +0 -1
  146. package/dist/src/templates/BaseTemplate.js +0 -105
  147. package/dist/src/templates/BaseTemplate.js.map +0 -1
  148. package/dist/src/templates/MagicLinkTemplate.js +0 -178
  149. package/dist/src/templates/MagicLinkTemplate.js.map +0 -1
  150. package/dist/src/templates/NewsletterTemplate.js +0 -150
  151. package/dist/src/templates/NewsletterTemplate.js.map +0 -1
  152. package/dist/src/templates/WelcomeTemplate.js +0 -192
  153. package/dist/src/templates/WelcomeTemplate.js.map +0 -1
  154. package/dist/src/templates/index.js +0 -6
  155. package/dist/src/templates/index.js.map +0 -1
  156. package/dist/src/types/index.js +0 -3
  157. package/dist/src/types/index.js.map +0 -1
  158. package/dist/src/utils/access.js +0 -80
  159. package/dist/src/utils/access.js.map +0 -1
  160. package/dist/src/utils/jwt.js +0 -91
  161. package/dist/src/utils/jwt.js.map +0 -1
  162. package/dist/src/utils/validation.js +0 -74
  163. package/dist/src/utils/validation.js.map +0 -1
  164. package/dist/templates/BaseTemplate.d.ts +0 -45
  165. package/dist/templates/BaseTemplate.d.ts.map +0 -1
  166. package/dist/templates/MagicLinkTemplate.d.ts +0 -67
  167. package/dist/templates/MagicLinkTemplate.d.ts.map +0 -1
  168. package/dist/templates/NewsletterTemplate.d.ts +0 -112
  169. package/dist/templates/NewsletterTemplate.d.ts.map +0 -1
  170. package/dist/templates/WelcomeTemplate.d.ts +0 -55
  171. package/dist/templates/WelcomeTemplate.d.ts.map +0 -1
  172. package/dist/templates/index.d.ts +0 -7
  173. package/dist/templates/index.d.ts.map +0 -1
  174. package/dist/types/index.d.ts.map +0 -1
  175. package/dist/utils/access.d.ts +0 -15
  176. package/dist/utils/access.d.ts.map +0 -1
  177. package/dist/utils/jwt.d.ts +0 -32
  178. package/dist/utils/jwt.d.ts.map +0 -1
  179. package/dist/utils/validation.d.ts +0 -25
  180. package/dist/utils/validation.d.ts.map +0 -1
@@ -1,390 +0,0 @@
1
- import { adminOnly } from '../utils/access';
2
- export const createNewsletterSettingsCollection = (pluginConfig)=>{
3
- const slug = pluginConfig.settingsSlug || 'newsletter-settings';
4
- return {
5
- slug,
6
- labels: {
7
- singular: 'Newsletter Setting',
8
- plural: 'Newsletter Settings'
9
- },
10
- admin: {
11
- useAsTitle: 'name',
12
- defaultColumns: [
13
- 'name',
14
- 'provider',
15
- 'active',
16
- 'updatedAt'
17
- ],
18
- group: 'Newsletter',
19
- description: 'Configure email provider settings and templates'
20
- },
21
- fields: [
22
- {
23
- name: 'name',
24
- type: 'text',
25
- label: 'Configuration Name',
26
- required: true,
27
- admin: {
28
- description: 'A descriptive name for this configuration (e.g., "Production", "Development", "Marketing Emails")'
29
- }
30
- },
31
- {
32
- name: 'active',
33
- type: 'checkbox',
34
- label: 'Active',
35
- defaultValue: false,
36
- admin: {
37
- description: 'Only one configuration can be active at a time'
38
- }
39
- },
40
- {
41
- type: 'tabs',
42
- tabs: [
43
- {
44
- label: 'Provider Settings',
45
- fields: [
46
- {
47
- name: 'provider',
48
- type: 'select',
49
- label: 'Email Provider',
50
- required: true,
51
- options: [
52
- {
53
- label: 'Resend',
54
- value: 'resend'
55
- },
56
- {
57
- label: 'Broadcast (Self-Hosted)',
58
- value: 'broadcast'
59
- }
60
- ],
61
- defaultValue: pluginConfig.providers.default,
62
- admin: {
63
- description: 'Choose which email service to use'
64
- }
65
- },
66
- {
67
- name: 'resendSettings',
68
- type: 'group',
69
- label: 'Resend Settings',
70
- admin: {
71
- condition: (data)=>data?.provider === 'resend'
72
- },
73
- fields: [
74
- {
75
- name: 'apiKey',
76
- type: 'text',
77
- label: 'API Key',
78
- required: true,
79
- admin: {
80
- description: 'Your Resend API key'
81
- }
82
- },
83
- {
84
- name: 'audienceIds',
85
- type: 'array',
86
- label: 'Audience IDs by Locale',
87
- fields: [
88
- {
89
- name: 'locale',
90
- type: 'select',
91
- label: 'Locale',
92
- required: true,
93
- options: pluginConfig.i18n?.locales?.map((locale)=>({
94
- label: locale.toUpperCase(),
95
- value: locale
96
- })) || [
97
- {
98
- label: 'EN',
99
- value: 'en'
100
- }
101
- ]
102
- },
103
- {
104
- name: 'production',
105
- type: 'text',
106
- label: 'Production Audience ID'
107
- },
108
- {
109
- name: 'development',
110
- type: 'text',
111
- label: 'Development Audience ID'
112
- }
113
- ]
114
- }
115
- ]
116
- },
117
- {
118
- name: 'broadcastSettings',
119
- type: 'group',
120
- label: 'Broadcast Settings',
121
- admin: {
122
- condition: (data)=>data?.provider === 'broadcast'
123
- },
124
- fields: [
125
- {
126
- name: 'apiUrl',
127
- type: 'text',
128
- label: 'API URL',
129
- required: true,
130
- admin: {
131
- description: 'Your Broadcast instance URL'
132
- }
133
- },
134
- {
135
- name: 'productionToken',
136
- type: 'text',
137
- label: 'Production Token',
138
- admin: {
139
- description: 'Token for production environment'
140
- }
141
- },
142
- {
143
- name: 'developmentToken',
144
- type: 'text',
145
- label: 'Development Token',
146
- admin: {
147
- description: 'Token for development environment'
148
- }
149
- }
150
- ]
151
- },
152
- {
153
- name: 'fromAddress',
154
- type: 'email',
155
- label: 'From Address',
156
- required: true,
157
- admin: {
158
- description: 'Default sender email address'
159
- }
160
- },
161
- {
162
- name: 'fromName',
163
- type: 'text',
164
- label: 'From Name',
165
- required: true,
166
- admin: {
167
- description: 'Default sender name'
168
- }
169
- },
170
- {
171
- name: 'replyTo',
172
- type: 'email',
173
- label: 'Reply-To Address',
174
- admin: {
175
- description: 'Optional reply-to email address'
176
- }
177
- }
178
- ]
179
- },
180
- {
181
- label: 'Email Templates',
182
- fields: [
183
- {
184
- name: 'emailTemplates',
185
- type: 'group',
186
- label: 'Email Templates',
187
- fields: [
188
- {
189
- name: 'welcome',
190
- type: 'group',
191
- label: 'Welcome Email',
192
- fields: [
193
- {
194
- name: 'enabled',
195
- type: 'checkbox',
196
- label: 'Send Welcome Email',
197
- defaultValue: true
198
- },
199
- {
200
- name: 'subject',
201
- type: 'text',
202
- label: 'Subject Line',
203
- defaultValue: 'Welcome to {{fromName}}!',
204
- admin: {
205
- condition: (data)=>data?.emailTemplates?.welcome?.enabled
206
- }
207
- },
208
- {
209
- name: 'preheader',
210
- type: 'text',
211
- label: 'Preheader Text',
212
- admin: {
213
- condition: (data)=>data?.emailTemplates?.welcome?.enabled
214
- }
215
- }
216
- ]
217
- },
218
- {
219
- name: 'magicLink',
220
- type: 'group',
221
- label: 'Magic Link Email',
222
- fields: [
223
- {
224
- name: 'subject',
225
- type: 'text',
226
- label: 'Subject Line',
227
- defaultValue: 'Sign in to {{fromName}}'
228
- },
229
- {
230
- name: 'preheader',
231
- type: 'text',
232
- label: 'Preheader Text',
233
- defaultValue: 'Click the link to access your preferences'
234
- },
235
- {
236
- name: 'expirationTime',
237
- type: 'select',
238
- label: 'Link Expiration',
239
- defaultValue: '7d',
240
- options: [
241
- {
242
- label: '1 hour',
243
- value: '1h'
244
- },
245
- {
246
- label: '24 hours',
247
- value: '24h'
248
- },
249
- {
250
- label: '7 days',
251
- value: '7d'
252
- },
253
- {
254
- label: '30 days',
255
- value: '30d'
256
- }
257
- ]
258
- }
259
- ]
260
- }
261
- ]
262
- }
263
- ]
264
- },
265
- {
266
- label: 'Subscription Settings',
267
- fields: [
268
- {
269
- name: 'subscriptionSettings',
270
- type: 'group',
271
- label: 'Subscription Settings',
272
- fields: [
273
- {
274
- name: 'requireDoubleOptIn',
275
- type: 'checkbox',
276
- label: 'Require Double Opt-In',
277
- defaultValue: false,
278
- admin: {
279
- description: 'Require email confirmation before activating subscriptions'
280
- }
281
- },
282
- {
283
- name: 'allowedDomains',
284
- type: 'array',
285
- label: 'Allowed Email Domains',
286
- admin: {
287
- description: 'Leave empty to allow all domains'
288
- },
289
- fields: [
290
- {
291
- name: 'domain',
292
- type: 'text',
293
- label: 'Domain',
294
- required: true,
295
- admin: {
296
- placeholder: 'example.com'
297
- }
298
- }
299
- ]
300
- },
301
- {
302
- name: 'maxSubscribersPerIP',
303
- type: 'number',
304
- label: 'Max Subscribers per IP',
305
- defaultValue: 10,
306
- min: 1,
307
- admin: {
308
- description: 'Maximum number of subscriptions allowed from a single IP address'
309
- }
310
- }
311
- ]
312
- }
313
- ]
314
- }
315
- ]
316
- }
317
- ],
318
- hooks: {
319
- beforeChange: [
320
- async ({ data, req, operation })=>{
321
- // Verify admin access for settings changes
322
- if (!req.user || req.user.collection !== 'users') {
323
- throw new Error('Only administrators can modify newsletter settings');
324
- }
325
- // If setting this config as active, deactivate all others
326
- if (data?.active && operation !== 'create') {
327
- await req.payload.update({
328
- collection: slug,
329
- where: {
330
- id: {
331
- not_equals: data.id
332
- }
333
- },
334
- data: {
335
- active: false
336
- }
337
- });
338
- }
339
- // For new configs, ensure only one is active
340
- if (operation === 'create' && data?.active) {
341
- const existingActive = await req.payload.find({
342
- collection: slug,
343
- where: {
344
- active: {
345
- equals: true
346
- }
347
- }
348
- });
349
- if (existingActive.docs.length > 0) {
350
- // Deactivate existing active configs
351
- for (const doc of existingActive.docs){
352
- await req.payload.update({
353
- collection: slug,
354
- id: doc.id,
355
- data: {
356
- active: false
357
- }
358
- });
359
- }
360
- }
361
- }
362
- return data;
363
- }
364
- ],
365
- afterChange: [
366
- async ({ doc, req })=>{
367
- // Reinitialize email service when settings change
368
- if (req.payload.newsletterEmailService && doc.active) {
369
- try {
370
- // TODO: Implement email service reinitialization
371
- console.warn('Newsletter settings updated, reinitializing service...');
372
- } catch (error) {
373
- console.error('Failed to reinitialize email service:', error);
374
- }
375
- }
376
- return doc;
377
- }
378
- ]
379
- },
380
- access: {
381
- read: ()=>true,
382
- create: adminOnly(pluginConfig),
383
- update: adminOnly(pluginConfig),
384
- delete: adminOnly(pluginConfig)
385
- },
386
- timestamps: true
387
- };
388
- };
389
-
390
- //# sourceMappingURL=NewsletterSettings.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/collections/NewsletterSettings.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { NewsletterPluginConfig } from '../types'\nimport { adminOnly } from '../utils/access'\n\nexport const createNewsletterSettingsCollection = (\n pluginConfig: NewsletterPluginConfig\n): CollectionConfig => {\n const slug = pluginConfig.settingsSlug || 'newsletter-settings'\n \n return {\n slug,\n labels: {\n singular: 'Newsletter Setting',\n plural: 'Newsletter Settings',\n },\n admin: {\n useAsTitle: 'name',\n defaultColumns: ['name', 'provider', 'active', 'updatedAt'],\n group: 'Newsletter',\n description: 'Configure email provider settings and templates',\n },\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Configuration Name',\n required: true,\n admin: {\n description: 'A descriptive name for this configuration (e.g., \"Production\", \"Development\", \"Marketing Emails\")',\n },\n },\n {\n name: 'active',\n type: 'checkbox',\n label: 'Active',\n defaultValue: false,\n admin: {\n description: 'Only one configuration can be active at a time',\n },\n },\n {\n type: 'tabs',\n tabs: [\n {\n label: 'Provider Settings',\n fields: [\n {\n name: 'provider',\n type: 'select',\n label: 'Email Provider',\n required: true,\n options: [\n { label: 'Resend', value: 'resend' },\n { label: 'Broadcast (Self-Hosted)', value: 'broadcast' },\n ],\n defaultValue: pluginConfig.providers.default,\n admin: {\n description: 'Choose which email service to use',\n },\n },\n {\n name: 'resendSettings',\n type: 'group',\n label: 'Resend Settings',\n admin: {\n condition: (data) => data?.provider === 'resend',\n },\n fields: [\n {\n name: 'apiKey',\n type: 'text',\n label: 'API Key',\n required: true,\n admin: {\n description: 'Your Resend API key',\n },\n },\n {\n name: 'audienceIds',\n type: 'array',\n label: 'Audience IDs by Locale',\n fields: [\n {\n name: 'locale',\n type: 'select',\n label: 'Locale',\n required: true,\n options: pluginConfig.i18n?.locales?.map(locale => ({\n label: locale.toUpperCase(),\n value: locale,\n })) || [\n { label: 'EN', value: 'en' },\n ],\n },\n {\n name: 'production',\n type: 'text',\n label: 'Production Audience ID',\n },\n {\n name: 'development',\n type: 'text',\n label: 'Development Audience ID',\n },\n ],\n },\n ],\n },\n {\n name: 'broadcastSettings',\n type: 'group',\n label: 'Broadcast Settings',\n admin: {\n condition: (data) => data?.provider === 'broadcast',\n },\n fields: [\n {\n name: 'apiUrl',\n type: 'text',\n label: 'API URL',\n required: true,\n admin: {\n description: 'Your Broadcast instance URL',\n },\n },\n {\n name: 'productionToken',\n type: 'text',\n label: 'Production Token',\n admin: {\n description: 'Token for production environment',\n },\n },\n {\n name: 'developmentToken',\n type: 'text',\n label: 'Development Token',\n admin: {\n description: 'Token for development environment',\n },\n },\n ],\n },\n {\n name: 'fromAddress',\n type: 'email',\n label: 'From Address',\n required: true,\n admin: {\n description: 'Default sender email address',\n },\n },\n {\n name: 'fromName',\n type: 'text',\n label: 'From Name',\n required: true,\n admin: {\n description: 'Default sender name',\n },\n },\n {\n name: 'replyTo',\n type: 'email',\n label: 'Reply-To Address',\n admin: {\n description: 'Optional reply-to email address',\n },\n },\n ],\n },\n {\n label: 'Email Templates',\n fields: [\n {\n name: 'emailTemplates',\n type: 'group',\n label: 'Email Templates',\n fields: [\n {\n name: 'welcome',\n type: 'group',\n label: 'Welcome Email',\n fields: [\n {\n name: 'enabled',\n type: 'checkbox',\n label: 'Send Welcome Email',\n defaultValue: true,\n },\n {\n name: 'subject',\n type: 'text',\n label: 'Subject Line',\n defaultValue: 'Welcome to {{fromName}}!',\n admin: {\n condition: (data) => data?.emailTemplates?.welcome?.enabled,\n },\n },\n {\n name: 'preheader',\n type: 'text',\n label: 'Preheader Text',\n admin: {\n condition: (data) => data?.emailTemplates?.welcome?.enabled,\n },\n },\n ],\n },\n {\n name: 'magicLink',\n type: 'group',\n label: 'Magic Link Email',\n fields: [\n {\n name: 'subject',\n type: 'text',\n label: 'Subject Line',\n defaultValue: 'Sign in to {{fromName}}',\n },\n {\n name: 'preheader',\n type: 'text',\n label: 'Preheader Text',\n defaultValue: 'Click the link to access your preferences',\n },\n {\n name: 'expirationTime',\n type: 'select',\n label: 'Link Expiration',\n defaultValue: '7d',\n options: [\n { label: '1 hour', value: '1h' },\n { label: '24 hours', value: '24h' },\n { label: '7 days', value: '7d' },\n { label: '30 days', value: '30d' },\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n {\n label: 'Subscription Settings',\n fields: [\n {\n name: 'subscriptionSettings',\n type: 'group',\n label: 'Subscription Settings',\n fields: [\n {\n name: 'requireDoubleOptIn',\n type: 'checkbox',\n label: 'Require Double Opt-In',\n defaultValue: false,\n admin: {\n description: 'Require email confirmation before activating subscriptions',\n },\n },\n {\n name: 'allowedDomains',\n type: 'array',\n label: 'Allowed Email Domains',\n admin: {\n description: 'Leave empty to allow all domains',\n },\n fields: [\n {\n name: 'domain',\n type: 'text',\n label: 'Domain',\n required: true,\n admin: {\n placeholder: 'example.com',\n },\n },\n ],\n },\n {\n name: 'maxSubscribersPerIP',\n type: 'number',\n label: 'Max Subscribers per IP',\n defaultValue: 10,\n min: 1,\n admin: {\n description: 'Maximum number of subscriptions allowed from a single IP address',\n },\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n hooks: {\n beforeChange: [\n async ({ data, req, operation }) => {\n // Verify admin access for settings changes\n if (!req.user || req.user.collection !== 'users') {\n throw new Error('Only administrators can modify newsletter settings')\n }\n \n // If setting this config as active, deactivate all others\n if (data?.active && operation !== 'create') {\n await req.payload.update({\n collection: slug,\n where: {\n id: {\n not_equals: data.id,\n },\n },\n data: {\n active: false,\n },\n // Keep overrideAccess: true for admin operations after verification\n })\n }\n \n // For new configs, ensure only one is active\n if (operation === 'create' && data?.active) {\n const existingActive = await req.payload.find({\n collection: slug,\n where: {\n active: {\n equals: true,\n },\n },\n // Keep overrideAccess: true for admin operations\n })\n \n if (existingActive.docs.length > 0) {\n // Deactivate existing active configs\n for (const doc of existingActive.docs) {\n await req.payload.update({\n collection: slug,\n id: doc.id,\n data: {\n active: false,\n },\n // Keep overrideAccess: true for admin operations\n })\n }\n }\n }\n \n return data\n },\n ],\n afterChange: [\n async ({ doc, req }) => {\n // Reinitialize email service when settings change\n if ((req.payload as any).newsletterEmailService && doc.active) {\n try {\n // TODO: Implement email service reinitialization\n console.warn('Newsletter settings updated, reinitializing service...')\n } catch (error) {\n console.error('Failed to reinitialize email service:', error)\n }\n }\n \n return doc\n },\n ],\n },\n access: {\n read: () => true, // Settings can be read publicly for validation\n create: adminOnly(pluginConfig),\n update: adminOnly(pluginConfig),\n delete: adminOnly(pluginConfig),\n },\n timestamps: true,\n }\n}"],"names":["adminOnly","createNewsletterSettingsCollection","pluginConfig","slug","settingsSlug","labels","singular","plural","admin","useAsTitle","defaultColumns","group","description","fields","name","type","label","required","defaultValue","tabs","options","value","providers","default","condition","data","provider","i18n","locales","map","locale","toUpperCase","emailTemplates","welcome","enabled","placeholder","min","hooks","beforeChange","req","operation","user","collection","Error","active","payload","update","where","id","not_equals","existingActive","find","equals","docs","length","doc","afterChange","newsletterEmailService","console","warn","error","access","read","create","delete","timestamps"],"mappings":"AAEA,SAASA,SAAS,QAAQ,kBAAiB;AAE3C,OAAO,MAAMC,qCAAqC,CAChDC;IAEA,MAAMC,OAAOD,aAAaE,YAAY,IAAI;IAE1C,OAAO;QACLD;QACAE,QAAQ;YACNC,UAAU;YACVC,QAAQ;QACV;QACAC,OAAO;YACLC,YAAY;YACZC,gBAAgB;gBAAC;gBAAQ;gBAAY;gBAAU;aAAY;YAC3DC,OAAO;YACPC,aAAa;QACf;QACAC,QAAQ;YACN;gBACEC,MAAM;gBACNC,MAAM;gBACNC,OAAO;gBACPC,UAAU;gBACVT,OAAO;oBACLI,aAAa;gBACf;YACF;YACA;gBACEE,MAAM;gBACNC,MAAM;gBACNC,OAAO;gBACPE,cAAc;gBACdV,OAAO;oBACLI,aAAa;gBACf;YACF;YACA;gBACEG,MAAM;gBACNI,MAAM;oBACJ;wBACEH,OAAO;wBACPH,QAAQ;4BACN;gCACEC,MAAM;gCACNC,MAAM;gCACNC,OAAO;gCACPC,UAAU;gCACVG,SAAS;oCACP;wCAAEJ,OAAO;wCAAUK,OAAO;oCAAS;oCACnC;wCAAEL,OAAO;wCAA2BK,OAAO;oCAAY;iCACxD;gCACDH,cAAchB,aAAaoB,SAAS,CAACC,OAAO;gCAC5Cf,OAAO;oCACLI,aAAa;gCACf;4BACF;4BACA;gCACEE,MAAM;gCACNC,MAAM;gCACNC,OAAO;gCACPR,OAAO;oCACLgB,WAAW,CAACC,OAASA,MAAMC,aAAa;gCAC1C;gCACAb,QAAQ;oCACN;wCACEC,MAAM;wCACNC,MAAM;wCACNC,OAAO;wCACPC,UAAU;wCACVT,OAAO;4CACLI,aAAa;wCACf;oCACF;oCACA;wCACEE,MAAM;wCACNC,MAAM;wCACNC,OAAO;wCACPH,QAAQ;4CACN;gDACEC,MAAM;gDACNC,MAAM;gDACNC,OAAO;gDACPC,UAAU;gDACVG,SAASlB,aAAayB,IAAI,EAAEC,SAASC,IAAIC,CAAAA,SAAW,CAAA;wDAClDd,OAAOc,OAAOC,WAAW;wDACzBV,OAAOS;oDACT,CAAA,MAAO;oDACL;wDAAEd,OAAO;wDAAMK,OAAO;oDAAK;iDAC5B;4CACH;4CACA;gDACEP,MAAM;gDACNC,MAAM;gDACNC,OAAO;4CACT;4CACA;gDACEF,MAAM;gDACNC,MAAM;gDACNC,OAAO;4CACT;yCACD;oCACH;iCACD;4BACH;4BACA;gCACEF,MAAM;gCACNC,MAAM;gCACNC,OAAO;gCACPR,OAAO;oCACLgB,WAAW,CAACC,OAASA,MAAMC,aAAa;gCAC1C;gCACAb,QAAQ;oCACN;wCACEC,MAAM;wCACNC,MAAM;wCACNC,OAAO;wCACPC,UAAU;wCACVT,OAAO;4CACLI,aAAa;wCACf;oCACF;oCACA;wCACEE,MAAM;wCACNC,MAAM;wCACNC,OAAO;wCACPR,OAAO;4CACLI,aAAa;wCACf;oCACF;oCACA;wCACEE,MAAM;wCACNC,MAAM;wCACNC,OAAO;wCACPR,OAAO;4CACLI,aAAa;wCACf;oCACF;iCACD;4BACH;4BACA;gCACEE,MAAM;gCACNC,MAAM;gCACNC,OAAO;gCACPC,UAAU;gCACVT,OAAO;oCACLI,aAAa;gCACf;4BACF;4BACA;gCACEE,MAAM;gCACNC,MAAM;gCACNC,OAAO;gCACPC,UAAU;gCACVT,OAAO;oCACLI,aAAa;gCACf;4BACF;4BACA;gCACEE,MAAM;gCACNC,MAAM;gCACNC,OAAO;gCACPR,OAAO;oCACLI,aAAa;gCACf;4BACF;yBACD;oBACH;oBACA;wBACEI,OAAO;wBACPH,QAAQ;4BACN;gCACEC,MAAM;gCACNC,MAAM;gCACNC,OAAO;gCACPH,QAAQ;oCACN;wCACEC,MAAM;wCACNC,MAAM;wCACNC,OAAO;wCACPH,QAAQ;4CACN;gDACEC,MAAM;gDACNC,MAAM;gDACNC,OAAO;gDACPE,cAAc;4CAChB;4CACA;gDACEJ,MAAM;gDACNC,MAAM;gDACNC,OAAO;gDACPE,cAAc;gDACdV,OAAO;oDACLgB,WAAW,CAACC,OAASA,MAAMO,gBAAgBC,SAASC;gDACtD;4CACF;4CACA;gDACEpB,MAAM;gDACNC,MAAM;gDACNC,OAAO;gDACPR,OAAO;oDACLgB,WAAW,CAACC,OAASA,MAAMO,gBAAgBC,SAASC;gDACtD;4CACF;yCACD;oCACH;oCACA;wCACEpB,MAAM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"}