payload-plugin-marketing 0.9.3 → 0.9.4

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 (62) hide show
  1. package/README.md +68 -19
  2. package/dist/admin/client.cjs +3 -0
  3. package/dist/admin/client.cjs.map +1 -0
  4. package/dist/admin/client.d.ts +7 -0
  5. package/dist/admin/client.d.ts.map +1 -0
  6. package/dist/admin/client.js +3 -0
  7. package/dist/admin/client.js.map +1 -0
  8. package/dist/admin/components/audience-buttons.d.ts.map +1 -1
  9. package/dist/admin/components/broadcast-list.d.ts.map +1 -1
  10. package/dist/admin/components/broadcasts-table.d.ts.map +1 -1
  11. package/dist/admin/components/contacts-table.d.ts.map +1 -1
  12. package/dist/admin/components/create-broadcast-button.d.ts +9 -1
  13. package/dist/admin/components/create-broadcast-button.d.ts.map +1 -1
  14. package/dist/admin/components/marketing-components.d.ts +0 -6
  15. package/dist/admin/components/marketing-components.d.ts.map +1 -1
  16. package/dist/admin/components/marketing-view-shell.d.ts.map +1 -1
  17. package/dist/admin/components/payload-modal.d.ts +8 -8
  18. package/dist/admin/components/payload-modal.d.ts.map +1 -1
  19. package/dist/admin/constants.cjs +2 -0
  20. package/dist/admin/constants.cjs.map +1 -0
  21. package/dist/admin/constants.d.ts +2 -0
  22. package/dist/admin/constants.d.ts.map +1 -0
  23. package/dist/admin/constants.js +2 -0
  24. package/dist/admin/constants.js.map +1 -0
  25. package/dist/admin/index.cjs +1 -1
  26. package/dist/admin/index.cjs.map +1 -1
  27. package/dist/admin/index.d.ts +3 -3
  28. package/dist/admin/index.d.ts.map +1 -1
  29. package/dist/admin/index.js +1 -1
  30. package/dist/admin/index.js.map +1 -1
  31. package/dist/admin/locale-options.d.ts +7 -0
  32. package/dist/admin/locale-options.d.ts.map +1 -0
  33. package/dist/admin/server.cjs +2 -0
  34. package/dist/admin/server.cjs.map +1 -0
  35. package/dist/admin/server.d.ts +2 -0
  36. package/dist/admin/server.d.ts.map +1 -0
  37. package/dist/admin/server.js +2 -0
  38. package/dist/admin/server.js.map +1 -0
  39. package/dist/admin/use-marketing-api.d.ts.map +1 -1
  40. package/dist/{chunk-S2EABBIN.js → chunk-G6DIJ7B2.js} +1 -1
  41. package/dist/chunk-G6DIJ7B2.js.map +1 -0
  42. package/dist/email-broadcast-template.d.ts +15 -0
  43. package/dist/email-broadcast-template.d.ts.map +1 -0
  44. package/dist/endpoints/marketing-endpoints.d.ts.map +1 -1
  45. package/dist/form-builder/index.cjs.map +1 -1
  46. package/dist/form-builder/index.js +1 -1
  47. package/dist/form-builder/normalize-placeholder-rows.d.ts.map +1 -1
  48. package/dist/index.cjs +1 -1
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.ts +1 -1
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +1 -1
  53. package/dist/index.js.map +1 -1
  54. package/dist/marketing-integration.d.ts +2 -1
  55. package/dist/marketing-integration.d.ts.map +1 -1
  56. package/dist/plugin.d.ts.map +1 -1
  57. package/dist/types.d.ts +31 -0
  58. package/dist/types.d.ts.map +1 -1
  59. package/package.json +10 -2
  60. package/dist/chunk-S2EABBIN.js.map +0 -1
  61. package/dist/chunk-SX3OTOU2.js +0 -2
  62. package/dist/chunk-SX3OTOU2.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/endpoints/marketing-endpoints.ts","../src/plugin.ts"],"sourcesContent":["import {\n getMarketingIntegrationFromRequest,\n marketingMetaAllowed,\n resolveMarketingPermissions,\n} from \"../marketing-integration\"\n\nimport type { CreateBroadcastInput, UpsertContactInput } from \"../types\"\nimport type { Endpoint, PayloadRequest } from \"payload\"\n\ntype MarketingPermissionResource = \"audiences\" | \"broadcasts\" | \"contacts\"\n\nfunction unauthorized() {\n return Response.json({ message: \"Unauthorized\" }, { status: 401 })\n}\n\nfunction forbidden() {\n return Response.json({ message: \"Forbidden\" }, { status: 403 })\n}\n\nfunction assertAuthenticated(req: PayloadRequest): Response | null {\n if (!req.user) return unauthorized()\n return null\n}\n\nfunction effectiveForRequest(req: PayloadRequest) {\n const { permissions } = getMarketingIntegrationFromRequest(req)\n return resolveMarketingPermissions(permissions)\n}\n\nfunction assertMarketingPermission(\n req: PayloadRequest,\n resource: MarketingPermissionResource,\n action: \"read\" | \"write\",\n): Response | null {\n const auth = assertAuthenticated(req)\n if (auth) return auth\n const eff = effectiveForRequest(req)\n if (!eff[resource][action]) return forbidden()\n return null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\")\n}\n\nasync function parseRequestJson(req: PayloadRequest): Promise<unknown> {\n return (await (req as unknown as Request).json()) as unknown\n}\n\nfunction adapterFor(req: PayloadRequest) {\n return getMarketingIntegrationFromRequest(req).adapter\n}\n\nexport function createMarketingEndpoints(): Endpoint[] {\n return [\n {\n handler: (req) => {\n const auth = assertAuthenticated(req)\n if (auth) return auth\n if (!marketingMetaAllowed(effectiveForRequest(req))) return forbidden()\n const { adapter } = getMarketingIntegrationFromRequest(req)\n return Response.json({\n label: adapter.label,\n provider: adapter.provider,\n urls: {\n audience: adapter.urls?.audiences,\n broadcasts: adapter.urls?.broadcasts,\n },\n })\n },\n method: \"get\",\n path: \"/marketing/meta\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"audiences\", \"read\")\n if (denied) return denied\n const adapter = getMarketingIntegrationFromRequest(req).adapter\n return Response.json(await adapter.audiences.list())\n },\n method: \"get\",\n path: \"/marketing/audiences\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"audiences\", \"write\")\n if (denied) return denied\n const bodyUnknown = await parseRequestJson(req)\n const name =\n typeof (bodyUnknown as { name?: unknown })?.name === \"string\"\n ? (bodyUnknown as { name: string }).name.trim()\n : \"\"\n if (!name) {\n return Response.json({ message: \"name is required\" }, { status: 400 })\n }\n await adapterFor(req).audiences.create({ name })\n return Response.json({ ok: true })\n },\n method: \"post\",\n path: \"/marketing/audiences\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"audiences\", \"read\")\n if (denied) return denied\n const id = typeof req.routeParams?.id === \"string\" ? req.routeParams.id : \"\"\n if (!id) {\n return Response.json({ message: \"Missing audience id\" }, { status: 400 })\n }\n const adapter = getMarketingIntegrationFromRequest(req).adapter\n const audience = await adapter.audiences.get(id)\n if (!audience) {\n return Response.json({ message: \"Not found\" }, { status: 404 })\n }\n return Response.json(audience)\n },\n method: \"get\",\n path: \"/marketing/audiences/:id\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"audiences\", \"write\")\n if (denied) return denied\n const id = typeof req.routeParams?.id === \"string\" ? req.routeParams.id : \"\"\n if (!id) {\n return Response.json({ message: \"Missing audience id\" }, { status: 400 })\n }\n await adapterFor(req).audiences.delete({ audienceId: id })\n return Response.json({ ok: true })\n },\n method: \"delete\",\n path: \"/marketing/audiences/:id\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"contacts\", \"read\")\n if (denied) return denied\n const audienceId =\n typeof req.routeParams?.audienceId === \"string\" ? req.routeParams.audienceId : \"\"\n if (!audienceId) {\n return Response.json({ message: \"Missing audience id\" }, { status: 400 })\n }\n const adapter = getMarketingIntegrationFromRequest(req).adapter\n return Response.json(await adapter.contacts.list({ audienceId }))\n },\n method: \"get\",\n path: \"/marketing/audiences/:audienceId/contacts\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"contacts\", \"write\")\n if (denied) return denied\n const audienceId =\n typeof req.routeParams?.audienceId === \"string\" ? req.routeParams.audienceId : \"\"\n const contactId =\n typeof req.routeParams?.contactId === \"string\" ? req.routeParams.contactId : \"\"\n if (!audienceId || !contactId) {\n return Response.json({ message: \"Missing audienceId or contactId\" }, { status: 400 })\n }\n await adapterFor(req).contacts.delete({ audienceId, contactId })\n return Response.json({ ok: true })\n },\n method: \"delete\",\n path: \"/marketing/audiences/:audienceId/contacts/:contactId\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"contacts\", \"write\")\n if (denied) return denied\n const bodyUnknown = await parseRequestJson(req)\n if (!isRecord(bodyUnknown)) {\n return Response.json({ message: \"Invalid JSON\" }, { status: 400 })\n }\n\n const email =\n typeof bodyUnknown.email === \"string\" ? bodyUnknown.email.trim() : undefined\n const audienceId =\n typeof bodyUnknown.audienceId === \"string\" ? bodyUnknown.audienceId : undefined\n\n if (!audienceId || !email) {\n return Response.json(\n { message: \"audienceId and email are required\" },\n { status: 400 },\n )\n }\n\n const payloadUpsert: UpsertContactInput = {\n audienceId,\n email,\n subscribed:\n typeof bodyUnknown.subscribed === \"boolean\" ? bodyUnknown.subscribed : true,\n }\n\n if (typeof bodyUnknown.id === \"string\" && bodyUnknown.id) {\n payloadUpsert.id = bodyUnknown.id\n }\n if (typeof bodyUnknown.firstName === \"string\") {\n payloadUpsert.firstName = bodyUnknown.firstName\n }\n if (typeof bodyUnknown.lastName === \"string\") {\n payloadUpsert.lastName = bodyUnknown.lastName\n }\n if (isRecord(bodyUnknown.properties)) {\n payloadUpsert.properties = bodyUnknown.properties as Record<\n string,\n string | number | null\n >\n }\n\n await adapterFor(req).contacts.upsert(payloadUpsert)\n return Response.json({ ok: true })\n },\n method: \"post\",\n path: \"/marketing/contacts\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"broadcasts\", \"read\")\n if (denied) return denied\n const adapter = getMarketingIntegrationFromRequest(req).adapter\n const broadcasts = await adapter.broadcasts.list()\n const enriched = broadcasts.map((b) => ({\n ...b,\n externalDashboardUrl: adapter.urls?.broadcast?.(b.id),\n }))\n return Response.json(enriched)\n },\n method: \"get\",\n path: \"/marketing/broadcasts\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"broadcasts\", \"write\")\n if (denied) return denied\n const bodyUnknown = await parseRequestJson(req)\n if (!isRecord(bodyUnknown)) {\n return Response.json({ message: \"Invalid JSON\" }, { status: 400 })\n }\n\n const audienceIdRaw =\n typeof bodyUnknown.audienceId === \"string\" ? bodyUnknown.audienceId.trim() : \"\"\n const name = typeof bodyUnknown.name === \"string\" ? bodyUnknown.name.trim() : \"\"\n const subject =\n typeof bodyUnknown.subject === \"string\" ? bodyUnknown.subject.trim() : \"\"\n const templateIdRaw =\n typeof bodyUnknown.templateId === \"string\" ? bodyUnknown.templateId.trim() : \"\"\n\n const htmlProvided = typeof bodyUnknown.html === \"string\" ? bodyUnknown.html.trim() : \"\"\n const replyTo =\n typeof bodyUnknown.replyTo === \"string\" ? bodyUnknown.replyTo.trim() : undefined\n const locale =\n typeof bodyUnknown.locale === \"string\" ? bodyUnknown.locale : undefined\n\n if (!audienceIdRaw || !name || !subject) {\n return Response.json(\n { message: \"audienceId, name, and subject are required\" },\n { status: 400 },\n )\n }\n\n const hasTpl = Boolean(templateIdRaw !== \"\")\n if (!hasTpl && !htmlProvided) {\n return Response.json(\n { message: \"Provide HTML body or a template id.\" },\n { status: 400 },\n )\n }\n\n let normalized: CreateBroadcastInput\n if (hasTpl && htmlProvided !== \"\") {\n return Response.json(\n { message: \"Use either HTML or template id, not both.\" },\n { status: 400 },\n )\n }\n if (hasTpl) {\n normalized = {\n audienceId: audienceIdRaw,\n locale,\n name,\n replyTo,\n subject,\n templateId: templateIdRaw,\n }\n } else {\n normalized = {\n audienceId: audienceIdRaw,\n html: htmlProvided,\n locale,\n name,\n replyTo,\n subject,\n }\n }\n\n await adapterFor(req).broadcasts.create(normalized)\n return Response.json({ ok: true })\n },\n method: \"post\",\n path: \"/marketing/broadcasts\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"broadcasts\", \"write\")\n if (denied) return denied\n const broadcastId =\n typeof req.routeParams?.broadcastId === \"string\" ? req.routeParams.broadcastId : \"\"\n if (!broadcastId) {\n return Response.json({ message: \"Missing broadcast id\" }, { status: 400 })\n }\n await adapterFor(req).broadcasts.delete({ broadcastId })\n return Response.json({ ok: true })\n },\n method: \"delete\",\n path: \"/marketing/broadcasts/:broadcastId\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"broadcasts\", \"write\")\n if (denied) return denied\n const broadcastId =\n typeof req.routeParams?.broadcastId === \"string\" ? req.routeParams.broadcastId : \"\"\n if (!broadcastId) {\n return Response.json({ message: \"Missing broadcast id\" }, { status: 400 })\n }\n\n let scheduledAt: string | undefined\n try {\n const cloned = (req as unknown as Request).clone()\n const payloadBody: unknown = await cloned.json()\n if (isRecord(payloadBody) && typeof payloadBody.scheduledAt === \"string\") {\n scheduledAt = payloadBody.scheduledAt\n }\n } catch {\n scheduledAt = undefined\n }\n\n await adapterFor(req).broadcasts.send({ broadcastId, scheduledAt })\n return Response.json({ ok: true })\n },\n method: \"post\",\n path: \"/marketing/broadcasts/:broadcastId/send\",\n },\n ]\n}\n","import { createMarketingEndpoints } from \"./endpoints/marketing-endpoints\"\nimport { mutateFormBuilderCollections } from \"./form-builder/mutate-collections\"\nimport {\n MARKETING_CUSTOM_CONFIG_KEY,\n type MarketingIntegrationState,\n} from \"./marketing-integration\"\n\nimport type { PayloadMarketingPlugin, PayloadPluginMarketingOptions } from \"./types\"\nimport type { Config } from \"payload\"\n\nfunction mergeMarketingCustom(\n config: Config,\n integration: MarketingIntegrationState,\n): Record<string, unknown> {\n const prev = config.custom\n const base =\n typeof prev === \"object\" && prev !== null && !Array.isArray(prev)\n ? { ...(prev as Record<string, unknown>) }\n : {}\n base[MARKETING_CUSTOM_CONFIG_KEY] = integration\n return base\n}\n\nfunction component(exportName: string, clientProps?: Record<string, unknown>) {\n return {\n path: \"payload-plugin-marketing/admin\",\n exportName,\n ...(clientProps ? { clientProps } : {}),\n }\n}\n\nfunction adminViewPath(basePath: string, ...segments: string[]): `/${string}` {\n const trimmed = basePath.replace(/^\\/+|\\/+$/g, \"\")\n const body = [trimmed, ...segments].filter(Boolean).join(\"/\")\n return `/${body}`\n}\n\nfunction withMarketingAdmin(config: Config, options: PayloadPluginMarketingOptions): Config {\n if (options.admin?.enabled === false) {\n return config\n }\n const basePath = options.admin?.basePath ?? \"\"\n const components = options.admin?.components ?? {}\n const menuComponent = components.marketingMenu ?? component(\"MarketingMenu\", { basePath })\n const viewClientProps: Record<string, unknown> = { basePath }\n\n const marketingIntegrationState: MarketingIntegrationState = {\n adapter: options.adapter,\n adminBasePath: basePath,\n permissions: options.permissions,\n }\n\n return {\n ...config,\n custom: mergeMarketingCustom(config, marketingIntegrationState),\n endpoints: [...(config.endpoints ?? []), ...createMarketingEndpoints()],\n admin: {\n ...(config.admin ?? {}),\n components: {\n ...(config.admin?.components ?? {}),\n afterNavLinks: [\n ...((config.admin?.components?.afterNavLinks as unknown[]) ?? []),\n menuComponent,\n ],\n views: {\n ...((config.admin?.components?.views as Record<string, unknown> | undefined) ?? {}),\n audienceList: {\n Component: components.audienceList ?? component(\"AudienceList\", viewClientProps),\n path: adminViewPath(basePath, \"audience\"),\n },\n audienceDetail: {\n Component: components.audienceDetail ?? component(\"AudienceDetail\", viewClientProps),\n path: adminViewPath(basePath, \"audience\", \":id\"),\n },\n broadcastList: {\n Component: components.broadcastList ?? component(\"BroadcastList\", viewClientProps),\n path: adminViewPath(basePath, \"broadcast\"),\n },\n },\n },\n },\n } as Config\n}\n\nexport function marketingPlugin(\n options: PayloadPluginMarketingOptions,\n): PayloadMarketingPlugin {\n const plugin: PayloadMarketingPlugin = (config) =>\n withMarketingAdmin(\n {\n ...config,\n collections: mutateFormBuilderCollections(config.collections, options),\n },\n options,\n )\n plugin.slug = \"marketing\"\n plugin.order = 10\n plugin.options = options as unknown as Record<string, unknown>\n return plugin\n}\n"],"mappings":"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","names":["unauthorized","forbidden","assertAuthenticated","req","effectiveForRequest","permissions","getMarketingIntegrationFromRequest","resolveMarketingPermissions","assertMarketingPermission","resource","action","auth","isRecord","value","parseRequestJson","adapterFor","createMarketingEndpoints","marketingMetaAllowed","adapter","denied","bodyUnknown","name","id","audience","audienceId","contactId","email","payloadUpsert","enriched","b","audienceIdRaw","subject","templateIdRaw","htmlProvided","replyTo","locale","hasTpl","normalized","broadcastId","scheduledAt","payloadBody","mergeMarketingCustom","config","integration","prev","base","MARKETING_CUSTOM_CONFIG_KEY","component","exportName","clientProps","adminViewPath","basePath","segments","withMarketingAdmin","options","components","menuComponent","viewClientProps","marketingIntegrationState","createMarketingEndpoints","marketingPlugin","plugin","mutateFormBuilderCollections"]}
