payload-plugin-marketing 0.9.3 → 0.9.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.
- package/README.md +68 -19
- package/dist/admin/client.cjs +3 -0
- package/dist/admin/client.cjs.map +1 -0
- package/dist/admin/client.d.ts +7 -0
- package/dist/admin/client.d.ts.map +1 -0
- package/dist/admin/client.js +3 -0
- package/dist/admin/client.js.map +1 -0
- package/dist/admin/components/audience-buttons.d.ts.map +1 -1
- package/dist/admin/components/broadcast-list.d.ts.map +1 -1
- package/dist/admin/components/broadcasts-table.d.ts.map +1 -1
- package/dist/admin/components/contacts-table.d.ts.map +1 -1
- package/dist/admin/components/create-broadcast-button.d.ts +9 -1
- package/dist/admin/components/create-broadcast-button.d.ts.map +1 -1
- package/dist/admin/components/marketing-components.d.ts +0 -6
- package/dist/admin/components/marketing-components.d.ts.map +1 -1
- package/dist/admin/components/marketing-view-shell.d.ts.map +1 -1
- package/dist/admin/components/payload-modal.d.ts +8 -8
- package/dist/admin/components/payload-modal.d.ts.map +1 -1
- package/dist/admin/constants.cjs +2 -0
- package/dist/admin/constants.cjs.map +1 -0
- package/dist/admin/constants.d.ts +2 -0
- package/dist/admin/constants.d.ts.map +1 -0
- package/dist/admin/constants.js +2 -0
- package/dist/admin/constants.js.map +1 -0
- package/dist/admin/index.cjs +1 -1
- package/dist/admin/index.cjs.map +1 -1
- package/dist/admin/index.d.ts +3 -3
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/locale-options.d.ts +7 -0
- package/dist/admin/locale-options.d.ts.map +1 -0
- package/dist/admin/server.cjs +2 -0
- package/dist/admin/server.cjs.map +1 -0
- package/dist/admin/server.d.ts +2 -0
- package/dist/admin/server.d.ts.map +1 -0
- package/dist/admin/server.js +2 -0
- package/dist/admin/server.js.map +1 -0
- package/dist/admin/use-marketing-api.d.ts.map +1 -1
- package/dist/{chunk-S2EABBIN.js → chunk-G6DIJ7B2.js} +1 -1
- package/dist/chunk-G6DIJ7B2.js.map +1 -0
- package/dist/email-broadcast-template.d.ts +15 -0
- package/dist/email-broadcast-template.d.ts.map +1 -0
- package/dist/endpoints/marketing-endpoints.d.ts.map +1 -1
- package/dist/form-builder/index.cjs.map +1 -1
- package/dist/form-builder/index.js +1 -1
- package/dist/form-builder/normalize-placeholder-rows.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/marketing-integration.d.ts +2 -1
- package/dist/marketing-integration.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -2
- package/dist/chunk-S2EABBIN.js.map +0 -1
- package/dist/chunk-SX3OTOU2.js +0 -2
- package/dist/chunk-SX3OTOU2.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/admin/server.ts","../../src/admin/components/audience-detail.tsx","../../src/marketing-integration.ts","../../src/admin/components/marketing-view-shell.tsx","../../src/admin/components/view-params.ts","../../src/admin/components/audience-list.tsx","../../src/admin/paths.ts","../../src/admin/components/broadcast-list.tsx","../../src/admin/locale-options.ts"],"sourcesContent":["export { AudienceDetail, AudienceList, BroadcastList } from \"./components/views\"\n","import { Gutter, Link } from \"@payloadcms/ui\"\nimport { notFound } from \"next/navigation\"\nimport { AudienceContactsTable, EditContactButton } from \"../client\"\nimport { Suspense } from \"react\"\n\nimport {\n getMarketingIntegration,\n resolveMarketingPermissions,\n tryGetMarketingIntegration,\n} from \"../../marketing-integration\"\nimport { MarketingViewShell } from \"./marketing-view-shell\"\nimport { marketingAudienceIdFromParams } from \"./view-params\"\n\nimport type { AdminViewServerProps } from \"payload\"\n\nexport type AudienceDetailViewProps = AdminViewServerProps & {\n basePath?: string\n}\n\nexport default function AudienceDetail({\n initPageResult,\n params,\n searchParams,\n}: AudienceDetailViewProps) {\n const audienceId = marketingAudienceIdFromParams(params)\n\n if (!audienceId) {\n throw new Error(\"No audience id in route params\")\n }\n\n return (\n <MarketingViewShell initPageResult={initPageResult} params={params} searchParams={searchParams}>\n <Gutter>\n <AudienceDetailBody audienceId={audienceId} initPageResult={initPageResult} />\n </Gutter>\n </MarketingViewShell>\n )\n}\n\nasync function AudienceDetailBody({\n audienceId,\n initPageResult,\n}: {\n audienceId: string\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const integration = tryGetMarketingIntegration(initPageResult.req.payload)\n if (!integration) {\n return (\n <p role=\"alert\">Marketing plugin is not configured (missing adapter on Payload config).</p>\n )\n }\n\n const effective = resolveMarketingPermissions(integration.permissions)\n if (!effective.audiences.read) {\n return <p role=\"alert\">You do not have permission to view this audience.</p>\n }\n\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const audience = await adapter.audiences.get(audienceId)\n if (!audience) {\n notFound()\n }\n\n const audienceDashboardUrl = adapter.urls?.audience?.(audienceId)\n\n return (\n <>\n <header className=\"flex flex-col gap-4\">\n <h1>{audience.name}</h1>\n {audienceDashboardUrl ? (\n <Link href={audienceDashboardUrl} rel=\"noreferrer noopener\" target=\"_blank\">\n Open this audience in {adapter.label}\n </Link>\n ) : null}\n </header>\n\n <div className=\"mt-12 flex flex-col gap-6\">\n {effective.contacts.write ? (\n <div>\n <EditContactButton audienceId={audienceId} contact={null} />\n </div>\n ) : null}\n {effective.contacts.read ? (\n <Suspense fallback={<div aria-busy style={{ minHeight: \"12rem\" }} />}>\n <DetailContacts audienceId={audienceId} initPageResult={initPageResult} />\n </Suspense>\n ) : (\n <p role=\"alert\">You do not have permission to list contacts.</p>\n )}\n </div>\n </>\n )\n}\n\nasync function DetailContacts({\n audienceId,\n initPageResult,\n}: {\n audienceId: string\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const contacts = await adapter.contacts.list({ audienceId })\n return <AudienceContactsTable audienceId={audienceId} contacts={contacts} />\n}\n","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 { DefaultTemplate } from \"@payloadcms/next/templates\"\n\nimport type { AdminViewServerProps } from \"payload\"\nimport type { ReactNode } from \"react\"\n\ntype ShellProps = Pick<AdminViewServerProps, \"initPageResult\" | \"params\" | \"searchParams\"> & {\n children: ReactNode\n}\n\nexport function MarketingViewShell({ children, initPageResult, params, searchParams }: ShellProps) {\n return (\n <DefaultTemplate\n i18n={initPageResult.req.i18n}\n locale={initPageResult.locale}\n params={params}\n payload={initPageResult.req.payload}\n permissions={initPageResult.permissions}\n searchParams={searchParams}\n user={initPageResult.req.user ?? undefined}\n visibleEntities={initPageResult.visibleEntities}\n >\n {children}\n </DefaultTemplate>\n )\n}\n","import type { AdminViewServerProps } from \"payload\"\n\nfunction firstString(value: string | string[] | undefined): string | undefined {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim()\n }\n if (Array.isArray(value) && typeof value[0] === \"string\" && value[0].trim()) {\n return value[0].trim()\n }\n return undefined\n}\n\n/** Resolve audience id from custom admin view params (`:id` or URL segments). */\nexport function marketingAudienceIdFromParams(\n params: AdminViewServerProps[\"params\"] | undefined,\n): string | undefined {\n if (!params) {\n return undefined\n }\n\n const fromId = firstString(params.id)\n if (fromId) {\n return fromId\n }\n\n const segmentsRaw = params.segments\n const segmentList: string[] = Array.isArray(segmentsRaw)\n ? segmentsRaw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : typeof segmentsRaw === \"string\"\n ? segmentsRaw.split(\"/\").filter(Boolean)\n : []\n\n if (segmentList.length === 0) {\n return undefined\n }\n\n const audienceIdx = segmentList.lastIndexOf(\"audience\")\n if (audienceIdx >= 0 && segmentList[audienceIdx + 1]) {\n return segmentList[audienceIdx + 1]\n }\n\n const last = segmentList[segmentList.length - 1]\n if (last === \"audience\") {\n return undefined\n }\n return last\n}\n","import { Gutter, Link, Table } from \"@payloadcms/ui\"\nimport { CreateAudienceButton, DeleteAudienceButton } from \"../client\"\nimport { Suspense } from \"react\"\n\nimport {\n getMarketingIntegration,\n resolveMarketingPermissions,\n tryGetMarketingIntegration,\n} from \"../../marketing-integration\"\nimport { marketingAdminHref } from \"../paths\"\nimport { MarketingViewShell } from \"./marketing-view-shell\"\n\nimport type { AdminViewServerProps } from \"payload\"\n\nexport type AudienceListViewProps = AdminViewServerProps & {\n basePath?: string\n}\n\nexport default function AudienceList({\n basePath = \"\",\n initPageResult,\n params,\n searchParams,\n}: AudienceListViewProps) {\n return (\n <MarketingViewShell initPageResult={initPageResult} params={params} searchParams={searchParams}>\n <Gutter>\n <AudienceListBody basePath={basePath} initPageResult={initPageResult} />\n </Gutter>\n </MarketingViewShell>\n )\n}\n\nfunction AudienceListBody({\n basePath,\n initPageResult,\n}: {\n basePath: string\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const integration = tryGetMarketingIntegration(initPageResult.req.payload)\n if (!integration) {\n return (\n <p role=\"alert\">Marketing plugin is not configured (missing adapter on Payload config).</p>\n )\n }\n\n const effective = resolveMarketingPermissions(integration.permissions)\n if (!effective.audiences.read) {\n return <p role=\"alert\">You do not have permission to view audiences.</p>\n }\n\n const audiencesUrl = integration.adapter.urls?.audiences\n\n return (\n <>\n <header className=\"flex flex-col gap-4\">\n <h1>Audiences</h1>\n {audiencesUrl ? (\n <Link href={audiencesUrl} rel=\"noreferrer noopener\" target=\"_blank\">\n View audiences in {integration.adapter.label}\n </Link>\n ) : null}\n </header>\n\n <div className=\"mt-4 flex flex-col gap-8\">\n {effective.audiences.write ? (\n <div>\n <CreateAudienceButton />\n </div>\n ) : null}\n <Suspense fallback={<div aria-busy style={{ minHeight: \"4rem\" }} />}>\n <AudienceTableRows\n audiencesWrite={effective.audiences.write}\n basePath={basePath}\n initPageResult={initPageResult}\n />\n </Suspense>\n </div>\n </>\n )\n}\n\nasync function AudienceTableRows({\n audiencesWrite,\n basePath,\n initPageResult,\n}: {\n audiencesWrite: boolean\n basePath: string\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const audiences = await adapter.audiences.list()\n\n const nameColumn = {\n Heading: \"Name\",\n accessor: \"name\",\n active: true,\n field: { name: \"name\", type: \"text\" as const },\n renderedCells: audiences.map((audience) => (\n <div key={audience.id}>\n <Link href={marketingAdminHref(basePath, \"audience\", audience.id)}>{audience.name}</Link>\n </div>\n )),\n }\n\n const deleteColumn = {\n Heading: \"\",\n accessor: \"\",\n active: true,\n field: { name: \"_delete\", type: \"text\" as const },\n renderedCells: audiences.map((audience) => (\n <div key={audience.id}>\n <DeleteAudienceButton audienceId={audience.id} audienceName={audience.name} />\n </div>\n )),\n }\n\n return (\n <Table\n columns={audiencesWrite ? [nameColumn, deleteColumn] : [nameColumn]}\n data={audiences as unknown as Record<string, unknown>[]}\n />\n )\n}\n","export function joinAdminSegments(adminRoute: string, ...segments: string[]): string {\n const trimmedAdmin = adminRoute.replace(/\\/+$/, \"\") || \"\"\n const body = segments\n .flatMap((s) => String(s).split(\"/\"))\n .map((segment) => segment.replace(/^\\/+|\\/+$/g, \"\"))\n .filter(Boolean)\n .join(\"/\")\n const combined = trimmedAdmin === \"\" ? `/${body}` : `${trimmedAdmin}/${body}`\n return combined.replace(/\\/{2,}/g, \"/\")\n}\n\n/** Absolute admin hrefs for marketing custom views (`/admin`, optional plugin `basePath`, then path segments). */\nexport function marketingAdminHref(basePath: string | undefined, ...segments: string[]): string {\n const normalized = basePath?.replace(/^\\/+|\\/+$/g, \"\") ?? \"\"\n const parts = [normalized, ...segments].filter(Boolean)\n return joinAdminSegments(\"/admin\", ...parts)\n}\n","import { Gutter, Link } from \"@payloadcms/ui\"\nimport {\n BroadcastsTable,\n CreateBroadcastButton,\n type MarketingBroadcastRow,\n} from \"../client\"\nimport { Suspense } from \"react\"\n\nimport {\n getMarketingIntegration,\n resolveMarketingPermissions,\n tryGetMarketingIntegration,\n} from \"../../marketing-integration\"\nimport { getLocaleSelectOptionsFromConfig } from \"../locale-options\"\nimport { MarketingViewShell } from \"./marketing-view-shell\"\n\nimport type { AdminViewServerProps } from \"payload\"\n\nexport type BroadcastListViewProps = AdminViewServerProps & {\n basePath?: string\n}\n\nexport default function BroadcastList({\n initPageResult,\n params,\n searchParams,\n}: BroadcastListViewProps) {\n return (\n <MarketingViewShell initPageResult={initPageResult} params={params} searchParams={searchParams}>\n <Gutter>\n <BroadcastListBody initPageResult={initPageResult} />\n </Gutter>\n </MarketingViewShell>\n )\n}\n\nfunction BroadcastListBody({\n initPageResult,\n}: {\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const integration = tryGetMarketingIntegration(initPageResult.req.payload)\n if (!integration) {\n return (\n <p role=\"alert\">Marketing plugin is not configured (missing adapter on Payload config).</p>\n )\n }\n\n const effective = resolveMarketingPermissions(integration.permissions)\n if (!effective.broadcasts.read) {\n return <p role=\"alert\">You do not have permission to view broadcasts.</p>\n }\n\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const broadcastsUrl = adapter.urls?.broadcasts\n\n return (\n <>\n <header className=\"flex flex-col gap-4\">\n <h1>Campaigns</h1>\n {broadcastsUrl ? (\n <Link href={broadcastsUrl} rel=\"noreferrer noopener\" target=\"_blank\">\n View campaigns in {adapter.label}\n </Link>\n ) : null}\n </header>\n\n <div className=\"mt-4 flex flex-col gap-8\">\n {effective.broadcasts.write ? (\n <div>\n <Suspense fallback={<div aria-busy style={{ minHeight: \"2.5rem\" }} />}>\n <CreateBroadcastRegion initPageResult={initPageResult} />\n </Suspense>\n </div>\n ) : null}\n <Suspense fallback={<div aria-busy style={{ minHeight: \"4rem\" }} />}>\n <BroadcastTableRegion initPageResult={initPageResult} />\n </Suspense>\n </div>\n </>\n )\n}\n\nasync function CreateBroadcastRegion({\n initPageResult,\n}: {\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const integration = getMarketingIntegration(initPageResult.req.payload)\n const { adapter } = integration\n const audiences = await adapter.audiences.list()\n const emailBroadcastTemplates =\n integration.emailBroadcastTemplates?.map(({ id, name }) => ({ id, name })) ?? []\n const localeOptions = getLocaleSelectOptionsFromConfig(initPageResult.req.payload.config)\n return (\n <CreateBroadcastButton\n audiences={audiences}\n emailBroadcastTemplates={emailBroadcastTemplates}\n localeOptions={localeOptions}\n provider={adapter.provider}\n />\n )\n}\n\nasync function BroadcastTableRegion({\n initPageResult,\n}: {\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const rows = await adapter.broadcasts.list()\n const broadcasts: MarketingBroadcastRow[] = rows.map((b) => ({\n ...b,\n externalDashboardUrl: adapter.urls?.broadcast?.(b.id),\n }))\n\n return <BroadcastsTable broadcasts={broadcasts} />\n}\n","import type { Locale, SanitizedConfig } from \"payload\"\n\nfunction labelForLocale(loc: Locale): string {\n const { label, code } = loc\n if (typeof label === \"string\") {\n return label\n }\n if (label && typeof label === \"object\") {\n for (const value of Object.values(label)) {\n if (typeof value === \"string\") {\n return value\n }\n }\n }\n return code\n}\n\n/** Options for admin selects; values are locale codes from `config.localization.locales`. */\nexport function getLocaleSelectOptionsFromConfig(\n config: SanitizedConfig,\n): { label: string; value: string }[] {\n const raw = config.localization\n if (raw === false || raw === undefined) {\n return []\n }\n const locales = raw.locales\n if (!locales?.length) {\n return []\n }\n return locales.map((locItem: Locale) => ({\n label: labelForLocale(locItem),\n value: locItem.code,\n }))\n}\n"],"mappings":"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","names":["server_exports","__export","AudienceDetail","AudienceList","BroadcastList","__toCommonJS","import_ui","import_navigation","import_client","import_react","MARKETING_CUSTOM_CONFIG_KEY","effectiveResource","slice","resolveMarketingPermissions","permissions","readIntegration","payload","custom","slice","MARKETING_CUSTOM_CONFIG_KEY","getMarketingIntegration","state","tryGetMarketingIntegration","import_templates","import_jsx_runtime","MarketingViewShell","children","initPageResult","params","searchParams","firstString","value","marketingAudienceIdFromParams","params","fromId","segmentsRaw","segmentList","s","audienceIdx","last","import_jsx_runtime","AudienceDetail","initPageResult","params","searchParams","audienceId","marketingAudienceIdFromParams","MarketingViewShell","AudienceDetailBody","integration","tryGetMarketingIntegration","effective","resolveMarketingPermissions","adapter","getMarketingIntegration","audience","audienceDashboardUrl","DetailContacts","contacts","import_ui","import_client","import_react","joinAdminSegments","adminRoute","segments","trimmedAdmin","body","s","segment","marketingAdminHref","basePath","parts","import_jsx_runtime","AudienceList","basePath","initPageResult","params","searchParams","MarketingViewShell","AudienceListBody","integration","tryGetMarketingIntegration","effective","resolveMarketingPermissions","audiencesUrl","AudienceTableRows","audiencesWrite","adapter","getMarketingIntegration","audiences","nameColumn","audience","marketingAdminHref","deleteColumn","import_ui","import_client","import_react","labelForLocale","loc","label","code","value","getLocaleSelectOptionsFromConfig","config","raw","locales","locItem","import_jsx_runtime","BroadcastList","initPageResult","params","searchParams","MarketingViewShell","BroadcastListBody","integration","tryGetMarketingIntegration","effective","resolveMarketingPermissions","adapter","getMarketingIntegration","broadcastsUrl","CreateBroadcastRegion","BroadcastTableRegion","audiences","emailBroadcastTemplates","id","name","localeOptions","getLocaleSelectOptionsFromConfig","broadcasts","b"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/admin/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Gutter as C,Link as q}from"@payloadcms/ui";import{notFound as T}from"next/navigation";import{AudienceContactsTable as N,EditContactButton as D}from"payload-plugin-marketing/admin/client";import{Suspense as E}from"react";var v="payloadPluginMarketing";function k(e){return{read:e?.read??!0,write:e?.write??!0}}function p(e){return e?{audiences:k(e.audiences),contacts:k(e.contacts),broadcasts:k(e.broadcasts)}:{audiences:{read:!0,write:!0},broadcasts:{read:!0,write:!0},contacts:{read:!0,write:!0}}}function A(e){let t=e.config.custom;if(!t||typeof t!="object")return;let r=t[v];if(r?.adapter)return r}function u(e){let t=A(e);if(!t)throw new Error(`${v}: adapter missing on Payload config. Is marketingPlugin() registered?`);return t}function m(e){return A(e)}import{DefaultTemplate as I}from"@payloadcms/next/templates";import{jsx as L}from"react/jsx-runtime";function f({children:e,initPageResult:t,params:r,searchParams:n}){return L(I,{i18n:t.req.i18n,locale:t.locale,params:r,payload:t.req.payload,permissions:t.permissions,searchParams:n,user:t.req.user??void 0,visibleEntities:t.visibleEntities,children:e})}function R(e){if(typeof e=="string"&&e.trim())return e.trim();if(Array.isArray(e)&&typeof e[0]=="string"&&e[0].trim())return e[0].trim()}function S(e){if(!e)return;let t=R(e.id);if(t)return t;let r=e.segments,n=Array.isArray(r)?r.filter(l=>typeof l=="string"&&l.length>0):typeof r=="string"?r.split("/").filter(Boolean):[];if(n.length===0)return;let i=n.lastIndexOf("audience");if(i>=0&&n[i+1])return n[i+1];let s=n[n.length-1];if(s!=="audience")return s}import{Fragment as F,jsx as d,jsxs as g}from"react/jsx-runtime";function w({initPageResult:e,params:t,searchParams:r}){let n=S(t);if(!n)throw new Error("No audience id in route params");return d(f,{initPageResult:e,params:t,searchParams:r,children:d(C,{children:d(G,{audienceId:n,initPageResult:e})})})}async function G({audienceId:e,initPageResult:t}){let r=m(t.req.payload);if(!r)return d("p",{role:"alert",children:"Marketing plugin is not configured (missing adapter on Payload config)."});let n=p(r.permissions);if(!n.audiences.read)return d("p",{role:"alert",children:"You do not have permission to view this audience."});let{adapter:i}=u(t.req.payload),s=await i.audiences.get(e);s||T();let l=i.urls?.audience?.(e);return g(F,{children:[g("header",{className:"flex flex-col gap-4",children:[d("h1",{children:s.name}),l?g(q,{href:l,rel:"noreferrer noopener",target:"_blank",children:["Open this audience in ",i.label]}):null]}),g("div",{className:"mt-12 flex flex-col gap-6",children:[n.contacts.write?d("div",{children:d(D,{audienceId:e,contact:null})}):null,n.contacts.read?d(E,{fallback:d("div",{"aria-busy":!0,style:{minHeight:"12rem"}}),children:d(O,{audienceId:e,initPageResult:t})}):d("p",{role:"alert",children:"You do not have permission to list contacts."})]})]})}async function O({audienceId:e,initPageResult:t}){let{adapter:r}=u(t.req.payload),n=await r.contacts.list({audienceId:e});return d(N,{audienceId:e,contacts:n})}import{Gutter as _,Link as x,Table as $}from"@payloadcms/ui";import{CreateAudienceButton as z,DeleteAudienceButton as U}from"payload-plugin-marketing/admin/client";import{Suspense as Y}from"react";function H(e,...t){let r=e.replace(/\/+$/,"")||"",n=t.flatMap(s=>String(s).split("/")).map(s=>s.replace(/^\/+|\/+$/g,"")).filter(Boolean).join("/");return(r===""?`/${n}`:`${r}/${n}`).replace(/\/{2,}/g,"/")}function M(e,...t){let n=[e?.replace(/^\/+|\/+$/g,"")??"",...t].filter(Boolean);return H("/admin",...n)}import{Fragment as j,jsx as a,jsxs as y}from"react/jsx-runtime";function b({basePath:e="",initPageResult:t,params:r,searchParams:n}){return a(f,{initPageResult:t,params:r,searchParams:n,children:a(_,{children:a(K,{basePath:e,initPageResult:t})})})}function K({basePath:e,initPageResult:t}){let r=m(t.req.payload);if(!r)return a("p",{role:"alert",children:"Marketing plugin is not configured (missing adapter on Payload config)."});let n=p(r.permissions);if(!n.audiences.read)return a("p",{role:"alert",children:"You do not have permission to view audiences."});let i=r.adapter.urls?.audiences;return y(j,{children:[y("header",{className:"flex flex-col gap-4",children:[a("h1",{children:"Audiences"}),i?y(x,{href:i,rel:"noreferrer noopener",target:"_blank",children:["View audiences in ",r.adapter.label]}):null]}),y("div",{className:"mt-4 flex flex-col gap-8",children:[n.audiences.write?a("div",{children:a(z,{})}):null,a(Y,{fallback:a("div",{"aria-busy":!0,style:{minHeight:"4rem"}}),children:a(W,{audiencesWrite:n.audiences.write,basePath:e,initPageResult:t})})]})]})}async function W({audiencesWrite:e,basePath:t,initPageResult:r}){let{adapter:n}=u(r.req.payload),i=await n.audiences.list(),s={Heading:"Name",accessor:"name",active:!0,field:{name:"name",type:"text"},renderedCells:i.map(c=>a("div",{children:a(x,{href:M(t,"audience",c.id),children:c.name})},c.id))},l={Heading:"",accessor:"",active:!0,field:{name:"_delete",type:"text"},renderedCells:i.map(c=>a("div",{children:a(U,{audienceId:c.id,audienceName:c.name})},c.id))};return a($,{columns:e?[s,l]:[s],data:i})}import{Gutter as Q,Link as X}from"@payloadcms/ui";import{BroadcastsTable as Z,CreateBroadcastButton as ee}from"payload-plugin-marketing/admin/client";import{Suspense as B}from"react";function J(e){let{label:t,code:r}=e;if(typeof t=="string")return t;if(t&&typeof t=="object"){for(let n of Object.values(t))if(typeof n=="string")return n}return r}function V(e){let t=e.localization;if(t===!1||t===void 0)return[];let r=t.locales;return r?.length?r.map(n=>({label:J(n),value:n.code})):[]}import{Fragment as ie,jsx as o,jsxs as P}from"react/jsx-runtime";function h({initPageResult:e,params:t,searchParams:r}){return o(f,{initPageResult:e,params:t,searchParams:r,children:o(Q,{children:o(te,{initPageResult:e})})})}function te({initPageResult:e}){let t=m(e.req.payload);if(!t)return o("p",{role:"alert",children:"Marketing plugin is not configured (missing adapter on Payload config)."});let r=p(t.permissions);if(!r.broadcasts.read)return o("p",{role:"alert",children:"You do not have permission to view broadcasts."});let{adapter:n}=u(e.req.payload),i=n.urls?.broadcasts;return P(ie,{children:[P("header",{className:"flex flex-col gap-4",children:[o("h1",{children:"Campaigns"}),i?P(X,{href:i,rel:"noreferrer noopener",target:"_blank",children:["View campaigns in ",n.label]}):null]}),P("div",{className:"mt-4 flex flex-col gap-8",children:[r.broadcasts.write?o("div",{children:o(B,{fallback:o("div",{"aria-busy":!0,style:{minHeight:"2.5rem"}}),children:o(re,{initPageResult:e})})}):null,o(B,{fallback:o("div",{"aria-busy":!0,style:{minHeight:"4rem"}}),children:o(ne,{initPageResult:e})})]})]})}async function re({initPageResult:e}){let t=u(e.req.payload),{adapter:r}=t,n=await r.audiences.list(),i=t.emailBroadcastTemplates?.map(({id:l,name:c})=>({id:l,name:c}))??[],s=V(e.req.payload.config);return o(ee,{audiences:n,emailBroadcastTemplates:i,localeOptions:s,provider:r.provider})}async function ne({initPageResult:e}){let{adapter:t}=u(e.req.payload),n=(await t.broadcasts.list()).map(i=>({...i,externalDashboardUrl:t.urls?.broadcast?.(i.id)}));return o(Z,{broadcasts:n})}export{w as AudienceDetail,b as AudienceList,h as BroadcastList};
|
|
2
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/admin/components/audience-detail.tsx","../../src/marketing-integration.ts","../../src/admin/components/marketing-view-shell.tsx","../../src/admin/components/view-params.ts","../../src/admin/components/audience-list.tsx","../../src/admin/paths.ts","../../src/admin/components/broadcast-list.tsx","../../src/admin/locale-options.ts"],"sourcesContent":["import { Gutter, Link } from \"@payloadcms/ui\"\nimport { notFound } from \"next/navigation\"\nimport { AudienceContactsTable, EditContactButton } from \"../client\"\nimport { Suspense } from \"react\"\n\nimport {\n getMarketingIntegration,\n resolveMarketingPermissions,\n tryGetMarketingIntegration,\n} from \"../../marketing-integration\"\nimport { MarketingViewShell } from \"./marketing-view-shell\"\nimport { marketingAudienceIdFromParams } from \"./view-params\"\n\nimport type { AdminViewServerProps } from \"payload\"\n\nexport type AudienceDetailViewProps = AdminViewServerProps & {\n basePath?: string\n}\n\nexport default function AudienceDetail({\n initPageResult,\n params,\n searchParams,\n}: AudienceDetailViewProps) {\n const audienceId = marketingAudienceIdFromParams(params)\n\n if (!audienceId) {\n throw new Error(\"No audience id in route params\")\n }\n\n return (\n <MarketingViewShell initPageResult={initPageResult} params={params} searchParams={searchParams}>\n <Gutter>\n <AudienceDetailBody audienceId={audienceId} initPageResult={initPageResult} />\n </Gutter>\n </MarketingViewShell>\n )\n}\n\nasync function AudienceDetailBody({\n audienceId,\n initPageResult,\n}: {\n audienceId: string\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const integration = tryGetMarketingIntegration(initPageResult.req.payload)\n if (!integration) {\n return (\n <p role=\"alert\">Marketing plugin is not configured (missing adapter on Payload config).</p>\n )\n }\n\n const effective = resolveMarketingPermissions(integration.permissions)\n if (!effective.audiences.read) {\n return <p role=\"alert\">You do not have permission to view this audience.</p>\n }\n\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const audience = await adapter.audiences.get(audienceId)\n if (!audience) {\n notFound()\n }\n\n const audienceDashboardUrl = adapter.urls?.audience?.(audienceId)\n\n return (\n <>\n <header className=\"flex flex-col gap-4\">\n <h1>{audience.name}</h1>\n {audienceDashboardUrl ? (\n <Link href={audienceDashboardUrl} rel=\"noreferrer noopener\" target=\"_blank\">\n Open this audience in {adapter.label}\n </Link>\n ) : null}\n </header>\n\n <div className=\"mt-12 flex flex-col gap-6\">\n {effective.contacts.write ? (\n <div>\n <EditContactButton audienceId={audienceId} contact={null} />\n </div>\n ) : null}\n {effective.contacts.read ? (\n <Suspense fallback={<div aria-busy style={{ minHeight: \"12rem\" }} />}>\n <DetailContacts audienceId={audienceId} initPageResult={initPageResult} />\n </Suspense>\n ) : (\n <p role=\"alert\">You do not have permission to list contacts.</p>\n )}\n </div>\n </>\n )\n}\n\nasync function DetailContacts({\n audienceId,\n initPageResult,\n}: {\n audienceId: string\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const contacts = await adapter.contacts.list({ audienceId })\n return <AudienceContactsTable audienceId={audienceId} contacts={contacts} />\n}\n","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 { DefaultTemplate } from \"@payloadcms/next/templates\"\n\nimport type { AdminViewServerProps } from \"payload\"\nimport type { ReactNode } from \"react\"\n\ntype ShellProps = Pick<AdminViewServerProps, \"initPageResult\" | \"params\" | \"searchParams\"> & {\n children: ReactNode\n}\n\nexport function MarketingViewShell({ children, initPageResult, params, searchParams }: ShellProps) {\n return (\n <DefaultTemplate\n i18n={initPageResult.req.i18n}\n locale={initPageResult.locale}\n params={params}\n payload={initPageResult.req.payload}\n permissions={initPageResult.permissions}\n searchParams={searchParams}\n user={initPageResult.req.user ?? undefined}\n visibleEntities={initPageResult.visibleEntities}\n >\n {children}\n </DefaultTemplate>\n )\n}\n","import type { AdminViewServerProps } from \"payload\"\n\nfunction firstString(value: string | string[] | undefined): string | undefined {\n if (typeof value === \"string\" && value.trim()) {\n return value.trim()\n }\n if (Array.isArray(value) && typeof value[0] === \"string\" && value[0].trim()) {\n return value[0].trim()\n }\n return undefined\n}\n\n/** Resolve audience id from custom admin view params (`:id` or URL segments). */\nexport function marketingAudienceIdFromParams(\n params: AdminViewServerProps[\"params\"] | undefined,\n): string | undefined {\n if (!params) {\n return undefined\n }\n\n const fromId = firstString(params.id)\n if (fromId) {\n return fromId\n }\n\n const segmentsRaw = params.segments\n const segmentList: string[] = Array.isArray(segmentsRaw)\n ? segmentsRaw.filter((s): s is string => typeof s === \"string\" && s.length > 0)\n : typeof segmentsRaw === \"string\"\n ? segmentsRaw.split(\"/\").filter(Boolean)\n : []\n\n if (segmentList.length === 0) {\n return undefined\n }\n\n const audienceIdx = segmentList.lastIndexOf(\"audience\")\n if (audienceIdx >= 0 && segmentList[audienceIdx + 1]) {\n return segmentList[audienceIdx + 1]\n }\n\n const last = segmentList[segmentList.length - 1]\n if (last === \"audience\") {\n return undefined\n }\n return last\n}\n","import { Gutter, Link, Table } from \"@payloadcms/ui\"\nimport { CreateAudienceButton, DeleteAudienceButton } from \"../client\"\nimport { Suspense } from \"react\"\n\nimport {\n getMarketingIntegration,\n resolveMarketingPermissions,\n tryGetMarketingIntegration,\n} from \"../../marketing-integration\"\nimport { marketingAdminHref } from \"../paths\"\nimport { MarketingViewShell } from \"./marketing-view-shell\"\n\nimport type { AdminViewServerProps } from \"payload\"\n\nexport type AudienceListViewProps = AdminViewServerProps & {\n basePath?: string\n}\n\nexport default function AudienceList({\n basePath = \"\",\n initPageResult,\n params,\n searchParams,\n}: AudienceListViewProps) {\n return (\n <MarketingViewShell initPageResult={initPageResult} params={params} searchParams={searchParams}>\n <Gutter>\n <AudienceListBody basePath={basePath} initPageResult={initPageResult} />\n </Gutter>\n </MarketingViewShell>\n )\n}\n\nfunction AudienceListBody({\n basePath,\n initPageResult,\n}: {\n basePath: string\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const integration = tryGetMarketingIntegration(initPageResult.req.payload)\n if (!integration) {\n return (\n <p role=\"alert\">Marketing plugin is not configured (missing adapter on Payload config).</p>\n )\n }\n\n const effective = resolveMarketingPermissions(integration.permissions)\n if (!effective.audiences.read) {\n return <p role=\"alert\">You do not have permission to view audiences.</p>\n }\n\n const audiencesUrl = integration.adapter.urls?.audiences\n\n return (\n <>\n <header className=\"flex flex-col gap-4\">\n <h1>Audiences</h1>\n {audiencesUrl ? (\n <Link href={audiencesUrl} rel=\"noreferrer noopener\" target=\"_blank\">\n View audiences in {integration.adapter.label}\n </Link>\n ) : null}\n </header>\n\n <div className=\"mt-4 flex flex-col gap-8\">\n {effective.audiences.write ? (\n <div>\n <CreateAudienceButton />\n </div>\n ) : null}\n <Suspense fallback={<div aria-busy style={{ minHeight: \"4rem\" }} />}>\n <AudienceTableRows\n audiencesWrite={effective.audiences.write}\n basePath={basePath}\n initPageResult={initPageResult}\n />\n </Suspense>\n </div>\n </>\n )\n}\n\nasync function AudienceTableRows({\n audiencesWrite,\n basePath,\n initPageResult,\n}: {\n audiencesWrite: boolean\n basePath: string\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const audiences = await adapter.audiences.list()\n\n const nameColumn = {\n Heading: \"Name\",\n accessor: \"name\",\n active: true,\n field: { name: \"name\", type: \"text\" as const },\n renderedCells: audiences.map((audience) => (\n <div key={audience.id}>\n <Link href={marketingAdminHref(basePath, \"audience\", audience.id)}>{audience.name}</Link>\n </div>\n )),\n }\n\n const deleteColumn = {\n Heading: \"\",\n accessor: \"\",\n active: true,\n field: { name: \"_delete\", type: \"text\" as const },\n renderedCells: audiences.map((audience) => (\n <div key={audience.id}>\n <DeleteAudienceButton audienceId={audience.id} audienceName={audience.name} />\n </div>\n )),\n }\n\n return (\n <Table\n columns={audiencesWrite ? [nameColumn, deleteColumn] : [nameColumn]}\n data={audiences as unknown as Record<string, unknown>[]}\n />\n )\n}\n","export function joinAdminSegments(adminRoute: string, ...segments: string[]): string {\n const trimmedAdmin = adminRoute.replace(/\\/+$/, \"\") || \"\"\n const body = segments\n .flatMap((s) => String(s).split(\"/\"))\n .map((segment) => segment.replace(/^\\/+|\\/+$/g, \"\"))\n .filter(Boolean)\n .join(\"/\")\n const combined = trimmedAdmin === \"\" ? `/${body}` : `${trimmedAdmin}/${body}`\n return combined.replace(/\\/{2,}/g, \"/\")\n}\n\n/** Absolute admin hrefs for marketing custom views (`/admin`, optional plugin `basePath`, then path segments). */\nexport function marketingAdminHref(basePath: string | undefined, ...segments: string[]): string {\n const normalized = basePath?.replace(/^\\/+|\\/+$/g, \"\") ?? \"\"\n const parts = [normalized, ...segments].filter(Boolean)\n return joinAdminSegments(\"/admin\", ...parts)\n}\n","import { Gutter, Link } from \"@payloadcms/ui\"\nimport {\n BroadcastsTable,\n CreateBroadcastButton,\n type MarketingBroadcastRow,\n} from \"../client\"\nimport { Suspense } from \"react\"\n\nimport {\n getMarketingIntegration,\n resolveMarketingPermissions,\n tryGetMarketingIntegration,\n} from \"../../marketing-integration\"\nimport { getLocaleSelectOptionsFromConfig } from \"../locale-options\"\nimport { MarketingViewShell } from \"./marketing-view-shell\"\n\nimport type { AdminViewServerProps } from \"payload\"\n\nexport type BroadcastListViewProps = AdminViewServerProps & {\n basePath?: string\n}\n\nexport default function BroadcastList({\n initPageResult,\n params,\n searchParams,\n}: BroadcastListViewProps) {\n return (\n <MarketingViewShell initPageResult={initPageResult} params={params} searchParams={searchParams}>\n <Gutter>\n <BroadcastListBody initPageResult={initPageResult} />\n </Gutter>\n </MarketingViewShell>\n )\n}\n\nfunction BroadcastListBody({\n initPageResult,\n}: {\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const integration = tryGetMarketingIntegration(initPageResult.req.payload)\n if (!integration) {\n return (\n <p role=\"alert\">Marketing plugin is not configured (missing adapter on Payload config).</p>\n )\n }\n\n const effective = resolveMarketingPermissions(integration.permissions)\n if (!effective.broadcasts.read) {\n return <p role=\"alert\">You do not have permission to view broadcasts.</p>\n }\n\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const broadcastsUrl = adapter.urls?.broadcasts\n\n return (\n <>\n <header className=\"flex flex-col gap-4\">\n <h1>Campaigns</h1>\n {broadcastsUrl ? (\n <Link href={broadcastsUrl} rel=\"noreferrer noopener\" target=\"_blank\">\n View campaigns in {adapter.label}\n </Link>\n ) : null}\n </header>\n\n <div className=\"mt-4 flex flex-col gap-8\">\n {effective.broadcasts.write ? (\n <div>\n <Suspense fallback={<div aria-busy style={{ minHeight: \"2.5rem\" }} />}>\n <CreateBroadcastRegion initPageResult={initPageResult} />\n </Suspense>\n </div>\n ) : null}\n <Suspense fallback={<div aria-busy style={{ minHeight: \"4rem\" }} />}>\n <BroadcastTableRegion initPageResult={initPageResult} />\n </Suspense>\n </div>\n </>\n )\n}\n\nasync function CreateBroadcastRegion({\n initPageResult,\n}: {\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const integration = getMarketingIntegration(initPageResult.req.payload)\n const { adapter } = integration\n const audiences = await adapter.audiences.list()\n const emailBroadcastTemplates =\n integration.emailBroadcastTemplates?.map(({ id, name }) => ({ id, name })) ?? []\n const localeOptions = getLocaleSelectOptionsFromConfig(initPageResult.req.payload.config)\n return (\n <CreateBroadcastButton\n audiences={audiences}\n emailBroadcastTemplates={emailBroadcastTemplates}\n localeOptions={localeOptions}\n provider={adapter.provider}\n />\n )\n}\n\nasync function BroadcastTableRegion({\n initPageResult,\n}: {\n initPageResult: AdminViewServerProps[\"initPageResult\"]\n}) {\n const { adapter } = getMarketingIntegration(initPageResult.req.payload)\n const rows = await adapter.broadcasts.list()\n const broadcasts: MarketingBroadcastRow[] = rows.map((b) => ({\n ...b,\n externalDashboardUrl: adapter.urls?.broadcast?.(b.id),\n }))\n\n return <BroadcastsTable broadcasts={broadcasts} />\n}\n","import type { Locale, SanitizedConfig } from \"payload\"\n\nfunction labelForLocale(loc: Locale): string {\n const { label, code } = loc\n if (typeof label === \"string\") {\n return label\n }\n if (label && typeof label === \"object\") {\n for (const value of Object.values(label)) {\n if (typeof value === \"string\") {\n return value\n }\n }\n }\n return code\n}\n\n/** Options for admin selects; values are locale codes from `config.localization.locales`. */\nexport function getLocaleSelectOptionsFromConfig(\n config: SanitizedConfig,\n): { label: string; value: string }[] {\n const raw = config.localization\n if (raw === false || raw === undefined) {\n return []\n }\n const locales = raw.locales\n if (!locales?.length) {\n return []\n }\n return locales.map((locItem: Locale) => ({\n label: labelForLocale(locItem),\n value: locItem.code,\n }))\n}\n"],"mappings":"AAAA,OAAS,UAAAA,EAAQ,QAAAC,MAAY,iBAC7B,OAAS,YAAAC,MAAgB,kBACzB,OAAS,yBAAAC,EAAuB,qBAAAC,MAAyB,wCACzD,OAAS,YAAAC,MAAgB,QCKlB,IAAMC,EAA8B,yBAS3C,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,CAMA,SAASC,EAAgBC,EAAyD,CAChF,IAAMC,EAASD,EAAQ,OAAO,OAC9B,GAAI,CAACC,GAAU,OAAOA,GAAW,SAC/B,OAEF,IAAMC,EAAQD,EAAOE,CAA2B,EAChD,GAAKD,GAAO,QAGZ,OAAOA,CACT,CAEO,SAASE,EAAwBJ,EAA6C,CACnF,IAAMK,EAAQN,EAAgBC,CAAO,EACrC,GAAI,CAACK,EACH,MAAM,IAAI,MACR,GAAGF,CAA2B,uEAChC,EAEF,OAAOE,CACT,CAEO,SAASC,EACdN,EACuC,CACvC,OAAOD,EAAgBC,CAAO,CAChC,CC3EA,OAAS,mBAAAO,MAAuB,6BAW5B,cAAAC,MAAA,oBAFG,SAASC,EAAmB,CAAE,SAAAC,EAAU,eAAAC,EAAgB,OAAAC,EAAQ,aAAAC,CAAa,EAAe,CACjG,OACEL,EAACD,EAAA,CACC,KAAMI,EAAe,IAAI,KACzB,OAAQA,EAAe,OACvB,OAAQC,EACR,QAASD,EAAe,IAAI,QAC5B,YAAaA,EAAe,YAC5B,aAAcE,EACd,KAAMF,EAAe,IAAI,MAAQ,OACjC,gBAAiBA,EAAe,gBAE/B,SAAAD,EACH,CAEJ,CCtBA,SAASI,EAAYC,EAA0D,CAC7E,GAAI,OAAOA,GAAU,UAAYA,EAAM,KAAK,EAC1C,OAAOA,EAAM,KAAK,EAEpB,GAAI,MAAM,QAAQA,CAAK,GAAK,OAAOA,EAAM,CAAC,GAAM,UAAYA,EAAM,CAAC,EAAE,KAAK,EACxE,OAAOA,EAAM,CAAC,EAAE,KAAK,CAGzB,CAGO,SAASC,EACdC,EACoB,CACpB,GAAI,CAACA,EACH,OAGF,IAAMC,EAASJ,EAAYG,EAAO,EAAE,EACpC,GAAIC,EACF,OAAOA,EAGT,IAAMC,EAAcF,EAAO,SACrBG,EAAwB,MAAM,QAAQD,CAAW,EACnDA,EAAY,OAAQE,GAAmB,OAAOA,GAAM,UAAYA,EAAE,OAAS,CAAC,EAC5E,OAAOF,GAAgB,SACrBA,EAAY,MAAM,GAAG,EAAE,OAAO,OAAO,EACrC,CAAC,EAEP,GAAIC,EAAY,SAAW,EACzB,OAGF,IAAME,EAAcF,EAAY,YAAY,UAAU,EACtD,GAAIE,GAAe,GAAKF,EAAYE,EAAc,CAAC,EACjD,OAAOF,EAAYE,EAAc,CAAC,EAGpC,IAAMC,EAAOH,EAAYA,EAAY,OAAS,CAAC,EAC/C,GAAIG,IAAS,WAGb,OAAOA,CACT,CHbQ,OAkCJ,YAAAC,EAlCI,OAAAC,EAsCE,QAAAC,MAtCF,oBAdO,SAARC,EAAgC,CACrC,eAAAC,EACA,OAAAC,EACA,aAAAC,CACF,EAA4B,CAC1B,IAAMC,EAAaC,EAA8BH,CAAM,EAEvD,GAAI,CAACE,EACH,MAAM,IAAI,MAAM,gCAAgC,EAGlD,OACEN,EAACQ,EAAA,CAAmB,eAAgBL,EAAgB,OAAQC,EAAQ,aAAcC,EAChF,SAAAL,EAACS,EAAA,CACC,SAAAT,EAACU,EAAA,CAAmB,WAAYJ,EAAY,eAAgBH,EAAgB,EAC9E,EACF,CAEJ,CAEA,eAAeO,EAAmB,CAChC,WAAAJ,EACA,eAAAH,CACF,EAGG,CACD,IAAMQ,EAAcC,EAA2BT,EAAe,IAAI,OAAO,EACzE,GAAI,CAACQ,EACH,OACEX,EAAC,KAAE,KAAK,QAAQ,mFAAuE,EAI3F,IAAMa,EAAYC,EAA4BH,EAAY,WAAW,EACrE,GAAI,CAACE,EAAU,UAAU,KACvB,OAAOb,EAAC,KAAE,KAAK,QAAQ,6DAAiD,EAG1E,GAAM,CAAE,QAAAe,CAAQ,EAAIC,EAAwBb,EAAe,IAAI,OAAO,EAChEc,EAAW,MAAMF,EAAQ,UAAU,IAAIT,CAAU,EAClDW,GACHC,EAAS,EAGX,IAAMC,EAAuBJ,EAAQ,MAAM,WAAWT,CAAU,EAEhE,OACEL,EAAAF,EAAA,CACE,UAAAE,EAAC,UAAO,UAAU,sBAChB,UAAAD,EAAC,MAAI,SAAAiB,EAAS,KAAK,EAClBE,EACClB,EAACmB,EAAA,CAAK,KAAMD,EAAsB,IAAI,sBAAsB,OAAO,SAAS,mCACnDJ,EAAQ,OACjC,EACE,MACN,EAEAd,EAAC,OAAI,UAAU,4BACZ,UAAAY,EAAU,SAAS,MAClBb,EAAC,OACC,SAAAA,EAACqB,EAAA,CAAkB,WAAYf,EAAY,QAAS,KAAM,EAC5D,EACE,KACHO,EAAU,SAAS,KAClBb,EAACsB,EAAA,CAAS,SAAUtB,EAAC,OAAI,YAAS,GAAC,MAAO,CAAE,UAAW,OAAQ,EAAG,EAChE,SAAAA,EAACuB,EAAA,CAAe,WAAYjB,EAAY,eAAgBH,EAAgB,EAC1E,EAEAH,EAAC,KAAE,KAAK,QAAQ,wDAA4C,GAEhE,GACF,CAEJ,CAEA,eAAeuB,EAAe,CAC5B,WAAAjB,EACA,eAAAH,CACF,EAGG,CACD,GAAM,CAAE,QAAAY,CAAQ,EAAIC,EAAwBb,EAAe,IAAI,OAAO,EAChEqB,EAAW,MAAMT,EAAQ,SAAS,KAAK,CAAE,WAAAT,CAAW,CAAC,EAC3D,OAAON,EAACyB,EAAA,CAAsB,WAAYnB,EAAY,SAAUkB,EAAU,CAC5E,CIzGA,OAAS,UAAAE,EAAQ,QAAAC,EAAM,SAAAC,MAAa,iBACpC,OAAS,wBAAAC,EAAsB,wBAAAC,MAA4B,wCAC3D,OAAS,YAAAC,MAAgB,QCFlB,SAASC,EAAkBC,KAAuBC,EAA4B,CACnF,IAAMC,EAAeF,EAAW,QAAQ,OAAQ,EAAE,GAAK,GACjDG,EAAOF,EACV,QAAS,GAAM,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,EACnC,IAAKG,GAAYA,EAAQ,QAAQ,aAAc,EAAE,CAAC,EAClD,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,OADiBF,IAAiB,GAAK,IAAIC,CAAI,GAAK,GAAGD,CAAY,IAAIC,CAAI,IAC3D,QAAQ,UAAW,GAAG,CACxC,CAGO,SAASE,EAAmBC,KAAiCL,EAA4B,CAE9F,IAAMM,EAAQ,CADKD,GAAU,QAAQ,aAAc,EAAE,GAAK,GAC/B,GAAGL,CAAQ,EAAE,OAAO,OAAO,EACtD,OAAOF,EAAkB,SAAU,GAAGQ,CAAK,CAC7C,CDWQ,OA4BJ,YAAAC,EA5BI,OAAAC,EAgCE,QAAAC,MAhCF,oBATO,SAARC,EAA8B,CACnC,SAAAC,EAAW,GACX,eAAAC,EACA,OAAAC,EACA,aAAAC,CACF,EAA0B,CACxB,OACEN,EAACO,EAAA,CAAmB,eAAgBH,EAAgB,OAAQC,EAAQ,aAAcC,EAChF,SAAAN,EAACQ,EAAA,CACC,SAAAR,EAACS,EAAA,CAAiB,SAAUN,EAAU,eAAgBC,EAAgB,EACxE,EACF,CAEJ,CAEA,SAASK,EAAiB,CACxB,SAAAN,EACA,eAAAC,CACF,EAGG,CACD,IAAMM,EAAcC,EAA2BP,EAAe,IAAI,OAAO,EACzE,GAAI,CAACM,EACH,OACEV,EAAC,KAAE,KAAK,QAAQ,mFAAuE,EAI3F,IAAMY,EAAYC,EAA4BH,EAAY,WAAW,EACrE,GAAI,CAACE,EAAU,UAAU,KACvB,OAAOZ,EAAC,KAAE,KAAK,QAAQ,yDAA6C,EAGtE,IAAMc,EAAeJ,EAAY,QAAQ,MAAM,UAE/C,OACET,EAAAF,EAAA,CACE,UAAAE,EAAC,UAAO,UAAU,sBAChB,UAAAD,EAAC,MAAG,qBAAS,EACZc,EACCb,EAACc,EAAA,CAAK,KAAMD,EAAc,IAAI,sBAAsB,OAAO,SAAS,+BAC/CJ,EAAY,QAAQ,OACzC,EACE,MACN,EAEAT,EAAC,OAAI,UAAU,2BACZ,UAAAW,EAAU,UAAU,MACnBZ,EAAC,OACC,SAAAA,EAACgB,EAAA,EAAqB,EACxB,EACE,KACJhB,EAACiB,EAAA,CAAS,SAAUjB,EAAC,OAAI,YAAS,GAAC,MAAO,CAAE,UAAW,MAAO,EAAG,EAC/D,SAAAA,EAACkB,EAAA,CACC,eAAgBN,EAAU,UAAU,MACpC,SAAUT,EACV,eAAgBC,EAClB,EACF,GACF,GACF,CAEJ,CAEA,eAAec,EAAkB,CAC/B,eAAAC,EACA,SAAAhB,EACA,eAAAC,CACF,EAIG,CACD,GAAM,CAAE,QAAAgB,CAAQ,EAAIC,EAAwBjB,EAAe,IAAI,OAAO,EAChEkB,EAAY,MAAMF,EAAQ,UAAU,KAAK,EAEzCG,EAAa,CACjB,QAAS,OACT,SAAU,OACV,OAAQ,GACR,MAAO,CAAE,KAAM,OAAQ,KAAM,MAAgB,EAC7C,cAAeD,EAAU,IAAKE,GAC5BxB,EAAC,OACC,SAAAA,EAACe,EAAA,CAAK,KAAMU,EAAmBtB,EAAU,WAAYqB,EAAS,EAAE,EAAI,SAAAA,EAAS,KAAK,GAD1EA,EAAS,EAEnB,CACD,CACH,EAEME,EAAe,CACnB,QAAS,GACT,SAAU,GACV,OAAQ,GACR,MAAO,CAAE,KAAM,UAAW,KAAM,MAAgB,EAChD,cAAeJ,EAAU,IAAKE,GAC5BxB,EAAC,OACC,SAAAA,EAAC2B,EAAA,CAAqB,WAAYH,EAAS,GAAI,aAAcA,EAAS,KAAM,GADpEA,EAAS,EAEnB,CACD,CACH,EAEA,OACExB,EAAC4B,EAAA,CACC,QAAST,EAAiB,CAACI,EAAYG,CAAY,EAAI,CAACH,CAAU,EAClE,KAAMD,EACR,CAEJ,CE7HA,OAAS,UAAAO,EAAQ,QAAAC,MAAY,iBAC7B,OACE,mBAAAC,EACA,yBAAAC,OAEK,wCACP,OAAS,YAAAC,MAAgB,QCJzB,SAASC,EAAeC,EAAqB,CAC3C,GAAM,CAAE,MAAAC,EAAO,KAAAC,CAAK,EAAIF,EACxB,GAAI,OAAOC,GAAU,SACnB,OAAOA,EAET,GAAIA,GAAS,OAAOA,GAAU,UAC5B,QAAWE,KAAS,OAAO,OAAOF,CAAK,EACrC,GAAI,OAAOE,GAAU,SACnB,OAAOA,EAIb,OAAOD,CACT,CAGO,SAASE,EACdC,EACoC,CACpC,IAAMC,EAAMD,EAAO,aACnB,GAAIC,IAAQ,IAASA,IAAQ,OAC3B,MAAO,CAAC,EAEV,IAAMC,EAAUD,EAAI,QACpB,OAAKC,GAAS,OAGPA,EAAQ,IAAKC,IAAqB,CACvC,MAAOT,EAAeS,CAAO,EAC7B,MAAOA,EAAQ,IACjB,EAAE,EALO,CAAC,CAMZ,CDHQ,OA2BJ,YAAAC,GA3BI,OAAAC,EA+BE,QAAAC,MA/BF,oBARO,SAARC,EAA+B,CACpC,eAAAC,EACA,OAAAC,EACA,aAAAC,CACF,EAA2B,CACzB,OACEL,EAACM,EAAA,CAAmB,eAAgBH,EAAgB,OAAQC,EAAQ,aAAcC,EAChF,SAAAL,EAACO,EAAA,CACC,SAAAP,EAACQ,GAAA,CAAkB,eAAgBL,EAAgB,EACrD,EACF,CAEJ,CAEA,SAASK,GAAkB,CACzB,eAAAL,CACF,EAEG,CACD,IAAMM,EAAcC,EAA2BP,EAAe,IAAI,OAAO,EACzE,GAAI,CAACM,EACH,OACET,EAAC,KAAE,KAAK,QAAQ,mFAAuE,EAI3F,IAAMW,EAAYC,EAA4BH,EAAY,WAAW,EACrE,GAAI,CAACE,EAAU,WAAW,KACxB,OAAOX,EAAC,KAAE,KAAK,QAAQ,0DAA8C,EAGvE,GAAM,CAAE,QAAAa,CAAQ,EAAIC,EAAwBX,EAAe,IAAI,OAAO,EAChEY,EAAgBF,EAAQ,MAAM,WAEpC,OACEZ,EAAAF,GAAA,CACE,UAAAE,EAAC,UAAO,UAAU,sBAChB,UAAAD,EAAC,MAAG,qBAAS,EACZe,EACCd,EAACe,EAAA,CAAK,KAAMD,EAAe,IAAI,sBAAsB,OAAO,SAAS,+BAChDF,EAAQ,OAC7B,EACE,MACN,EAEAZ,EAAC,OAAI,UAAU,2BACZ,UAAAU,EAAU,WAAW,MACpBX,EAAC,OACC,SAAAA,EAACiB,EAAA,CAAS,SAAUjB,EAAC,OAAI,YAAS,GAAC,MAAO,CAAE,UAAW,QAAS,EAAG,EACjE,SAAAA,EAACkB,GAAA,CAAsB,eAAgBf,EAAgB,EACzD,EACF,EACE,KACJH,EAACiB,EAAA,CAAS,SAAUjB,EAAC,OAAI,YAAS,GAAC,MAAO,CAAE,UAAW,MAAO,EAAG,EAC/D,SAAAA,EAACmB,GAAA,CAAqB,eAAgBhB,EAAgB,EACxD,GACF,GACF,CAEJ,CAEA,eAAee,GAAsB,CACnC,eAAAf,CACF,EAEG,CACD,IAAMM,EAAcK,EAAwBX,EAAe,IAAI,OAAO,EAChE,CAAE,QAAAU,CAAQ,EAAIJ,EACdW,EAAY,MAAMP,EAAQ,UAAU,KAAK,EACzCQ,EACJZ,EAAY,yBAAyB,IAAI,CAAC,CAAE,GAAAa,EAAI,KAAAC,CAAK,KAAO,CAAE,GAAAD,EAAI,KAAAC,CAAK,EAAE,GAAK,CAAC,EAC3EC,EAAgBC,EAAiCtB,EAAe,IAAI,QAAQ,MAAM,EACxF,OACEH,EAAC0B,GAAA,CACC,UAAWN,EACX,wBAAyBC,EACzB,cAAeG,EACf,SAAUX,EAAQ,SACpB,CAEJ,CAEA,eAAeM,GAAqB,CAClC,eAAAhB,CACF,EAEG,CACD,GAAM,CAAE,QAAAU,CAAQ,EAAIC,EAAwBX,EAAe,IAAI,OAAO,EAEhEwB,GADO,MAAMd,EAAQ,WAAW,KAAK,GACM,IAAKe,IAAO,CAC3D,GAAGA,EACH,qBAAsBf,EAAQ,MAAM,YAAYe,EAAE,EAAE,CACtD,EAAE,EAEF,OAAO5B,EAAC6B,EAAA,CAAgB,WAAYF,EAAY,CAClD","names":["Gutter","Link","notFound","AudienceContactsTable","EditContactButton","Suspense","MARKETING_CUSTOM_CONFIG_KEY","effectiveResource","slice","resolveMarketingPermissions","permissions","readIntegration","payload","custom","slice","MARKETING_CUSTOM_CONFIG_KEY","getMarketingIntegration","state","tryGetMarketingIntegration","DefaultTemplate","jsx","MarketingViewShell","children","initPageResult","params","searchParams","firstString","value","marketingAudienceIdFromParams","params","fromId","segmentsRaw","segmentList","s","audienceIdx","last","Fragment","jsx","jsxs","AudienceDetail","initPageResult","params","searchParams","audienceId","marketingAudienceIdFromParams","MarketingViewShell","Gutter","AudienceDetailBody","integration","tryGetMarketingIntegration","effective","resolveMarketingPermissions","adapter","getMarketingIntegration","audience","notFound","audienceDashboardUrl","Link","EditContactButton","Suspense","DetailContacts","contacts","AudienceContactsTable","Gutter","Link","Table","CreateAudienceButton","DeleteAudienceButton","Suspense","joinAdminSegments","adminRoute","segments","trimmedAdmin","body","segment","marketingAdminHref","basePath","parts","Fragment","jsx","jsxs","AudienceList","basePath","initPageResult","params","searchParams","MarketingViewShell","Gutter","AudienceListBody","integration","tryGetMarketingIntegration","effective","resolveMarketingPermissions","audiencesUrl","Link","CreateAudienceButton","Suspense","AudienceTableRows","audiencesWrite","adapter","getMarketingIntegration","audiences","nameColumn","audience","marketingAdminHref","deleteColumn","DeleteAudienceButton","Table","Gutter","Link","BroadcastsTable","CreateBroadcastButton","Suspense","labelForLocale","loc","label","code","value","getLocaleSelectOptionsFromConfig","config","raw","locales","locItem","Fragment","jsx","jsxs","BroadcastList","initPageResult","params","searchParams","MarketingViewShell","Gutter","BroadcastListBody","integration","tryGetMarketingIntegration","effective","resolveMarketingPermissions","adapter","getMarketingIntegration","broadcastsUrl","Link","Suspense","CreateBroadcastRegion","BroadcastTableRegion","audiences","emailBroadcastTemplates","id","name","localeOptions","getLocaleSelectOptionsFromConfig","CreateBroadcastButton","broadcasts","b","BroadcastsTable"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-marketing-api.d.ts","sourceRoot":"","sources":["../../src/admin/use-marketing-api.ts"],"names":[],"mappings":"AAKA,wBAAgB,eAAe;;+BAYP,MAAM,SAAS,WAAW,KAAG,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"use-marketing-api.d.ts","sourceRoot":"","sources":["../../src/admin/use-marketing-api.ts"],"names":[],"mappings":"AAKA,wBAAgB,eAAe;;+BAYP,MAAM,SAAS,WAAW,KAAG,OAAO,CAAC,OAAO,CAAC;EAwCpE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
function d(e,n){if(!n)return e;let{overrides:t,...i}=n;return{...e,...i,...t??{},admin:{..."admin"in e?e.admin:void 0,...i.admin??{},...t?.admin??{}}}}function y(e){return{type:"row",fields:e}}function I(e,n,t){let i=t?.fields??{};return{...{slug:e,labels:t?.labels??n,fields:[y([d({name:"name",type:"text",label:"Name (lowercase, no special characters)",required:!0,admin:{width:"50%"}},i.name),d({name:"label",type:"text",label:"Label",localized:!0,admin:{width:"50%"}},i.label)]),y([d({name:"width",type:"number",label:"Field Width (percentage)",admin:{width:"20%"}},i.width),d({name:"placeholder",type:"text",label:"Placeholder",localized:!0,admin:{width:"40%"}},i.placeholder),d({name:"defaultValue",type:"text",label:"Default Value",localized:!0,admin:{width:"40%"}},i.defaultValue)]),d({name:"required",type:"checkbox",label:"Required"},i.required)]},...t?.overrides??{}}}function R(e){let n=e?.fields??{};return{...{slug:"acceptance",labels:e?.labels??{singular:"Acceptance",plural:"Acceptances"},fields:[y([d({name:"name",type:"text",label:"Name (lowercase, no special characters)",required:!0,admin:{width:"50%"}},n.name),d({name:"label",type:"richText",label:"Label",localized:!0,admin:{width:"50%"}},n.label)]),y([d({name:"width",type:"number",label:"Field Width (percentage)",admin:{width:"50%"}},n.width),d({name:"required",type:"checkbox",label:"Required"},n.required)])]},...e?.overrides??{}}}function k(e={}){return{url:I("url",{singular:"URL",plural:"URLs"},e.url||void 0),phone:I("phone",{singular:"Phone",plural:"Phones"},e.phone||void 0),acceptance:R(e.acceptance||void 0)}}var h="__website",w="__startedAt",H=1500,T={acceptance:5,checkbox:5,country:200,date:100,email:320,message:5e3,number:64,payment:1e3,phone:50,select:200,state:200,text:200,textarea:5e3,upload:1e3,url:2048};function U(e){return e===h||e===w}function z(e){let n=e.find(i=>i.field===h)?.value,t=e.find(i=>i.field===w)?.value;return{honeypot:typeof n=="string"?n:"",startedAt:typeof t=="string"||typeof t=="number"?String(t):""}}function D(e){return typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e)?String(e):typeof e=="string"?e.trim():""}function j(e,n){if(!n)return!e.required;if(n.length>(T[e.blockType]??1e3))return!1;if(e.blockType==="email")return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n);if(e.blockType==="url")try{return new URL(n),!0}catch{return!1}return e.blockType==="number"?Number.isFinite(Number(n)):e.blockType==="checkbox"||e.blockType==="acceptance"?n==="true"||n==="false":e.blockType==="select"&&e.options?.length?e.options.some(t=>t.value===n):!0}function $(e,n){return e.required?e.blockType==="acceptance"?n==="true":!!n:!0}function S(e){let n=z(e.submissionData??[]);if(n.honeypot.trim())return{ok:!1,error:"Invalid submission."};let t=Number(n.startedAt);if(!Number.isFinite(t))return{ok:!1,error:"Invalid submission."};if(e.now-t<1500)return{ok:!1,error:"Form submitted too quickly."};let i=e.formFields.flatMap(a=>a.name&&a.blockType in T?[{...a,name:a.name}]:[]),r=new Map(i.map(a=>[a.name,a])),s=[],l=new Set;for(let a of e.submissionData??[]){let o=a.field?.trim();if(!o||U(o))continue;if(l.has(o))return{ok:!1,error:`Field "${o}" was submitted more than once.`};l.add(o);let c=r.get(o);if(!c)return{ok:!1,error:`Unexpected field "${o}".`};let u=D(a.value);if(!j(c,u))return{ok:!1,error:`Field "${o}" is invalid.`};s.push({field:o,value:u})}for(let a of i){let o=s.find(c=>c.field===a.name)?.value;if(!$(a,o))return{ok:!1,error:`Field "${a.name}" is required.`}}return{ok:!0,data:s}}function B(e){return Object.fromEntries(e.flatMap(n=>n.field?[[n.field,D(n.value)]]:[]))}function N(e,n){return e.replace(/\{\{\s*([\w.-]+)\s*\}\}/g,(t,i)=>n[i]??"")}function M(e,n){return(e??"").split(",").map(t=>N(t,n).trim()).filter(Boolean)}function x(e,n){let t=e.submissionData?.find(i=>i.field===n)?.value;if(typeof t=="string")return t;if(t!=null&&(typeof t=="number"&&Number.isFinite(t)||typeof t=="boolean"))return String(t)}async function P(e,n,t="forms"){return typeof e.form=="string"?await n.payload.findByID({collection:t,depth:0,id:e.form,overrideAccess:!0}):e.form}function C(e={}){return async({data:n,operation:t,req:i})=>{if(t!=="create")return n;let r=await P(n,i,e.formsSlug),s=S({formFields:r?.fields??[],now:Date.now(),submissionData:n?.submissionData??[]});if(!s.ok)throw new Error(s.error);return n.submissionData=s.data,n}}function O(e,n={}){return async({data:t,operation:i,req:r})=>{if(i!=="create")return t;let l=await P(t,r,n.formsSlug);if(l?.event!=="lead"||!l.audienceId)return t;let a=t,o=x(a,"email");if(!o)return t;let c=B(a.submissionData??[]),u=M(l.tags,c);return await e.contacts.upsert({audienceId:l.audienceId,email:o,firstName:x(a,"firstName"),lastName:x(a,"lastName"),properties:u.length>0?{tags:u.join(",")}:void 0,subscribed:!0}),t}}var W=new Set(["acceptance","checkbox","message","payment","upload"]);function p(e){return{type:"row",fields:e}}function m(e){return typeof e=="object"&&e!==null&&"type"in e&&e.type==="row"&&"fields"in e&&Array.isArray(e.fields)}function G(e){let n=new Map;function t(i){for(let r of i)"name"in r&&typeof r.name=="string"&&n.set(r.name,r),m(r)&&t(r.fields)}return t(e),n}function _(e,n){let t="admin"in e&&e.admin&&typeof e.admin=="object"?e.admin:{};return{...e,admin:{...t,width:n}}}function g(e,n){let t={name:"width",type:"number",label:"Field Width (percentage)",admin:{width:"20%"}},i=n?d(t,n):t;return i=d(i,e?.fields?.width),_(i,"20%")}function F(e,n){let t=e.get("placeholder"),i={name:"placeholder",type:"text",label:"Placeholder",localized:!0,admin:{width:"40%"}},r=t?d(i,t):i;return r=d(r,n?.fields?.placeholder),_(r,"40%")}function b(e,n,t){let i={...t,admin:{..."admin"in t&&t.admin&&typeof t.admin=="object"?t.admin:{},width:"40%"}},r=n?d(i,n):i;return r=d(r,e?.fields?.defaultValue),_(r,"40%")}function v(e,n){let t=e.slug;if(!t||W.has(t))return e;let i=[...e.fields],r=G(i);if(t==="text"||t==="textarea"||t==="radio"){let s=i[1];if(!m(s))return e;let l=p([g(n,r.get("width")),F(r,n),b(n,r.get("defaultValue"),{name:"defaultValue",type:"text",label:"Default Value",localized:!0})]);return{...e,fields:[i[0],l,...i.slice(2)]}}if(t==="number"){let s=i[1];if(!m(s))return e;let l=p([g(n,r.get("width")),F(r,n),b(n,r.get("defaultValue"),{name:"defaultValue",type:"number",label:"Default Value"})]);return{...e,fields:[i[0],l,...i.slice(2)]}}if(t==="select"){let s=i[1],l=i[2];if(!m(s))return e;let a=m(l)&&l.fields.length===1&&"name"in l.fields[0]&&l.fields[0].name==="placeholder",o=p([g(n,r.get("width")),F(r,n),b(n,r.get("defaultValue"),{name:"defaultValue",type:"text",label:"Default Value",localized:!0})]),c=a?3:2;return{...e,fields:[i[0],o,...i.slice(c)]}}if(t==="email"||t==="state"||t==="country"){let s=i[0],l=i[1],a=i.slice(2);if(!m(s)||!l||!("name"in l)||l.name!=="width")return e;let o=p([g(n,r.get("width")),F(r,n),b(n,r.get("defaultValue"),{name:"defaultValue",type:"text",label:"Default Value",localized:!0})]);return{...e,fields:[s,o,...a]}}if(t==="date"){let s=i[0],l=i[1],a=i[2];if(!m(s)||!m(l)||!a||!("name"in a)||a.name!=="defaultValue")return e;let o=l.fields.find(u=>"name"in u&&u.name==="required");if(!o)return e;let c=p([g(n,r.get("width")),F(r,n),b(n,r.get("defaultValue"),{name:"defaultValue",type:"date",label:"Default Value"})]);return{...e,fields:[s,c,o]}}return e}function V(e,n){return"name"in e&&e.name===n}function E(e){return!!(e&&typeof e=="object"&&"slug"in e&&typeof e.slug=="string")}function L(e){return!!(e&&typeof e=="object")}function K(e,n){return!("name"in n)||!n.name?[...e,n]:e.some(t=>V(t,n.name))?e.map(t=>V(t,n.name)?n:t):[...e,n]}function Y(e){let n=e.admin?.components?.audienceSelect??{path:"payload-plugin-marketing/admin",exportName:"AudienceSelect"};return[{name:"event",type:"select",defaultValue:"submission",options:[{label:"Submission",value:"submission"},{label:"Lead",value:"lead"}]},{name:"audienceId",type:"text",label:"Audience ID",required:!1,admin:{condition:(t,i)=>i?.event==="lead",components:{Field:n}},validate:(t,{siblingData:i}={})=>i?.event==="lead"&&!t?"Audience is required for lead forms.":!0},{name:"tags",type:"textarea",label:"Tags",admin:{condition:(t,i)=>i?.event==="lead",description:"Optional comma-separated tags. Use {{fieldName}} to insert submitted values."}}]}function X(e,n){let t=[...e.fields],i=t.findIndex(u=>V(u,"fields")&&u.type==="blocks");if(i<0){if(n.formBuilder?.strict===!1)return e;throw new Error(`Could not find a blocks field named "fields" on form-builder forms collection "${e.slug}".`)}let r=t[i],s=Array.isArray(r.blocks)?r.blocks:[],l=n.formBuilder?.fields??{},a=s.map(u=>{if(!E(u)||!L(u))return u;let f=l[u.slug],q=f&&L(f)?{...u,...f.overrides??{},...f.labels?{labels:f.labels}:{}}:u;return v(q,f)}),o=new Set(a.flatMap(u=>E(u)?[u.slug]:[])),c=Object.values(k(n.formBuilder?.fields)).filter(u=>!o.has(u.slug));t[i]={...r,blocks:[...a,...c]};for(let u of Y(n))t.splice(0,t.length,...K(t,u));return{...e,fields:t}}function J(e,n){let t=e.hooks??{};return{...e,hooks:{...t,beforeChange:[...t.beforeChange??[],C({formsSlug:n.formBuilder?.formsSlug}),O(n.adapter,{formsSlug:n.formBuilder?.formsSlug})]}}}function A(e,n){let t=n.formBuilder?.formsSlug??"forms",i=n.formBuilder?.submissionsSlug??"form-submissions",r=n.formBuilder?.strict??!0,s=e??[],l=s.some(o=>o.slug===t),a=s.some(o=>o.slug===i);if(r&&!l)throw new Error(`Could not find form-builder forms collection "${t}".`);if(r&&!a)throw new Error(`Could not find form-builder submissions collection "${i}".`);return s.map(o=>o.slug===t?X(o,n):o.slug===i?J(o,n):o)}export{R as a,k as b,h as c,w as d,H as e,S as f,B as g,N as h,M as i,C as j,O as k,A as l};
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
2
|
+
//# sourceMappingURL=chunk-G6DIJ7B2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 (\n !isRowField(row0) ||\n !maybeWidth ||\n !(\"name\" in maybeWidth) ||\n maybeWidth.name !== \"width\"\n ) {\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 { createCreateLeadHook, createValidateFormSubmissionHook } from \"./hooks\"\nimport { normalizeFormBuilderPlaceholderRow } from \"./normalize-placeholder-rows\"\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"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { MarketingEmailBroadcastTemplate, MarketingEmailTemplateProps } from "./types";
|
|
3
|
+
import type { ComponentType } from "react";
|
|
4
|
+
/**
|
|
5
|
+
* Splits `path` into a dynamic-import specifier and optional named export using a `#` suffix,
|
|
6
|
+
* e.g. `"@/emails/digest#DigestEmail"`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseEmailBroadcastTemplatePath(path: string): {
|
|
9
|
+
importPath: string;
|
|
10
|
+
namedExport?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function validateEmailBroadcastTemplates(templates: MarketingEmailBroadcastTemplate[]): void;
|
|
13
|
+
export declare function resolveEmailBroadcastTemplateComponent(definition: MarketingEmailBroadcastTemplate): Promise<ComponentType<MarketingEmailTemplateProps>>;
|
|
14
|
+
export declare function createEmailBroadcastReactElement(Component: ComponentType<MarketingEmailTemplateProps>, props: MarketingEmailTemplateProps): React.ReactElement;
|
|
15
|
+
//# sourceMappingURL=email-broadcast-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-broadcast-template.d.ts","sourceRoot":"","sources":["../src/email-broadcast-template.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,KAAK,EAAE,+BAA+B,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAA;AAC3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAI1C;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,GAAG;IAC7D,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAiBA;AAED,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,+BAA+B,EAAE,GAC3C,IAAI,CAiCN;AAED,wBAAsB,sCAAsC,CAC1D,UAAU,EAAE,+BAA+B,GAC1C,OAAO,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAC,CA+BrD;AAED,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,aAAa,CAAC,2BAA2B,CAAC,EACrD,KAAK,EAAE,2BAA2B,GACjC,KAAK,CAAC,YAAY,CAEpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketing-endpoints.d.ts","sourceRoot":"","sources":["../../src/endpoints/marketing-endpoints.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"marketing-endpoints.d.ts","sourceRoot":"","sources":["../../src/endpoints/marketing-endpoints.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,SAAS,CAAA;AA8CvD,wBAAgB,wBAAwB,IAAI,QAAQ,EAAE,CAuVrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/form-builder/index.ts","../../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":["export { createAcceptanceBlock, createMarketingFormFields } from \"./fields\"\nexport { createCreateLeadHook, createValidateFormSubmissionHook } from \"./hooks\"\nexport { extendFormBuilderCollections } from \"./mutate\"\nexport { mutateFormBuilderCollections } from \"./mutate-collections\"\nexport {\n FORM_HONEYPOT_FIELD,\n FORM_STARTED_AT_FIELD,\n MIN_SUBMISSION_TIME_MS,\n resolveCommaSeparatedSubmissionTags,\n submissionDataToPlainRecord,\n substituteSubmissionPlaceholders,\n validateSubmissionInput,\n type SubmissionValidationResult,\n type ValidationFormField,\n type ValidationSubmissionField,\n} from \"./submission\"\n","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":["form_builder_exports","__export","FORM_HONEYPOT_FIELD","FORM_STARTED_AT_FIELD","MIN_SUBMISSION_TIME_MS","createAcceptanceBlock","createCreateLeadHook","createMarketingFormFields","createValidateFormSubmissionHook","mutateFormBuilderCollections","resolveCommaSeparatedSubmissionTags","submissionDataToPlainRecord","substituteSubmissionPlaceholders","validateSubmissionInput","__toCommonJS","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
|
+
{"version":3,"sources":["../../src/form-builder/index.ts","../../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":["export { createAcceptanceBlock, createMarketingFormFields } from \"./fields\"\nexport { createCreateLeadHook, createValidateFormSubmissionHook } from \"./hooks\"\nexport { extendFormBuilderCollections } from \"./mutate\"\nexport { mutateFormBuilderCollections } from \"./mutate-collections\"\nexport {\n FORM_HONEYPOT_FIELD,\n FORM_STARTED_AT_FIELD,\n MIN_SUBMISSION_TIME_MS,\n resolveCommaSeparatedSubmissionTags,\n submissionDataToPlainRecord,\n substituteSubmissionPlaceholders,\n validateSubmissionInput,\n type SubmissionValidationResult,\n type ValidationFormField,\n type ValidationSubmissionField,\n} from \"./submission\"\n","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 (\n !isRowField(row0) ||\n !maybeWidth ||\n !(\"name\" in maybeWidth) ||\n maybeWidth.name !== \"width\"\n ) {\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 { createCreateLeadHook, createValidateFormSubmissionHook } from \"./hooks\"\nimport { normalizeFormBuilderPlaceholderRow } from \"./normalize-placeholder-rows\"\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":["form_builder_exports","__export","FORM_HONEYPOT_FIELD","FORM_STARTED_AT_FIELD","MIN_SUBMISSION_TIME_MS","createAcceptanceBlock","createCreateLeadHook","createMarketingFormFields","createValidateFormSubmissionHook","mutateFormBuilderCollections","resolveCommaSeparatedSubmissionTags","submissionDataToPlainRecord","substituteSubmissionPlaceholders","validateSubmissionInput","__toCommonJS","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 +1,2 @@
|
|
|
1
|
-
import{a,b,c,d,e,f,g,h,i,j,k,l}from"../chunk-
|
|
1
|
+
import{a,b,c,d,e,f,g,h,i,j,k,l}from"../chunk-G6DIJ7B2.js";export{c as FORM_HONEYPOT_FIELD,d as FORM_STARTED_AT_FIELD,e as MIN_SUBMISSION_TIME_MS,a as createAcceptanceBlock,k as createCreateLeadHook,b as createMarketingFormFields,j as createValidateFormSubmissionHook,l as extendFormBuilderCollections,l as mutateFormBuilderCollections,i as resolveCommaSeparatedSubmissionTags,g as submissionDataToPlainRecord,h as substituteSubmissionPlaceholders,f as validateSubmissionInput};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize-placeholder-rows.d.ts","sourceRoot":"","sources":["../../src/form-builder/normalize-placeholder-rows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,qBAAqB,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,KAAK,EAAE,KAAK,EAAS,MAAM,SAAS,CAAA;AAgG3C,6EAA6E;AAC7E,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,KAAK,EACZ,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,KAAK,
|
|
1
|
+
{"version":3,"file":"normalize-placeholder-rows.d.ts","sourceRoot":"","sources":["../../src/form-builder/normalize-placeholder-rows.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,qBAAqB,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,KAAK,EAAE,KAAK,EAAS,MAAM,SAAS,CAAA;AAgG3C,6EAA6E;AAC7E,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,KAAK,EACZ,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,KAAK,CA4HP"}
|