@10x-media/form-builder 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["isRecord","optionLabelsFor"],"sources":["../src/actions/defineAction.ts","../src/actions/builtin/confirmation.ts","../src/actions/builtin/emailTeam.ts","../src/actions/sign.ts","../src/actions/builtin/signedWebhook.ts","../src/actions/builtin/index.ts","../src/actions/registry.ts","../src/collections/uploads.ts","../src/consent/defineConsentSource.ts","../src/consent/resolvePublishedVersionRef.ts","../src/consent/builtin/pageReference.ts","../src/consent/builtin/static.ts","../src/consent/builtin/index.ts","../src/consent/registry.ts","../src/actions/dispatch.ts","../src/events/resolveEventSink.ts","../src/spam/reserved.ts","../src/spam/spamGuard.ts","../src/actions/buildActionBlocks.ts","../src/aggregation/aggregateRows.ts","../src/aggregation/aggregateResponses.ts","../src/aggregation/resolveResultsRequest.ts","../src/calc/normalizeCalc.ts","../src/conditions/conditionType.ts","../src/conditions/normalizeConditions.ts","../src/validation/buildRuleBlocks.ts","../src/fields/sharedConfig.ts","../src/fields/buildFieldBlocks.ts","../src/flow/normalizeFlow.ts","../src/collections/forms.ts","../src/consent/resolveConsentLinks.ts","../src/consent/captureConsent.ts","../src/uploads/resolveFileRef.ts","../src/uploads/captureFileRef.ts","../src/submissions/runSubmission.ts","../src/submissions/validateSubmission.ts","../src/collections/formSubmissions.ts","../src/actions/runActions.ts","../src/actions/task.ts","../src/spam/uploadHooks.ts","../src/plugin/registerCollections.ts","../src/plugin/registerTranslations.ts","../src/presentations/registry.ts","../src/spam/identify.ts","../src/spam/rateLimiter.ts","../src/spam/resolveSpam.ts","../src/spam/captcha.ts","../src/index.ts"],"sourcesContent":["import type { Field, Payload, PayloadRequest } from 'payload'\nimport type { Translate } from '../fields/types'\nimport type { SubmissionDescriptor, SubmissionValue } from '../submissions/types'\n\n/** Context passed to an action's `run` when a submission completes. */\nexport type ActionRunArgs<TConfig extends Record<string, unknown> = Record<string, unknown>> = {\n\tform: { id: number | string; title?: string }\n\tsubmissionId: number | string\n\tvalues: SubmissionValue[]\n\tdescriptors: SubmissionDescriptor[]\n\tconfig: TConfig\n\tpayload: Payload\n\treq?: PayloadRequest\n\tlocale: string\n\tt: Translate\n}\n\n/**\n * A post-submit action type, authored once: `config` is the admin `Field[]` for authoring;\n * `run` executes when a submission completes. Built-ins use this same primitive.\n */\nexport type ActionDefinition<TConfig extends Record<string, unknown> = Record<string, unknown>> = {\n\ttype: string\n\tlabel: string\n\tconfig?: Field[]\n\trun: (args: ActionRunArgs<TConfig>) => Promise<void> | void\n}\n\n/** Erased shape stored in the registry; config re-narrows per matched type at execution. */\nexport type AnyActionDefinition = ActionDefinition<Record<string, unknown>>\n\nexport const defineAction = <TConfig extends Record<string, unknown> = Record<string, unknown>>(\n\tdefinition: ActionDefinition<TConfig>\n): ActionDefinition<TConfig> => definition\n","import { interpolate } from '../../recall/interpolate'\nimport { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineAction } from '../defineAction'\n\ntype ConfirmationConfig = { toField?: string; subject?: string; body?: string }\n\nexport const confirmation = defineAction<ConfirmationConfig>({\n\ttype: 'confirmation',\n\tlabel: keys.actionConfirmation,\n\tconfig: [\n\t\t{ name: 'toField', type: 'text', label: labelFor(keys.actionConfigToField) },\n\t\t{ name: 'subject', type: 'text', label: labelFor(keys.actionConfigSubject) },\n\t\t{ name: 'body', type: 'textarea', label: labelFor(keys.actionConfigBody) },\n\t],\n\trun: async (args) => {\n\t\tconst { config, values, payload } = args\n\n\t\tif (!config.toField) {\n\t\t\treturn\n\t\t}\n\n\t\tconst entry = values.find((v) => v.field === config.toField)\n\t\tconst to = entry == null ? '' : String(entry.value ?? '')\n\n\t\tif (!to) {\n\t\t\treturn\n\t\t}\n\n\t\tif (typeof payload.sendEmail !== 'function') {\n\t\t\tthrow new Error('confirmation: no email adapter configured')\n\t\t}\n\n\t\tconst resolve = (name: string) => {\n\t\t\tconst found = values.find((v) => v.field === name)\n\t\t\treturn found == null ? '' : String(found.value ?? '')\n\t\t}\n\n\t\tconst subject = interpolate(config.subject ?? '', resolve)\n\t\tconst html = interpolate(config.body ?? '', resolve)\n\n\t\tawait payload.sendEmail({ to, subject, html })\n\t},\n})\n","import { interpolate } from '../../recall/interpolate'\nimport { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineAction } from '../defineAction'\n\ntype EmailTeamConfig = { to?: string; subject?: string; body?: string }\n\nexport const emailTeam = defineAction<EmailTeamConfig>({\n\ttype: 'emailTeam',\n\tlabel: keys.actionEmailTeam,\n\tconfig: [\n\t\t{ name: 'to', type: 'text', label: labelFor(keys.actionConfigTo) },\n\t\t{ name: 'subject', type: 'text', label: labelFor(keys.actionConfigSubject) },\n\t\t{ name: 'body', type: 'textarea', label: labelFor(keys.actionConfigBody) },\n\t],\n\trun: async (args) => {\n\t\tconst { config, values, payload } = args\n\n\t\tif (!config.to) {\n\t\t\tthrow new Error('emailTeam: missing \"to\" address')\n\t\t}\n\n\t\tif (typeof payload.sendEmail !== 'function') {\n\t\t\tthrow new Error('emailTeam: no email adapter configured')\n\t\t}\n\n\t\tconst resolve = (name: string) => {\n\t\t\tconst entry = values.find((v) => v.field === name)\n\t\t\treturn entry == null ? '' : String(entry.value ?? '')\n\t\t}\n\n\t\tconst subject = interpolate(config.subject ?? '', resolve)\n\t\tconst html = interpolate(config.body ?? '', resolve)\n\n\t\tawait payload.sendEmail({ to: config.to, subject, html })\n\t},\n})\n","import { createHmac } from 'node:crypto'\n\n// Distinct from @10x-media/webhooks' `X-Webhook-Signature` (which signs `timestamp.body`): this action signs the body alone, so a separate header prevents a consumer mistaking the two verification schemes.\nexport const SIGNATURE_HEADER = 'X-Form-Signature'\n\n/** HMAC-SHA256 over `body`, hex-encoded, wrapped in the versioned header value (`v1=<hex>`). */\nexport const signPayload = (body: string, secret: string): string =>\n\t`v1=${createHmac('sha256', secret).update(body).digest('hex')}`\n","import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineAction } from '../defineAction'\nimport { SIGNATURE_HEADER, signPayload } from '../sign'\n\ntype SignedWebhookConfig = { url?: string; secret?: string }\n\nexport const signedWebhook = defineAction<SignedWebhookConfig>({\n\ttype: 'signedWebhook',\n\tlabel: keys.actionSignedWebhook,\n\tconfig: [\n\t\t{ name: 'url', type: 'text', label: labelFor(keys.actionConfigUrl) },\n\t\t{ name: 'secret', type: 'text', label: labelFor(keys.actionConfigSecret) },\n\t],\n\trun: async (args) => {\n\t\tconst { config, form, submissionId, values } = args\n\n\t\tif (!config.url) {\n\t\t\tthrow new Error('signedWebhook: missing \"url\"')\n\t\t}\n\t\tif (!config.secret) {\n\t\t\tthrow new Error('signedWebhook: missing \"secret\"')\n\t\t}\n\n\t\tconst body = JSON.stringify({ formId: form.id, submissionId, values })\n\t\tconst controller = new AbortController()\n\t\tconst timer = setTimeout(() => controller.abort(), 10_000)\n\n\t\tlet response: Response\n\t\ttry {\n\t\t\tresponse = await fetch(config.url, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t[SIGNATURE_HEADER]: signPayload(body, config.secret),\n\t\t\t\t},\n\t\t\t\tbody,\n\t\t\t\tsignal: controller.signal,\n\t\t\t})\n\t\t} finally {\n\t\t\tclearTimeout(timer)\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`signedWebhook: server responded ${response.status}`)\n\t\t}\n\t},\n})\n","import type { AnyActionDefinition } from '../defineAction'\nimport { confirmation } from './confirmation'\nimport { emailTeam } from './emailTeam'\nimport { signedWebhook } from './signedWebhook'\n\nexport const defaultActionDefinitions: Record<string, AnyActionDefinition> = {\n\temailTeam: emailTeam as AnyActionDefinition,\n\tconfirmation: confirmation as AnyActionDefinition,\n\tsignedWebhook: signedWebhook as AnyActionDefinition,\n}\n","import type { AnyActionDefinition } from './defineAction'\n\nexport type ActionRegistry = Map<string, AnyActionDefinition>\n\n/** `false` removes a built-in, `true` keeps it, a definition adds or replaces one. */\nexport type ActionOption = boolean | AnyActionDefinition\n\nexport type ActionsConfig = Record<string, ActionOption>\n\n/**\n * Resolve the active action registry from built-in defaults and a consumer override map. `false`\n * removes a type, `true` keeps the default (no-op when none exists), a definition adds or replaces.\n * Mirrors the field-type and validation-rule registry convention.\n */\nexport const resolveActions = (\n\tdefaults: Record<string, AnyActionDefinition>,\n\tconfig: ActionsConfig = {}\n): ActionRegistry => {\n\tconst registry: ActionRegistry = new Map(Object.entries(defaults))\n\tfor (const [type, option] of Object.entries(config)) {\n\t\tif (option === false) {\n\t\t\tregistry.delete(type)\n\t\t} else if (option === true) {\n\t\t\t// keep the default; no-op when no default exists for this key\n\t\t} else {\n\t\t\tregistry.set(type, option)\n\t\t}\n\t}\n\treturn registry\n}\n","import type { CollectionConfig } from 'payload'\n\nexport const FORM_UPLOADS_SLUG = 'form-uploads'\n\n/** Override surface for the built-in upload collection. */\nexport type UploadsCollectionConfig = {\n\tslug?: string\n\t/** Merged onto the collection's `upload` config (e.g. `staticDir`, `mimeTypes`). `true` uses Payload defaults. */\n\tupload?: NonNullable<CollectionConfig['upload']> | true\n\t/** Replace access (defaults: anonymous create, authed read/update/delete). */\n\taccess?: CollectionConfig['access']\n\t/** Append extra fields. */\n\tfields?: CollectionConfig['fields']\n}\n\nexport type UploadsOption = boolean | UploadsCollectionConfig\n\n/**\n * The built-in upload collection backing the `file` field. Anonymous create (public forms upload here),\n * authed read/update/delete (only admins read stored files; submitters cannot enumerate others' uploads).\n * Per-field MIME/size is re-enforced at submit, so the collection stays permissive by default. No\n * `imageSizes`, so it needs no `sharp`. Projects with their own upload collection set `uploads: false` and\n * point the file field's `relationTo` at theirs.\n */\nexport const buildUploadsCollection = (config: UploadsCollectionConfig = {}): CollectionConfig => ({\n\tslug: config.slug ?? FORM_UPLOADS_SLUG,\n\taccess: config.access ?? {\n\t\tcreate: () => true,\n\t\tread: ({ req }) => Boolean(req.user),\n\t\tupdate: ({ req }) => Boolean(req.user),\n\t\tdelete: ({ req }) => Boolean(req.user),\n\t},\n\tadmin: { group: 'Forms' },\n\tupload: config.upload && config.upload !== true ? config.upload : true,\n\tfields: [\n\t\t{ name: 'owner', type: 'text', admin: { readOnly: true, hidden: true } },\n\t\t...(config.fields ?? []),\n\t],\n})\n\n/** Resolve the `uploads` plugin option: `false` disables, `true`/object enables the built-in collection. */\nexport const resolveUploads = (\n\toption: UploadsOption | undefined\n): { enabled: boolean; slug: string; collection?: CollectionConfig } => {\n\tif (option === false) {\n\t\treturn { enabled: false, slug: FORM_UPLOADS_SLUG }\n\t}\n\tconst config = option && option !== true ? option : {}\n\tconst collection = buildUploadsCollection(config)\n\treturn { enabled: true, slug: collection.slug, collection }\n}\n","import type { Field, Payload, PayloadRequest } from 'payload'\n\nexport type ConsentLink = { label: string; url: string }\nexport type ConsentResolved = { links: ConsentLink[]; versionRef?: string; versionLabel?: string }\n\nexport type ConsentResolveArgs<TConfig extends Record<string, unknown> = Record<string, unknown>> =\n\t{\n\t\tconfig: TConfig\n\t\tpayload: Payload\n\t\treq?: PayloadRequest\n\t\tlocale: string\n\t}\n\n/**\n * A consent source type, authored once: `config` is the admin `Field[]` for authoring;\n * `resolve` returns localized policy links and an optional version reference at capture time.\n * Built-ins use this same primitive.\n */\nexport type ConsentSource<TConfig extends Record<string, unknown> = Record<string, unknown>> = {\n\ttype: string\n\tlabel: string\n\tconfig?: Field[]\n\tresolve: (args: ConsentResolveArgs<TConfig>) => Promise<ConsentResolved> | ConsentResolved\n}\n\n/** Erased shape stored in the registry; config re-narrows per matched type at resolution. */\nexport type AnyConsentSource = ConsentSource<Record<string, unknown>>\n\nexport const defineConsentSource = <\n\tTConfig extends Record<string, unknown> = Record<string, unknown>,\n>(\n\tsource: ConsentSource<TConfig>\n): ConsentSource<TConfig> => source\n","import type { Payload } from 'payload'\n\n/**\n * Returns the latest published version of a doc, or null when versions/drafts are off or nothing\n * is published. Never throws.\n */\nexport const resolvePublishedVersionRef = async (\n\tpayload: Payload,\n\targs: { collection: string; id: string | number }\n): Promise<{ versionId: string; updatedAt: string } | null> => {\n\ttry {\n\t\tconst result = await payload.findVersions({\n\t\t\tcollection: args.collection as never,\n\t\t\twhere: {\n\t\t\t\tand: [{ parent: { equals: args.id } }, { 'version._status': { equals: 'published' } }],\n\t\t\t},\n\t\t\tsort: '-updatedAt',\n\t\t\tlimit: 1,\n\t\t\tdepth: 0,\n\t\t})\n\t\tconst doc = result?.docs?.[0]\n\t\tif (!doc) {\n\t\t\treturn null\n\t\t}\n\t\treturn { versionId: String(doc.id), updatedAt: String(doc.updatedAt) }\n\t} catch {\n\t\treturn null\n\t}\n}\n","import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineConsentSource } from '../defineConsentSource'\nimport { resolvePublishedVersionRef } from '../resolvePublishedVersionRef'\n\ntype PageReferenceConfig = {\n\trelationTo?: string\n\tdocId?: string\n\turlField?: string\n\tcaptureVersion?: boolean\n}\n\nexport const pageReferenceSource = defineConsentSource<PageReferenceConfig>({\n\ttype: 'pageReference',\n\tlabel: keys.consentSourcePageReference,\n\tconfig: [\n\t\t{ name: 'relationTo', type: 'text', label: labelFor(keys.consentConfigRelationTo) },\n\t\t{ name: 'docId', type: 'text', label: labelFor(keys.consentConfigDocId) },\n\t\t{\n\t\t\tname: 'urlField',\n\t\t\ttype: 'text',\n\t\t\tlabel: labelFor(keys.consentConfigUrlField),\n\t\t\tdefaultValue: 'slug',\n\t\t},\n\t\t{\n\t\t\tname: 'captureVersion',\n\t\t\ttype: 'checkbox',\n\t\t\tlabel: labelFor(keys.consentConfigCaptureVersion),\n\t\t},\n\t],\n\tresolve: async ({ config, payload, req, locale }) => {\n\t\tconst relationTo = String(config.relationTo ?? '')\n\t\tconst docId = String(config.docId ?? '')\n\t\tconst urlField = String(config.urlField ?? 'slug')\n\t\tconst captureVersion = Boolean(config.captureVersion)\n\n\t\tif (!relationTo || !docId) {\n\t\t\treturn { links: [] }\n\t\t}\n\n\t\tconst doc = await payload\n\t\t\t.findByID({\n\t\t\t\tcollection: relationTo as never,\n\t\t\t\tid: docId,\n\t\t\t\tdepth: 0,\n\t\t\t\tlocale: locale as never,\n\t\t\t\treq,\n\t\t\t})\n\t\t\t.catch(() => null)\n\n\t\tif (!doc) {\n\t\t\treturn { links: [{ label: relationTo, url: '' }] }\n\t\t}\n\n\t\tconst docRecord = doc as Record<string, unknown>\n\t\tconst label = String(docRecord.title ?? docRecord[urlField] ?? relationTo)\n\t\tconst url = String(docRecord[urlField] ?? '')\n\n\t\tif (!captureVersion) {\n\t\t\treturn { links: [{ label, url }] }\n\t\t}\n\n\t\tconst v = await resolvePublishedVersionRef(payload, { collection: relationTo, id: docId })\n\t\treturn {\n\t\t\tlinks: [{ label, url }],\n\t\t\t...(v ? { versionRef: v.versionId, versionLabel: v.updatedAt } : {}),\n\t\t}\n\t},\n})\n","import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineConsentSource } from '../defineConsentSource'\n\ntype StaticConfig = { label?: string; url?: string; version?: string }\n\nexport const staticSource = defineConsentSource<StaticConfig>({\n\ttype: 'static',\n\tlabel: keys.consentSourceStatic,\n\tconfig: [\n\t\t{ name: 'label', type: 'text', label: labelFor(keys.consentConfigLabel) },\n\t\t{ name: 'url', type: 'text', label: labelFor(keys.consentConfigUrl) },\n\t\t{ name: 'version', type: 'text', label: labelFor(keys.consentConfigVersion) },\n\t],\n\tresolve({ config }) {\n\t\tconst label = String(config.label ?? '')\n\t\tconst url = String(config.url ?? '')\n\t\tconst version = config.version ? String(config.version) : undefined\n\t\treturn {\n\t\t\tlinks: [{ label, url }],\n\t\t\t...(version ? { versionRef: version, versionLabel: version } : {}),\n\t\t}\n\t},\n})\n","import type { AnyConsentSource } from '../defineConsentSource'\nimport { pageReferenceSource } from './pageReference'\nimport { staticSource } from './static'\n\nexport const defaultConsentSources: Record<string, AnyConsentSource> = {\n\tstatic: staticSource as AnyConsentSource,\n\tpageReference: pageReferenceSource as AnyConsentSource,\n}\n","import type { AnyConsentSource } from './defineConsentSource'\n\nexport type ConsentSourceRegistry = Map<string, AnyConsentSource>\n\n/** `false` removes a built-in, `true` keeps it, a definition adds or replaces one. */\nexport type ConsentSourceOption = boolean | AnyConsentSource\n\nexport type ConsentSourcesConfig = Record<string, ConsentSourceOption>\n\n/**\n * Resolve the active consent-source registry from built-in defaults and a consumer override map.\n * `false` removes a type, `true` keeps the default (no-op when none exists), a definition adds or\n * replaces. Mirrors the action and field-type registry convention.\n */\nexport const resolveConsentSources = (\n\tdefaults: Record<string, AnyConsentSource>,\n\tconfig: ConsentSourcesConfig = {}\n): ConsentSourceRegistry => {\n\tconst registry: ConsentSourceRegistry = new Map(Object.entries(defaults))\n\tfor (const [type, option] of Object.entries(config)) {\n\t\tif (option === false) {\n\t\t\tregistry.delete(type)\n\t\t} else if (option === true) {\n\t\t\t// keep the default; no-op when no default exists for this key\n\t\t} else {\n\t\t\tregistry.set(type, option)\n\t\t}\n\t}\n\treturn registry\n}\n","import type { Payload, PayloadRequest } from 'payload'\nimport type { ActionRegistry } from './registry'\nimport type { ActionInstance } from './runActions'\nimport { ACTIONS_TASK_SLUG, type ActionsTaskInput, runActionsForSubmission } from './task'\n\n/** Default cap on inline action work so a missing worker never hangs the submission response. */\nexport const INLINE_DISPATCH_DEADLINE_MS = 5_000\n\nexport type DispatchActionsArgs = {\n\tactions: ActionInstance[] | null | undefined\n\tformId: number | string\n\tsubmissionId: number | string\n\tregistry: ActionRegistry\n\tpayload: Payload\n\treq?: PayloadRequest\n\t/** Whether a job runner is likely present (queued path); otherwise the bounded-inline fallback runs. */\n\thasRunner: boolean\n\tdeadlineMs?: number\n}\n\nconst canQueue = (payload: Payload): boolean => typeof payload.jobs?.queue === 'function'\n\nconst deadline = (ms: number): Promise<void> =>\n\tnew Promise((resolve) => {\n\t\tconst timer = setTimeout(resolve, ms)\n\t\ttimer.unref?.()\n\t})\n\n/**\n * Dispatch a submission's post-submit actions without throwing and without blocking the response on slow\n * action work. With no actions, returns immediately. When a job runner is present, enqueues the native\n * `form-builder-actions` task and returns (action work happens out of band). Otherwise runs the actions\n * inline but bounded by a deadline so a missing worker still delivers without hanging the request; any\n * error is swallowed (logged via `payload.logger`). Never rejects.\n */\nexport const dispatchActions = async (args: DispatchActionsArgs): Promise<void> => {\n\tconst { payload, registry, req, formId, submissionId } = args\n\tconst actions = args.actions ?? []\n\tif (actions.length === 0) {\n\t\treturn\n\t}\n\n\tif (args.hasRunner && canQueue(payload)) {\n\t\ttry {\n\t\t\tconst input: ActionsTaskInput = { formId, submissionId }\n\t\t\tawait payload.jobs.queue({ task: ACTIONS_TASK_SLUG, input, req })\n\t\t} catch (error) {\n\t\t\tpayload.logger?.error(\n\t\t\t\t`@10x-media/form-builder: failed to enqueue actions for submission ${String(submissionId)}: ${\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t}`\n\t\t\t)\n\t\t}\n\t\treturn\n\t}\n\n\tconst ms = args.deadlineMs ?? INLINE_DISPATCH_DEADLINE_MS\n\t// Guard the action arm itself (not just the race) so a rejection AFTER the deadline wins is never an unhandled rejection.\n\tconst work = runActionsForSubmission({\n\t\tinput: { formId, submissionId },\n\t\tregistry,\n\t\tpayload,\n\t\treq,\n\t}).catch((error) => {\n\t\tpayload.logger?.error(\n\t\t\t`@10x-media/form-builder: inline action dispatch for submission ${String(submissionId)} threw: ${\n\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t}`\n\t\t)\n\t})\n\tawait Promise.race([work, deadline(ms)])\n}\n","import { noopEventSink } from './noopSink'\nimport type { FormEventSink } from './types'\n\n/** Resolves the configured event sink, falling back to the no-op sink. Consumed by the submission pipeline in a later phase. */\nexport const resolveEventSink = (sink: FormEventSink | undefined): FormEventSink =>\n\tsink ?? noopEventSink\n","import type { SubmissionValue } from '../submissions/types'\nimport { CAPTCHA_TOKEN_KEY } from './constants'\n\nexport type ExtractedReserved = {\n\t/** Real field values with reserved entries removed. */\n\tcleaned: SubmissionValue[]\n\t/** The honeypot decoy value, if a honeypot field name was active and present. */\n\thoneypot?: unknown\n\t/** A captcha token carried by the client. */\n\tcaptchaToken?: string\n}\n\n/**\n * Split reserved entries (honeypot decoy, captcha token) out of the submitted `values`. The honeypot\n * rides a configurable, innocuous field name; the captcha token rides a fixed reserved key. Real field\n * values pass through unchanged. `runSubmission` would already ignore unknown field names, but stripping\n * here keeps them out of storage and out of the validation pass.\n */\nexport const extractReservedValues = (\n\tvalues: SubmissionValue[],\n\thoneypotField: string | null\n): ExtractedReserved => {\n\tconst cleaned: SubmissionValue[] = []\n\tconst result: ExtractedReserved = { cleaned }\n\tfor (const entry of values) {\n\t\tif (entry.field === CAPTCHA_TOKEN_KEY) {\n\t\t\tif (typeof entry.value === 'string') {\n\t\t\t\tresult.captchaToken = entry.value\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif (honeypotField !== null && entry.field === honeypotField) {\n\t\t\tresult.honeypot = entry.value\n\t\t\tcontinue\n\t\t}\n\t\tcleaned.push(entry)\n\t}\n\treturn result\n}\n\n/** A honeypot is tripped when the decoy carries any non-empty value (a real user never fills it). */\nexport const isHoneypotTripped = (value: unknown): boolean =>\n\tvalue != null && value !== '' && !(Array.isArray(value) && value.length === 0)\n","import { APIError, type CollectionBeforeValidateHook } from 'payload'\nimport type { SubmissionValue } from '../submissions/types'\nimport { keys } from '../translations/keys'\nimport { asTranslate } from '../translations/server'\nimport { IDENTITY_CONTEXT_KEY } from './constants'\nimport { extractReservedValues, isHoneypotTripped } from './reserved'\nimport type { ResolvedSpamConfig } from './types'\n\nconst firstHop = (req: { headers?: Headers }, header: string): string | undefined => {\n\tconst raw = req.headers?.get(header)\n\treturn raw ? (raw.split(',')[0]?.trim() ?? undefined) : undefined\n}\n\n/**\n * Submissions spam guard, prepended before `validateSubmission` in `beforeValidate` so it rejects before\n * the form load + field validation. On create it: resolves the request identity once (stashing it on\n * `req.context` for upload-ownership verification downstream); rate-limits per form + identity (429,\n * fail-open when identity is null); strips reserved `values` entries (honeypot, captcha token); rejects a\n * filled honeypot with a generic error; verifies a configured captcha; and writes a server-authoritative\n * `meta` (timestamp + spam signal, with opt-in ip/ua). App-level rate limiting is defense-in-depth that\n * complements edge/CDN/WAF limiting, not a DoS replacement.\n */\nexport const buildSpamGuard =\n\t(spam: ResolvedSpamConfig): CollectionBeforeValidateHook =>\n\tasync ({ data, operation, req }) => {\n\t\tif (operation !== 'create' || !data) {\n\t\t\treturn data\n\t\t}\n\t\tconst t = asTranslate(req.i18n.t)\n\t\t// Honeypot + captcha are anti-bot measures for the anonymous public path; an authenticated request\n\t\t// (admin panel, logged-in API client) is already gated by auth and never carries a decoy/token, so\n\t\t// checking it would falsely reject legitimate authed creates. Rate-limit + ownership still apply.\n\t\tconst authenticated = Boolean(req.user)\n\n\t\tconst identity = await spam.identify(req)\n\t\tif (identity != null) {\n\t\t\treq.context[IDENTITY_CONTEXT_KEY] = identity\n\t\t}\n\n\t\tif (spam.rateLimit !== false && identity != null) {\n\t\t\tconst formKey = data.form != null ? String(data.form) : 'unknown'\n\t\t\tconst { ok } = await spam.rateLimit.limiter.check({\n\t\t\t\tkey: `submissions:${formKey}:${identity}`,\n\t\t\t\tmax: spam.rateLimit.max,\n\t\t\t\twindow: spam.rateLimit.window,\n\t\t\t\treq,\n\t\t\t})\n\t\t\tif (!ok) {\n\t\t\t\tthrow new APIError(t(keys.spamRateLimited), 429)\n\t\t\t}\n\t\t}\n\n\t\tconst honeypotField = spam.honeypot === false ? null : spam.honeypot.fieldName\n\t\tconst values = (data.values as SubmissionValue[] | undefined) ?? []\n\t\tconst { cleaned, honeypot, captchaToken } = extractReservedValues(values, honeypotField)\n\t\tdata.values = cleaned\n\n\t\tif (!authenticated && honeypotField !== null && isHoneypotTripped(honeypot)) {\n\t\t\tthrow new APIError(t(keys.spamRejected), 400)\n\t\t}\n\n\t\tconst captchaChecked = Boolean(spam.captcha) && !authenticated\n\t\tif (spam.captcha && !authenticated) {\n\t\t\tconst passed =\n\t\t\t\ttypeof captchaToken === 'string' && captchaToken.length > 0\n\t\t\t\t\t? await spam.captcha.verify({ token: captchaToken, req }).catch(() => false)\n\t\t\t\t\t: false\n\t\t\tif (!passed) {\n\t\t\t\tthrow new APIError(t(keys.spamCaptchaFailed), 400)\n\t\t\t}\n\t\t}\n\n\t\tconst serverMeta: Record<string, unknown> = {\n\t\t\tat: new Date().toISOString(),\n\t\t\tspam: { captcha: captchaChecked ? 'passed' : 'skipped' },\n\t\t}\n\t\tif (spam.metadata.ip) {\n\t\t\tconst ip = firstHop(req, spam.ipHeader)\n\t\t\tif (ip) {\n\t\t\t\tserverMeta.ip = ip\n\t\t\t}\n\t\t}\n\t\tif (spam.metadata.ua) {\n\t\t\tconst ua = req.headers?.get('user-agent')\n\t\t\tif (ua) {\n\t\t\t\tserverMeta.ua = ua\n\t\t\t}\n\t\t}\n\t\t// Preserve an authenticated (trusted) caller's own `meta` keys, with server fields winning. Anonymous\n\t\t// `meta` is never trusted, so it is discarded.\n\t\tconst clientMeta =\n\t\t\tauthenticated && data.meta != null && typeof data.meta === 'object'\n\t\t\t\t? (data.meta as Record<string, unknown>)\n\t\t\t\t: {}\n\t\tdata.meta = { ...clientMeta, ...serverMeta }\n\n\t\treturn data\n\t}\n","import type { Block } from 'payload'\nimport { labelFor } from '../translations/server'\nimport type { ActionRegistry } from './registry'\n\n/** One authoring block per registered action type: the action's own config fields. */\nexport const buildActionBlocks = (registry: ActionRegistry): Block[] => {\n\tconst blocks: Block[] = []\n\tfor (const definition of registry.values()) {\n\t\tblocks.push({\n\t\t\tslug: definition.type,\n\t\t\tlabels: { singular: labelFor(definition.label), plural: labelFor(definition.label) },\n\t\t\tfields: definition.config ?? [],\n\t\t})\n\t}\n\treturn blocks\n}\n","import type { AggregationBucket, AggregationRow, FieldAggregation, FieldMeta } from './types'\n\nconst round1 = (n: number): number => Math.round(n * 10) / 10\n\n/** The grouping keys a single answer contributes: [] for empty, one per element for arrays, else one. */\nconst valueKeys = (value: unknown): string[] => {\n\tif (value == null || value === '') {\n\t\treturn []\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.filter((entry) => entry != null && entry !== '').map((entry) => String(entry))\n\t}\n\treturn [String(value)]\n}\n\n/** Merge every row's descriptor snapshot for one field into a value -> label map (last write wins). */\nconst snapshotLabels = (rows: AggregationRow[], field: string): Map<string, string> => {\n\tconst labels = new Map<string, string>()\n\tfor (const row of rows) {\n\t\tfor (const descriptor of row.descriptors ?? []) {\n\t\t\tif (descriptor.field === field && descriptor.optionLabels) {\n\t\t\t\tfor (const [value, label] of Object.entries(descriptor.optionLabels)) {\n\t\t\t\t\tlabels.set(value, label)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn labels\n}\n\n/** Aggregate one field across rows: respondent-denominated counts + percentages, option-ordered. */\nexport const aggregateRowForField = (\n\trows: AggregationRow[],\n\tmeta: FieldMeta,\n\ttruncated: boolean\n): FieldAggregation => {\n\tconst counts = new Map<string, number>()\n\tconst order: string[] = []\n\tfor (const option of meta.options ?? []) {\n\t\tcounts.set(option.value, 0)\n\t\torder.push(option.value)\n\t}\n\tconst snapshots = snapshotLabels(rows, meta.field)\n\tlet total = 0\n\tfor (const row of rows) {\n\t\tconst answer = (row.values ?? []).find((entry) => entry.field === meta.field)\n\t\tconst keys = valueKeys(answer?.value)\n\t\tif (keys.length === 0) {\n\t\t\tcontinue\n\t\t}\n\t\ttotal += 1\n\t\tfor (const key of keys) {\n\t\t\tif (!counts.has(key)) {\n\t\t\t\tcounts.set(key, 0)\n\t\t\t\torder.push(key)\n\t\t\t}\n\t\t\tcounts.set(key, (counts.get(key) ?? 0) + 1)\n\t\t}\n\t}\n\n\tconst optionValues = new Set((meta.options ?? []).map((option) => option.value))\n\tconst leftovers = order\n\t\t.filter((value) => !optionValues.has(value))\n\t\t.sort((a, b) => (counts.get(b) ?? 0) - (counts.get(a) ?? 0))\n\tconst ordered = [...(meta.options ?? []).map((option) => option.value), ...leftovers]\n\n\tconst optionLabelByValue = new Map(\n\t\t(meta.options ?? []).map((option) => [option.value, option.label])\n\t)\n\tconst buckets: AggregationBucket[] = ordered.map((value) => {\n\t\tconst count = counts.get(value) ?? 0\n\t\treturn {\n\t\t\tvalue,\n\t\t\tlabel: optionLabelByValue.get(value) ?? snapshots.get(value) ?? value,\n\t\t\tcount,\n\t\t\tpercentage: total > 0 ? round1((count / total) * 100) : 0,\n\t\t}\n\t})\n\n\treturn {\n\t\tfield: meta.field,\n\t\tlabel: meta.label,\n\t\tfieldType: meta.fieldType,\n\t\ttotal,\n\t\tbuckets,\n\t\ttruncated,\n\t}\n}\n\n/** Aggregate several fields across the same set of rows. */\nexport const aggregateRowsForFields = (\n\trows: AggregationRow[],\n\tmetas: FieldMeta[],\n\ttruncated: boolean\n): FieldAggregation[] => metas.map((meta) => aggregateRowForField(rows, meta, truncated))\n","import type { Payload, PayloadRequest } from 'payload'\nimport { FORM_SUBMISSIONS_SLUG } from '../collections/formSubmissions'\nimport { FORMS_SLUG } from '../collections/forms'\nimport type { FormFieldInstance } from '../submissions/types'\nimport { aggregateRowsForFields } from './aggregateRows'\nimport type { AggregationRow, FieldAggregation, FieldMeta, SubmissionStatusFilter } from './types'\n\nexport type AggregateFormResponsesArgs = {\n\tpayload: Payload\n\tformId: number | string\n\t/** Field machine names to aggregate. Defaults to every field that declares options (enumerable). */\n\tfields?: string[]\n\t/** Submission status to count. Defaults to `complete`. */\n\tstatus?: SubmissionStatusFilter\n\treq?: PayloadRequest\n\t/** Safety cap on submissions scanned; beyond it the result is flagged `truncated`. Default 10000. */\n\tmaxSubmissions?: number\n\t/** Page size for the submission scan. Default 500. */\n\tpageSize?: number\n}\n\nconst optionsOf = (field: FormFieldInstance): { value: string; label: string }[] | undefined => {\n\tif (!Array.isArray(field.options)) {\n\t\treturn undefined\n\t}\n\tconst options = (field.options as Array<{ label?: string; value?: string }>)\n\t\t.filter((option) => typeof option?.value === 'string')\n\t\t.map((option) => ({ value: String(option.value), label: option.label ?? String(option.value) }))\n\treturn options.length > 0 ? options : undefined\n}\n\n/** True when a field declares non-empty options (a choice field safe to aggregate publicly). */\nexport const fieldHasOptions = (field: FormFieldInstance): boolean => optionsOf(field) !== undefined\n\nconst metaFor = (field: FormFieldInstance): FieldMeta => ({\n\tfield: field.name,\n\tlabel: field.label ?? field.name,\n\tfieldType: field.blockType,\n\toptions: optionsOf(field),\n})\n\n/**\n * Aggregate submission responses for a form. Loads the form for current labels + option order, then pages\n * `payload.find` over its submissions (JSON `values` cannot be GROUP BY'd portably across Mongo + Postgres,\n * so we scan + reduce in JS, cross-DB-identically). Bounded by `maxSubmissions`; beyond it the result is\n * `truncated`. Returns one `FieldAggregation` per requested field (or per enumerable field by default).\n */\nexport const aggregateFormResponses = async (\n\targs: AggregateFormResponsesArgs\n): Promise<FieldAggregation[]> => {\n\tconst {\n\t\tpayload,\n\t\tformId,\n\t\tfields,\n\t\tstatus = 'complete',\n\t\treq,\n\t\tmaxSubmissions = 10000,\n\t\tpageSize = 500,\n\t} = args\n\tconst form = await payload\n\t\t.findByID({ collection: FORMS_SLUG, id: formId, depth: 0, overrideAccess: true, req })\n\t\t.catch(() => null)\n\tif (!form || !Array.isArray(form.fields)) {\n\t\treturn []\n\t}\n\tconst instances = form.fields as FormFieldInstance[]\n\tconst selected = fields\n\t\t? instances.filter((field) => fields.includes(field.name))\n\t\t: instances.filter((field) => optionsOf(field) !== undefined)\n\tif (selected.length === 0) {\n\t\treturn []\n\t}\n\tconst metas = selected.map(metaFor)\n\n\tconst statusWhere = status === 'all' ? [] : [{ status: { equals: status } }]\n\tconst where = { and: [{ form: { equals: formId } }, ...statusWhere] }\n\n\tconst rows: AggregationRow[] = []\n\tlet page = 1\n\tlet truncated = false\n\tfor (;;) {\n\t\tconst result = await payload.find({\n\t\t\tcollection: FORM_SUBMISSIONS_SLUG,\n\t\t\twhere,\n\t\t\tlimit: pageSize,\n\t\t\tpage,\n\t\t\tdepth: 0,\n\t\t\toverrideAccess: true,\n\t\t\treq,\n\t\t\tselect: { values: true, descriptors: true },\n\t\t})\n\t\tfor (const doc of result.docs as AggregationRow[]) {\n\t\t\t// Check before pushing so `truncated` means \"matching rows were left out\", not \"the cap was reached\n\t\t\t// exactly\": a form with precisely `maxSubmissions` responses is complete, not a sample.\n\t\t\tif (rows.length >= maxSubmissions) {\n\t\t\t\ttruncated = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\trows.push({ values: doc.values, descriptors: doc.descriptors })\n\t\t}\n\t\tif (truncated || !result.hasNextPage) {\n\t\t\tbreak\n\t\t}\n\t\tpage += 1\n\t}\n\n\treturn aggregateRowsForFields(rows, metas, truncated)\n}\n\nexport type AggregateFieldResponsesArgs = Omit<AggregateFormResponsesArgs, 'fields'> & {\n\tfield: string\n}\n\n/** Single-field convenience over `aggregateFormResponses`. Returns the field's aggregation, or null if absent. */\nexport const aggregateFieldResponses = async (\n\targs: AggregateFieldResponsesArgs\n): Promise<FieldAggregation | null> => {\n\tconst { field, ...rest } = args\n\tconst [result] = await aggregateFormResponses({ ...rest, fields: [field] })\n\treturn result ?? null\n}\n","import type { Payload, PayloadRequest } from 'payload'\nimport { FORMS_SLUG } from '../collections/forms'\nimport type { FormFieldInstance } from '../submissions/types'\nimport { aggregateFormResponses, fieldHasOptions } from './aggregateResponses'\nimport type { FieldAggregation } from './types'\n\nexport type ResolveResultsRequestArgs = {\n\tpayload: Payload\n\tformId: number | string | undefined\n\t/** The requested field (query param). */\n\tfield?: string\n\t/** Whether the caller is authenticated (an admin/user). */\n\tisAuthed: boolean\n\treq?: PayloadRequest\n}\n\nexport type ResolveResultsRequestResult = {\n\tstatus: number\n\tbody: { results: FieldAggregation[] } | { errors: { message: string }[] }\n}\n\nconst forbidden: ResolveResultsRequestResult = {\n\tstatus: 403,\n\tbody: { errors: [{ message: 'Forbidden' }] },\n}\n\n/**\n * Authorize and resolve a poll/survey results request. Authed callers may aggregate any field (or all\n * enumerable fields). Anonymous callers are allowed only when the form opted in (`showResults`), and then\n * only for the configured `resultsField`, and only if that field is enumerable (has options) so a\n * misconfigured `resultsField` pointing at a free-text or PII field can never be dumped publicly. Returns\n * only aggregate counts, never raw submissions.\n */\nexport const resolveFormResultsRequest = async (\n\targs: ResolveResultsRequestArgs\n): Promise<ResolveResultsRequestResult> => {\n\tconst { payload, formId, field, isAuthed, req } = args\n\tif (formId == null) {\n\t\treturn { status: 400, body: { errors: [{ message: 'Missing form id' }] } }\n\t}\n\tconst form = await payload\n\t\t.findByID({ collection: FORMS_SLUG, id: formId, depth: 0, overrideAccess: true, req })\n\t\t.catch(() => null)\n\tif (!form) {\n\t\treturn { status: 404, body: { errors: [{ message: 'Not found' }] } }\n\t}\n\n\tlet fields: string[] | undefined\n\tif (isAuthed) {\n\t\tfields = field ? [field] : undefined\n\t} else {\n\t\tif (form.showResults !== true) {\n\t\t\treturn forbidden\n\t\t}\n\t\tconst publicField =\n\t\t\ttypeof form.resultsField === 'string' && form.resultsField.length > 0\n\t\t\t\t? form.resultsField\n\t\t\t\t: undefined\n\t\tif (!publicField) {\n\t\t\treturn forbidden\n\t\t}\n\t\tif (field && field !== publicField) {\n\t\t\treturn forbidden\n\t\t}\n\t\tconst instances = Array.isArray(form.fields) ? (form.fields as FormFieldInstance[]) : []\n\t\tconst instance = instances.find((entry) => entry.name === publicField)\n\t\tif (!instance || !fieldHasOptions(instance)) {\n\t\t\treturn forbidden\n\t\t}\n\t\tfields = [publicField]\n\t}\n\n\tconst results = await aggregateFormResponses({ payload, formId, fields, req })\n\treturn { status: 200, body: { results } }\n}\n","import type { CalcExpression } from './types'\n\nconst MAX_DEPTH = 64\n\nconst OP_SET = new Set(['+', '-', '*', '/', '%'])\nconst FN_SET = new Set(['min', 'max', 'round', 'abs', 'ceil', 'floor'])\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n\tv !== null && typeof v === 'object' && !Array.isArray(v)\n\nconst normalizeNode = (value: unknown, depth: number): CalcExpression | undefined => {\n\tif (depth > MAX_DEPTH) return undefined\n\tif (!isRecord(value)) return undefined\n\n\tswitch (value.type) {\n\t\tcase 'lit': {\n\t\t\tconst { value: v } = value\n\t\t\tif (typeof v !== 'number' || !Number.isFinite(v)) return undefined\n\t\t\treturn { type: 'lit', value: v }\n\t\t}\n\t\tcase 'ref': {\n\t\t\tconst { field } = value\n\t\t\tif (typeof field !== 'string') return undefined\n\t\t\treturn { type: 'ref', field }\n\t\t}\n\t\tcase 'op': {\n\t\t\tconst { op, left, right } = value\n\t\t\tif (typeof op !== 'string' || !OP_SET.has(op)) return undefined\n\t\t\tconst l = normalizeNode(left, depth + 1)\n\t\t\tif (!l) return undefined\n\t\t\tconst r = normalizeNode(right, depth + 1)\n\t\t\tif (!r) return undefined\n\t\t\treturn { type: 'op', op: op as '+' | '-' | '*' | '/' | '%', left: l, right: r }\n\t\t}\n\t\tcase 'neg': {\n\t\t\tconst operand = normalizeNode(value.operand, depth + 1)\n\t\t\tif (!operand) return undefined\n\t\t\treturn { type: 'neg', operand }\n\t\t}\n\t\tcase 'fn': {\n\t\t\tconst { fn, args } = value\n\t\t\tif (typeof fn !== 'string' || !FN_SET.has(fn)) return undefined\n\t\t\tif (!Array.isArray(args)) return undefined\n\t\t\tconst normalizedArgs: CalcExpression[] = []\n\t\t\tfor (const arg of args) {\n\t\t\t\tconst a = normalizeNode(arg, depth + 1)\n\t\t\t\tif (!a) return undefined\n\t\t\t\tnormalizedArgs.push(a)\n\t\t\t}\n\t\t\treturn {\n\t\t\t\ttype: 'fn',\n\t\t\t\tfn: fn as 'min' | 'max' | 'round' | 'abs' | 'ceil' | 'floor',\n\t\t\t\targs: normalizedArgs,\n\t\t\t}\n\t\t}\n\t\tcase 'weight': {\n\t\t\tconst { field, weights } = value\n\t\t\tif (typeof field !== 'string') return undefined\n\t\t\tif (!isRecord(weights)) return undefined\n\t\t\tconst normalizedWeights: Record<string, number> = {}\n\t\t\tfor (const [k, v] of Object.entries(weights)) {\n\t\t\t\tif (typeof v !== 'number' || !Number.isFinite(v)) return undefined\n\t\t\t\tnormalizedWeights[k] = v\n\t\t\t}\n\t\t\treturn { type: 'weight', field, weights: normalizedWeights }\n\t\t}\n\t\tdefault:\n\t\t\treturn undefined\n\t}\n}\n\n/** Structural guard: returns a valid CalcExpression if `value` is structurally sound (depth-guarded at 64), otherwise undefined. Never throws. */\nexport const normalizeCalc = (value: unknown): CalcExpression | undefined => normalizeNode(value, 0)\n","import type { AnyFormFieldDefinition } from '../fields/types'\nimport { type ConditionFieldType, defaultConditionType } from './fieldTypes'\n\n/** The condition input a field type uses in the builder: its declared `conditionType` or the value-kind default. */\nexport const conditionTypeForDefinition = (\n\tdefinition: Pick<AnyFormFieldDefinition, 'value' | 'conditionType'>\n): ConditionFieldType => definition.conditionType ?? defaultConditionType(definition.value)\n\n/** A serializable slug -> condition type map for every registered field type, handed to the client builder. */\nexport const buildConditionTypeMap = (\n\tregistry: Map<string, AnyFormFieldDefinition>\n): Record<string, ConditionFieldType> => {\n\tconst map: Record<string, ConditionFieldType> = {}\n\tfor (const definition of registry.values()) {\n\t\tmap[definition.type] = conditionTypeForDefinition(definition)\n\t}\n\treturn map\n}\n","import type { Where } from 'payload'\nimport { transformWhereQuery } from 'payload/shared'\nimport type { ConditionFieldType } from './fieldTypes'\nimport { conditionOperators } from './fieldTypes'\n\nexport type FieldRow = {\n\tblockType: string\n\tname?: string\n\tvisibleWhen?: unknown\n\tvalidateWhen?: unknown\n\t[key: string]: unknown\n}\n\nconst isValidConstraint = (\n\tconstraint: unknown,\n\toperandTypes: Map<string, ConditionFieldType>\n): boolean => {\n\tif (constraint == null || typeof constraint !== 'object') {\n\t\treturn false\n\t}\n\tconst field = Object.keys(constraint as object)[0]\n\tif (!field) {\n\t\treturn false\n\t}\n\tconst type = operandTypes.get(field)\n\tif (!type) {\n\t\treturn false\n\t}\n\tconst ops = (constraint as Record<string, unknown>)[field]\n\tif (ops == null || typeof ops !== 'object') {\n\t\treturn false\n\t}\n\tconst operator = Object.keys(ops as object)[0]\n\treturn Boolean(operator && (conditionOperators[type] as readonly string[]).includes(operator))\n}\n\nconst normalizeOne = (\n\traw: unknown,\n\toperandTypes: Map<string, ConditionFieldType>\n): Where | undefined => {\n\tif (raw == null || typeof raw !== 'object' || Object.keys(raw as object).length === 0) {\n\t\treturn undefined\n\t}\n\tconst canonical = transformWhereQuery(raw as Where)\n\tconst or = Array.isArray(canonical.or)\n\t\t? canonical.or\n\t\t: Array.isArray(canonical.and)\n\t\t\t? [{ and: canonical.and }]\n\t\t\t: []\n\tconst groups = or\n\t\t.map((group) => {\n\t\t\tconst and = Array.isArray((group as Where).and) ? ((group as Where).and as unknown[]) : []\n\t\t\treturn and.filter((constraint) => isValidConstraint(constraint, operandTypes))\n\t\t})\n\t\t.filter((group) => group.length > 0)\n\treturn groups.length > 0 ? ({ or: groups.map((and) => ({ and })) } as Where) : undefined\n}\n\n/**\n * Normalize every field's `visibleWhen`/`validateWhen` against the form's own field list. Canonicalizes\n * to OR-of-ANDs and strips constraints whose operand field is missing or whose operator is invalid for\n * that field's condition type, so stored conditions always match what `evaluateCondition` can run.\n */\nexport const normalizeFormConditions = (\n\tfields: FieldRow[],\n\tconditionTypes: Record<string, ConditionFieldType>\n): FieldRow[] => {\n\tconst operandTypes = new Map<string, ConditionFieldType>()\n\tfor (const row of fields) {\n\t\tconst name = typeof row.name === 'string' ? row.name.trim() : ''\n\t\tif (name.length > 0) {\n\t\t\toperandTypes.set(name, conditionTypes[row.blockType] ?? 'text')\n\t\t}\n\t}\n\treturn fields.map((row) => {\n\t\tconst visibleWhen = normalizeOne(row.visibleWhen, operandTypes)\n\t\tconst validateWhen = normalizeOne(row.validateWhen, operandTypes)\n\t\treturn { ...row, visibleWhen, validateWhen }\n\t})\n}\n","import type { Block } from 'payload'\nimport { keys } from '../translations/keys'\nimport { labelFor } from '../translations/server'\nimport type { ValidationRuleRegistry } from './registry'\n\n/** Each rule block appends its own `message` and `severity` fields, so a rule param of either name would collide and be silently dropped by Payload. */\nconst RESERVED_PARAM_NAMES = new Set(['message', 'severity'])\n\n/** One block per rule applicable to `fieldType` (gated by `appliesTo`): the rule params, then a message override and severity. */\nexport const buildRuleBlocks = (registry: ValidationRuleRegistry, fieldType: string): Block[] => {\n\tconst blocks: Block[] = []\n\tfor (const rule of registry.values()) {\n\t\tif (rule.appliesTo && !rule.appliesTo.includes(fieldType)) {\n\t\t\tcontinue\n\t\t}\n\t\tfor (const param of rule.params ?? []) {\n\t\t\tif ('name' in param && RESERVED_PARAM_NAMES.has(param.name)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`form-builder: validation rule \"${rule.type}\" declares a reserved param name \"${param.name}\". The names \"message\" and \"severity\" are reserved for the constraint-list UI.`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tblocks.push({\n\t\t\tslug: rule.type,\n\t\t\tlabels: { singular: labelFor(rule.label), plural: labelFor(rule.label) },\n\t\t\tfields: [\n\t\t\t\t...(rule.params ?? []),\n\t\t\t\t{ name: 'message', type: 'text', label: labelFor(keys.validationMessageLabel) },\n\t\t\t\t{\n\t\t\t\t\tname: 'severity',\n\t\t\t\t\ttype: 'select',\n\t\t\t\t\tdefaultValue: 'error',\n\t\t\t\t\tlabel: labelFor(keys.validationSeverityLabel),\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{ label: labelFor(keys.validationSeverityError), value: 'error' },\n\t\t\t\t\t\t{ label: labelFor(keys.validationSeverityWarning), value: 'warning' },\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t})\n\t}\n\treturn blocks\n}\n","import type { Field } from 'payload'\nimport type { ConditionFieldType } from '../conditions/fieldTypes'\nimport { keys } from '../translations/keys'\nimport { labelFor } from '../translations/server'\n\nconst CONDITION_FIELD_REF = '@10x-media/form-builder/client#FormConditionField'\n\nconst conditionField = (\n\tname: 'visibleWhen' | 'validateWhen',\n\tlabelKey: string,\n\tconditionTypes: Record<string, ConditionFieldType>\n): Field => ({\n\tname,\n\ttype: 'json',\n\tlabel: labelFor(labelKey),\n\tadmin: {\n\t\tcomponents: {\n\t\t\tField: { path: CONDITION_FIELD_REF, clientProps: { conditionTypes } },\n\t\t},\n\t},\n})\n\n/**\n * Config every field instance carries regardless of type. `name` is the machine key written into\n * submissions; `width` is stored for the layout grid. `visibleWhen`/`validateWhen` store a\n * canonical Payload `Where`, edited by the native condition builder. Field types add their own `config`\n * after these.\n */\nexport const sharedFieldConfig = (conditionTypes: Record<string, ConditionFieldType>): Field[] => [\n\t{ name: 'name', type: 'text', required: true, label: labelFor(keys.configName) },\n\t{ name: 'label', type: 'text', label: labelFor(keys.configLabel) },\n\t{ name: 'required', type: 'checkbox', label: labelFor(keys.configRequired) },\n\t{\n\t\tname: 'width',\n\t\ttype: 'select',\n\t\tdefaultValue: 'full',\n\t\tlabel: labelFor(keys.configWidth),\n\t\toptions: [\n\t\t\t{ label: 'Full', value: 'full' },\n\t\t\t{ label: 'Half', value: 'half' },\n\t\t\t{ label: 'Third', value: 'third' },\n\t\t\t{ label: 'Two thirds', value: 'twoThirds' },\n\t\t],\n\t},\n\t{ name: 'placeholder', type: 'text', label: labelFor(keys.configPlaceholder) },\n\t{ name: 'description', type: 'textarea', label: labelFor(keys.configDescription) },\n\t{\n\t\ttype: 'collapsible',\n\t\tlabel: labelFor(keys.configAdvanced),\n\t\tadmin: { initCollapsed: true },\n\t\tfields: [\n\t\t\tconditionField('visibleWhen', keys.configVisibleWhen, conditionTypes),\n\t\t\tconditionField('validateWhen', keys.configValidateWhen, conditionTypes),\n\t\t\t{ name: 'hidden', type: 'checkbox', label: labelFor(keys.configHidden) },\n\t\t],\n\t},\n]\n","import type { Block } from 'payload'\nimport { buildConditionTypeMap } from '../conditions/conditionType'\nimport { keys } from '../translations/keys'\nimport { labelFor } from '../translations/server'\nimport { buildRuleBlocks } from '../validation/buildRuleBlocks'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport type { FieldTypeRegistry } from './registry'\nimport { sharedFieldConfig } from './sharedConfig'\n\n/** One add-field block per registered type: shared config, the type's own config, then its validations. */\nexport const buildFieldBlocks = (\n\tregistry: FieldTypeRegistry,\n\truleRegistry: ValidationRuleRegistry\n): Block[] => {\n\tconst conditionTypes = buildConditionTypeMap(registry)\n\tconst blocks: Block[] = []\n\tfor (const definition of registry.values()) {\n\t\tblocks.push({\n\t\t\tslug: definition.type,\n\t\t\tlabels: { singular: labelFor(definition.label), plural: labelFor(definition.label) },\n\t\t\tfields: [\n\t\t\t\t...sharedFieldConfig(conditionTypes),\n\t\t\t\t...(definition.config ?? []),\n\t\t\t\t{\n\t\t\t\t\tname: 'validations',\n\t\t\t\t\ttype: 'blocks',\n\t\t\t\t\tlabel: labelFor(keys.validationsLabel),\n\t\t\t\t\tblocks: buildRuleBlocks(ruleRegistry, definition.type),\n\t\t\t\t},\n\t\t\t],\n\t\t})\n\t}\n\treturn blocks\n}\n","import type { Where } from 'payload'\nimport type { FlowStep, FormFlow } from './types'\n\nconst isRecord = (v: unknown): v is Record<string, unknown> =>\n\tv !== null && typeof v === 'object' && !Array.isArray(v)\n\n/**\n * Pure guard that normalizes a raw (possibly untrusted) flow value against the\n * form's current field list. Returns `undefined` when the flow is absent, empty,\n * or resolves to fewer than two steps (a single step is an ordinary form).\n */\nexport const normalizeFlow = (raw: unknown, fieldNames: string[]): FormFlow | undefined => {\n\tif (!isRecord(raw) || !Array.isArray(raw.steps)) {\n\t\treturn undefined\n\t}\n\n\tconst knownFields = new Set(fieldNames)\n\n\tconst rawSteps = raw.steps.filter(\n\t\t(s): s is Record<string, unknown> => isRecord(s) && typeof s.id === 'string'\n\t)\n\n\tconst knownIds = new Set(rawSteps.map((s) => s.id as string))\n\n\tif (knownIds.size < 2) {\n\t\treturn undefined\n\t}\n\n\tconst steps: FlowStep[] = rawSteps.map((s) => {\n\t\tconst id = s.id as string\n\n\t\tconst fields = Array.isArray(s.fields)\n\t\t\t? s.fields.filter((f): f is string => typeof f === 'string' && knownFields.has(f))\n\t\t\t: []\n\n\t\tconst rawTransitions = Array.isArray(s.transitions) ? s.transitions : []\n\t\tconst transitions = rawTransitions\n\t\t\t.filter(\n\t\t\t\t(t): t is Record<string, unknown> =>\n\t\t\t\t\tisRecord(t) &&\n\t\t\t\t\ttypeof t.to === 'string' &&\n\t\t\t\t\tknownIds.has(t.to as string) &&\n\t\t\t\t\tisRecord(t.when)\n\t\t\t)\n\t\t\t.map((t) => ({ when: t.when as Where, to: t.to as string }))\n\n\t\tconst next = typeof s.next === 'string' && knownIds.has(s.next) ? (s.next as string) : undefined\n\n\t\tconst step: FlowStep = { id, fields }\n\t\tif (typeof s.title === 'string') step.title = s.title\n\t\tif (transitions.length > 0) step.transitions = transitions\n\t\tif (next !== undefined) step.next = next\n\n\t\treturn step\n\t})\n\n\treturn { steps }\n}\n","import type { CollectionBeforeValidateHook, CollectionConfig, PayloadRequest } from 'payload'\nimport { buildActionBlocks } from '../actions/buildActionBlocks'\nimport type { ActionRegistry } from '../actions/registry'\nimport { resolveFormResultsRequest } from '../aggregation/resolveResultsRequest'\nimport { normalizeCalc } from '../calc/normalizeCalc'\nimport { buildConditionTypeMap } from '../conditions/conditionType'\nimport { type FieldRow, normalizeFormConditions } from '../conditions/normalizeConditions'\nimport { buildFieldBlocks } from '../fields/buildFieldBlocks'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport { normalizeFlow } from '../flow/normalizeFlow'\nimport {\n\tDEFAULT_PRESENTATION_NAME,\n\tdefaultPresentationDescriptors,\n} from '../presentations/defaults'\nimport type { PresentationDescriptorRegistry } from '../presentations/registry'\nimport { keys } from '../translations/keys'\nimport { labelFor, labelForKey } from '../translations/server'\nimport type { ValidationRuleRegistry } from '../validation/registry'\n\nexport const FORMS_SLUG = 'forms'\n\ntype BuildFormsCollectionArgs = {\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tpresentationRegistry?: PresentationDescriptorRegistry\n\tactionRegistry?: ActionRegistry\n}\n\nexport const buildFormsCollection = ({\n\tregistry,\n\truleRegistry,\n\tpresentationRegistry = new Map(Object.entries(defaultPresentationDescriptors)),\n\tactionRegistry = new Map(),\n}: BuildFormsCollectionArgs): CollectionConfig => {\n\tconst conditionTypes = buildConditionTypeMap(registry)\n\n\tconst beforeValidate: CollectionBeforeValidateHook = ({ data }) => {\n\t\tif (\n\t\t\tdata &&\n\t\t\ttypeof data.defaultPresentation === 'string' &&\n\t\t\t!presentationRegistry.has(data.defaultPresentation)\n\t\t) {\n\t\t\tdata.defaultPresentation = DEFAULT_PRESENTATION_NAME\n\t\t}\n\t\tif (data && Array.isArray(data.fields)) {\n\t\t\tconst normalized: FieldRow[] = normalizeFormConditions(\n\t\t\t\tdata.fields as FieldRow[],\n\t\t\t\tconditionTypes\n\t\t\t)\n\t\t\tfor (const field of normalized) {\n\t\t\t\tif ('expression' in field) {\n\t\t\t\t\tfield.expression = normalizeCalc(field.expression)\n\t\t\t\t}\n\t\t\t}\n\t\t\tdata.fields = normalized\n\t\t\tconst fieldNames = normalized\n\t\t\t\t.map((field: FieldRow) => (typeof field.name === 'string' ? field.name : undefined))\n\t\t\t\t.filter((name): name is string => name !== undefined)\n\t\t\tdata.flow = normalizeFlow(data.flow, fieldNames)\n\t\t}\n\t\treturn data\n\t}\n\n\treturn {\n\t\tslug: FORMS_SLUG,\n\t\tlabels: { singular: 'Form', plural: 'Forms' },\n\t\tadmin: { group: 'Forms', useAsTitle: 'title' },\n\t\taccess: { read: () => true },\n\t\thooks: {\n\t\t\tbeforeValidate: [beforeValidate],\n\t\t},\n\t\tfields: [\n\t\t\t{ name: 'title', type: 'text', required: true, label: labelForKey(keys.fieldTitle) },\n\t\t\t{ name: 'fields', type: 'blocks', blocks: buildFieldBlocks(registry, ruleRegistry) },\n\t\t\t{ name: 'flow', type: 'json' },\n\t\t\t{\n\t\t\t\tname: 'actions',\n\t\t\t\ttype: 'blocks',\n\t\t\t\tblocks: buildActionBlocks(actionRegistry),\n\t\t\t\tlabel: labelForKey(keys.configActions),\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'defaultPresentation',\n\t\t\t\ttype: 'select',\n\t\t\t\tdefaultValue: DEFAULT_PRESENTATION_NAME,\n\t\t\t\toptions: [...presentationRegistry.values()].map((descriptor) => ({\n\t\t\t\t\tlabel: labelFor(descriptor.label),\n\t\t\t\t\tvalue: descriptor.name,\n\t\t\t\t})),\n\t\t\t\tlabel: labelForKey(keys.configDefaultPresentation),\n\t\t\t\tadmin: { position: 'sidebar' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'showResults',\n\t\t\t\ttype: 'checkbox',\n\t\t\t\tdefaultValue: false,\n\t\t\t\tlabel: labelForKey(keys.configShowResults),\n\t\t\t\tadmin: { position: 'sidebar' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'resultsField',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelForKey(keys.configResultsField),\n\t\t\t\tadmin: {\n\t\t\t\t\tposition: 'sidebar',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Field whose aggregate results are public when \"Show results publicly\" is on. Use a choice field, never a free-text or PII field.',\n\t\t\t\t\tcondition: (data) => Boolean(data?.showResults),\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tendpoints: [\n\t\t\t{\n\t\t\t\tpath: '/:id/results',\n\t\t\t\tmethod: 'get',\n\t\t\t\thandler: async (req: PayloadRequest) => {\n\t\t\t\t\tconst field = typeof req.query?.field === 'string' ? req.query.field : undefined\n\t\t\t\t\tconst { status, body } = await resolveFormResultsRequest({\n\t\t\t\t\t\tpayload: req.payload,\n\t\t\t\t\t\tformId: req.routeParams?.id as number | string | undefined,\n\t\t\t\t\t\tfield,\n\t\t\t\t\t\tisAuthed: Boolean(req.user),\n\t\t\t\t\t\treq,\n\t\t\t\t\t})\n\t\t\t\t\treturn Response.json(body, { status })\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t}\n}\n","import type { Payload, PayloadRequest } from 'payload'\nimport type { FormFieldInstance } from '../submissions/types'\nimport type { ConsentResolved } from './defineConsentSource'\nimport type { ConsentSourceRegistry } from './registry'\n\nconst EMPTY: ConsentResolved = { links: [] }\n\n/**\n * Resolve a consent field's policy links via its configured source (for display).\n * Unknown/missing source returns empty links. Never throws.\n */\nexport const resolveConsentLinks = async (\n\tfield: FormFieldInstance,\n\tctx: {\n\t\tregistry: ConsentSourceRegistry\n\t\tpayload: Payload\n\t\treq?: PayloadRequest\n\t\tlocale: string\n\t}\n): Promise<ConsentResolved> => {\n\tconst sourceType = typeof field.source === 'string' ? field.source : 'static'\n\tconst source = ctx.registry.get(sourceType)\n\tif (!source) {\n\t\treturn EMPTY\n\t}\n\t// The source params live in the field's `sourceConfig` group (kept off the top level so they cannot collide with the shared field config).\n\tconst sourceConfig =\n\t\tfield.sourceConfig && typeof field.sourceConfig === 'object'\n\t\t\t? (field.sourceConfig as Record<string, unknown>)\n\t\t\t: {}\n\ttry {\n\t\treturn await source.resolve({\n\t\t\tconfig: sourceConfig,\n\t\t\tpayload: ctx.payload,\n\t\t\treq: ctx.req,\n\t\t\tlocale: ctx.locale,\n\t\t})\n\t} catch {\n\t\treturn EMPTY\n\t}\n}\n","import type { Payload, PayloadRequest } from 'payload'\nimport type { FormFieldInstance } from '../submissions/types'\nimport type { ConsentSourceRegistry } from './registry'\nimport { resolveConsentLinks } from './resolveConsentLinks'\n\nexport type ConsentProof = {\n\tagreed: boolean\n\tref?: string\n\tversionRef?: string\n\tat: string\n}\n\n/**\n * Build the authoritative consent proof at submit time: re-resolve the source server-side\n * (ignores any client ref), capturing a reference url -- never the policy text.\n * `now` is injected by the caller (`new Date().toISOString()`) for testability.\n */\nexport const captureConsent = async (args: {\n\tfield: FormFieldInstance\n\tagreed: boolean\n\tregistry: ConsentSourceRegistry\n\tpayload: Payload\n\treq?: PayloadRequest\n\tlocale: string\n\tnow: string\n}): Promise<ConsentProof> => {\n\tconst resolved = await resolveConsentLinks(args.field, {\n\t\tregistry: args.registry,\n\t\tpayload: args.payload,\n\t\treq: args.req,\n\t\tlocale: args.locale,\n\t})\n\tconst ref = resolved.links[0]?.url || undefined\n\treturn {\n\t\tagreed: args.agreed,\n\t\t...(ref ? { ref } : {}),\n\t\t...(resolved.versionRef ? { versionRef: resolved.versionRef } : {}),\n\t\tat: args.now,\n\t}\n}\n","import type { FileFieldConfig, FileRef, FileRefError } from './types'\n\ntype UploadDoc = {\n\tid?: string | number\n\tfilename?: unknown\n\tmimeType?: unknown\n\tfilesize?: unknown\n\turl?: unknown\n}\n\nexport type ResolveFileRefResult = { ok: true; ref: FileRef } | { ok: false; code: FileRefError }\n\nconst mimeAllowed = (mimeType: string, allow: string[] | undefined): boolean => {\n\tif (!allow || allow.length === 0) {\n\t\treturn true\n\t}\n\treturn allow.some((pattern) => {\n\t\tif (pattern.endsWith('/*')) {\n\t\t\treturn mimeType.startsWith(pattern.slice(0, -1))\n\t\t}\n\t\treturn mimeType === pattern\n\t})\n}\n\n/**\n * Pure server trust-boundary check for an uploaded file: given the loaded upload doc (or null) and the\n * field's constraints, either return an authoritative `FileRef` snapshot or a rejection code. Never trusts\n * client metadata; the caller passes the doc it loaded from the upload collection.\n */\nexport const resolveFileRef = (\n\tdoc: UploadDoc | null | undefined,\n\tconfig: FileFieldConfig\n): ResolveFileRefResult => {\n\tif (doc == null || doc.id == null) {\n\t\treturn { ok: false, code: 'missing' }\n\t}\n\tconst mimeType = typeof doc.mimeType === 'string' ? doc.mimeType : ''\n\tconst filesize = typeof doc.filesize === 'number' ? doc.filesize : 0\n\tif (!mimeAllowed(mimeType, config.mimeTypes)) {\n\t\treturn { ok: false, code: 'mimeType' }\n\t}\n\tif (typeof config.maxSize === 'number' && filesize > config.maxSize) {\n\t\treturn { ok: false, code: 'tooLarge' }\n\t}\n\tconst ref: FileRef = {\n\t\tid: doc.id,\n\t\tfilename: typeof doc.filename === 'string' ? doc.filename : '',\n\t\tmimeType,\n\t\tfilesize,\n\t}\n\tif (typeof doc.url === 'string' && doc.url.length > 0) {\n\t\tref.url = doc.url\n\t}\n\treturn { ok: true, ref }\n}\n","import type { CollectionSlug, Payload, PayloadRequest } from 'payload'\nimport { type ResolveFileRefResult, resolveFileRef } from './resolveFileRef'\nimport type { FileFieldConfig } from './types'\n\nexport type CaptureFileRefArgs = {\n\tpayload: Payload\n\tcollectionSlug: string\n\tuploadId: string | number\n\tconfig: FileFieldConfig\n\treq?: PayloadRequest\n\t/** Resolved submitter identity; must match the upload's `owner` stamp when both are present. */\n\texpectedOwner?: string\n}\n\n/**\n * Load the referenced upload doc and run the pure trust-boundary check. The client sends only the id; the\n * filename/mimeType/filesize are read authoritatively from the stored doc, never from the client. When the\n * upload carries an `owner` stamp AND the submitter is identifiable, the two must match, so an anonymous\n * submitter cannot capture another identity's upload; a mismatch collapses to `missing`, indistinguishable\n * from a deleted upload. When the submitter cannot be identified (no `expectedOwner`), ownership is not\n * enforced (fail-open, consistent with rate-limiting): a proxy-configured deployment identifies every\n * request, so this only relaxes scoping where it could not be applied fairly anyway. Unstamped uploads\n * (no identity at upload time, or a BYO collection without the field) pass unchanged.\n */\nexport const captureFileRef = async (args: CaptureFileRefArgs): Promise<ResolveFileRefResult> => {\n\tconst { payload, collectionSlug, uploadId, config, req, expectedOwner } = args\n\tconst doc = await payload\n\t\t.findByID({\n\t\t\tcollection: collectionSlug as CollectionSlug,\n\t\t\tid: uploadId,\n\t\t\tdepth: 0,\n\t\t\toverrideAccess: true,\n\t\t\treq,\n\t\t})\n\t\t.catch(() => null)\n\tif (doc && expectedOwner != null) {\n\t\tconst owner = (doc as { owner?: unknown }).owner\n\t\tif (typeof owner === 'string' && owner.length > 0 && owner !== expectedOwner) {\n\t\t\treturn { ok: false, code: 'missing' }\n\t\t}\n\t}\n\treturn resolveFileRef(doc, config)\n}\n","import type { Payload, PayloadRequest } from 'payload'\nimport { calcExpressionOf, computeCalcFields } from '../calc/computeCalcFields'\nimport { evaluateCondition } from '../conditions/evaluate'\nimport type { ConsentProof } from '../consent/captureConsent'\nimport { captureConsent } from '../consent/captureConsent'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport type { Translate } from '../fields/types'\nimport { keys } from '../translations/keys'\nimport { captureFileRef } from '../uploads/captureFileRef'\nimport type { FileFieldConfig, FileRefError } from '../uploads/types'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport { runValidation } from '../validation/runValidation'\nimport type {\n\tFormFieldInstance,\n\tSubmissionDescriptor,\n\tSubmissionFieldError,\n\tSubmissionValue,\n} from './types'\n\nconst errorKeyFor = (code: FileRefError): string => {\n\tif (code === 'mimeType') {\n\t\treturn keys.validationFileMimeType\n\t}\n\tif (code === 'tooLarge') {\n\t\treturn keys.validationFileTooLarge\n\t}\n\treturn keys.validationFileMissing\n}\n\n/** Normalize the authored `mimeTypes` (a `hasMany` text field) to a `string[]`. */\nconst mimeTypesOf = (raw: unknown): string[] | undefined => {\n\tif (!Array.isArray(raw)) {\n\t\treturn undefined\n\t}\n\tconst out = (raw as unknown[]).filter((entry): entry is string => typeof entry === 'string')\n\treturn out.length > 0 ? out : undefined\n}\n\nconst fileFieldConfigOf = (instance: FormFieldInstance): FileFieldConfig => ({\n\trelationTo: typeof instance.relationTo === 'string' ? instance.relationTo : undefined,\n\tmimeTypes: mimeTypesOf(instance.mimeTypes),\n\tmaxSize: typeof instance.maxSize === 'number' ? instance.maxSize : undefined,\n})\n\nconst isEmpty = (value: unknown): boolean =>\n\tvalue == null || value === '' || (Array.isArray(value) && value.length === 0)\n\nconst coerce = (kind: string, value: unknown): unknown => {\n\tif (value == null) {\n\t\treturn value\n\t}\n\tif (kind === 'number') {\n\t\tconst next = typeof value === 'number' ? value : Number(value)\n\t\treturn Number.isNaN(next) ? value : next\n\t}\n\tif (kind === 'boolean') {\n\t\t// A genuine boolean from the renderer passes through; a raw client string is parsed strictly so that\n\t\t// \"false\"/\"0\"/\"off\"/\"no\"/\"\" are not silently truthy (this matters for the required-consent check).\n\t\tif (typeof value === 'string') {\n\t\t\tconst normalized = value.trim().toLowerCase()\n\t\t\treturn !(\n\t\t\t\tnormalized === '' ||\n\t\t\t\tnormalized === 'false' ||\n\t\t\t\tnormalized === '0' ||\n\t\t\t\tnormalized === 'off' ||\n\t\t\t\tnormalized === 'no'\n\t\t\t)\n\t\t}\n\t\treturn Boolean(value)\n\t}\n\tif (kind === 'text') {\n\t\treturn typeof value === 'string' ? value : String(value)\n\t}\n\treturn value\n}\n\nconst optionLabelsFor = (instance: FormFieldInstance): Record<string, string> | undefined => {\n\tconst options = instance.options\n\tif (!Array.isArray(options)) {\n\t\treturn undefined\n\t}\n\tconst map: Record<string, string> = {}\n\tfor (const option of options as Array<{ label?: string; value?: string }>) {\n\t\tif (typeof option?.value === 'string') {\n\t\t\tmap[option.value] = option.label ?? option.value\n\t\t}\n\t}\n\treturn Object.keys(map).length > 0 ? map : undefined\n}\n\nexport type ConsentProofEntry = { field: string } & ConsentProof\n\nexport type RunSubmissionInput = {\n\tfields: FormFieldInstance[]\n\tvalues: SubmissionValue[]\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tconsentRegistry: ConsentSourceRegistry\n\tlocale: string\n\tt: Translate\n\toperation: 'create' | 'update'\n\treq?: PayloadRequest\n\tpayload?: Payload\n\tformId?: number | string\n\t/** Upload collection slug for file fields without an explicit `relationTo`. Defaults to `form-uploads`. */\n\tuploadSlug?: string\n\t/** Resolved request identity, verified against an upload's `owner` stamp when a file field is captured. */\n\texpectedOwner?: string\n}\n\nexport type RunSubmissionResult = {\n\terrors: SubmissionFieldError[]\n\tvalues: SubmissionValue[]\n\tdescriptors: SubmissionDescriptor[]\n\tconsent: ConsentProofEntry[]\n}\n\n/**\n * Pure submission core, two-pass: first coerce every answered field to its typed kind (so cross-field\n * rules see coerced siblings), then validate each field through `runValidation` (required, intrinsic\n * facet, declarative rules), snapshotting a localized descriptor per answered field. Calc fields are\n * the trust boundary: their client-sent values are never seeded, their values are derived from their\n * expressions over the coerced answers, and those derived values are authoritative everywhere downstream\n * (conditions, validation, storage). Conditions gate the second pass against these effective answers: a\n * field whose `visibleWhen` is false is skipped entirely (never validated, never stored, so a client-sent\n * value for it is ignored), and a visible field whose `validateWhen` is false stores its value but skips\n * validation. A visible calc field stores its derived value and is never validated. Only `error` severity\n * blocks; warnings are computed but not surfaced server-side (the renderer surfaces them).\n */\nexport const runSubmission = async (input: RunSubmissionInput): Promise<RunSubmissionResult> => {\n\tconst {\n\t\tfields,\n\t\tvalues,\n\t\tregistry,\n\t\truleRegistry,\n\t\tconsentRegistry,\n\t\tlocale,\n\t\tt,\n\t\toperation,\n\t\treq,\n\t\tpayload,\n\t\tformId,\n\t\tuploadSlug,\n\t\texpectedOwner,\n\t} = input\n\tconst incoming = new Map(values.map((entry) => [entry.field, entry.value]))\n\n\tconst coercedAnswers: Record<string, unknown> = {}\n\tconst coercedByName = new Map<string, unknown>()\n\tfor (const instance of fields) {\n\t\tconst definition = registry.get(instance.blockType)\n\t\tconst raw = incoming.get(instance.name)\n\t\t// Never seed a calc field's client value: its value is derived below, so the client cannot influence it (even for a self-referencing expression).\n\t\tif (!definition || calcExpressionOf(instance)) {\n\t\t\tcontinue\n\t\t}\n\t\t// A consent field's \"not agreed\" state is semantically meaningful: treat a missing value as\n\t\t// `false` so the intrinsic validate can enforce required-agreement (not optional = must be true).\n\t\tconst effectiveRaw = instance.blockType === 'consent' && isEmpty(raw) ? false : raw\n\t\tif (isEmpty(effectiveRaw)) {\n\t\t\tcontinue\n\t\t}\n\t\tconst value = coerce(definition.value, effectiveRaw)\n\t\tcoercedAnswers[instance.name] = value\n\t\tcoercedByName.set(instance.name, value)\n\t}\n\n\t// Calc values are authoritative everywhere downstream (conditions, validation, storage), never the client-sent value.\n\tconst effective = computeCalcFields(fields, coercedAnswers)\n\n\tconst errors: SubmissionFieldError[] = []\n\tconst outValues: SubmissionValue[] = []\n\tconst descriptors: SubmissionDescriptor[] = []\n\tconst consentProofs: ConsentProofEntry[] = []\n\tconst now = new Date().toISOString()\n\n\tfor (const instance of fields) {\n\t\tconst definition = registry.get(instance.blockType)\n\t\tif (!definition) {\n\t\t\tcontinue\n\t\t}\n\t\tconst raw = incoming.get(instance.name)\n\t\tconst value = coercedByName.has(instance.name) ? coercedByName.get(instance.name) : raw\n\n\t\tif (!evaluateCondition(instance.visibleWhen, effective)) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// A calc field's value is server-derived and always valid: skip validation and the client value entirely, storing the computed result.\n\t\tif (calcExpressionOf(instance)) {\n\t\t\toutValues.push({ field: instance.name, value: effective[instance.name] })\n\t\t\tdescriptors.push({\n\t\t\t\tfield: instance.name,\n\t\t\t\tlabel: instance.label ?? instance.name,\n\t\t\t\tfieldType: instance.blockType,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tif (evaluateCondition(instance.validateWhen, effective)) {\n\t\t\tconst { errors: issues } = await runValidation({\n\t\t\t\tfield: instance,\n\t\t\t\tfieldDefinition: definition,\n\t\t\t\tvalue,\n\t\t\t\tfieldType: instance.blockType,\n\t\t\t\truleRegistry,\n\t\t\t\tanswers: effective,\n\t\t\t\tlocale,\n\t\t\t\tt,\n\t\t\t\toperation,\n\t\t\t\tevent: 'submit',\n\t\t\t\tmode: 'server',\n\t\t\t\treq,\n\t\t\t\tpayload,\n\t\t\t\tformId,\n\t\t\t})\n\t\t\tconst blocking = issues.filter((issue) => issue.severity === 'error')\n\t\t\tif (blocking.length > 0) {\n\t\t\t\tfor (const issue of blocking) {\n\t\t\t\t\terrors.push({ path: instance.name, message: issue.message })\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif (instance.blockType === 'file') {\n\t\t\tif (isEmpty(value)) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (payload) {\n\t\t\t\tconst fileConfig = fileFieldConfigOf(instance)\n\t\t\t\tconst slug = fileConfig.relationTo ?? uploadSlug ?? 'form-uploads'\n\t\t\t\tconst captured = await captureFileRef({\n\t\t\t\t\tpayload,\n\t\t\t\t\tcollectionSlug: slug,\n\t\t\t\t\tuploadId: value as string | number,\n\t\t\t\t\tconfig: fileConfig,\n\t\t\t\t\treq,\n\t\t\t\t\texpectedOwner,\n\t\t\t\t})\n\t\t\t\tif (!captured.ok) {\n\t\t\t\t\terrors.push({ path: instance.name, message: t(errorKeyFor(captured.code)) })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\toutValues.push({ field: instance.name, value: captured.ref })\n\t\t\t\tdescriptors.push({\n\t\t\t\t\tfield: instance.name,\n\t\t\t\t\tlabel: instance.label ?? instance.name,\n\t\t\t\t\tfieldType: instance.blockType,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\toutValues.push({ field: instance.name, value })\n\t\t\tdescriptors.push({\n\t\t\t\tfield: instance.name,\n\t\t\t\tlabel: instance.label ?? instance.name,\n\t\t\t\tfieldType: instance.blockType,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tif (instance.blockType === 'consent' && payload) {\n\t\t\tconst proof = await captureConsent({\n\t\t\t\tfield: instance,\n\t\t\t\tagreed: value === true,\n\t\t\t\tregistry: consentRegistry,\n\t\t\t\tpayload,\n\t\t\t\treq,\n\t\t\t\tlocale,\n\t\t\t\tnow,\n\t\t\t})\n\t\t\tconsentProofs.push({ field: instance.name, ...proof })\n\t\t\tcontinue\n\t\t}\n\n\t\tif (isEmpty(raw)) {\n\t\t\tcontinue\n\t\t}\n\n\t\toutValues.push({ field: instance.name, value })\n\t\tconst optionLabels = optionLabelsFor(instance)\n\t\tdescriptors.push({\n\t\t\tfield: instance.name,\n\t\t\tlabel: instance.label ?? instance.name,\n\t\t\tfieldType: instance.blockType,\n\t\t\t...(optionLabels ? { optionLabels } : {}),\n\t\t})\n\t}\n\n\treturn { errors, values: outValues, descriptors, consent: consentProofs }\n}\n","import { type CollectionBeforeValidateHook, ValidationError } from 'payload'\nimport { FORM_SUBMISSIONS_SLUG } from '../collections/formSubmissions'\nimport { FORMS_SLUG } from '../collections/forms'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport { IDENTITY_CONTEXT_KEY } from '../spam/constants'\nimport { asFieldTranslate } from '../translations/server'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport { runSubmission } from './runSubmission'\nimport type { FormFieldInstance, SubmissionValue } from './types'\n\nexport type ValidateSubmissionArgs = {\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tconsentRegistry: ConsentSourceRegistry\n\t/** Upload collection slug for file fields without an explicit `relationTo`. */\n\tuploadSlug?: string\n}\n\n/**\n * Server-authoritative submission validation. On create it loads the referenced form, re-runs every\n * field's required check, intrinsic validator, and declarative rules through `runSubmission`, threading\n * `req`/`payload` so server-only async rules can hit the DB, and throws a Payload `ValidationError` with\n * per-field paths on any error-severity failure. The client is never trusted.\n * Consent fields are captured into `result.consent` (array of proofs, one per visible consent field).\n */\nexport const validateSubmission =\n\t({\n\t\tregistry,\n\t\truleRegistry,\n\t\tconsentRegistry,\n\t\tuploadSlug,\n\t}: ValidateSubmissionArgs): CollectionBeforeValidateHook =>\n\tasync ({ data, operation, req }) => {\n\t\tif (operation !== 'create' || !data) {\n\t\t\treturn data\n\t\t}\n\t\tconst formId = data.form\n\t\tif (formId == null) {\n\t\t\treturn data\n\t\t}\n\n\t\tconst form = await req.payload.findByID({\n\t\t\tcollection: FORMS_SLUG,\n\t\t\tid: formId as string | number,\n\t\t\tdepth: 0,\n\t\t\tlocale: req.locale,\n\t\t\treq,\n\t\t})\n\n\t\tconst fields = ((form.fields as FormFieldInstance[] | undefined) ?? []) as FormFieldInstance[]\n\t\tconst incoming = ((data.values as SubmissionValue[] | undefined) ?? []) as SubmissionValue[]\n\t\tconst locale = req.locale ?? 'en'\n\t\tconst t = asFieldTranslate(req.i18n.t)\n\t\tconst expectedOwner =\n\t\t\ttypeof req.context?.[IDENTITY_CONTEXT_KEY] === 'string'\n\t\t\t\t? (req.context[IDENTITY_CONTEXT_KEY] as string)\n\t\t\t\t: undefined\n\n\t\tconst result = await runSubmission({\n\t\t\tfields,\n\t\t\tvalues: incoming,\n\t\t\tregistry,\n\t\t\truleRegistry,\n\t\t\tconsentRegistry,\n\t\t\tlocale,\n\t\t\tt,\n\t\t\toperation: 'create',\n\t\t\treq,\n\t\t\tpayload: req.payload,\n\t\t\tformId: formId as number | string,\n\t\t\tuploadSlug,\n\t\t\texpectedOwner,\n\t\t})\n\n\t\tif (result.errors.length > 0) {\n\t\t\tthrow new ValidationError({ collection: FORM_SUBMISSIONS_SLUG, errors: result.errors }, req.t)\n\t\t}\n\n\t\tdata.values = result.values\n\t\tdata.descriptors = result.descriptors\n\t\tdata.consent = result.consent.length > 0 ? result.consent : undefined\n\t\tdata.locale = locale\n\t\treturn data\n\t}\n","import type { CollectionAfterChangeHook, CollectionConfig } from 'payload'\nimport { dispatchActions } from '../actions/dispatch'\nimport type { ActionRegistry } from '../actions/registry'\nimport type { ActionInstance } from '../actions/runActions'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport { resolveEventSink } from '../events/resolveEventSink'\nimport type { FormEventSink } from '../events/types'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport { buildSpamGuard } from '../spam/spamGuard'\nimport type { ResolvedSpamConfig } from '../spam/types'\nimport { validateSubmission } from '../submissions/validateSubmission'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport { FORMS_SLUG } from './forms'\n\nexport const FORM_SUBMISSIONS_SLUG = 'form-submissions'\n\ntype BuildSubmissionsCollectionArgs = {\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tconsentRegistry: ConsentSourceRegistry\n\tactionRegistry?: ActionRegistry\n\tevents?: FormEventSink\n\t/** Whether a job runner is likely present; gates the queued vs bounded-inline dispatch path. */\n\thasRunner?: boolean\n\t/** Upload collection slug for file fields without an explicit `relationTo`. */\n\tuploadSlug?: string\n\t/** Resolved spam config; when active, prepends the spam guard before validation. `false` disables it. */\n\tspam?: ResolvedSpamConfig | false\n}\n\nconst formIdOf = (form: unknown): number | string | undefined => {\n\tif (typeof form === 'number' || typeof form === 'string') {\n\t\treturn form\n\t}\n\tif (form && typeof form === 'object' && 'id' in form) {\n\t\tconst id = (form as { id: unknown }).id\n\t\tif (typeof id === 'number' || typeof id === 'string') {\n\t\t\treturn id\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * On a completed submission create, dispatch the form's post-submit actions and emit `submission.created`.\n * Both are side effects on an already-written row, so the whole body is wrapped: nothing it does can throw\n * past the hook (a failed action or sink must never fail the submission write). Dispatch is itself bounded\n * and non-throwing; the inline fallback is awaited so the bound caps the added latency, while the queued\n * path returns immediately. The form's `actions` are null-guarded for legacy rows created before the field\n * existed.\n */\nconst makeAfterChange =\n\t(args: {\n\t\tactionRegistry: ActionRegistry\n\t\tevents?: FormEventSink\n\t\thasRunner: boolean\n\t}): CollectionAfterChangeHook =>\n\tasync ({ doc, operation, req }) => {\n\t\tif (operation !== 'create' || (doc.status != null && doc.status !== 'complete')) {\n\t\t\treturn doc\n\t\t}\n\t\tconst { payload } = req\n\t\ttry {\n\t\t\tconst formId = formIdOf(doc.form)\n\t\t\tif (formId == null) {\n\t\t\t\treturn doc\n\t\t\t}\n\t\t\tconst form = await payload\n\t\t\t\t.findByID({ collection: FORMS_SLUG, id: formId, depth: 0, overrideAccess: true, req })\n\t\t\t\t.catch(() => null)\n\n\t\t\tawait dispatchActions({\n\t\t\t\tactions: (form?.actions ?? null) as ActionInstance[] | null,\n\t\t\t\tformId,\n\t\t\t\tsubmissionId: doc.id as number | string,\n\t\t\t\tregistry: args.actionRegistry,\n\t\t\t\tpayload,\n\t\t\t\treq,\n\t\t\t\thasRunner: args.hasRunner,\n\t\t\t})\n\n\t\t\ttry {\n\t\t\t\tawait resolveEventSink(args.events).emit({\n\t\t\t\t\ttype: 'submission.created',\n\t\t\t\t\tformId: String(formId),\n\t\t\t\t\tsubmissionId: String(doc.id),\n\t\t\t\t\tat: new Date().toISOString(),\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tpayload.logger?.error(\n\t\t\t\t\t`@10x-media/form-builder: submission.created sink threw: ${\n\t\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t\t}`\n\t\t\t\t)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tpayload.logger?.error(\n\t\t\t\t`@10x-media/form-builder: afterChange dispatch failed for submission ${String(doc.id)}: ${\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t}`\n\t\t\t)\n\t\t}\n\t\treturn doc\n\t}\n\nexport const buildSubmissionsCollection = ({\n\tregistry,\n\truleRegistry,\n\tconsentRegistry,\n\tactionRegistry = new Map(),\n\tevents,\n\thasRunner = false,\n\tuploadSlug,\n\tspam,\n}: BuildSubmissionsCollectionArgs): CollectionConfig => ({\n\tslug: FORM_SUBMISSIONS_SLUG,\n\tlabels: { singular: 'Submission', plural: 'Submissions' },\n\tadmin: { group: 'Forms' },\n\taccess: {\n\t\tcreate: () => true,\n\t\tread: ({ req }) => Boolean(req.user),\n\t\tupdate: () => false,\n\t},\n\thooks: {\n\t\tbeforeValidate: [\n\t\t\t...(spam ? [buildSpamGuard(spam)] : []),\n\t\t\tvalidateSubmission({ registry, ruleRegistry, consentRegistry, uploadSlug }),\n\t\t],\n\t\tafterChange: [makeAfterChange({ actionRegistry, events, hasRunner })],\n\t},\n\tfields: [\n\t\t{ name: 'form', type: 'relationship', relationTo: FORMS_SLUG, required: true },\n\t\t{\n\t\t\tname: 'status',\n\t\t\ttype: 'select',\n\t\t\tdefaultValue: 'complete',\n\t\t\toptions: [\n\t\t\t\t{ label: 'Complete', value: 'complete' },\n\t\t\t\t{ label: 'Partial', value: 'partial' },\n\t\t\t],\n\t\t},\n\t\t{ name: 'locale', type: 'text' },\n\t\t{ name: 'values', type: 'json' },\n\t\t{ name: 'descriptors', type: 'json' },\n\t\t{ name: 'consent', type: 'json' },\n\t\t{ name: 'meta', type: 'json' },\n\t\t{\n\t\t\tname: 'answers',\n\t\t\ttype: 'ui',\n\t\t\tadmin: {\n\t\t\t\tcomponents: { Field: '@10x-media/form-builder/rsc#SubmissionAnswers' },\n\t\t\t},\n\t\t},\n\t],\n})\n","import type { ActionRunArgs } from './defineAction'\nimport type { ActionRegistry } from './registry'\n\n/** A stored action instance from the form's `actions` blocks array. */\nexport type ActionInstance = { blockType: string; [key: string]: unknown }\n\nexport type ActionResult = { type: string; ok: boolean; error?: string }\n\nexport type RunActionsArgs = Omit<ActionRunArgs, 'config'> & {\n\tactions: ActionInstance[]\n\tregistry: ActionRegistry\n}\n\n/**\n * Run each configured action, isolating failures: a throwing action is captured as a failed result\n * and never breaks the others or the caller.\n */\nexport const runActions = async (args: RunActionsArgs): Promise<ActionResult[]> => {\n\tconst { actions, registry, ...ctx } = args\n\tconst results: ActionResult[] = []\n\tfor (const instance of actions) {\n\t\tconst definition = registry.get(instance.blockType)\n\t\tif (!definition) {\n\t\t\tcontinue\n\t\t}\n\t\ttry {\n\t\t\tawait definition.run({ ...ctx, config: instance })\n\t\t\tresults.push({ type: instance.blockType, ok: true })\n\t\t} catch (error) {\n\t\t\tresults.push({\n\t\t\t\ttype: instance.blockType,\n\t\t\t\tok: false,\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t})\n\t\t}\n\t}\n\treturn results\n}\n","import type { Config, Payload, PayloadRequest, TaskConfig } from 'payload'\nimport { FORM_SUBMISSIONS_SLUG } from '../collections/formSubmissions'\nimport { FORMS_SLUG } from '../collections/forms'\nimport type { Translate } from '../fields/types'\nimport type { SubmissionDescriptor, SubmissionValue } from '../submissions/types'\nimport { asFieldTranslate } from '../translations/server'\nimport type { ActionRegistry } from './registry'\nimport type { ActionInstance } from './runActions'\nimport { runActions } from './runActions'\n\nexport const ACTIONS_TASK_SLUG = 'form-builder-actions'\n\n/** Input the dispatch path enqueues; the handler re-loads everything else from the DB. */\nexport type ActionsTaskInput = { formId: number | string; submissionId: number | string }\n\nconst asActions = (value: unknown): ActionInstance[] =>\n\tArray.isArray(value) ? (value as ActionInstance[]) : []\n\nconst asValues = (value: unknown): SubmissionValue[] =>\n\tArray.isArray(value) ? (value as SubmissionValue[]) : []\n\nconst asDescriptors = (value: unknown): SubmissionDescriptor[] =>\n\tArray.isArray(value) ? (value as SubmissionDescriptor[]) : []\n\n/**\n * Load the form and submission by id and run the form's actions through the shared, failure-isolating\n * `runActions`. Tolerates a missing form or submission (the row may have been deleted between enqueue and\n * run) by returning early. Used by both the queued task handler and the inline fallback.\n */\nexport const runActionsForSubmission = async (args: {\n\tinput: ActionsTaskInput\n\tregistry: ActionRegistry\n\tpayload: Payload\n\treq?: PayloadRequest\n}): Promise<void> => {\n\tconst { input, registry, payload, req } = args\n\tconst form = await payload\n\t\t.findByID({\n\t\t\tcollection: FORMS_SLUG,\n\t\t\tid: input.formId,\n\t\t\tdepth: 0,\n\t\t\toverrideAccess: true,\n\t\t\treq,\n\t\t})\n\t\t.catch(() => null)\n\tif (!form) {\n\t\treturn\n\t}\n\tconst submission = await payload\n\t\t.findByID({\n\t\t\tcollection: FORM_SUBMISSIONS_SLUG,\n\t\t\tid: input.submissionId,\n\t\t\tdepth: 0,\n\t\t\toverrideAccess: true,\n\t\t\treq,\n\t\t})\n\t\t.catch(() => null)\n\tif (!submission) {\n\t\treturn\n\t}\n\n\tconst locale = typeof submission.locale === 'string' ? submission.locale : (req?.locale ?? 'en')\n\tconst t: Translate = asFieldTranslate(req?.i18n?.t ?? ((key: string) => key))\n\n\tawait runActions({\n\t\tactions: asActions(form.actions),\n\t\tregistry,\n\t\tform: { id: form.id, title: typeof form.title === 'string' ? form.title : undefined },\n\t\tsubmissionId: submission.id,\n\t\tvalues: asValues(submission.values),\n\t\tdescriptors: asDescriptors(submission.descriptors),\n\t\tpayload,\n\t\treq,\n\t\tlocale,\n\t\tt,\n\t})\n}\n\n/** Native Payload jobs task that runs a submission's post-submit actions out of band. */\nexport const buildActionsTask = (registry: ActionRegistry): TaskConfig =>\n\t({\n\t\tslug: ACTIONS_TASK_SLUG,\n\t\tinputSchema: [\n\t\t\t{ name: 'formId', type: 'text', required: true },\n\t\t\t{ name: 'submissionId', type: 'text', required: true },\n\t\t],\n\t\thandler: async ({ input, req }) => {\n\t\t\tawait runActionsForSubmission({\n\t\t\t\tinput: input as ActionsTaskInput,\n\t\t\t\tregistry,\n\t\t\t\tpayload: req.payload,\n\t\t\t\treq,\n\t\t\t})\n\t\t\treturn { output: {} }\n\t\t},\n\t}) as TaskConfig\n\n/** Register the actions task on `config.jobs.tasks`, creating the jobs config if absent. */\nexport const registerActionsTask = (config: Config, registry: ActionRegistry): void => {\n\tconfig.jobs ??= {}\n\tconfig.jobs.tasks ??= []\n\tconfig.jobs.tasks.push(buildActionsTask(registry))\n}\n","import {\n\tAPIError,\n\ttype CollectionBeforeOperationHook,\n\ttype CollectionBeforeValidateHook,\n} from 'payload'\nimport { keys } from '../translations/keys'\nimport { asTranslate } from '../translations/server'\nimport type { ResolvedSpamConfig } from './types'\n\n/**\n * Stamp the resolved request identity onto a new upload's `owner`. `captureFileRef` later requires the\n * referencing submission's identity to match, so an anonymous submitter cannot capture another identity's\n * upload. No identity (no user, no trusted IP header) means no stamp, so the upload stays unscoped (a\n * deliberate fail-open; identity granularity is IP-level, so same-network clients share scope -- documented).\n */\nexport const buildUploadOwnerStamp =\n\t(spam: ResolvedSpamConfig): CollectionBeforeValidateHook =>\n\tasync ({ data, operation, req }) => {\n\t\tif (operation !== 'create' || !data) {\n\t\t\treturn data\n\t\t}\n\t\tconst identity = await spam.identify(req)\n\t\tif (identity != null && (data as { owner?: unknown }).owner == null) {\n\t\t\t;(data as { owner?: string }).owner = identity\n\t\t}\n\t\treturn data\n\t}\n\n/** Reject upload floods per identity before the file is written to `staticDir`. Fail-open without identity. */\nexport const buildUploadRateLimit =\n\t(spam: ResolvedSpamConfig): CollectionBeforeOperationHook =>\n\tasync ({ operation, req }) => {\n\t\tif (operation !== 'create' || spam.uploadRateLimit === false) {\n\t\t\treturn\n\t\t}\n\t\tconst identity = await spam.identify(req)\n\t\tif (identity == null) {\n\t\t\treturn\n\t\t}\n\t\tconst { ok } = await spam.uploadRateLimit.limiter.check({\n\t\t\tkey: `uploads:${identity}`,\n\t\t\tmax: spam.uploadRateLimit.max,\n\t\t\twindow: spam.uploadRateLimit.window,\n\t\t\treq,\n\t\t})\n\t\tif (!ok) {\n\t\t\tthrow new APIError(asTranslate(req.i18n.t)(keys.spamRateLimited), 429)\n\t\t}\n\t}\n","import type { CollectionConfig, Config } from 'payload'\nimport type { ActionRegistry } from '../actions/registry'\nimport { registerActionsTask } from '../actions/task'\nimport { buildSubmissionsCollection } from '../collections/formSubmissions'\nimport { buildFormsCollection } from '../collections/forms'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport type { FormEventSink } from '../events/types'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport type { PresentationDescriptorRegistry } from '../presentations/registry'\nimport type { ResolvedSpamConfig } from '../spam/types'\nimport { buildUploadOwnerStamp, buildUploadRateLimit } from '../spam/uploadHooks'\nimport type { ValidationRuleRegistry } from '../validation/registry'\n\ntype RegisterCollectionsArgs = {\n\tconfig: Config\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tconsentRegistry: ConsentSourceRegistry\n\tpresentationRegistry: PresentationDescriptorRegistry\n\tactionRegistry: ActionRegistry\n\thasJobsPlugin: boolean\n\tevents?: FormEventSink\n\tuploads: { enabled: boolean; slug: string; collection?: CollectionConfig }\n\tspam: ResolvedSpamConfig | false\n}\n\nexport const registerCollections = ({\n\tconfig,\n\tregistry,\n\truleRegistry,\n\tconsentRegistry,\n\tpresentationRegistry,\n\tactionRegistry,\n\thasJobsPlugin,\n\tevents,\n\tuploads,\n\tspam,\n}: RegisterCollectionsArgs): void => {\n\tregisterActionsTask(config, actionRegistry)\n\tconst hasRunner = Boolean(config.jobs?.autoRun) || hasJobsPlugin\n\tif (spam && uploads.enabled && uploads.collection) {\n\t\tconst collection = uploads.collection\n\t\tcollection.hooks = collection.hooks ?? {}\n\t\tcollection.hooks.beforeOperation = [\n\t\t\t...(collection.hooks.beforeOperation ?? []),\n\t\t\tbuildUploadRateLimit(spam),\n\t\t]\n\t\tcollection.hooks.beforeValidate = [\n\t\t\t...(collection.hooks.beforeValidate ?? []),\n\t\t\tbuildUploadOwnerStamp(spam),\n\t\t]\n\t}\n\tconfig.collections = [\n\t\t...(config.collections ?? []),\n\t\t...(uploads.enabled && uploads.collection ? [uploads.collection] : []),\n\t\tbuildFormsCollection({ registry, ruleRegistry, presentationRegistry, actionRegistry }),\n\t\tbuildSubmissionsCollection({\n\t\t\tregistry,\n\t\t\truleRegistry,\n\t\t\tconsentRegistry,\n\t\t\tactionRegistry,\n\t\t\tevents,\n\t\t\thasRunner,\n\t\t\tuploadSlug: uploads.slug,\n\t\t\tspam,\n\t\t}),\n\t]\n}\n","import type { Config } from 'payload'\nimport { deepMergeSimple } from 'payload/shared'\n\nimport { translations } from '../translations'\n\ntype Translations = NonNullable<NonNullable<Config['i18n']>['translations']>\n\n/**\n * Merge this plugin's translations into the host config. A host value wins on\n * conflict (`deepMergeSimple` lets the second argument override), so projects can\n * override any string.\n */\nexport const registerTranslations = (config: Config): void => {\n\tconfig.i18n ??= {}\n\tconfig.i18n.translations = deepMergeSimple<Translations>(\n\t\ttranslations,\n\t\tconfig.i18n.translations ?? {}\n\t)\n}\n","import type { PresentationDescriptor } from './types'\n\nexport type PresentationDescriptorRegistry = Map<string, PresentationDescriptor>\n\n/** Per-name override: `false` removes, `true` keeps the default, a descriptor adds or replaces one. */\nexport type PresentationDescriptorOption = boolean | PresentationDescriptor\n\nexport type PresentationsDescriptorConfig = Record<string, PresentationDescriptorOption>\n\n/**\n * Resolve the active presentation descriptors from the defaults and a consumer override map.\n * Mirrors the field-type, validation-rule, and renderer registry convention.\n */\nexport const resolvePresentationDescriptors = (\n\tdefaults: Record<string, PresentationDescriptor>,\n\tconfig: PresentationsDescriptorConfig = {}\n): PresentationDescriptorRegistry => {\n\tconst registry: PresentationDescriptorRegistry = new Map(Object.entries(defaults))\n\tfor (const [name, option] of Object.entries(config)) {\n\t\tif (option === false) {\n\t\t\tregistry.delete(name)\n\t\t} else if (option === true) {\n\t\t\t// keep the default; no-op when no default exists for this name\n\t\t} else {\n\t\t\tregistry.set(name, option)\n\t\t}\n\t}\n\treturn registry\n}\n","import type { IdentifyFn } from './types'\n\n/**\n * Default identity resolution for rate-limiting + upload ownership. Prefers an authenticated user id\n * (trustworthy); else the first hop of the configured trusted IP header (best-effort, proxy-dependent);\n * else null, in which case the caller fails open (cannot fairly rate-limit an unidentifiable client).\n */\nexport const defaultIdentify =\n\t(ipHeader: string): IdentifyFn =>\n\t(req) => {\n\t\tconst userId = req.user?.id\n\t\tif (userId != null) {\n\t\t\treturn `user:${String(userId)}`\n\t\t}\n\t\tconst header = req.headers?.get(ipHeader)\n\t\tif (header) {\n\t\t\tconst first = header.split(',')[0]?.trim()\n\t\t\tif (first) {\n\t\t\t\treturn `ip:${first}`\n\t\t\t}\n\t\t}\n\t\treturn null\n\t}\n","import type { RateLimiter } from './types'\n\ntype WindowState = { count: number; windowStart: number }\n\n/**\n * The default rate limiter: a read-modify-write window counter over Payload's `payload.kv`\n * (always present; default `DatabaseKVAdapter`, durable + cross-instance). Because the KV interface\n * has no atomic increment, the get-then-set is NON-ATOMIC, so a concurrent burst can slightly undercount.\n * This is a SOFT limit, acceptable for spam basics and complemented by edge/WAF limiting. The window\n * expires lazily on read; stale keys for one-time identities linger (minor; the count self-resets).\n * `now` is injectable for tests.\n */\nexport const createKvRateLimiter = (\n\toptions: { now?: () => number; namespace?: string } = {}\n): RateLimiter => {\n\tconst now = options.now ?? (() => Date.now())\n\tconst prefix = options.namespace ?? 'fb:rl:'\n\treturn {\n\t\tasync check({ key, max, window, req }) {\n\t\t\tconst kv = req.payload.kv\n\t\t\tconst storeKey = `${prefix}${key}`\n\t\t\tconst current = now()\n\t\t\tconst existing = await kv.get<WindowState>(storeKey).catch(() => null)\n\t\t\tlet count: number\n\t\t\tlet windowStart: number\n\t\t\tif (!existing || current - existing.windowStart >= window) {\n\t\t\t\tcount = 1\n\t\t\t\twindowStart = current\n\t\t\t} else {\n\t\t\t\tcount = existing.count + 1\n\t\t\t\twindowStart = existing.windowStart\n\t\t\t}\n\t\t\tawait kv.set(storeKey, { count, windowStart }).catch(() => undefined)\n\t\t\treturn {\n\t\t\t\tok: count <= max,\n\t\t\t\tremaining: Math.max(0, max - count),\n\t\t\t\tresetAt: windowStart + window,\n\t\t\t}\n\t\t},\n\t}\n}\n","import { DEFAULT_HONEYPOT_FIELD } from './constants'\nimport { defaultIdentify } from './identify'\nimport { createKvRateLimiter } from './rateLimiter'\nimport type {\n\tRateLimitConfig,\n\tResolvedRateLimit,\n\tResolvedSpamConfig,\n\tSpamConfig,\n\tSpamOption,\n} from './types'\n\nconst DEFAULT_WINDOW = 60_000\nconst DEFAULT_SUBMISSION_MAX = 5\nconst DEFAULT_UPLOAD_MAX = 20\n\nconst resolveRateLimit = (\n\toption: false | RateLimitConfig | undefined,\n\tdefaultMax: number\n): false | ResolvedRateLimit => {\n\tif (option === false) {\n\t\treturn false\n\t}\n\tconst cfg = option ?? {}\n\treturn {\n\t\twindow: cfg.window ?? DEFAULT_WINDOW,\n\t\tmax: cfg.max ?? defaultMax,\n\t\tlimiter: cfg.limiter ?? createKvRateLimiter(),\n\t}\n}\n\n/**\n * Resolve the `spam` plugin option into a concrete config. `false` disables the whole subsystem.\n * Otherwise honeypot + both rate limits default on, captcha + metadata capture default off, and the\n * identity seam defaults to user id / trusted IP header.\n */\nexport const resolveSpamConfig = (option: SpamOption | undefined): ResolvedSpamConfig | false => {\n\tif (option === false) {\n\t\treturn false\n\t}\n\tconst cfg: SpamConfig = option ?? {}\n\tconst ipHeader = cfg.ipHeader ?? 'x-forwarded-for'\n\treturn {\n\t\thoneypot:\n\t\t\tcfg.honeypot === false\n\t\t\t\t? false\n\t\t\t\t: { fieldName: cfg.honeypot?.fieldName ?? DEFAULT_HONEYPOT_FIELD },\n\t\trateLimit: resolveRateLimit(cfg.rateLimit, DEFAULT_SUBMISSION_MAX),\n\t\tuploadRateLimit: resolveRateLimit(cfg.uploadRateLimit, DEFAULT_UPLOAD_MAX),\n\t\tcaptcha: cfg.captcha,\n\t\tidentify: cfg.identify ?? defaultIdentify(ipHeader),\n\t\tipHeader,\n\t\tmetadata: { ip: cfg.metadata?.ip ?? false, ua: cfg.metadata?.ua ?? false },\n\t}\n}\n","import type { CaptchaProvider } from './types'\n\n/**\n * Identity helper for authoring a captcha provider (mirrors `defineAction`/`defineConsentSource`).\n * v1 ships no built-in provider; a project supplies one (Turnstile/reCAPTCHA/hCaptcha) and the submit\n * path verifies a token carried on the submission. Prebuilt providers are a v1.x addition.\n */\nexport const defineCaptchaProvider = (provider: CaptchaProvider): CaptchaProvider => provider\n","import { type Config, definePlugin } from 'payload'\nimport { defaultActionDefinitions } from './actions/builtin'\nimport type { ActionsConfig } from './actions/registry'\nimport { resolveActions } from './actions/registry'\nimport { resolveUploads, type UploadsOption } from './collections/uploads'\nimport { defaultConsentSources } from './consent/builtin'\nimport type { ConsentSourcesConfig } from './consent/registry'\nimport { resolveConsentSources } from './consent/registry'\nimport type { FormEventSink } from './events/types'\nimport { defaultFieldDefinitions } from './fields/builtin'\nimport { type FieldTypesConfig, resolveFieldTypes } from './fields/registry'\nimport { registerCollections } from './plugin/registerCollections'\nimport { registerTranslations } from './plugin/registerTranslations'\nimport { defaultPresentationDescriptors } from './presentations/defaults'\nimport type { PresentationsDescriptorConfig } from './presentations/registry'\nimport { resolvePresentationDescriptors } from './presentations/registry'\nimport { resolveSpamConfig } from './spam/resolveSpam'\nimport type { SpamOption } from './spam/types'\nimport { defaultValidationRules } from './validation/builtin'\nimport { resolveValidationRules, type ValidationRulesConfig } from './validation/registry'\n\nexport type FormBuilderPluginOptions = {\n\tdisabled?: boolean\n\t/** Pluggable sink for form lifecycle events. Defaults to a no-op; analytics adapters or a future analytics plugin subscribe here. */\n\tevents?: FormEventSink\n\t/** Add, override, or remove field types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tfields?: FieldTypesConfig\n\t/** Add, override, or remove presentations. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tpresentations?: PresentationsDescriptorConfig\n\t/** Add, override, or remove validation rule types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\trules?: ValidationRulesConfig\n\t/** Add, override, or remove post-submit action types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tactions?: ActionsConfig\n\t/** Add, override, or remove consent source types. `false` removes a built-in, `true` keeps it, an object adds or replaces one. */\n\tconsentSources?: ConsentSourcesConfig\n\t/** The built-in `form-uploads` collection backing file fields. `false` disables it (bring your own); an object overrides slug/upload/access/fields. */\n\tuploads?: UploadsOption\n\t/** Honeypot + rate-limiting (on by default) + a captcha adapter seam + upload-ownership scoping. `false` disables the whole subsystem. */\n\tspam?: SpamOption\n}\n\ndeclare module 'payload' {\n\tinterface RegisteredPlugins {\n\t\t'@10x-media/form-builder': FormBuilderPluginOptions\n\t}\n}\n\nexport const formBuilder = definePlugin<FormBuilderPluginOptions>({\n\tslug: '@10x-media/form-builder',\n\torder: 50,\n\tplugin: ({ config, plugins, ...options }): Config => {\n\t\tif (options.disabled === true) {\n\t\t\treturn config\n\t\t}\n\t\tconst registry = resolveFieldTypes(defaultFieldDefinitions, options.fields)\n\t\tconst ruleRegistry = resolveValidationRules(defaultValidationRules, options.rules)\n\t\tconst consentRegistry = resolveConsentSources(defaultConsentSources, options.consentSources)\n\t\tconst presentationRegistry = resolvePresentationDescriptors(\n\t\t\tdefaultPresentationDescriptors,\n\t\t\toptions.presentations\n\t\t)\n\t\tconst actionRegistry = resolveActions(defaultActionDefinitions, options.actions)\n\t\tconst uploads = resolveUploads(options.uploads)\n\t\tconst spam = resolveSpamConfig(options.spam)\n\t\tregisterTranslations(config)\n\t\tregisterCollections({\n\t\t\tconfig,\n\t\t\tregistry,\n\t\t\truleRegistry,\n\t\t\tconsentRegistry,\n\t\t\tpresentationRegistry,\n\t\t\tactionRegistry,\n\t\t\thasJobsPlugin: Boolean(plugins['@10x-media/jobs']),\n\t\t\tevents: options.events,\n\t\t\tuploads,\n\t\t\tspam,\n\t\t})\n\t\treturn config\n\t},\n})\n\nexport { defaultActionDefinitions } from './actions/builtin'\nexport type { ActionDefinition, ActionRunArgs, AnyActionDefinition } from './actions/defineAction'\nexport { defineAction } from './actions/defineAction'\nexport type { ActionOption, ActionRegistry, ActionsConfig } from './actions/registry'\nexport { resolveActions } from './actions/registry'\nexport type { ActionResult } from './actions/runActions'\nexport { SIGNATURE_HEADER, signPayload } from './actions/sign'\nexport type {\n\tAggregateFieldResponsesArgs,\n\tAggregateFormResponsesArgs,\n} from './aggregation/aggregateResponses'\nexport {\n\taggregateFieldResponses,\n\taggregateFormResponses,\n\tfieldHasOptions,\n} from './aggregation/aggregateResponses'\nexport { aggregateRowForField, aggregateRowsForFields } from './aggregation/aggregateRows'\nexport type {\n\tResolveResultsRequestArgs,\n\tResolveResultsRequestResult,\n} from './aggregation/resolveResultsRequest'\nexport { resolveFormResultsRequest } from './aggregation/resolveResultsRequest'\nexport type {\n\tAggregationBucket,\n\tAggregationRow,\n\tFieldAggregation,\n\tFieldMeta,\n\tSubmissionStatusFilter,\n} from './aggregation/types'\nexport { calcExpressionOf, computeCalcFields } from './calc/computeCalcFields'\nexport { evaluateCalc } from './calc/evaluate'\nexport { normalizeCalc } from './calc/normalizeCalc'\nexport type { CalcExpression } from './calc/types'\nexport type { UploadsCollectionConfig, UploadsOption } from './collections/uploads'\nexport { buildUploadsCollection, FORM_UPLOADS_SLUG, resolveUploads } from './collections/uploads'\nexport { evaluateCondition } from './conditions/evaluate'\nexport type { FieldCondition } from './conditions/types'\nexport { defaultConsentSources } from './consent/builtin'\nexport type { ConsentProof } from './consent/captureConsent'\nexport { captureConsent } from './consent/captureConsent'\nexport type {\n\tAnyConsentSource,\n\tConsentLink,\n\tConsentResolveArgs,\n\tConsentResolved,\n\tConsentSource,\n} from './consent/defineConsentSource'\nexport { defineConsentSource } from './consent/defineConsentSource'\nexport type {\n\tConsentSourceOption,\n\tConsentSourceRegistry,\n\tConsentSourcesConfig,\n} from './consent/registry'\nexport { resolveConsentSources } from './consent/registry'\nexport { resolveConsentLinks } from './consent/resolveConsentLinks'\nexport { resolvePublishedVersionRef } from './consent/resolvePublishedVersionRef'\nexport { defineFormField } from './fields/defineFormField'\nexport type { FieldTypeOption, FieldTypeRegistry, FieldTypesConfig } from './fields/registry'\nexport type {\n\tAnyFormFieldDefinition,\n\tFormFieldDefinition,\n\tFormFieldFormat,\n\tFormFieldValidate,\n\tFormFieldValueKind,\n} from './fields/types'\nexport type { PrefillOptions } from './prefill/valuesFromSearchParams'\nexport { valuesFromSearchParams } from './prefill/valuesFromSearchParams'\nexport { DEFAULT_PRESENTATION_NAME, defaultPresentationDescriptors } from './presentations/defaults'\nexport type {\n\tPresentationDescriptorOption,\n\tPresentationDescriptorRegistry,\n\tPresentationsDescriptorConfig,\n} from './presentations/registry'\nexport { resolvePresentationDescriptors } from './presentations/registry'\nexport type {\n\tPresentationDensity,\n\tPresentationDescriptor,\n\tPresentationSurface,\n} from './presentations/types'\nexport { interpolate } from './recall/interpolate'\nexport type { RecallResolver } from './recall/resolver'\nexport { buildRecallResolver, optionLabelsFor } from './recall/resolver'\nexport { defineCaptchaProvider } from './spam/captcha'\nexport { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD } from './spam/constants'\nexport { defaultIdentify } from './spam/identify'\nexport { createKvRateLimiter } from './spam/rateLimiter'\nexport { resolveSpamConfig } from './spam/resolveSpam'\nexport type {\n\tCaptchaProvider,\n\tCaptchaVerifyArgs,\n\tIdentifyFn,\n\tRateLimitCheckArgs,\n\tRateLimitConfig,\n\tRateLimiter,\n\tRateLimitResult,\n\tSpamConfig,\n\tSpamMetadataConfig,\n\tSpamOption,\n} from './spam/types'\nexport { captureFileRef } from './uploads/captureFileRef'\nexport { resolveFileRef } from './uploads/resolveFileRef'\nexport type { FileFieldConfig, FileRef, FileRefError } from './uploads/types'\nexport { defineValidationRule } from './validation/defineValidationRule'\nexport type {\n\tValidationRuleOption,\n\tValidationRuleRegistry,\n\tValidationRulesConfig,\n} from './validation/registry'\nexport type {\n\tAnyValidationRuleDefinition,\n\tValidationRuleDefinition,\n\tValidationRuleResult,\n\tValidationSeverity,\n} from './validation/types'\nexport type { FormBuilderPluginOptions as PluginOptions }\n"],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ //#region src/translations/keys.ts
2
+ /**
3
+ * Typed translation keys. Lookups must go through these constants, not string
4
+ * literals (enforced by requireI18nKeysTyped.grit). Every key here must have a
5
+ * value in every locale (`en.ts`), or it is a type error.
6
+ */
7
+ const keys = {
8
+ pluginName: "formBuilder:pluginName",
9
+ fieldTitle: "formBuilder:fieldTitle",
10
+ fieldTypeText: "formBuilder:fieldType.text",
11
+ fieldTypeTextarea: "formBuilder:fieldType.textarea",
12
+ fieldTypeEmail: "formBuilder:fieldType.email",
13
+ fieldTypeNumber: "formBuilder:fieldType.number",
14
+ fieldTypeSelect: "formBuilder:fieldType.select",
15
+ fieldTypeCheckbox: "formBuilder:fieldType.checkbox",
16
+ configOptions: "formBuilder:config.options",
17
+ configOption: "formBuilder:config.option",
18
+ configOptionLabel: "formBuilder:config.optionLabel",
19
+ configOptionValue: "formBuilder:config.optionValue",
20
+ validationRequired: "formBuilder:validation.required",
21
+ validationEmail: "formBuilder:validation.email",
22
+ validationNumber: "formBuilder:validation.number",
23
+ validationSelect: "formBuilder:validation.select",
24
+ formatYes: "formBuilder:format.yes",
25
+ formatNo: "formBuilder:format.no",
26
+ configName: "formBuilder:config.name",
27
+ configLabel: "formBuilder:config.label",
28
+ configRequired: "formBuilder:config.required",
29
+ configWidth: "formBuilder:config.width",
30
+ configPlaceholder: "formBuilder:config.placeholder",
31
+ configDescription: "formBuilder:config.description",
32
+ configVisibleWhen: "formBuilder:config.visibleWhen",
33
+ configValidateWhen: "formBuilder:config.validateWhen",
34
+ submissionAnswers: "formBuilder:submission.answers",
35
+ submissionNoAnswers: "formBuilder:submission.noAnswers",
36
+ ruleMinLength: "formBuilder:rule.minLength.label",
37
+ ruleMaxLength: "formBuilder:rule.maxLength.label",
38
+ ruleMin: "formBuilder:rule.min.label",
39
+ ruleMax: "formBuilder:rule.max.label",
40
+ rulePattern: "formBuilder:rule.pattern.label",
41
+ ruleEmail: "formBuilder:rule.email.label",
42
+ ruleUrl: "formBuilder:rule.url.label",
43
+ ruleOneOf: "formBuilder:rule.oneOf.label",
44
+ ruleMatchesField: "formBuilder:rule.matchesField.label",
45
+ ruleNotAlreadySubmitted: "formBuilder:rule.notAlreadySubmitted.label",
46
+ ruleMinLengthMessage: "formBuilder:rule.minLength.message",
47
+ ruleMaxLengthMessage: "formBuilder:rule.maxLength.message",
48
+ ruleMinMessage: "formBuilder:rule.min.message",
49
+ ruleMaxMessage: "formBuilder:rule.max.message",
50
+ rulePatternMessage: "formBuilder:rule.pattern.message",
51
+ ruleEmailMessage: "formBuilder:rule.email.message",
52
+ ruleUrlMessage: "formBuilder:rule.url.message",
53
+ ruleOneOfMessage: "formBuilder:rule.oneOf.message",
54
+ ruleMatchesFieldMessage: "formBuilder:rule.matchesField.message",
55
+ ruleNotAlreadySubmittedMessage: "formBuilder:rule.notAlreadySubmitted.message",
56
+ ruleParamMin: "formBuilder:rule.param.min",
57
+ ruleParamMax: "formBuilder:rule.param.max",
58
+ ruleParamPattern: "formBuilder:rule.param.pattern",
59
+ ruleParamFlags: "formBuilder:rule.param.flags",
60
+ ruleParamValues: "formBuilder:rule.param.values",
61
+ ruleParamField: "formBuilder:rule.param.field",
62
+ validationsLabel: "formBuilder:validations.label",
63
+ validationMessageLabel: "formBuilder:validations.message",
64
+ validationSeverityLabel: "formBuilder:validations.severity",
65
+ validationSeverityError: "formBuilder:validations.severity.error",
66
+ validationSeverityWarning: "formBuilder:validations.severity.warning",
67
+ conditionAddCondition: "formBuilder:condition.addCondition",
68
+ conditionAddOr: "formBuilder:condition.addOr",
69
+ conditionAnd: "formBuilder:condition.and",
70
+ conditionOr: "formBuilder:condition.or",
71
+ conditionRemove: "formBuilder:condition.remove",
72
+ conditionNoFields: "formBuilder:condition.noFields",
73
+ conditionEmpty: "formBuilder:condition.empty",
74
+ conditionSelectField: "formBuilder:condition.selectField",
75
+ conditionValuePlaceholder: "formBuilder:condition.value",
76
+ conditionTrue: "formBuilder:condition.true",
77
+ conditionFalse: "formBuilder:condition.false",
78
+ configAdvanced: "formBuilder:config.advanced",
79
+ configHidden: "formBuilder:config.hidden",
80
+ fieldTypeCalculation: "formBuilder:fieldType.calculation",
81
+ configExpression: "formBuilder:config.expression",
82
+ configCalcDisplay: "formBuilder:config.calcDisplay",
83
+ configDefaultPresentation: "formBuilder:config.defaultPresentation",
84
+ presentationPage: "formBuilder:presentation.page",
85
+ presentationModal: "formBuilder:presentation.modal",
86
+ presentationDrawer: "formBuilder:presentation.drawer",
87
+ presentationInline: "formBuilder:presentation.inline",
88
+ actionEmailTeam: "formBuilder:action.emailTeam",
89
+ actionConfirmation: "formBuilder:action.confirmation",
90
+ actionSignedWebhook: "formBuilder:action.signedWebhook",
91
+ actionConfigTo: "formBuilder:action.config.to",
92
+ actionConfigSubject: "formBuilder:action.config.subject",
93
+ actionConfigBody: "formBuilder:action.config.body",
94
+ actionConfigToField: "formBuilder:action.config.toField",
95
+ actionConfigUrl: "formBuilder:action.config.url",
96
+ actionConfigSecret: "formBuilder:action.config.secret",
97
+ configActions: "formBuilder:config.actions",
98
+ consentSourceStatic: "formBuilder:consentSource.static",
99
+ consentSourcePageReference: "formBuilder:consentSource.pageReference",
100
+ consentConfigLabel: "formBuilder:consent.config.label",
101
+ consentConfigUrl: "formBuilder:consent.config.url",
102
+ consentConfigVersion: "formBuilder:consent.config.version",
103
+ consentConfigRelationTo: "formBuilder:consent.config.relationTo",
104
+ consentConfigDocId: "formBuilder:consent.config.docId",
105
+ consentConfigUrlField: "formBuilder:consent.config.urlField",
106
+ consentConfigCaptureVersion: "formBuilder:consent.config.captureVersion",
107
+ fieldTypeConsent: "formBuilder:fieldType.consent",
108
+ consentConfigStatement: "formBuilder:consent.config.statement",
109
+ consentConfigSource: "formBuilder:consent.config.source",
110
+ consentConfigSourceConfig: "formBuilder:consent.config.sourceConfig",
111
+ consentConfigOptional: "formBuilder:consent.config.optional",
112
+ resultsTitle: "formBuilder:results.title",
113
+ resultsResponses: "formBuilder:results.responses",
114
+ resultsNoResponses: "formBuilder:results.noResponses",
115
+ resultsTruncated: "formBuilder:results.truncated",
116
+ configShowResults: "formBuilder:config.showResults",
117
+ configResultsField: "formBuilder:config.resultsField",
118
+ validationFileMissing: "formBuilder:validation.file.missing",
119
+ validationFileMimeType: "formBuilder:validation.file.mimeType",
120
+ validationFileTooLarge: "formBuilder:validation.file.tooLarge",
121
+ fieldTypeFile: "formBuilder:fieldType.file",
122
+ fileConfigRelationTo: "formBuilder:file.config.relationTo",
123
+ fileConfigMimeTypes: "formBuilder:file.config.mimeTypes",
124
+ fileConfigMaxSize: "formBuilder:file.config.maxSize",
125
+ spamRateLimited: "formBuilder:spam.rateLimited",
126
+ spamRejected: "formBuilder:spam.rejected",
127
+ spamCaptchaFailed: "formBuilder:spam.captchaFailed"
128
+ };
129
+ //#endregion
130
+ export { keys as t };
131
+
132
+ //# sourceMappingURL=keys-N5xGiUsh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys-N5xGiUsh.js","names":[],"sources":["../src/translations/keys.ts"],"sourcesContent":["/**\n * Typed translation keys. Lookups must go through these constants, not string\n * literals (enforced by requireI18nKeysTyped.grit). Every key here must have a\n * value in every locale (`en.ts`), or it is a type error.\n */\nexport const keys = {\n\tpluginName: 'formBuilder:pluginName',\n\tfieldTitle: 'formBuilder:fieldTitle',\n\tfieldTypeText: 'formBuilder:fieldType.text',\n\tfieldTypeTextarea: 'formBuilder:fieldType.textarea',\n\tfieldTypeEmail: 'formBuilder:fieldType.email',\n\tfieldTypeNumber: 'formBuilder:fieldType.number',\n\tfieldTypeSelect: 'formBuilder:fieldType.select',\n\tfieldTypeCheckbox: 'formBuilder:fieldType.checkbox',\n\tconfigOptions: 'formBuilder:config.options',\n\tconfigOption: 'formBuilder:config.option',\n\tconfigOptionLabel: 'formBuilder:config.optionLabel',\n\tconfigOptionValue: 'formBuilder:config.optionValue',\n\tvalidationRequired: 'formBuilder:validation.required',\n\tvalidationEmail: 'formBuilder:validation.email',\n\tvalidationNumber: 'formBuilder:validation.number',\n\tvalidationSelect: 'formBuilder:validation.select',\n\tformatYes: 'formBuilder:format.yes',\n\tformatNo: 'formBuilder:format.no',\n\tconfigName: 'formBuilder:config.name',\n\tconfigLabel: 'formBuilder:config.label',\n\tconfigRequired: 'formBuilder:config.required',\n\tconfigWidth: 'formBuilder:config.width',\n\tconfigPlaceholder: 'formBuilder:config.placeholder',\n\tconfigDescription: 'formBuilder:config.description',\n\tconfigVisibleWhen: 'formBuilder:config.visibleWhen',\n\tconfigValidateWhen: 'formBuilder:config.validateWhen',\n\tsubmissionAnswers: 'formBuilder:submission.answers',\n\tsubmissionNoAnswers: 'formBuilder:submission.noAnswers',\n\truleMinLength: 'formBuilder:rule.minLength.label',\n\truleMaxLength: 'formBuilder:rule.maxLength.label',\n\truleMin: 'formBuilder:rule.min.label',\n\truleMax: 'formBuilder:rule.max.label',\n\trulePattern: 'formBuilder:rule.pattern.label',\n\truleEmail: 'formBuilder:rule.email.label',\n\truleUrl: 'formBuilder:rule.url.label',\n\truleOneOf: 'formBuilder:rule.oneOf.label',\n\truleMatchesField: 'formBuilder:rule.matchesField.label',\n\truleNotAlreadySubmitted: 'formBuilder:rule.notAlreadySubmitted.label',\n\truleMinLengthMessage: 'formBuilder:rule.minLength.message',\n\truleMaxLengthMessage: 'formBuilder:rule.maxLength.message',\n\truleMinMessage: 'formBuilder:rule.min.message',\n\truleMaxMessage: 'formBuilder:rule.max.message',\n\trulePatternMessage: 'formBuilder:rule.pattern.message',\n\truleEmailMessage: 'formBuilder:rule.email.message',\n\truleUrlMessage: 'formBuilder:rule.url.message',\n\truleOneOfMessage: 'formBuilder:rule.oneOf.message',\n\truleMatchesFieldMessage: 'formBuilder:rule.matchesField.message',\n\truleNotAlreadySubmittedMessage: 'formBuilder:rule.notAlreadySubmitted.message',\n\truleParamMin: 'formBuilder:rule.param.min',\n\truleParamMax: 'formBuilder:rule.param.max',\n\truleParamPattern: 'formBuilder:rule.param.pattern',\n\truleParamFlags: 'formBuilder:rule.param.flags',\n\truleParamValues: 'formBuilder:rule.param.values',\n\truleParamField: 'formBuilder:rule.param.field',\n\tvalidationsLabel: 'formBuilder:validations.label',\n\tvalidationMessageLabel: 'formBuilder:validations.message',\n\tvalidationSeverityLabel: 'formBuilder:validations.severity',\n\tvalidationSeverityError: 'formBuilder:validations.severity.error',\n\tvalidationSeverityWarning: 'formBuilder:validations.severity.warning',\n\tconditionAddCondition: 'formBuilder:condition.addCondition',\n\tconditionAddOr: 'formBuilder:condition.addOr',\n\tconditionAnd: 'formBuilder:condition.and',\n\tconditionOr: 'formBuilder:condition.or',\n\tconditionRemove: 'formBuilder:condition.remove',\n\tconditionNoFields: 'formBuilder:condition.noFields',\n\tconditionEmpty: 'formBuilder:condition.empty',\n\tconditionSelectField: 'formBuilder:condition.selectField',\n\tconditionValuePlaceholder: 'formBuilder:condition.value',\n\tconditionTrue: 'formBuilder:condition.true',\n\tconditionFalse: 'formBuilder:condition.false',\n\tconfigAdvanced: 'formBuilder:config.advanced',\n\tconfigHidden: 'formBuilder:config.hidden',\n\tfieldTypeCalculation: 'formBuilder:fieldType.calculation',\n\tconfigExpression: 'formBuilder:config.expression',\n\tconfigCalcDisplay: 'formBuilder:config.calcDisplay',\n\tconfigDefaultPresentation: 'formBuilder:config.defaultPresentation',\n\tpresentationPage: 'formBuilder:presentation.page',\n\tpresentationModal: 'formBuilder:presentation.modal',\n\tpresentationDrawer: 'formBuilder:presentation.drawer',\n\tpresentationInline: 'formBuilder:presentation.inline',\n\tactionEmailTeam: 'formBuilder:action.emailTeam',\n\tactionConfirmation: 'formBuilder:action.confirmation',\n\tactionSignedWebhook: 'formBuilder:action.signedWebhook',\n\tactionConfigTo: 'formBuilder:action.config.to',\n\tactionConfigSubject: 'formBuilder:action.config.subject',\n\tactionConfigBody: 'formBuilder:action.config.body',\n\tactionConfigToField: 'formBuilder:action.config.toField',\n\tactionConfigUrl: 'formBuilder:action.config.url',\n\tactionConfigSecret: 'formBuilder:action.config.secret',\n\tconfigActions: 'formBuilder:config.actions',\n\tconsentSourceStatic: 'formBuilder:consentSource.static',\n\tconsentSourcePageReference: 'formBuilder:consentSource.pageReference',\n\tconsentConfigLabel: 'formBuilder:consent.config.label',\n\tconsentConfigUrl: 'formBuilder:consent.config.url',\n\tconsentConfigVersion: 'formBuilder:consent.config.version',\n\tconsentConfigRelationTo: 'formBuilder:consent.config.relationTo',\n\tconsentConfigDocId: 'formBuilder:consent.config.docId',\n\tconsentConfigUrlField: 'formBuilder:consent.config.urlField',\n\tconsentConfigCaptureVersion: 'formBuilder:consent.config.captureVersion',\n\tfieldTypeConsent: 'formBuilder:fieldType.consent',\n\tconsentConfigStatement: 'formBuilder:consent.config.statement',\n\tconsentConfigSource: 'formBuilder:consent.config.source',\n\tconsentConfigSourceConfig: 'formBuilder:consent.config.sourceConfig',\n\tconsentConfigOptional: 'formBuilder:consent.config.optional',\n\tresultsTitle: 'formBuilder:results.title',\n\tresultsResponses: 'formBuilder:results.responses',\n\tresultsNoResponses: 'formBuilder:results.noResponses',\n\tresultsTruncated: 'formBuilder:results.truncated',\n\tconfigShowResults: 'formBuilder:config.showResults',\n\tconfigResultsField: 'formBuilder:config.resultsField',\n\tvalidationFileMissing: 'formBuilder:validation.file.missing',\n\tvalidationFileMimeType: 'formBuilder:validation.file.mimeType',\n\tvalidationFileTooLarge: 'formBuilder:validation.file.tooLarge',\n\tfieldTypeFile: 'formBuilder:fieldType.file',\n\tfileConfigRelationTo: 'formBuilder:file.config.relationTo',\n\tfileConfigMimeTypes: 'formBuilder:file.config.mimeTypes',\n\tfileConfigMaxSize: 'formBuilder:file.config.maxSize',\n\tspamRateLimited: 'formBuilder:spam.rateLimited',\n\tspamRejected: 'formBuilder:spam.rejected',\n\tspamCaptchaFailed: 'formBuilder:spam.captchaFailed',\n} as const\n\nexport type TranslationKey = (typeof keys)[keyof typeof keys]\n"],"mappings":";;;;;;AAKA,MAAa,OAAO;CACnB,YAAY;CACZ,YAAY;CACZ,eAAe;CACf,mBAAmB;CACnB,gBAAgB;CAChB,iBAAiB;CACjB,iBAAiB;CACjB,mBAAmB;CACnB,eAAe;CACf,cAAc;CACd,mBAAmB;CACnB,mBAAmB;CACnB,oBAAoB;CACpB,iBAAiB;CACjB,kBAAkB;CAClB,kBAAkB;CAClB,WAAW;CACX,UAAU;CACV,YAAY;CACZ,aAAa;CACb,gBAAgB;CAChB,aAAa;CACb,mBAAmB;CACnB,mBAAmB;CACnB,mBAAmB;CACnB,oBAAoB;CACpB,mBAAmB;CACnB,qBAAqB;CACrB,eAAe;CACf,eAAe;CACf,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,SAAS;CACT,WAAW;CACX,kBAAkB;CAClB,yBAAyB;CACzB,sBAAsB;CACtB,sBAAsB;CACtB,gBAAgB;CAChB,gBAAgB;CAChB,oBAAoB;CACpB,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,yBAAyB;CACzB,gCAAgC;CAChC,cAAc;CACd,cAAc;CACd,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,kBAAkB;CAClB,wBAAwB;CACxB,yBAAyB;CACzB,yBAAyB;CACzB,2BAA2B;CAC3B,uBAAuB;CACvB,gBAAgB;CAChB,cAAc;CACd,aAAa;CACb,iBAAiB;CACjB,mBAAmB;CACnB,gBAAgB;CAChB,sBAAsB;CACtB,2BAA2B;CAC3B,eAAe;CACf,gBAAgB;CAChB,gBAAgB;CAChB,cAAc;CACd,sBAAsB;CACtB,kBAAkB;CAClB,mBAAmB;CACnB,2BAA2B;CAC3B,kBAAkB;CAClB,mBAAmB;CACnB,oBAAoB;CACpB,oBAAoB;CACpB,iBAAiB;CACjB,oBAAoB;CACpB,qBAAqB;CACrB,gBAAgB;CAChB,qBAAqB;CACrB,kBAAkB;CAClB,qBAAqB;CACrB,iBAAiB;CACjB,oBAAoB;CACpB,eAAe;CACf,qBAAqB;CACrB,4BAA4B;CAC5B,oBAAoB;CACpB,kBAAkB;CAClB,sBAAsB;CACtB,yBAAyB;CACzB,oBAAoB;CACpB,uBAAuB;CACvB,6BAA6B;CAC7B,kBAAkB;CAClB,wBAAwB;CACxB,qBAAqB;CACrB,2BAA2B;CAC3B,uBAAuB;CACvB,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,kBAAkB;CAClB,mBAAmB;CACnB,oBAAoB;CACpB,uBAAuB;CACvB,wBAAwB;CACxB,wBAAwB;CACxB,eAAe;CACf,sBAAsB;CACtB,qBAAqB;CACrB,mBAAmB;CACnB,iBAAiB;CACjB,cAAc;CACd,mBAAmB;AACpB"}