1
+ {"version":3,"sources":["../src/marketing-integration.ts","../src/email-broadcast-template.ts","../src/endpoints/marketing-endpoints.ts","../src/plugin.ts"],"sourcesContent":["import type {\n MarketingAdapter,\n MarketingEffectivePermissions,\n MarketingEmailBroadcastTemplate,\n MarketingPluginPermissions,\n} from \"./types\"\nimport type { Payload, PayloadRequest } from \"payload\"\n\nexport const MARKETING_CUSTOM_CONFIG_KEY = \"payloadPluginMarketing\"\n\nexport interface MarketingIntegrationState {\n adapter: MarketingAdapter\n adminBasePath: string\n emailBroadcastTemplates?: MarketingEmailBroadcastTemplate[]\n permissions?: MarketingPluginPermissions\n}\n\nfunction effectiveResource(slice: { read?: boolean; write?: boolean } | undefined): {\n read: boolean\n write: boolean\n} {\n return {\n read: slice?.read ?? true,\n write: slice?.write ?? true,\n }\n}\n\n/** Resolves endpoint access flags. If `permissions` is absent (plugin option omitted), all actions are allowed for authenticated users. */\nexport function resolveMarketingPermissions(\n permissions: MarketingPluginPermissions | undefined,\n): MarketingEffectivePermissions {\n if (!permissions) {\n return {\n audiences: { read: true, write: true },\n broadcasts: { read: true, write: true },\n contacts: { read: true, write: true },\n }\n }\n return {\n audiences: effectiveResource(permissions.audiences),\n contacts: effectiveResource(permissions.contacts),\n broadcasts: effectiveResource(permissions.broadcasts),\n }\n}\n\nexport function marketingMetaAllowed(effective: MarketingEffectivePermissions): boolean {\n return effective.audiences.read || effective.contacts.read || effective.broadcasts.read\n}\n\nfunction readIntegration(payload: Payload): MarketingIntegrationState | undefined {\n const custom = payload.config.custom as Record<string, unknown> | undefined\n if (!custom || typeof custom !== \"object\") {\n return undefined\n }\n const slice = custom[MARKETING_CUSTOM_CONFIG_KEY] as MarketingIntegrationState | undefined\n if (!slice?.adapter) {\n return undefined\n }\n return slice\n}\n\nexport function getMarketingIntegration(payload: Payload): MarketingIntegrationState {\n const state = readIntegration(payload)\n if (!state) {\n throw new Error(\n `${MARKETING_CUSTOM_CONFIG_KEY}: adapter missing on Payload config. Is marketingPlugin() registered?`,\n )\n }\n return state\n}\n\nexport function tryGetMarketingIntegration(\n payload: Payload,\n): MarketingIntegrationState | undefined {\n return readIntegration(payload)\n}\n\nexport function getMarketingIntegrationFromRequest(req: PayloadRequest): MarketingIntegrationState {\n return getMarketingIntegration(req.payload)\n}\n","import React from \"react\"\n\nimport type { MarketingEmailBroadcastTemplate, MarketingEmailTemplateProps } from \"./types\"\nimport type { ComponentType } from \"react\"\n\nconst resolvedComponentCache = new Map<string, ComponentType<MarketingEmailTemplateProps>>()\n\n/**\n * Splits `path` into a dynamic-import specifier and optional named export using a `#` suffix,\n * e.g. `\"@/emails/digest#DigestEmail\"`.\n */\nexport function parseEmailBroadcastTemplatePath(path: string): {\n importPath: string\n namedExport?: string\n} {\n const trimmed = path.trim()\n const hash = trimmed.indexOf(\"#\")\n if (hash === -1) {\n return { importPath: trimmed }\n }\n const importPath = trimmed.slice(0, hash).trim()\n const namedExport = trimmed.slice(hash + 1).trim()\n if (!importPath) {\n throw new Error(\"Invalid email template path: empty module specifier before `#`.\")\n }\n if (!namedExport) {\n throw new Error(\n \"Invalid email template path: expected export name after `#` (e.g. `@/emails/x#Name`).\",\n )\n }\n return { importPath, namedExport }\n}\n\nexport function validateEmailBroadcastTemplates(\n templates: MarketingEmailBroadcastTemplate[],\n): void {\n const seen = new Set<string>()\n for (const t of templates) {\n if (!t.id?.trim()) {\n throw new Error(\"Each emailBroadcastTemplates entry must have a non-empty `id`.\")\n }\n if (!t.name?.trim()) {\n throw new Error(`emailBroadcastTemplates id \"${t.id}\": name is required.`)\n }\n if (seen.has(t.id)) {\n throw new Error(`Duplicate emailBroadcastTemplates id \"${t.id}\".`)\n }\n seen.add(t.id)\n const hasComponent = typeof t.component === \"function\"\n const hasPath = typeof t.path === \"string\" && t.path.trim() !== \"\"\n if (hasComponent === hasPath) {\n throw new Error(\n `emailBroadcastTemplates id \"${t.id}\": provide exactly one of \\`component\\` or \\`path\\`.`,\n )\n }\n if (hasPath && t.path) {\n const pathTrim = t.path.trim()\n const hasHashExport = pathTrim.includes(\"#\")\n if (hasHashExport && t.exportName?.trim()) {\n throw new Error(\n `emailBroadcastTemplates id \"${t.id}\": use either \\`path\\` with \\`#ExportName\\` or \\`exportName\\`, not both.`,\n )\n }\n if (hasHashExport) {\n parseEmailBroadcastTemplatePath(pathTrim)\n }\n }\n }\n}\n\nexport async function resolveEmailBroadcastTemplateComponent(\n definition: MarketingEmailBroadcastTemplate,\n): Promise<ComponentType<MarketingEmailTemplateProps>> {\n if (definition.component) {\n return definition.component\n }\n const rawPath = definition.path?.trim()\n if (!rawPath) {\n throw new Error(`Email template \"${definition.id}\" has no resolvable \\`path\\`.`)\n }\n\n const { importPath, namedExport: namedExportFromPath } = parseEmailBroadcastTemplatePath(rawPath)\n const namedExportField = definition.exportName?.trim()\n const namedExport = namedExportFromPath ?? namedExportField\n const cacheKey = `${definition.id}\\0${importPath}\\0${namedExport ?? \"\"}`\n const cached = resolvedComponentCache.get(cacheKey)\n if (cached) {\n return cached\n }\n\n const mod = (await import(/* webpackIgnore: true */ importPath)) as Record<string, unknown>\n const resolved = (namedExport ? mod[namedExport] : mod.default) as\n | ComponentType<MarketingEmailTemplateProps>\n | undefined\n if (typeof resolved !== \"function\") {\n throw new Error(\n namedExport\n ? `Email template \"${definition.id}\": module \"${importPath}\" has no export \"${namedExport}\".`\n : `Email template \"${definition.id}\": module \"${importPath}\" has no default export.`,\n )\n }\n resolvedComponentCache.set(cacheKey, resolved)\n return resolved\n}\n\nexport function createEmailBroadcastReactElement(\n Component: ComponentType<MarketingEmailTemplateProps>,\n props: MarketingEmailTemplateProps,\n): React.ReactElement {\n return React.createElement(Component, props)\n}\n","import {\n createEmailBroadcastReactElement,\n resolveEmailBroadcastTemplateComponent,\n} from \"../email-broadcast-template\"\nimport {\n getMarketingIntegrationFromRequest,\n marketingMetaAllowed,\n resolveMarketingPermissions,\n} from \"../marketing-integration\"\n\nimport type {\n CreateBroadcastInput,\n MarketingEmailTemplateProps,\n UpsertContactInput,\n} from \"../types\"\nimport type { Endpoint, PayloadRequest } from \"payload\"\n\ntype MarketingPermissionResource = \"audiences\" | \"broadcasts\" | \"contacts\"\n\nfunction unauthorized() {\n return Response.json({ message: \"Unauthorized\" }, { status: 401 })\n}\n\nfunction forbidden() {\n return Response.json({ message: \"Forbidden\" }, { status: 403 })\n}\n\nfunction assertAuthenticated(req: PayloadRequest): Response | null {\n if (!req.user) return unauthorized()\n return null\n}\n\nfunction effectiveForRequest(req: PayloadRequest) {\n const { permissions } = getMarketingIntegrationFromRequest(req)\n return resolveMarketingPermissions(permissions)\n}\n\nfunction assertMarketingPermission(\n req: PayloadRequest,\n resource: MarketingPermissionResource,\n action: \"read\" | \"write\",\n): Response | null {\n const auth = assertAuthenticated(req)\n if (auth) return auth\n const eff = effectiveForRequest(req)\n if (!eff[resource][action]) return forbidden()\n return null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\")\n}\n\nasync function parseRequestJson(req: PayloadRequest): Promise<unknown> {\n return (await (req as unknown as Request).json()) as unknown\n}\n\nfunction adapterFor(req: PayloadRequest) {\n return getMarketingIntegrationFromRequest(req).adapter\n}\n\nexport function createMarketingEndpoints(): Endpoint[] {\n return [\n {\n handler: (req) => {\n const auth = assertAuthenticated(req)\n if (auth) return auth\n if (!marketingMetaAllowed(effectiveForRequest(req))) return forbidden()\n const { adapter } = getMarketingIntegrationFromRequest(req)\n return Response.json({\n label: adapter.label,\n provider: adapter.provider,\n urls: {\n audience: adapter.urls?.audiences,\n broadcasts: adapter.urls?.broadcasts,\n },\n })\n },\n method: \"get\",\n path: \"/marketing/meta\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"audiences\", \"read\")\n if (denied) return denied\n const adapter = getMarketingIntegrationFromRequest(req).adapter\n return Response.json(await adapter.audiences.list())\n },\n method: \"get\",\n path: \"/marketing/audiences\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"audiences\", \"write\")\n if (denied) return denied\n const bodyUnknown = await parseRequestJson(req)\n const name =\n typeof (bodyUnknown as { name?: unknown })?.name === \"string\"\n ? (bodyUnknown as { name: string }).name.trim()\n : \"\"\n if (!name) {\n return Response.json({ message: \"name is required\" }, { status: 400 })\n }\n await adapterFor(req).audiences.create({ name })\n return Response.json({ ok: true })\n },\n method: \"post\",\n path: \"/marketing/audiences\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"audiences\", \"read\")\n if (denied) return denied\n const id = typeof req.routeParams?.id === \"string\" ? req.routeParams.id : \"\"\n if (!id) {\n return Response.json({ message: \"Missing audience id\" }, { status: 400 })\n }\n const adapter = getMarketingIntegrationFromRequest(req).adapter\n const audience = await adapter.audiences.get(id)\n if (!audience) {\n return Response.json({ message: \"Not found\" }, { status: 404 })\n }\n return Response.json(audience)\n },\n method: \"get\",\n path: \"/marketing/audiences/:id\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"audiences\", \"write\")\n if (denied) return denied\n const id = typeof req.routeParams?.id === \"string\" ? req.routeParams.id : \"\"\n if (!id) {\n return Response.json({ message: \"Missing audience id\" }, { status: 400 })\n }\n await adapterFor(req).audiences.delete({ audienceId: id })\n return Response.json({ ok: true })\n },\n method: \"delete\",\n path: \"/marketing/audiences/:id\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"contacts\", \"read\")\n if (denied) return denied\n const audienceId =\n typeof req.routeParams?.audienceId === \"string\" ? req.routeParams.audienceId : \"\"\n if (!audienceId) {\n return Response.json({ message: \"Missing audience id\" }, { status: 400 })\n }\n const adapter = getMarketingIntegrationFromRequest(req).adapter\n return Response.json(await adapter.contacts.list({ audienceId }))\n },\n method: \"get\",\n path: \"/marketing/audiences/:audienceId/contacts\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"contacts\", \"write\")\n if (denied) return denied\n const audienceId =\n typeof req.routeParams?.audienceId === \"string\" ? req.routeParams.audienceId : \"\"\n const contactId =\n typeof req.routeParams?.contactId === \"string\" ? req.routeParams.contactId : \"\"\n if (!audienceId || !contactId) {\n return Response.json({ message: \"Missing audienceId or contactId\" }, { status: 400 })\n }\n await adapterFor(req).contacts.delete({ audienceId, contactId })\n return Response.json({ ok: true })\n },\n method: \"delete\",\n path: \"/marketing/audiences/:audienceId/contacts/:contactId\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"contacts\", \"write\")\n if (denied) return denied\n const bodyUnknown = await parseRequestJson(req)\n if (!isRecord(bodyUnknown)) {\n return Response.json({ message: \"Invalid JSON\" }, { status: 400 })\n }\n\n const email = typeof bodyUnknown.email === \"string\" ? bodyUnknown.email.trim() : undefined\n const audienceId =\n typeof bodyUnknown.audienceId === \"string\" ? bodyUnknown.audienceId : undefined\n\n if (!audienceId || !email) {\n return Response.json({ message: \"audienceId and email are required\" }, { status: 400 })\n }\n\n const payloadUpsert: UpsertContactInput = {\n audienceId,\n email,\n subscribed: typeof bodyUnknown.subscribed === \"boolean\" ? bodyUnknown.subscribed : true,\n }\n\n if (typeof bodyUnknown.id === \"string\" && bodyUnknown.id) {\n payloadUpsert.id = bodyUnknown.id\n }\n if (typeof bodyUnknown.firstName === \"string\") {\n payloadUpsert.firstName = bodyUnknown.firstName\n }\n if (typeof bodyUnknown.lastName === \"string\") {\n payloadUpsert.lastName = bodyUnknown.lastName\n }\n if (isRecord(bodyUnknown.properties)) {\n payloadUpsert.properties = bodyUnknown.properties as Record<\n string,\n string | number | null\n >\n }\n\n await adapterFor(req).contacts.upsert(payloadUpsert)\n return Response.json({ ok: true })\n },\n method: \"post\",\n path: \"/marketing/contacts\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"broadcasts\", \"read\")\n if (denied) return denied\n const adapter = getMarketingIntegrationFromRequest(req).adapter\n const broadcasts = await adapter.broadcasts.list()\n const enriched = broadcasts.map((b) => ({\n ...b,\n externalDashboardUrl: adapter.urls?.broadcast?.(b.id),\n }))\n return Response.json(enriched)\n },\n method: \"get\",\n path: \"/marketing/broadcasts\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"broadcasts\", \"write\")\n if (denied) return denied\n const bodyUnknown = await parseRequestJson(req)\n if (!isRecord(bodyUnknown)) {\n return Response.json({ message: \"Invalid JSON\" }, { status: 400 })\n }\n\n const audienceIdRaw =\n typeof bodyUnknown.audienceId === \"string\" ? bodyUnknown.audienceId.trim() : \"\"\n const name = typeof bodyUnknown.name === \"string\" ? bodyUnknown.name.trim() : \"\"\n const subject = typeof bodyUnknown.subject === \"string\" ? bodyUnknown.subject.trim() : \"\"\n const templateIdRaw =\n typeof bodyUnknown.templateId === \"string\" ? bodyUnknown.templateId.trim() : \"\"\n const emailTemplateIdRaw =\n typeof bodyUnknown.emailTemplateId === \"string\" ? bodyUnknown.emailTemplateId.trim() : \"\"\n\n const htmlProvided = typeof bodyUnknown.html === \"string\" ? bodyUnknown.html.trim() : \"\"\n const replyTo =\n typeof bodyUnknown.replyTo === \"string\" ? bodyUnknown.replyTo.trim() : undefined\n const localeRaw = typeof bodyUnknown.locale === \"string\" ? bodyUnknown.locale.trim() : \"\"\n const locale = localeRaw !== \"\" ? localeRaw : undefined\n\n if (!audienceIdRaw || !name || !subject) {\n return Response.json(\n { message: \"audienceId, name, and subject are required\" },\n { status: 400 },\n )\n }\n\n const hasHtml = htmlProvided !== \"\"\n const hasMailchimpTpl = templateIdRaw !== \"\"\n const hasReactEmailTpl = emailTemplateIdRaw !== \"\"\n const contentModes = [hasHtml, hasMailchimpTpl, hasReactEmailTpl].filter(Boolean).length\n\n if (contentModes === 0) {\n return Response.json(\n {\n message:\n \"Provide `html`, Mailchimp `templateId`, or `emailTemplateId` for a registered React email template.\",\n },\n { status: 400 },\n )\n }\n\n if (contentModes > 1) {\n return Response.json(\n {\n message:\n \"Use exactly one of: HTML body (`html`), Mailchimp template id (`templateId`), or React email template (`emailTemplateId`).\",\n },\n { status: 400 },\n )\n }\n\n let normalized: CreateBroadcastInput\n\n if (hasReactEmailTpl) {\n const integration = getMarketingIntegrationFromRequest(req)\n const templates = integration.emailBroadcastTemplates ?? []\n const definition = templates.find((t) => t.id === emailTemplateIdRaw)\n if (!definition) {\n return Response.json(\n { message: `Unknown emailTemplateId \"${emailTemplateIdRaw}\".` },\n { status: 400 },\n )\n }\n const adapter = integration.adapter\n if (adapter.provider !== \"resend\") {\n return Response.json(\n {\n message:\n \"emailTemplateId (React email) is only supported when using the Resend adapter.\",\n },\n { status: 400 },\n )\n }\n\n const props: MarketingEmailTemplateProps = locale !== undefined ? { locale } : {}\n const Component = await resolveEmailBroadcastTemplateComponent(definition)\n const react = createEmailBroadcastReactElement(Component, props)\n\n normalized = {\n audienceId: audienceIdRaw,\n locale,\n name,\n react,\n replyTo,\n subject,\n }\n } else if (hasMailchimpTpl) {\n normalized = {\n audienceId: audienceIdRaw,\n locale,\n name,\n replyTo,\n subject,\n templateId: templateIdRaw,\n }\n } else {\n normalized = {\n audienceId: audienceIdRaw,\n html: htmlProvided,\n locale,\n name,\n replyTo,\n subject,\n }\n }\n\n await adapterFor(req).broadcasts.create(normalized)\n return Response.json({ ok: true })\n },\n method: \"post\",\n path: \"/marketing/broadcasts\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"broadcasts\", \"write\")\n if (denied) return denied\n const broadcastId =\n typeof req.routeParams?.broadcastId === \"string\" ? req.routeParams.broadcastId : \"\"\n if (!broadcastId) {\n return Response.json({ message: \"Missing broadcast id\" }, { status: 400 })\n }\n await adapterFor(req).broadcasts.delete({ broadcastId })\n return Response.json({ ok: true })\n },\n method: \"delete\",\n path: \"/marketing/broadcasts/:broadcastId\",\n },\n\n {\n handler: async (req) => {\n const denied = assertMarketingPermission(req, \"broadcasts\", \"write\")\n if (denied) return denied\n const broadcastId =\n typeof req.routeParams?.broadcastId === \"string\" ? req.routeParams.broadcastId : \"\"\n if (!broadcastId) {\n return Response.json({ message: \"Missing broadcast id\" }, { status: 400 })\n }\n\n let scheduledAt: string | undefined\n try {\n const cloned = (req as unknown as Request).clone()\n const payloadBody: unknown = await cloned.json()\n if (isRecord(payloadBody) && typeof payloadBody.scheduledAt === \"string\") {\n scheduledAt = payloadBody.scheduledAt\n }\n } catch {\n scheduledAt = undefined\n }\n\n await adapterFor(req).broadcasts.send({ broadcastId, scheduledAt })\n return Response.json({ ok: true })\n },\n method: \"post\",\n path: \"/marketing/broadcasts/:broadcastId/send\",\n },\n ]\n}\n","import { validateEmailBroadcastTemplates } from \"./email-broadcast-template\"\nimport { createMarketingEndpoints } from \"./endpoints/marketing-endpoints\"\nimport { mutateFormBuilderCollections } from \"./form-builder/mutate-collections\"\nimport {\n MARKETING_CUSTOM_CONFIG_KEY,\n type MarketingIntegrationState,\n} from \"./marketing-integration\"\n\nimport type { PayloadMarketingPlugin, PayloadPluginMarketingOptions } from \"./types\"\nimport type { Config } from \"payload\"\n\nfunction mergeMarketingCustom(\n config: Config,\n integration: MarketingIntegrationState,\n): Record<string, unknown> {\n const prev = config.custom\n const base =\n typeof prev === \"object\" && prev !== null && !Array.isArray(prev)\n ? { ...(prev as Record<string, unknown>) }\n : {}\n base[MARKETING_CUSTOM_CONFIG_KEY] = integration\n return base\n}\n\nfunction component(exportName: string, clientProps?: Record<string, unknown>) {\n return {\n path: \"payload-plugin-marketing/admin\",\n exportName,\n ...(clientProps ? { clientProps } : {}),\n }\n}\n\nfunction adminViewPath(basePath: string, ...segments: string[]): `/${string}` {\n const trimmed = basePath.replace(/^\\/+|\\/+$/g, \"\")\n const body = [trimmed, ...segments].filter(Boolean).join(\"/\")\n return `/${body}`\n}\n\nfunction withMarketingAdmin(config: Config, options: PayloadPluginMarketingOptions): Config {\n if (options.admin?.enabled === false) {\n return config\n }\n const basePath = options.admin?.basePath ?? \"\"\n const components = options.admin?.components ?? {}\n const menuComponent = components.marketingMenu ?? component(\"MarketingMenu\", { basePath })\n const viewClientProps: Record<string, unknown> = { basePath }\n\n if (options.emailBroadcastTemplates?.length) {\n validateEmailBroadcastTemplates(options.emailBroadcastTemplates)\n }\n\n const marketingIntegrationState: MarketingIntegrationState = {\n adapter: options.adapter,\n adminBasePath: basePath,\n emailBroadcastTemplates: options.emailBroadcastTemplates,\n permissions: options.permissions,\n }\n\n return {\n ...config,\n custom: mergeMarketingCustom(config, marketingIntegrationState),\n endpoints: [...(config.endpoints ?? []), ...createMarketingEndpoints()],\n admin: {\n ...(config.admin ?? {}),\n components: {\n ...(config.admin?.components ?? {}),\n afterNavLinks: [\n ...((config.admin?.components?.afterNavLinks as unknown[]) ?? []),\n menuComponent,\n ],\n views: {\n ...((config.admin?.components?.views as Record<string, unknown> | undefined) ?? {}),\n // Register before `/audience` so `/audience/:id` does not resolve to the list view.\n audienceDetail: {\n Component: components.audienceDetail ?? component(\"AudienceDetail\", viewClientProps),\n path: adminViewPath(basePath, \"audience\", \":id\"),\n },\n audienceList: {\n Component: components.audienceList ?? component(\"AudienceList\", viewClientProps),\n path: adminViewPath(basePath, \"audience\"),\n },\n broadcastList: {\n Component: components.broadcastList ?? component(\"BroadcastList\", viewClientProps),\n path: adminViewPath(basePath, \"broadcast\"),\n },\n },\n },\n },\n } as Config\n}\n\nexport function marketingPlugin(options: PayloadPluginMarketingOptions): PayloadMarketingPlugin {\n const plugin: PayloadMarketingPlugin = (config) =>\n withMarketingAdmin(\n {\n ...config,\n collections: mutateFormBuilderCollections(config.collections, options),\n },\n options,\n )\n plugin.slug = \"marketing\"\n plugin.order = 10\n plugin.options = options as unknown as Record<string, unknown>\n return plugin\n}\n"],"mappings":"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","names":["MARKETING_CUSTOM_CONFIG_KEY","effectiveResource","slice","resolveMarketingPermissions","permissions","marketingMetaAllowed","effective","readIntegration","payload","custom","getMarketingIntegration","state","tryGetMarketingIntegration","getMarketingIntegrationFromRequest","req","React","resolvedComponentCache","parseEmailBroadcastTemplatePath","path","trimmed","hash","importPath","namedExport","validateEmailBroadcastTemplates","templates","seen","hasComponent","hasPath","pathTrim","hasHashExport","resolveEmailBroadcastTemplateComponent","definition","rawPath","namedExportFromPath","namedExportField","cacheKey","cached","mod","resolved","createEmailBroadcastReactElement","Component","props","unauthorized","forbidden","assertAuthenticated","req","effectiveForRequest","permissions","getMarketingIntegrationFromRequest","resolveMarketingPermissions","assertMarketingPermission","resource","action","auth","isRecord","value","parseRequestJson","adapterFor","createMarketingEndpoints","marketingMetaAllowed","adapter","denied","bodyUnknown","name","id","audience","audienceId","contactId","email","payloadUpsert","enriched","b","audienceIdRaw","subject","templateIdRaw","emailTemplateIdRaw","htmlProvided","replyTo","localeRaw","locale","hasHtml","hasMailchimpTpl","hasReactEmailTpl","contentModes","normalized","integration","definition","t","props","Component","resolveEmailBroadcastTemplateComponent","react","createEmailBroadcastReactElement","broadcastId","scheduledAt","payloadBody","mergeMarketingCustom","config","integration","prev","base","MARKETING_CUSTOM_CONFIG_KEY","component","exportName","clientProps","adminViewPath","basePath","segments","withMarketingAdmin","options","components","menuComponent","viewClientProps","validateEmailBroadcastTemplates","marketingIntegrationState","createMarketingEndpoints","marketingPlugin","plugin","mutateFormBuilderCollections"]}
@@ -1,9 +1,10 @@
1
- import type { MarketingAdapter, MarketingEffectivePermissions, MarketingPluginPermissions } from "./types";
1
+ import type { MarketingAdapter, MarketingEffectivePermissions, MarketingEmailBroadcastTemplate, MarketingPluginPermissions } from "./types";
2
2
  import type { Payload, PayloadRequest } from "payload";
3
3
  export declare const MARKETING_CUSTOM_CONFIG_KEY = "payloadPluginMarketing";
4
4
  export interface MarketingIntegrationState {
5
5
  adapter: MarketingAdapter;
6
6
  adminBasePath: string;
7
+ emailBroadcastTemplates?: MarketingEmailBroadcastTemplate[];
7
8
  permissions?: MarketingPluginPermissions;
8
9
  }
9
10
  /** Resolves endpoint access flags. If `permissions` is absent (plugin option omitted), all actions are allowed for authenticated users. */
@@ -1 +1 @@
1
- {"version":3,"file":"marketing-integration.d.ts","sourceRoot":"","sources":["../src/marketing-integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,6BAA6B,EAC7B,0BAA0B,EAC3B,MAAM,SAAS,CAAA;AAChB,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEtD,eAAO,MAAM,2BAA2B,2BAA2B,CAAA;AAEnE,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,gBAAgB,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,0BAA0B,CAAA;CACzC;AAYD,2IAA2I;AAC3I,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,0BAA0B,GAAG,SAAS,GAClD,6BAA6B,CAa/B;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,6BAA6B,GAAG,OAAO,CAEtF;AAcD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,CAQnF;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CAElG;AAED,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,cAAc,GAAG,yBAAyB,CAEjG"}
1
+ {"version":3,"file":"marketing-integration.d.ts","sourceRoot":"","sources":["../src/marketing-integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,6BAA6B,EAC7B,+BAA+B,EAC/B,0BAA0B,EAC3B,MAAM,SAAS,CAAA;AAChB,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEtD,eAAO,MAAM,2BAA2B,2BAA2B,CAAA;AAEnE,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,gBAAgB,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,uBAAuB,CAAC,EAAE,+BAA+B,EAAE,CAAA;IAC3D,WAAW,CAAC,EAAE,0BAA0B,CAAA;CACzC;AAYD,2IAA2I;AAC3I,wBAAgB,2BAA2B,CACzC,WAAW,EAAE,0BAA0B,GAAG,SAAS,GAClD,6BAA6B,CAa/B;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,6BAA6B,GAAG,OAAO,CAEtF;AAcD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,CAQnF;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,GACf,yBAAyB,GAAG,SAAS,CAEvC;AAED,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,cAAc,GAAG,yBAAyB,CAEjG"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAA;AA6EpF,wBAAgB,eAAe,CAC7B,OAAO,EAAE,6BAA6B,GACrC,sBAAsB,CAaxB"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAA;AAmFpF,wBAAgB,eAAe,CAAC,OAAO,EAAE,6BAA6B,GAAG,sBAAsB,CAa9F"}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Block, CollectionConfig, PayloadComponent, Plugin } from "payload";
2
+ import type { ComponentType } from "react";
2
3
  export interface MarketingAudience {
3
4
  id: string;
4
5
  name: string;
@@ -41,6 +42,31 @@ export interface DeleteContactInput {
41
42
  audienceId: string;
42
43
  contactId: string;
43
44
  }
45
+ /** Props passed to React email templates when creating a broadcast (`locale` matches common @react-email usage). */
46
+ export interface MarketingEmailTemplateProps {
47
+ locale?: string;
48
+ [key: string]: unknown;
49
+ }
50
+ /**
51
+ * Register server-side React email templates for the marketing admin “create broadcast” flow.
52
+ * Provide exactly one of {@link MarketingEmailBroadcastTemplate.path} (recommended: import path string)
53
+ * or {@link MarketingEmailBroadcastTemplate.component}.
54
+ */
55
+ export interface MarketingEmailBroadcastTemplate {
56
+ /** Alternative to {@link path}; use when you import the component in your Payload config. */
57
+ component?: ComponentType<MarketingEmailTemplateProps>;
58
+ /**
59
+ * Named export when {@link path} has no `#ExportName` fragment; ignored if `path` includes `#`.
60
+ */
61
+ exportName?: string;
62
+ id: string;
63
+ name: string;
64
+ /**
65
+ * Import path for `import()` when creating a broadcast. Append `#ExportName` for a named export
66
+ * (e.g. `@/emails/digest#DigestEmail`); otherwise use {@link exportName} or the module default.
67
+ */
68
+ path?: string;
69
+ }
44
70
  export interface CreateBroadcastInput {
45
71
  audienceId: string;
46
72
  html?: string;
@@ -144,6 +170,11 @@ export interface MarketingEffectivePermissions {
144
170
  }
145
171
  export interface PayloadPluginMarketingOptions {
146
172
  adapter: MarketingAdapter;
173
+ /**
174
+ * React email templates for the create-broadcast admin UI and `POST /api/.../marketing/broadcasts`
175
+ * with `emailTemplateId`. Resolved on the server; only the Resend adapter supports {@link CreateBroadcastInput.react}.
176
+ */
177
+ emailBroadcastTemplates?: MarketingEmailBroadcastTemplate[];
147
178
  /** Restrict marketing REST endpoints by resource. See `MarketingPluginPermissions`. */
148
179
  permissions?: MarketingPluginPermissions;
149
180
  admin?: {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload-plugin-marketing",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "description": "Payload CMS plugin for marketing forms, audiences, contacts, and broadcasts.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -44,6 +44,11 @@
44
44
  "import": "./dist/admin/index.js",
45
45
  "require": "./dist/admin/index.cjs"
46
46
  },
47
+ "./admin/client": {
48
+ "types": "./dist/admin/client.d.ts",
49
+ "import": "./dist/admin/client.js",
50
+ "require": "./dist/admin/client.cjs"
51
+ },
47
52
  "./form-builder": {
48
53
  "types": "./dist/form-builder/index.d.ts",
49
54
  "import": "./dist/form-builder/index.js",
@@ -58,7 +63,10 @@
58
63
  "build": "tsup --config tsup.config.ts --minify && tsc -p tsconfig.build.json --emitDeclarationOnly",
59
64
  "dev": "tsup --config tsup.config.ts --watch",
60
65
  "test": "vitest run tests",
61
- "typecheck": "tsc --noEmit"
66
+ "typecheck": "tsc --noEmit",
67
+ "lint": "pnpm -w exec oxlint \"packages/${npm_package_name}\"",
68
+ "format": "pnpm exec oxfmt .",
69
+ "format:check": "pnpm exec oxfmt --check ."
62
70
  },
63
71
  "peerDependencies": {
64
72
  "@mailchimp/mailchimp_marketing": "*",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/form-builder/fields.ts","../src/form-builder/submission.ts","../src/form-builder/hooks.ts","../src/form-builder/normalize-placeholder-rows.ts","../src/form-builder/mutate-collections.ts"],"sourcesContent":["import type { FieldOverride, MarketingBlockOptions, MarketingFormFieldOverrides } from \"../types\"\nimport type { Block, Field } from \"payload\"\n\nexport const CUSTOM_MARKETING_FIELD_NAMES = [\"url\", \"phone\", \"acceptance\"] as const\n\nexport function mergeField(base: Field, override?: FieldOverride): Field {\n if (!override) {\n return base\n }\n\n const { overrides, ...direct } = override\n return {\n ...base,\n ...direct,\n ...(overrides ?? {}),\n admin: {\n ...(\"admin\" in base ? base.admin : undefined),\n ...(direct.admin ?? {}),\n ...(overrides?.admin ?? {}),\n },\n } as Field\n}\n\nfunction row(fields: Field[]): Field {\n return { type: \"row\", fields } as Field\n}\n\nfunction textLikeBlock(\n slug: \"phone\" | \"url\",\n labels: Required<Block>[\"labels\"],\n options?: MarketingBlockOptions,\n): Block {\n const fields = options?.fields ?? {}\n const block: Block = {\n slug,\n labels: options?.labels ?? labels,\n fields: [\n row([\n mergeField(\n {\n name: \"name\",\n type: \"text\",\n label: \"Name (lowercase, no special characters)\",\n required: true,\n admin: { width: \"50%\" },\n },\n fields.name,\n ),\n mergeField(\n {\n name: \"label\",\n type: \"text\",\n label: \"Label\",\n localized: true,\n admin: { width: \"50%\" },\n },\n fields.label,\n ),\n ]),\n row([\n mergeField(\n {\n name: \"width\",\n type: \"number\",\n label: \"Field Width (percentage)\",\n admin: { width: \"20%\" },\n },\n fields.width,\n ),\n mergeField(\n {\n name: \"placeholder\",\n type: \"text\",\n label: \"Placeholder\",\n localized: true,\n admin: { width: \"40%\" },\n },\n fields.placeholder,\n ),\n mergeField(\n {\n name: \"defaultValue\",\n type: \"text\",\n label: \"Default Value\",\n localized: true,\n admin: { width: \"40%\" },\n },\n fields.defaultValue,\n ),\n ]),\n mergeField({ name: \"required\", type: \"checkbox\", label: \"Required\" }, fields.required),\n ],\n }\n\n return { ...block, ...(options?.overrides ?? {}) }\n}\n\nexport function createAcceptanceBlock(options?: MarketingBlockOptions): Block {\n const fields = options?.fields ?? {}\n const block: Block = {\n slug: \"acceptance\",\n labels: options?.labels ?? { singular: \"Acceptance\", plural: \"Acceptances\" },\n fields: [\n row([\n mergeField(\n {\n name: \"name\",\n type: \"text\",\n label: \"Name (lowercase, no special characters)\",\n required: true,\n admin: { width: \"50%\" },\n },\n fields.name,\n ),\n mergeField(\n {\n name: \"label\",\n type: \"richText\",\n label: \"Label\",\n localized: true,\n admin: { width: \"50%\" },\n },\n fields.label,\n ),\n ]),\n row([\n mergeField(\n {\n name: \"width\",\n type: \"number\",\n label: \"Field Width (percentage)\",\n admin: { width: \"50%\" },\n },\n fields.width,\n ),\n mergeField({ name: \"required\", type: \"checkbox\", label: \"Required\" }, fields.required),\n ]),\n ],\n }\n\n return { ...block, ...(options?.overrides ?? {}) }\n}\n\nexport function createMarketingFormFields(\n overrides: MarketingFormFieldOverrides = {},\n): Record<(typeof CUSTOM_MARKETING_FIELD_NAMES)[number], Block> {\n return {\n url: textLikeBlock(\"url\", { singular: \"URL\", plural: \"URLs\" }, overrides.url || undefined),\n phone: textLikeBlock(\n \"phone\",\n { singular: \"Phone\", plural: \"Phones\" },\n overrides.phone || undefined,\n ),\n acceptance: createAcceptanceBlock(overrides.acceptance || undefined),\n }\n}\n\nexport function createMarketingBlocksForMutation(\n overrides: MarketingFormFieldOverrides = {},\n): Block[] {\n return Object.values(createMarketingFormFields(overrides))\n}\n","export const FORM_HONEYPOT_FIELD = \"__website\"\nexport const FORM_STARTED_AT_FIELD = \"__startedAt\"\nexport const MIN_SUBMISSION_TIME_MS = 1_500\n\nconst MAX_LENGTH_BY_BLOCK: Record<string, number> = {\n acceptance: 5,\n checkbox: 5,\n country: 200,\n date: 100,\n email: 320,\n message: 5_000,\n number: 64,\n payment: 1_000,\n phone: 50,\n select: 200,\n state: 200,\n text: 200,\n textarea: 5_000,\n upload: 1_000,\n url: 2_048,\n}\n\nexport interface ValidationFormField {\n blockType: string\n name?: string | null\n options?: Array<{ value: string }> | null\n required?: boolean | null\n}\n\nexport interface ValidationSubmissionField {\n field?: string | null\n value?: unknown\n}\n\nexport type SubmissionValidationResult =\n | { data: Array<{ field: string; value: string }>; ok: true }\n | { error: string; ok: false }\n\nfunction isControlField(fieldName: string): boolean {\n return fieldName === FORM_HONEYPOT_FIELD || fieldName === FORM_STARTED_AT_FIELD\n}\n\nfunction extractControlFields(submissionData: ValidationSubmissionField[]): {\n honeypot: string\n startedAt: string\n} {\n const honeypot = submissionData.find((entry) => entry.field === FORM_HONEYPOT_FIELD)?.value\n const startedAt = submissionData.find((entry) => entry.field === FORM_STARTED_AT_FIELD)?.value\n return {\n honeypot: typeof honeypot === \"string\" ? honeypot : \"\",\n startedAt:\n typeof startedAt === \"string\" || typeof startedAt === \"number\" ? String(startedAt) : \"\",\n }\n}\n\nfunction stringifySubmissionValue(value: unknown): string {\n if (typeof value === \"boolean\") {\n return String(value)\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return String(value)\n }\n return typeof value === \"string\" ? value.trim() : \"\"\n}\n\nfunction isValidFieldValue(field: ValidationFormField, value: string): boolean {\n if (!value) {\n return !field.required\n }\n if (value.length > (MAX_LENGTH_BY_BLOCK[field.blockType] ?? 1_000)) {\n return false\n }\n if (field.blockType === \"email\") {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)\n }\n if (field.blockType === \"url\") {\n try {\n new URL(value)\n return true\n } catch {\n return false\n }\n }\n if (field.blockType === \"number\") {\n return Number.isFinite(Number(value))\n }\n if (field.blockType === \"checkbox\" || field.blockType === \"acceptance\") {\n return value === \"true\" || value === \"false\"\n }\n if (field.blockType === \"select\" && field.options?.length) {\n return field.options.some((option) => option.value === value)\n }\n return true\n}\n\nfunction requiredValueIsPresent(field: ValidationFormField, value: string | undefined): boolean {\n if (!field.required) {\n return true\n }\n if (field.blockType === \"acceptance\") {\n return value === \"true\"\n }\n return Boolean(value)\n}\n\nexport function validateSubmissionInput(input: {\n formFields: ValidationFormField[]\n now: number\n submissionData: ValidationSubmissionField[] | null | undefined\n}): SubmissionValidationResult {\n const controlFields = extractControlFields(input.submissionData ?? [])\n if (controlFields.honeypot.trim()) {\n return { ok: false, error: \"Invalid submission.\" }\n }\n const startedAt = Number(controlFields.startedAt)\n if (!Number.isFinite(startedAt)) {\n return { ok: false, error: \"Invalid submission.\" }\n }\n if (input.now - startedAt < MIN_SUBMISSION_TIME_MS) {\n return { ok: false, error: \"Form submitted too quickly.\" }\n }\n\n const supportedFields = input.formFields.flatMap((field) =>\n field.name && field.blockType in MAX_LENGTH_BY_BLOCK ? [{ ...field, name: field.name }] : [],\n )\n const formFieldMap = new Map(supportedFields.map((field) => [field.name, field]))\n const normalized: Array<{ field: string; value: string }> = []\n const seenFields = new Set<string>()\n\n for (const entry of input.submissionData ?? []) {\n const fieldName = entry.field?.trim()\n if (!fieldName || isControlField(fieldName)) {\n continue\n }\n if (seenFields.has(fieldName)) {\n return { ok: false, error: `Field \"${fieldName}\" was submitted more than once.` }\n }\n seenFields.add(fieldName)\n const formField = formFieldMap.get(fieldName)\n if (!formField) {\n return { ok: false, error: `Unexpected field \"${fieldName}\".` }\n }\n const value = stringifySubmissionValue(entry.value)\n if (!isValidFieldValue(formField, value)) {\n return { ok: false, error: `Field \"${fieldName}\" is invalid.` }\n }\n normalized.push({ field: fieldName, value })\n }\n\n for (const field of supportedFields) {\n const value = normalized.find((entry) => entry.field === field.name)?.value\n if (!requiredValueIsPresent(field, value)) {\n return { ok: false, error: `Field \"${field.name}\" is required.` }\n }\n }\n\n return { ok: true, data: normalized }\n}\n\nexport function submissionDataToPlainRecord(\n submissionData: ValidationSubmissionField[],\n): Record<string, string> {\n return Object.fromEntries(\n submissionData.flatMap((entry) =>\n entry.field ? [[entry.field, stringifySubmissionValue(entry.value)]] : [],\n ),\n )\n}\n\nexport function substituteSubmissionPlaceholders(\n template: string,\n values: Record<string, string>,\n): string {\n return template.replace(\n /\\{\\{\\s*([\\w.-]+)\\s*\\}\\}/g,\n (_, fieldName: string) => values[fieldName] ?? \"\",\n )\n}\n\nexport function resolveCommaSeparatedSubmissionTags(\n tags: string | null | undefined,\n values: Record<string, string>,\n): string[] {\n return (tags ?? \"\")\n .split(\",\")\n .map((tag) => substituteSubmissionPlaceholders(tag, values).trim())\n .filter(Boolean)\n}\n","import {\n resolveCommaSeparatedSubmissionTags,\n submissionDataToPlainRecord,\n validateSubmissionInput,\n} from \"./submission\"\n\nimport type { MarketingAdapter } from \"../types\"\nimport type { CollectionBeforeChangeHook, PayloadRequest } from \"payload\"\n\ninterface FormSubmissionData {\n form?: unknown\n submissionData?: Array<{ field?: string | null; value?: unknown }>\n}\n\nfunction getStringField(data: FormSubmissionData, field: string): string | undefined {\n const value = data.submissionData?.find((row) => row.field === field)?.value\n if (typeof value === \"string\") {\n return value\n }\n if (value == null) {\n return undefined\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return String(value)\n }\n if (typeof value === \"boolean\") {\n return String(value)\n }\n return undefined\n}\n\ninterface HookOptions {\n formsSlug?: string\n minSubmitDurationMs?: number\n}\n\nasync function resolveMarketingForm(\n data: { form?: unknown },\n req: PayloadRequest,\n formsSlug = \"forms\",\n): Promise<unknown> {\n if (typeof data.form === \"string\") {\n return await req.payload.findByID({\n collection: formsSlug,\n depth: 0,\n id: data.form,\n overrideAccess: true,\n })\n }\n return data.form\n}\n\nexport function createValidateFormSubmissionHook(\n options: HookOptions = {},\n): CollectionBeforeChangeHook {\n return async ({ data, operation, req }) => {\n if (operation !== \"create\") {\n return data\n }\n const form = await resolveMarketingForm(data as { form?: unknown }, req, options.formsSlug)\n const result = validateSubmissionInput({\n formFields: ((form as { fields?: unknown[] } | undefined)?.fields ?? []) as never,\n now: Date.now(),\n submissionData: (data?.submissionData ?? []) as never,\n })\n if (!result.ok) {\n throw new Error(result.error)\n }\n data.submissionData = result.data\n return data\n }\n}\n\nexport function createCreateLeadHook(\n adapter: MarketingAdapter,\n options: HookOptions = {},\n): CollectionBeforeChangeHook {\n return async ({ data, operation, req }) => {\n if (operation !== \"create\") {\n return data\n }\n const form = await resolveMarketingForm(data as { form?: unknown }, req, options.formsSlug)\n const formRecord = form as\n | { audienceId?: string; event?: string; tags?: string | null }\n | undefined\n if (formRecord?.event !== \"lead\" || !formRecord.audienceId) {\n return data\n }\n\n const submission = data as FormSubmissionData\n const email = getStringField(submission, \"email\")\n if (!email) {\n return data\n }\n\n const fieldValues = submissionDataToPlainRecord(submission.submissionData ?? [])\n const tags = resolveCommaSeparatedSubmissionTags(formRecord.tags, fieldValues)\n await adapter.contacts.upsert({\n audienceId: formRecord.audienceId,\n email,\n firstName: getStringField(submission, \"firstName\"),\n lastName: getStringField(submission, \"lastName\"),\n properties: tags.length > 0 ? { tags: tags.join(\",\") } : undefined,\n subscribed: true,\n })\n return data\n }\n}\n","import { mergeField } from \"./fields\"\n\nimport type { FieldOverride, MarketingBlockOptions } from \"../types\"\nimport type { Block, Field } from \"payload\"\n\n/** Blocks that do not use a free-text style placeholder in the admin or render layer. */\nconst BLOCK_SLUGS_WITHOUT_PLACEHOLDER_ROW = new Set([\n \"acceptance\",\n \"checkbox\",\n \"message\",\n \"payment\",\n \"upload\",\n])\n\nfunction row(fields: Field[]): Field {\n return { type: \"row\", fields }\n}\n\nfunction isRowField(field: Field): field is Field & { type: \"row\"; fields: Field[] } {\n return (\n typeof field === \"object\" &&\n field !== null &&\n \"type\" in field &&\n field.type === \"row\" &&\n \"fields\" in field &&\n Array.isArray((field as { fields: unknown }).fields)\n )\n}\n\nfunction collectNamedFields(fields: Field[]): Map<string, Field> {\n const map = new Map<string, Field>()\n function walk(items: Field[]) {\n for (const item of items) {\n if (\"name\" in item && typeof item.name === \"string\") {\n map.set(item.name, item)\n }\n if (isRowField(item)) {\n walk(item.fields)\n }\n }\n }\n walk(fields)\n return map\n}\n\nfunction withAdminWidth(field: Field, width: string): Field {\n const prevAdmin =\n \"admin\" in field && field.admin && typeof field.admin === \"object\" ? field.admin : {}\n return { ...field, admin: { ...prevAdmin, width } } as Field\n}\n\nfunction widthColumn(override: MarketingBlockOptions | undefined, existing?: Field): Field {\n const base: Field = {\n name: \"width\",\n type: \"number\",\n label: \"Field Width (percentage)\",\n admin: { width: \"20%\" },\n }\n let field = existing ? mergeField(base, existing as FieldOverride) : base\n field = mergeField(field, override?.fields?.width)\n return withAdminWidth(field, \"20%\")\n}\n\nfunction placeholderColumn(\n named: Map<string, Field>,\n override: MarketingBlockOptions | undefined,\n): Field {\n const existing = named.get(\"placeholder\")\n const base: Field = {\n name: \"placeholder\",\n type: \"text\",\n label: \"Placeholder\",\n localized: true,\n admin: { width: \"40%\" },\n }\n let field = existing ? mergeField(base, existing as FieldOverride) : base\n field = mergeField(field, override?.fields?.placeholder)\n return withAdminWidth(field, \"40%\")\n}\n\nfunction defaultValueColumn(\n override: MarketingBlockOptions | undefined,\n existing: Field | undefined,\n fallback: Field,\n): Field {\n const base = {\n ...fallback,\n admin: {\n ...(\"admin\" in fallback && fallback.admin && typeof fallback.admin === \"object\"\n ? fallback.admin\n : {}),\n width: \"40%\",\n },\n } as Field\n let field = existing ? mergeField(base, existing as FieldOverride) : base\n field = mergeField(field, override?.fields?.defaultValue)\n return withAdminWidth(field, \"40%\")\n}\n\n/** Layout: row 2 is width (20%) | placeholder (40%) | defaultValue (40%). */\nexport function normalizeFormBuilderPlaceholderRow(\n block: Block,\n override?: MarketingBlockOptions,\n): Block {\n const slug = block.slug\n if (!slug || BLOCK_SLUGS_WITHOUT_PLACEHOLDER_ROW.has(slug)) {\n return block\n }\n\n const fields = [...block.fields]\n const named = collectNamedFields(fields)\n\n if (slug === \"text\" || slug === \"textarea\" || slug === \"radio\") {\n const row1 = fields[1]\n if (!isRowField(row1)) {\n return block\n }\n const newSecond = row([\n widthColumn(override, named.get(\"width\")),\n placeholderColumn(named, override),\n defaultValueColumn(override, named.get(\"defaultValue\"), {\n name: \"defaultValue\",\n type: \"text\",\n label: \"Default Value\",\n localized: true,\n } as Field),\n ])\n return { ...block, fields: [fields[0], newSecond, ...fields.slice(2)] }\n }\n\n if (slug === \"number\") {\n const row1 = fields[1]\n if (!isRowField(row1)) {\n return block\n }\n const newSecond = row([\n widthColumn(override, named.get(\"width\")),\n placeholderColumn(named, override),\n defaultValueColumn(override, named.get(\"defaultValue\"), {\n name: \"defaultValue\",\n type: \"number\",\n label: \"Default Value\",\n } as Field),\n ])\n return { ...block, fields: [fields[0], newSecond, ...fields.slice(2)] }\n }\n\n if (slug === \"select\") {\n const row1 = fields[1]\n const row2 = fields[2]\n if (!isRowField(row1)) {\n return block\n }\n const wasStandalonePlaceholderRow =\n isRowField(row2) &&\n row2.fields.length === 1 &&\n \"name\" in row2.fields[0] &&\n row2.fields[0].name === \"placeholder\"\n const newSecond = row([\n widthColumn(override, named.get(\"width\")),\n placeholderColumn(named, override),\n defaultValueColumn(override, named.get(\"defaultValue\"), {\n name: \"defaultValue\",\n type: \"text\",\n label: \"Default Value\",\n localized: true,\n } as Field),\n ])\n const tailStart = wasStandalonePlaceholderRow ? 3 : 2\n return { ...block, fields: [fields[0], newSecond, ...fields.slice(tailStart)] }\n }\n\n if (slug === \"email\" || slug === \"state\" || slug === \"country\") {\n const row0 = fields[0]\n const maybeWidth = fields[1]\n const rest = fields.slice(2)\n if (!isRowField(row0) || !maybeWidth || !(\"name\" in maybeWidth) || maybeWidth.name !== \"width\") {\n return block\n }\n const newSecond = row([\n widthColumn(override, named.get(\"width\")),\n placeholderColumn(named, override),\n defaultValueColumn(override, named.get(\"defaultValue\"), {\n name: \"defaultValue\",\n type: \"text\",\n label: \"Default Value\",\n localized: true,\n } as Field),\n ])\n return { ...block, fields: [row0, newSecond, ...rest] }\n }\n\n if (slug === \"date\") {\n const row0 = fields[0]\n const row1 = fields[1]\n const defaultField = fields[2]\n if (\n !isRowField(row0) ||\n !isRowField(row1) ||\n !defaultField ||\n !(\"name\" in defaultField) ||\n defaultField.name !== \"defaultValue\"\n ) {\n return block\n }\n const requiredField = row1.fields.find((f) => \"name\" in f && f.name === \"required\")\n if (!requiredField) {\n return block\n }\n const newSecond = row([\n widthColumn(override, named.get(\"width\")),\n placeholderColumn(named, override),\n defaultValueColumn(override, named.get(\"defaultValue\"), {\n name: \"defaultValue\",\n type: \"date\",\n label: \"Default Value\",\n } as Field),\n ])\n return { ...block, fields: [row0, newSecond, requiredField] }\n }\n\n return block\n}\n","import { createMarketingFormFields } from \"./fields\"\nimport { normalizeFormBuilderPlaceholderRow } from \"./normalize-placeholder-rows\"\nimport { createCreateLeadHook, createValidateFormSubmissionHook } from \"./hooks\"\n\nimport type { PayloadPluginMarketingOptions } from \"../types\"\nimport type { Block, CollectionConfig, Field } from \"payload\"\n\nfunction isNamedField(field: Field, name: string): field is Field & { name: string } {\n return \"name\" in field && field.name === name\n}\n\nfunction hasSlug(item: unknown): item is { slug: string } {\n return Boolean(\n item && typeof item === \"object\" && \"slug\" in item && typeof item.slug === \"string\",\n )\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\")\n}\n\nfunction upsertField(fields: Field[], field: Field): Field[] {\n if (!(\"name\" in field) || !field.name) {\n return [...fields, field]\n }\n return fields.some((existing) => isNamedField(existing, field.name))\n ? fields.map((existing) => (isNamedField(existing, field.name) ? field : existing))\n : [...fields, field]\n}\n\nfunction createMarketingConfigFields(options: PayloadPluginMarketingOptions): Field[] {\n const audienceSelect = options.admin?.components?.audienceSelect ?? {\n path: \"payload-plugin-marketing/admin\",\n exportName: \"AudienceSelect\",\n }\n return [\n {\n name: \"event\",\n type: \"select\",\n defaultValue: \"submission\",\n options: [\n { label: \"Submission\", value: \"submission\" },\n { label: \"Lead\", value: \"lead\" },\n ],\n },\n {\n name: \"audienceId\",\n type: \"text\",\n label: \"Audience ID\",\n required: false,\n admin: {\n condition: (_data, siblingData) => siblingData?.event === \"lead\",\n components: { Field: audienceSelect },\n },\n validate: (value: unknown, { siblingData }: { siblingData?: { event?: string } } = {}) =>\n siblingData?.event === \"lead\" && !value ? \"Audience is required for lead forms.\" : true,\n },\n {\n name: \"tags\",\n type: \"textarea\",\n label: \"Tags\",\n admin: {\n condition: (_data, siblingData) => siblingData?.event === \"lead\",\n description: \"Optional comma-separated tags. Use {{fieldName}} to insert submitted values.\",\n },\n },\n ] as Field[]\n}\n\nfunction mutateFormsCollection(\n collection: CollectionConfig,\n options: PayloadPluginMarketingOptions,\n): CollectionConfig {\n const fields = [...collection.fields]\n const fieldsIndex = fields.findIndex(\n (field) => isNamedField(field, \"fields\") && field.type === \"blocks\",\n )\n if (fieldsIndex < 0) {\n if (options.formBuilder?.strict === false) {\n return collection\n }\n throw new Error(\n `Could not find a blocks field named \"fields\" on form-builder forms collection \"${collection.slug}\".`,\n )\n }\n\n const fieldsField = fields[fieldsIndex] as Field & { blocks: unknown[] }\n const existingBlocks = Array.isArray(fieldsField.blocks) ? fieldsField.blocks : []\n const blockOverrides = options.formBuilder?.fields ?? {}\n const overriddenExistingBlocks = existingBlocks.map((block) => {\n if (!hasSlug(block)) {\n return block\n }\n if (!isRecord(block)) {\n return block\n }\n const override = blockOverrides[block.slug as keyof typeof blockOverrides]\n const merged =\n override && isRecord(override)\n ? {\n ...block,\n ...(override.overrides ?? {}),\n ...(override.labels ? { labels: override.labels } : {}),\n }\n : block\n return normalizeFormBuilderPlaceholderRow(merged as Block, override)\n })\n const existingSlugs = new Set(\n overriddenExistingBlocks.flatMap((block) => (hasSlug(block) ? [block.slug] : [])),\n )\n const marketingBlocks = Object.values(\n createMarketingFormFields(options.formBuilder?.fields),\n ).filter((block) => !existingSlugs.has(block.slug))\n\n fields[fieldsIndex] = {\n ...fieldsField,\n blocks: [...overriddenExistingBlocks, ...marketingBlocks],\n } as Field\n\n for (const field of createMarketingConfigFields(options)) {\n fields.splice(0, fields.length, ...upsertField(fields, field))\n }\n\n return { ...collection, fields }\n}\n\nfunction mutateSubmissionsCollection(\n collection: CollectionConfig,\n options: PayloadPluginMarketingOptions,\n): CollectionConfig {\n const hooks = collection.hooks ?? {}\n return {\n ...collection,\n hooks: {\n ...hooks,\n beforeChange: [\n ...(hooks.beforeChange ?? []),\n createValidateFormSubmissionHook({ formsSlug: options.formBuilder?.formsSlug }),\n createCreateLeadHook(options.adapter, { formsSlug: options.formBuilder?.formsSlug }),\n ],\n },\n }\n}\n\nexport function mutateFormBuilderCollections(\n collections: CollectionConfig[] | undefined,\n options: PayloadPluginMarketingOptions,\n): CollectionConfig[] | undefined {\n const formsSlug = options.formBuilder?.formsSlug ?? \"forms\"\n const submissionsSlug = options.formBuilder?.submissionsSlug ?? \"form-submissions\"\n const strict = options.formBuilder?.strict ?? true\n const list = collections ?? []\n const hasForms = list.some((collection) => collection.slug === formsSlug)\n const hasSubmissions = list.some((collection) => collection.slug === submissionsSlug)\n\n if (strict && !hasForms) {\n throw new Error(`Could not find form-builder forms collection \"${formsSlug}\".`)\n }\n if (strict && !hasSubmissions) {\n throw new Error(`Could not find form-builder submissions collection \"${submissionsSlug}\".`)\n }\n\n return list.map((collection) => {\n if (collection.slug === formsSlug) {\n return mutateFormsCollection(collection, options)\n }\n if (collection.slug === submissionsSlug) {\n return mutateSubmissionsCollection(collection, options)\n }\n return collection\n })\n}\n"],"mappings":"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","names":["mergeField","base","override","overrides","direct","row","fields","textLikeBlock","slug","labels","options","createAcceptanceBlock","createMarketingFormFields","FORM_HONEYPOT_FIELD","FORM_STARTED_AT_FIELD","MIN_SUBMISSION_TIME_MS","MAX_LENGTH_BY_BLOCK","isControlField","fieldName","extractControlFields","submissionData","honeypot","entry","startedAt","stringifySubmissionValue","value","isValidFieldValue","field","option","requiredValueIsPresent","validateSubmissionInput","input","controlFields","supportedFields","formFieldMap","normalized","seenFields","formField","submissionDataToPlainRecord","substituteSubmissionPlaceholders","template","values","_","resolveCommaSeparatedSubmissionTags","tags","tag","getStringField","data","field","value","row","resolveMarketingForm","req","formsSlug","createValidateFormSubmissionHook","options","operation","form","result","validateSubmissionInput","createCreateLeadHook","adapter","formRecord","submission","email","fieldValues","submissionDataToPlainRecord","tags","resolveCommaSeparatedSubmissionTags","BLOCK_SLUGS_WITHOUT_PLACEHOLDER_ROW","row","fields","isRowField","field","collectNamedFields","map","walk","items","item","withAdminWidth","width","prevAdmin","widthColumn","override","existing","base","mergeField","placeholderColumn","named","defaultValueColumn","fallback","normalizeFormBuilderPlaceholderRow","block","slug","row1","newSecond","row2","wasStandalonePlaceholderRow","tailStart","row0","maybeWidth","rest","defaultField","requiredField","f","isNamedField","field","name","hasSlug","item","isRecord","value","upsertField","fields","existing","createMarketingConfigFields","options","audienceSelect","_data","siblingData","mutateFormsCollection","collection","fieldsIndex","fieldsField","existingBlocks","blockOverrides","overriddenExistingBlocks","block","override","merged","normalizeFormBuilderPlaceholderRow","existingSlugs","marketingBlocks","createMarketingFormFields","mutateSubmissionsCollection","hooks","createValidateFormSubmissionHook","createCreateLeadHook","mutateFormBuilderCollections","collections","formsSlug","submissionsSlug","strict","list","hasForms","hasSubmissions"]}
@@ -1,2 +0,0 @@
1
- var a="payloadPluginMarketing";function n(e){return{read:e?.read??!0,write:e?.write??!0}}function d(e){return e?{audiences:n(e.audiences),contacts:n(e.contacts),broadcasts:n(e.broadcasts)}:{audiences:{read:!0,write:!0},broadcasts:{read:!0,write:!0},contacts:{read:!0,write:!0}}}function s(e){return e.audiences.read||e.contacts.read||e.broadcasts.read}function i(e){let t=e.config.custom;if(!t||typeof t!="object")return;let r=t[a];if(r?.adapter)return r}function o(e){let t=i(e);if(!t)throw new Error(`${a}: adapter missing on Payload config. Is marketingPlugin() registered?`);return t}function u(e){return i(e)}function g(e){return o(e.payload)}export{a,d as b,s as c,o as d,u as e,g as f};
2
- //# sourceMappingURL=chunk-SX3OTOU2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/marketing-integration.ts"],"sourcesContent":["import type {\n MarketingAdapter,\n MarketingEffectivePermissions,\n MarketingPluginPermissions,\n} from \"./types\"\nimport type { Payload, PayloadRequest } from \"payload\"\n\nexport const MARKETING_CUSTOM_CONFIG_KEY = \"payloadPluginMarketing\"\n\nexport interface MarketingIntegrationState {\n adapter: MarketingAdapter\n adminBasePath: string\n permissions?: MarketingPluginPermissions\n}\n\nfunction effectiveResource(slice: { read?: boolean; write?: boolean } | undefined): {\n read: boolean\n write: boolean\n} {\n return {\n read: slice?.read ?? true,\n write: slice?.write ?? true,\n }\n}\n\n/** Resolves endpoint access flags. If `permissions` is absent (plugin option omitted), all actions are allowed for authenticated users. */\nexport function resolveMarketingPermissions(\n permissions: MarketingPluginPermissions | undefined,\n): MarketingEffectivePermissions {\n if (!permissions) {\n return {\n audiences: { read: true, write: true },\n broadcasts: { read: true, write: true },\n contacts: { read: true, write: true },\n }\n }\n return {\n audiences: effectiveResource(permissions.audiences),\n contacts: effectiveResource(permissions.contacts),\n broadcasts: effectiveResource(permissions.broadcasts),\n }\n}\n\nexport function marketingMetaAllowed(effective: MarketingEffectivePermissions): boolean {\n return effective.audiences.read || effective.contacts.read || effective.broadcasts.read\n}\n\nfunction readIntegration(payload: Payload): MarketingIntegrationState | undefined {\n const custom = payload.config.custom as Record<string, unknown> | undefined\n if (!custom || typeof custom !== \"object\") {\n return undefined\n }\n const slice = custom[MARKETING_CUSTOM_CONFIG_KEY] as MarketingIntegrationState | undefined\n if (!slice?.adapter) {\n return undefined\n }\n return slice\n}\n\nexport function getMarketingIntegration(payload: Payload): MarketingIntegrationState {\n const state = readIntegration(payload)\n if (!state) {\n throw new Error(\n `${MARKETING_CUSTOM_CONFIG_KEY}: adapter missing on Payload config. Is marketingPlugin() registered?`,\n )\n }\n return state\n}\n\nexport function tryGetMarketingIntegration(payload: Payload): MarketingIntegrationState | undefined {\n return readIntegration(payload)\n}\n\nexport function getMarketingIntegrationFromRequest(req: PayloadRequest): MarketingIntegrationState {\n return getMarketingIntegration(req.payload)\n}\n"],"mappings":"AAOO,IAAMA,EAA8B,yBAQ3C,SAASC,EAAkBC,EAGzB,CACA,MAAO,CACL,KAAMA,GAAO,MAAQ,GACrB,MAAOA,GAAO,OAAS,EACzB,CACF,CAGO,SAASC,EACdC,EAC+B,CAC/B,OAAKA,EAOE,CACL,UAAWH,EAAkBG,EAAY,SAAS,EAClD,SAAUH,EAAkBG,EAAY,QAAQ,EAChD,WAAYH,EAAkBG,EAAY,UAAU,CACtD,EAVS,CACL,UAAW,CAAE,KAAM,GAAM,MAAO,EAAK,EACrC,WAAY,CAAE,KAAM,GAAM,MAAO,EAAK,EACtC,SAAU,CAAE,KAAM,GAAM,MAAO,EAAK,CACtC,CAOJ,CAEO,SAASC,EAAqBC,EAAmD,CACtF,OAAOA,EAAU,UAAU,MAAQA,EAAU,SAAS,MAAQA,EAAU,WAAW,IACrF,CAEA,SAASC,EAAgBC,EAAyD,CAChF,IAAMC,EAASD,EAAQ,OAAO,OAC9B,GAAI,CAACC,GAAU,OAAOA,GAAW,SAC/B,OAEF,IAAMP,EAAQO,EAAOT,CAA2B,EAChD,GAAKE,GAAO,QAGZ,OAAOA,CACT,CAEO,SAASQ,EAAwBF,EAA6C,CACnF,IAAMG,EAAQJ,EAAgBC,CAAO,EACrC,GAAI,CAACG,EACH,MAAM,IAAI,MACR,GAAGX,CAA2B,uEAChC,EAEF,OAAOW,CACT,CAEO,SAASC,EAA2BJ,EAAyD,CAClG,OAAOD,EAAgBC,CAAO,CAChC,CAEO,SAASK,EAAmCC,EAAgD,CACjG,OAAOJ,EAAwBI,EAAI,OAAO,CAC5C","names":["MARKETING_CUSTOM_CONFIG_KEY","effectiveResource","slice","resolveMarketingPermissions","permissions","marketingMetaAllowed","effective","readIntegration","payload","custom","getMarketingIntegration","state","tryGetMarketingIntegration","getMarketingIntegrationFromRequest","req"]}