@marktiderman/genesis-forms 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +299 -10
  2. package/dist/destinations.cjs +331 -114
  3. package/dist/destinations.cjs.map +1 -1
  4. package/dist/destinations.d.cts +67 -45
  5. package/dist/destinations.d.ts +67 -45
  6. package/dist/destinations.js +327 -111
  7. package/dist/destinations.js.map +1 -1
  8. package/dist/{engine-Bj23YJlB.d.cts → engine-BaHPC2-1.d.cts} +2 -2
  9. package/dist/{engine-CzinTJph.d.ts → engine-Da99Tv-E.d.ts} +2 -2
  10. package/dist/index.cjs +996 -167
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +288 -11
  13. package/dist/index.d.ts +288 -11
  14. package/dist/index.js +975 -168
  15. package/dist/index.js.map +1 -1
  16. package/dist/server.cjs +563 -173
  17. package/dist/server.cjs.map +1 -1
  18. package/dist/server.d.cts +3 -474
  19. package/dist/server.d.ts +3 -474
  20. package/dist/server.js +558 -174
  21. package/dist/server.js.map +1 -1
  22. package/dist/submit-protocol-CFi-0Qd0.d.ts +840 -0
  23. package/dist/submit-protocol-D0cOckmK.d.cts +840 -0
  24. package/dist/testing.cjs +250 -154
  25. package/dist/testing.cjs.map +1 -1
  26. package/dist/testing.d.cts +4 -4
  27. package/dist/testing.d.ts +4 -4
  28. package/dist/testing.js +250 -154
  29. package/dist/testing.js.map +1 -1
  30. package/dist/{types-jqDKcmP4.d.cts → types-C0pUfew3.d.cts} +7 -1
  31. package/dist/{types-jqDKcmP4.d.ts → types-C0pUfew3.d.ts} +7 -1
  32. package/dist/{validate-DvfQHYnu.d.ts → validate-DpmBssFk.d.ts} +258 -140
  33. package/dist/{validate-irIPubxc.d.cts → validate-U5LoW3eR.d.cts} +258 -140
  34. package/package.json +3 -2
  35. package/dist/upload-protocol-BOe018kL.d.cts +0 -122
  36. package/dist/upload-protocol-BUO74WkS.d.ts +0 -122
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/destinations/types.ts","../src/calculated.ts","../src/structured.ts","../src/photo.ts","../src/fields.ts","../src/logic.ts","../src/recall.ts","../src/destinations/row.ts","../src/destinations/email.ts","../src/destinations/google-auth.ts","../src/destinations/sheets.ts","../src/destinations/hook-url.ts","../src/destinations/webhook.ts","../src/destinations/slack.ts","../src/destinations/condition.ts","../src/destinations/google-oauth.ts","../src/destinations/secret-box.ts","../src/destinations/runner.ts"],"names":["plural","numberOps","out","used","state","resolve","isObject","body","cache","seconds"],"mappings":"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","file":"destinations.js","sourcesContent":["/**\n * The contract every destination keeps. A destination sends one checked\n * submission somewhere (an inbox, a spreadsheet, a URL) and says whether a\n * failure is worth retrying. It never throws, never logs, and never puts a\n * secret, an answer or contact details in an error message.\n *\n * Storage is the app's: it keeps the outbox, claims due deliveries, counts\n * attempts and schedules retries. A destination only reports what happened.\n */\nimport type { FormDefinition, Json } from \"../types\";\n\n/** One cell of a flat response row. */\nexport type Cell = string | number | boolean;\n\n/**\n * What a destination delivers: a submission `validateSubmission` checked,\n * plus the id the app stored it under. `{ id, ...result.submission }` fits.\n */\nexport interface DeliverySubmission {\n /** The stored response's id. Every destination records it, so a resend is recognised. */\n id: string;\n /** Answers keyed by field id. */\n answers: Record<string, Json>;\n /** Untrusted URL and host inputs. */\n hidden?: Record<string, Json> | undefined;\n /** Trusted server inputs (account id, location…). */\n context?: Record<string, Json> | undefined;\n ending?: string | null | undefined;\n /** When it was submitted, as the app wants it shown: an ISO time, or a day such as `2026-10-22`. */\n submittedAt?: string | undefined;\n /**\n * Extra leading columns the app adds, in order, after `id` and `submitted_at`:\n * the form's slug and version, an account id, a location. Rows and emails show them;\n * the webhook sends them.\n */\n meta?: Record<string, Cell> | undefined;\n /** Labels the app attached, such as `low_rating`. The webhook sends them; a custom email can read them. */\n tags?: readonly string[] | undefined;\n}\n\nexport interface DeliveryOptions {\n /**\n * This delivery's id, stable across its retries. The email destination's\n * idempotency key and the webhook's `webhook-id`. Defaults to the submission id.\n */\n deliveryId?: string | undefined;\n /** What this destination cached last time (`DeliveryResult.state`). */\n state?: Record<string, Json> | undefined;\n /**\n * An earlier attempt of this delivery may have gone through (it timed out,\n * or its lease ran out). Destinations that can look first do: the sheet\n * skips rows whose id is already there.\n */\n redelivery?: boolean | undefined;\n /** Aborts the delivery. Each request also has its own timeout. */\n signal?: AbortSignal | undefined;\n /**\n * The submission was delivered before and this is its update (an edit).\n * The sheet overwrites the response's row where it is (appending only when\n * it is gone), and the webhook's event type becomes `form.updated`.\n */\n update?: boolean | undefined;\n /**\n * The app's id for the destination. Passed on to option functions (a\n * secret, an account, an access token, a URL), so they can look up what\n * is stored for it.\n */\n destinationId?: string | undefined;\n}\n\n/** One submission in a batch: each carries its own definition and delivery id. */\nexport interface DeliveryItem {\n submission: DeliverySubmission;\n definition: FormDefinition;\n deliveryId?: string | undefined;\n /** This item is an update of a submission delivered before (see `DeliveryOptions.update`). */\n update?: boolean | undefined;\n}\n\nexport type DeliveryResult =\n | {\n ok: true;\n /** New state to keep for this destination, when it changed. */\n state?: Record<string, Json>;\n /** Submission ids already there (a redelivery), so nothing was sent for them. */\n skipped?: string[];\n /**\n * Set when the destination deliberately sent nothing (no address to\n * send to, a daily cap reached): the reason, safe to store. Not a\n * failure and never retried; `createDeliveryRunner` records it as skipped.\n */\n notSent?: string;\n }\n | DeliveryFailure;\n\nexport interface DeliveryFailure {\n ok: false;\n /**\n * `true`: the same request may succeed later (rate limited, the service\n * down, a timeout). `false`: it will not until someone changes the config\n * or credentials (a bad key, an unshared sheet, a 404 URL).\n */\n retryable: boolean;\n /**\n * Set when the service said when to come back (429, 503) or is plainly\n * down: retry after this many seconds. An app may choose not to count the\n * attempt, since it says nothing about the delivery itself.\n */\n retryAfterSeconds?: number;\n /** The HTTP status that refused it, if one did. */\n status?: number;\n /** Safe to store and log: a status and a short reason, never secrets, answers or contact details. */\n error: string;\n}\n\n/** Config is plain JSON the app stores per destination. Secrets never go in it. */\nexport type DestinationConfig = Readonly<Record<string, unknown>>;\n\nexport interface Destination {\n /** `\"email\"`, `\"sheet\"`, `\"webhook\"`, or an app's own. */\n readonly kind: string;\n /** Deliver one submission. Never throws. */\n deliver(\n submission: DeliverySubmission,\n definition: FormDefinition,\n config: DestinationConfig,\n options?: DeliveryOptions,\n ): Promise<DeliveryResult>;\n /**\n * Deliver several submissions to the same destination in one request where\n * the service allows it. All succeed or all fail together. Never throws.\n */\n deliverBatch?(\n items: readonly DeliveryItem[],\n config: DestinationConfig,\n options?: Omit<DeliveryOptions, \"deliveryId\">,\n ): Promise<DeliveryResult>;\n}\n\n/**\n * A failure with a message that is safe to store. Destinations throw it\n * internally and `deliveryFailure` turns it into a result; app-written\n * destinations may do the same.\n */\nexport class DeliveryError extends Error {\n override name = \"DeliveryError\";\n readonly retryable: boolean;\n readonly retryAfterSeconds: number | undefined;\n readonly status: number | undefined;\n constructor(\n message: string,\n options: { retryable?: boolean | undefined; retryAfterSeconds?: number | undefined; status?: number | undefined } = {},\n ) {\n super(message);\n this.retryable = options.retryable ?? false;\n this.retryAfterSeconds = options.retryAfterSeconds;\n this.status = options.status;\n }\n}\n\n/** Every outbound request gives up after this long, unless the destination is given another `timeoutMs`. */\nexport const REQUEST_TIMEOUT_MS = 10_000;\n\nconst IMF_FIXDATE = /^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \\d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$/;\n\n/**\n * Seconds to wait from a Retry-After header, else the fallback. Only the\n * two forms RFC 9110 defines are read: delta-seconds (digits only) and an\n * IMF-fixdate (`Wed, 21 Oct 2026 07:28:00 GMT`); anything else (`-5`,\n * `1.5`, a loose date) gets the fallback. At least 1 second, at most a day.\n */\nexport function retryAfterSeconds(header: string | null | undefined, fallback = 60, now = Date.now()): number {\n const clamp = (s: number) => Math.min(86_400, Math.max(1, s));\n if (header) {\n const trimmed = header.trim();\n if (/^\\d+$/.test(trimmed)) return clamp(Number(trimmed));\n if (IMF_FIXDATE.test(trimmed)) {\n const at = Date.parse(trimmed);\n if (Number.isFinite(at)) return clamp(Math.ceil((at - now) / 1000));\n }\n }\n return fallback;\n}\n\n/** Whether an HTTP status is worth retrying unchanged: 408, 425, 429 and 5xx. */\nexport function isRetryableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\n/**\n * The error for a refused request. Retryable statuses (see\n * `isRetryableStatus`) wait for the Retry-After header, else 60 seconds;\n * every other status is permanent.\n */\nexport function httpError(what: string, response: Response, detail?: string): DeliveryError {\n const status = response.status;\n const message = `${what} answered ${status}${detail ? ` (${detail})` : \"\"}`;\n if (isRetryableStatus(status)) {\n return new DeliveryError(message, {\n retryable: true,\n retryAfterSeconds: retryAfterSeconds(response.headers.get(\"retry-after\")),\n status,\n });\n }\n return new DeliveryError(message, { retryable: false, status });\n}\n\n/**\n * Any error as a failed result with a safe message. A `DeliveryError` keeps\n * its message; anything else is reduced to its kind (\"Timed out\", \"Network\n * error\"), because a raw message may hold a URL with a token in it.\n * Timeouts and aborts are retryable. A `TypeError` is permanent: it is\n * almost always a bug that a retry would only repeat. `timedFetch` turns\n * fetch's own network `TypeError` into a retryable `DeliveryError` first, so\n * an app destination that calls `fetch` directly should do the same.\n */\nexport function deliveryFailure(error: unknown): DeliveryFailure {\n if (error instanceof DeliveryError) {\n return {\n ok: false,\n retryable: error.retryable,\n error: error.message.slice(0, 500),\n ...(error.retryAfterSeconds !== undefined ? { retryAfterSeconds: error.retryAfterSeconds } : {}),\n ...(error.status !== undefined ? { status: error.status } : {}),\n };\n }\n const name = error instanceof Error ? error.name : \"\";\n if (name === \"TimeoutError\") return { ok: false, retryable: true, error: \"Timed out\" };\n if (name === \"AbortError\") return { ok: false, retryable: true, error: \"Aborted\" };\n if (name === \"TypeError\") return { ok: false, retryable: false, error: \"Unexpected error\" };\n return { ok: false, retryable: true, error: \"Unexpected error\" };\n}\n\n/** Shared by the built-in destinations. */\nexport interface HttpDeps {\n /** Defaults to the global `fetch`. */\n fetch?: typeof fetch | undefined;\n /** Per request. Default `REQUEST_TIMEOUT_MS`. */\n timeoutMs?: number | undefined;\n}\n\n/**\n * A request with a timeout, also aborted by the caller's signal. A network\n * failure (fetch rejects with a `TypeError`) becomes a retryable\n * `DeliveryError(\"Network error\")`; timeouts and aborts pass through.\n */\nexport async function timedFetch(\n deps: HttpDeps,\n url: string,\n init: RequestInit,\n signal: AbortSignal | undefined,\n): Promise<Response> {\n const timeout = AbortSignal.timeout(deps.timeoutMs ?? REQUEST_TIMEOUT_MS);\n const any = (AbortSignal as unknown as { any?: (signals: AbortSignal[]) => AbortSignal }).any;\n const combined = signal ? (any ? any([timeout, signal]) : signal.aborted ? signal : timeout) : timeout;\n // fetch rejects with a TypeError both for a network failure and for a\n // request that can never be sent (a newline in a header value, a bad URL).\n // Building the Request first separates the two: that one fails for good,\n // without echoing the value that broke it.\n try {\n // Without the body, so a stream body is never locked by the check.\n new Request(url, { method: init.method ?? \"GET\", headers: init.headers ?? {} });\n } catch {\n throw new DeliveryError(\"Invalid request (a header value or the URL is malformed)\", { retryable: false });\n }\n try {\n return await (deps.fetch ?? fetch)(url, { ...init, signal: combined });\n } catch (error) {\n if (error instanceof Error && error.name === \"TypeError\") throw new DeliveryError(\"Network error\", { retryable: true });\n throw error;\n }\n}\n\n/** What an option function is told besides the config. */\nexport interface ResolveContext {\n /** `DeliveryOptions.destinationId`, when the app gave one. */\n destinationId?: string | undefined;\n}\n\n/** A factory option worked out per delivery from the destination's config. */\nexport type OptionResolver<T> = (config: DestinationConfig, context: ResolveContext) => T | Promise<T>;\n\n/**\n * A factory option that may be a value or a function of the config (an\n * account, a secret). A function that throws fails the delivery\n * permanently with \"<what> could not be resolved\", never retried and never\n * echoing its message; to ask for a retry it can throw a retryable\n * `DeliveryError` itself.\n */\nexport async function resolveOption<T>(\n what: string,\n option: T | OptionResolver<T>,\n config: DestinationConfig,\n context: ResolveContext = {},\n): Promise<T> {\n if (typeof option !== \"function\") return option;\n try {\n return await (option as OptionResolver<T>)(config, context);\n } catch (error) {\n if (error instanceof DeliveryError) throw error;\n throw new DeliveryError(`${what} could not be resolved`);\n }\n}\n\n/** Lets go of a body we will not read, so the connection is freed. */\nexport function discard(response: Response): void {\n try {\n void response.body?.cancel().catch(() => {});\n } catch {\n // A mocked or already-read body.\n }\n}\n\n/** The string config value at `key`, trimmed, or \"\" (a snake_case `alias` is accepted too). */\nexport function configString(config: DestinationConfig, key: string, alias?: string): string {\n const raw = config[key] ?? (alias ? config[alias] : undefined);\n return typeof raw === \"string\" ? raw.trim() : \"\";\n}\n\n/** Bytes as base64url, no padding. */\nexport function base64url(bytes: Uint8Array | string): string {\n return base64(bytes).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** Bytes (or UTF-8 text) as standard base64. */\nexport function base64(bytes: Uint8Array | string): string {\n const raw = typeof bytes === \"string\" ? new TextEncoder().encode(bytes) : bytes;\n let s = \"\";\n for (let i = 0; i < raw.length; i++) s += String.fromCharCode(raw[i]!);\n return btoa(s);\n}\n\n/** Standard base64 (or base64url) as bytes. Throws on anything else. */\nexport function fromBase64(text: string): Uint8Array<ArrayBuffer> {\n const bin = atob(text.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\n/** SHA-256 of a text, as lowercase hex. */\nexport async function sha256Hex(text: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(text));\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/** WebCrypto's key type, named without depending on the DOM lib. */\nexport type WebCryptoKey = Awaited<ReturnType<typeof crypto.subtle.importKey>>;\n","import type { FieldTypeManifest } from \"./fields\";\nimport { evaluateFormula, formulaNumber, ownFormulaList, parseFormula, type FormulaNode, type FormulaRef, type FormulaValue } from \"./formula\";\nimport type { FieldBlock, FormDefinition, Json, Operator } from \"./types\";\n\n/** The calculated field type's registry key. */\nexport const CALCULATED_TYPE = \"calculated\";\n\n/**\n * Field types the builder offers only to a host that names them in its\n * palette, like `STRUCTURED_FIELD_TYPES`: `calculated` shows a value worked\n * out from other answers, so it is opt-in for hosts that want formulas.\n */\nexport const COMPUTED_FIELD_TYPES = [CALCULATED_TYPE] as const;\n\nexport type CalculatedFormat = \"number\" | \"percent\" | \"text\";\n/** Longest the formulas of one form may be, all together (`parseForm` checks it). */\nexport const MAX_FORM_FORMULA_LENGTH = 20_000;\n/** Most decimal places a calculated value may keep. */\nexport const MAX_CALCULATED_DECIMALS = 10;\n\nexport interface CalculatedProps {\n formula: string;\n format?: CalculatedFormat | undefined;\n decimals?: number | undefined;\n}\n\n/** A calculated field's settings, with anything malformed left out. */\nexport function calculatedProps(field: FieldBlock): CalculatedProps {\n const p = field.props ?? {};\n const out: CalculatedProps = { formula: typeof p.formula === \"string\" ? p.formula : \"\" };\n if (p.format === \"number\" || p.format === \"percent\" || p.format === \"text\") out.format = p.format;\n if (typeof p.decimals === \"number\" && Number.isInteger(p.decimals) && p.decimals >= 0 && p.decimals <= MAX_CALCULATED_DECIMALS) {\n out.decimals = p.decimals;\n }\n return out;\n}\n\nexport const isCalculated = (field: FieldBlock | undefined): boolean => field?.type === CALCULATED_TYPE;\n\nconst round = (n: number, decimals: number | undefined) => {\n if (decimals === undefined) return n;\n const r = Number(n.toFixed(decimals));\n return Object.is(r, -0) ? 0 : r;\n};\n\n/**\n * What a formula's result is stored as. `number` and `percent` keep a number\n * (`0.25` for 25%), rounded to `decimals`; `text` keeps text. Without a\n * format, numbers, text and true / false are kept as they are. A list, and\n * anything the format can't hold, is no value (`undefined`).\n */\nexport function calculatedValue(result: FormulaValue, field: FieldBlock): Json | undefined {\n return valueAs(result, calculatedProps(field));\n}\n\nfunction valueAs(result: FormulaValue, { format, decimals }: CalculatedProps): Json | undefined {\n if (result === null || Array.isArray(result)) return undefined;\n if (format === \"number\" || format === \"percent\") {\n const n = formulaNumber(result);\n return n === null ? undefined : round(n, decimals);\n }\n if (format === \"text\") {\n if (typeof result === \"number\") return decimals === undefined ? String(result) : result.toFixed(decimals);\n return typeof result === \"boolean\" ? (result ? \"Yes\" : \"No\") : result;\n }\n return typeof result === \"number\" ? round(result, decimals) : result;\n}\n\n/** A calculated value as shown: `12.5`, `25%`, the text, Yes / No. Empty when there is none. */\nexport function formatCalculated(value: Json | undefined, field: FieldBlock): string {\n if (value === undefined || value === null) return \"\";\n const { format, decimals } = calculatedProps(field);\n const fixed = (n: number) => (decimals === undefined ? String(Number(n.toFixed(6))) : n.toFixed(decimals));\n if (typeof value === \"number\") return format === \"percent\" ? `${fixed(value * 100)}%` : fixed(value);\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n return typeof value === \"string\" ? value : \"\";\n}\n\n/**\n * Most items a formula reads from one answer (a list's items, a table's\n * rows). A longer answer reads as blank, so one oversized value sent to the\n * server can't make every formula over it slow.\n */\nexport const MAX_FORMULA_ITEMS = 10_000;\n\n/**\n * Most list items and table rows all of a form's formulas read in one go\n * (each list or table counted once, however many of its columns are read, in form order). A formula that reads\n * an answer past the limit, or one over `MAX_FORMULA_ITEMS`, has no value\n * (blank, never a partial total), so many big answers can't make working\n * the values out slow either.\n */\nexport const MAX_SETTLE_ITEMS = 50_000;\n\nconst extract = (value: readonly Json[], column: string | undefined): FormulaValue[] =>\n column !== undefined\n ? value.flatMap((row): FormulaValue[] => {\n if (!row || typeof row !== \"object\" || Array.isArray(row)) return [];\n const cell = row[column];\n return typeof cell === \"string\" || typeof cell === \"number\" ? [cell] : [];\n })\n : value.flatMap((v): FormulaValue[] => (typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\" ? [v] : []));\n\n\n/**\n * The value a formula reads for an answer: numbers and text as they are, a\n * list's items, one table column's cells. A list or table of more than\n * `MAX_FORMULA_ITEMS` reads as blank. Each call builds a new list.\n */\nexport function formulaInput(value: Json | undefined, column?: string): FormulaValue {\n if (value === undefined || value === null) return null;\n if (Array.isArray(value) && value.length > MAX_FORMULA_ITEMS) return null;\n if (column !== undefined) {\n if (!Array.isArray(value)) return null;\n return extract(value, column);\n }\n if (Array.isArray(value)) return extract(value, undefined);\n return typeof value === \"object\" ? null : value;\n}\n\ninterface Compiled {\n field: FieldBlock;\n /** `formulaSize` of `ast`. */\n size: number;\n props: CalculatedProps;\n ast: FormulaNode | null;\n /** The answers it reads, each (answer, column) once (`id` is `undefined` for a key that is not a field). */\n reads: Read[];\n /** Each `ref` node of the formula, to its index in `reads`. */\n slots: Map<FormulaNode, number>;\n /** The inputs of the last evaluation and its result, reused while they are the same values. */\n last: { inputs: unknown[]; value: Json | undefined } | null;\n}\n\ninterface Read {\n id: string | undefined;\n column: string | undefined;\n /** `id` and `column` as one key, to read each once per formula. */\n key: string;\n}\n\nfunction refNodes(node: FormulaNode, out: Extract<FormulaNode, { kind: \"ref\" }>[] = []) {\n if (node.kind === \"ref\") out.push(node);\n else if (node.kind === \"unary\") refNodes(node.arg, out);\n else if (node.kind === \"binary\") (refNodes(node.left, out), refNodes(node.right, out));\n else if (node.kind === \"if\") (refNodes(node.test, out), refNodes(node.then, out), refNodes(node.else, out));\n else if (node.kind === \"call\") for (const a of node.args) refNodes(a, out);\n return out;\n}\n\n/** How many parts (numbers, answers, operators, calls) a formula has: what working it out once costs. */\nfunction formulaSize(node: FormulaNode): number {\n if (node.kind === \"unary\") return 1 + formulaSize(node.arg);\n if (node.kind === \"binary\") return 1 + formulaSize(node.left) + formulaSize(node.right);\n if (node.kind === \"if\") return 1 + formulaSize(node.test) + formulaSize(node.then) + formulaSize(node.else);\n if (node.kind === \"call\") return node.args.reduce((n, a) => n + formulaSize(a), 1);\n return 1;\n}\n\n/**\n * Work an engine may spend while replaying (see `MAX_REPLAY_WORK` in\n * `server.ts`): `spend` throws `ReplayWorkExceeded` once `used` passes `max`.\n */\nexport interface WorkBudget {\n used: number;\n max: number;\n}\n\n/**\n * Counts of the work calculators and replays did, for tests to check the\n * work stays bounded rather than timing it (not exported from the package).\n * `reset` zeroes them.\n */\nexport const workStats = {\n /** Formulas worked out (a cached result reused is not counted). */\n formulaRuns: 0,\n /** Lists read out of an answer (a list or one table column). */\n listBuilds: 0,\n /** Calls of `withCalculated`. */\n settles: 0,\n /** Copies of the answers made by `withCalculated`: at most one per call. */\n answerCopies: 0,\n /** Units of work the last limited replay used (see `WorkBudget`). */\n lastReplayWork: 0,\n reset() {\n this.formulaRuns = this.listBuilds = this.settles = this.answerCopies = this.lastReplayWork = 0;\n },\n};\n\nexport class ReplayWorkExceeded extends Error {\n constructor(readonly limit: number) {\n super(`Replaying the response would take more than ${limit} steps of work.`);\n }\n}\n\nexport function spend(budget: WorkBudget | undefined, amount: number): void {\n if (!budget) return;\n budget.used += amount;\n if (budget.used > budget.max) throw new ReplayWorkExceeded(budget.max);\n}\n\n/** Stands for an answer that is off the path or unanswered. */\nconst UNREAD = Symbol(\"unread\");\n/** Stands for an answer too big to read: over `MAX_FORMULA_ITEMS`, or past `MAX_SETTLE_ITEMS`. */\nconst OVER = Symbol(\"over\");\n\n/**\n * Works out a form's calculated fields from its answers. `withCalculated`\n * returns `values` itself when nothing changed. Each formula reads the\n * answers on `path` only (an answer logic hides reads as blank) and the\n * calculated fields before it, in form order.\n */\nexport function calculator(definition: FormDefinition, work?: WorkBudget) {\n // Work: 1 for each formula looked at in a settle, plus its size each time\n // it is worked out. Past the budget, `withCalculated` throws.\n const compiled: Compiled[] = [];\n const idByKey = new Map<string, string>();\n for (const block of definition.blocks) {\n if (block.kind !== \"field\") continue;\n idByKey.set(block.key, block.id);\n }\n for (const block of definition.blocks) {\n if (block.kind !== \"field\" || !isCalculated(block)) continue;\n const props = calculatedProps(block);\n const parsed = parseFormula(props.formula);\n const reads: Read[] = [];\n const slots = new Map<FormulaNode, number>();\n const byKey = new Map<string, number>();\n for (const ref of parsed.ok ? refNodes(parsed.ast) : []) {\n const id = idByKey.get(ref.key);\n const key = `${id ?? \"\"}\\u0000${ref.column ?? \"\"}`;\n let slot = byKey.get(key);\n if (slot === undefined) {\n slot = reads.push({ id, column: ref.column, key }) - 1;\n byKey.set(key, slot);\n }\n slots.set(ref, slot);\n }\n compiled.push({ field: block, props, ast: parsed.ok ? parsed.ast : null, size: parsed.ok ? formulaSize(parsed.ast) : 0, reads, slots, last: null });\n }\n /**\n * This calculator's lists, by the answer's array and then the column (`\"\"`\n * for a list's own items), so an unchanged table is walked once. Each\n * engine (and so each `validateSubmission` call) has its own, so a host\n * array changed between two calls is read afresh. Within one engine an\n * answer is not changed in place: the engine never changes a value it\n * holds, and `setValue` with an array it already holds calls `forget`.\n */\n const extracted = new WeakMap<readonly Json[], Map<string, readonly FormulaValue[]>>();\n const cachedList = (value: readonly Json[], column: string | undefined): readonly FormulaValue[] => {\n let byColumn = extracted.get(value);\n if (!byColumn) extracted.set(value, (byColumn = new Map()));\n const key = column ?? \"\";\n let list = byColumn.get(key);\n if (!list) {\n workStats.listBuilds++;\n byColumn.set(key, (list = ownFormulaList(extract(value, column))));\n }\n return list;\n };\n const readAnswer = (value: Json | undefined, column: string | undefined): FormulaValue => {\n if (Array.isArray(value)) return cachedList(value, column) as FormulaValue[];\n return column !== undefined ? null : formulaInput(value);\n };\n /** Drop what was worked out from `value`: it may have been changed in place. */\n const forget = (value: Json | undefined) => {\n if (!value || typeof value !== \"object\") return;\n if (Array.isArray(value)) extracted.delete(value);\n for (const entry of compiled) if (entry.last?.inputs.includes(value)) entry.last = null;\n };\n\n const withCalculated = (values: Record<string, Json | undefined>, path: readonly string[]) => {\n if (!compiled.length) return values;\n workStats.settles++;\n const visible = new Set(path);\n let next = values;\n // `values` is copied once, on the first change, then written into.\n let copied = false;\n // The items every formula may read, together: each list answer and table\n // counts its items or rows once (however many of its columns are read),\n // in form order, and one past the limit reads as blank. It depends on the\n // answers only, so a client and the server agree.\n let budget = MAX_SETTLE_ITEMS;\n const within = new Map<string, boolean>();\n const input = ({ id }: Read): unknown => {\n if (id === undefined || !visible.has(id) || !Object.prototype.hasOwnProperty.call(next, id)) return UNREAD;\n const value = next[id];\n if (!Array.isArray(value)) return value;\n let ok = within.get(id);\n if (ok === undefined) {\n // An answer over the per-answer limit is never read, so it uses none of the allowance.\n ok = value.length <= MAX_FORMULA_ITEMS && value.length <= budget;\n if (ok) budget -= value.length;\n within.set(id, ok);\n }\n return ok ? value : OVER;\n };\n for (const entry of compiled) {\n const { field, ast } = entry;\n // A formula is worked out again only when an answer it reads is a different value:\n // an engine settles on every answer, and most answers are to other questions.\n const { reads } = entry;\n spend(work, 1);\n const inputs: unknown[] = new Array(reads.length);\n let over = false;\n let same = entry.last !== null;\n for (let i = 0; i < reads.length; i++) {\n const v = input(reads[i]!);\n inputs[i] = v;\n if (v === OVER) over = true;\n if (same && entry.last!.inputs[i] !== v) same = false;\n }\n let value: Json | undefined;\n if (same) {\n value = entry.last!.value;\n } else {\n spend(work, entry.size);\n workStats.formulaRuns++;\n const resolved: (FormulaValue | undefined)[] = new Array(inputs.length);\n const read = (ref: FormulaRef): FormulaValue => {\n const slot = entry.slots.get(ref as FormulaNode);\n if (slot === undefined) return null;\n let v = resolved[slot];\n if (v === undefined) {\n const raw = inputs[slot];\n v = resolved[slot] = raw === UNREAD ? null : readAnswer(raw as Json | undefined, reads[slot]!.column);\n }\n return v;\n };\n // An answer too big to read leaves the value blank rather than a partial total.\n value = ast && !over ? valueAs(evaluateFormula(ast, read), entry.props) : undefined;\n entry.last = { inputs, value };\n }\n const current = Object.prototype.hasOwnProperty.call(next, field.id) ? next[field.id] : undefined;\n if (current !== value) {\n if (!copied) {\n workStats.answerCopies++;\n next = { ...next };\n copied = true;\n }\n next[field.id] = value;\n }\n }\n return next;\n };\n return { active: compiled.length > 0, ids: new Set(compiled.map((c) => c.field.id)), withCalculated, forget };\n}\n\nconst numberOps: Operator[] = [\"eq\", \"neq\", \"lt\", \"lte\", \"gt\", \"gte\", \"in\", \"answered\", \"empty\"];\n\nexport const calculatedFieldType: FieldTypeManifest = {\n type: CALCULATED_TYPE,\n label: \"Calculated\",\n category: \"advanced\",\n value: { json: true },\n operators: numberOps,\n a11y: { semantics: \"control\" },\n // The engine works the value out; any number, text or true / false it made is valid.\n validate: (value) => (typeof value === \"number\" || typeof value === \"string\" || typeof value === \"boolean\" ? null : \"This value is worked out from other answers.\"),\n summarize: (value, field) => formatCalculated(value, field),\n};\n","import type { FieldTypeManifest } from \"./fields\";\nimport type { FieldBlock, Json } from \"./types\";\n\ntype JsonObject = { [key: string]: Json };\nconst isObject = (v: unknown): v is JsonObject => !!v && typeof v === \"object\" && !Array.isArray(v);\nfunction intProp(field: FieldBlock, name: string, fallback: number, floor = 1): number {\n const v = field.props?.[name];\n return typeof v === \"number\" && Number.isInteger(v) && v >= floor ? v : fallback;\n}\nfunction optionalIntProp(field: FieldBlock, name: string, floor = 0): number | undefined {\n const v = field.props?.[name];\n return typeof v === \"number\" && Number.isInteger(v) && v >= floor ? v : undefined;\n}\nconst blank = (v: unknown) => typeof v !== \"string\" || v.trim() === \"\";\n/**\n * Unanswered: nothing, or a list whose every entry is a blank one. Anything\n * else (a string, a list with a malformed entry) is an answer, so validation\n * rejects it instead of dropping it silently.\n */\nconst blankText = (v: unknown) => typeof v === \"string\" && v.trim() === \"\";\nconst emptyList = (value: Json | undefined, isBlank: (entry: Json) => boolean) =>\n value === undefined || value === null || (Array.isArray(value) && value.every(isBlank));\nconst plural = (n: number, one: string, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;\n\nexport function listLimits(field: FieldBlock) {\n return { min: optionalIntProp(field, \"min\") ?? 0, max: intProp(field, \"max\", 10), itemMaxLength: intProp(field, \"itemMaxLength\", 500) };\n}\nconst listItems = (value: Json | undefined): string[] =>\n Array.isArray(value) ? value.filter((v): v is string => typeof v === \"string\" && v.trim() !== \"\") : [];\n\nexport interface TableColumn { key: string; label: string; long?: boolean }\nexport const MAX_TABLE_COLUMNS = 6;\nexport const MAX_TABLE_CELL_LENGTH = 2000;\nexport function tableColumns(field: FieldBlock): TableColumn[] {\n const raw = field.props?.columns;\n if (!Array.isArray(raw)) return [];\n const seen = new Set<string>();\n const out: TableColumn[] = [];\n for (const c of raw) {\n if (!isObject(c) || typeof c.key !== \"string\" || !c.key || seen.has(c.key)) continue;\n seen.add(c.key);\n const column: TableColumn = { key: c.key, label: typeof c.label === \"string\" ? c.label : c.key };\n if (c.long === true) column.long = true;\n out.push(column);\n }\n return out;\n}\nexport function tableLimits(field: FieldBlock) {\n return { minRows: optionalIntProp(field, \"minRows\") ?? 0, maxRows: intProp(field, \"maxRows\", 3) };\n}\nconst filledRows = (value: Json | undefined): JsonObject[] =>\n Array.isArray(value) ? value.filter((r): r is JsonObject => isObject(r) && Object.values(r).some((c) => !blank(c))) : [];\n\nexport interface MediaNote { at: number; text: string }\nexport const MAX_TIMESTAMP_SECONDS = 86400;\nexport function formatTimestamp(seconds: number): string {\n const total = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = String(total % 60).padStart(2, \"0\");\n return h ? `${h}:${String(m).padStart(2, \"0\")}:${s}` : `${m}:${s}`;\n}\nexport function parseTimestamp(text: string): number | null {\n const t = text.trim();\n if (!t) return null;\n const parts = t.split(\":\");\n if (parts.length > 3) return null;\n if (parts.length === 1) {\n if (!/^\\d+(\\.\\d+)?$/.test(t)) return null;\n const n = Number(t);\n return n <= MAX_TIMESTAMP_SECONDS ? n : null;\n }\n const last = parts.length - 1;\n let total = 0;\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i]!;\n const ok = i === 0 ? /^\\d+$/.test(p) : i === last ? /^\\d{2}(\\.\\d+)?$/.test(p) : /^\\d{2}$/.test(p);\n if (!ok) return null;\n const n = Number(p);\n if (i > 0 && n >= 60) return null;\n total = total * 60 + n;\n }\n return total <= MAX_TIMESTAMP_SECONDS ? total : null;\n}\nconst isTimestamp = (v: unknown): v is number => typeof v === \"number\" && Number.isFinite(v) && v >= 0 && v <= MAX_TIMESTAMP_SECONDS;\nconst notesWithText = (value: Json | undefined): JsonObject[] =>\n Array.isArray(value) ? value.filter((n): n is JsonObject => isObject(n) && !blank(n.text)) : [];\n\nexport interface Highlight { start: number; end: number; quote: string; note: string }\nexport const MAX_HIGHLIGHT_NOTE_LENGTH = 1000;\n/** The longest passage one highlight may quote; also bounds a quote the server can't check against `props.text`. */\nexport const MAX_HIGHLIGHT_QUOTE_LENGTH = 2000;\nexport const HIGHLIGHT_NOTE_MESSAGE = \"Add a note to each highlight.\";\nconst sourceText = (field: FieldBlock) => (typeof field.props?.text === \"string\" && field.props.text ? field.props.text : undefined);\n\n/**\n * The structured field types, whose answers are lists or records rather than one\n * value:\n * - `list`: several short answers, e.g. goals, action items, three things that went well.\n * - `table`: a small table each answer fills row by row, e.g. an action plan\n * (What / Who / By when), pros and cons.\n * - `media-notes`: notes pinned to times in a video or audio, e.g. lecture notes,\n * a recorded call review.\n * - `text-highlights`: highlight passages of a text and note on each, e.g.\n * annotating an article, a policy or a contract.\n *\n * They are registered like any other, but the builder offers them only to a\n * host that names them in its palette (`FormBuilder palette`), so forms that\n * never had them don't change.\n */\nexport const STRUCTURED_FIELD_TYPES = [\"list\", \"table\", \"media-notes\", \"text-highlights\"] as const;\n\nexport const structuredFieldTypes: FieldTypeManifest[] = [\n {\n type: \"list\", label: \"List\", category: \"text\", value: { json: true },\n // logic.ts `contains` on an array is exact item equality, same as multi-choice, so it is offered.\n operators: [\"contains\", \"answered\", \"empty\"], a11y: { semantics: \"group\" },\n isEmpty: (value) => emptyList(value, blankText),\n validate: (value, field) => {\n if (!Array.isArray(value) || !value.every((v) => typeof v === \"string\")) return \"Enter a list of answers.\";\n const { min, max, itemMaxLength } = listLimits(field);\n if (value.some((v) => (v as string).trim().length > itemMaxLength)) return `Keep each item under ${itemMaxLength} characters.`;\n const count = listItems(value).length;\n if (count < min) return `Add at least ${plural(min, \"item\")}.`;\n if (count > max) return `Add at most ${plural(max, \"item\")}.`;\n return null;\n },\n normalize: (value) => (Array.isArray(value) ? listItems(value).map((v) => v.trim()) : value),\n summarize: (value) => listItems(value).map((v) => v.trim()).join(\"; \"),\n samples: (field) => {\n const { min, max } = listLimits(field);\n return [Array.from({ length: Math.min(Math.max(1, min), max) }, (_, i) => `Item ${i + 1}`)];\n },\n },\n {\n type: \"table\", label: \"Table\", category: \"advanced\", value: { json: true },\n operators: [\"answered\", \"empty\"], a11y: { semantics: \"group\" },\n isEmpty: (value) => emptyList(value, (r) => isObject(r) && Object.values(r).every(blankText)),\n validate: (value, field) => {\n const columns = tableColumns(field);\n if (!columns.length) return \"This question has no columns.\";\n if (!Array.isArray(value) || !value.every(isObject)) return \"Fill in the rows.\";\n const keys = new Set(columns.map((c) => c.key));\n for (const row of value as JsonObject[]) {\n for (const [key, cell] of Object.entries(row)) {\n if (!keys.has(key)) return \"An answer names a column this question doesn't have.\";\n if (typeof cell !== \"string\") return \"Fill in the rows with text.\";\n if (cell.trim().length > MAX_TABLE_CELL_LENGTH) return `Keep each answer under ${MAX_TABLE_CELL_LENGTH} characters.`;\n }\n }\n const { minRows, maxRows } = tableLimits(field);\n const count = filledRows(value).length;\n if (count < minRows) return `Fill in at least ${plural(minRows, \"row\")}.`;\n if (count > maxRows) return `Fill in at most ${plural(maxRows, \"row\")}.`;\n return null;\n },\n normalize: (value) => Array.isArray(value)\n ? filledRows(value).map((row) => {\n const out: JsonObject = {};\n for (const [key, cell] of Object.entries(row)) if (typeof cell === \"string\") out[key] = cell.trim();\n return out;\n })\n : value,\n summarize: (value, field) => {\n const columns = tableColumns(field);\n return filledRows(value)\n .map((row) => columns.filter((c) => !blank(row[c.key])).map((c) => `${c.label}: ${(row[c.key] as string).trim()}`).join(\" · \"))\n .join(\" / \");\n },\n samples: (field) => {\n const columns = tableColumns(field);\n if (!columns.length) return [];\n const { minRows, maxRows } = tableLimits(field);\n const row = Object.fromEntries(columns.map((c) => [c.key, \"sample\"]));\n return [Array.from({ length: Math.min(Math.max(1, minRows), maxRows) }, () => ({ ...row }))];\n },\n },\n {\n type: \"media-notes\", label: \"Notes at moments\", category: \"media\", value: { json: true },\n operators: [\"answered\", \"empty\"], a11y: { semantics: \"group\" },\n isEmpty: (value) => emptyList(value, (n) => isObject(n) && blankText(n.text)),\n validate: (value, field) => {\n if (!Array.isArray(value)) return \"Add notes.\";\n const textMaxLength = intProp(field, \"textMaxLength\", 1000);\n for (const note of value) {\n if (!isObject(note) || typeof note.text !== \"string\") return \"Add notes.\";\n if (!isTimestamp(note.at)) return \"Each note needs a time.\";\n if (note.text.trim().length > textMaxLength) return `Keep each note under ${textMaxLength} characters.`;\n }\n const maxNotes = intProp(field, \"maxNotes\", 20);\n return notesWithText(value).length > maxNotes ? `Add at most ${plural(maxNotes, \"note\")}.` : null;\n },\n normalize: (value) => Array.isArray(value)\n ? notesWithText(value).map((n) => ({ at: n.at as number, text: (n.text as string).trim() })).sort((a, b) => a.at - b.at)\n : value,\n summarize: (value) => notesWithText(value)\n .map((n) => ({ at: typeof n.at === \"number\" ? n.at : 0, text: (n.text as string).trim() }))\n .sort((a, b) => a.at - b.at)\n .map((n) => `${formatTimestamp(n.at)} ${n.text}`)\n .join(\"; \"),\n samples: () => [[{ at: 0, text: \"sample\" }]],\n },\n {\n type: \"text-highlights\", label: \"Highlights\", category: \"media\", value: { json: true },\n operators: [\"answered\", \"empty\"], a11y: { semantics: \"group\" },\n isEmpty: (value) => emptyList(value, () => false),\n validate: (value, field) => {\n if (!Array.isArray(value)) return \"Highlight a passage.\";\n const maxHighlights = intProp(field, \"maxHighlights\", 20);\n if (value.length > maxHighlights) return `Add at most ${plural(maxHighlights, \"highlight\")}.`;\n const text = sourceText(field);\n for (const h of value) {\n if (!isObject(h) || !Number.isInteger(h.start) || !Number.isInteger(h.end) || typeof h.quote !== \"string\" || typeof h.note !== \"string\") {\n return \"Highlight a passage of the text.\";\n }\n const start = h.start as number;\n const end = h.end as number;\n if (start < 0 || end <= start || h.quote.length !== end - start) return \"Highlight a passage of the text.\";\n if (end - start > MAX_HIGHLIGHT_QUOTE_LENGTH) return `Highlight under ${MAX_HIGHLIGHT_QUOTE_LENGTH} characters at a time.`;\n if (text !== undefined && (end > text.length || text.slice(start, end) !== h.quote)) return \"A highlight doesn't match the text.\";\n if (h.note.trim() === \"\") return HIGHLIGHT_NOTE_MESSAGE;\n if (h.note.trim().length > MAX_HIGHLIGHT_NOTE_LENGTH) return `Keep each note under ${MAX_HIGHLIGHT_NOTE_LENGTH} characters.`;\n }\n return null;\n },\n normalize: (value) => Array.isArray(value)\n ? value.filter(isObject)\n .map((h) => ({ start: h.start as number, end: h.end as number, quote: h.quote as string, note: String(h.note).trim() }))\n .sort((a, b) => a.start - b.start || a.end - b.end)\n : value,\n summarize: (value) => Array.isArray(value)\n ? value.filter(isObject).map((h) => `\"${String(h.quote)}\" — ${String(h.note).trim()}`).join(\"; \")\n : \"\",\n samples: (field) => {\n const text = sourceText(field);\n if (text === undefined) return [[{ start: 0, end: 6, quote: \"sample\", note: \"sample\" }]];\n const end = Math.min(text.length, 20);\n return [[{ start: 0, end, quote: text.slice(0, end), note: \"sample\" }]];\n },\n },\n];\n","import type { FieldTypeManifest } from \"./fields\";\nimport type { FieldBlock, Json } from \"./types\";\n\n/**\n * The `photo` field type: a respondent attaches up to a few photos, such as a\n * picture of broken equipment. The answer holds references the host's storage\n * handed back (`PhotoRef`), never the bytes: the renderer uploads through the\n * host (`onUpload` on genesis-forms-web's `Form`), so the engine and the\n * server stay storage-agnostic. A host's server should check that each\n * reference is a file it stored for this respondent before saving.\n *\n * Opt-in in a builder palette (`UPLOAD_FIELD_TYPES`), since a host must be\n * able to store the files.\n */\nexport const PHOTO_TYPE = \"photo\";\n\n/** Field types that need the host to store files; a builder offers them only when the host names them. */\nexport const UPLOAD_FIELD_TYPES = [PHOTO_TYPE] as const;\n\n/** One stored photo, as the host's upload returned it. */\nexport type PhotoRef = {\n /** The host's id for the stored file. */\n id: string;\n /** The file's name on the respondent's device. */\n name: string;\n /** Its MIME type, such as `image/jpeg`. */\n type: string;\n /** Bytes. */\n size: number;\n};\n\nexport type PhotoFormat = \"jpeg\" | \"png\" | \"heic\" | \"webp\";\n\n/** The MIME types each format covers. */\nexport const PHOTO_FORMATS: Record<PhotoFormat, readonly string[]> = {\n jpeg: [\"image/jpeg\"],\n png: [\"image/png\"],\n heic: [\"image/heic\", \"image/heif\"],\n webp: [\"image/webp\"],\n};\n\nconst FORMAT_NAMES: Record<PhotoFormat, string> = { jpeg: \"JPEG\", png: \"PNG\", heic: \"HEIC\", webp: \"WebP\" };\nconst ALL_FORMATS = Object.keys(PHOTO_FORMATS) as PhotoFormat[];\n\nexport const DEFAULT_PHOTO_FILES = 3;\nexport const MAX_PHOTO_FILES = 5;\nexport const DEFAULT_PHOTO_SIZE_MB = 10;\nexport const MAX_PHOTO_SIZE_MB = 25;\n/** The longest reference id and file name a photo answer may carry. */\nexport const MAX_PHOTO_ID_LENGTH = 200;\nexport const MAX_PHOTO_NAME_LENGTH = 255;\n\nexport const isPhotoFormat = (v: unknown): v is PhotoFormat =>\n typeof v === \"string\" && Object.prototype.hasOwnProperty.call(PHOTO_FORMATS, v);\n\nconst wholeIn = (v: unknown, min: number, max: number): v is number =>\n typeof v === \"number\" && Number.isInteger(v) && v >= min && v <= max;\n\nexport interface PhotoLimits {\n maxFiles: number;\n maxSizeMb: number;\n maxBytes: number;\n formats: PhotoFormat[];\n /** Every MIME type the formats cover. */\n mimeTypes: string[];\n}\n\n/** A photo field's limits; a prop that is missing or out of range uses its default. */\nexport function photoLimits(field: FieldBlock): PhotoLimits {\n const maxFiles = wholeIn(field.props?.maxFiles, 1, MAX_PHOTO_FILES) ? field.props.maxFiles : DEFAULT_PHOTO_FILES;\n const maxSizeMb = wholeIn(field.props?.maxSizeMb, 1, MAX_PHOTO_SIZE_MB) ? field.props.maxSizeMb : DEFAULT_PHOTO_SIZE_MB;\n const raw = field.props?.formats;\n const picked = Array.isArray(raw) ? ALL_FORMATS.filter((f) => raw.includes(f)) : [];\n const formats = picked.length ? picked : [...ALL_FORMATS];\n return {\n maxFiles,\n maxSizeMb,\n maxBytes: maxSizeMb * 1024 * 1024,\n formats,\n mimeTypes: formats.flatMap((f) => PHOTO_FORMATS[f]),\n };\n}\n\n/** Whether `v` has a photo reference's shape (any type and size). */\nexport function isPhotoRef(v: unknown): v is PhotoRef {\n if (!v || typeof v !== \"object\" || Array.isArray(v)) return false;\n const r = v as Record<string, unknown>;\n return (\n typeof r.id === \"string\" &&\n r.id.length > 0 &&\n r.id.length <= MAX_PHOTO_ID_LENGTH &&\n typeof r.name === \"string\" &&\n r.name.length <= MAX_PHOTO_NAME_LENGTH &&\n typeof r.type === \"string\" &&\n typeof r.size === \"number\" &&\n Number.isInteger(r.size) &&\n r.size > 0\n );\n}\n\n/** The well-formed references in a photo answer, as `{ id, name, type, size }` only. */\nexport function photoRefs(value: Json | undefined): PhotoRef[] {\n if (!Array.isArray(value)) return [];\n const refs: PhotoRef[] = [];\n for (const r of value as unknown[]) if (isPhotoRef(r)) refs.push({ id: r.id, name: r.name, type: r.type, size: r.size });\n return refs;\n}\n\nconst plural = (n: number, one: string, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;\n\n/** \"JPEG, PNG or WebP\". */\nexport function photoFormatList(formats: readonly PhotoFormat[]): string {\n const names = formats.map((f) => FORMAT_NAMES[f]);\n return names.length > 1 ? `${names.slice(0, -1).join(\", \")} or ${names[names.length - 1]}` : (names[0] ?? \"\");\n}\n\n/** The message for a file of a type the field doesn't take. */\nexport const photoTypeMessage = (field: FieldBlock) => `Use a ${photoFormatList(photoLimits(field).formats)} photo.`;\n/** The message for a file over the field's size limit. */\nexport const photoSizeMessage = (field: FieldBlock) => `Each photo must be ${photoLimits(field).maxSizeMb} MB or smaller.`;\n/** The message for more photos than the field takes. */\nexport const photoCountMessage = (field: FieldBlock) => `Add at most ${plural(photoLimits(field).maxFiles, \"photo\")}.`;\n\nexport const photoFieldType: FieldTypeManifest = {\n type: PHOTO_TYPE,\n label: \"Photo\",\n category: \"media\",\n value: { json: true },\n operators: [\"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n isEmpty: (value) => value === undefined || value === null || (Array.isArray(value) && value.length === 0),\n validate: (value, field) => {\n if (!Array.isArray(value) || !value.every(isPhotoRef)) return \"Add a photo.\";\n const limits = photoLimits(field);\n if (value.length > limits.maxFiles) return photoCountMessage(field);\n const refs = value as unknown as PhotoRef[];\n if (new Set(refs.map((r) => r.id)).size !== refs.length) return \"Each photo can be added once.\";\n if (refs.some((r) => !limits.mimeTypes.includes(r.type.toLowerCase()))) return photoTypeMessage(field);\n if (refs.some((r) => r.size > limits.maxBytes)) return photoSizeMessage(field);\n return null;\n },\n normalize: (value) => (Array.isArray(value) && value.every(isPhotoRef) ? photoRefs(value) : value),\n summarize: (value) => photoRefs(value).map((r) => r.name || \"Photo\").join(\", \"),\n samples: () => [[{ id: \"sample-photo\", name: \"photo.jpg\", type: \"image/jpeg\", size: 1024 }]],\n};\n","import type { Block, FieldBlock, FormDefinition, Json, Operator, OptionsSource } from \"./types\";\nimport { calculatedFieldType } from \"./calculated\";\nimport { structuredFieldTypes } from \"./structured\";\nimport { photoFieldType } from \"./photo\";\n\n/**\n * A field type, without any UI. Renderers are registered separately per\n * platform (`genesis-forms-react`), so a manifest runs anywhere.\n */\nexport interface FieldTypeManifest {\n type: string;\n label: string;\n category: \"text\" | \"choice\" | \"scale\" | \"date\" | \"media\" | \"advanced\";\n /** `json: false` types must convert, so drafts and server replay never lose an answer. */\n value:\n | { json: true }\n | { json: false; serialize: (value: unknown) => Json; deserialize: (json: Json) => unknown };\n operators: Operator[];\n a11y: {\n semantics: \"control\" | \"group\";\n /** The HTML `autocomplete` token, such as `\"email\"` or `\"tel\"`. */\n autocomplete?: string;\n /** The HTML `inputmode` hint for on-screen keyboards, such as `\"email\"` or `\"tel\"`. */\n inputMode?: \"text\" | \"email\" | \"tel\" | \"numeric\" | \"decimal\" | \"url\" | \"search\";\n };\n isEmpty?: (value: Json | undefined) => boolean;\n /** Return an error message, or null when the (non-empty) value is valid. */\n validate?: (value: Json, field: FieldBlock) => string | null;\n /** Plain text for recall, exports and emails. */\n summarize?: (value: Json, field: FieldBlock) => string;\n /**\n * The form a (valid, non-empty) value is stored in, such as an email\n * without surrounding spaces. Applied by `engine.answers()` and the server.\n */\n normalize?: (value: Json, field: FieldBlock) => Json;\n /** Valid example answers, used by `coverage()` and other test tools to explore a path. */\n samples?: (field: FieldBlock) => Json[];\n}\n\n// One registry per process, shared by every entry point (index, server,\n// testing are bundled separately), so a plugin registered once is seen by all.\nconst REGISTRY = Symbol.for(\"@marktiderman/genesis-forms/field-types\");\nconst globalScope = globalThis as typeof globalThis & { [REGISTRY]?: Map<string, FieldTypeManifest> };\nconst registry: Map<string, FieldTypeManifest> = (globalScope[REGISTRY] ??= new Map());\n\nexport function registerFieldType(manifest: FieldTypeManifest): void {\n if (!manifest.type) throw new Error(\"registerFieldType: a field type needs a `type`.\");\n const value = manifest.value as { json: boolean; serialize?: unknown; deserialize?: unknown };\n if (\n !value.json &&\n (typeof value.serialize !== \"function\" || typeof value.deserialize !== \"function\")\n ) {\n throw new Error(\n `registerFieldType: \"${manifest.type}\" stores a non-JSON value, so it must provide both serialize and deserialize.`,\n );\n }\n registry.set(manifest.type, manifest);\n}\n\nexport function getFieldType(type: string): FieldTypeManifest | undefined {\n return registry.get(type);\n}\n\nexport function listFieldTypes(): FieldTypeManifest[] {\n return [...registry.values()];\n}\n\nexport function isEmptyValue(value: Json | undefined, field?: FieldBlock): boolean {\n const manifest = field ? registry.get(field.type) : undefined;\n if (manifest?.isEmpty) return manifest.isEmpty(value);\n if (value === undefined || value === null) return true;\n if (typeof value === \"string\") return value.trim() === \"\";\n if (Array.isArray(value)) return value.length === 0;\n return false;\n}\n\n/** A value in its stored form (see `FieldTypeManifest.normalize`). */\nexport function normalizeValue(value: Json, field: FieldBlock): Json {\n const manifest = registry.get(field.type);\n return manifest?.normalize ? manifest.normalize(value, field) : value;\n}\n\n/** Whether a block holds personal or secret data: `sensitive: true`, or the `props.sensitive: true` alias. */\nexport function isSensitive(block: Block): boolean {\n return block.kind === \"field\" && (block.sensitive === true || block.props?.sensitive === true);\n}\n\nexport function summarizeValue(value: Json | undefined, field: FieldBlock): string {\n if (isEmptyValue(value, field)) return \"\";\n const manifest = registry.get(field.type);\n if (manifest?.summarize) return manifest.summarize(value as Json, field);\n if (Array.isArray(value)) return value.join(\", \");\n return String(value);\n}\n\n// ── Built-in types (R1) ──────────────────────────────────────────────────────\n\nexport interface ChoiceOption {\n value: string;\n label?: string;\n /** A muted line under the label, such as a location's address. At most `OPTION_LIMITS.description` characters. */\n description?: string;\n /** A small picture beside the label: an `https://` URL, at most `OPTION_LIMITS.image` characters. */\n image?: string;\n /**\n * Facts about the option for filtering and recall, such as `{ location: [\"riverside\", \"hilltop\"] }`\n * for a coach who works at two locations (see `props.optionsFrom.filter`). Names and values are\n * text; a value is one text or a list of them.\n */\n attributes?: Record<string, string | string[]>;\n}\n\n/** Bounds on an option's extra details. A longer or malformed detail is dropped when options are read. */\nexport const OPTION_LIMITS = {\n /** Characters in a description. */\n description: 500,\n /** Characters in an image URL. */\n image: 2048,\n /** Attributes on one option. */\n attributes: 20,\n /** Characters in an attribute's name. */\n attributeName: 64,\n /** Characters in one attribute value. */\n attributeValue: 200,\n /** Values in one attribute's list. */\n attributeItems: 50,\n} as const;\n\n/**\n * Whether `url` is an `https://` link with a host and no spaces or control characters, within\n * `OPTION_LIMITS.image`. A pattern rather than `new URL`, so it behaves the same in React Native.\n */\nexport function isHttpsUrl(url: unknown): url is string {\n return (\n typeof url === \"string\" &&\n url.length <= OPTION_LIMITS.image &&\n /^https:\\/\\/[^\\s/?#@\\\\]+(?:[/?#][^\\s]*)?$/i.test(url) &&\n // No control characters anywhere (a line break would end a CSV row or an HTML attribute).\n ![...url].some((c) => c.charCodeAt(0) < 32 || c.charCodeAt(0) === 127)\n );\n}\n\n/** A well-formed attribute name: text, not blank, not an `Object.prototype` name, within the limit. */\nfunction attributeName(name: string): boolean {\n return name.trim() !== \"\" && name.length <= OPTION_LIMITS.attributeName && !(name in Object.prototype);\n}\n\n/** The attributes of a raw option that are well formed, or undefined when none are. */\nfunction readAttributes(raw: unknown): Record<string, string | string[]> | undefined {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return undefined;\n const out: Record<string, string | string[]> = {};\n let count = 0;\n for (const name of Object.keys(raw)) {\n if (count >= OPTION_LIMITS.attributes) break;\n if (!attributeName(name)) continue;\n const v = (raw as Record<string, unknown>)[name];\n const fits = (x: unknown): x is string => typeof x === \"string\" && x.length <= OPTION_LIMITS.attributeValue;\n if (fits(v)) out[name] = v;\n else if (Array.isArray(v) && v.length <= OPTION_LIMITS.attributeItems && v.every(fits)) out[name] = [...v];\n else continue;\n count++;\n }\n return count ? out : undefined;\n}\n\n/**\n * An option from untrusted JSON (a definition, the host's list): its string `value`, and its\n * `label`, `description`, `image` and `attributes` when each is well formed and within\n * `OPTION_LIMITS`; anything else is left out. Null when there is no string value.\n */\nexport function readOption(raw: unknown): ChoiceOption | null {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return null;\n const o = raw as Record<string, unknown>;\n if (typeof o.value !== \"string\") return null;\n const out: ChoiceOption = { value: o.value };\n if (typeof o.label === \"string\") out.label = o.label;\n if (typeof o.description === \"string\" && o.description.trim() && o.description.length <= OPTION_LIMITS.description) {\n out.description = o.description;\n }\n if (isHttpsUrl(o.image)) out.image = o.image;\n const attributes = readAttributes(o.attributes);\n if (attributes) out.attributes = attributes;\n return out;\n}\n\n/** An option as JSON, with only the details it has. */\nexport function optionJson(option: ChoiceOption): Json {\n const out: Record<string, Json> = { value: option.value };\n if (option.label !== undefined) out.label = option.label;\n if (option.description !== undefined) out.description = option.description;\n if (option.image !== undefined) out.image = option.image;\n if (option.attributes !== undefined) out.attributes = { ...option.attributes } as Record<string, Json>;\n return out;\n}\n\n/** The longest answer an \"Other\" option takes. */\nexport const OTHER_MAX_LENGTH = 200;\n\n/**\n * A choice question's \"Other\" option (`props.other: true` or `{ label }`): the respondent types\n * their own answer, stored as the answer's value itself (single choice, dropdown) or as one more\n * item (multiple choice). Null when the question has none.\n */\nexport function otherOption(field: FieldBlock): { label: string } | null {\n const other = field.props?.other;\n if (other === true) return { label: \"Other\" };\n if (other && typeof other === \"object\" && !Array.isArray(other)) {\n const label = typeof other.label === \"string\" && other.label.trim() ? other.label.trim() : \"Other\";\n return { label };\n }\n return null;\n}\n\n/** Whether a value is a typed \"Other\" answer: text that isn't one of the question's options. */\nexport function isOtherValue(field: FieldBlock, value: unknown): value is string {\n return (\n otherOption(field) !== null &&\n typeof value === \"string\" &&\n !choiceOptions(field).some((o) => o.value === value)\n );\n}\n\nconst typedOther = (field: FieldBlock, value: unknown) =>\n isOtherValue(field, value) && value.trim() !== \"\" && value.length <= OTHER_MAX_LENGTH;\n\nexport function choiceOptions(field: FieldBlock): ChoiceOption[] {\n const raw = field.props?.options;\n if (!Array.isArray(raw)) return [];\n return raw.flatMap((o) => {\n const option = readOption(o);\n return option ? [option] : [];\n });\n}\n\n/**\n * Option lists the app showing a form supplies, by key (`OptionsSource.key`):\n * `{ coaches: [{ value: \"8c1…\", label: \"Ada Lovelace\" }] }`.\n */\nexport type HostOptions = Readonly<Record<string, readonly ChoiceOption[]>>;\n\n/**\n * A choice field's `props.optionsFrom`, when it is a well-formed `{ source: \"host\", key }`, with its\n * `filter` when that is well formed too (`{ attribute, field }`, both non-empty text).\n */\nexport function optionsSource(field: FieldBlock): OptionsSource | undefined {\n const raw = field.props?.optionsFrom;\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return undefined;\n if (raw.source !== \"host\" || typeof raw.key !== \"string\" || !raw.key) return undefined;\n const out: OptionsSource = { source: \"host\", key: raw.key };\n const filter = raw.filter;\n if (\n filter &&\n typeof filter === \"object\" &&\n !Array.isArray(filter) &&\n typeof filter.attribute === \"string\" &&\n filter.attribute &&\n typeof filter.field === \"string\" &&\n filter.field\n ) {\n out.filter = { attribute: filter.attribute, field: filter.field };\n }\n return out;\n}\n\n/** The host's list for `key`, as options: string values only, each value once, labels when they are text. */\nfunction hostList(hostOptions: HostOptions | undefined, key: string): ChoiceOption[] {\n if (!hostOptions || !Object.prototype.hasOwnProperty.call(hostOptions, key)) return [];\n const list = hostOptions[key];\n if (!Array.isArray(list)) return [];\n const seen = new Set<string>();\n const out: ChoiceOption[] = [];\n for (const o of list as unknown[]) {\n const option = readOption(o);\n if (!option || !option.value || seen.has(option.value)) continue;\n seen.add(option.value);\n out.push(option);\n }\n return out;\n}\n\n/**\n * The definition with each `optionsFrom: { source: \"host\" }` field's options\n * filled in from `hostOptions`: its own `props.options` first, then the host's\n * list for its key (a value the field already has is not added twice). A key\n * the host does not supply adds nothing, so the field offers its own options\n * only. `createForm` and `validateSubmission` call it with their `hostOptions`,\n * so a respondent sees, and a submit accepts, exactly these. Returns\n * `definition` itself when no field takes options from the host.\n */\nexport function withHostOptions(definition: FormDefinition, hostOptions: HostOptions | undefined): FormDefinition {\n let changed = false;\n const blocks = definition.blocks.map((block) => {\n if (block.kind !== \"field\") return block;\n const from = optionsSource(block);\n if (!from) return block;\n const own = choiceOptions(block);\n const taken = new Set(own.map((o) => o.value));\n const added = hostList(hostOptions, from.key).filter((o) => !taken.has(o.value));\n if (!added.length) return block;\n changed = true;\n const options = [...own, ...added].map(optionJson);\n return { ...block, props: { ...block.props, options } };\n });\n return changed ? { ...definition, blocks } : definition;\n}\n\nfunction optionLabel(field: FieldBlock, value: string): string {\n const option = choiceOptions(field).find((o) => o.value === value);\n return option?.label ?? value;\n}\n\nfunction intRange(field: FieldBlock, min: number, maxDefault: number) {\n const max = typeof field.props?.max === \"number\" ? field.props.max : maxDefault;\n return { min, max };\n}\n\nconst numberOps: Operator[] = [\"eq\", \"neq\", \"lt\", \"lte\", \"gt\", \"gte\", \"in\", \"answered\", \"empty\"];\nconst textOps: Operator[] = [\"eq\", \"neq\", \"contains\", \"answered\", \"empty\"];\n\nfunction maxLength(field: FieldBlock, fallback: number): number {\n return typeof field.props?.maxLength === \"number\" ? field.props.maxLength : fallback;\n}\n\nfunction textValidate(fallback: number) {\n return (value: Json, field: FieldBlock) => {\n if (typeof value !== \"string\") return \"Enter text.\";\n const limit = maxLength(field, fallback);\n return value.length > limit ? `Keep it under ${limit} characters.` : null;\n };\n}\n\n/** The longest address SMTP allows (RFC 5321). */\nconst MAX_EMAIL_LENGTH = 254;\n\n/**\n * `local@domain.tld`: no spaces, exactly one `@`, and a dot inside the domain.\n * A linear scan rather than a regex, so a hostile value cannot backtrack.\n */\nexport function isEmailAddress(value: string): boolean {\n if (value.length > MAX_EMAIL_LENGTH || /\\s/.test(value)) return false;\n const at = value.indexOf(\"@\");\n if (at < 1 || value.indexOf(\"@\", at + 1) !== -1) return false;\n const domain = value.slice(at + 1);\n // A dot with at least one character on each side.\n return domain.slice(1, -1).includes(\".\");\n}\n\n/** Longest phone number accepted, separators included. */\nconst MAX_PHONE_LENGTH = 32;\n\n/**\n * Digits with optional separators (spaces, `-`, `(`, `)`, `.`) and an\n * optional leading `+`; 7 to 15 digits (E.164 allows at most 15). One linear scan.\n */\nfunction isPhoneNumber(value: string): boolean {\n if (value.length > MAX_PHONE_LENGTH) return false;\n let digits = 0;\n for (let i = 0; i < value.length; i++) {\n const c = value[i]!;\n if (c >= \"0\" && c <= \"9\") digits++;\n else if (c === \"+\") {\n if (i !== 0) return false;\n } else if (c !== \" \" && c !== \"-\" && c !== \"(\" && c !== \")\" && c !== \".\") return false;\n }\n return digits >= 7 && digits <= 15;\n}\n\nconst builtins: FieldTypeManifest[] = [\n {\n type: \"short-text\",\n label: \"Short text\",\n category: \"text\",\n value: { json: true },\n operators: textOps,\n a11y: { semantics: \"control\" },\n validate: textValidate(500),\n },\n {\n type: \"long-text\",\n label: \"Long text\",\n category: \"text\",\n value: { json: true },\n operators: textOps,\n a11y: { semantics: \"control\" },\n validate: textValidate(5000),\n },\n {\n type: \"email\",\n label: \"Email\",\n category: \"text\",\n value: { json: true },\n operators: textOps,\n a11y: { semantics: \"control\", autocomplete: \"email\", inputMode: \"email\" },\n validate: (value) =>\n typeof value === \"string\" && isEmailAddress(value.trim())\n ? null\n : \"Enter an email address like name@example.com.\",\n normalize: (value) => (typeof value === \"string\" ? value.trim() : value),\n },\n {\n type: \"phone\",\n label: \"Phone\",\n category: \"text\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"answered\", \"empty\"],\n a11y: { semantics: \"control\", autocomplete: \"tel\", inputMode: \"tel\" },\n validate: (value) =>\n typeof value === \"string\" && isPhoneNumber(value.trim())\n ? null\n : \"Enter a phone number with 7 to 15 digits.\",\n normalize: (value) => (typeof value === \"string\" ? value.trim() : value),\n summarize: (value) => String(value),\n },\n {\n type: \"rating\",\n label: \"Rating\",\n category: \"scale\",\n value: { json: true },\n operators: numberOps,\n a11y: { semantics: \"group\" },\n validate: (value, field) => {\n const { min, max } = intRange(field, 1, 5);\n return Number.isInteger(value) && (value as number) >= min && (value as number) <= max\n ? null\n : `Choose a rating from ${min} to ${max}.`;\n },\n summarize: (value, field) => {\n const { max } = intRange(field, 1, 5);\n const end = scaleEndLabel(field, value as number, 1, max);\n return end ? `${value}/${max} (${end})` : `${value}/${max}`;\n },\n },\n {\n type: \"nps\",\n label: \"Net Promoter Score\",\n category: \"scale\",\n value: { json: true },\n operators: numberOps,\n a11y: { semantics: \"group\" },\n validate: (value) =>\n Number.isInteger(value) && (value as number) >= 0 && (value as number) <= 10\n ? null\n : \"Choose a score from 0 to 10.\",\n summarize: (value, field) => {\n const end = scaleEndLabel(field, value as number, 0, 10);\n return end ? `${value}/10 (${end})` : `${value}/10`;\n },\n },\n {\n type: \"single-choice\",\n label: \"Single choice\",\n category: \"choice\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"in\", \"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n validate: (value, field) =>\n typeof value === \"string\" && (choiceOptions(field).some((o) => o.value === value) || typedOther(field, value))\n ? null\n : \"Choose one of the options.\",\n summarize: (value, field) => optionLabel(field, String(value)),\n },\n {\n type: \"multi-choice\",\n label: \"Multiple choice\",\n category: \"choice\",\n value: { json: true },\n operators: [\"contains\", \"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n validate: (value, field) => {\n const allowed = new Set(choiceOptions(field).map((o) => o.value));\n // Each option at most once, plus at most one typed \"Other\" answer, so a value is never\n // longer than the option list and one.\n const others = Array.isArray(value) ? value.filter((v) => typeof v === \"string\" && !allowed.has(v)) : [];\n return Array.isArray(value) &&\n new Set(value).size === value.length &&\n value.every((v) => typeof v === \"string\") &&\n (others.length === 0 || (others.length === 1 && typedOther(field, others[0])))\n ? null\n : \"Choose from the options.\";\n },\n summarize: (value, field) =>\n Array.isArray(value) ? value.map((v) => optionLabel(field, String(v))).join(\", \") : String(value),\n },\n {\n type: \"yes-no\",\n label: \"Yes / no\",\n category: \"choice\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n validate: (value) => (typeof value === \"boolean\" ? null : \"Choose yes or no.\"),\n summarize: (value) => (value ? \"Yes\" : \"No\"),\n },\n {\n type: \"dropdown\",\n label: \"Dropdown\",\n category: \"choice\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"in\", \"answered\", \"empty\"],\n a11y: { semantics: \"control\" },\n validate: (value, field) =>\n typeof value === \"string\" && (choiceOptions(field).some((o) => o.value === value) || typedOther(field, value))\n ? null\n : \"Choose one of the options.\",\n summarize: (value, field) => optionLabel(field, String(value)),\n },\n {\n type: \"number\",\n label: \"Number\",\n category: \"text\",\n value: { json: true },\n operators: numberOps,\n a11y: { semantics: \"control\", inputMode: \"decimal\" },\n validate: (value, field) => {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return \"Enter a number.\";\n const { min, max, step } = numberLimits(field);\n if (min !== undefined && max !== undefined && (value < min || value > max)) {\n return `Enter a number from ${min} to ${max}.`;\n }\n if (min !== undefined && value < min) return `Enter ${min} or more.`;\n if (max !== undefined && value > max) return `Enter ${max} or less.`;\n if (step !== undefined && !onStep(value, min ?? 0, step)) {\n return step === 1 && Number.isInteger(min ?? 0)\n ? \"Enter a whole number.\"\n : `Enter a number in steps of ${step}.`;\n }\n return null;\n },\n summarize: (value) => String(value),\n samples: (field) => {\n const { min, max } = numberLimits(field);\n return [min, max, 0, 1].filter((v): v is number => v !== undefined);\n },\n },\n {\n type: \"date\",\n label: \"Date\",\n category: \"date\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"answered\", \"empty\"],\n a11y: { semantics: \"control\" },\n validate: (value, field) => {\n if (typeof value !== \"string\" || !isIsoDate(value.trim())) return \"Enter a date like 2026-10-22.\";\n const date = value.trim();\n const { min, max } = dateLimits(field);\n if (min && max && (date < min || date > max)) return `Choose a date from ${min} to ${max}.`;\n if (min && date < min) return `Choose ${min} or later.`;\n if (max && date > max) return `Choose ${max} or earlier.`;\n return null;\n },\n normalize: (value) => (typeof value === \"string\" ? value.trim() : value),\n samples: (field) => {\n const { min, max } = dateLimits(field);\n return [min ?? max ?? \"2000-01-01\"];\n },\n },\n {\n type: \"consent\",\n label: \"Consent checkbox\",\n category: \"choice\",\n value: { json: true },\n operators: [\"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n // Unchecked is unanswered, so a required consent must be checked.\n isEmpty: (value) => value === undefined || value === null || value === false,\n validate: (value) => (value === true ? null : \"Check the box to agree.\"),\n summarize: () => \"Agreed\",\n samples: () => [true],\n },\n];\n\n/** The optional words under the ends of a rating or NPS scale (\"Poor\", \"Great\"). */\nexport function scaleLabels(field: FieldBlock): { low?: string; high?: string } {\n const out: { low?: string; high?: string } = {};\n const low = field.props?.lowLabel;\n const high = field.props?.highLabel;\n if (typeof low === \"string\" && low.trim()) out.low = low.trim();\n if (typeof high === \"string\" && high.trim()) out.high = high.trim();\n return out;\n}\n\n/** How a rating is drawn: `\"numbers\"` (default) or `\"stars\"`. */\nexport function ratingDisplay(field: FieldBlock): \"numbers\" | \"stars\" {\n return field.props?.display === \"stars\" ? \"stars\" : \"numbers\";\n}\n\nfunction scaleEndLabel(field: FieldBlock, value: number, min: number, max: number): string | undefined {\n const { low, high } = scaleLabels(field);\n return value === min ? low : value === max ? high : undefined;\n}\n\nconst finite = (v: Json | undefined): number | undefined =>\n typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n\n/** A `number` field's limits: `min`, `max` and `step` (each optional; `step` is above 0). */\nexport function numberLimits(field: FieldBlock): { min?: number; max?: number; step?: number } {\n const out: { min?: number; max?: number; step?: number } = {};\n const min = finite(field.props?.min);\n const max = finite(field.props?.max);\n const step = finite(field.props?.step);\n if (min !== undefined) out.min = min;\n if (max !== undefined) out.max = max;\n if (step !== undefined && step > 0) out.step = step;\n return out;\n}\n\n/** Whether `value` is `base` plus a whole number of `step`s, allowing for floating-point error. */\nfunction onStep(value: number, base: number, step: number): boolean {\n const n = (value - base) / step;\n return Math.abs(n - Math.round(n)) < 1e-9 * Math.max(1, Math.abs(n));\n}\n\n/** `YYYY-MM-DD`, a real calendar day (no 2026-02-30), years 0001 to 9999. */\nexport function isIsoDate(value: string): boolean {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return false;\n const [y, m, d] = value.split(\"-\").map(Number) as [number, number, number];\n if (y < 1 || m < 1 || m > 12 || d < 1) return false;\n const days = [31, y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n return d <= days[m - 1]!;\n}\n\n/** A `date` field's earliest and latest days (`YYYY-MM-DD`), when set. */\nexport function dateLimits(field: FieldBlock): { min?: string; max?: string } {\n const out: { min?: string; max?: string } = {};\n const min = field.props?.min;\n const max = field.props?.max;\n if (typeof min === \"string\" && isIsoDate(min)) out.min = min;\n if (typeof max === \"string\" && isIsoDate(max)) out.max = max;\n return out;\n}\n\nfor (const manifest of [...builtins, ...structuredFieldTypes, calculatedFieldType, photoFieldType]) registerFieldType(manifest);\n","import { isEmptyValue } from \"./fields\";\nimport type { Block, Condition, FieldBlock, FormDefinition, Json, LogicRule, Operand } from \"./types\";\n\nexport interface EvalScope {\n values: Record<string, Json | undefined>;\n hidden: Record<string, Json | undefined>;\n fields: Map<string, FieldBlock>;\n}\n\n/** `record[key]` if it is the record's own property: `values.constructor` is not an answer. */\nexport function own<T>(record: Record<string, T>, key: string): T | undefined {\n return Object.prototype.hasOwnProperty.call(record, key) ? record[key] : undefined;\n}\n\nfunction resolve(operand: Operand, scope: EvalScope): Json | undefined {\n if (\"field\" in operand) return own(scope.values, operand.field);\n if (\"hidden\" in operand) return own(scope.hidden, operand.hidden);\n return operand.value;\n}\n\nfunction deepEqual(a: Json | undefined, b: Json | undefined): boolean {\n if (a === b) return true;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));\n }\n return false;\n}\n\n/**\n * Evaluate a condition. Never throws. An empty value (unanswered, `null`,\n * blank text, an empty list: see `isEmptyValue`) is unanswered: it fails\n * every comparison, including `eq`, `in` and `contains`, and passes `neq`.\n */\nexport function evaluate(condition: Condition, scope: EvalScope): boolean {\n if (\"all\" in condition) return condition.all.every((c) => evaluate(c, scope));\n if (\"any\" in condition) return condition.any.some((c) => evaluate(c, scope));\n if (\"not\" in condition) return !evaluate(condition.not, scope);\n\n const left = resolve(condition.left, scope);\n const right = condition.right ? resolve(condition.right, scope) : undefined;\n const field = \"field\" in condition.left ? scope.fields.get(condition.left.field) : undefined;\n const unanswered = isEmptyValue(left, field);\n\n switch (condition.op) {\n case \"answered\":\n return !unanswered;\n case \"empty\":\n return unanswered;\n case \"eq\":\n return !unanswered && deepEqual(left, right);\n case \"neq\":\n // An unanswered field is \"not\" any value.\n return unanswered || !deepEqual(left, right);\n case \"lt\":\n case \"lte\":\n case \"gt\":\n case \"gte\": {\n if (typeof left !== \"number\" || typeof right !== \"number\") return false;\n if (condition.op === \"lt\") return left < right;\n if (condition.op === \"lte\") return left <= right;\n if (condition.op === \"gt\") return left > right;\n return left >= right;\n }\n case \"in\":\n return !unanswered && Array.isArray(right) && right.some((r) => deepEqual(r, left));\n case \"contains\":\n if (unanswered) return false;\n if (Array.isArray(left)) return left.some((l) => deepEqual(l, right));\n return (\n typeof left === \"string\" &&\n typeof right === \"string\" &&\n left.toLowerCase().includes(right.toLowerCase())\n );\n }\n}\n\n/** Blocks a respondent steps through: fields and content, in order. */\nexport function steps(def: FormDefinition): Block[] {\n return def.blocks.filter((b) => b.kind !== \"page-break\");\n}\n\nfunction visibilityRules(def: FormDefinition, blockId: string) {\n return (def.logic ?? []).filter(\n (r): r is Extract<LogicRule, { target: string }> =>\n (r.effect === \"show\" || r.effect === \"hide\") && r.target === blockId,\n );\n}\n\n/** Whether a field is withheld because the form is anonymous and the field identifies the respondent. */\nexport function withheld(def: FormDefinition, field: FieldBlock | undefined): boolean {\n return def.settings?.anonymous === true && field?.identifying === true;\n}\n\n/** Show/hide rules against a scope as given. A matching `hide` wins; any `show` must match. */\nfunction rulesAllow(def: FormDefinition, blockId: string, scope: EvalScope): boolean {\n if (withheld(def, scope.fields.get(blockId))) return false;\n const rules = visibilityRules(def, blockId);\n if (rules.some((r) => r.effect === \"hide\" && evaluate(r.when, scope))) return false;\n const shows = rules.filter((r) => r.effect === \"show\");\n return shows.length === 0 || shows.some((r) => evaluate(r.when, scope));\n}\n\nexport interface PathResult {\n /** Block ids the respondent will step through, given the answers on the path. */\n path: string[];\n /** The ending reached by a jump, or the default ending. */\n ending: string | null;\n}\n\nexport interface PathWalk extends PathResult {\n /**\n * The scope logic sees at a block: the values of the fields on the path\n * before it (and of the block itself, with `inclusive`), nothing else.\n */\n scopeAt(blockId: string, inclusive?: boolean): EvalScope;\n}\n\n/** One forward pass over the blocks. See `computePath`. */\nexport function walkPath(def: FormDefinition, scope: EvalScope): PathWalk {\n const list = steps(def);\n // Built only when needed: an engine walks the path on every step.\n let index: Map<string, number> | undefined;\n let position: Map<string, number> | undefined;\n const jumps = (def.logic ?? []).filter(\n (r): r is Extract<LogicRule, { effect: \"jump\" }> => r.effect === \"jump\",\n );\n const defaultEnding = def.endings?.find((e) => e.id === \"default\")?.id ?? def.endings?.[0]?.id ?? null;\n\n // Values of the fields placed on the path so far. It only grows, so every\n // decision reads blocks already placed and the pass needs no fixed point.\n const placed = Object.create(null) as Record<string, Json | undefined>;\n const local: EvalScope = { values: placed, hidden: scope.hidden, fields: scope.fields };\n const path: string[] = [];\n const nextVisible = (from: number) => {\n for (let i = from; i < list.length; i++) if (rulesAllow(def, list[i]!.id, local)) return i;\n return list.length;\n };\n\n let ending = defaultEnding;\n let i = nextVisible(0);\n while (i < list.length) {\n const block = list[i]!;\n path.push(block.id);\n if (block.kind === \"field\") placed[block.id] = own(scope.values, block.id);\n const jump = jumps.find((r) => r.from === block.id && evaluate(r.when, local));\n if (jump) {\n if (typeof jump.to === \"object\") {\n ending = jump.to.ending;\n break;\n }\n index ??= new Map(list.map((b, at) => [b.id, at]));\n const target = index.get(jump.to);\n if (target !== undefined && target > i) {\n i = nextVisible(target);\n continue;\n }\n }\n i = nextVisible(i + 1);\n }\n\n const scopeAt = (blockId: string, inclusive = false): EvalScope => {\n position ??= new Map(def.blocks.map((b, i) => [b.id, i]));\n const at = position.get(blockId) ?? -1;\n const values = Object.create(null) as Record<string, Json | undefined>;\n for (const id of path) {\n const p = position!.get(id)!;\n if (p > at || (p === at && !inclusive)) break;\n if (id in placed) values[id] = placed[id];\n }\n return { values, hidden: scope.hidden, fields: scope.fields };\n };\n return { path, ending, scopeAt };\n}\n\n/**\n * The respondent's path, derived from the answers on the path, so the client,\n * the server and a replay always agree. It is built in one forward pass: a\n * block's show/hide rules, and the jumps from it, see only the fields already\n * on the path before it (and, for a jump, the block itself). A field that is\n * hidden, jumped over or later in the form reads as unanswered, whatever\n * value it holds.\n *\n * A block jumped over is off the path and counts as hidden: it is not\n * validated and its value is cleared on submit. A jump never revisits a block;\n * a jump to an earlier block is ignored (the checker in `parseForm` reports it).\n */\nexport function computePath(def: FormDefinition, scope: EvalScope): PathResult {\n const { path, ending } = walkPath(def, scope);\n return { path, ending };\n}\n\n/**\n * Whether a block's show/hide rules let it be shown, ignoring jumps. The rules\n * read the answers on the path before the block, as in `computePath`. A block\n * with any `show` rule is hidden until one matches; a matching `hide` rule\n * always wins.\n */\nexport function ruleVisible(def: FormDefinition, blockId: string, scope: EvalScope): boolean {\n return rulesAllow(def, blockId, walkPath(def, scope).scopeAt(blockId));\n}\n\nexport function fieldMap(def: FormDefinition): Map<string, FieldBlock> {\n const map = new Map<string, FieldBlock>();\n for (const block of def.blocks) if (block.kind === \"field\") map.set(block.id, block);\n return map;\n}\n","import { summarizeValue } from \"./fields\";\nimport { own } from \"./logic\";\nimport type { FieldBlock, Json } from \"./types\";\n\nconst TOKEN = /\\{\\{\\s*(field|hidden):([A-Za-z0-9_-]+)\\s*(?:\\|([^}]*))?\\}\\}/g;\n\nexport interface RecallScope {\n /** Fields by key. */\n fieldsByKey: Map<string, FieldBlock>;\n values: Record<string, Json | undefined>;\n hidden: Record<string, Json | undefined>;\n}\n\n/**\n * Replace `{{field:key|fallback}}` and `{{hidden:name|fallback}}` tokens.\n * An unanswered value renders its fallback (default empty); the text is\n * never dropped.\n */\nexport function recall(text: string, scope: RecallScope): string {\n return text.replace(TOKEN, (_match, kind: string, name: string, fallback?: string) => {\n if (kind === \"field\") {\n const field = scope.fieldsByKey.get(name);\n const out = field ? summarizeValue(own(scope.values, field.id), field) : \"\";\n return out || (fallback ?? \"\").trim();\n }\n const value = own(scope.hidden, name);\n const out = value === undefined || value === null ? \"\" : String(value);\n return out || (fallback ?? \"\").trim();\n });\n}\n\n/** The keys a text recalls, for the checker. */\nexport function recallRefs(text: string): { kind: \"field\" | \"hidden\"; name: string }[] {\n return [...text.matchAll(TOKEN)].map((m) => ({ kind: m[1] as \"field\" | \"hidden\", name: m[2]! }));\n}\n","/**\n * One response as a flat row: the shape the sheet appends, the email lists\n * and the webhook sends alongside the raw answers.\n */\nimport { getFieldType, isEmptyValue, isSensitive, summarizeValue } from \"../fields\";\nimport { own, withheld } from \"../logic\";\nimport { recall } from \"../recall\";\nimport type { FieldBlock, FormDefinition, Json } from \"../types\";\nimport type { Cell, DeliverySubmission } from \"./types\";\n\nexport interface RowOptions {\n /**\n * Fields marked `sensitive`: `\"include\"` their values (default), `\"mask\"`\n * them as `[sensitive]`, or `\"omit\"` their columns.\n */\n sensitive?: \"include\" | \"mask\" | \"omit\" | undefined;\n}\n\nexport interface ResponseRow {\n /** Cells by column key. */\n row: Record<string, Cell>;\n /** The column keys in order: `id`, `submitted_at`, the meta keys, then one per field key. */\n columns: string[];\n /** Field labels by key, recall filled in from this submission. */\n labels: Record<string, string>;\n}\n\nexport const SENSITIVE_MASK = \"[sensitive]\";\n\n// Never used as column keys, so a hostile meta key cannot touch a prototype.\nconst RESERVED = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n/**\n * One answer as a cell: numbers stay numbers (ratings, NPS), choices show\n * their labels, a list is joined with \", \", yes/no reads \"Yes\"/\"No\", and a\n * plugin type's `summarize` is used where it has one.\n */\nexport function answerCell(field: FieldBlock, value: Json | undefined): Cell {\n if (value === undefined || isEmptyValue(value, field)) return \"\";\n if (typeof value === \"number\") return value;\n const manifest = getFieldType(field.type);\n if (manifest?.summarize) return summarizeValue(value, field);\n if (typeof value === \"string\") return value;\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n if (Array.isArray(value) && value.every((v) => typeof v !== \"object\" || v === null)) {\n return value.map((v) => String(v)).join(\", \");\n }\n return JSON.stringify(value);\n}\n\n/**\n * The row for one submission. Columns: `id` (the response id), then\n * `submitted_at` when given, then the app's `meta` columns in order, then\n * one per field key in form order (blank when unanswered or hidden by\n * logic). Content blocks get no column. On an anonymous form, identifying\n * fields get no column at all, whatever the answers hold.\n */\nexport function responseRow(\n submission: DeliverySubmission,\n definition: FormDefinition,\n options: RowOptions = {},\n): ResponseRow {\n const row: Record<string, Cell> = {};\n const columns: string[] = [];\n const set = (key: string, value: Cell) => {\n if (RESERVED.has(key)) return;\n if (!Object.prototype.hasOwnProperty.call(row, key)) columns.push(key);\n row[key] = value;\n };\n set(\"id\", submission.id);\n if (submission.submittedAt !== undefined) set(\"submitted_at\", submission.submittedAt);\n for (const [key, value] of Object.entries(submission.meta ?? {})) {\n if (key !== \"id\" && key !== \"submitted_at\") set(key, value);\n }\n\n const fields = definition.blocks.filter((b): b is FieldBlock => b.kind === \"field\");\n const fieldsByKey = new Map(fields.map((f) => [f.key, f]));\n const sensitive = options.sensitive ?? \"include\";\n // Recall in a label must not leak what the row itself withholds or masks.\n const values: Record<string, Json> = {};\n for (const field of fields) {\n const value = own(submission.answers, field.id);\n if (value === undefined || withheld(definition, field)) continue;\n if (isSensitive(field) && sensitive !== \"include\") continue;\n values[field.id] = value;\n }\n const scope = { fieldsByKey, values, hidden: visibleInputs(submission, definition, sensitive) };\n const labels: Record<string, string> = {};\n for (const field of fields) {\n if (withheld(definition, field)) continue;\n if (isSensitive(field) && sensitive === \"omit\") continue;\n if (RESERVED.has(field.key)) continue;\n labels[field.key] = recall(field.label, scope).trim() || field.key;\n const cell = answerCell(field, own(submission.answers, field.id));\n set(field.key, isSensitive(field) && sensitive === \"mask\" && cell !== \"\" ? SENSITIVE_MASK : cell);\n }\n return { row, columns, labels };\n}\n\n/**\n * Hidden and server inputs as recall and the webhook may show them: on an\n * anonymous form identifying ones are left out, and sensitive ones are left\n * out unless `sensitive` is `\"include\"`.\n */\nexport function visibleInputs(\n submission: DeliverySubmission,\n definition: FormDefinition,\n sensitive: RowOptions[\"sensitive\"] = \"include\",\n): Record<string, Json> {\n const declared = new Map((definition.hidden ?? []).map((h) => [h.name, h]));\n const out: Record<string, Json> = {};\n for (const [name, value] of Object.entries({ ...submission.hidden, ...submission.context })) {\n const input = declared.get(name);\n if (RESERVED.has(name)) continue;\n if (input?.identifying && definition.settings?.anonymous === true) continue;\n if (input?.sensitive && sensitive !== \"include\") continue;\n out[name] = value;\n }\n return out;\n}\n\n/**\n * A cell that a spreadsheet will never run as a formula when the text is\n * opened elsewhere (a CSV export opened in Excel). Opt-in: use it when\n * writing CSV, not for the sheet destination, whose RAW writes are already\n * safe and would store the `'` literally. Text starting with `=`,\n * `@`, a tab or a carriage return gets a leading `'`, as OWASP recommends;\n * so does text starting with `+` or `-` unless it is only digits and\n * number punctuation (a phone number such as `+1 (555) 010-0000`, `-2.5`),\n * which cannot call a function or name a cell. Numbers and booleans are\n * returned as they are.\n */\nexport function escapeFormula(cell: Cell): Cell {\n if (typeof cell !== \"string\" || cell === \"\") return cell;\n const first = cell[0]!;\n if (first === \"=\" || first === \"@\" || first === \"\\t\" || first === \"\\r\") return `'${cell}`;\n if ((first === \"+\" || first === \"-\") && !/^[+-][\\d\\s().,+-]*$/.test(cell)) return `'${cell}`;\n return cell;\n}\n","/**\n * The email destination: one notification per submission, through any\n * provider that implements `EmailProvider`. `resendProvider` is built in.\n *\n * The body is built from the definition: each answered field's label (recall\n * filled in) and its value, in form order, after the app's meta columns.\n * Every value is HTML-escaped. Subjects and addresses are stripped of line\n * breaks and checked, so an answer can never add a header. Sensitive fields\n * are masked unless `sensitive: \"include\"` is set: an inbox is not a vault.\n */\nimport { isEmailAddress } from \"../fields\";\nimport { own } from \"../logic\";\nimport type { FormDefinition } from \"../types\";\nimport { responseRow, type ResponseRow, type RowOptions } from \"./row\";\nimport {\n configString,\n deliveryFailure,\n DeliveryError,\n discard,\n httpError,\n\n sha256Hex,\n timedFetch,\n type Cell,\n type DeliveryOptions,\n type DeliveryResult,\n type DeliverySubmission,\n type Destination,\n type DestinationConfig,\n type HttpDeps,\n} from \"./types\";\n\n/** One message, ready to send. Addresses are already checked. */\nexport interface EmailMessage {\n from: string;\n to: string[];\n replyTo?: string | undefined;\n subject: string;\n text: string;\n html: string;\n /** Stable across retries of one delivery: a provider that supports it sends once. */\n idempotencyKey: string;\n}\n\n/** Sends one message. Throws a `DeliveryError` (or any error) on failure. */\nexport interface EmailProvider {\n readonly name: string;\n send(message: EmailMessage, options: { signal?: AbortSignal | undefined }): Promise<void>;\n}\n\nexport interface EmailContent {\n subject: string;\n text: string;\n html: string;\n}\n\nexport interface EmailRenderInput {\n submission: DeliverySubmission;\n definition: FormDefinition;\n config: DestinationConfig;\n /** The submission as a row (sensitive values masked unless `sensitive: \"include\"`). */\n row: ResponseRow;\n}\n\n/** What the email destination reads from a destination's config. */\nexport interface EmailConfig {\n /** One address or a list (at most 50). */\n to: string | string[];\n /** Overrides the default subject (still stripped of line breaks). */\n subject?: string;\n}\n\nexport interface EmailDestinationOptions {\n provider: EmailProvider;\n /** `\"Feedback <feedback@send.example.com>\"` or a bare address. */\n from: string;\n /**\n * The Reply-To address: the key of an email field whose answer is used, or\n * a function returning an address (or null for none). Only a valid single\n * address is ever used.\n */\n replyTo?: string | ((input: EmailRenderInput) => string | null | undefined) | undefined;\n /** Builds the subject and bodies. Defaults to `renderEmail`. The subject is sanitized afterwards either way. */\n render?: ((input: EmailRenderInput) => EmailContent) | undefined;\n /** Sensitive fields: `\"mask\"` (default), `\"omit\"` or `\"include\"`. */\n sensitive?: RowOptions[\"sensitive\"];\n}\n\n/** Resend allows 50 recipients per email. */\nexport const MAX_RECIPIENTS = 50;\nconst MAX_SUBJECT_LENGTH = 200;\n\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/**\n * A header value on one line: control characters (CR, LF, NUL…) and Unicode\n * line separators become spaces, runs of spaces collapse, and it is cut to\n * `max` characters.\n */\nexport function headerSafe(text: string, max = MAX_SUBJECT_LENGTH): string {\n // eslint-disable-next-line no-control-regex\n const flat = text.replace(/[\\u0000-\\u001f\\u007f\\u2028\\u2029]+/g, \" \").replace(/\\s+/g, \" \").trim();\n return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;\n}\n\n/** A bare address that is safe as a header value: valid, one line, no display name. */\nexport function isSafeAddress(value: unknown): value is string {\n return typeof value === \"string\" && isEmailAddress(value) && !/[\\u0000-\\u001f\\u007f<>,;:\"()[\\]\\\\]/.test(value);\n}\n\n/**\n * A From value: a bare address, or `Name <address>` where the name has no\n * quotes, angle brackets or line breaks.\n */\nexport function isSafeFrom(value: string): boolean {\n const named = /^([^\"<>\\u0000-\\u001f\\u007f]{1,100}) <([^<>]+)>$/.exec(value);\n return named ? isSafeAddress(named[2]) : isSafeAddress(value);\n}\n\n/** Plain text and HTML bodies from label/value lines, every value escaped. */\nexport function emailBody(lines: readonly (readonly [string, Cell])[], footer?: string): { text: string; html: string } {\n const text = lines.map(([k, v]) => `${k}: ${v}`).join(\"\\n\") + (footer ? `\\n\\n${footer}` : \"\");\n // Paragraphs rather than a table: email clients render them alike everywhere.\n const font = \"font-family:sans-serif;font-size:14px;margin:0 0 12px\";\n const html =\n lines\n .map(\n ([k, v]) =>\n `<p style=\"${font}\"><span style=\"color:#666\">${escapeHtml(k)}</span><br>` +\n `<span style=\"white-space:pre-wrap\">${escapeHtml(String(v))}</span></p>`,\n )\n .join(\"\") +\n (footer ? `<p style=\"font-family:sans-serif;font-size:12px;color:#666\">${escapeHtml(footer)}</p>` : \"\");\n return { text, html };\n}\n\n/**\n * The default notification: subject `\"<form title>: new response\"` (or\n * `config.subject`), then the meta columns, each answered field by label,\n * the ending's title when the form has several, and the response id.\n */\nexport function renderEmail(input: EmailRenderInput): EmailContent {\n const { submission, definition, config, row } = input;\n const lines: [string, Cell][] = [];\n const fieldKeys = new Set(Object.keys(row.labels));\n for (const key of row.columns) {\n if (key === \"id\") continue;\n const value = row.row[key];\n if (value === undefined || value === \"\") continue;\n const label = fieldKeys.has(key) ? row.labels[key]! : key === \"submitted_at\" ? \"Submitted\" : key;\n lines.push([label, value]);\n }\n const endings = definition.endings ?? [];\n if (submission.ending && endings.length > 1) {\n const ending = endings.find((e) => e.id === submission.ending);\n if (ending) lines.push([\"Ending\", ending.title]);\n }\n if (!lines.length) lines.push([\"Answers\", \"(none)\"]);\n const subject = configString(config, \"subject\") || `${definition.title || definition.id}: new response`;\n return { subject, ...emailBody(lines, `Response ${submission.id}`) };\n}\n\n/** Recipients from config: a string or a list, each checked. Throws when there are none or too many. */\nfunction recipients(config: DestinationConfig): string[] {\n const raw = config[\"to\"];\n const list = (Array.isArray(raw) ? raw : typeof raw === \"string\" ? raw.split(\",\") : []).map((t) =>\n typeof t === \"string\" ? t.trim() : t,\n );\n const to = [...new Set(list.filter(isSafeAddress))];\n if (to.length !== list.filter((t) => t !== \"\").length) {\n throw new DeliveryError(\"The email destination has an invalid recipient\");\n }\n if (!to.length) throw new DeliveryError(\"The email destination has no recipients\");\n if (to.length > MAX_RECIPIENTS) throw new DeliveryError(`The email destination has more than ${MAX_RECIPIENTS} recipients`);\n return to;\n}\n\nfunction replyToAddress(option: EmailDestinationOptions[\"replyTo\"], input: EmailRenderInput): string | undefined {\n if (!option) return undefined;\n let value: unknown;\n if (typeof option === \"function\") value = option(input);\n else {\n const field = input.definition.blocks.find((b) => b.kind === \"field\" && b.key === option);\n value = field ? own(input.submission.answers, field.id) : undefined;\n // An anonymous form never gives away an identifying answer, not even as Reply-To.\n if (field?.kind === \"field\" && field.identifying && input.definition.settings?.anonymous) value = undefined;\n }\n const trimmed = typeof value === \"string\" ? value.trim() : value;\n return isSafeAddress(trimmed) ? trimmed : undefined;\n}\n\n/**\n * The idempotency key: the delivery id and the first 16 hex digits of\n * SHA-256 of the sorted recipients, so a retried delivery never sends twice\n * and one whose recipients changed meanwhile is a new send.\n */\nexport async function idempotencyKey(deliveryId: string, to: readonly string[]): Promise<string> {\n const hex = await sha256Hex([...to].sort().join(\",\"));\n return `${deliveryId.slice(0, 200)}:${hex.slice(0, 16)}`;\n}\n\nexport function emailDestination(options: EmailDestinationOptions): Destination {\n return {\n kind: \"email\",\n async deliver(submission, definition, config, deliveryOptions: DeliveryOptions = {}): Promise<DeliveryResult> {\n try {\n if (!isSafeFrom(options.from)) throw new DeliveryError(\"The email destination's from address is invalid\");\n const to = recipients(config);\n const row = responseRow(submission, definition, { sensitive: options.sensitive ?? \"mask\" });\n const input: EmailRenderInput = { submission, definition, config, row };\n const content = (options.render ?? renderEmail)(input);\n const replyTo = replyToAddress(options.replyTo, input);\n await options.provider.send(\n {\n from: options.from,\n to,\n ...(replyTo ? { replyTo } : {}),\n subject: headerSafe(content.subject) || \"New response\",\n text: content.text,\n html: content.html,\n idempotencyKey: await idempotencyKey(deliveryOptions.deliveryId ?? submission.id, to),\n },\n { signal: deliveryOptions.signal },\n );\n return { ok: true };\n } catch (error) {\n return deliveryFailure(error);\n }\n },\n };\n}\n\nexport const RESEND_API = \"https://api.resend.com/emails\";\n\nexport interface ResendOptions extends HttpDeps {\n apiKey: string;\n /** Default `RESEND_API`. */\n endpoint?: string | undefined;\n}\n\n/**\n * Resend's REST API. Sends the idempotency key, so a retry within Resend's\n * 24-hour window never sends twice. A 409 for a concurrent request with the\n * same key is retried; one for a key reused with a different body is not.\n */\nexport function resendProvider(options: ResendOptions): EmailProvider {\n return {\n name: \"resend\",\n async send(message, { signal }) {\n if (!options.apiKey) throw new DeliveryError(\"The Resend API key is not set\");\n const response = await timedFetch(\n options,\n options.endpoint ?? RESEND_API,\n {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${options.apiKey}`,\n \"content-type\": \"application/json\",\n \"idempotency-key\": message.idempotencyKey,\n },\n body: JSON.stringify({\n from: message.from,\n to: message.to,\n subject: message.subject,\n text: message.text,\n html: message.html,\n ...(message.replyTo ? { reply_to: message.replyTo } : {}),\n }),\n },\n signal,\n );\n if (response.ok) {\n discard(response);\n return;\n }\n // Resend's error `name` (such as \"validation_error\") is safe to keep; its message may echo input.\n let name: string | undefined;\n try {\n const body = (await response.json()) as { name?: unknown };\n if (typeof body.name === \"string\" && /^[a-z_]{1,64}$/.test(body.name)) name = body.name;\n } catch {\n // Not JSON.\n }\n if (response.status === 409 && name === \"concurrent_idempotent_requests\") {\n throw new DeliveryError(\"Resend answered 409 (concurrent_idempotent_requests)\", {\n retryable: true,\n retryAfterSeconds: 5,\n status: 409,\n });\n }\n throw httpError(\"Resend\", response, name);\n },\n };\n}\n","/**\n * An access token for a Google service account by the OAuth 2.0 JWT bearer\n * flow: sign a JWT with the account's private key (RS256, WebCrypto) and\n * trade it at Google's token endpoint. No googleapis dependency, so it runs\n * on Node 20+, edge runtimes and Workers alike.\n */\nimport {\n base64url,\n DeliveryError,\n discard,\n fromBase64,\n httpError,\n sha256Hex,\n timedFetch,\n type HttpDeps,\n type WebCryptoKey,\n} from \"./types\";\n\nexport const GOOGLE_TOKEN_URL = \"https://oauth2.googleapis.com/token\";\nexport const SHEETS_SCOPE = \"https://www.googleapis.com/auth/spreadsheets\";\n\nexport interface GoogleServiceAccount {\n /** The service account's `client_email`. */\n clientEmail: string;\n /** Its `private_key`: a PKCS#8 PEM. The `\\n`-escaped form env vars often hold is accepted. */\n privateKey: string;\n}\n\n/** The PKCS#8 key bytes from a PEM. */\nfunction pemToPkcs8(pem: string): Uint8Array<ArrayBuffer> {\n const text = pem.replace(/\\\\n/g, \"\\n\");\n if (/-----BEGIN RSA PRIVATE KEY-----/.test(text)) {\n throw new DeliveryError(\"The Google private key is PKCS#1; convert it to PKCS#8 (BEGIN PRIVATE KEY)\");\n }\n const body = text.replace(/-----(BEGIN|END) PRIVATE KEY-----/g, \"\").replace(/\\s+/g, \"\");\n return fromBase64(body);\n}\n\n/** A signed RS256 JWT. Throws a `DeliveryError` when the key is not a valid PKCS#8 RSA key. */\nexport async function signJwt(claims: Record<string, unknown>, privateKeyPem: string): Promise<string> {\n let key: WebCryptoKey;\n try {\n key = await crypto.subtle.importKey(\n \"pkcs8\",\n pemToPkcs8(privateKeyPem),\n { name: \"RSASSA-PKCS1-v1_5\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n } catch (error) {\n if (error instanceof DeliveryError) throw error;\n // Never the key or the platform's message, which may quote it.\n throw new DeliveryError(\"The Google private key is not a valid PKCS#8 RSA key\");\n }\n const unsigned = `${base64url(JSON.stringify({ alg: \"RS256\", typ: \"JWT\" }))}.${base64url(JSON.stringify(claims))}`;\n const signature = await crypto.subtle.sign(\"RSASSA-PKCS1-v1_5\", key, new TextEncoder().encode(unsigned));\n return `${unsigned}.${base64url(new Uint8Array(signature))}`;\n}\n\n// One per process, shared by every destination: a token is good for an hour.\nconst cache = new Map<string, { token: string; expiresAt: number }>();\n\n/** Forgets cached tokens (tests, or after rotating a key). */\nexport function clearGoogleTokenCache(): void {\n cache.clear();\n}\n\nexport interface GoogleTokenOptions extends HttpDeps {\n scope?: string | undefined;\n now?: (() => number) | undefined;\n signal?: AbortSignal | undefined;\n}\n\n/** A cached or fresh access token. Throws a `DeliveryError` with a safe message on failure. */\nexport async function googleAccessToken(account: GoogleServiceAccount, options: GoogleTokenOptions = {}): Promise<string> {\n const { clientEmail, privateKey } = account;\n if (!clientEmail || !privateKey) throw new DeliveryError(\"The Google service account email or private key is not set\");\n const scope = options.scope ?? SHEETS_SCOPE;\n const now = options.now?.() ?? Date.now();\n // The key's digest is part of the cache key: a hit returns a token without\n // signing anything, so email + scope alone would hand one tenant's live\n // token to any config naming that email with any key, and keep a rotated\n // or wrong key working until the token expires.\n const cacheKey = `${clientEmail} ${scope} ${await sha256Hex(privateKey.replace(/\\\\n/g, \"\\n\").trim())}`;\n const hit = cache.get(cacheKey);\n if (hit && hit.expiresAt - 60_000 > now) return hit.token;\n\n const iat = Math.floor(now / 1000);\n const assertion = await signJwt({ iss: clientEmail, scope, aud: GOOGLE_TOKEN_URL, iat, exp: iat + 3600 }, privateKey);\n const response = await timedFetch(\n options,\n GOOGLE_TOKEN_URL,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({ grant_type: \"urn:ietf:params:oauth:grant-type:jwt-bearer\", assertion }).toString(),\n },\n options.signal,\n );\n if (!response.ok) {\n discard(response);\n throw httpError(\"Google token endpoint\", response);\n }\n const body = (await response.json()) as { access_token?: unknown; expires_in?: unknown };\n if (typeof body.access_token !== \"string\") throw new DeliveryError(\"Google token endpoint returned no access token\", { retryable: true });\n const ttl = typeof body.expires_in === \"number\" ? body.expires_in * 1000 : 3_600_000;\n cache.set(cacheKey, { token: body.access_token, expiresAt: now + ttl });\n return body.access_token;\n}\n","/**\n * The Google Sheets destination: appends one row per submission to a sheet\n * shared with a Google service account, or reached with an access token the\n * app supplies (a sheet a person connected with Google sign-in). Config:\n * `{ spreadsheetId, sheetName? }` (`spreadsheet_id` and `sheet_name` are\n * accepted too). An update (the delivery of an edit) overwrites the\n * response's row where it is, and is appended only when that row is gone.\n *\n * The tab is created when missing, the header row is written from the row's\n * column keys and gains a column for any new key without moving the others,\n * and an `id` column holds the response id, so a redelivery is not appended\n * twice. Every write is `valueInputOption=RAW`, so Sheets stores text as\n * typed and never runs it as a formula: `@team thanks` stays exactly that.\n * Text is therefore not escaped by default (a `'` would be stored literally).\n * Set `escapeFormulas` only when the sheet's text is exported and opened in\n * another spreadsheet that might run it (see `escapeFormula`).\n *\n * Quota: Google allows a service account about 60 reads and 60 writes a\n * minute. So the tab id, header and last row are kept in the destination's\n * state, and a normal delivery is one write: the append. The tab and header\n * are read again only when a row has a key the cached header lacks, or when\n * an append is refused. The id column is read only on a redelivery, and then\n * only its recent rows. `deliverBatch` appends many rows in one request.\n */\nimport type { Json } from \"../types\";\nimport { googleAccessToken, type GoogleServiceAccount } from \"./google-auth\";\nimport { escapeFormula, responseRow, type RowOptions } from \"./row\";\nimport {\n configString,\n deliveryFailure,\n DeliveryError,\n discard,\n httpError,\n resolveOption,\n timedFetch,\n type Cell,\n type DeliveryItem,\n type DeliveryOptions,\n type DeliveryResult,\n type Destination,\n type DestinationConfig,\n type HttpDeps,\n type OptionResolver,\n} from \"./types\";\n\nexport const SHEETS_API = \"https://sheets.googleapis.com/v4/spreadsheets\";\nexport const DEFAULT_SHEET_NAME = \"Responses\";\n/** How many of the latest rows a redelivery checks for its id. */\nexport const DEDUPE_WINDOW = 500;\n/**\n * How many rows the header read looks at to find the columns in use: the\n * header row and the first responses under it. Bounded, so a tab with years\n * of responses is never read whole just to learn its header.\n */\nexport const HEADER_SCAN_ROWS = 100;\n/** Header writes tried before a concurrent writer is reported as a retryable failure. */\nconst HEADER_WRITE_ATTEMPTS = 3;\n\n/** What the sheet destination reads from a destination's config. */\nexport interface SheetConfig {\n spreadsheetId: string;\n /** Default `\"Responses\"`. */\n sheetName?: string;\n}\n\nexport interface SheetsDestinationOptions extends HttpDeps {\n /**\n * The service account the sheet is shared with, or a function that finds\n * the one for a destination's config. Give this or `accessToken`.\n */\n account?: GoogleServiceAccount | OptionResolver<GoogleServiceAccount> | undefined;\n /**\n * An access token for the sheet instead of a service account: a sheet a\n * person connected with Google sign-in, say (see `googleOAuthAccessToken`).\n * Gets the config and `{ destinationId }`; called once per delivery or\n * batch, so cache inside it.\n */\n accessToken?: OptionResolver<string> | undefined;\n /**\n * Prefix text a spreadsheet could run as a formula with `'` (see\n * `escapeFormula`), headers included. Default false: writes are RAW, so\n * Sheets never runs text as a formula, and the `'` would be stored as part\n * of the text. Turn it on only if the sheet is exported as CSV and opened\n * in another spreadsheet. Keep one setting per sheet: header keys are\n * escaped too, so switching it later adds new columns for escaped keys.\n */\n escapeFormulas?: boolean | undefined;\n /** Sensitive fields: `\"include\"` (default), `\"mask\"` or `\"omit\"`. */\n sensitive?: RowOptions[\"sensitive\"];\n now?: (() => number) | undefined;\n}\n\n/**\n * The existing header plus any keys it does not have yet, in the order they\n * arrive. A blank header cell keeps its place (dropping it would shift every\n * later column away from the values stored under it), as do blank header\n * cells over the `width` columns that hold responses; only blanks beyond\n * those are trimmed.\n */\nexport function mergeHeader(existing: readonly unknown[], keys: readonly string[], width = 0): string[] {\n const header = existing.map((h) => (h == null ? \"\" : String(h)));\n while (header.length < width) header.push(\"\");\n while (header.length > width && header[header.length - 1] === \"\") header.pop();\n for (const key of keys) if (key && !header.includes(key)) header.push(key);\n return header;\n}\n\n/** One cell per header column, blank where the row has no value; `escape` applies `escapeFormula` (default false). */\nexport function rowFor(header: readonly string[], row: Record<string, Cell>, escape = false): Cell[] {\n return header.map((h) => {\n const cell = Object.prototype.hasOwnProperty.call(row, h) ? (row[h] ?? \"\") : \"\";\n return escape ? escapeFormula(cell) : cell;\n });\n}\n\n/** A1 column letters: 0 → A, 25 → Z, 26 → AA. */\nexport function columnLetter(index: number): string {\n let n = index + 1;\n let s = \"\";\n while (n > 0) {\n const r = (n - 1) % 26;\n s = String.fromCharCode(65 + r) + s;\n n = Math.floor((n - 1) / 26);\n }\n return s;\n}\n\nconst quoteSheet = (name: string) => `'${name.replace(/'/g, \"''\")}'`;\n\n/** What the destination keeps between deliveries. Opaque to the app: store and pass it back. */\nexport interface SheetState {\n spreadsheet_id: string;\n sheet_name: string;\n sheet_id: number;\n header: string[];\n columns: number;\n /** The last row an append wrote (1-based), 0 when unknown. */\n last_row: number;\n}\n\nfunction readState(raw: Record<string, Json> | undefined, spreadsheetId: string, sheetName: string): SheetState | null {\n if (!raw) return null;\n const header = raw[\"header\"];\n if (\n raw[\"spreadsheet_id\"] !== spreadsheetId ||\n raw[\"sheet_name\"] !== sheetName ||\n typeof raw[\"sheet_id\"] !== \"number\" ||\n !Array.isArray(header) ||\n !header.every((h) => typeof h === \"string\") ||\n !header.includes(\"id\")\n ) {\n return null;\n }\n return {\n spreadsheet_id: spreadsheetId,\n sheet_name: sheetName,\n sheet_id: raw[\"sheet_id\"],\n header: header as string[],\n columns: typeof raw[\"columns\"] === \"number\" ? raw[\"columns\"] : header.length,\n last_row: typeof raw[\"last_row\"] === \"number\" ? raw[\"last_row\"] : 0,\n };\n}\n\n/** An append Google refused for a reason a fresh look at the tab may fix (renamed, deleted or resized). */\nclass StaleSheetError extends DeliveryError {}\n\ninterface SheetProps {\n sheetId: number;\n title: string;\n gridProperties?: { columnCount?: number };\n}\n\nfunction configOf(config: DestinationConfig) {\n const spreadsheetId = configString(config, \"spreadsheetId\", \"spreadsheet_id\");\n if (!spreadsheetId) throw new DeliveryError(\"The sheet destination has no spreadsheetId\");\n if (!/^[A-Za-z0-9_-]{10,200}$/.test(spreadsheetId)) throw new DeliveryError(\"The sheet destination's spreadsheetId is invalid\");\n const sheetName = configString(config, \"sheetName\", \"sheet_name\") || DEFAULT_SHEET_NAME;\n if (sheetName.length > 100) throw new DeliveryError(\"The sheet destination's sheetName is too long\");\n return { spreadsheetId, sheetName };\n}\n\nexport function sheetsDestination(options: SheetsDestinationOptions): Destination {\n async function run(\n items: readonly DeliveryItem[],\n config: DestinationConfig,\n deliveryOptions: Omit<DeliveryOptions, \"deliveryId\">,\n ): Promise<DeliveryResult> {\n if (!items.length) return { ok: true };\n const { spreadsheetId, sheetName } = configOf(config);\n const signal = deliveryOptions.signal;\n const context = { destinationId: deliveryOptions.destinationId };\n let account: GoogleServiceAccount | null = null;\n let token: string;\n if (options.accessToken) {\n token = await resolveOption(\"The sheet destination's access token\", options.accessToken, config, context);\n if (typeof token !== \"string\" || !token) throw new DeliveryError(\"The sheet destination has no access token\");\n } else if (options.account) {\n account = await resolveOption(\"The sheet destination's account\", options.account, config, context);\n token = await googleAccessToken(account, { ...options, signal });\n } else {\n throw new DeliveryError(\"The sheet destination has neither an account nor an access token\");\n }\n const sharedWith = account\n ? `is the sheet shared with ${account.clientEmail}?`\n : \"is the sheet still connected to its Google account?\";\n const base = `${SHEETS_API}/${encodeURIComponent(spreadsheetId)}`;\n const escape = options.escapeFormulas === true;\n\n const call = async <T>(what: string, url: string, init: RequestInit = {}): Promise<T> => {\n const response = await timedFetch(\n options,\n url,\n { ...init, headers: { authorization: `Bearer ${token}`, \"content-type\": \"application/json\" } },\n signal,\n );\n if (!response.ok) {\n discard(response);\n if ((what === \"append\" || what === \"update rows\") && (response.status === 400 || response.status === 404)) {\n throw new StaleSheetError(`Google Sheets append answered ${response.status}`, { status: response.status });\n }\n if (response.status === 403 || response.status === 404) {\n throw new DeliveryError(\n `Google Sheets ${what} answered ${response.status}: ${sharedWith}`,\n { status: response.status },\n );\n }\n throw httpError(`Google Sheets ${what}`, response);\n }\n return (await response.json()) as T;\n };\n const batchUpdate = (what: string, requests: unknown[]) =>\n call<{ replies?: { addSheet?: { properties?: SheetProps } }[] }>(what, `${base}:batchUpdate`, {\n method: \"POST\",\n body: JSON.stringify({ requests }),\n });\n const range = (a1: string) => `${base}/values/${encodeURIComponent(`${quoteSheet(sheetName)}!${a1}`)}`;\n\n const sensitive = options.sensitive ?? \"include\";\n // Column keys are escaped like cells (a builder-made key could start with \"=\"),\n // so the header as stored and read back matches the keys looked up in it.\n const columnKey = (key: string) => (escape ? String(escapeFormula(key)) : key);\n const rows = items.map((item) => {\n const { row, columns } = responseRow(item.submission, item.definition, { sensitive });\n const escaped: Record<string, Cell> = {};\n for (const key of columns) escaped[columnKey(key)] = row[key]!;\n return { row: escaped, columns: columns.map(columnKey) };\n });\n const keys = [...new Set(rows.flatMap((r) => r.columns))];\n\n /** Reads the tab and header, adds what is missing, and returns the fresh state. */\n async function setUp(previous: SheetState | null): Promise<SheetState> {\n const readTabs = async () => {\n const meta = await call<{ sheets?: { properties?: SheetProps }[] }>(\n \"read\",\n `${base}?fields=${encodeURIComponent(\"sheets.properties(sheetId,title,gridProperties.columnCount)\")}`,\n );\n return meta.sheets?.map((s) => s.properties).find((p) => p?.title === sheetName);\n };\n let sheet = await readTabs();\n if (!sheet) {\n try {\n const added = await batchUpdate(\"add tab\", [{ addSheet: { properties: { title: sheetName } } }]);\n sheet = added.replies?.[0]?.addSheet?.properties ?? { sheetId: 0, title: sheetName };\n } catch (error) {\n // Two first deliveries race: both saw no tab, and the loser's\n // addSheet answers 400 (\"already exists\"). Use the winner's tab.\n if (!(error instanceof DeliveryError) || error.status !== 400) throw error;\n sheet = await readTabs();\n if (!sheet) throw error;\n }\n }\n // Read by column: the values API drops trailing blank cells, so the header\n // row alone can look narrower than the responses under it (a column added\n // by hand). Column by column, the number returned is the width in use.\n const readHeader = async () => {\n const read = await call<{ values?: unknown[][] }>(\n \"read header\",\n `${range(`A1:ZZZ${HEADER_SCAN_ROWS}`)}?majorDimension=COLUMNS`,\n );\n const used = read.values ?? [];\n return { used: used.length, existing: used.map((column) => column[0] ?? \"\") };\n };\n let columns = sheet.gridProperties?.columnCount ?? 26;\n let { used, existing } = await readHeader();\n let header: string[] = [];\n // The header row is written whole, so two deliveries merging different\n // keys at once can overwrite each other. After a write, read it back: if\n // a key of ours is missing, merge onto what is there and write again.\n // The state keeps the header as read, so rows map onto the real columns.\n for (let attempt = 0; ; attempt++) {\n header = mergeHeader(existing, keys, used);\n // A new tab starts with the id column; one already in use gets it at the\n // end, so the columns already holding responses don't move.\n if (!header.includes(\"id\")) {\n if (used) header.push(\"id\");\n else header.unshift(\"id\");\n }\n const changed = header.length !== existing.length || header.some((h, i) => h !== String(existing[i] ?? \"\"));\n if (!changed) break;\n if (attempt >= HEADER_WRITE_ATTEMPTS) {\n throw new DeliveryError(\"Google Sheets header kept changing while it was written\", { retryable: true });\n }\n if (header.length > columns) {\n await batchUpdate(\"add columns\", [\n { appendDimension: { sheetId: sheet.sheetId, dimension: \"COLUMNS\", length: header.length - columns } },\n ]);\n columns = header.length;\n }\n await call(\"write header\", `${range(\"A1\")}?valueInputOption=RAW`, {\n method: \"PUT\",\n body: JSON.stringify({ values: [header] }),\n });\n if (existing.length === 0) {\n await batchUpdate(\"freeze header\", [\n {\n updateSheetProperties: {\n properties: { sheetId: sheet.sheetId, gridProperties: { frozenRowCount: 1 } },\n fields: \"gridProperties.frozenRowCount\",\n },\n },\n ]);\n }\n ({ used, existing } = await readHeader());\n }\n return {\n spreadsheet_id: spreadsheetId,\n sheet_name: sheetName,\n sheet_id: sheet.sheetId,\n header,\n columns,\n last_row: previous?.last_row ?? 0,\n };\n }\n\n let skipped: string[] = [];\n async function append(state: SheetState): Promise<SheetState> {\n // A redelivery may find its row already there: an earlier append went\n // through even though Google answered 5xx or the request timed out.\n // An update overwrites its response's row where it is, and is appended\n // only when that row is gone (deleted by hand, say).\n // One row per response: a batch holding a response twice (sent, then\n // edited) writes its latest version once, as an update if either was.\n const byId = new Map<string, { id: string; row: Record<string, Cell>; update: boolean }>();\n items.forEach((item, i) => {\n const id = item.submission.id;\n const update = (item.update ?? deliveryOptions.update) === true || byId.get(id)?.update === true;\n byId.delete(id);\n byId.set(id, { id, row: rows[i]!.row, update });\n });\n let pending = [...byId.values()];\n const updating = pending.some((p) => p.update);\n const overwrite: { at: number; row: Record<string, Cell> }[] = [];\n skipped = [];\n if (deliveryOptions.redelivery || updating) {\n const column = columnLetter(state.header.indexOf(\"id\"));\n // An update may be for a response from long ago, so it reads the whole\n // id column (one column, one request); a redelivery only the rows it\n // can have written.\n const from = !updating && state.last_row > 0 ? Math.max(2, state.last_row - DEDUPE_WINDOW) : 2;\n const ids = await call<{ values?: unknown[][] }>(\"read ids\", range(`${column}${from}:${column}`));\n const rowOf = new Map<string, number>();\n (ids.values ?? []).forEach((r, i) => {\n const id = String(r?.[0] ?? \"\");\n if (id && !rowOf.has(id)) rowOf.set(id, from + i);\n });\n pending = pending.filter((p) => {\n const at = rowOf.get(p.id);\n if (at === undefined) return true;\n if (p.update) overwrite.push({ at, row: p.row });\n else skipped.push(p.id);\n return false;\n });\n }\n if (overwrite.length) {\n await call(\"update rows\", `${base}/values:batchUpdate`, {\n method: \"POST\",\n body: JSON.stringify({\n valueInputOption: \"RAW\",\n data: overwrite.map((o) => ({\n range: `${quoteSheet(sheetName)}!A${o.at}`,\n values: [rowFor(state.header, o.row, escape)],\n })),\n }),\n });\n }\n if (!pending.length) return state;\n const result = await call<{ updates?: { updatedRange?: string } }>(\n \"append\",\n `${range(\"A1\")}:append?valueInputOption=RAW&insertDataOption=INSERT_ROWS`,\n { method: \"POST\", body: JSON.stringify({ values: pending.map((p) => rowFor(state.header, p.row, escape)) }) },\n );\n const last = /![A-Z]+\\d+:[A-Z]+(\\d+)$/.exec(result.updates?.updatedRange ?? \"\")?.[1];\n return { ...state, last_row: last ? Number(last) : state.last_row + pending.length };\n }\n\n const cached = readState(deliveryOptions.state, spreadsheetId, sheetName);\n const fresh = !cached || keys.some((k) => !cached.header.includes(k));\n let state = fresh ? await setUp(cached) : cached;\n try {\n state = await append(state);\n } catch (error) {\n if (!(error instanceof StaleSheetError) || fresh) throw error;\n state = await append(await setUp(cached));\n }\n return {\n ok: true,\n state: state as unknown as Record<string, Json>,\n ...(skipped.length ? { skipped } : {}),\n };\n }\n\n const guarded = async (...args: Parameters<typeof run>): Promise<DeliveryResult> => {\n try {\n return await run(...args);\n } catch (error) {\n return deliveryFailure(error);\n }\n };\n\n return {\n kind: \"sheet\",\n deliver: (submission, definition, config, deliveryOptions = {}) =>\n guarded(\n [{ submission, definition, deliveryId: deliveryOptions.deliveryId, update: deliveryOptions.update }],\n config,\n deliveryOptions,\n ),\n deliverBatch: (items, config, deliveryOptions = {}) => guarded(items, config, deliveryOptions),\n };\n}\n","/**\n * Where a Slack or webhook destination may post, checked against SSRF: https\n * only, on the default port, with no credentials in the address, and only to\n * a public host, never a private, loopback, link-local or otherwise internal\n * one. `parseHookUrl` checks the text (use it when someone adds the address);\n * `checkHookHost` checks every address the name resolves to right now (use it\n * before every request: what a name points to can change).\n *\n * A check before the request still leaves a short window in which the name\n * could be re-pointed (DNS rebinding). Where untrusted people choose URLs,\n * also send from a network that cannot reach internal services.\n */\nimport { DeliveryError } from \"./types\";\n\nexport type HookKind = \"slack\" | \"webhook\";\n\n/** Resolves a host name to its addresses (IPv4 and IPv6), as the server's DNS sees them. In Node: `dns.promises.lookup(host, { all: true })` mapped to `.address`. */\nexport type ResolveHost = (host: string) => Promise<string[]>;\n\nexport const MAX_HOOK_URL_LENGTH = 2048;\n/** The hosts a Slack incoming webhook lives on. */\nexport const SLACK_HOSTS: ReadonlySet<string> = new Set([\"hooks.slack.com\"]);\n\n/** An address that can't be used, with a reason safe to show and to store (never the address). */\nexport class HookUrlError extends DeliveryError {\n override name = \"HookUrlError\";\n}\n\nconst NOT_PUBLIC = \"The address must be on the public internet.\";\n\n// Host names that only ever mean something internal.\nconst INTERNAL_SUFFIXES = [\".localhost\", \".local\", \".internal\", \".intranet\", \".lan\", \".home.arpa\"];\n\n/** IPv4 dotted quad to its 4 bytes, or null. */\nfunction ipv4Bytes(ip: string): number[] | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n const bytes = parts.map((p) => (/^\\d{1,3}$/.test(p) ? Number(p) : NaN));\n return bytes.every((b) => Number.isInteger(b) && b >= 0 && b <= 255) ? bytes : null;\n}\n\nfunction publicIpv4(b: number[]): boolean {\n const [a, c] = [b[0]!, b[1]!];\n if (a === 0 || a === 10 || a === 127) return false; // this network, private, loopback\n if (a === 100 && c >= 64 && c <= 127) return false; // carrier-grade NAT\n if (a === 169 && c === 254) return false; // link-local, cloud metadata\n if (a === 172 && c >= 16 && c <= 31) return false; // private\n if (a === 192 && c === 168) return false; // private\n if (a === 192 && c === 0 && (b[2] === 0 || b[2] === 2)) return false; // IETF, documentation\n if (a === 198 && (c === 18 || c === 19)) return false; // benchmarking\n if (a === 198 && c === 51 && b[2] === 100) return false; // documentation\n if (a === 203 && c === 0 && b[2] === 113) return false; // documentation\n if (a >= 224) return false; // multicast, reserved, broadcast\n return true;\n}\n\n/** IPv6 text to its 16 bytes, or null. Accepts `::`, brackets, a zone and a trailing dotted IPv4. */\nfunction ipv6Bytes(ip: string): number[] | null {\n let text = ip.replace(/^\\[|\\]$/g, \"\").toLowerCase();\n const zone = text.indexOf(\"%\");\n if (zone >= 0) text = text.slice(0, zone);\n let tail: number[] = [];\n const lastColon = text.lastIndexOf(\":\");\n if (text.slice(lastColon + 1).includes(\".\")) {\n const v4 = ipv4Bytes(text.slice(lastColon + 1));\n if (!v4) return null;\n tail = v4;\n text = text.slice(0, lastColon + 1) + \"0:0\";\n }\n const halves = text.split(\"::\");\n if (halves.length > 2) return null;\n const groups = (s: string) => (s === \"\" ? [] : s.split(\":\"));\n const head = groups(halves[0]!);\n const rest = halves.length === 2 ? groups(halves[1]!) : [];\n const missing = 8 - head.length - rest.length;\n if (halves.length === 1 ? missing !== 0 : missing < 1) return null;\n const all = [...head, ...Array<string>(halves.length === 2 ? missing : 0).fill(\"0\"), ...rest];\n const bytes: number[] = [];\n for (const g of all) {\n if (!/^[0-9a-f]{1,4}$/.test(g)) return null;\n const n = parseInt(g, 16);\n bytes.push(n >> 8, n & 255);\n }\n if (tail.length) bytes.splice(12, 4, ...tail);\n return bytes;\n}\n\nfunction publicIpv6(b: number[]): boolean {\n const zeros = (from: number, to: number) => b.slice(from, to).every((x) => x === 0);\n if (zeros(0, 16)) return false; // ::\n if (zeros(0, 15) && b[15] === 1) return false; // ::1\n // IPv4-mapped (::ffff:a.b.c.d) and IPv4-compatible (::a.b.c.d): the IPv4 address decides.\n if (zeros(0, 10) && b[10] === 0xff && b[11] === 0xff) return publicIpv4(b.slice(12));\n if (zeros(0, 12)) return publicIpv4(b.slice(12));\n // NAT64 (64:ff9b::/96): the embedded IPv4 address decides too.\n if (b[0] === 0 && b[1] === 0x64 && b[2] === 0xff && b[3] === 0x9b && zeros(4, 12)) return publicIpv4(b.slice(12));\n if ((b[0]! & 0xfe) === 0xfc) return false; // unique local fc00::/7\n if (b[0] === 0xfe && (b[1]! & 0xc0) === 0x80) return false; // link-local fe80::/10\n if (b[0] === 0xfe && (b[1]! & 0xc0) === 0xc0) return false; // site-local fec0::/10\n if (b[0] === 0xff) return false; // multicast\n if (b[0] === 0x20 && b[1] === 0x01 && b[2] === 0x0d && b[3] === 0xb8) return false; // documentation\n if (b[0] === 0x20 && b[1] === 0x01 && b[2] === 0 && b[3] === 0) return false; // Teredo\n if (b[0] === 0x20 && b[1] === 0x02) return publicIpv4(b.slice(2, 6)); // 6to4\n if (b[0] === 0x01 && zeros(1, 8)) return false; // discard-only 100::/64\n return true;\n}\n\n/** Whether an IP address (v4 or v6) is a public one a hook may reach. Anything unparsable is not. */\nexport function isPublicAddress(ip: string): boolean {\n const v4 = ipv4Bytes(ip);\n if (v4) return publicIpv4(v4);\n const v6 = ipv6Bytes(ip);\n return v6 ? publicIpv6(v6) : false;\n}\n\n/** Whether a URL host (as `URL.hostname` gives it) is an IP literal rather than a name. */\nfunction isIpLiteral(host: string): boolean {\n return ipv4Bytes(host) !== null || host.startsWith(\"[\");\n}\n\n/**\n * The address as it will be used (its fragment dropped), or a `HookUrlError`\n * saying what is wrong with it. Checks the text only; `checkHookHost` checks\n * where the name resolves. A `\"slack\"` address must be a Slack incoming\n * webhook (`https://hooks.slack.com/services/…`).\n */\nexport function parseHookUrl(raw: string, kind: HookKind = \"webhook\"): URL {\n const text = raw.trim();\n if (!text) throw new HookUrlError(\"Paste the address to send responses to.\");\n if (text.length > MAX_HOOK_URL_LENGTH) throw new HookUrlError(\"That address is too long.\");\n let url: URL;\n try {\n url = new URL(text);\n } catch {\n throw new HookUrlError(\"That doesn't look like a web address.\");\n }\n if (url.protocol !== \"https:\") throw new HookUrlError(\"The address must start with https://.\");\n if (url.username || url.password) throw new HookUrlError(\"The address can't include a user name or password.\");\n if (url.port && url.port !== \"443\") throw new HookUrlError(\"The address must use the standard https port.\");\n url.hash = \"\";\n const host = url.hostname.replace(/\\.$/, \"\");\n if (kind === \"slack\") {\n if (!SLACK_HOSTS.has(host) || !url.pathname.startsWith(\"/services/\")) {\n throw new HookUrlError(\"Use a Slack incoming webhook address, which starts with https://hooks.slack.com/services/.\");\n }\n return url;\n }\n if (isIpLiteral(host)) {\n if (!isPublicAddress(host)) throw new HookUrlError(NOT_PUBLIC);\n return url;\n }\n if (!host.includes(\".\") || host === \"localhost\" || INTERNAL_SUFFIXES.some((suffix) => host.endsWith(suffix))) {\n throw new HookUrlError(NOT_PUBLIC);\n }\n return url;\n}\n\n/**\n * Checks that every address the URL's host resolves to is public. A host\n * that resolves to nothing, or whose lookup fails, is refused too, as a\n * retryable failure (DNS may be briefly down); a private address is final.\n */\nexport async function checkHookHost(url: URL, resolve: ResolveHost): Promise<void> {\n const host = url.hostname.replace(/\\.$/, \"\");\n if (isIpLiteral(host)) {\n if (!isPublicAddress(host)) throw new HookUrlError(NOT_PUBLIC);\n return;\n }\n let addresses: string[];\n try {\n addresses = await resolve(host);\n } catch {\n throw new HookUrlError(`${host} couldn't be found`, { retryable: true });\n }\n if (!addresses.length) throw new HookUrlError(`${host} couldn't be found`, { retryable: true });\n if (!addresses.every(isPublicAddress)) throw new HookUrlError(NOT_PUBLIC);\n}\n\n/** The host as a screen may show it (never the path: a Slack or webhook path can be the secret). */\nexport function hookHost(url: URL): string {\n return url.hostname.replace(/\\.$/, \"\").toLowerCase();\n}\n","/**\n * The webhook destination: a signed JSON POST to a URL, following the\n * Standard Webhooks spec (standardwebhooks.com), so receivers can verify it\n * with any Standard Webhooks library, or with `verifyWebhook` here.\n *\n * Headers: `webhook-id` (the delivery id, stable across retries: receivers\n * dedupe on it), `webhook-timestamp` (Unix seconds) and `webhook-signature`\n * (`v1,<base64 HMAC-SHA256 of \"<id>.<timestamp>.<body>\">`). Receivers reject\n * a timestamp more than five minutes off, which stops replays.\n *\n * The URL comes from config, which an admin may type, so by default it must\n * be https, carry no credentials, and not name localhost or a private,\n * loopback or link-local address literally. Redirects are not followed. A\n * hostname that resolves to a private address is not caught here: if\n * untrusted users choose URLs, send from a network that cannot reach\n * internal services.\n */\nimport { own, withheld } from \"../logic\";\nimport { isSensitive } from \"../fields\";\nimport type { FieldBlock, FormDefinition, Json } from \"../types\";\nimport { checkHookHost, type ResolveHost } from \"./hook-url\";\nimport { responseRow, visibleInputs, type RowOptions } from \"./row\";\nimport {\n base64,\n configString,\n deliveryFailure,\n DeliveryError,\n discard,\n fromBase64,\n httpError,\n resolveOption,\n timedFetch,\n type DeliveryOptions,\n type DeliveryResult,\n type DeliverySubmission,\n type Destination,\n type DestinationConfig,\n type HttpDeps,\n type OptionResolver,\n type WebCryptoKey,\n} from \"./types\";\n\n/** What the webhook destination reads from a destination's config. */\nexport interface WebhookConfig {\n url: string;\n}\n\nexport interface WebhookDestinationOptions extends HttpDeps {\n /**\n * The signing secret: base64 of at least 16 random bytes, usually with\n * the `whsec_` prefix Standard Webhooks tools issue (`whsec_` plus base64\n * of 24 to 64 bytes is what the spec recommends). The prefix is optional;\n * the rest is always base64-decoded, as every Standard Webhooks library\n * does, so a receiver verifies with the same string. A secret that is not\n * base64 fails permanently. Or a function that finds the one for a\n * destination's config. Never put it in config.\n */\n secret: string | OptionResolver<string>;\n /** Allow `http:` URLs. Default false. */\n allowInsecureUrls?: boolean | undefined;\n /** Allow localhost and private, loopback and link-local address literals. Default false. */\n allowPrivateHosts?: boolean | undefined;\n /** Sensitive fields: `\"include\"` (default), `\"mask\"` or `\"omit\"`. */\n sensitive?: RowOptions[\"sensitive\"];\n /** The event type in the payload. Default `\"form.submitted\"`, or `\"form.updated\"` for an update. */\n type?: string | undefined;\n /**\n * Where to post, when it is not `config.url`: the address kept apart from\n * config (encrypted, say, since a webhook URL can carry a token). Gets the\n * config and `{ destinationId }`. It passes the same checks.\n */\n url?: OptionResolver<string> | undefined;\n /**\n * Resolves the URL's host before every request, and the delivery is refused\n * unless every address is public (see `checkHookHost`). This catches a\n * hostname that points at a private address, which the URL checks alone\n * cannot. Recommended wherever untrusted people choose URLs.\n */\n resolveHost?: ResolveHost | undefined;\n now?: (() => number) | undefined;\n}\n\n/** The JSON body a webhook receives. */\nexport interface WebhookPayload {\n type: string;\n /** ISO time the delivery was sent. */\n timestamp: string;\n data: {\n form: { id: string; title: string };\n submission: {\n id: string;\n /** Answers keyed by field id. */\n answers: Record<string, Json>;\n hidden: Record<string, Json>;\n context: Record<string, Json>;\n ending: string | null;\n submittedAt: string | null;\n meta: Record<string, Json>;\n tags: string[];\n };\n /** The same submission as a flat row by column key: labels for choices, as the sheet shows it. */\n row: Record<string, Json>;\n };\n}\n\nconst MIN_SECRET_BYTES = 16;\nconst STRICT_BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;\n\n/**\n * The HMAC key bytes for a secret, decoded as the Standard Webhooks\n * reference libraries do: an optional `whsec_` prefix is dropped and the\n * rest is base64-decoded. Only padded standard base64 is accepted, the form\n * every reference library decodes the same way. Throws a `DeliveryError` for\n * a secret that is not base64 or is shorter than 16 bytes once decoded.\n */\nfunction secretKey(secret: string): Uint8Array<ArrayBuffer> {\n const encoded = secret.startsWith(\"whsec_\") ? secret.slice(6) : secret;\n if (!encoded || !STRICT_BASE64.test(encoded)) {\n throw new DeliveryError(\n \"The webhook secret must be base64, optionally prefixed with whsec_ (Standard Webhooks libraries base64-decode it)\",\n );\n }\n const bytes = fromBase64(encoded);\n if (bytes.length < MIN_SECRET_BYTES) throw new DeliveryError(`The webhook secret is shorter than ${MIN_SECRET_BYTES} bytes`);\n return bytes;\n}\n\nasync function hmacKey(secret: string, usage: \"sign\" | \"verify\"): Promise<WebCryptoKey> {\n return crypto.subtle.importKey(\"raw\", secretKey(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [usage]);\n}\n\n/**\n * A new signing secret: `whsec_` and standard base64 of 32 random bytes, the\n * form Standard Webhooks libraries read. Show it to the receiver once; keep it\n * out of config.\n */\nexport function newWebhookSecret(): string {\n return `whsec_${base64(crypto.getRandomValues(new Uint8Array(32)))}`;\n}\n\n/** The `webhook-signature` value for a message: `v1,<base64>`. */\nexport async function signWebhook(secret: string, id: string, timestamp: number, body: string): Promise<string> {\n const key = await hmacKey(secret, \"sign\");\n const mac = await crypto.subtle.sign(\"HMAC\", key, new TextEncoder().encode(`${id}.${timestamp}.${body}`));\n return `v1,${base64(new Uint8Array(mac))}`;\n}\n\nexport interface VerifyWebhookInput {\n /** The same secret the sender signs with (base64, optionally `whsec_`-prefixed). */\n secret: string;\n /** The request's headers: a `Headers` or a plain object. */\n headers: Headers | Record<string, string | string[] | undefined>;\n /** The raw body, exactly as received. */\n body: string;\n /** Default 300: a timestamp further off than this is refused. */\n toleranceSeconds?: number | undefined;\n now?: (() => number) | undefined;\n}\n\n/**\n * Checks a Standard Webhooks request: the timestamp is recent and one of the\n * space-separated `v1` signatures matches. Compares in constant time (by\n * WebCrypto `verify`). Never throws on a malformed request: returns false.\n */\nexport async function verifyWebhook(input: VerifyWebhookInput): Promise<boolean> {\n const header = (name: string): string => {\n if (typeof (input.headers as Headers).get === \"function\") return (input.headers as Headers).get(name) ?? \"\";\n const raw = (input.headers as Record<string, string | string[] | undefined>)[name];\n return Array.isArray(raw) ? (raw[0] ?? \"\") : (raw ?? \"\");\n };\n const id = header(\"webhook-id\");\n const timestamp = header(\"webhook-timestamp\");\n const signatures = header(\"webhook-signature\");\n if (!id || !/^\\d{1,12}$/.test(timestamp) || !signatures) return false;\n const now = Math.floor((input.now?.() ?? Date.now()) / 1000);\n if (Math.abs(now - Number(timestamp)) > (input.toleranceSeconds ?? 300)) return false;\n let key: WebCryptoKey;\n try {\n key = await hmacKey(input.secret, \"verify\");\n } catch {\n return false;\n }\n const data = new TextEncoder().encode(`${id}.${timestamp}.${input.body}`);\n for (const part of signatures.split(\" \")) {\n const [version, value] = part.split(\",\", 2);\n if (version !== \"v1\" || !value) continue;\n let mac: Uint8Array<ArrayBuffer>;\n try {\n mac = fromBase64(value);\n } catch {\n continue;\n }\n if (await crypto.subtle.verify(\"HMAC\", key, mac, data)) return true;\n }\n return false;\n}\n\nconst PRIVATE_HOSTNAME = /(^|\\.)(localhost|local|internal|localdomain|home\\.arpa)$/i;\n\n/** Whether a URL hostname is localhost or a private, loopback, link-local or unspecified address literal. */\nexport function isPrivateHost(hostname: string): boolean {\n const host = hostname.toLowerCase().replace(/\\.$/, \"\");\n if (PRIVATE_HOSTNAME.test(host)) return true;\n const v4 = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(host);\n if (v4) return isPrivateV4(v4.slice(1).map(Number) as [number, number, number, number]);\n if (host.startsWith(\"[\") && host.endsWith(\"]\")) {\n const v6 = host.slice(1, -1);\n if (v6 === \"::\" || v6 === \"::1\") return true;\n // IPv4-mapped (::ffff:a.b.c.d, which URL writes as ::ffff:xxxx:xxxx).\n const mapped = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(v6);\n if (mapped) {\n const hi = parseInt(mapped[1]!, 16);\n const lo = parseInt(mapped[2]!, 16);\n return isPrivateV4([hi >> 8, hi & 255, lo >> 8, lo & 255]);\n }\n const first = parseInt(v6.split(\":\")[0] || \"0\", 16);\n return (first & 0xfe00) === 0xfc00 || (first & 0xffc0) === 0xfe80; // fc00::/7, fe80::/10\n }\n return false;\n}\n\nfunction isPrivateV4([a, b]: [number, number, number, number]): boolean {\n return (\n a === 0 ||\n a === 10 ||\n a === 127 ||\n (a === 100 && b >= 64 && b <= 127) ||\n (a === 169 && b === 254) ||\n (a === 172 && b >= 16 && b <= 31) ||\n (a === 192 && b === 168) ||\n (a === 198 && (b === 18 || b === 19)) ||\n a >= 224\n );\n}\n\n/** The URL from config, checked. Throws a `DeliveryError` naming the rule it broke (never the URL, which may hold a token). */\nexport function checkWebhookUrl(\n raw: string,\n options: Pick<WebhookDestinationOptions, \"allowInsecureUrls\" | \"allowPrivateHosts\"> = {},\n): URL {\n if (!raw) throw new DeliveryError(\"The webhook destination has no url\");\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new DeliveryError(\"The webhook url is not a valid URL\");\n }\n if (url.protocol !== \"https:\" && !(options.allowInsecureUrls && url.protocol === \"http:\")) {\n throw new DeliveryError(\"The webhook url must use https\");\n }\n if (url.username || url.password) throw new DeliveryError(\"The webhook url must not contain credentials\");\n if (!options.allowPrivateHosts && isPrivateHost(url.hostname)) {\n throw new DeliveryError(\"The webhook url points at a private or local address\");\n }\n return url;\n}\n\n/** The payload for one submission. Identifying answers stay out on anonymous forms. */\nexport function webhookPayload(\n submission: DeliverySubmission,\n definition: FormDefinition,\n options: { sensitive?: RowOptions[\"sensitive\"]; type?: string | undefined; now?: number | undefined } = {},\n): WebhookPayload {\n const sensitive = options.sensitive ?? \"include\";\n const { row } = responseRow(submission, definition, { sensitive });\n const answers: Record<string, Json> = {};\n for (const block of definition.blocks) {\n if (block.kind !== \"field\") continue;\n const field = block as FieldBlock;\n const value = own(submission.answers, field.id);\n if (value === undefined || withheld(definition, field)) continue;\n if (isSensitive(field) && sensitive !== \"include\") {\n if (sensitive === \"mask\") answers[field.id] = \"[sensitive]\";\n continue;\n }\n answers[field.id] = value;\n }\n const inputs = visibleInputs(submission, definition, sensitive);\n const pick = (source: Record<string, Json> | undefined, allowed: Record<string, Json>) => {\n const out: Record<string, Json> = {};\n for (const [name, value] of Object.entries(source ?? {})) if (own(allowed, name) !== undefined) out[name] = value;\n return out;\n };\n return {\n type: options.type ?? \"form.submitted\",\n timestamp: new Date(options.now ?? Date.now()).toISOString(),\n data: {\n form: { id: definition.id, title: definition.title },\n submission: {\n id: submission.id,\n answers,\n hidden: pick(submission.hidden, inputs),\n context: pick(submission.context, inputs),\n ending: submission.ending ?? null,\n submittedAt: submission.submittedAt ?? null,\n meta: { ...submission.meta },\n tags: [...(submission.tags ?? [])],\n },\n row,\n },\n };\n}\n\nexport function webhookDestination(options: WebhookDestinationOptions): Destination {\n return {\n kind: \"webhook\",\n async deliver(submission, definition, config, deliveryOptions: DeliveryOptions = {}): Promise<DeliveryResult> {\n try {\n const context = { destinationId: deliveryOptions.destinationId };\n const raw = options.url\n ? await resolveOption(\"The webhook url\", options.url, config, context)\n : configString(config, \"url\");\n const url = checkWebhookUrl(typeof raw === \"string\" ? raw.trim() : \"\", options);\n // allowPrivateHosts opts out of the address check, the resolved one included.\n if (options.resolveHost && !options.allowPrivateHosts) await checkHookHost(url, options.resolveHost);\n const secret = await resolveOption(\"The webhook secret\", options.secret, config, context);\n if (!secret) throw new DeliveryError(\"The webhook secret is not set\");\n const now = options.now?.() ?? Date.now();\n const id = deliveryOptions.deliveryId ?? submission.id;\n const timestamp = Math.floor(now / 1000);\n const type = options.type ?? (deliveryOptions.update ? \"form.updated\" : undefined);\n const body = JSON.stringify(webhookPayload(submission, definition, { sensitive: options.sensitive, type, now }));\n const response = await timedFetch(\n options,\n url.toString(),\n {\n method: \"POST\",\n redirect: \"manual\",\n headers: {\n \"content-type\": \"application/json\",\n \"user-agent\": \"genesis-forms-webhook/1\",\n \"webhook-id\": id,\n \"webhook-timestamp\": String(timestamp),\n \"webhook-signature\": await signWebhook(secret, id, timestamp, body),\n },\n body,\n },\n deliveryOptions.signal,\n );\n discard(response);\n if (response.status >= 200 && response.status < 300) return { ok: true };\n // `redirect: \"manual\"` gives a 3xx (or, in browsers, an opaque status 0).\n if (response.status === 0 || (response.status >= 300 && response.status < 400)) {\n throw new DeliveryError(`Webhook answered ${response.status || \"a redirect\"}: redirects are not followed`, {\n ...(response.status ? { status: response.status } : {}),\n });\n }\n throw httpError(\"Webhook\", response);\n } catch (error) {\n return deliveryFailure(error);\n }\n },\n };\n}\n","/**\n * The Slack destination: one message per submission to a Slack incoming\n * webhook (the channel is the webhook's). The message is a heading (the\n * form's title), each answer as \"label: value\" in form order, and a footer\n * with a link back to the app when one is given. Every value is escaped, so\n * text a respondent typed can't mention `@channel` or make a link.\n *\n * The webhook URL is itself the credential, so it is usually kept out of\n * config: pass `url` to look it up. It must be a Slack incoming webhook\n * (`https://hooks.slack.com/services/…`); redirects are not followed.\n */\nimport type { FormDefinition } from \"../types\";\nimport { checkHookHost, parseHookUrl, type ResolveHost } from \"./hook-url\";\nimport { responseRow, type RowOptions } from \"./row\";\nimport {\n configString,\n deliveryFailure,\n DeliveryError,\n discard,\n httpError,\n resolveOption,\n timedFetch,\n type DeliveryOptions,\n type DeliveryResult,\n type DeliverySubmission,\n type Destination,\n type DestinationConfig,\n type HttpDeps,\n type OptionResolver,\n} from \"./types\";\n\n/** Longest answer shown in full; longer ones are cut (the app has the rest). */\nexport const SLACK_VALUE_LIMIT = 1500;\n\n/** Text for Slack's mrkdwn: `&`, `<` and `>` escaped, which is all Slack asks. */\nexport function escapeSlack(text: string): string {\n return text.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nconst cut = (text: string) => (text.length > SLACK_VALUE_LIMIT ? `${text.slice(0, SLACK_VALUE_LIMIT)}…` : text);\n\nexport interface SlackMessageOptions {\n /** The heading, as plain text (it is escaped). Default `New response: <title>`, or `Updated response: …` for an update. */\n heading?: string | undefined;\n /** An update of a submission delivered before. */\n update?: boolean | undefined;\n /** Lines shown before the answers, as `[label, value]` plain text (a location, a session). */\n lines?: readonly (readonly [string, string])[] | undefined;\n /** A link back to the response in the app: http(s) only. */\n link?: { url: string; text?: string | undefined } | null | undefined;\n /** Sensitive fields: `\"mask\"` (default), `\"omit\"` or `\"include\"`. A channel is usually wider than an inbox. */\n sensitive?: RowOptions[\"sensitive\"];\n /** Field keys left out (contact details, say). */\n omit?: readonly string[] | undefined;\n}\n\n/** The message Slack gets for one submission: `{ text }` in Slack mrkdwn. */\nexport function slackMessage(\n submission: DeliverySubmission,\n definition: FormDefinition,\n options: SlackMessageOptions = {},\n): { text: string } {\n const title = definition.title || definition.id;\n const heading = options.heading ?? `${options.update ? \"Updated response\" : \"New response\"}: ${title}`;\n const lines = [`*${escapeSlack(heading)}*`];\n for (const [label, value] of options.lines ?? []) {\n if (value.trim()) lines.push(`*${escapeSlack(label)}*: ${escapeSlack(cut(value))}`);\n }\n const { row, labels } = responseRow(submission, definition, { sensitive: options.sensitive ?? \"mask\" });\n const omit = new Set(options.omit ?? []);\n let answered = 0;\n for (const [key, label] of Object.entries(labels)) {\n const text = String(row[key] ?? \"\");\n if (!text || omit.has(key)) continue;\n answered++;\n lines.push(`*${escapeSlack(label || key)}*: ${escapeSlack(cut(text))}`);\n }\n if (!answered) lines.push(\"_No answers._\");\n const when = submission.submittedAt ? ` · ${escapeSlack(submission.submittedAt)}` : \"\";\n const link = options.link;\n lines.push(\n link && /^https?:\\/\\//i.test(link.url)\n ? `<${link.url.replace(/[<>|]/g, \"\")}|${escapeSlack(link.text ?? \"Open the response\").replace(/[|]/g, \"\")}>${when}`\n : `Response ${escapeSlack(submission.id)}${when}`,\n );\n return { text: lines.join(\"\\n\") };\n}\n\nexport interface SlackMessageInput {\n submission: DeliverySubmission;\n definition: FormDefinition;\n config: DestinationConfig;\n /** `DeliveryOptions.update`. */\n update: boolean;\n destinationId?: string | undefined;\n}\n\nexport interface SlackDestinationOptions extends HttpDeps {\n /**\n * The incoming webhook URL, when it is not `config.url`. Gets the config\n * and `{ destinationId }`.\n */\n url?: OptionResolver<string> | undefined;\n /** Resolves the host before every request; the delivery is refused unless every address is public. */\n resolveHost?: ResolveHost | undefined;\n /** The message's options per delivery (heading, extra lines, a link back). */\n message?: ((input: SlackMessageInput) => SlackMessageOptions | Promise<SlackMessageOptions>) | undefined;\n}\n\nexport function slackDestination(options: SlackDestinationOptions = {}): Destination {\n return {\n kind: \"slack\",\n async deliver(submission, definition, config, deliveryOptions: DeliveryOptions = {}): Promise<DeliveryResult> {\n try {\n const context = { destinationId: deliveryOptions.destinationId };\n const raw = options.url\n ? await resolveOption(\"The Slack webhook url\", options.url, config, context)\n : configString(config, \"url\");\n if (typeof raw !== \"string\" || !raw.trim()) throw new DeliveryError(\"The Slack destination has no url\");\n const url = parseHookUrl(raw, \"slack\");\n if (options.resolveHost) await checkHookHost(url, options.resolveHost);\n const update = deliveryOptions.update === true;\n const messageOptions = options.message\n ? await resolveOption(\n \"The Slack message\",\n () => options.message!({ submission, definition, config, update, destinationId: deliveryOptions.destinationId }),\n config,\n )\n : {};\n const body = JSON.stringify(slackMessage(submission, definition, { update, ...messageOptions }));\n const response = await timedFetch(\n options,\n url.toString(),\n {\n method: \"POST\",\n redirect: \"manual\",\n headers: { \"content-type\": \"application/json\", \"user-agent\": \"genesis-forms-slack/1\" },\n body,\n },\n deliveryOptions.signal,\n );\n discard(response);\n if (response.status >= 200 && response.status < 300) return { ok: true };\n if (response.status === 0 || (response.status >= 300 && response.status < 400)) {\n throw new DeliveryError(`Slack answered ${response.status || \"a redirect\"}: redirects are not followed`, {\n ...(response.status ? { status: response.status } : {}),\n });\n }\n throw httpError(\"Slack\", response);\n } catch (error) {\n return deliveryFailure(error);\n }\n },\n };\n}\n","/**\n * Sending by answer: a destination's `config.when`, a form `Condition`,\n * decides which submissions it gets. It is evaluated with the engine's own\n * `evaluate` against the submission's answers (by field id), its hidden\n * inputs and its context (trusted server inputs, read as hidden inputs and\n * winning over a hidden input of the same name). `createDeliveryRunner`\n * applies it before calling a destination; a submission that does not match\n * is recorded as filtered, not sent and not failed.\n */\nimport { evaluate, own } from \"../logic\";\nimport type { Condition, FieldBlock, FormDefinition, Json } from \"../types\";\nimport { DeliveryError, type DeliverySubmission, type DestinationConfig } from \"./types\";\n\nconst OPERATORS: ReadonlySet<string> = new Set([\"eq\", \"neq\", \"lt\", \"lte\", \"gt\", \"gte\", \"in\", \"contains\", \"answered\", \"empty\"]);\n/** How deep `all` / `any` / `not` may nest in a stored condition. */\nexport const MAX_CONDITION_DEPTH = 10;\n\nconst isObject = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null && !Array.isArray(v);\n\nfunction isOperand(v: unknown): boolean {\n if (!isObject(v)) return false;\n const keys = Object.keys(v);\n if (keys.length !== 1) return false;\n if (keys[0] === \"field\" || keys[0] === \"hidden\") return typeof v[keys[0]] === \"string\";\n return keys[0] === \"value\";\n}\n\n/** Whether a stored value has a `Condition`'s shape, nested at most `MAX_CONDITION_DEPTH` deep. */\nexport function isCondition(v: unknown, depth = 0): v is Condition {\n if (!isObject(v) || depth > MAX_CONDITION_DEPTH) return false;\n if (\"all\" in v) return Array.isArray(v[\"all\"]) && v[\"all\"].every((c) => isCondition(c, depth + 1));\n if (\"any\" in v) return Array.isArray(v[\"any\"]) && v[\"any\"].every((c) => isCondition(c, depth + 1));\n if (\"not\" in v) return isCondition(v[\"not\"], depth + 1);\n return (\n typeof v[\"op\"] === \"string\" &&\n OPERATORS.has(v[\"op\"]) &&\n isOperand(v[\"left\"]) &&\n (v[\"right\"] === undefined || isOperand(v[\"right\"]))\n );\n}\n\n/**\n * The destination's condition (`config.when`), or null when it has none. One\n * that can't be read throws a permanent `DeliveryError` rather than meaning\n * \"send everything\" or \"send nothing\".\n */\nexport function conditionOf(config: DestinationConfig): Condition | null {\n const when = config[\"when\"];\n if (when === undefined || when === null) return null;\n if (!isCondition(when)) throw new DeliveryError(\"The destination's condition can't be read\");\n return when;\n}\n\n/**\n * Whether a submission matches its destination's condition (true when there\n * is none). Throws a `DeliveryError` when the condition can't be read.\n */\nexport function passesCondition(\n submission: Pick<DeliverySubmission, \"answers\" | \"hidden\" | \"context\">,\n definition: FormDefinition,\n config: DestinationConfig,\n): boolean {\n const condition = conditionOf(config);\n if (!condition) return true;\n const fields = new Map<string, FieldBlock>();\n for (const block of definition.blocks) if (block.kind === \"field\") fields.set(block.id, block as FieldBlock);\n // No prototype, so a hidden input named __proto__ is just a name.\n const hidden = Object.create(null) as Record<string, Json>;\n for (const source of [submission.hidden, submission.context]) {\n for (const name of Object.keys(source ?? {})) {\n const value = own(source!, name);\n if (value !== undefined) hidden[name] = value;\n }\n }\n return evaluate(condition, { values: submission.answers, hidden, fields });\n}\n","/**\n * Google sign-in for a Sheet: a person's refresh token (from the app's own\n * OAuth consent flow, usually with the `drive.file` scope, which reaches only\n * the files they picked or created through the app) traded for a short-lived\n * access token at Google's token endpoint. Where the refresh token is kept,\n * and how it is encrypted, is the app's (see `sealSecret`); this module only\n * trades it. fetch only, no dependency.\n *\n * Use it with the sheet destination's `accessToken` option:\n *\n * sheetsDestination({\n * accessToken: async (config, { destinationId }) =>\n * googleOAuthAccessToken(client, await refreshTokenFor(destinationId)),\n * })\n */\nimport { GOOGLE_TOKEN_URL } from \"./google-auth\";\nimport { DeliveryError, discard, httpError, sha256Hex, timedFetch, type HttpDeps } from \"./types\";\n\n/** Google's scope for files the person picked or created through the app. */\nexport const DRIVE_FILE_SCOPE = \"https://www.googleapis.com/auth/drive.file\";\n\n/** The app's OAuth client, from the Google Cloud console. Server-side only. */\nexport interface GoogleOAuthClient {\n clientId: string;\n clientSecret: string;\n}\n\nexport interface GoogleOAuthTokenOptions extends HttpDeps {\n now?: (() => number) | undefined;\n signal?: AbortSignal | undefined;\n}\n\nexport interface RefreshedGoogleToken {\n accessToken: string;\n /** Seconds the access token is good for. */\n expiresIn: number;\n /** The scopes granted, space-separated. */\n scope: string;\n}\n\n/**\n * Trades a refresh token for an access token, uncached. `invalid_grant`\n * (access revoked, or the account gone) is a permanent failure saying to\n * connect the sheet again; 429 and 5xx are retryable. Never puts a token in\n * an error message.\n */\nexport async function refreshGoogleAccessToken(\n client: GoogleOAuthClient,\n refreshToken: string,\n options: GoogleOAuthTokenOptions = {},\n): Promise<RefreshedGoogleToken> {\n if (!client.clientId || !client.clientSecret) throw new DeliveryError(\"The Google OAuth client id or secret is not set\");\n if (!refreshToken) throw new DeliveryError(\"This sheet's Google connection is gone. Connect the sheet again.\");\n const response = await timedFetch(\n options,\n GOOGLE_TOKEN_URL,\n {\n method: \"POST\",\n // The body holds the refresh token and client secret: never follow a redirect with it.\n redirect: \"error\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: client.clientId,\n client_secret: client.clientSecret,\n }).toString(),\n },\n options.signal,\n );\n if (!response.ok) {\n const body = jsonObject(await response.json().catch(() => null)) as { error?: unknown };\n if (response.status === 400 && body.error === \"invalid_grant\") {\n throw new DeliveryError(\"Google access to this sheet was removed. Connect the sheet again.\", { status: 400 });\n }\n discard(response);\n throw httpError(\"Google token endpoint\", response);\n }\n const body = jsonObject(await response.json().catch(() => null)) as { access_token?: unknown; expires_in?: unknown; scope?: unknown };\n if (typeof body.access_token !== \"string\" || !body.access_token) {\n throw new DeliveryError(\"Google token endpoint returned no access token\", { retryable: true });\n }\n return {\n accessToken: body.access_token,\n expiresIn: typeof body.expires_in === \"number\" && body.expires_in > 0 ? body.expires_in : 3600,\n scope: typeof body.scope === \"string\" ? body.scope : DRIVE_FILE_SCOPE,\n };\n}\n\n/** A parsed JSON body as an object: `null`, a list or a scalar become `{}`. */\nfunction jsonObject(value: unknown): Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\n// One per process. Keyed by a digest of the client and the refresh token, so\n// a hit is only ever for the same grant.\nconst cache = new Map<string, { token: string; expiresAt: number }>();\n\n/** Forgets cached OAuth access tokens (tests, or after a sheet is disconnected). */\nexport function clearGoogleOAuthTokenCache(): void {\n cache.clear();\n}\n\n/** A cached or fresh access token for a refresh token, cached until a minute before it expires. */\nexport async function googleOAuthAccessToken(\n client: GoogleOAuthClient,\n refreshToken: string | null | undefined,\n options: GoogleOAuthTokenOptions = {},\n): Promise<string> {\n if (!refreshToken) throw new DeliveryError(\"This sheet's Google connection is gone. Connect the sheet again.\");\n const now = options.now?.() ?? Date.now();\n const key = await sha256Hex(`${client.clientId}\\n${refreshToken}`);\n const hit = cache.get(key);\n if (hit && hit.expiresAt - 60_000 > now) return hit.token;\n const fresh = await refreshGoogleAccessToken(client, refreshToken, options);\n cache.set(key, { token: fresh.accessToken, expiresAt: now + fresh.expiresIn * 1000 });\n return fresh.accessToken;\n}\n","/**\n * Keeping a destination's secrets at rest: a webhook or Slack URL, a signing\n * secret, a Google refresh token. AES-256-GCM (WebCrypto) under a key derived\n * with HKDF-SHA-256 from one 32-byte app secret and a purpose string, so no\n * two purposes share a key; each ciphertext is bound to associated data (the\n * row it belongs to), so one moved onto another row does not decrypt.\n *\n * The sealed form is `v1.<iv>.<ciphertext and tag>`, base64url. Where it is\n * stored is the app's; the key never is.\n */\nimport { base64url, DeliveryError, fromBase64, type WebCryptoKey } from \"./types\";\n\nconst enc = new TextEncoder();\n\n/**\n * The 32 key bytes from base64 or base64url text (as `openssl rand -base64 32`\n * prints), or the bytes themselves. Throws a `DeliveryError` naming the\n * problem, never the key.\n */\nexport function secretKeyBytes(key: string | Uint8Array): Uint8Array<ArrayBuffer> {\n if (typeof key !== \"string\") {\n if (key.length !== 32) throw new DeliveryError(\"The encryption key must be 32 bytes\");\n return new Uint8Array(key);\n }\n const text = key.trim().replace(/=+$/, \"\");\n if (!text) throw new DeliveryError(\"The encryption key is not set\");\n let bytes: Uint8Array<ArrayBuffer>;\n try {\n bytes = fromBase64(text + \"=\".repeat((4 - (text.length % 4)) % 4));\n } catch {\n throw new DeliveryError(\"The encryption key is not base64\");\n }\n if (bytes.length !== 32) throw new DeliveryError(\"The encryption key must be 32 bytes\");\n return bytes;\n}\n\n/**\n * An AES-GCM key for one purpose, derived from the app secret with HKDF-SHA-256\n * (empty salt, `info` naming the purpose). Use a different `info` for each\n * kind of secret; keep it fixed once anything is sealed with it.\n */\nexport async function deriveSecretKey(key: string | Uint8Array, info: string): Promise<WebCryptoKey> {\n if (!info) throw new DeliveryError(\"A sealing key needs its purpose (info)\");\n const base = await crypto.subtle.importKey(\"raw\", secretKeyBytes(key), \"HKDF\", false, [\"deriveKey\"]);\n return crypto.subtle.deriveKey(\n { name: \"HKDF\", hash: \"SHA-256\", salt: new Uint8Array(0), info: enc.encode(info) },\n base,\n { name: \"AES-GCM\", length: 256 },\n false,\n [\"encrypt\", \"decrypt\"],\n );\n}\n\n/** Encrypts `plaintext` bound to `aad` (the row it belongs to): `v1.<iv>.<ciphertext>`. */\nexport async function sealSecret(key: WebCryptoKey, plaintext: string, aad: string): Promise<string> {\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const sealed = await crypto.subtle.encrypt({ name: \"AES-GCM\", iv, additionalData: enc.encode(aad) }, key, enc.encode(plaintext));\n return `v1.${base64url(iv)}.${base64url(new Uint8Array(sealed))}`;\n}\n\n/**\n * Decrypts what `sealSecret` sealed with the same key and `aad`. Throws a\n * permanent `DeliveryError` for an unknown format, a wrong key (rotated?) or\n * a ciphertext from another row; never echoes the ciphertext.\n */\nexport async function openSecret(key: WebCryptoKey, sealed: string, aad: string): Promise<string> {\n const [version, iv, body, extra] = sealed.split(\".\");\n if (version !== \"v1\" || !iv || !body || extra !== undefined) throw new DeliveryError(\"The stored secret is not in a known format\");\n try {\n const plain = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: padded(iv), additionalData: enc.encode(aad) },\n key,\n padded(body),\n );\n return new TextDecoder().decode(plain);\n } catch {\n throw new DeliveryError(\"The stored secret could not be decrypted\");\n }\n}\n\nfunction padded(text: string): Uint8Array<ArrayBuffer> {\n return fromBase64(text + \"=\".repeat((4 - (text.length % 4)) % 4));\n}\n","/**\n * The outbox runner: claim a batch of due deliveries, send each to its\n * destination, and record what happened. The store is the app's (a SQL\n * outbox, a queue, a KV list): it hands over claimed deliveries and takes\n * back outcomes, and decides how claims and leases work. The runner owns the\n * rest: the destination's condition (`config.when`), batching deliveries to\n * one destination into one request where the destination can, keeping its\n * state, and turning each result into an outcome with a retry time.\n *\n * Outcomes:\n * - `sent`: delivered (or already there, on a redelivery).\n * - `filtered`: the submission doesn't match the destination's condition; nothing was sent, nothing to retry.\n * - `skipped`: the destination deliberately sent nothing (`notSent`); never retried.\n * - `retry`: a retryable failure. With the service's own Retry-After it is\n * deferred without counting an attempt (`counted: false`); otherwise it backs\n * off by attempt (`counted: true`), until `maxAttempts`.\n * - `failed`: permanent, an unknown kind, or out of attempts.\n *\n * It never throws for a delivery's failure, and never logs answers, contact\n * details or secrets: only ids, kinds and the destinations' safe messages.\n */\nimport type { FormDefinition, Json } from \"../types\";\nimport { passesCondition } from \"./condition\";\nimport {\n deliveryFailure,\n type DeliveryItem,\n type DeliveryResult,\n type DeliverySubmission,\n type Destination,\n type DestinationConfig,\n} from \"./types\";\n\n/** One claimed delivery, as the app's store hands it over. */\nexport interface ClaimedDelivery {\n /** The delivery's id: stable across its retries (the email idempotency key, the webhook-id). */\n id: string;\n /** The destination's id. Deliveries to one destination are batched, and its state is kept by it. */\n destinationId: string;\n /** The destination's kind: a key of `destinations`. */\n kind: string;\n /** The destination's config (no secrets). */\n config: DestinationConfig;\n /** What the destination cached last time (`DeliveryResult.state`), as stored. */\n state?: Record<string, Json> | undefined;\n submission: DeliverySubmission;\n definition: FormDefinition;\n /** This delivery's attempt number, from 1 for its first. */\n attempt: number;\n /**\n * How many times it was deferred so far (outcomes with `counted: false`).\n * Keep and pass it back, so `maxDeferrals` can stop a service that answers\n * \"try later\" forever. Default 0.\n */\n deferrals?: number | undefined;\n /**\n * An earlier attempt may have gone through (it was claimed before and timed\n * out, or its lease ran out), so destinations that can look first do.\n */\n redelivery?: boolean | undefined;\n /** An update of a submission delivered before (an edit). */\n update?: boolean | undefined;\n}\n\nexport type DeliveryOutcome =\n | {\n status: \"sent\";\n /** It was already there (a redelivery), so nothing was sent this time. */\n alreadyThere?: boolean;\n }\n | { status: \"filtered\" }\n | {\n status: \"skipped\";\n /** Why, safe to store. */\n reason: string;\n }\n | {\n status: \"retry\";\n error: string;\n /** When to try again. */\n retryAt: Date;\n retryAfterSeconds: number;\n /** Whether this attempt counts toward `maxAttempts`. False when the service said when to come back. */\n counted: boolean;\n httpStatus?: number;\n }\n | {\n status: \"failed\";\n error: string;\n httpStatus?: number;\n };\n\nexport interface ClaimRequest<Filter> {\n /** Most deliveries to claim. */\n limit: number;\n /** What `run` was given: the app's own narrowing (one response, one account). */\n filter?: Filter | undefined;\n}\n\nexport interface DeliveryRunnerOptions<Filter = undefined> {\n /** Claims up to `limit` due deliveries, each held (leased) so no other runner sends it meanwhile. */\n claim(request: ClaimRequest<Filter>): Promise<readonly ClaimedDelivery[]>;\n /**\n * Records an outcome. Resolve `false` when the claim was no longer held\n * (its lease ran out and another runner took it): it is counted as stale.\n * A rejection is logged and counted as unrecorded; the lease then runs out\n * and the delivery comes back on its own.\n */\n record(delivery: ClaimedDelivery, outcome: DeliveryOutcome): Promise<void | boolean>;\n /** Keeps a destination's new state (a sheet's header and last row). Failures are logged, never fatal. */\n saveState?: ((destinationId: string, state: Record<string, Json>) => Promise<void>) | undefined;\n /** The destinations by kind. */\n destinations: Readonly<Record<string, Destination>>;\n now?: (() => number) | undefined;\n /** Safe lines (ids, kinds, short reasons). Default: nothing is logged. */\n log?: ((message: string) => void) | undefined;\n /** Deliveries claimed per run. Default 25. */\n batchSize?: number | undefined;\n /** Counted attempts before a retryable failure is given up. Default `DEFAULT_MAX_ATTEMPTS` (8). */\n maxAttempts?: number | undefined;\n /**\n * Deferrals (Retry-After, no attempt counted) allowed before a further one\n * counts as an attempt and backs off. Default `DEFAULT_MAX_DEFERRALS` (24).\n */\n maxDeferrals?: number | undefined;\n /** Seconds to wait after a counted failed attempt. Default `defaultBackoff`. */\n backoff?: ((attempt: number) => number) | undefined;\n}\n\nexport interface DeliveryReport {\n claimed: number;\n sent: number;\n filtered: number;\n skipped: number;\n /** Retryable failures, backed off by attempt. */\n retrying: number;\n /** Retryable failures the service said when to retry; no attempt used. */\n deferred: number;\n failed: number;\n /** Recorded after the claim was lost (`record` resolved false). */\n stale: number;\n /** `record` threw. */\n unrecorded: number;\n}\n\nexport interface RunOptions<Filter> {\n filter?: Filter | undefined;\n /** Overrides `batchSize` for this run. */\n limit?: number | undefined;\n /** Aborts the sends in flight; their outcomes are recorded as retries. */\n signal?: AbortSignal | undefined;\n}\n\nexport interface DeliveryRunner<Filter = undefined> {\n /** One claim, its sends and their records. Never rejects for a delivery's failure; a failing `claim` rejects. */\n run(options?: RunOptions<Filter>): Promise<DeliveryReport>;\n}\n\nexport const DEFAULT_MAX_ATTEMPTS = 8;\nexport const DEFAULT_MAX_DEFERRALS = 24;\nexport const DEFAULT_BATCH_SIZE = 25;\n\n/** 1 minute, doubling each attempt, at most 6 hours: 1m, 2m, 4m … 6h. */\nexport function defaultBackoff(attempt: number): number {\n return Math.min(6 * 3600, 60 * 2 ** Math.max(0, attempt - 1));\n}\n\n/** Turns a destination's result into an outcome for a delivery on its `attempt`. */\nexport function deliveryOutcome(\n result: DeliveryResult,\n attempt: number,\n options: {\n now?: number | undefined;\n maxAttempts?: number | undefined;\n backoff?: ((attempt: number) => number) | undefined;\n /** Deferrals so far (`ClaimedDelivery.deferrals`). */\n deferrals?: number | undefined;\n maxDeferrals?: number | undefined;\n } = {},\n): DeliveryOutcome {\n if (result.ok) return result.notSent ? { status: \"skipped\", reason: result.notSent.slice(0, 500) } : { status: \"sent\" };\n const http = result.status !== undefined ? { httpStatus: result.status } : {};\n if (!result.retryable) return { status: \"failed\", error: result.error, ...http };\n const now = options.now ?? Date.now();\n // Deferred without counting an attempt, until maxDeferrals: after that a\n // service that keeps saying \"later\" is backed off and given up like any other.\n if (result.retryAfterSeconds !== undefined && (options.deferrals ?? 0) < (options.maxDeferrals ?? DEFAULT_MAX_DEFERRALS)) {\n const seconds = Math.max(1, Math.ceil(result.retryAfterSeconds));\n return { status: \"retry\", error: result.error, retryAt: new Date(now + seconds * 1000), retryAfterSeconds: seconds, counted: false, ...http };\n }\n const max = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n if (attempt >= max) return { status: \"failed\", error: `${result.error} (gave up after ${attempt} attempts)`.slice(0, 500), ...http };\n const seconds = Math.max(1, Math.ceil((options.backoff ?? defaultBackoff)(attempt)));\n return { status: \"retry\", error: result.error, retryAt: new Date(now + seconds * 1000), retryAfterSeconds: seconds, counted: true, ...http };\n}\n\nexport function createDeliveryRunner<Filter = undefined>(options: DeliveryRunnerOptions<Filter>): DeliveryRunner<Filter> {\n // App code: a logger that throws must never stop an outcome being recorded.\n const log = (message: string): void => {\n try {\n options.log?.(message);\n } catch {\n // Ignored.\n }\n };\n const now = () => options.now?.() ?? Date.now();\n\n /** Sends one destination's deliveries; resolves one result per delivery, in order. */\n async function send(group: readonly ClaimedDelivery[], signal: AbortSignal | undefined): Promise<(DeliveryResult | \"filtered\")[]> {\n const first = group[0]!;\n const destination = options.destinations[first.kind];\n if (!destination) {\n return group.map(() => ({ ok: false, retryable: false, error: `No destination for kind ${first.kind}` }));\n }\n // The condition first: a submission that doesn't match is never sent.\n const results: (DeliveryResult | \"filtered\" | null)[] = group.map((d) => {\n try {\n return passesCondition(d.submission, d.definition, d.config) ? null : \"filtered\";\n } catch (error) {\n return deliveryFailure(error);\n }\n });\n const due = group.filter((_, i) => results[i] === null);\n let state = first.state;\n const keep = (result: DeliveryResult) => {\n if (result.ok && result.state) state = result.state;\n };\n const guard = async (call: () => Promise<DeliveryResult>): Promise<DeliveryResult> => {\n try {\n return await call();\n } catch (error) {\n // Destinations never throw; an app-written one might.\n return deliveryFailure(error);\n }\n };\n const base = { state, signal, destinationId: first.destinationId };\n let sent: DeliveryResult[];\n if (due.length > 1 && destination.deliverBatch) {\n const items: DeliveryItem[] = due.map((d) => ({ submission: d.submission, definition: d.definition, deliveryId: d.id, update: d.update }));\n const result = await guard(() =>\n destination.deliverBatch!(items, first.config, { ...base, redelivery: due.some((d) => d.redelivery) }),\n );\n keep(result);\n sent = due.map(() => result);\n } else {\n sent = [];\n for (const d of due) {\n const result = await guard(() =>\n destination.deliver(d.submission, d.definition, d.config, {\n ...base,\n state,\n deliveryId: d.id,\n redelivery: d.redelivery,\n update: d.update,\n }),\n );\n keep(result);\n sent.push(result);\n }\n }\n if (state !== first.state && state && options.saveState) {\n try {\n await options.saveState(first.destinationId, state);\n } catch {\n log(`Saving destination ${first.destinationId}'s state failed`);\n }\n }\n let next = 0;\n return results.map((r) => r ?? sent[next++]!);\n }\n\n return {\n async run(runOptions: RunOptions<Filter> = {}): Promise<DeliveryReport> {\n const report: DeliveryReport = {\n claimed: 0,\n sent: 0,\n filtered: 0,\n skipped: 0,\n retrying: 0,\n deferred: 0,\n failed: 0,\n stale: 0,\n unrecorded: 0,\n };\n const limit = runOptions.limit ?? options.batchSize ?? DEFAULT_BATCH_SIZE;\n const claimed = await options.claim({ limit, filter: runOptions.filter });\n report.claimed = claimed.length;\n\n // One group per destination: a sheet gets one append for all its rows.\n const groups = new Map<string, ClaimedDelivery[]>();\n for (const delivery of claimed) {\n const list = groups.get(delivery.destinationId) ?? [];\n list.push(delivery);\n groups.set(delivery.destinationId, list);\n }\n\n await Promise.all(\n [...groups.values()].map(async (group) => {\n const results = await send(group, runOptions.signal);\n const at = now();\n await Promise.all(\n group.map(async (delivery, i) => {\n const result = results[i]!;\n const outcome: DeliveryOutcome =\n result === \"filtered\"\n ? { status: \"filtered\" }\n : deliveryOutcome(result, delivery.attempt, {\n now: at,\n maxAttempts: options.maxAttempts,\n backoff: options.backoff,\n deferrals: delivery.deferrals,\n maxDeferrals: options.maxDeferrals,\n });\n if (outcome.status === \"sent\" && result !== \"filtered\" && result.ok && result.skipped?.includes(delivery.submission.id)) {\n outcome.alreadyThere = true;\n }\n if (outcome.status === \"failed\" || outcome.status === \"retry\") {\n log(`Delivery ${delivery.id} (${delivery.kind}) ${outcome.status === \"failed\" ? \"failed\" : \"will be retried\"}: ${outcome.error}`);\n } else if (outcome.status === \"skipped\") {\n log(`Delivery ${delivery.id} (${delivery.kind}) skipped: ${outcome.reason}`);\n }\n let recorded: void | boolean;\n try {\n recorded = await options.record(delivery, outcome);\n } catch {\n report.unrecorded++;\n log(`Recording delivery ${delivery.id} failed`);\n return;\n }\n if (recorded === false) report.stale++;\n else if (outcome.status === \"sent\") report.sent++;\n else if (outcome.status === \"filtered\") report.filtered++;\n else if (outcome.status === \"skipped\") report.skipped++;\n else if (outcome.status === \"failed\") report.failed++;\n else if (outcome.counted) report.retrying++;\n else report.deferred++;\n }),\n );\n }),\n );\n return report;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/destinations/types.ts","../src/props-check.ts","../src/calculated.ts","../src/structured.ts","../src/photo.ts","../src/fields.ts","../src/logic.ts","../src/recall.ts","../src/destinations/row.ts","../src/destinations/email.ts","../src/destinations/google-auth.ts","../src/destinations/sheets.ts","../src/destinations/hook-url.ts","../src/destinations/webhook.ts","../src/destinations/slack.ts","../src/destinations/condition.ts","../src/destinations/google-oauth.ts","../src/destinations/secret-box.ts","../../notifications/src/runner/index.ts","../src/destinations/runner.ts"],"names":["plural","numberOps","out","used","state","resolve","isObject","body","cache","seconds","DEFAULT_MAX_ATTEMPTS","DEFAULT_MAX_DEFERRALS","DEFAULT_BATCH_SIZE","defaultBackoff"],"mappings":"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","file":"destinations.js","sourcesContent":["/**\n * The contract every destination keeps. A destination sends one checked\n * submission somewhere (an inbox, a spreadsheet, a URL) and says whether a\n * failure is worth retrying. It never throws, never logs, and never puts a\n * secret, an answer or contact details in an error message.\n *\n * Storage is the app's: it keeps the outbox, claims due deliveries, counts\n * attempts and schedules retries. A destination only reports what happened.\n */\nimport type { FormDefinition, Json } from \"../types\";\n\n/** One cell of a flat response row. */\nexport type Cell = string | number | boolean;\n\n/**\n * What a destination delivers: a submission `validateSubmission` checked,\n * plus the id the app stored it under. `{ id, ...result.submission }` fits.\n */\nexport interface DeliverySubmission {\n /** The stored response's id. Every destination records it, so a resend is recognised. */\n id: string;\n /** Answers keyed by field id. */\n answers: Record<string, Json>;\n /** Untrusted URL and host inputs. */\n hidden?: Record<string, Json> | undefined;\n /** Trusted server inputs (account id, location…). */\n context?: Record<string, Json> | undefined;\n ending?: string | null | undefined;\n /** When it was submitted, as the app wants it shown: an ISO time, or a day such as `2026-10-22`. */\n submittedAt?: string | undefined;\n /**\n * Extra leading columns the app adds, in order, after `id` and `submitted_at`:\n * the form's slug and version, an account id, a location. Rows and emails show them;\n * the webhook sends them.\n */\n meta?: Record<string, Cell> | undefined;\n /** Labels the app attached, such as `low_rating`. The webhook sends them; a custom email can read them. */\n tags?: readonly string[] | undefined;\n}\n\nexport interface DeliveryOptions {\n /**\n * This delivery's id, stable across its retries. The email destination's\n * idempotency key and the webhook's `webhook-id`. Defaults to the submission id.\n */\n deliveryId?: string | undefined;\n /** What this destination cached last time (`DeliveryResult.state`). */\n state?: Record<string, Json> | undefined;\n /**\n * An earlier attempt of this delivery may have gone through (it timed out,\n * or its lease ran out). Destinations that can look first do: the sheet\n * skips rows whose id is already there.\n */\n redelivery?: boolean | undefined;\n /** Aborts the delivery. Each request also has its own timeout. */\n signal?: AbortSignal | undefined;\n /**\n * The submission was delivered before and this is its update (an edit).\n * The sheet overwrites the response's row where it is (appending only when\n * it is gone), and the webhook's event type becomes `form.updated`.\n */\n update?: boolean | undefined;\n /**\n * The app's id for the destination. Passed on to option functions (a\n * secret, an account, an access token, a URL), so they can look up what\n * is stored for it.\n */\n destinationId?: string | undefined;\n}\n\n/** One submission in a batch: each carries its own definition and delivery id. */\nexport interface DeliveryItem {\n submission: DeliverySubmission;\n definition: FormDefinition;\n deliveryId?: string | undefined;\n /** This item is an update of a submission delivered before (see `DeliveryOptions.update`). */\n update?: boolean | undefined;\n}\n\nexport type DeliveryResult =\n | {\n ok: true;\n /** New state to keep for this destination, when it changed. */\n state?: Record<string, Json>;\n /** Submission ids already there (a redelivery), so nothing was sent for them. */\n skipped?: string[];\n /**\n * Set when the destination deliberately sent nothing (no address to\n * send to, a daily cap reached): the reason, safe to store. Not a\n * failure and never retried; `createDeliveryRunner` records it as skipped.\n */\n notSent?: string;\n }\n | DeliveryFailure;\n\nexport interface DeliveryFailure {\n ok: false;\n /**\n * `true`: the same request may succeed later (rate limited, the service\n * down, a timeout). `false`: it will not until someone changes the config\n * or credentials (a bad key, an unshared sheet, a 404 URL).\n */\n retryable: boolean;\n /**\n * Set when the service said when to come back (429, 503) or is plainly\n * down: retry after this many seconds. An app may choose not to count the\n * attempt, since it says nothing about the delivery itself.\n */\n retryAfterSeconds?: number;\n /** The HTTP status that refused it, if one did. */\n status?: number;\n /**\n * The receiver asked to be switched off (a webhook answered 410 Gone, as\n * Standard Webhooks specifies): disable the destination rather than keep\n * sending to it. Always with `retryable: false`.\n */\n disable?: true;\n /** Safe to store and log: a status and a short reason, never secrets, answers or contact details. */\n error: string;\n}\n\n/** Config is plain JSON the app stores per destination. Secrets never go in it. */\nexport type DestinationConfig = Readonly<Record<string, unknown>>;\n\nexport interface Destination {\n /** `\"email\"`, `\"sheet\"`, `\"webhook\"`, or an app's own. */\n readonly kind: string;\n /** Deliver one submission. Never throws. */\n deliver(\n submission: DeliverySubmission,\n definition: FormDefinition,\n config: DestinationConfig,\n options?: DeliveryOptions,\n ): Promise<DeliveryResult>;\n /**\n * Deliver several submissions to the same destination in one request where\n * the service allows it. All succeed or all fail together. Never throws.\n */\n deliverBatch?(\n items: readonly DeliveryItem[],\n config: DestinationConfig,\n options?: Omit<DeliveryOptions, \"deliveryId\">,\n ): Promise<DeliveryResult>;\n}\n\n/**\n * A failure with a message that is safe to store. Destinations throw it\n * internally and `deliveryFailure` turns it into a result; app-written\n * destinations may do the same.\n */\nexport class DeliveryError extends Error {\n override name = \"DeliveryError\";\n readonly retryable: boolean;\n readonly retryAfterSeconds: number | undefined;\n readonly status: number | undefined;\n /** The receiver asked to be switched off (`DeliveryFailure.disable`); never retryable. */\n readonly disable: boolean;\n constructor(\n message: string,\n options: {\n retryable?: boolean | undefined;\n retryAfterSeconds?: number | undefined;\n status?: number | undefined;\n disable?: boolean | undefined;\n } = {},\n ) {\n super(message);\n this.disable = options.disable ?? false;\n this.retryable = !this.disable && (options.retryable ?? false);\n this.retryAfterSeconds = options.retryAfterSeconds;\n this.status = options.status;\n }\n}\n\n/** Every outbound request gives up after this long, unless the destination is given another `timeoutMs`. */\nexport const REQUEST_TIMEOUT_MS = 10_000;\n\nconst IMF_FIXDATE = /^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \\d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$/;\n\n/**\n * Seconds to wait from a Retry-After header, else the fallback. Only the\n * two forms RFC 9110 defines are read: delta-seconds (digits only) and an\n * IMF-fixdate (`Wed, 21 Oct 2026 07:28:00 GMT`); anything else (`-5`,\n * `1.5`, a loose date) gets the fallback. At least 1 second, at most a day.\n */\nexport function retryAfterSeconds(header: string | null | undefined, fallback = 60, now = Date.now()): number {\n const clamp = (s: number) => Math.min(86_400, Math.max(1, s));\n if (header) {\n const trimmed = header.trim();\n if (/^\\d+$/.test(trimmed)) return clamp(Number(trimmed));\n if (IMF_FIXDATE.test(trimmed)) {\n const at = Date.parse(trimmed);\n if (Number.isFinite(at)) return clamp(Math.ceil((at - now) / 1000));\n }\n }\n return fallback;\n}\n\n/** Whether an HTTP status is worth retrying unchanged: 408, 425, 429 and 5xx. */\nexport function isRetryableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\n/**\n * The error for a refused request. Retryable statuses (see\n * `isRetryableStatus`) wait for the Retry-After header, else 60 seconds;\n * every other status is permanent.\n */\nexport function httpError(what: string, response: Response, detail?: string): DeliveryError {\n const status = response.status;\n const message = `${what} answered ${status}${detail ? ` (${detail})` : \"\"}`;\n if (isRetryableStatus(status)) {\n return new DeliveryError(message, {\n retryable: true,\n retryAfterSeconds: retryAfterSeconds(response.headers.get(\"retry-after\")),\n status,\n });\n }\n return new DeliveryError(message, { retryable: false, status });\n}\n\n/**\n * Any error as a failed result with a safe message. A `DeliveryError` keeps\n * its message; anything else is reduced to its kind (\"Timed out\", \"Network\n * error\"), because a raw message may hold a URL with a token in it.\n * Timeouts and aborts are retryable. A `TypeError` is permanent: it is\n * almost always a bug that a retry would only repeat. `timedFetch` turns\n * fetch's own network `TypeError` into a retryable `DeliveryError` first, so\n * an app destination that calls `fetch` directly should do the same.\n */\nexport function deliveryFailure(error: unknown): DeliveryFailure {\n if (error instanceof DeliveryError) {\n return {\n ok: false,\n retryable: error.retryable,\n error: error.message.slice(0, 500),\n ...(error.retryAfterSeconds !== undefined ? { retryAfterSeconds: error.retryAfterSeconds } : {}),\n ...(error.status !== undefined ? { status: error.status } : {}),\n ...(error.disable ? { disable: true as const } : {}),\n };\n }\n const name = error instanceof Error ? error.name : \"\";\n if (name === \"TimeoutError\") return { ok: false, retryable: true, error: \"Timed out\" };\n if (name === \"AbortError\") return { ok: false, retryable: true, error: \"Aborted\" };\n if (name === \"TypeError\") return { ok: false, retryable: false, error: \"Unexpected error\" };\n return { ok: false, retryable: true, error: \"Unexpected error\" };\n}\n\n/** Shared by the built-in destinations. */\nexport interface HttpDeps {\n /** Defaults to the global `fetch`. */\n fetch?: typeof fetch | undefined;\n /** Per request. Default `REQUEST_TIMEOUT_MS`. */\n timeoutMs?: number | undefined;\n}\n\n/**\n * A request with a timeout, also aborted by the caller's signal. A network\n * failure (fetch rejects with a `TypeError`) becomes a retryable\n * `DeliveryError(\"Network error\")`; timeouts and aborts pass through.\n */\nexport async function timedFetch(\n deps: HttpDeps,\n url: string,\n init: RequestInit,\n signal: AbortSignal | undefined,\n): Promise<Response> {\n const timeout = AbortSignal.timeout(deps.timeoutMs ?? REQUEST_TIMEOUT_MS);\n const any = (AbortSignal as unknown as { any?: (signals: AbortSignal[]) => AbortSignal }).any;\n const combined = signal ? (any ? any([timeout, signal]) : signal.aborted ? signal : timeout) : timeout;\n // fetch rejects with a TypeError both for a network failure and for a\n // request that can never be sent (a newline in a header value, a bad URL).\n // Building the Request first separates the two: that one fails for good,\n // without echoing the value that broke it.\n try {\n // Without the body, so a stream body is never locked by the check.\n new Request(url, { method: init.method ?? \"GET\", headers: init.headers ?? {} });\n } catch {\n throw new DeliveryError(\"Invalid request (a header value or the URL is malformed)\", { retryable: false });\n }\n try {\n return await (deps.fetch ?? fetch)(url, { ...init, signal: combined });\n } catch (error) {\n if (error instanceof Error && error.name === \"TypeError\") throw new DeliveryError(\"Network error\", { retryable: true });\n throw error;\n }\n}\n\n/** What an option function is told besides the config. */\nexport interface ResolveContext {\n /** `DeliveryOptions.destinationId`, when the app gave one. */\n destinationId?: string | undefined;\n}\n\n/** A factory option worked out per delivery from the destination's config. */\nexport type OptionResolver<T> = (config: DestinationConfig, context: ResolveContext) => T | Promise<T>;\n\n/**\n * A factory option that may be a value or a function of the config (an\n * account, a secret). A function that throws fails the delivery\n * permanently with \"<what> could not be resolved\", never retried and never\n * echoing its message; to ask for a retry it can throw a retryable\n * `DeliveryError` itself.\n */\nexport async function resolveOption<T>(\n what: string,\n option: T | OptionResolver<T>,\n config: DestinationConfig,\n context: ResolveContext = {},\n): Promise<T> {\n if (typeof option !== \"function\") return option;\n try {\n return await (option as OptionResolver<T>)(config, context);\n } catch (error) {\n if (error instanceof DeliveryError) throw error;\n throw new DeliveryError(`${what} could not be resolved`);\n }\n}\n\n/** Lets go of a body we will not read, so the connection is freed. */\nexport function discard(response: Response): void {\n try {\n void response.body?.cancel().catch(() => {});\n } catch {\n // A mocked or already-read body.\n }\n}\n\n/** The string config value at `key`, trimmed, or \"\" (a snake_case `alias` is accepted too). */\nexport function configString(config: DestinationConfig, key: string, alias?: string): string {\n const raw = config[key] ?? (alias ? config[alias] : undefined);\n return typeof raw === \"string\" ? raw.trim() : \"\";\n}\n\n/** Bytes as base64url, no padding. */\nexport function base64url(bytes: Uint8Array | string): string {\n return base64(bytes).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/** Bytes (or UTF-8 text) as standard base64. */\nexport function base64(bytes: Uint8Array | string): string {\n const raw = typeof bytes === \"string\" ? new TextEncoder().encode(bytes) : bytes;\n let s = \"\";\n for (let i = 0; i < raw.length; i++) s += String.fromCharCode(raw[i]!);\n return btoa(s);\n}\n\n/** Standard base64 (or base64url) as bytes. Throws on anything else. */\nexport function fromBase64(text: string): Uint8Array<ArrayBuffer> {\n const bin = atob(text.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\n/** SHA-256 of a text, as lowercase hex. */\nexport async function sha256Hex(text: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(text));\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/** WebCrypto's key type, named without depending on the DOM lib. */\nexport type WebCryptoKey = Awaited<ReturnType<typeof crypto.subtle.importKey>>;\n","/**\n * Checking a block's `props` for `parseForm`: the shared helpers every content and field kind's\n * `checkProps` uses, so each kind states its own settings once and they are reported the same way.\n */\n\n/**\n * A kind's check of its `props` (an object, `{}` when the block has none). Report through\n * `check`, with paths under `props` (`\"max\"`, `\"columns[0].key\"`); `parseForm` prefixes each\n * with the block's (`blocks[3].props.`).\n */\nexport type PropsCheck = (props: Readonly<Record<string, unknown>>, check: PropsChecker) => void;\n\n/**\n * Names an id, key or hidden input may not take: they collide with `Object.prototype`\n * (`__proto__`, `constructor`, `toString`…) when used as a record key.\n */\nexport const RESERVED_NAMES: ReadonlySet<string> = new Set(Object.getOwnPropertyNames(Object.prototype));\n\nexport const isPlainRecord = (v: unknown): v is Record<string, unknown> => !!v && typeof v === \"object\" && !Array.isArray(v);\nexport const isWholeNumber = (v: unknown): v is number => typeof v === \"number\" && Number.isInteger(v);\nexport const isFiniteNumber = (v: unknown): v is number => typeof v === \"number\" && Number.isFinite(v);\n\n/** The helpers a `PropsCheck` reports through. Paths are relative to `props`. */\nexport interface PropsChecker {\n /** Report a problem with the setting at `path`. */\n issue(path: string, message: string): void;\n /** A required string (non-empty with `nonEmpty`). */\n text(v: unknown, path: string, nonEmpty?: boolean): void;\n /** An optional string. */\n optionalText(v: unknown, path: string): void;\n /** An optional true or false. */\n optionalBoolean(v: unknown, path: string): void;\n /** An optional whole number of at least `floor`. */\n optionalInt(v: unknown, path: string, floor: number): void;\n /** `low` may not exceed `high` when both are whole numbers. */\n ordered(low: unknown, high: unknown, path: string, what: string): void;\n /** An identifier: a non-empty string that is not an `Object.prototype` name. */\n name(v: unknown, path: string, what: string): v is string;\n}\n\n/**\n * A `PropsChecker` that reports to `report` with `prefix` before each path (`\"\"` for a path of\n * `props` itself). `parseForm` makes one per block.\n */\nexport function propsChecker(prefix: string, report: (path: string, message: string) => void): PropsChecker {\n const at = (path: string) => (path ? `${prefix}.${path}` : prefix);\n const issue = (path: string, message: string) => report(at(path), message);\n return {\n issue,\n text(v, path, nonEmpty = false) {\n if (typeof v !== \"string\" || (nonEmpty && !v)) issue(path, nonEmpty ? \"Required.\" : \"Required text.\");\n },\n optionalText(v, path) {\n if (v !== undefined && typeof v !== \"string\") issue(path, \"Must be text.\");\n },\n optionalBoolean(v, path) {\n if (v !== undefined && typeof v !== \"boolean\") issue(path, \"Must be true or false.\");\n },\n optionalInt(v, path, floor) {\n if (v !== undefined && !(isWholeNumber(v) && v >= floor)) issue(path, `Must be a whole number of ${floor} or more.`);\n },\n ordered(low, high, path, what) {\n if (isWholeNumber(low) && isWholeNumber(high) && low > high) issue(path, `Can't be more than the ${what}.`);\n },\n name(v, path, what): v is string {\n if (typeof v !== \"string\" || !v) {\n issue(path, `${what} must be a non-empty string.`);\n return false;\n }\n if (RESERVED_NAMES.has(v)) {\n issue(path, `\"${v}\" is reserved and cannot be used as ${what.toLowerCase()}.`);\n return false;\n }\n return true;\n },\n };\n}\n","import type { FieldTypeManifest } from \"./fields\";\nimport { isWholeNumber } from \"./props-check\";\nimport { evaluateFormula, formulaNumber, ownFormulaList, parseFormula, type FormulaNode, type FormulaRef, type FormulaValue } from \"./formula\";\nimport type { FieldBlock, FormDefinition, Json, Operator } from \"./types\";\n\n/** The calculated field type's registry key. */\nexport const CALCULATED_TYPE = \"calculated\";\n\n/**\n * Field types the builder offers only to a host that names them in its\n * palette, like `STRUCTURED_FIELD_TYPES`: `calculated` shows a value worked\n * out from other answers, so it is opt-in for hosts that want formulas.\n */\nexport const COMPUTED_FIELD_TYPES = [CALCULATED_TYPE] as const;\n\nexport type CalculatedFormat = \"number\" | \"percent\" | \"text\";\n/** Longest the formulas of one form may be, all together (`parseForm` checks it). */\nexport const MAX_FORM_FORMULA_LENGTH = 20_000;\n/** Most decimal places a calculated value may keep. */\nexport const MAX_CALCULATED_DECIMALS = 10;\n\nexport interface CalculatedProps {\n formula: string;\n format?: CalculatedFormat | undefined;\n decimals?: number | undefined;\n}\n\n/** A calculated field's settings, with anything malformed left out. */\nexport function calculatedProps(field: FieldBlock): CalculatedProps {\n const p = field.props ?? {};\n const out: CalculatedProps = { formula: typeof p.formula === \"string\" ? p.formula : \"\" };\n if (p.format === \"number\" || p.format === \"percent\" || p.format === \"text\") out.format = p.format;\n if (typeof p.decimals === \"number\" && Number.isInteger(p.decimals) && p.decimals >= 0 && p.decimals <= MAX_CALCULATED_DECIMALS) {\n out.decimals = p.decimals;\n }\n return out;\n}\n\nexport const isCalculated = (field: FieldBlock | undefined): boolean => field?.type === CALCULATED_TYPE;\n\nconst round = (n: number, decimals: number | undefined) => {\n if (decimals === undefined) return n;\n const r = Number(n.toFixed(decimals));\n return Object.is(r, -0) ? 0 : r;\n};\n\n/**\n * What a formula's result is stored as. `number` and `percent` keep a number\n * (`0.25` for 25%), rounded to `decimals`; `text` keeps text. Without a\n * format, numbers, text and true / false are kept as they are. A list, and\n * anything the format can't hold, is no value (`undefined`).\n */\nexport function calculatedValue(result: FormulaValue, field: FieldBlock): Json | undefined {\n return valueAs(result, calculatedProps(field));\n}\n\nfunction valueAs(result: FormulaValue, { format, decimals }: CalculatedProps): Json | undefined {\n if (result === null || Array.isArray(result)) return undefined;\n if (format === \"number\" || format === \"percent\") {\n const n = formulaNumber(result);\n return n === null ? undefined : round(n, decimals);\n }\n if (format === \"text\") {\n if (typeof result === \"number\") return decimals === undefined ? String(result) : result.toFixed(decimals);\n return typeof result === \"boolean\" ? (result ? \"Yes\" : \"No\") : result;\n }\n return typeof result === \"number\" ? round(result, decimals) : result;\n}\n\n/** A calculated value as shown: `12.5`, `25%`, the text, Yes / No. Empty when there is none. */\nexport function formatCalculated(value: Json | undefined, field: FieldBlock): string {\n if (value === undefined || value === null) return \"\";\n const { format, decimals } = calculatedProps(field);\n const fixed = (n: number) => (decimals === undefined ? String(Number(n.toFixed(6))) : n.toFixed(decimals));\n if (typeof value === \"number\") return format === \"percent\" ? `${fixed(value * 100)}%` : fixed(value);\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n return typeof value === \"string\" ? value : \"\";\n}\n\n/**\n * Most items a formula reads from one answer (a list's items, a table's\n * rows). A longer answer reads as blank, so one oversized value sent to the\n * server can't make every formula over it slow.\n */\nexport const MAX_FORMULA_ITEMS = 10_000;\n\n/**\n * Most list items and table rows all of a form's formulas read in one go\n * (each list or table counted once, however many of its columns are read, in form order). A formula that reads\n * an answer past the limit, or one over `MAX_FORMULA_ITEMS`, has no value\n * (blank, never a partial total), so many big answers can't make working\n * the values out slow either.\n */\nexport const MAX_SETTLE_ITEMS = 50_000;\n\nconst extract = (value: readonly Json[], column: string | undefined): FormulaValue[] =>\n column !== undefined\n ? value.flatMap((row): FormulaValue[] => {\n if (!row || typeof row !== \"object\" || Array.isArray(row)) return [];\n const cell = row[column];\n return typeof cell === \"string\" || typeof cell === \"number\" ? [cell] : [];\n })\n : value.flatMap((v): FormulaValue[] => (typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\" ? [v] : []));\n\n\n/**\n * The value a formula reads for an answer: numbers and text as they are, a\n * list's items, one table column's cells. A list or table of more than\n * `MAX_FORMULA_ITEMS` reads as blank. Each call builds a new list.\n */\nexport function formulaInput(value: Json | undefined, column?: string): FormulaValue {\n if (value === undefined || value === null) return null;\n if (Array.isArray(value) && value.length > MAX_FORMULA_ITEMS) return null;\n if (column !== undefined) {\n if (!Array.isArray(value)) return null;\n return extract(value, column);\n }\n if (Array.isArray(value)) return extract(value, undefined);\n return typeof value === \"object\" ? null : value;\n}\n\ninterface Compiled {\n field: FieldBlock;\n /** `formulaSize` of `ast`. */\n size: number;\n props: CalculatedProps;\n ast: FormulaNode | null;\n /** The answers it reads, each (answer, column) once (`id` is `undefined` for a key that is not a field). */\n reads: Read[];\n /** Each `ref` node of the formula, to its index in `reads`. */\n slots: Map<FormulaNode, number>;\n /** The inputs of the last evaluation and its result, reused while they are the same values. */\n last: { inputs: unknown[]; value: Json | undefined } | null;\n}\n\ninterface Read {\n id: string | undefined;\n column: string | undefined;\n /** `id` and `column` as one key, to read each once per formula. */\n key: string;\n}\n\nfunction refNodes(node: FormulaNode, out: Extract<FormulaNode, { kind: \"ref\" }>[] = []) {\n if (node.kind === \"ref\") out.push(node);\n else if (node.kind === \"unary\") refNodes(node.arg, out);\n else if (node.kind === \"binary\") (refNodes(node.left, out), refNodes(node.right, out));\n else if (node.kind === \"if\") (refNodes(node.test, out), refNodes(node.then, out), refNodes(node.else, out));\n else if (node.kind === \"call\") for (const a of node.args) refNodes(a, out);\n return out;\n}\n\n/** How many parts (numbers, answers, operators, calls) a formula has: what working it out once costs. */\nfunction formulaSize(node: FormulaNode): number {\n if (node.kind === \"unary\") return 1 + formulaSize(node.arg);\n if (node.kind === \"binary\") return 1 + formulaSize(node.left) + formulaSize(node.right);\n if (node.kind === \"if\") return 1 + formulaSize(node.test) + formulaSize(node.then) + formulaSize(node.else);\n if (node.kind === \"call\") return node.args.reduce((n, a) => n + formulaSize(a), 1);\n return 1;\n}\n\n/**\n * Work an engine may spend while replaying (see `MAX_REPLAY_WORK` in\n * `server.ts`): `spend` throws `ReplayWorkExceeded` once `used` passes `max`.\n */\nexport interface WorkBudget {\n used: number;\n max: number;\n}\n\n/**\n * Counts of the work calculators and replays did, for tests to check the\n * work stays bounded rather than timing it (not exported from the package).\n * `reset` zeroes them.\n */\nexport const workStats = {\n /** Formulas worked out (a cached result reused is not counted). */\n formulaRuns: 0,\n /** Lists read out of an answer (a list or one table column). */\n listBuilds: 0,\n /** Calls of `withCalculated`. */\n settles: 0,\n /** Copies of the answers made by `withCalculated`: at most one per call. */\n answerCopies: 0,\n /** Units of work the last limited replay used (see `WorkBudget`). */\n lastReplayWork: 0,\n reset() {\n this.formulaRuns = this.listBuilds = this.settles = this.answerCopies = this.lastReplayWork = 0;\n },\n};\n\nexport class ReplayWorkExceeded extends Error {\n constructor(readonly limit: number) {\n super(`Replaying the response would take more than ${limit} steps of work.`);\n }\n}\n\nexport function spend(budget: WorkBudget | undefined, amount: number): void {\n if (!budget) return;\n budget.used += amount;\n if (budget.used > budget.max) throw new ReplayWorkExceeded(budget.max);\n}\n\n/** Stands for an answer that is off the path or unanswered. */\nconst UNREAD = Symbol(\"unread\");\n/** Stands for an answer too big to read: over `MAX_FORMULA_ITEMS`, or past `MAX_SETTLE_ITEMS`. */\nconst OVER = Symbol(\"over\");\n\n/**\n * Works out a form's calculated fields from its answers. `withCalculated`\n * returns `values` itself when nothing changed. Each formula reads the\n * answers on `path` only (an answer logic hides reads as blank) and the\n * calculated fields before it, in form order.\n */\nexport function calculator(definition: FormDefinition, work?: WorkBudget) {\n // Work: 1 for each formula looked at in a settle, plus its size each time\n // it is worked out. Past the budget, `withCalculated` throws.\n const compiled: Compiled[] = [];\n const idByKey = new Map<string, string>();\n for (const block of definition.blocks) {\n if (block.kind !== \"field\") continue;\n idByKey.set(block.key, block.id);\n }\n for (const block of definition.blocks) {\n if (block.kind !== \"field\" || !isCalculated(block)) continue;\n const props = calculatedProps(block);\n const parsed = parseFormula(props.formula);\n const reads: Read[] = [];\n const slots = new Map<FormulaNode, number>();\n const byKey = new Map<string, number>();\n for (const ref of parsed.ok ? refNodes(parsed.ast) : []) {\n const id = idByKey.get(ref.key);\n const key = `${id ?? \"\"}\\u0000${ref.column ?? \"\"}`;\n let slot = byKey.get(key);\n if (slot === undefined) {\n slot = reads.push({ id, column: ref.column, key }) - 1;\n byKey.set(key, slot);\n }\n slots.set(ref, slot);\n }\n compiled.push({ field: block, props, ast: parsed.ok ? parsed.ast : null, size: parsed.ok ? formulaSize(parsed.ast) : 0, reads, slots, last: null });\n }\n /**\n * This calculator's lists, by the answer's array and then the column (`\"\"`\n * for a list's own items), so an unchanged table is walked once. Each\n * engine (and so each `validateSubmission` call) has its own, so a host\n * array changed between two calls is read afresh. Within one engine an\n * answer is not changed in place: the engine never changes a value it\n * holds, and `setValue` with an array it already holds calls `forget`.\n */\n const extracted = new WeakMap<readonly Json[], Map<string, readonly FormulaValue[]>>();\n const cachedList = (value: readonly Json[], column: string | undefined): readonly FormulaValue[] => {\n let byColumn = extracted.get(value);\n if (!byColumn) extracted.set(value, (byColumn = new Map()));\n const key = column ?? \"\";\n let list = byColumn.get(key);\n if (!list) {\n workStats.listBuilds++;\n byColumn.set(key, (list = ownFormulaList(extract(value, column))));\n }\n return list;\n };\n const readAnswer = (value: Json | undefined, column: string | undefined): FormulaValue => {\n if (Array.isArray(value)) return cachedList(value, column) as FormulaValue[];\n return column !== undefined ? null : formulaInput(value);\n };\n /** Drop what was worked out from `value`: it may have been changed in place. */\n const forget = (value: Json | undefined) => {\n if (!value || typeof value !== \"object\") return;\n if (Array.isArray(value)) extracted.delete(value);\n for (const entry of compiled) if (entry.last?.inputs.includes(value)) entry.last = null;\n };\n\n const withCalculated = (values: Record<string, Json | undefined>, path: readonly string[]) => {\n if (!compiled.length) return values;\n workStats.settles++;\n const visible = new Set(path);\n let next = values;\n // `values` is copied once, on the first change, then written into.\n let copied = false;\n // The items every formula may read, together: each list answer and table\n // counts its items or rows once (however many of its columns are read),\n // in form order, and one past the limit reads as blank. It depends on the\n // answers only, so a client and the server agree.\n let budget = MAX_SETTLE_ITEMS;\n const within = new Map<string, boolean>();\n const input = ({ id }: Read): unknown => {\n if (id === undefined || !visible.has(id) || !Object.prototype.hasOwnProperty.call(next, id)) return UNREAD;\n const value = next[id];\n if (!Array.isArray(value)) return value;\n let ok = within.get(id);\n if (ok === undefined) {\n // An answer over the per-answer limit is never read, so it uses none of the allowance.\n ok = value.length <= MAX_FORMULA_ITEMS && value.length <= budget;\n if (ok) budget -= value.length;\n within.set(id, ok);\n }\n return ok ? value : OVER;\n };\n for (const entry of compiled) {\n const { field, ast } = entry;\n // A formula is worked out again only when an answer it reads is a different value:\n // an engine settles on every answer, and most answers are to other questions.\n const { reads } = entry;\n spend(work, 1);\n const inputs: unknown[] = new Array(reads.length);\n let over = false;\n let same = entry.last !== null;\n for (let i = 0; i < reads.length; i++) {\n const v = input(reads[i]!);\n inputs[i] = v;\n if (v === OVER) over = true;\n if (same && entry.last!.inputs[i] !== v) same = false;\n }\n let value: Json | undefined;\n if (same) {\n value = entry.last!.value;\n } else {\n spend(work, entry.size);\n workStats.formulaRuns++;\n const resolved: (FormulaValue | undefined)[] = new Array(inputs.length);\n const read = (ref: FormulaRef): FormulaValue => {\n const slot = entry.slots.get(ref as FormulaNode);\n if (slot === undefined) return null;\n let v = resolved[slot];\n if (v === undefined) {\n const raw = inputs[slot];\n v = resolved[slot] = raw === UNREAD ? null : readAnswer(raw as Json | undefined, reads[slot]!.column);\n }\n return v;\n };\n // An answer too big to read leaves the value blank rather than a partial total.\n value = ast && !over ? valueAs(evaluateFormula(ast, read), entry.props) : undefined;\n entry.last = { inputs, value };\n }\n const current = Object.prototype.hasOwnProperty.call(next, field.id) ? next[field.id] : undefined;\n if (current !== value) {\n if (!copied) {\n workStats.answerCopies++;\n next = { ...next };\n copied = true;\n }\n next[field.id] = value;\n }\n }\n return next;\n };\n return { active: compiled.length > 0, ids: new Set(compiled.map((c) => c.field.id)), withCalculated, forget };\n}\n\nconst numberOps: Operator[] = [\"eq\", \"neq\", \"lt\", \"lte\", \"gt\", \"gte\", \"in\", \"answered\", \"empty\"];\n\nexport const calculatedFieldType: FieldTypeManifest = {\n type: CALCULATED_TYPE,\n label: \"Calculated\",\n category: \"advanced\",\n value: { json: true },\n operators: numberOps,\n a11y: { semantics: \"control\" },\n // A number, unless the format says text; without a format it can hold either, so it isn't known.\n literal: (props) => (props.format === \"text\" ? \"string\" : props.format === \"number\" || props.format === \"percent\" ? \"number\" : undefined),\n // The formula itself is checked once every key is known (`parseForm`).\n checkProps: (props, check) => {\n if (props.format !== undefined && props.format !== \"number\" && props.format !== \"percent\" && props.format !== \"text\") {\n check.issue(\"format\", \"Must be number, percent or text.\");\n }\n if (props.decimals !== undefined && !(isWholeNumber(props.decimals) && props.decimals >= 0 && props.decimals <= MAX_CALCULATED_DECIMALS)) {\n check.issue(\"decimals\", `Must be a whole number from 0 to ${MAX_CALCULATED_DECIMALS}.`);\n }\n },\n // The engine works the value out; any number, text or true / false it made is valid.\n validate: (value) => (typeof value === \"number\" || typeof value === \"string\" || typeof value === \"boolean\" ? null : \"This value is worked out from other answers.\"),\n summarize: (value, field) => formatCalculated(value, field),\n};\n","import type { FieldTypeManifest } from \"./fields\";\nimport { isPlainRecord, type PropsCheck } from \"./props-check\";\nimport type { FieldBlock, Json } from \"./types\";\n\ntype JsonObject = { [key: string]: Json };\nconst isObject = (v: unknown): v is JsonObject => !!v && typeof v === \"object\" && !Array.isArray(v);\nfunction intProp(field: FieldBlock, name: string, fallback: number, floor = 1): number {\n const v = field.props?.[name];\n return typeof v === \"number\" && Number.isInteger(v) && v >= floor ? v : fallback;\n}\nfunction optionalIntProp(field: FieldBlock, name: string, floor = 0): number | undefined {\n const v = field.props?.[name];\n return typeof v === \"number\" && Number.isInteger(v) && v >= floor ? v : undefined;\n}\nconst blank = (v: unknown) => typeof v !== \"string\" || v.trim() === \"\";\n/**\n * Unanswered: nothing, or a list whose every entry is a blank one. Anything\n * else (a string, a list with a malformed entry) is an answer, so validation\n * rejects it instead of dropping it silently.\n */\nconst blankText = (v: unknown) => typeof v === \"string\" && v.trim() === \"\";\nconst emptyList = (value: Json | undefined, isBlank: (entry: Json) => boolean) =>\n value === undefined || value === null || (Array.isArray(value) && value.every(isBlank));\nconst plural = (n: number, one: string, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;\n\nexport function listLimits(field: FieldBlock) {\n return { min: optionalIntProp(field, \"min\") ?? 0, max: intProp(field, \"max\", 10), itemMaxLength: intProp(field, \"itemMaxLength\", 500) };\n}\nconst listItems = (value: Json | undefined): string[] =>\n Array.isArray(value) ? value.filter((v): v is string => typeof v === \"string\" && v.trim() !== \"\") : [];\n\nexport interface TableColumn { key: string; label: string; long?: boolean }\nexport const MAX_TABLE_COLUMNS = 6;\nexport const MAX_TABLE_CELL_LENGTH = 2000;\nexport function tableColumns(field: FieldBlock): TableColumn[] {\n const raw = field.props?.columns;\n if (!Array.isArray(raw)) return [];\n const seen = new Set<string>();\n const out: TableColumn[] = [];\n for (const c of raw) {\n if (!isObject(c) || typeof c.key !== \"string\" || !c.key || seen.has(c.key)) continue;\n seen.add(c.key);\n const column: TableColumn = { key: c.key, label: typeof c.label === \"string\" ? c.label : c.key };\n if (c.long === true) column.long = true;\n out.push(column);\n }\n return out;\n}\nexport function tableLimits(field: FieldBlock) {\n return { minRows: optionalIntProp(field, \"minRows\") ?? 0, maxRows: intProp(field, \"maxRows\", 3) };\n}\nconst filledRows = (value: Json | undefined): JsonObject[] =>\n Array.isArray(value) ? value.filter((r): r is JsonObject => isObject(r) && Object.values(r).some((c) => !blank(c))) : [];\n\nexport interface MediaNote { at: number; text: string }\nexport const MAX_TIMESTAMP_SECONDS = 86400;\nexport function formatTimestamp(seconds: number): string {\n const total = Number.isFinite(seconds) && seconds > 0 ? Math.floor(seconds) : 0;\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = String(total % 60).padStart(2, \"0\");\n return h ? `${h}:${String(m).padStart(2, \"0\")}:${s}` : `${m}:${s}`;\n}\nexport function parseTimestamp(text: string): number | null {\n const t = text.trim();\n if (!t) return null;\n const parts = t.split(\":\");\n if (parts.length > 3) return null;\n if (parts.length === 1) {\n if (!/^\\d+(\\.\\d+)?$/.test(t)) return null;\n const n = Number(t);\n return n <= MAX_TIMESTAMP_SECONDS ? n : null;\n }\n const last = parts.length - 1;\n let total = 0;\n for (let i = 0; i < parts.length; i++) {\n const p = parts[i]!;\n const ok = i === 0 ? /^\\d+$/.test(p) : i === last ? /^\\d{2}(\\.\\d+)?$/.test(p) : /^\\d{2}$/.test(p);\n if (!ok) return null;\n const n = Number(p);\n if (i > 0 && n >= 60) return null;\n total = total * 60 + n;\n }\n return total <= MAX_TIMESTAMP_SECONDS ? total : null;\n}\nconst isTimestamp = (v: unknown): v is number => typeof v === \"number\" && Number.isFinite(v) && v >= 0 && v <= MAX_TIMESTAMP_SECONDS;\nconst notesWithText = (value: Json | undefined): JsonObject[] =>\n Array.isArray(value) ? value.filter((n): n is JsonObject => isObject(n) && !blank(n.text)) : [];\n\nexport interface Highlight { start: number; end: number; quote: string; note: string }\nexport const MAX_HIGHLIGHT_NOTE_LENGTH = 1000;\n/** The longest passage one highlight may quote; also bounds a quote the server can't check against `props.text`. */\nexport const MAX_HIGHLIGHT_QUOTE_LENGTH = 2000;\nexport const HIGHLIGHT_NOTE_MESSAGE = \"Add a note to each highlight.\";\nconst sourceText = (field: FieldBlock) => (typeof field.props?.text === \"string\" && field.props.text ? field.props.text : undefined);\n\n/**\n * The structured field types, whose answers are lists or records rather than one\n * value:\n * - `list`: several short answers, e.g. goals, action items, three things that went well.\n * - `table`: a small table each answer fills row by row, e.g. an action plan\n * (What / Who / By when), pros and cons.\n * - `media-notes`: notes pinned to times in a video or audio, e.g. lecture notes,\n * a recorded call review.\n * - `text-highlights`: highlight passages of a text and note on each, e.g.\n * annotating an article, a policy or a contract.\n *\n * They are registered like any other, but the builder offers them only to a\n * host that names them in its palette (`FormBuilder palette`), so forms that\n * never had them don't change.\n */\nexport const STRUCTURED_FIELD_TYPES = [\"list\", \"table\", \"media-notes\", \"text-highlights\"] as const;\n\nconst listProps: PropsCheck = (props, check) => {\n check.optionalInt(props.min, \"min\", 0);\n check.optionalInt(props.max, \"max\", 1);\n check.optionalInt(props.itemMaxLength, \"itemMaxLength\", 1);\n check.optionalText(props.placeholder, \"placeholder\");\n check.ordered(props.min, props.max ?? 10, \"min\", \"most items\");\n};\n\n// Checked with or without props: a table with no columns would block every submission.\nconst tableProps: PropsCheck = (props, check) => {\n const columns = props.columns;\n if (!Array.isArray(columns) || columns.length < 1 || columns.length > MAX_TABLE_COLUMNS) {\n check.issue(\"columns\", `Must be a list of 1 to ${MAX_TABLE_COLUMNS} columns.`);\n } else {\n const seen = new Set<string>();\n columns.forEach((c, j) => {\n const at = `columns[${j}]`;\n if (!isPlainRecord(c)) return check.issue(at, \"Each column needs a key and a label.\");\n if (check.name(c.key, `${at}.key`, \"A column key\")) {\n if (seen.has(c.key)) check.issue(`${at}.key`, `Duplicate column key \"${c.key}\".`);\n seen.add(c.key);\n }\n check.text(c.label, `${at}.label`);\n check.optionalBoolean(c.long, `${at}.long`);\n });\n }\n check.optionalInt(props.minRows, \"minRows\", 0);\n check.optionalInt(props.maxRows, \"maxRows\", 1);\n check.ordered(props.minRows, props.maxRows ?? 3, \"minRows\", \"most rows\");\n};\n\nexport const structuredFieldTypes: FieldTypeManifest[] = [\n {\n type: \"list\", label: \"List\", category: \"text\", value: { json: true }, literal: \"string\",\n checkProps: listProps,\n // logic.ts `contains` on an array is exact item equality, same as multi-choice, so it is offered.\n operators: [\"contains\", \"answered\", \"empty\"], a11y: { semantics: \"group\" },\n isEmpty: (value) => emptyList(value, blankText),\n validate: (value, field) => {\n if (!Array.isArray(value) || !value.every((v) => typeof v === \"string\")) return \"Enter a list of answers.\";\n const { min, max, itemMaxLength } = listLimits(field);\n if (value.some((v) => (v as string).trim().length > itemMaxLength)) return `Keep each item under ${itemMaxLength} characters.`;\n const count = listItems(value).length;\n if (count < min) return `Add at least ${plural(min, \"item\")}.`;\n if (count > max) return `Add at most ${plural(max, \"item\")}.`;\n return null;\n },\n normalize: (value) => (Array.isArray(value) ? listItems(value).map((v) => v.trim()) : value),\n summarize: (value) => listItems(value).map((v) => v.trim()).join(\"; \"),\n samples: (field) => {\n const { min, max } = listLimits(field);\n return [Array.from({ length: Math.min(Math.max(1, min), max) }, (_, i) => `Item ${i + 1}`)];\n },\n },\n {\n type: \"table\", label: \"Table\", category: \"advanced\", value: { json: true },\n checkProps: tableProps,\n operators: [\"answered\", \"empty\"], a11y: { semantics: \"group\" },\n isEmpty: (value) => emptyList(value, (r) => isObject(r) && Object.values(r).every(blankText)),\n validate: (value, field) => {\n const columns = tableColumns(field);\n if (!columns.length) return \"This question has no columns.\";\n if (!Array.isArray(value) || !value.every(isObject)) return \"Fill in the rows.\";\n const keys = new Set(columns.map((c) => c.key));\n for (const row of value as JsonObject[]) {\n for (const [key, cell] of Object.entries(row)) {\n if (!keys.has(key)) return \"An answer names a column this question doesn't have.\";\n if (typeof cell !== \"string\") return \"Fill in the rows with text.\";\n if (cell.trim().length > MAX_TABLE_CELL_LENGTH) return `Keep each answer under ${MAX_TABLE_CELL_LENGTH} characters.`;\n }\n }\n const { minRows, maxRows } = tableLimits(field);\n const count = filledRows(value).length;\n if (count < minRows) return `Fill in at least ${plural(minRows, \"row\")}.`;\n if (count > maxRows) return `Fill in at most ${plural(maxRows, \"row\")}.`;\n return null;\n },\n normalize: (value) => Array.isArray(value)\n ? filledRows(value).map((row) => {\n const out: JsonObject = {};\n for (const [key, cell] of Object.entries(row)) if (typeof cell === \"string\") out[key] = cell.trim();\n return out;\n })\n : value,\n summarize: (value, field) => {\n const columns = tableColumns(field);\n return filledRows(value)\n .map((row) => columns.filter((c) => !blank(row[c.key])).map((c) => `${c.label}: ${(row[c.key] as string).trim()}`).join(\" · \"))\n .join(\" / \");\n },\n samples: (field) => {\n const columns = tableColumns(field);\n if (!columns.length) return [];\n const { minRows, maxRows } = tableLimits(field);\n const row = Object.fromEntries(columns.map((c) => [c.key, \"sample\"]));\n return [Array.from({ length: Math.min(Math.max(1, minRows), maxRows) }, () => ({ ...row }))];\n },\n },\n {\n type: \"media-notes\", label: \"Notes at moments\", category: \"media\", value: { json: true },\n checkProps: (props, check) => {\n check.optionalInt(props.maxNotes, \"maxNotes\", 1);\n check.optionalInt(props.textMaxLength, \"textMaxLength\", 1);\n },\n operators: [\"answered\", \"empty\"], a11y: { semantics: \"group\" },\n isEmpty: (value) => emptyList(value, (n) => isObject(n) && blankText(n.text)),\n validate: (value, field) => {\n if (!Array.isArray(value)) return \"Add notes.\";\n const textMaxLength = intProp(field, \"textMaxLength\", 1000);\n for (const note of value) {\n if (!isObject(note) || typeof note.text !== \"string\") return \"Add notes.\";\n if (!isTimestamp(note.at)) return \"Each note needs a time.\";\n if (note.text.trim().length > textMaxLength) return `Keep each note under ${textMaxLength} characters.`;\n }\n const maxNotes = intProp(field, \"maxNotes\", 20);\n return notesWithText(value).length > maxNotes ? `Add at most ${plural(maxNotes, \"note\")}.` : null;\n },\n normalize: (value) => Array.isArray(value)\n ? notesWithText(value).map((n) => ({ at: n.at as number, text: (n.text as string).trim() })).sort((a, b) => a.at - b.at)\n : value,\n summarize: (value) => notesWithText(value)\n .map((n) => ({ at: typeof n.at === \"number\" ? n.at : 0, text: (n.text as string).trim() }))\n .sort((a, b) => a.at - b.at)\n .map((n) => `${formatTimestamp(n.at)} ${n.text}`)\n .join(\"; \"),\n samples: () => [[{ at: 0, text: \"sample\" }]],\n },\n {\n type: \"text-highlights\", label: \"Highlights\", category: \"media\", value: { json: true },\n checkProps: (props, check) => {\n check.optionalText(props.text, \"text\");\n check.optionalInt(props.maxHighlights, \"maxHighlights\", 1);\n },\n operators: [\"answered\", \"empty\"], a11y: { semantics: \"group\" },\n isEmpty: (value) => emptyList(value, () => false),\n validate: (value, field) => {\n if (!Array.isArray(value)) return \"Highlight a passage.\";\n const maxHighlights = intProp(field, \"maxHighlights\", 20);\n if (value.length > maxHighlights) return `Add at most ${plural(maxHighlights, \"highlight\")}.`;\n const text = sourceText(field);\n for (const h of value) {\n if (!isObject(h) || !Number.isInteger(h.start) || !Number.isInteger(h.end) || typeof h.quote !== \"string\" || typeof h.note !== \"string\") {\n return \"Highlight a passage of the text.\";\n }\n const start = h.start as number;\n const end = h.end as number;\n if (start < 0 || end <= start || h.quote.length !== end - start) return \"Highlight a passage of the text.\";\n if (end - start > MAX_HIGHLIGHT_QUOTE_LENGTH) return `Highlight under ${MAX_HIGHLIGHT_QUOTE_LENGTH} characters at a time.`;\n if (text !== undefined && (end > text.length || text.slice(start, end) !== h.quote)) return \"A highlight doesn't match the text.\";\n if (h.note.trim() === \"\") return HIGHLIGHT_NOTE_MESSAGE;\n if (h.note.trim().length > MAX_HIGHLIGHT_NOTE_LENGTH) return `Keep each note under ${MAX_HIGHLIGHT_NOTE_LENGTH} characters.`;\n }\n return null;\n },\n normalize: (value) => Array.isArray(value)\n ? value.filter(isObject)\n .map((h) => ({ start: h.start as number, end: h.end as number, quote: h.quote as string, note: String(h.note).trim() }))\n .sort((a, b) => a.start - b.start || a.end - b.end)\n : value,\n summarize: (value) => Array.isArray(value)\n ? value.filter(isObject).map((h) => `\"${String(h.quote)}\" — ${String(h.note).trim()}`).join(\"; \")\n : \"\",\n samples: (field) => {\n const text = sourceText(field);\n if (text === undefined) return [[{ start: 0, end: 6, quote: \"sample\", note: \"sample\" }]];\n const end = Math.min(text.length, 20);\n return [[{ start: 0, end, quote: text.slice(0, end), note: \"sample\" }]];\n },\n },\n];\n","import type { FieldTypeManifest } from \"./fields\";\nimport { isWholeNumber } from \"./props-check\";\nimport type { FieldBlock, Json } from \"./types\";\n\n/**\n * The `photo` field type: a respondent attaches up to a few photos, such as a\n * picture of broken equipment. The answer holds references the host's storage\n * handed back (`PhotoRef`), never the bytes: the renderer uploads through the\n * host (`onUpload` on genesis-forms-web's `Form`), so the engine and the\n * server stay storage-agnostic. A host's server should check that each\n * reference is a file it stored for this respondent before saving.\n *\n * Opt-in in a builder palette (`UPLOAD_FIELD_TYPES`), since a host must be\n * able to store the files.\n */\nexport const PHOTO_TYPE = \"photo\";\n\n/** Field types that need the host to store files; a builder offers them only when the host names them. */\nexport const UPLOAD_FIELD_TYPES = [PHOTO_TYPE] as const;\n\n/** One stored photo, as the host's upload returned it. */\nexport type PhotoRef = {\n /** The host's id for the stored file. */\n id: string;\n /** The file's name on the respondent's device. */\n name: string;\n /** Its MIME type, such as `image/jpeg`. */\n type: string;\n /** Bytes. */\n size: number;\n};\n\nexport type PhotoFormat = \"jpeg\" | \"png\" | \"heic\" | \"webp\";\n\n/** The MIME types each format covers. */\nexport const PHOTO_FORMATS: Record<PhotoFormat, readonly string[]> = {\n jpeg: [\"image/jpeg\"],\n png: [\"image/png\"],\n heic: [\"image/heic\", \"image/heif\"],\n webp: [\"image/webp\"],\n};\n\nconst FORMAT_NAMES: Record<PhotoFormat, string> = { jpeg: \"JPEG\", png: \"PNG\", heic: \"HEIC\", webp: \"WebP\" };\nconst ALL_FORMATS = Object.keys(PHOTO_FORMATS) as PhotoFormat[];\n\nexport const DEFAULT_PHOTO_FILES = 3;\nexport const MAX_PHOTO_FILES = 5;\nexport const DEFAULT_PHOTO_SIZE_MB = 10;\nexport const MAX_PHOTO_SIZE_MB = 25;\n/** The longest reference id and file name a photo answer may carry. */\nexport const MAX_PHOTO_ID_LENGTH = 200;\nexport const MAX_PHOTO_NAME_LENGTH = 255;\n\nexport const isPhotoFormat = (v: unknown): v is PhotoFormat =>\n typeof v === \"string\" && Object.prototype.hasOwnProperty.call(PHOTO_FORMATS, v);\n\nconst wholeIn = (v: unknown, min: number, max: number): v is number =>\n typeof v === \"number\" && Number.isInteger(v) && v >= min && v <= max;\n\nexport interface PhotoLimits {\n maxFiles: number;\n maxSizeMb: number;\n maxBytes: number;\n formats: PhotoFormat[];\n /** Every MIME type the formats cover. */\n mimeTypes: string[];\n}\n\n/** A photo field's limits; a prop that is missing or out of range uses its default. */\nexport function photoLimits(field: FieldBlock): PhotoLimits {\n const maxFiles = wholeIn(field.props?.maxFiles, 1, MAX_PHOTO_FILES) ? field.props.maxFiles : DEFAULT_PHOTO_FILES;\n const maxSizeMb = wholeIn(field.props?.maxSizeMb, 1, MAX_PHOTO_SIZE_MB) ? field.props.maxSizeMb : DEFAULT_PHOTO_SIZE_MB;\n const raw = field.props?.formats;\n const picked = Array.isArray(raw) ? ALL_FORMATS.filter((f) => raw.includes(f)) : [];\n const formats = picked.length ? picked : [...ALL_FORMATS];\n return {\n maxFiles,\n maxSizeMb,\n maxBytes: maxSizeMb * 1024 * 1024,\n formats,\n mimeTypes: formats.flatMap((f) => PHOTO_FORMATS[f]),\n };\n}\n\n/** Whether `v` has a photo reference's shape (any type and size). */\nexport function isPhotoRef(v: unknown): v is PhotoRef {\n if (!v || typeof v !== \"object\" || Array.isArray(v)) return false;\n const r = v as Record<string, unknown>;\n return (\n typeof r.id === \"string\" &&\n r.id.length > 0 &&\n r.id.length <= MAX_PHOTO_ID_LENGTH &&\n typeof r.name === \"string\" &&\n r.name.length <= MAX_PHOTO_NAME_LENGTH &&\n typeof r.type === \"string\" &&\n typeof r.size === \"number\" &&\n Number.isInteger(r.size) &&\n r.size > 0\n );\n}\n\n/** The well-formed references in a photo answer, as `{ id, name, type, size }` only. */\nexport function photoRefs(value: Json | undefined): PhotoRef[] {\n if (!Array.isArray(value)) return [];\n const refs: PhotoRef[] = [];\n for (const r of value as unknown[]) if (isPhotoRef(r)) refs.push({ id: r.id, name: r.name, type: r.type, size: r.size });\n return refs;\n}\n\nconst plural = (n: number, one: string, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;\n\n/** \"JPEG, PNG or WebP\". */\nexport function photoFormatList(formats: readonly PhotoFormat[]): string {\n const names = formats.map((f) => FORMAT_NAMES[f]);\n return names.length > 1 ? `${names.slice(0, -1).join(\", \")} or ${names[names.length - 1]}` : (names[0] ?? \"\");\n}\n\n/** The message for a file of a type the field doesn't take. */\nexport const photoTypeMessage = (field: FieldBlock) => `Use a ${photoFormatList(photoLimits(field).formats)} photo.`;\n/** The message for a file over the field's size limit. */\nexport const photoSizeMessage = (field: FieldBlock) => `Each photo must be ${photoLimits(field).maxSizeMb} MB or smaller.`;\n/** The message for more photos than the field takes. */\nexport const photoCountMessage = (field: FieldBlock) => `Add at most ${plural(photoLimits(field).maxFiles, \"photo\")}.`;\n\nexport const photoFieldType: FieldTypeManifest = {\n type: PHOTO_TYPE,\n label: \"Photo\",\n category: \"media\",\n value: { json: true },\n operators: [\"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n checkProps: (props, check) => {\n if (props.maxFiles !== undefined && !(isWholeNumber(props.maxFiles) && props.maxFiles >= 1 && props.maxFiles <= MAX_PHOTO_FILES)) {\n check.issue(\"maxFiles\", `Must be a whole number from 1 to ${MAX_PHOTO_FILES}.`);\n }\n if (props.maxSizeMb !== undefined && !(isWholeNumber(props.maxSizeMb) && props.maxSizeMb >= 1 && props.maxSizeMb <= MAX_PHOTO_SIZE_MB)) {\n check.issue(\"maxSizeMb\", `Must be a whole number from 1 to ${MAX_PHOTO_SIZE_MB}.`);\n }\n if (props.formats !== undefined) {\n const formats = props.formats;\n if (!Array.isArray(formats) || formats.length === 0 || !formats.every(isPhotoFormat)) {\n check.issue(\"formats\", \"Must be a list of one or more of jpeg, png, heic and webp.\");\n } else if (new Set(formats).size !== formats.length) {\n check.issue(\"formats\", \"Name each format once.\");\n }\n }\n },\n isEmpty: (value) => value === undefined || value === null || (Array.isArray(value) && value.length === 0),\n validate: (value, field) => {\n if (!Array.isArray(value) || !value.every(isPhotoRef)) return \"Add a photo.\";\n const limits = photoLimits(field);\n if (value.length > limits.maxFiles) return photoCountMessage(field);\n const refs = value as unknown as PhotoRef[];\n if (new Set(refs.map((r) => r.id)).size !== refs.length) return \"Each photo can be added once.\";\n if (refs.some((r) => !limits.mimeTypes.includes(r.type.toLowerCase()))) return photoTypeMessage(field);\n if (refs.some((r) => r.size > limits.maxBytes)) return photoSizeMessage(field);\n return null;\n },\n normalize: (value) => (Array.isArray(value) && value.every(isPhotoRef) ? photoRefs(value) : value),\n summarize: (value) => photoRefs(value).map((r) => r.name || \"Photo\").join(\", \"),\n samples: () => [[{ id: \"sample-photo\", name: \"photo.jpg\", type: \"image/jpeg\", size: 1024 }]],\n};\n","import type { Block, ContentBlock, FieldBlock, FormDefinition, Json, Operator, OptionsSource } from \"./types\";\nimport { calculatedFieldType } from \"./calculated\";\nimport { structuredFieldTypes } from \"./structured\";\nimport { photoFieldType } from \"./photo\";\nimport { isFiniteNumber, type PropsCheck } from \"./props-check\";\nimport type { AnswerSnapshot, OptionSnapshot } from \"./options\";\n\n/** The JSON type a comparison literal must have to match an answer (`parseForm` warns otherwise). */\nexport type LiteralType = \"string\" | \"number\" | \"boolean\";\n\n/**\n * A field kind, without any UI: the one definition the engine, `parseForm`, validation, the\n * server and snapshots all read, so a kind is described once instead of in a switch in each.\n * Renderers are registered separately per platform (`genesis-forms-react`), so a manifest runs\n * anywhere. Every hook is optional except where noted; a missing one means \"nothing special\".\n * `validate`, `checkProps`, `literal`, `snapshot` and `fromSnapshot` may throw (each fails safe,\n * as its doc says); `isEmpty`, `normalize` and `summarize` must not.\n */\nexport interface FieldTypeManifest {\n type: string;\n label: string;\n category: \"text\" | \"choice\" | \"scale\" | \"date\" | \"media\" | \"advanced\";\n /** `json: false` types must convert, so drafts and server replay never lose an answer. */\n value:\n | { json: true }\n | { json: false; serialize: (value: unknown) => Json; deserialize: (json: Json) => unknown };\n operators: Operator[];\n a11y: {\n semantics: \"control\" | \"group\";\n /** The HTML `autocomplete` token, such as `\"email\"` or `\"tel\"`. */\n autocomplete?: string;\n /** The HTML `inputmode` hint for on-screen keyboards, such as `\"email\"` or `\"tel\"`. */\n inputMode?: \"text\" | \"email\" | \"tel\" | \"numeric\" | \"decimal\" | \"url\" | \"search\";\n };\n /**\n * The props schema: `parseForm` calls it with the field's `props` (`{}` when it has none) and\n * reports what it finds as issues at `blocks[i].props.<path>`. A check that throws is reported\n * as one issue, never thrown.\n */\n checkProps?: PropsCheck;\n /**\n * The answer's shape. `choice`: the answer is one of `props.options` (`multiple: false`, a\n * text) or several (`multiple: true`, a list of texts), so the field takes `optionsFrom`,\n * `prefill`, `other` and filters, and its answers are snapshotted with their labels. Without\n * its own `validate` (or `summarize`) it gets the built-in one for its shape, so an answer is\n * always one of its options (or a typed \"Other\" when `props.other` allows it).\n */\n choice?: { multiple: boolean };\n /**\n * The JSON type a logic literal compared with this field must have, or a function of its props\n * (`undefined`: not known). `parseForm` warns about a literal that can never match.\n */\n literal?: LiteralType | ((props: Readonly<Record<string, unknown>>) => LiteralType | undefined);\n /** The empty-check: whether a value counts as no answer. Default: nothing, null, blank text or `[]`. */\n isEmpty?: (value: Json | undefined) => boolean;\n /**\n * The validator: an error message, or null when the (non-empty) value is valid. A validator\n * that throws refuses the answer (`VALIDATOR_FAILED_MESSAGE`) rather than throwing.\n */\n validate?: (value: Json, field: FieldBlock) => string | null;\n /** The display text: plain text for recall, exports and emails. */\n summarize?: (value: Json, field: FieldBlock) => string;\n /**\n * The form a (valid, non-empty) value is stored in, such as an email\n * without surrounding spaces. Applied by `engine.answers()` and the server.\n */\n normalize?: (value: Json, field: FieldBlock) => Json;\n /**\n * The snapshot of a (non-empty) answer as it was when stored, for `answerSnapshots`: the\n * labels it showed, so history keeps them when the source changes. Choice kinds have one\n * built in (for fields with `optionsFrom`); give another kind one here.\n */\n snapshot?: (value: Json, field: FieldBlock) => AnswerSnapshot | undefined;\n /**\n * The reverse of `snapshot`, for `answersFromSnapshots`: the answer to prefill from a stored\n * snapshot (or none), and the picks that no longer exist.\n */\n fromSnapshot?: (snapshot: unknown, field: FieldBlock) => { value?: Json; missing: OptionSnapshot[] };\n /** Valid example answers, used by `coverage()` and other test tools to explore a path. */\n samples?: (field: FieldBlock) => Json[];\n}\n\n/** The message an answer gets when its kind's validator throws. */\nexport const VALIDATOR_FAILED_MESSAGE = \"This answer couldn't be checked.\";\n\n// One registry per process, shared by every entry point (index, server,\n// testing are bundled separately), so a plugin registered once is seen by all.\n// The key names the manifest format: a copy of an older release in the same\n// process (whose manifests lack `choice`, `checkProps` and `literal`) keeps its\n// own registry instead of overwriting these built-ins or keeping its own.\nconst REGISTRY = Symbol.for(\"@marktiderman/genesis-forms/field-types@2\");\nconst BUILT_IN = Symbol.for(\"@marktiderman/genesis-forms/built-in-field-types@2\");\nconst globalScope = globalThis as typeof globalThis & {\n [REGISTRY]?: Map<string, FieldTypeManifest>;\n [BUILT_IN]?: Set<string>;\n};\nconst registry: Map<string, FieldTypeManifest> = (globalScope[REGISTRY] ??= new Map());\nconst builtIn: Set<string> = (globalScope[BUILT_IN] ??= new Set());\n\nexport interface RegisterOptions {\n /**\n * Replace a built-in kind (`email`, `single-choice`…). Off by default: the registry is shared\n * by every form in the process, the server's checks included, so changing what a built-in\n * accepts must be deliberate.\n */\n replace?: boolean;\n}\n\nconst freezeRecord = (v: unknown) => (v && typeof v === \"object\" && !Array.isArray(v) ? Object.freeze({ ...v }) : v);\n\n/**\n * A frozen copy, so changing the object after registering it (or the one `getFieldType`\n * returns) changes nothing the engine or the server reads: `choice`, `a11y` and `value` are\n * frozen copies too, and `operators` hands out a fresh copy of the list on each read.\n */\nfunction frozen<T extends object>(manifest: T): T {\n const copy = { ...manifest } as Record<string, unknown>;\n for (const key of [\"choice\", \"a11y\", \"value\"]) if (key in copy) copy[key] = freezeRecord(copy[key]);\n if (Array.isArray(copy.operators)) {\n const operators = Object.freeze([...(copy.operators as unknown[])]);\n Object.defineProperty(copy, \"operators\", { get: () => [...operators], enumerable: true });\n }\n return Object.freeze(copy) as T;\n}\n\n/**\n * Register a field kind, or replace one a host registered before (re-registering is allowed,\n * so hot reload works). Throws on a malformed manifest, and on a built-in kind's name unless\n * `{ replace: true }`. Registered kinds are frozen copies.\n */\nexport function registerFieldType(manifest: FieldTypeManifest, options: RegisterOptions = {}): void {\n if (!manifest || typeof manifest.type !== \"string\" || !manifest.type) {\n throw new Error(\"registerFieldType: a field type needs a `type`.\");\n }\n const value = manifest.value as { json: boolean; serialize?: unknown; deserialize?: unknown } | undefined;\n if (\n value &&\n !value.json &&\n (typeof value.serialize !== \"function\" || typeof value.deserialize !== \"function\")\n ) {\n throw new Error(\n `registerFieldType: \"${manifest.type}\" stores a non-JSON value, so it must provide both serialize and deserialize.`,\n );\n }\n if (!value || !Array.isArray(manifest.operators)) {\n throw new Error(`registerFieldType: \"${manifest.type}\" needs a \\`value\\` and a list of \\`operators\\`.`);\n }\n if (manifest.choice !== undefined && typeof manifest.choice?.multiple !== \"boolean\") {\n throw new Error(`registerFieldType: \"${manifest.type}\" has a \\`choice\\` without \\`multiple: true | false\\`.`);\n }\n if (builtIn.has(manifest.type) && options.replace !== true) {\n throw new Error(\n `registerFieldType: \"${manifest.type}\" is a built-in field type; pass { replace: true } to replace it for every form in this process.`,\n );\n }\n registry.set(manifest.type, frozen(withChoiceDefaults(manifest)));\n}\n\n/** Built-ins: the first copy loaded wins, so a later entry point never undoes a host's `replace`. */\nfunction registerBuiltIn(manifest: FieldTypeManifest): void {\n builtIn.add(manifest.type);\n if (!registry.has(manifest.type)) registry.set(manifest.type, frozen(manifest));\n}\n\nexport function getFieldType(type: string): FieldTypeManifest | undefined {\n return registry.get(type);\n}\n\nexport function listFieldTypes(): FieldTypeManifest[] {\n return [...registry.values()];\n}\n\n/** Whether `type` is one of the field kinds the package ships. */\nexport function isBuiltInFieldType(type: string): boolean {\n return builtIn.has(type);\n}\n\n/** A choice kind's answer shape (`FieldTypeManifest.choice`), or undefined for any other kind. */\nexport function choiceKind(type: string): { multiple: boolean } | undefined {\n return registry.get(type)?.choice;\n}\n\n/** Whether a block is a field of a choice kind: its answer is one or more of its options. */\nexport function isChoiceField(block: unknown): block is FieldBlock {\n return (\n !!block &&\n (block as FieldBlock).kind === \"field\" &&\n typeof (block as FieldBlock).type === \"string\" &&\n choiceKind((block as FieldBlock).type) !== undefined\n );\n}\n\n/** The JSON type a logic literal must have to match a field of `type` with these props, when known. */\nexport function literalType(type: string, props: Readonly<Record<string, unknown>>): LiteralType | undefined {\n const literal = registry.get(type)?.literal;\n if (typeof literal !== \"function\") return literal;\n try {\n return literal(props);\n } catch {\n // Not known: `parseForm` only warns from it, and never throws.\n return undefined;\n }\n}\n\n// ── Content kinds ────────────────────────────────────────────────────────────\n\n/**\n * A content kind (a block that shows something and takes no answer): `heading` and `text` are\n * built in; a host registers others (a message screen, a media block) with\n * `registerContentType`, plus a renderer per platform.\n */\nexport interface ContentTypeManifest {\n type: string;\n label: string;\n /** The props schema, as for a field kind; the block's `props`, `{}` when it has none. */\n checkProps?: PropsCheck;\n /** The display text (recall, exports, a renderer with no special drawing). Default: `block.text`. */\n text?: (block: ContentBlock) => string;\n}\n\nconst CONTENT_REGISTRY = Symbol.for(\"@marktiderman/genesis-forms/content-types@1\");\nconst contentScope = globalThis as typeof globalThis & { [CONTENT_REGISTRY]?: Map<string, ContentTypeManifest> };\nconst contentRegistry: Map<string, ContentTypeManifest> = (contentScope[CONTENT_REGISTRY] ??= new Map());\nconst BUILT_IN_CONTENT: ReadonlySet<string> = new Set([\"heading\", \"text\"]);\n\n/** Register a content kind. Throws on a malformed manifest or a built-in kind's name (unless `{ replace: true }`). */\nexport function registerContentType(manifest: ContentTypeManifest, options: RegisterOptions = {}): void {\n if (!manifest || typeof manifest.type !== \"string\" || !manifest.type) {\n throw new Error(\"registerContentType: a content type needs a `type`.\");\n }\n if (typeof manifest.label !== \"string\") throw new Error(`registerContentType: \"${manifest.type}\" needs a \\`label\\`.`);\n for (const hook of [\"checkProps\", \"text\"] as const) {\n if (manifest[hook] !== undefined && typeof manifest[hook] !== \"function\") {\n throw new Error(`registerContentType: \"${manifest.type}\" has a \\`${hook}\\` that isn't a function.`);\n }\n }\n if (BUILT_IN_CONTENT.has(manifest.type) && options.replace !== true) {\n throw new Error(\n `registerContentType: \"${manifest.type}\" is a built-in content type; pass { replace: true } to replace it for every form in this process.`,\n );\n }\n contentRegistry.set(manifest.type, frozen(manifest));\n}\n\nexport function getContentType(type: string): ContentTypeManifest | undefined {\n return contentRegistry.get(type);\n}\n\nexport function listContentTypes(): ContentTypeManifest[] {\n return [...contentRegistry.values()];\n}\n\n/** A content block's display text: its kind's `text` (when it gives a string without throwing), or `block.text`. */\nexport function contentText(block: ContentBlock): string {\n const text = contentRegistry.get(block.type)?.text;\n if (!text) return block.text;\n try {\n const shown = text(block);\n return typeof shown === \"string\" ? shown : block.text;\n } catch {\n return block.text;\n }\n}\n\nfor (const manifest of [\n { type: \"heading\", label: \"Heading\" },\n { type: \"text\", label: \"Text\" },\n] satisfies ContentTypeManifest[]) {\n if (!contentRegistry.has(manifest.type)) contentRegistry.set(manifest.type, frozen(manifest));\n}\n\nexport function isEmptyValue(value: Json | undefined, field?: FieldBlock): boolean {\n const manifest = field ? registry.get(field.type) : undefined;\n if (manifest?.isEmpty) return manifest.isEmpty(value);\n if (value === undefined || value === null) return true;\n if (typeof value === \"string\") return value.trim() === \"\";\n if (Array.isArray(value)) return value.length === 0;\n return false;\n}\n\n/** A value in its stored form (see `FieldTypeManifest.normalize`). */\nexport function normalizeValue(value: Json, field: FieldBlock): Json {\n const manifest = registry.get(field.type);\n return manifest?.normalize ? manifest.normalize(value, field) : value;\n}\n\n/** Whether a block holds personal or secret data: `sensitive: true`, or the `props.sensitive: true` alias. */\nexport function isSensitive(block: Block): boolean {\n return block.kind === \"field\" && (block.sensitive === true || block.props?.sensitive === true);\n}\n\nexport function summarizeValue(value: Json | undefined, field: FieldBlock): string {\n if (isEmptyValue(value, field)) return \"\";\n const manifest = registry.get(field.type);\n if (manifest?.summarize) return manifest.summarize(value as Json, field);\n if (Array.isArray(value)) return value.join(\", \");\n return String(value);\n}\n\n// ── Built-in types (R1) ──────────────────────────────────────────────────────\n\nexport interface ChoiceOption {\n value: string;\n label?: string;\n /** A muted line under the label, such as a location's address. At most `OPTION_LIMITS.description` characters. */\n description?: string;\n /** A small picture beside the label: an `https://` URL, at most `OPTION_LIMITS.image` characters. */\n image?: string;\n /**\n * Facts about the option for filtering and recall, such as `{ location: [\"riverside\", \"hilltop\"] }`\n * for a coach who works at two locations (see `props.optionsFrom.filter`). Names and values are\n * text; a value is one text or a list of them.\n */\n attributes?: Record<string, string | string[]>;\n}\n\n/** Bounds on an option's extra details. A longer or malformed detail is dropped when options are read. */\nexport const OPTION_LIMITS = {\n /** Characters in a description. */\n description: 500,\n /** Characters in an image URL. */\n image: 2048,\n /** Attributes on one option. */\n attributes: 20,\n /** Characters in an attribute's name. */\n attributeName: 64,\n /** Characters in one attribute value. */\n attributeValue: 200,\n /** Values in one attribute's list. */\n attributeItems: 50,\n} as const;\n\n/**\n * Whether `url` is an `https://` link with a host and no spaces or control characters, within\n * `OPTION_LIMITS.image`. A pattern rather than `new URL`, so it behaves the same in React Native.\n */\nexport function isHttpsUrl(url: unknown): url is string {\n return (\n typeof url === \"string\" &&\n url.length <= OPTION_LIMITS.image &&\n /^https:\\/\\/[^\\s/?#@\\\\]+(?:[/?#][^\\s]*)?$/i.test(url) &&\n // No control characters anywhere (a line break would end a CSV row or an HTML attribute).\n ![...url].some((c) => c.charCodeAt(0) < 32 || c.charCodeAt(0) === 127)\n );\n}\n\n/** A well-formed attribute name: text, not blank, not an `Object.prototype` name, within the limit. */\nfunction attributeName(name: string): boolean {\n return name.trim() !== \"\" && name.length <= OPTION_LIMITS.attributeName && !(name in Object.prototype);\n}\n\n/** The attributes of a raw option that are well formed, or undefined when none are. */\nfunction readAttributes(raw: unknown): Record<string, string | string[]> | undefined {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return undefined;\n const out: Record<string, string | string[]> = {};\n let count = 0;\n for (const name of Object.keys(raw)) {\n if (count >= OPTION_LIMITS.attributes) break;\n if (!attributeName(name)) continue;\n const v = (raw as Record<string, unknown>)[name];\n const fits = (x: unknown): x is string => typeof x === \"string\" && x.length <= OPTION_LIMITS.attributeValue;\n if (fits(v)) out[name] = v;\n else if (Array.isArray(v) && v.length <= OPTION_LIMITS.attributeItems && v.every(fits)) out[name] = [...v];\n else continue;\n count++;\n }\n return count ? out : undefined;\n}\n\n/**\n * An option from untrusted JSON (a definition, the host's list): its string `value`, and its\n * `label`, `description`, `image` and `attributes` when each is well formed and within\n * `OPTION_LIMITS`; anything else is left out. Null when there is no string value.\n */\nexport function readOption(raw: unknown): ChoiceOption | null {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return null;\n const o = raw as Record<string, unknown>;\n if (typeof o.value !== \"string\") return null;\n const out: ChoiceOption = { value: o.value };\n if (typeof o.label === \"string\") out.label = o.label;\n if (typeof o.description === \"string\" && o.description.trim() && o.description.length <= OPTION_LIMITS.description) {\n out.description = o.description;\n }\n if (isHttpsUrl(o.image)) out.image = o.image;\n const attributes = readAttributes(o.attributes);\n if (attributes) out.attributes = attributes;\n return out;\n}\n\n/** An option as JSON, with only the details it has. */\nexport function optionJson(option: ChoiceOption): Json {\n const out: Record<string, Json> = { value: option.value };\n if (option.label !== undefined) out.label = option.label;\n if (option.description !== undefined) out.description = option.description;\n if (option.image !== undefined) out.image = option.image;\n if (option.attributes !== undefined) out.attributes = { ...option.attributes } as Record<string, Json>;\n return out;\n}\n\n/** The longest answer an \"Other\" option takes. */\nexport const OTHER_MAX_LENGTH = 200;\n\n/**\n * A choice question's \"Other\" option (`props.other: true` or `{ label }`): the respondent types\n * their own answer, stored as the answer's value itself (single choice, dropdown) or as one more\n * item (multiple choice). Null when the question has none.\n */\nexport function otherOption(field: FieldBlock): { label: string } | null {\n const other = field.props?.other;\n if (other === true) return { label: \"Other\" };\n if (other && typeof other === \"object\" && !Array.isArray(other)) {\n const label = typeof other.label === \"string\" && other.label.trim() ? other.label.trim() : \"Other\";\n return { label };\n }\n return null;\n}\n\n/** Whether a value is a typed \"Other\" answer: text that isn't one of the question's options. */\nexport function isOtherValue(field: FieldBlock, value: unknown): value is string {\n return (\n otherOption(field) !== null &&\n typeof value === \"string\" &&\n !choiceOptions(field).some((o) => o.value === value)\n );\n}\n\nconst typedOther = (field: FieldBlock, value: unknown) =>\n isOtherValue(field, value) && value.trim() !== \"\" && value.length <= OTHER_MAX_LENGTH;\n\nexport function choiceOptions(field: FieldBlock): ChoiceOption[] {\n const raw = field.props?.options;\n if (!Array.isArray(raw)) return [];\n return raw.flatMap((o) => {\n const option = readOption(o);\n return option ? [option] : [];\n });\n}\n\n/**\n * Option lists the app showing a form supplies, by key (`OptionsSource.key`):\n * `{ coaches: [{ value: \"8c1…\", label: \"Ada Lovelace\" }] }`.\n */\nexport type HostOptions = Readonly<Record<string, readonly ChoiceOption[]>>;\n\n/**\n * A choice field's `props.optionsFrom`, when it is a well-formed `{ source: \"host\", key }`, with its\n * `filter` when that is well formed too (`{ attribute, field }`, both non-empty text).\n */\nexport function optionsSource(field: FieldBlock): OptionsSource | undefined {\n const raw = field.props?.optionsFrom;\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return undefined;\n if (raw.source !== \"host\" || typeof raw.key !== \"string\" || !raw.key) return undefined;\n const out: OptionsSource = { source: \"host\", key: raw.key };\n const filter = raw.filter;\n if (\n filter &&\n typeof filter === \"object\" &&\n !Array.isArray(filter) &&\n typeof filter.attribute === \"string\" &&\n filter.attribute &&\n typeof filter.field === \"string\" &&\n filter.field\n ) {\n out.filter = { attribute: filter.attribute, field: filter.field };\n }\n return out;\n}\n\n/** The host's list for `key`, as options: string values only, each value once, labels when they are text. */\nfunction hostList(hostOptions: HostOptions | undefined, key: string): ChoiceOption[] {\n if (!hostOptions || !Object.prototype.hasOwnProperty.call(hostOptions, key)) return [];\n const list = hostOptions[key];\n if (!Array.isArray(list)) return [];\n const seen = new Set<string>();\n const out: ChoiceOption[] = [];\n for (const o of list as unknown[]) {\n const option = readOption(o);\n if (!option || !option.value || seen.has(option.value)) continue;\n seen.add(option.value);\n out.push(option);\n }\n return out;\n}\n\n/**\n * The definition with each `optionsFrom: { source: \"host\" }` field's options\n * filled in from `hostOptions`: its own `props.options` first, then the host's\n * list for its key (a value the field already has is not added twice). A key\n * the host does not supply adds nothing, so the field offers its own options\n * only. `createForm` and `validateSubmission` call it with their `hostOptions`,\n * so a respondent sees, and a submit accepts, exactly these. Returns\n * `definition` itself when no field takes options from the host.\n */\nexport function withHostOptions(definition: FormDefinition, hostOptions: HostOptions | undefined): FormDefinition {\n let changed = false;\n const blocks = definition.blocks.map((block) => {\n if (block.kind !== \"field\") return block;\n const from = optionsSource(block);\n if (!from) return block;\n const own = choiceOptions(block);\n const taken = new Set(own.map((o) => o.value));\n const added = hostList(hostOptions, from.key).filter((o) => !taken.has(o.value));\n if (!added.length) return block;\n changed = true;\n const options = [...own, ...added].map(optionJson);\n return { ...block, props: { ...block.props, options } };\n });\n return changed ? { ...definition, blocks } : definition;\n}\n\nfunction optionLabel(field: FieldBlock, value: string): string {\n const option = choiceOptions(field).find((o) => o.value === value);\n return option?.label ?? value;\n}\n\nfunction intRange(field: FieldBlock, min: number, maxDefault: number) {\n const max = typeof field.props?.max === \"number\" ? field.props.max : maxDefault;\n return { min, max };\n}\n\nconst numberOps: Operator[] = [\"eq\", \"neq\", \"lt\", \"lte\", \"gt\", \"gte\", \"in\", \"answered\", \"empty\"];\nconst textOps: Operator[] = [\"eq\", \"neq\", \"contains\", \"answered\", \"empty\"];\n\nfunction maxLength(field: FieldBlock, fallback: number): number {\n return typeof field.props?.maxLength === \"number\" ? field.props.maxLength : fallback;\n}\n\nfunction textValidate(fallback: number) {\n return (value: Json, field: FieldBlock) => {\n if (typeof value !== \"string\") return \"Enter text.\";\n const limit = maxLength(field, fallback);\n return value.length > limit ? `Keep it under ${limit} characters.` : null;\n };\n}\n\n/** The longest address SMTP allows (RFC 5321). */\nconst MAX_EMAIL_LENGTH = 254;\n\n/**\n * `local@domain.tld`: no spaces, exactly one `@`, and a dot inside the domain.\n * A linear scan rather than a regex, so a hostile value cannot backtrack.\n */\nexport function isEmailAddress(value: string): boolean {\n if (value.length > MAX_EMAIL_LENGTH || /\\s/.test(value)) return false;\n const at = value.indexOf(\"@\");\n if (at < 1 || value.indexOf(\"@\", at + 1) !== -1) return false;\n const domain = value.slice(at + 1);\n // A dot with at least one character on each side.\n return domain.slice(1, -1).includes(\".\");\n}\n\n/** Longest phone number accepted, separators included. */\nconst MAX_PHONE_LENGTH = 32;\n\n/**\n * Digits with optional separators (spaces, `-`, `(`, `)`, `.`) and an\n * optional leading `+`; 7 to 15 digits (E.164 allows at most 15). One linear scan.\n */\nfunction isPhoneNumber(value: string): boolean {\n if (value.length > MAX_PHONE_LENGTH) return false;\n let digits = 0;\n for (let i = 0; i < value.length; i++) {\n const c = value[i]!;\n if (c >= \"0\" && c <= \"9\") digits++;\n else if (c === \"+\") {\n if (i !== 0) return false;\n } else if (c !== \" \" && c !== \"-\" && c !== \"(\" && c !== \")\" && c !== \".\") return false;\n }\n return digits >= 7 && digits <= 15;\n}\n\n/** A single choice's or dropdown's check: one of the options, or a typed \"Other\" answer. */\nconst oneOptionValidate = (value: Json, field: FieldBlock): string | null =>\n typeof value === \"string\" && (choiceOptions(field).some((o) => o.value === value) || typedOther(field, value))\n ? null\n : \"Choose one of the options.\";\nconst oneOptionSummary = (value: Json, field: FieldBlock) => optionLabel(field, String(value));\n\n/** A multiple choice's check. */\nconst optionsValidate = (value: Json, field: FieldBlock): string | null => {\n const allowed = new Set(choiceOptions(field).map((o) => o.value));\n // Each option at most once, plus at most one typed \"Other\" answer, so a value is never\n // longer than the option list and one.\n const others = Array.isArray(value) ? value.filter((v) => typeof v === \"string\" && !allowed.has(v)) : [];\n return Array.isArray(value) &&\n new Set(value).size === value.length &&\n value.every((v) => typeof v === \"string\") &&\n (others.length === 0 || (others.length === 1 && typedOther(field, others[0])))\n ? null\n : \"Choose from the options.\";\n};\nconst optionsSummary = (value: Json, field: FieldBlock) =>\n Array.isArray(value) ? value.map((v) => optionLabel(field, String(v))).join(\", \") : String(value);\n\n/**\n * A choice kind registered without its own `validate` or `summarize` gets the built-in ones for\n * its answer shape, so its answers are always checked against its options.\n */\nfunction withChoiceDefaults(manifest: FieldTypeManifest): FieldTypeManifest {\n if (!manifest.choice || (manifest.validate && manifest.summarize)) return manifest;\n const multiple = manifest.choice.multiple;\n return {\n ...manifest,\n validate: manifest.validate ?? (multiple ? optionsValidate : oneOptionValidate),\n summarize: manifest.summarize ?? (multiple ? optionsSummary : oneOptionSummary),\n };\n}\n\n/** A rating's or NPS's words under the ends of the scale. */\nconst scaleProps: PropsCheck = (props, check) => {\n check.optionalText(props.lowLabel, \"lowLabel\");\n check.optionalText(props.highLabel, \"highLabel\");\n};\n\nconst builtins: FieldTypeManifest[] = [\n {\n type: \"short-text\",\n label: \"Short text\",\n category: \"text\",\n value: { json: true },\n operators: textOps,\n a11y: { semantics: \"control\" },\n literal: \"string\",\n validate: textValidate(500),\n },\n {\n type: \"long-text\",\n label: \"Long text\",\n category: \"text\",\n value: { json: true },\n operators: textOps,\n a11y: { semantics: \"control\" },\n literal: \"string\",\n validate: textValidate(5000),\n },\n {\n type: \"email\",\n label: \"Email\",\n category: \"text\",\n value: { json: true },\n operators: textOps,\n a11y: { semantics: \"control\", autocomplete: \"email\", inputMode: \"email\" },\n literal: \"string\",\n validate: (value) =>\n typeof value === \"string\" && isEmailAddress(value.trim())\n ? null\n : \"Enter an email address like name@example.com.\",\n normalize: (value) => (typeof value === \"string\" ? value.trim() : value),\n },\n {\n type: \"phone\",\n label: \"Phone\",\n category: \"text\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"answered\", \"empty\"],\n a11y: { semantics: \"control\", autocomplete: \"tel\", inputMode: \"tel\" },\n literal: \"string\",\n validate: (value) =>\n typeof value === \"string\" && isPhoneNumber(value.trim())\n ? null\n : \"Enter a phone number with 7 to 15 digits.\",\n normalize: (value) => (typeof value === \"string\" ? value.trim() : value),\n summarize: (value) => String(value),\n },\n {\n type: \"rating\",\n label: \"Rating\",\n category: \"scale\",\n value: { json: true },\n operators: numberOps,\n a11y: { semantics: \"group\" },\n literal: \"number\",\n checkProps: (props, check) => {\n scaleProps(props, check);\n if (props.display !== undefined && props.display !== \"numbers\" && props.display !== \"stars\") {\n check.issue(\"display\", \"Must be numbers or stars.\");\n }\n },\n validate: (value, field) => {\n const { min, max } = intRange(field, 1, 5);\n return Number.isInteger(value) && (value as number) >= min && (value as number) <= max\n ? null\n : `Choose a rating from ${min} to ${max}.`;\n },\n summarize: (value, field) => {\n const { max } = intRange(field, 1, 5);\n const end = scaleEndLabel(field, value as number, 1, max);\n return end ? `${value}/${max} (${end})` : `${value}/${max}`;\n },\n },\n {\n type: \"nps\",\n label: \"Net Promoter Score\",\n category: \"scale\",\n value: { json: true },\n operators: numberOps,\n a11y: { semantics: \"group\" },\n literal: \"number\",\n checkProps: scaleProps,\n validate: (value) =>\n Number.isInteger(value) && (value as number) >= 0 && (value as number) <= 10\n ? null\n : \"Choose a score from 0 to 10.\",\n summarize: (value, field) => {\n const end = scaleEndLabel(field, value as number, 0, 10);\n return end ? `${value}/10 (${end})` : `${value}/10`;\n },\n },\n {\n type: \"single-choice\",\n label: \"Single choice\",\n category: \"choice\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"in\", \"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n literal: \"string\",\n choice: { multiple: false },\n validate: oneOptionValidate,\n summarize: oneOptionSummary,\n },\n {\n type: \"multi-choice\",\n label: \"Multiple choice\",\n category: \"choice\",\n value: { json: true },\n operators: [\"contains\", \"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n literal: \"string\",\n choice: { multiple: true },\n validate: optionsValidate,\n summarize: optionsSummary,\n },\n {\n type: \"yes-no\",\n label: \"Yes / no\",\n category: \"choice\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n literal: \"boolean\",\n validate: (value) => (typeof value === \"boolean\" ? null : \"Choose yes or no.\"),\n summarize: (value) => (value ? \"Yes\" : \"No\"),\n },\n {\n type: \"dropdown\",\n label: \"Dropdown\",\n category: \"choice\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"in\", \"answered\", \"empty\"],\n a11y: { semantics: \"control\" },\n literal: \"string\",\n choice: { multiple: false },\n validate: oneOptionValidate,\n summarize: oneOptionSummary,\n },\n {\n type: \"number\",\n label: \"Number\",\n category: \"text\",\n value: { json: true },\n operators: numberOps,\n a11y: { semantics: \"control\", inputMode: \"decimal\" },\n literal: \"number\",\n checkProps: (props, check) => {\n for (const k of [\"min\", \"max\", \"step\"] as const) {\n if (props[k] !== undefined && !isFiniteNumber(props[k])) check.issue(k, \"Must be a number.\");\n }\n if (isFiniteNumber(props.step) && props.step <= 0) check.issue(\"step\", \"Must be above 0.\");\n if (isFiniteNumber(props.min) && isFiniteNumber(props.max) && props.min > props.max) {\n check.issue(\"min\", \"Can't be more than the largest number.\");\n }\n },\n validate: (value, field) => {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return \"Enter a number.\";\n const { min, max, step } = numberLimits(field);\n if (min !== undefined && max !== undefined && (value < min || value > max)) {\n return `Enter a number from ${min} to ${max}.`;\n }\n if (min !== undefined && value < min) return `Enter ${min} or more.`;\n if (max !== undefined && value > max) return `Enter ${max} or less.`;\n if (step !== undefined && !onStep(value, min ?? 0, step)) {\n return step === 1 && Number.isInteger(min ?? 0)\n ? \"Enter a whole number.\"\n : `Enter a number in steps of ${step}.`;\n }\n return null;\n },\n summarize: (value) => String(value),\n samples: (field) => {\n const { min, max } = numberLimits(field);\n return [min, max, 0, 1].filter((v): v is number => v !== undefined);\n },\n },\n {\n type: \"date\",\n label: \"Date\",\n category: \"date\",\n value: { json: true },\n operators: [\"eq\", \"neq\", \"answered\", \"empty\"],\n a11y: { semantics: \"control\" },\n literal: \"string\",\n checkProps: (props, check) => {\n for (const k of [\"min\", \"max\"] as const) {\n if (props[k] !== undefined && !(typeof props[k] === \"string\" && isIsoDate(props[k]))) {\n check.issue(k, \"Must be a date like 2026-10-22.\");\n }\n }\n if (typeof props.min === \"string\" && typeof props.max === \"string\" && isIsoDate(props.min) && isIsoDate(props.max) && props.min > props.max) {\n check.issue(\"min\", \"Can't be after the latest date.\");\n }\n },\n validate: (value, field) => {\n if (typeof value !== \"string\" || !isIsoDate(value.trim())) return \"Enter a date like 2026-10-22.\";\n const date = value.trim();\n const { min, max } = dateLimits(field);\n if (min && max && (date < min || date > max)) return `Choose a date from ${min} to ${max}.`;\n if (min && date < min) return `Choose ${min} or later.`;\n if (max && date > max) return `Choose ${max} or earlier.`;\n return null;\n },\n normalize: (value) => (typeof value === \"string\" ? value.trim() : value),\n samples: (field) => {\n const { min, max } = dateLimits(field);\n return [min ?? max ?? \"2000-01-01\"];\n },\n },\n {\n type: \"consent\",\n label: \"Consent checkbox\",\n category: \"choice\",\n value: { json: true },\n operators: [\"answered\", \"empty\"],\n a11y: { semantics: \"group\" },\n literal: \"boolean\",\n checkProps: (props, check) => check.optionalText(props.text, \"text\"),\n // Unchecked is unanswered, so a required consent must be checked.\n isEmpty: (value) => value === undefined || value === null || value === false,\n validate: (value) => (value === true ? null : \"Check the box to agree.\"),\n summarize: () => \"Agreed\",\n samples: () => [true],\n },\n];\n\n/** The optional words under the ends of a rating or NPS scale (\"Poor\", \"Great\"). */\nexport function scaleLabels(field: FieldBlock): { low?: string; high?: string } {\n const out: { low?: string; high?: string } = {};\n const low = field.props?.lowLabel;\n const high = field.props?.highLabel;\n if (typeof low === \"string\" && low.trim()) out.low = low.trim();\n if (typeof high === \"string\" && high.trim()) out.high = high.trim();\n return out;\n}\n\n/** How a rating is drawn: `\"numbers\"` (default) or `\"stars\"`. */\nexport function ratingDisplay(field: FieldBlock): \"numbers\" | \"stars\" {\n return field.props?.display === \"stars\" ? \"stars\" : \"numbers\";\n}\n\nfunction scaleEndLabel(field: FieldBlock, value: number, min: number, max: number): string | undefined {\n const { low, high } = scaleLabels(field);\n return value === min ? low : value === max ? high : undefined;\n}\n\nconst finite = (v: Json | undefined): number | undefined =>\n typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n\n/** A `number` field's limits: `min`, `max` and `step` (each optional; `step` is above 0). */\nexport function numberLimits(field: FieldBlock): { min?: number; max?: number; step?: number } {\n const out: { min?: number; max?: number; step?: number } = {};\n const min = finite(field.props?.min);\n const max = finite(field.props?.max);\n const step = finite(field.props?.step);\n if (min !== undefined) out.min = min;\n if (max !== undefined) out.max = max;\n if (step !== undefined && step > 0) out.step = step;\n return out;\n}\n\n/** Whether `value` is `base` plus a whole number of `step`s, allowing for floating-point error. */\nfunction onStep(value: number, base: number, step: number): boolean {\n const n = (value - base) / step;\n return Math.abs(n - Math.round(n)) < 1e-9 * Math.max(1, Math.abs(n));\n}\n\n/** `YYYY-MM-DD`, a real calendar day (no 2026-02-30), years 0001 to 9999. */\nexport function isIsoDate(value: string): boolean {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) return false;\n const [y, m, d] = value.split(\"-\").map(Number) as [number, number, number];\n if (y < 1 || m < 1 || m > 12 || d < 1) return false;\n const days = [31, y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n return d <= days[m - 1]!;\n}\n\n/** A `date` field's earliest and latest days (`YYYY-MM-DD`), when set. */\nexport function dateLimits(field: FieldBlock): { min?: string; max?: string } {\n const out: { min?: string; max?: string } = {};\n const min = field.props?.min;\n const max = field.props?.max;\n if (typeof min === \"string\" && isIsoDate(min)) out.min = min;\n if (typeof max === \"string\" && isIsoDate(max)) out.max = max;\n return out;\n}\n\nfor (const manifest of [...builtins, ...structuredFieldTypes, calculatedFieldType, photoFieldType]) registerBuiltIn(manifest);\n","import { isEmptyValue } from \"./fields\";\nimport type { Block, Condition, FieldBlock, FormDefinition, Json, LogicRule, Operand } from \"./types\";\n\nexport interface EvalScope {\n values: Record<string, Json | undefined>;\n hidden: Record<string, Json | undefined>;\n fields: Map<string, FieldBlock>;\n}\n\n/** `record[key]` if it is the record's own property: `values.constructor` is not an answer. */\nexport function own<T>(record: Record<string, T>, key: string): T | undefined {\n return Object.prototype.hasOwnProperty.call(record, key) ? record[key] : undefined;\n}\n\nfunction resolve(operand: Operand, scope: EvalScope): Json | undefined {\n if (\"field\" in operand) return own(scope.values, operand.field);\n if (\"hidden\" in operand) return own(scope.hidden, operand.hidden);\n return operand.value;\n}\n\nfunction deepEqual(a: Json | undefined, b: Json | undefined): boolean {\n if (a === b) return true;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));\n }\n return false;\n}\n\n/**\n * Evaluate a condition. Never throws. An empty value (unanswered, `null`,\n * blank text, an empty list: see `isEmptyValue`) is unanswered: it fails\n * every comparison, including `eq`, `in` and `contains`, and passes `neq`.\n */\nexport function evaluate(condition: Condition, scope: EvalScope): boolean {\n if (\"all\" in condition) return condition.all.every((c) => evaluate(c, scope));\n if (\"any\" in condition) return condition.any.some((c) => evaluate(c, scope));\n if (\"not\" in condition) return !evaluate(condition.not, scope);\n\n const left = resolve(condition.left, scope);\n const right = condition.right ? resolve(condition.right, scope) : undefined;\n const field = \"field\" in condition.left ? scope.fields.get(condition.left.field) : undefined;\n const unanswered = isEmptyValue(left, field);\n\n switch (condition.op) {\n case \"answered\":\n return !unanswered;\n case \"empty\":\n return unanswered;\n case \"eq\":\n return !unanswered && deepEqual(left, right);\n case \"neq\":\n // An unanswered field is \"not\" any value.\n return unanswered || !deepEqual(left, right);\n case \"lt\":\n case \"lte\":\n case \"gt\":\n case \"gte\": {\n if (typeof left !== \"number\" || typeof right !== \"number\") return false;\n if (condition.op === \"lt\") return left < right;\n if (condition.op === \"lte\") return left <= right;\n if (condition.op === \"gt\") return left > right;\n return left >= right;\n }\n case \"in\":\n return !unanswered && Array.isArray(right) && right.some((r) => deepEqual(r, left));\n case \"contains\":\n if (unanswered) return false;\n if (Array.isArray(left)) return left.some((l) => deepEqual(l, right));\n return (\n typeof left === \"string\" &&\n typeof right === \"string\" &&\n left.toLowerCase().includes(right.toLowerCase())\n );\n }\n}\n\n/** Blocks a respondent steps through: fields and content, in order. */\nexport function steps(def: FormDefinition): Block[] {\n return def.blocks.filter((b) => b.kind !== \"page-break\");\n}\n\nfunction visibilityRules(def: FormDefinition, blockId: string) {\n return (def.logic ?? []).filter(\n (r): r is Extract<LogicRule, { target: string }> =>\n (r.effect === \"show\" || r.effect === \"hide\") && r.target === blockId,\n );\n}\n\n/** Whether a field is withheld because the form is anonymous and the field identifies the respondent. */\nexport function withheld(def: FormDefinition, field: FieldBlock | undefined): boolean {\n return def.settings?.anonymous === true && field?.identifying === true;\n}\n\n/** Show/hide rules against a scope as given. A matching `hide` wins; any `show` must match. */\nfunction rulesAllow(def: FormDefinition, blockId: string, scope: EvalScope): boolean {\n if (withheld(def, scope.fields.get(blockId))) return false;\n const rules = visibilityRules(def, blockId);\n if (rules.some((r) => r.effect === \"hide\" && evaluate(r.when, scope))) return false;\n const shows = rules.filter((r) => r.effect === \"show\");\n return shows.length === 0 || shows.some((r) => evaluate(r.when, scope));\n}\n\nexport interface PathResult {\n /** Block ids the respondent will step through, given the answers on the path. */\n path: string[];\n /** The ending reached by a jump, or the default ending. */\n ending: string | null;\n}\n\nexport interface PathWalk extends PathResult {\n /**\n * The scope logic sees at a block: the values of the fields on the path\n * before it (and of the block itself, with `inclusive`), nothing else.\n */\n scopeAt(blockId: string, inclusive?: boolean): EvalScope;\n}\n\n/** One forward pass over the blocks. See `computePath`. */\nexport function walkPath(def: FormDefinition, scope: EvalScope): PathWalk {\n const list = steps(def);\n // Built only when needed: an engine walks the path on every step.\n let index: Map<string, number> | undefined;\n let position: Map<string, number> | undefined;\n const jumps = (def.logic ?? []).filter(\n (r): r is Extract<LogicRule, { effect: \"jump\" }> => r.effect === \"jump\",\n );\n const defaultEnding = def.endings?.find((e) => e.id === \"default\")?.id ?? def.endings?.[0]?.id ?? null;\n\n // Values of the fields placed on the path so far. It only grows, so every\n // decision reads blocks already placed and the pass needs no fixed point.\n const placed = Object.create(null) as Record<string, Json | undefined>;\n const local: EvalScope = { values: placed, hidden: scope.hidden, fields: scope.fields };\n const path: string[] = [];\n const nextVisible = (from: number) => {\n for (let i = from; i < list.length; i++) if (rulesAllow(def, list[i]!.id, local)) return i;\n return list.length;\n };\n\n let ending = defaultEnding;\n let i = nextVisible(0);\n while (i < list.length) {\n const block = list[i]!;\n path.push(block.id);\n if (block.kind === \"field\") placed[block.id] = own(scope.values, block.id);\n const jump = jumps.find((r) => r.from === block.id && evaluate(r.when, local));\n if (jump) {\n if (typeof jump.to === \"object\") {\n ending = jump.to.ending;\n break;\n }\n index ??= new Map(list.map((b, at) => [b.id, at]));\n const target = index.get(jump.to);\n if (target !== undefined && target > i) {\n i = nextVisible(target);\n continue;\n }\n }\n i = nextVisible(i + 1);\n }\n\n const scopeAt = (blockId: string, inclusive = false): EvalScope => {\n position ??= new Map(def.blocks.map((b, i) => [b.id, i]));\n const at = position.get(blockId) ?? -1;\n const values = Object.create(null) as Record<string, Json | undefined>;\n for (const id of path) {\n const p = position!.get(id)!;\n if (p > at || (p === at && !inclusive)) break;\n if (id in placed) values[id] = placed[id];\n }\n return { values, hidden: scope.hidden, fields: scope.fields };\n };\n return { path, ending, scopeAt };\n}\n\n/**\n * The respondent's path, derived from the answers on the path, so the client,\n * the server and a replay always agree. It is built in one forward pass: a\n * block's show/hide rules, and the jumps from it, see only the fields already\n * on the path before it (and, for a jump, the block itself). A field that is\n * hidden, jumped over or later in the form reads as unanswered, whatever\n * value it holds.\n *\n * A block jumped over is off the path and counts as hidden: it is not\n * validated and its value is cleared on submit. A jump never revisits a block;\n * a jump to an earlier block is ignored (the checker in `parseForm` reports it).\n */\nexport function computePath(def: FormDefinition, scope: EvalScope): PathResult {\n const { path, ending } = walkPath(def, scope);\n return { path, ending };\n}\n\n/**\n * Whether a block's show/hide rules let it be shown, ignoring jumps. The rules\n * read the answers on the path before the block, as in `computePath`. A block\n * with any `show` rule is hidden until one matches; a matching `hide` rule\n * always wins.\n */\nexport function ruleVisible(def: FormDefinition, blockId: string, scope: EvalScope): boolean {\n return rulesAllow(def, blockId, walkPath(def, scope).scopeAt(blockId));\n}\n\nexport function fieldMap(def: FormDefinition): Map<string, FieldBlock> {\n const map = new Map<string, FieldBlock>();\n for (const block of def.blocks) if (block.kind === \"field\") map.set(block.id, block);\n return map;\n}\n","import { summarizeValue } from \"./fields\";\nimport { own } from \"./logic\";\nimport type { FieldBlock, Json } from \"./types\";\n\nconst TOKEN = /\\{\\{\\s*(field|hidden):([A-Za-z0-9_-]+)\\s*(?:\\|([^}]*))?\\}\\}/g;\n\nexport interface RecallScope {\n /** Fields by key. */\n fieldsByKey: Map<string, FieldBlock>;\n values: Record<string, Json | undefined>;\n hidden: Record<string, Json | undefined>;\n}\n\n/**\n * Replace `{{field:key|fallback}}` and `{{hidden:name|fallback}}` tokens.\n * An unanswered value renders its fallback (default empty); the text is\n * never dropped.\n */\nexport function recall(text: string, scope: RecallScope): string {\n return text.replace(TOKEN, (_match, kind: string, name: string, fallback?: string) => {\n if (kind === \"field\") {\n const field = scope.fieldsByKey.get(name);\n const out = field ? summarizeValue(own(scope.values, field.id), field) : \"\";\n return out || (fallback ?? \"\").trim();\n }\n const value = own(scope.hidden, name);\n const out = value === undefined || value === null ? \"\" : String(value);\n return out || (fallback ?? \"\").trim();\n });\n}\n\n/** The keys a text recalls, for the checker. */\nexport function recallRefs(text: string): { kind: \"field\" | \"hidden\"; name: string }[] {\n return [...text.matchAll(TOKEN)].map((m) => ({ kind: m[1] as \"field\" | \"hidden\", name: m[2]! }));\n}\n","/**\n * One response as a flat row: the shape the sheet appends, the email lists\n * and the webhook sends alongside the raw answers.\n */\nimport { getFieldType, isEmptyValue, isSensitive, summarizeValue } from \"../fields\";\nimport { own, withheld } from \"../logic\";\nimport { recall } from \"../recall\";\nimport type { FieldBlock, FormDefinition, Json } from \"../types\";\nimport type { Cell, DeliverySubmission } from \"./types\";\n\nexport interface RowOptions {\n /**\n * Fields marked `sensitive`: `\"include\"` their values (default), `\"mask\"`\n * them as `[sensitive]`, or `\"omit\"` their columns.\n */\n sensitive?: \"include\" | \"mask\" | \"omit\" | undefined;\n}\n\nexport interface ResponseRow {\n /** Cells by column key. */\n row: Record<string, Cell>;\n /** The column keys in order: `id`, `submitted_at`, the meta keys, then one per field key. */\n columns: string[];\n /** Field labels by key, recall filled in from this submission. */\n labels: Record<string, string>;\n}\n\nexport const SENSITIVE_MASK = \"[sensitive]\";\n\n// Never used as column keys, so a hostile meta key cannot touch a prototype.\nconst RESERVED = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n/**\n * One answer as a cell: numbers stay numbers (ratings, NPS), choices show\n * their labels, a list is joined with \", \", yes/no reads \"Yes\"/\"No\", and a\n * plugin type's `summarize` is used where it has one.\n */\nexport function answerCell(field: FieldBlock, value: Json | undefined): Cell {\n if (value === undefined || isEmptyValue(value, field)) return \"\";\n if (typeof value === \"number\") return value;\n const manifest = getFieldType(field.type);\n if (manifest?.summarize) return summarizeValue(value, field);\n if (typeof value === \"string\") return value;\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n if (Array.isArray(value) && value.every((v) => typeof v !== \"object\" || v === null)) {\n return value.map((v) => String(v)).join(\", \");\n }\n return JSON.stringify(value);\n}\n\n/**\n * The row for one submission. Columns: `id` (the response id), then\n * `submitted_at` when given, then the app's `meta` columns in order, then\n * one per field key in form order (blank when unanswered or hidden by\n * logic). Content blocks get no column. On an anonymous form, identifying\n * fields get no column at all, whatever the answers hold.\n */\nexport function responseRow(\n submission: DeliverySubmission,\n definition: FormDefinition,\n options: RowOptions = {},\n): ResponseRow {\n const row: Record<string, Cell> = {};\n const columns: string[] = [];\n const set = (key: string, value: Cell) => {\n if (RESERVED.has(key)) return;\n if (!Object.prototype.hasOwnProperty.call(row, key)) columns.push(key);\n row[key] = value;\n };\n set(\"id\", submission.id);\n if (submission.submittedAt !== undefined) set(\"submitted_at\", submission.submittedAt);\n for (const [key, value] of Object.entries(submission.meta ?? {})) {\n if (key !== \"id\" && key !== \"submitted_at\") set(key, value);\n }\n\n const fields = definition.blocks.filter((b): b is FieldBlock => b.kind === \"field\");\n const fieldsByKey = new Map(fields.map((f) => [f.key, f]));\n const sensitive = options.sensitive ?? \"include\";\n // Recall in a label must not leak what the row itself withholds or masks.\n const values: Record<string, Json> = {};\n for (const field of fields) {\n const value = own(submission.answers, field.id);\n if (value === undefined || withheld(definition, field)) continue;\n if (isSensitive(field) && sensitive !== \"include\") continue;\n values[field.id] = value;\n }\n const scope = { fieldsByKey, values, hidden: visibleInputs(submission, definition, sensitive) };\n const labels: Record<string, string> = {};\n for (const field of fields) {\n if (withheld(definition, field)) continue;\n if (isSensitive(field) && sensitive === \"omit\") continue;\n if (RESERVED.has(field.key)) continue;\n labels[field.key] = recall(field.label, scope).trim() || field.key;\n const cell = answerCell(field, own(submission.answers, field.id));\n set(field.key, isSensitive(field) && sensitive === \"mask\" && cell !== \"\" ? SENSITIVE_MASK : cell);\n }\n return { row, columns, labels };\n}\n\n/**\n * Hidden and server inputs as recall and the webhook may show them: on an\n * anonymous form identifying ones are left out, and sensitive ones are left\n * out unless `sensitive` is `\"include\"`.\n */\nexport function visibleInputs(\n submission: DeliverySubmission,\n definition: FormDefinition,\n sensitive: RowOptions[\"sensitive\"] = \"include\",\n): Record<string, Json> {\n const declared = new Map((definition.hidden ?? []).map((h) => [h.name, h]));\n const out: Record<string, Json> = {};\n for (const [name, value] of Object.entries({ ...submission.hidden, ...submission.context })) {\n const input = declared.get(name);\n if (RESERVED.has(name)) continue;\n if (input?.identifying && definition.settings?.anonymous === true) continue;\n if (input?.sensitive && sensitive !== \"include\") continue;\n out[name] = value;\n }\n return out;\n}\n\n/**\n * A cell that a spreadsheet will never run as a formula when the text is\n * opened elsewhere (a CSV export opened in Excel). Opt-in: use it when\n * writing CSV, not for the sheet destination, whose RAW writes are already\n * safe and would store the `'` literally. Text starting with `=`,\n * `@`, a tab or a carriage return gets a leading `'`, as OWASP recommends;\n * so does text starting with `+` or `-` unless it is only digits and\n * number punctuation (a phone number such as `+1 (555) 010-0000`, `-2.5`),\n * which cannot call a function or name a cell. Numbers and booleans are\n * returned as they are.\n */\nexport function escapeFormula(cell: Cell): Cell {\n if (typeof cell !== \"string\" || cell === \"\") return cell;\n const first = cell[0]!;\n if (first === \"=\" || first === \"@\" || first === \"\\t\" || first === \"\\r\") return `'${cell}`;\n if ((first === \"+\" || first === \"-\") && !/^[+-][\\d\\s().,+-]*$/.test(cell)) return `'${cell}`;\n return cell;\n}\n","/**\n * The email destination: one notification per submission, through any\n * provider that implements `EmailProvider`. `resendProvider` is built in.\n *\n * The body is built from the definition: each answered field's label (recall\n * filled in) and its value, in form order, after the app's meta columns.\n * Every value is HTML-escaped. Subjects and addresses are stripped of line\n * breaks and checked, so an answer can never add a header. Sensitive fields\n * are masked unless `sensitive: \"include\"` is set: an inbox is not a vault.\n */\nimport { isEmailAddress } from \"../fields\";\nimport { own } from \"../logic\";\nimport type { FormDefinition } from \"../types\";\nimport { responseRow, type ResponseRow, type RowOptions } from \"./row\";\nimport {\n configString,\n deliveryFailure,\n DeliveryError,\n discard,\n httpError,\n\n sha256Hex,\n timedFetch,\n type Cell,\n type DeliveryOptions,\n type DeliveryResult,\n type DeliverySubmission,\n type Destination,\n type DestinationConfig,\n type HttpDeps,\n} from \"./types\";\n\n/** One message, ready to send. Addresses are already checked. */\nexport interface EmailMessage {\n from: string;\n to: string[];\n replyTo?: string | undefined;\n subject: string;\n text: string;\n html: string;\n /** Stable across retries of one delivery: a provider that supports it sends once. */\n idempotencyKey: string;\n}\n\n/** Sends one message. Throws a `DeliveryError` (or any error) on failure. */\nexport interface EmailProvider {\n readonly name: string;\n send(message: EmailMessage, options: { signal?: AbortSignal | undefined }): Promise<void>;\n}\n\nexport interface EmailContent {\n subject: string;\n text: string;\n html: string;\n}\n\nexport interface EmailRenderInput {\n submission: DeliverySubmission;\n definition: FormDefinition;\n config: DestinationConfig;\n /** The submission as a row (sensitive values masked unless `sensitive: \"include\"`). */\n row: ResponseRow;\n}\n\n/** What the email destination reads from a destination's config. */\nexport interface EmailConfig {\n /** One address or a list (at most 50). */\n to: string | string[];\n /** Overrides the default subject (still stripped of line breaks). */\n subject?: string;\n}\n\nexport interface EmailDestinationOptions {\n provider: EmailProvider;\n /** `\"Feedback <feedback@send.example.com>\"` or a bare address. */\n from: string;\n /**\n * The Reply-To address: the key of an email field whose answer is used, or\n * a function returning an address (or null for none). Only a valid single\n * address is ever used.\n */\n replyTo?: string | ((input: EmailRenderInput) => string | null | undefined) | undefined;\n /** Builds the subject and bodies. Defaults to `renderEmail`. The subject is sanitized afterwards either way. */\n render?: ((input: EmailRenderInput) => EmailContent) | undefined;\n /** Sensitive fields: `\"mask\"` (default), `\"omit\"` or `\"include\"`. */\n sensitive?: RowOptions[\"sensitive\"];\n}\n\n/** Resend allows 50 recipients per email. */\nexport const MAX_RECIPIENTS = 50;\nconst MAX_SUBJECT_LENGTH = 200;\n\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/**\n * A header value on one line: control characters (CR, LF, NUL…) and Unicode\n * line separators become spaces, runs of spaces collapse, and it is cut to\n * `max` characters.\n */\nexport function headerSafe(text: string, max = MAX_SUBJECT_LENGTH): string {\n // eslint-disable-next-line no-control-regex\n const flat = text.replace(/[\\u0000-\\u001f\\u007f\\u2028\\u2029]+/g, \" \").replace(/\\s+/g, \" \").trim();\n return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;\n}\n\n/** A bare address that is safe as a header value: valid, one line, no display name. */\nexport function isSafeAddress(value: unknown): value is string {\n return typeof value === \"string\" && isEmailAddress(value) && !/[\\u0000-\\u001f\\u007f<>,;:\"()[\\]\\\\]/.test(value);\n}\n\n/**\n * A From value: a bare address, or `Name <address>` where the name has no\n * quotes, angle brackets or line breaks.\n */\nexport function isSafeFrom(value: string): boolean {\n const named = /^([^\"<>\\u0000-\\u001f\\u007f]{1,100}) <([^<>]+)>$/.exec(value);\n return named ? isSafeAddress(named[2]) : isSafeAddress(value);\n}\n\n/** Plain text and HTML bodies from label/value lines, every value escaped. */\nexport function emailBody(lines: readonly (readonly [string, Cell])[], footer?: string): { text: string; html: string } {\n const text = lines.map(([k, v]) => `${k}: ${v}`).join(\"\\n\") + (footer ? `\\n\\n${footer}` : \"\");\n // Paragraphs rather than a table: email clients render them alike everywhere.\n const font = \"font-family:sans-serif;font-size:14px;margin:0 0 12px\";\n const html =\n lines\n .map(\n ([k, v]) =>\n `<p style=\"${font}\"><span style=\"color:#666\">${escapeHtml(k)}</span><br>` +\n `<span style=\"white-space:pre-wrap\">${escapeHtml(String(v))}</span></p>`,\n )\n .join(\"\") +\n (footer ? `<p style=\"font-family:sans-serif;font-size:12px;color:#666\">${escapeHtml(footer)}</p>` : \"\");\n return { text, html };\n}\n\n/**\n * The default notification: subject `\"<form title>: new response\"` (or\n * `config.subject`), then the meta columns, each answered field by label,\n * the ending's title when the form has several, and the response id.\n */\nexport function renderEmail(input: EmailRenderInput): EmailContent {\n const { submission, definition, config, row } = input;\n const lines: [string, Cell][] = [];\n const fieldKeys = new Set(Object.keys(row.labels));\n for (const key of row.columns) {\n if (key === \"id\") continue;\n const value = row.row[key];\n if (value === undefined || value === \"\") continue;\n const label = fieldKeys.has(key) ? row.labels[key]! : key === \"submitted_at\" ? \"Submitted\" : key;\n lines.push([label, value]);\n }\n const endings = definition.endings ?? [];\n if (submission.ending && endings.length > 1) {\n const ending = endings.find((e) => e.id === submission.ending);\n if (ending) lines.push([\"Ending\", ending.title]);\n }\n if (!lines.length) lines.push([\"Answers\", \"(none)\"]);\n const subject = configString(config, \"subject\") || `${definition.title || definition.id}: new response`;\n return { subject, ...emailBody(lines, `Response ${submission.id}`) };\n}\n\n/** Recipients from config: a string or a list, each checked. Throws when there are none or too many. */\nfunction recipients(config: DestinationConfig): string[] {\n const raw = config[\"to\"];\n const list = (Array.isArray(raw) ? raw : typeof raw === \"string\" ? raw.split(\",\") : []).map((t) =>\n typeof t === \"string\" ? t.trim() : t,\n );\n const to = [...new Set(list.filter(isSafeAddress))];\n if (to.length !== list.filter((t) => t !== \"\").length) {\n throw new DeliveryError(\"The email destination has an invalid recipient\");\n }\n if (!to.length) throw new DeliveryError(\"The email destination has no recipients\");\n if (to.length > MAX_RECIPIENTS) throw new DeliveryError(`The email destination has more than ${MAX_RECIPIENTS} recipients`);\n return to;\n}\n\nfunction replyToAddress(option: EmailDestinationOptions[\"replyTo\"], input: EmailRenderInput): string | undefined {\n if (!option) return undefined;\n let value: unknown;\n if (typeof option === \"function\") value = option(input);\n else {\n const field = input.definition.blocks.find((b) => b.kind === \"field\" && b.key === option);\n value = field ? own(input.submission.answers, field.id) : undefined;\n // An anonymous form never gives away an identifying answer, not even as Reply-To.\n if (field?.kind === \"field\" && field.identifying && input.definition.settings?.anonymous) value = undefined;\n }\n const trimmed = typeof value === \"string\" ? value.trim() : value;\n return isSafeAddress(trimmed) ? trimmed : undefined;\n}\n\n/**\n * The idempotency key: the delivery id and the first 16 hex digits of\n * SHA-256 of the sorted recipients, so a retried delivery never sends twice\n * and one whose recipients changed meanwhile is a new send.\n */\nexport async function idempotencyKey(deliveryId: string, to: readonly string[]): Promise<string> {\n const hex = await sha256Hex([...to].sort().join(\",\"));\n return `${deliveryId.slice(0, 200)}:${hex.slice(0, 16)}`;\n}\n\nexport function emailDestination(options: EmailDestinationOptions): Destination {\n return {\n kind: \"email\",\n async deliver(submission, definition, config, deliveryOptions: DeliveryOptions = {}): Promise<DeliveryResult> {\n try {\n if (!isSafeFrom(options.from)) throw new DeliveryError(\"The email destination's from address is invalid\");\n const to = recipients(config);\n const row = responseRow(submission, definition, { sensitive: options.sensitive ?? \"mask\" });\n const input: EmailRenderInput = { submission, definition, config, row };\n const content = (options.render ?? renderEmail)(input);\n const replyTo = replyToAddress(options.replyTo, input);\n await options.provider.send(\n {\n from: options.from,\n to,\n ...(replyTo ? { replyTo } : {}),\n subject: headerSafe(content.subject) || \"New response\",\n text: content.text,\n html: content.html,\n idempotencyKey: await idempotencyKey(deliveryOptions.deliveryId ?? submission.id, to),\n },\n { signal: deliveryOptions.signal },\n );\n return { ok: true };\n } catch (error) {\n return deliveryFailure(error);\n }\n },\n };\n}\n\nexport const RESEND_API = \"https://api.resend.com/emails\";\n\nexport interface ResendOptions extends HttpDeps {\n apiKey: string;\n /** Default `RESEND_API`. */\n endpoint?: string | undefined;\n}\n\n/**\n * Resend's REST API. Sends the idempotency key, so a retry within Resend's\n * 24-hour window never sends twice. A 409 for a concurrent request with the\n * same key is retried; one for a key reused with a different body is not.\n */\nexport function resendProvider(options: ResendOptions): EmailProvider {\n return {\n name: \"resend\",\n async send(message, { signal }) {\n if (!options.apiKey) throw new DeliveryError(\"The Resend API key is not set\");\n const response = await timedFetch(\n options,\n options.endpoint ?? RESEND_API,\n {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${options.apiKey}`,\n \"content-type\": \"application/json\",\n \"idempotency-key\": message.idempotencyKey,\n },\n body: JSON.stringify({\n from: message.from,\n to: message.to,\n subject: message.subject,\n text: message.text,\n html: message.html,\n ...(message.replyTo ? { reply_to: message.replyTo } : {}),\n }),\n },\n signal,\n );\n if (response.ok) {\n discard(response);\n return;\n }\n // Resend's error `name` (such as \"validation_error\") is safe to keep; its message may echo input.\n let name: string | undefined;\n try {\n const body = (await response.json()) as { name?: unknown };\n if (typeof body.name === \"string\" && /^[a-z_]{1,64}$/.test(body.name)) name = body.name;\n } catch {\n // Not JSON.\n }\n if (response.status === 409 && name === \"concurrent_idempotent_requests\") {\n throw new DeliveryError(\"Resend answered 409 (concurrent_idempotent_requests)\", {\n retryable: true,\n retryAfterSeconds: 5,\n status: 409,\n });\n }\n throw httpError(\"Resend\", response, name);\n },\n };\n}\n","/**\n * An access token for a Google service account by the OAuth 2.0 JWT bearer\n * flow: sign a JWT with the account's private key (RS256, WebCrypto) and\n * trade it at Google's token endpoint. No googleapis dependency, so it runs\n * on Node 20+, edge runtimes and Workers alike.\n */\nimport {\n base64url,\n DeliveryError,\n discard,\n fromBase64,\n httpError,\n sha256Hex,\n timedFetch,\n type HttpDeps,\n type WebCryptoKey,\n} from \"./types\";\n\nexport const GOOGLE_TOKEN_URL = \"https://oauth2.googleapis.com/token\";\nexport const SHEETS_SCOPE = \"https://www.googleapis.com/auth/spreadsheets\";\n\nexport interface GoogleServiceAccount {\n /** The service account's `client_email`. */\n clientEmail: string;\n /** Its `private_key`: a PKCS#8 PEM. The `\\n`-escaped form env vars often hold is accepted. */\n privateKey: string;\n}\n\n/** The PKCS#8 key bytes from a PEM. */\nfunction pemToPkcs8(pem: string): Uint8Array<ArrayBuffer> {\n const text = pem.replace(/\\\\n/g, \"\\n\");\n if (/-----BEGIN RSA PRIVATE KEY-----/.test(text)) {\n throw new DeliveryError(\"The Google private key is PKCS#1; convert it to PKCS#8 (BEGIN PRIVATE KEY)\");\n }\n const body = text.replace(/-----(BEGIN|END) PRIVATE KEY-----/g, \"\").replace(/\\s+/g, \"\");\n return fromBase64(body);\n}\n\n/** A signed RS256 JWT. Throws a `DeliveryError` when the key is not a valid PKCS#8 RSA key. */\nexport async function signJwt(claims: Record<string, unknown>, privateKeyPem: string): Promise<string> {\n let key: WebCryptoKey;\n try {\n key = await crypto.subtle.importKey(\n \"pkcs8\",\n pemToPkcs8(privateKeyPem),\n { name: \"RSASSA-PKCS1-v1_5\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n );\n } catch (error) {\n if (error instanceof DeliveryError) throw error;\n // Never the key or the platform's message, which may quote it.\n throw new DeliveryError(\"The Google private key is not a valid PKCS#8 RSA key\");\n }\n const unsigned = `${base64url(JSON.stringify({ alg: \"RS256\", typ: \"JWT\" }))}.${base64url(JSON.stringify(claims))}`;\n const signature = await crypto.subtle.sign(\"RSASSA-PKCS1-v1_5\", key, new TextEncoder().encode(unsigned));\n return `${unsigned}.${base64url(new Uint8Array(signature))}`;\n}\n\n// One per process, shared by every destination: a token is good for an hour.\nconst cache = new Map<string, { token: string; expiresAt: number }>();\n\n/** Forgets cached tokens (tests, or after rotating a key). */\nexport function clearGoogleTokenCache(): void {\n cache.clear();\n}\n\nexport interface GoogleTokenOptions extends HttpDeps {\n scope?: string | undefined;\n now?: (() => number) | undefined;\n signal?: AbortSignal | undefined;\n}\n\n/** A cached or fresh access token. Throws a `DeliveryError` with a safe message on failure. */\nexport async function googleAccessToken(account: GoogleServiceAccount, options: GoogleTokenOptions = {}): Promise<string> {\n const { clientEmail, privateKey } = account;\n if (!clientEmail || !privateKey) throw new DeliveryError(\"The Google service account email or private key is not set\");\n const scope = options.scope ?? SHEETS_SCOPE;\n const now = options.now?.() ?? Date.now();\n // The key's digest is part of the cache key: a hit returns a token without\n // signing anything, so email + scope alone would hand one tenant's live\n // token to any config naming that email with any key, and keep a rotated\n // or wrong key working until the token expires.\n const cacheKey = `${clientEmail} ${scope} ${await sha256Hex(privateKey.replace(/\\\\n/g, \"\\n\").trim())}`;\n const hit = cache.get(cacheKey);\n if (hit && hit.expiresAt - 60_000 > now) return hit.token;\n\n const iat = Math.floor(now / 1000);\n const assertion = await signJwt({ iss: clientEmail, scope, aud: GOOGLE_TOKEN_URL, iat, exp: iat + 3600 }, privateKey);\n const response = await timedFetch(\n options,\n GOOGLE_TOKEN_URL,\n {\n method: \"POST\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({ grant_type: \"urn:ietf:params:oauth:grant-type:jwt-bearer\", assertion }).toString(),\n },\n options.signal,\n );\n if (!response.ok) {\n discard(response);\n throw httpError(\"Google token endpoint\", response);\n }\n const body = (await response.json()) as { access_token?: unknown; expires_in?: unknown };\n if (typeof body.access_token !== \"string\") throw new DeliveryError(\"Google token endpoint returned no access token\", { retryable: true });\n const ttl = typeof body.expires_in === \"number\" ? body.expires_in * 1000 : 3_600_000;\n cache.set(cacheKey, { token: body.access_token, expiresAt: now + ttl });\n return body.access_token;\n}\n","/**\n * The Google Sheets destination: appends one row per submission to a sheet\n * shared with a Google service account, or reached with an access token the\n * app supplies (a sheet a person connected with Google sign-in). Config:\n * `{ spreadsheetId, sheetName? }` (`spreadsheet_id` and `sheet_name` are\n * accepted too). An update (the delivery of an edit) overwrites the\n * response's row where it is, and is appended only when that row is gone.\n *\n * The tab is created when missing, the header row is written from the row's\n * column keys and gains a column for any new key without moving the others,\n * and an `id` column holds the response id, so a redelivery is not appended\n * twice. Every write is `valueInputOption=RAW`, so Sheets stores text as\n * typed and never runs it as a formula: `@team thanks` stays exactly that.\n * Text is therefore not escaped by default (a `'` would be stored literally).\n * Set `escapeFormulas` only when the sheet's text is exported and opened in\n * another spreadsheet that might run it (see `escapeFormula`).\n *\n * Quota: Google allows a service account about 60 reads and 60 writes a\n * minute. So the tab id, header and last row are kept in the destination's\n * state, and a normal delivery is one write: the append. The tab and header\n * are read again only when a row has a key the cached header lacks, or when\n * an append is refused. The id column is read only on a redelivery, and then\n * only its recent rows. `deliverBatch` appends many rows in one request.\n */\nimport type { Json } from \"../types\";\nimport { googleAccessToken, type GoogleServiceAccount } from \"./google-auth\";\nimport { escapeFormula, responseRow, type RowOptions } from \"./row\";\nimport {\n configString,\n deliveryFailure,\n DeliveryError,\n discard,\n httpError,\n resolveOption,\n timedFetch,\n type Cell,\n type DeliveryItem,\n type DeliveryOptions,\n type DeliveryResult,\n type Destination,\n type DestinationConfig,\n type HttpDeps,\n type OptionResolver,\n} from \"./types\";\n\nexport const SHEETS_API = \"https://sheets.googleapis.com/v4/spreadsheets\";\nexport const DEFAULT_SHEET_NAME = \"Responses\";\n/** How many of the latest rows a redelivery checks for its id. */\nexport const DEDUPE_WINDOW = 500;\n/**\n * How many rows the header read looks at to find the columns in use: the\n * header row and the first responses under it. Bounded, so a tab with years\n * of responses is never read whole just to learn its header.\n */\nexport const HEADER_SCAN_ROWS = 100;\n/** Header writes tried before a concurrent writer is reported as a retryable failure. */\nconst HEADER_WRITE_ATTEMPTS = 3;\n\n/** What the sheet destination reads from a destination's config. */\nexport interface SheetConfig {\n spreadsheetId: string;\n /** Default `\"Responses\"`. */\n sheetName?: string;\n}\n\nexport interface SheetsDestinationOptions extends HttpDeps {\n /**\n * The service account the sheet is shared with, or a function that finds\n * the one for a destination's config. Give this or `accessToken`.\n */\n account?: GoogleServiceAccount | OptionResolver<GoogleServiceAccount> | undefined;\n /**\n * An access token for the sheet instead of a service account: a sheet a\n * person connected with Google sign-in, say (see `googleOAuthAccessToken`).\n * Gets the config and `{ destinationId }`; called once per delivery or\n * batch, so cache inside it.\n */\n accessToken?: OptionResolver<string> | undefined;\n /**\n * Prefix text a spreadsheet could run as a formula with `'` (see\n * `escapeFormula`), headers included. Default false: writes are RAW, so\n * Sheets never runs text as a formula, and the `'` would be stored as part\n * of the text. Turn it on only if the sheet is exported as CSV and opened\n * in another spreadsheet. Keep one setting per sheet: header keys are\n * escaped too, so switching it later adds new columns for escaped keys.\n */\n escapeFormulas?: boolean | undefined;\n /** Sensitive fields: `\"include\"` (default), `\"mask\"` or `\"omit\"`. */\n sensitive?: RowOptions[\"sensitive\"];\n now?: (() => number) | undefined;\n}\n\n/**\n * The existing header plus any keys it does not have yet, in the order they\n * arrive. A blank header cell keeps its place (dropping it would shift every\n * later column away from the values stored under it), as do blank header\n * cells over the `width` columns that hold responses; only blanks beyond\n * those are trimmed.\n */\nexport function mergeHeader(existing: readonly unknown[], keys: readonly string[], width = 0): string[] {\n const header = existing.map((h) => (h == null ? \"\" : String(h)));\n while (header.length < width) header.push(\"\");\n while (header.length > width && header[header.length - 1] === \"\") header.pop();\n for (const key of keys) if (key && !header.includes(key)) header.push(key);\n return header;\n}\n\n/** One cell per header column, blank where the row has no value; `escape` applies `escapeFormula` (default false). */\nexport function rowFor(header: readonly string[], row: Record<string, Cell>, escape = false): Cell[] {\n return header.map((h) => {\n const cell = Object.prototype.hasOwnProperty.call(row, h) ? (row[h] ?? \"\") : \"\";\n return escape ? escapeFormula(cell) : cell;\n });\n}\n\n/** A1 column letters: 0 → A, 25 → Z, 26 → AA. */\nexport function columnLetter(index: number): string {\n let n = index + 1;\n let s = \"\";\n while (n > 0) {\n const r = (n - 1) % 26;\n s = String.fromCharCode(65 + r) + s;\n n = Math.floor((n - 1) / 26);\n }\n return s;\n}\n\nconst quoteSheet = (name: string) => `'${name.replace(/'/g, \"''\")}'`;\n\n/** What the destination keeps between deliveries. Opaque to the app: store and pass it back. */\nexport interface SheetState {\n spreadsheet_id: string;\n sheet_name: string;\n sheet_id: number;\n header: string[];\n columns: number;\n /** The last row an append wrote (1-based), 0 when unknown. */\n last_row: number;\n}\n\nfunction readState(raw: Record<string, Json> | undefined, spreadsheetId: string, sheetName: string): SheetState | null {\n if (!raw) return null;\n const header = raw[\"header\"];\n if (\n raw[\"spreadsheet_id\"] !== spreadsheetId ||\n raw[\"sheet_name\"] !== sheetName ||\n typeof raw[\"sheet_id\"] !== \"number\" ||\n !Array.isArray(header) ||\n !header.every((h) => typeof h === \"string\") ||\n !header.includes(\"id\")\n ) {\n return null;\n }\n return {\n spreadsheet_id: spreadsheetId,\n sheet_name: sheetName,\n sheet_id: raw[\"sheet_id\"],\n header: header as string[],\n columns: typeof raw[\"columns\"] === \"number\" ? raw[\"columns\"] : header.length,\n last_row: typeof raw[\"last_row\"] === \"number\" ? raw[\"last_row\"] : 0,\n };\n}\n\n/** An append Google refused for a reason a fresh look at the tab may fix (renamed, deleted or resized). */\nclass StaleSheetError extends DeliveryError {}\n\ninterface SheetProps {\n sheetId: number;\n title: string;\n gridProperties?: { columnCount?: number };\n}\n\nfunction configOf(config: DestinationConfig) {\n const spreadsheetId = configString(config, \"spreadsheetId\", \"spreadsheet_id\");\n if (!spreadsheetId) throw new DeliveryError(\"The sheet destination has no spreadsheetId\");\n if (!/^[A-Za-z0-9_-]{10,200}$/.test(spreadsheetId)) throw new DeliveryError(\"The sheet destination's spreadsheetId is invalid\");\n const sheetName = configString(config, \"sheetName\", \"sheet_name\") || DEFAULT_SHEET_NAME;\n if (sheetName.length > 100) throw new DeliveryError(\"The sheet destination's sheetName is too long\");\n return { spreadsheetId, sheetName };\n}\n\nexport function sheetsDestination(options: SheetsDestinationOptions): Destination {\n async function run(\n items: readonly DeliveryItem[],\n config: DestinationConfig,\n deliveryOptions: Omit<DeliveryOptions, \"deliveryId\">,\n ): Promise<DeliveryResult> {\n if (!items.length) return { ok: true };\n const { spreadsheetId, sheetName } = configOf(config);\n const signal = deliveryOptions.signal;\n const context = { destinationId: deliveryOptions.destinationId };\n let account: GoogleServiceAccount | null = null;\n let token: string;\n if (options.accessToken) {\n token = await resolveOption(\"The sheet destination's access token\", options.accessToken, config, context);\n if (typeof token !== \"string\" || !token) throw new DeliveryError(\"The sheet destination has no access token\");\n } else if (options.account) {\n account = await resolveOption(\"The sheet destination's account\", options.account, config, context);\n token = await googleAccessToken(account, { ...options, signal });\n } else {\n throw new DeliveryError(\"The sheet destination has neither an account nor an access token\");\n }\n const sharedWith = account\n ? `is the sheet shared with ${account.clientEmail}?`\n : \"is the sheet still connected to its Google account?\";\n const base = `${SHEETS_API}/${encodeURIComponent(spreadsheetId)}`;\n const escape = options.escapeFormulas === true;\n\n const call = async <T>(what: string, url: string, init: RequestInit = {}): Promise<T> => {\n const response = await timedFetch(\n options,\n url,\n { ...init, headers: { authorization: `Bearer ${token}`, \"content-type\": \"application/json\" } },\n signal,\n );\n if (!response.ok) {\n discard(response);\n if ((what === \"append\" || what === \"update rows\") && (response.status === 400 || response.status === 404)) {\n throw new StaleSheetError(`Google Sheets append answered ${response.status}`, { status: response.status });\n }\n if (response.status === 403 || response.status === 404) {\n throw new DeliveryError(\n `Google Sheets ${what} answered ${response.status}: ${sharedWith}`,\n { status: response.status },\n );\n }\n throw httpError(`Google Sheets ${what}`, response);\n }\n return (await response.json()) as T;\n };\n const batchUpdate = (what: string, requests: unknown[]) =>\n call<{ replies?: { addSheet?: { properties?: SheetProps } }[] }>(what, `${base}:batchUpdate`, {\n method: \"POST\",\n body: JSON.stringify({ requests }),\n });\n const range = (a1: string) => `${base}/values/${encodeURIComponent(`${quoteSheet(sheetName)}!${a1}`)}`;\n\n const sensitive = options.sensitive ?? \"include\";\n // Column keys are escaped like cells (a builder-made key could start with \"=\"),\n // so the header as stored and read back matches the keys looked up in it.\n const columnKey = (key: string) => (escape ? String(escapeFormula(key)) : key);\n const rows = items.map((item) => {\n const { row, columns } = responseRow(item.submission, item.definition, { sensitive });\n const escaped: Record<string, Cell> = {};\n for (const key of columns) escaped[columnKey(key)] = row[key]!;\n return { row: escaped, columns: columns.map(columnKey) };\n });\n const keys = [...new Set(rows.flatMap((r) => r.columns))];\n\n /** Reads the tab and header, adds what is missing, and returns the fresh state. */\n async function setUp(previous: SheetState | null): Promise<SheetState> {\n const readTabs = async () => {\n const meta = await call<{ sheets?: { properties?: SheetProps }[] }>(\n \"read\",\n `${base}?fields=${encodeURIComponent(\"sheets.properties(sheetId,title,gridProperties.columnCount)\")}`,\n );\n return meta.sheets?.map((s) => s.properties).find((p) => p?.title === sheetName);\n };\n let sheet = await readTabs();\n if (!sheet) {\n try {\n const added = await batchUpdate(\"add tab\", [{ addSheet: { properties: { title: sheetName } } }]);\n sheet = added.replies?.[0]?.addSheet?.properties ?? { sheetId: 0, title: sheetName };\n } catch (error) {\n // Two first deliveries race: both saw no tab, and the loser's\n // addSheet answers 400 (\"already exists\"). Use the winner's tab.\n if (!(error instanceof DeliveryError) || error.status !== 400) throw error;\n sheet = await readTabs();\n if (!sheet) throw error;\n }\n }\n // Read by column: the values API drops trailing blank cells, so the header\n // row alone can look narrower than the responses under it (a column added\n // by hand). Column by column, the number returned is the width in use.\n const readHeader = async () => {\n const read = await call<{ values?: unknown[][] }>(\n \"read header\",\n `${range(`A1:ZZZ${HEADER_SCAN_ROWS}`)}?majorDimension=COLUMNS`,\n );\n const used = read.values ?? [];\n return { used: used.length, existing: used.map((column) => column[0] ?? \"\") };\n };\n let columns = sheet.gridProperties?.columnCount ?? 26;\n let { used, existing } = await readHeader();\n let header: string[] = [];\n // The header row is written whole, so two deliveries merging different\n // keys at once can overwrite each other. After a write, read it back: if\n // a key of ours is missing, merge onto what is there and write again.\n // The state keeps the header as read, so rows map onto the real columns.\n for (let attempt = 0; ; attempt++) {\n header = mergeHeader(existing, keys, used);\n // A new tab starts with the id column; one already in use gets it at the\n // end, so the columns already holding responses don't move.\n if (!header.includes(\"id\")) {\n if (used) header.push(\"id\");\n else header.unshift(\"id\");\n }\n const changed = header.length !== existing.length || header.some((h, i) => h !== String(existing[i] ?? \"\"));\n if (!changed) break;\n if (attempt >= HEADER_WRITE_ATTEMPTS) {\n throw new DeliveryError(\"Google Sheets header kept changing while it was written\", { retryable: true });\n }\n if (header.length > columns) {\n await batchUpdate(\"add columns\", [\n { appendDimension: { sheetId: sheet.sheetId, dimension: \"COLUMNS\", length: header.length - columns } },\n ]);\n columns = header.length;\n }\n await call(\"write header\", `${range(\"A1\")}?valueInputOption=RAW`, {\n method: \"PUT\",\n body: JSON.stringify({ values: [header] }),\n });\n if (existing.length === 0) {\n await batchUpdate(\"freeze header\", [\n {\n updateSheetProperties: {\n properties: { sheetId: sheet.sheetId, gridProperties: { frozenRowCount: 1 } },\n fields: \"gridProperties.frozenRowCount\",\n },\n },\n ]);\n }\n ({ used, existing } = await readHeader());\n }\n return {\n spreadsheet_id: spreadsheetId,\n sheet_name: sheetName,\n sheet_id: sheet.sheetId,\n header,\n columns,\n last_row: previous?.last_row ?? 0,\n };\n }\n\n let skipped: string[] = [];\n async function append(state: SheetState): Promise<SheetState> {\n // A redelivery may find its row already there: an earlier append went\n // through even though Google answered 5xx or the request timed out.\n // An update overwrites its response's row where it is, and is appended\n // only when that row is gone (deleted by hand, say).\n // One row per response: a batch holding a response twice (sent, then\n // edited) writes its latest version once, as an update if either was.\n const byId = new Map<string, { id: string; row: Record<string, Cell>; update: boolean }>();\n items.forEach((item, i) => {\n const id = item.submission.id;\n const update = (item.update ?? deliveryOptions.update) === true || byId.get(id)?.update === true;\n byId.delete(id);\n byId.set(id, { id, row: rows[i]!.row, update });\n });\n let pending = [...byId.values()];\n const updating = pending.some((p) => p.update);\n const overwrite: { at: number; row: Record<string, Cell> }[] = [];\n skipped = [];\n if (deliveryOptions.redelivery || updating) {\n const column = columnLetter(state.header.indexOf(\"id\"));\n // An update may be for a response from long ago, so it reads the whole\n // id column (one column, one request); a redelivery only the rows it\n // can have written.\n const from = !updating && state.last_row > 0 ? Math.max(2, state.last_row - DEDUPE_WINDOW) : 2;\n const ids = await call<{ values?: unknown[][] }>(\"read ids\", range(`${column}${from}:${column}`));\n const rowOf = new Map<string, number>();\n (ids.values ?? []).forEach((r, i) => {\n const id = String(r?.[0] ?? \"\");\n if (id && !rowOf.has(id)) rowOf.set(id, from + i);\n });\n pending = pending.filter((p) => {\n const at = rowOf.get(p.id);\n if (at === undefined) return true;\n if (p.update) overwrite.push({ at, row: p.row });\n else skipped.push(p.id);\n return false;\n });\n }\n if (overwrite.length) {\n await call(\"update rows\", `${base}/values:batchUpdate`, {\n method: \"POST\",\n body: JSON.stringify({\n valueInputOption: \"RAW\",\n data: overwrite.map((o) => ({\n range: `${quoteSheet(sheetName)}!A${o.at}`,\n values: [rowFor(state.header, o.row, escape)],\n })),\n }),\n });\n }\n if (!pending.length) return state;\n const result = await call<{ updates?: { updatedRange?: string } }>(\n \"append\",\n `${range(\"A1\")}:append?valueInputOption=RAW&insertDataOption=INSERT_ROWS`,\n { method: \"POST\", body: JSON.stringify({ values: pending.map((p) => rowFor(state.header, p.row, escape)) }) },\n );\n const last = /![A-Z]+\\d+:[A-Z]+(\\d+)$/.exec(result.updates?.updatedRange ?? \"\")?.[1];\n return { ...state, last_row: last ? Number(last) : state.last_row + pending.length };\n }\n\n const cached = readState(deliveryOptions.state, spreadsheetId, sheetName);\n const fresh = !cached || keys.some((k) => !cached.header.includes(k));\n let state = fresh ? await setUp(cached) : cached;\n try {\n state = await append(state);\n } catch (error) {\n if (!(error instanceof StaleSheetError) || fresh) throw error;\n state = await append(await setUp(cached));\n }\n return {\n ok: true,\n state: state as unknown as Record<string, Json>,\n ...(skipped.length ? { skipped } : {}),\n };\n }\n\n const guarded = async (...args: Parameters<typeof run>): Promise<DeliveryResult> => {\n try {\n return await run(...args);\n } catch (error) {\n return deliveryFailure(error);\n }\n };\n\n return {\n kind: \"sheet\",\n deliver: (submission, definition, config, deliveryOptions = {}) =>\n guarded(\n [{ submission, definition, deliveryId: deliveryOptions.deliveryId, update: deliveryOptions.update }],\n config,\n deliveryOptions,\n ),\n deliverBatch: (items, config, deliveryOptions = {}) => guarded(items, config, deliveryOptions),\n };\n}\n","/**\n * Where a Slack or webhook destination may post, checked against SSRF: https\n * only, on the default port, with no credentials in the address, and only to\n * a public host, never a private, loopback, link-local or otherwise internal\n * one. `parseHookUrl` checks the text (use it when someone adds the address);\n * `checkHookHost` checks every address the name resolves to right now (use it\n * before every request: what a name points to can change).\n *\n * A check before the request still leaves a short window in which the name\n * could be re-pointed (DNS rebinding). Where untrusted people choose URLs,\n * also send from a network that cannot reach internal services.\n */\nimport { DeliveryError } from \"./types\";\n\nexport type HookKind = \"slack\" | \"webhook\";\n\n/** Resolves a host name to its addresses (IPv4 and IPv6), as the server's DNS sees them. In Node: `dns.promises.lookup(host, { all: true })` mapped to `.address`. */\nexport type ResolveHost = (host: string) => Promise<string[]>;\n\nexport const MAX_HOOK_URL_LENGTH = 2048;\n/** The hosts a Slack incoming webhook lives on. */\nexport const SLACK_HOSTS: ReadonlySet<string> = new Set([\"hooks.slack.com\"]);\n\n/** An address that can't be used, with a reason safe to show and to store (never the address). */\nexport class HookUrlError extends DeliveryError {\n override name = \"HookUrlError\";\n}\n\nconst NOT_PUBLIC = \"The address must be on the public internet.\";\n\n// Host names that only ever mean something internal.\nconst INTERNAL_SUFFIXES = [\".localhost\", \".local\", \".internal\", \".intranet\", \".lan\", \".home.arpa\"];\n\n/** IPv4 dotted quad to its 4 bytes, or null. */\nfunction ipv4Bytes(ip: string): number[] | null {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n const bytes = parts.map((p) => (/^\\d{1,3}$/.test(p) ? Number(p) : NaN));\n return bytes.every((b) => Number.isInteger(b) && b >= 0 && b <= 255) ? bytes : null;\n}\n\nfunction publicIpv4(b: number[]): boolean {\n const [a, c] = [b[0]!, b[1]!];\n if (a === 0 || a === 10 || a === 127) return false; // this network, private, loopback\n if (a === 100 && c >= 64 && c <= 127) return false; // carrier-grade NAT\n if (a === 169 && c === 254) return false; // link-local, cloud metadata\n if (a === 172 && c >= 16 && c <= 31) return false; // private\n if (a === 192 && c === 168) return false; // private\n if (a === 192 && c === 0 && (b[2] === 0 || b[2] === 2)) return false; // IETF, documentation\n if (a === 198 && (c === 18 || c === 19)) return false; // benchmarking\n if (a === 198 && c === 51 && b[2] === 100) return false; // documentation\n if (a === 203 && c === 0 && b[2] === 113) return false; // documentation\n if (a >= 224) return false; // multicast, reserved, broadcast\n return true;\n}\n\n/** IPv6 text to its 16 bytes, or null. Accepts `::`, brackets, a zone and a trailing dotted IPv4. */\nfunction ipv6Bytes(ip: string): number[] | null {\n let text = ip.replace(/^\\[|\\]$/g, \"\").toLowerCase();\n const zone = text.indexOf(\"%\");\n if (zone >= 0) text = text.slice(0, zone);\n let tail: number[] = [];\n const lastColon = text.lastIndexOf(\":\");\n if (text.slice(lastColon + 1).includes(\".\")) {\n const v4 = ipv4Bytes(text.slice(lastColon + 1));\n if (!v4) return null;\n tail = v4;\n text = text.slice(0, lastColon + 1) + \"0:0\";\n }\n const halves = text.split(\"::\");\n if (halves.length > 2) return null;\n const groups = (s: string) => (s === \"\" ? [] : s.split(\":\"));\n const head = groups(halves[0]!);\n const rest = halves.length === 2 ? groups(halves[1]!) : [];\n const missing = 8 - head.length - rest.length;\n if (halves.length === 1 ? missing !== 0 : missing < 1) return null;\n const all = [...head, ...Array<string>(halves.length === 2 ? missing : 0).fill(\"0\"), ...rest];\n const bytes: number[] = [];\n for (const g of all) {\n if (!/^[0-9a-f]{1,4}$/.test(g)) return null;\n const n = parseInt(g, 16);\n bytes.push(n >> 8, n & 255);\n }\n if (tail.length) bytes.splice(12, 4, ...tail);\n return bytes;\n}\n\nfunction publicIpv6(b: number[]): boolean {\n const zeros = (from: number, to: number) => b.slice(from, to).every((x) => x === 0);\n if (zeros(0, 16)) return false; // ::\n if (zeros(0, 15) && b[15] === 1) return false; // ::1\n // IPv4-mapped (::ffff:a.b.c.d) and IPv4-compatible (::a.b.c.d): the IPv4 address decides.\n if (zeros(0, 10) && b[10] === 0xff && b[11] === 0xff) return publicIpv4(b.slice(12));\n if (zeros(0, 12)) return publicIpv4(b.slice(12));\n // NAT64 (64:ff9b::/96): the embedded IPv4 address decides too.\n if (b[0] === 0 && b[1] === 0x64 && b[2] === 0xff && b[3] === 0x9b && zeros(4, 12)) return publicIpv4(b.slice(12));\n if ((b[0]! & 0xfe) === 0xfc) return false; // unique local fc00::/7\n if (b[0] === 0xfe && (b[1]! & 0xc0) === 0x80) return false; // link-local fe80::/10\n if (b[0] === 0xfe && (b[1]! & 0xc0) === 0xc0) return false; // site-local fec0::/10\n if (b[0] === 0xff) return false; // multicast\n if (b[0] === 0x20 && b[1] === 0x01 && b[2] === 0x0d && b[3] === 0xb8) return false; // documentation\n if (b[0] === 0x20 && b[1] === 0x01 && b[2] === 0 && b[3] === 0) return false; // Teredo\n if (b[0] === 0x20 && b[1] === 0x02) return publicIpv4(b.slice(2, 6)); // 6to4\n if (b[0] === 0x01 && zeros(1, 8)) return false; // discard-only 100::/64\n return true;\n}\n\n/** Whether an IP address (v4 or v6) is a public one a hook may reach. Anything unparsable is not. */\nexport function isPublicAddress(ip: string): boolean {\n const v4 = ipv4Bytes(ip);\n if (v4) return publicIpv4(v4);\n const v6 = ipv6Bytes(ip);\n return v6 ? publicIpv6(v6) : false;\n}\n\n/** Whether a URL host (as `URL.hostname` gives it) is an IP literal rather than a name. */\nfunction isIpLiteral(host: string): boolean {\n return ipv4Bytes(host) !== null || host.startsWith(\"[\");\n}\n\n/**\n * The address as it will be used (its fragment dropped), or a `HookUrlError`\n * saying what is wrong with it. Checks the text only; `checkHookHost` checks\n * where the name resolves. A `\"slack\"` address must be a Slack incoming\n * webhook (`https://hooks.slack.com/services/…`).\n */\nexport function parseHookUrl(raw: string, kind: HookKind = \"webhook\"): URL {\n const text = raw.trim();\n if (!text) throw new HookUrlError(\"Paste the address to send responses to.\");\n if (text.length > MAX_HOOK_URL_LENGTH) throw new HookUrlError(\"That address is too long.\");\n let url: URL;\n try {\n url = new URL(text);\n } catch {\n throw new HookUrlError(\"That doesn't look like a web address.\");\n }\n if (url.protocol !== \"https:\") throw new HookUrlError(\"The address must start with https://.\");\n if (url.username || url.password) throw new HookUrlError(\"The address can't include a user name or password.\");\n if (url.port && url.port !== \"443\") throw new HookUrlError(\"The address must use the standard https port.\");\n url.hash = \"\";\n const host = url.hostname.replace(/\\.$/, \"\");\n if (kind === \"slack\") {\n if (!SLACK_HOSTS.has(host) || !url.pathname.startsWith(\"/services/\")) {\n throw new HookUrlError(\"Use a Slack incoming webhook address, which starts with https://hooks.slack.com/services/.\");\n }\n return url;\n }\n if (isIpLiteral(host)) {\n if (!isPublicAddress(host)) throw new HookUrlError(NOT_PUBLIC);\n return url;\n }\n if (!host.includes(\".\") || host === \"localhost\" || INTERNAL_SUFFIXES.some((suffix) => host.endsWith(suffix))) {\n throw new HookUrlError(NOT_PUBLIC);\n }\n return url;\n}\n\n/**\n * Checks that every address the URL's host resolves to is public. A host\n * that resolves to nothing, or whose lookup fails, is refused too, as a\n * retryable failure (DNS may be briefly down); a private address is final.\n */\nexport async function checkHookHost(url: URL, resolve: ResolveHost): Promise<void> {\n const host = url.hostname.replace(/\\.$/, \"\");\n if (isIpLiteral(host)) {\n if (!isPublicAddress(host)) throw new HookUrlError(NOT_PUBLIC);\n return;\n }\n let addresses: string[];\n try {\n addresses = await resolve(host);\n } catch {\n throw new HookUrlError(`${host} couldn't be found`, { retryable: true });\n }\n if (!addresses.length) throw new HookUrlError(`${host} couldn't be found`, { retryable: true });\n if (!addresses.every(isPublicAddress)) throw new HookUrlError(NOT_PUBLIC);\n}\n\n/** The host as a screen may show it (never the path: a Slack or webhook path can be the secret). */\nexport function hookHost(url: URL): string {\n return url.hostname.replace(/\\.$/, \"\").toLowerCase();\n}\n","/**\n * The webhook destination: a signed JSON POST to a URL, following the\n * Standard Webhooks spec (standardwebhooks.com), so receivers can verify it\n * with any Standard Webhooks library, or with `verifyWebhook` here.\n *\n * Headers: `webhook-id` (the delivery id, stable across retries: receivers\n * dedupe on it), `webhook-timestamp` (Unix seconds) and `webhook-signature`\n * (`v1,<base64 HMAC-SHA256 of \"<id>.<timestamp>.<body>\">`). Receivers reject\n * a timestamp more than five minutes off, which stops replays. Given\n * several secrets (a rotation), it signs with each, space-separated, so the\n * receiver can move to the new one without missing a delivery. A 410 Gone\n * fails with `disable: true`: the receiver asks to be switched off.\n *\n * The URL comes from config, which an admin may type, so by default it must\n * be https, carry no credentials, and not name localhost or a private,\n * loopback or link-local address literally. Redirects are not followed. A\n * hostname that resolves to a private address is not caught here, and even\n * `resolveHost` checks the name before the request, which DNS rebinding can\n * get around: if untrusted users choose URLs, send through an egress proxy\n * that refuses internal addresses.\n */\nimport { own, withheld } from \"../logic\";\nimport { isSensitive } from \"../fields\";\nimport type { FieldBlock, FormDefinition, Json } from \"../types\";\nimport { checkHookHost, type ResolveHost } from \"./hook-url\";\nimport { responseRow, visibleInputs, type RowOptions } from \"./row\";\nimport {\n base64,\n configString,\n deliveryFailure,\n DeliveryError,\n discard,\n fromBase64,\n httpError,\n resolveOption,\n timedFetch,\n type DeliveryOptions,\n type DeliveryResult,\n type DeliverySubmission,\n type Destination,\n type DestinationConfig,\n type HttpDeps,\n type OptionResolver,\n type WebCryptoKey,\n} from \"./types\";\n\n/** What the webhook destination reads from a destination's config. */\nexport interface WebhookConfig {\n url: string;\n}\n\nexport interface WebhookDestinationOptions extends HttpDeps {\n /**\n * The signing secret: base64 of at least 24 random bytes (the spec\n * recommends 24 to 64), usually with the `whsec_` prefix Standard Webhooks\n * tools issue. The prefix is optional; the rest is always base64-decoded,\n * as every Standard Webhooks library does, so a receiver verifies with the\n * same string. A secret that is not base64, or is shorter, fails\n * permanently. Several secrets (new and old, during a rotation) sign with\n * each, space-separated in `webhook-signature`, so the receiver verifies\n * with either. Or a function that finds them for a destination's config.\n * Never put it in config.\n */\n secret: string | readonly string[] | OptionResolver<string | readonly string[]>;\n /** Allow `http:` URLs. Default false. */\n allowInsecureUrls?: boolean | undefined;\n /** Allow localhost and private, loopback and link-local address literals. Default false. */\n allowPrivateHosts?: boolean | undefined;\n /** Sensitive fields: `\"include\"` (default), `\"mask\"` or `\"omit\"`. */\n sensitive?: RowOptions[\"sensitive\"];\n /** The event type in the payload. Default `\"form.submitted\"`, or `\"form.updated\"` for an update. */\n type?: string | undefined;\n /**\n * Where to post, when it is not `config.url`: the address kept apart from\n * config (encrypted, say, since a webhook URL can carry a token). Gets the\n * config and `{ destinationId }`. It passes the same checks.\n */\n url?: OptionResolver<string> | undefined;\n /**\n * Resolves the URL's host before every request, and the delivery is refused\n * unless every address is public (see `checkHookHost`). This catches a\n * hostname that points at a private address, which the URL checks alone\n * cannot. Recommended wherever untrusted people choose URLs.\n */\n resolveHost?: ResolveHost | undefined;\n now?: (() => number) | undefined;\n}\n\n/** The JSON body a webhook receives. */\nexport interface WebhookPayload {\n type: string;\n /**\n * ISO time the event happened: the submission's `submittedAt`, or the send\n * time when it has none. The `webhook-timestamp` header is the send time.\n */\n timestamp: string;\n data: {\n form: { id: string; title: string };\n submission: {\n id: string;\n /** Answers keyed by field id. */\n answers: Record<string, Json>;\n hidden: Record<string, Json>;\n context: Record<string, Json>;\n ending: string | null;\n submittedAt: string | null;\n meta: Record<string, Json>;\n tags: string[];\n };\n /** The same submission as a flat row by column key: labels for choices, as the sheet shows it. */\n row: Record<string, Json>;\n };\n}\n\n/** The shortest signing secret, decoded: Standard Webhooks recommends 24 to 64 bytes. */\nexport const MIN_WEBHOOK_SECRET_BYTES = 24;\nconst STRICT_BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;\n\n/**\n * The HMAC key bytes for a secret, decoded as the Standard Webhooks\n * reference libraries do: an optional `whsec_` prefix is dropped and the\n * rest is base64-decoded. Only padded standard base64 is accepted, the form\n * every reference library decodes the same way. Throws a `DeliveryError` for\n * a secret that is not base64 or is shorter than 24 bytes once decoded.\n */\nfunction secretKey(secret: string): Uint8Array<ArrayBuffer> {\n const encoded = secret.startsWith(\"whsec_\") ? secret.slice(6) : secret;\n if (!encoded || !STRICT_BASE64.test(encoded)) {\n throw new DeliveryError(\n \"The webhook secret must be base64, optionally prefixed with whsec_ (Standard Webhooks libraries base64-decode it)\",\n );\n }\n const bytes = fromBase64(encoded);\n if (bytes.length < MIN_WEBHOOK_SECRET_BYTES) {\n throw new DeliveryError(`The webhook secret is shorter than ${MIN_WEBHOOK_SECRET_BYTES} bytes`);\n }\n return bytes;\n}\n\nasync function hmacKey(secret: string, usage: \"sign\" | \"verify\"): Promise<WebCryptoKey> {\n return crypto.subtle.importKey(\"raw\", secretKey(secret), { name: \"HMAC\", hash: \"SHA-256\" }, false, [usage]);\n}\n\n/**\n * A new signing secret: `whsec_` and standard base64 of 32 random bytes, the\n * form Standard Webhooks libraries read. Show it to the receiver once; keep it\n * out of config.\n */\nexport function newWebhookSecret(): string {\n return `whsec_${base64(crypto.getRandomValues(new Uint8Array(32)))}`;\n}\n\n/**\n * The `webhook-signature` value for a message: `v1,<base64>`, or one such\n * signature per secret, space-separated, when given several (a rotation).\n */\nexport async function signWebhook(secret: string | readonly string[], id: string, timestamp: number, body: string): Promise<string> {\n const secrets = typeof secret === \"string\" ? [secret] : secret;\n if (secrets.length === 0) throw new DeliveryError(\"The webhook secret is not set\");\n const data = new TextEncoder().encode(`${id}.${timestamp}.${body}`);\n const signatures: string[] = [];\n for (const one of secrets) {\n const key = await hmacKey(one, \"sign\");\n signatures.push(`v1,${base64(new Uint8Array(await crypto.subtle.sign(\"HMAC\", key, data)))}`);\n }\n return signatures.join(\" \");\n}\n\nexport interface VerifyWebhookInput {\n /**\n * The same secret the sender signs with (base64, optionally\n * `whsec_`-prefixed), or several (new and old, during a rotation): any one\n * matching signature passes.\n */\n secret: string | readonly string[];\n /** The request's headers: a `Headers` or a plain object. */\n headers: Headers | Record<string, string | string[] | undefined>;\n /** The raw body, exactly as received. */\n body: string;\n /** Default 300: a timestamp further off than this is refused. */\n toleranceSeconds?: number | undefined;\n now?: (() => number) | undefined;\n}\n\n/**\n * Checks a Standard Webhooks request: the timestamp is recent and one of the\n * space-separated `v1` signatures matches. Compares in constant time (by\n * WebCrypto `verify`). Never throws on a malformed request: returns false.\n */\nexport async function verifyWebhook(input: VerifyWebhookInput): Promise<boolean> {\n const header = (name: string): string => {\n if (typeof (input.headers as Headers).get === \"function\") return (input.headers as Headers).get(name) ?? \"\";\n const raw = (input.headers as Record<string, string | string[] | undefined>)[name];\n return Array.isArray(raw) ? (raw[0] ?? \"\") : (raw ?? \"\");\n };\n const id = header(\"webhook-id\");\n const timestamp = header(\"webhook-timestamp\");\n const signatures = header(\"webhook-signature\");\n if (!id || !/^\\d{1,12}$/.test(timestamp) || !signatures) return false;\n const now = Math.floor((input.now?.() ?? Date.now()) / 1000);\n if (Math.abs(now - Number(timestamp)) > (input.toleranceSeconds ?? 300)) return false;\n const keys: WebCryptoKey[] = [];\n for (const secret of typeof input.secret === \"string\" ? [input.secret] : input.secret) {\n try {\n keys.push(await hmacKey(secret, \"verify\"));\n } catch {\n // An unusable secret matches nothing.\n }\n }\n if (keys.length === 0) return false;\n const data = new TextEncoder().encode(`${id}.${timestamp}.${input.body}`);\n for (const part of signatures.split(\" \")) {\n const [version, value] = part.split(\",\", 2);\n if (version !== \"v1\" || !value) continue;\n let mac: Uint8Array<ArrayBuffer>;\n try {\n mac = fromBase64(value);\n } catch {\n continue;\n }\n for (const key of keys) if (await crypto.subtle.verify(\"HMAC\", key, mac, data)) return true;\n }\n return false;\n}\n\nconst PRIVATE_HOSTNAME = /(^|\\.)(localhost|local|internal|localdomain|home\\.arpa)$/i;\n\n/** Whether a URL hostname is localhost or a private, loopback, link-local or unspecified address literal. */\nexport function isPrivateHost(hostname: string): boolean {\n const host = hostname.toLowerCase().replace(/\\.$/, \"\");\n if (PRIVATE_HOSTNAME.test(host)) return true;\n const v4 = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/.exec(host);\n if (v4) return isPrivateV4(v4.slice(1).map(Number) as [number, number, number, number]);\n if (host.startsWith(\"[\") && host.endsWith(\"]\")) {\n const v6 = host.slice(1, -1);\n if (v6 === \"::\" || v6 === \"::1\") return true;\n // IPv4-mapped (::ffff:a.b.c.d, which URL writes as ::ffff:xxxx:xxxx).\n const mapped = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(v6);\n if (mapped) {\n const hi = parseInt(mapped[1]!, 16);\n const lo = parseInt(mapped[2]!, 16);\n return isPrivateV4([hi >> 8, hi & 255, lo >> 8, lo & 255]);\n }\n const first = parseInt(v6.split(\":\")[0] || \"0\", 16);\n return (first & 0xfe00) === 0xfc00 || (first & 0xffc0) === 0xfe80; // fc00::/7, fe80::/10\n }\n return false;\n}\n\nfunction isPrivateV4([a, b]: [number, number, number, number]): boolean {\n return (\n a === 0 ||\n a === 10 ||\n a === 127 ||\n (a === 100 && b >= 64 && b <= 127) ||\n (a === 169 && b === 254) ||\n (a === 172 && b >= 16 && b <= 31) ||\n (a === 192 && b === 168) ||\n (a === 198 && (b === 18 || b === 19)) ||\n a >= 224\n );\n}\n\n/** The URL from config, checked. Throws a `DeliveryError` naming the rule it broke (never the URL, which may hold a token). */\nexport function checkWebhookUrl(\n raw: string,\n options: Pick<WebhookDestinationOptions, \"allowInsecureUrls\" | \"allowPrivateHosts\"> = {},\n): URL {\n if (!raw) throw new DeliveryError(\"The webhook destination has no url\");\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new DeliveryError(\"The webhook url is not a valid URL\");\n }\n if (url.protocol !== \"https:\" && !(options.allowInsecureUrls && url.protocol === \"http:\")) {\n throw new DeliveryError(\"The webhook url must use https\");\n }\n if (url.username || url.password) throw new DeliveryError(\"The webhook url must not contain credentials\");\n if (!options.allowPrivateHosts && isPrivateHost(url.hostname)) {\n throw new DeliveryError(\"The webhook url points at a private or local address\");\n }\n return url;\n}\n\n/** The payload for one submission. Identifying answers stay out on anonymous forms. */\nexport function webhookPayload(\n submission: DeliverySubmission,\n definition: FormDefinition,\n options: { sensitive?: RowOptions[\"sensitive\"]; type?: string | undefined; now?: number | undefined } = {},\n): WebhookPayload {\n const sensitive = options.sensitive ?? \"include\";\n const { row } = responseRow(submission, definition, { sensitive });\n const answers: Record<string, Json> = {};\n for (const block of definition.blocks) {\n if (block.kind !== \"field\") continue;\n const field = block as FieldBlock;\n const value = own(submission.answers, field.id);\n if (value === undefined || withheld(definition, field)) continue;\n if (isSensitive(field) && sensitive !== \"include\") {\n if (sensitive === \"mask\") answers[field.id] = \"[sensitive]\";\n continue;\n }\n answers[field.id] = value;\n }\n const inputs = visibleInputs(submission, definition, sensitive);\n const pick = (source: Record<string, Json> | undefined, allowed: Record<string, Json>) => {\n const out: Record<string, Json> = {};\n for (const [name, value] of Object.entries(source ?? {})) if (own(allowed, name) !== undefined) out[name] = value;\n return out;\n };\n const happened = submission.submittedAt ? Date.parse(submission.submittedAt) : Number.NaN;\n return {\n type: options.type ?? \"form.submitted\",\n timestamp: new Date(Number.isNaN(happened) ? (options.now ?? Date.now()) : happened).toISOString(),\n data: {\n form: { id: definition.id, title: definition.title },\n submission: {\n id: submission.id,\n answers,\n hidden: pick(submission.hidden, inputs),\n context: pick(submission.context, inputs),\n ending: submission.ending ?? null,\n submittedAt: submission.submittedAt ?? null,\n meta: { ...submission.meta },\n tags: [...(submission.tags ?? [])],\n },\n row,\n },\n };\n}\n\nexport function webhookDestination(options: WebhookDestinationOptions): Destination {\n return {\n kind: \"webhook\",\n async deliver(submission, definition, config, deliveryOptions: DeliveryOptions = {}): Promise<DeliveryResult> {\n try {\n const context = { destinationId: deliveryOptions.destinationId };\n const raw = options.url\n ? await resolveOption(\"The webhook url\", options.url, config, context)\n : configString(config, \"url\");\n const url = checkWebhookUrl(typeof raw === \"string\" ? raw.trim() : \"\", options);\n // allowPrivateHosts opts out of the address check, the resolved one included.\n if (options.resolveHost && !options.allowPrivateHosts) await checkHookHost(url, options.resolveHost);\n const secret = await resolveOption(\"The webhook secret\", options.secret, config, context);\n if (!secret || secret.length === 0) throw new DeliveryError(\"The webhook secret is not set\");\n const now = options.now?.() ?? Date.now();\n const id = deliveryOptions.deliveryId ?? submission.id;\n const timestamp = Math.floor(now / 1000);\n const type = options.type ?? (deliveryOptions.update ? \"form.updated\" : undefined);\n const body = JSON.stringify(webhookPayload(submission, definition, { sensitive: options.sensitive, type, now }));\n const response = await timedFetch(\n options,\n url.toString(),\n {\n method: \"POST\",\n redirect: \"manual\",\n headers: {\n \"content-type\": \"application/json\",\n \"user-agent\": \"genesis-forms-webhook/1\",\n \"webhook-id\": id,\n \"webhook-timestamp\": String(timestamp),\n \"webhook-signature\": await signWebhook(secret, id, timestamp, body),\n },\n body,\n },\n deliveryOptions.signal,\n );\n discard(response);\n if (response.status >= 200 && response.status < 300) return { ok: true };\n // Standard Webhooks: 410 Gone means the receiver wants no more deliveries.\n if (response.status === 410) {\n throw new DeliveryError(\"Webhook answered 410: the endpoint is gone; disable the destination\", { status: 410, disable: true });\n }\n // `redirect: \"manual\"` gives a 3xx (or, in browsers, an opaque status 0).\n if (response.status === 0 || (response.status >= 300 && response.status < 400)) {\n throw new DeliveryError(`Webhook answered ${response.status || \"a redirect\"}: redirects are not followed`, {\n ...(response.status ? { status: response.status } : {}),\n });\n }\n throw httpError(\"Webhook\", response);\n } catch (error) {\n return deliveryFailure(error);\n }\n },\n };\n}\n","/**\n * The Slack destination: one message per submission to a Slack incoming\n * webhook (the channel is the webhook's). The message is a heading (the\n * form's title), each answer as \"label: value\" in form order, and a footer\n * with a link back to the app when one is given. Every value is escaped, so\n * text a respondent typed can't mention `@channel` or make a link.\n *\n * The webhook URL is itself the credential, so it is usually kept out of\n * config: pass `url` to look it up. It must be a Slack incoming webhook\n * (`https://hooks.slack.com/services/…`); redirects are not followed.\n */\nimport type { FormDefinition } from \"../types\";\nimport { checkHookHost, parseHookUrl, type ResolveHost } from \"./hook-url\";\nimport { responseRow, type RowOptions } from \"./row\";\nimport {\n configString,\n deliveryFailure,\n DeliveryError,\n discard,\n httpError,\n resolveOption,\n timedFetch,\n type DeliveryOptions,\n type DeliveryResult,\n type DeliverySubmission,\n type Destination,\n type DestinationConfig,\n type HttpDeps,\n type OptionResolver,\n} from \"./types\";\n\n/** Longest answer shown in full; longer ones are cut (the app has the rest). */\nexport const SLACK_VALUE_LIMIT = 1500;\n\n/** Text for Slack's mrkdwn: `&`, `<` and `>` escaped, which is all Slack asks. */\nexport function escapeSlack(text: string): string {\n return text.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nconst cut = (text: string) => (text.length > SLACK_VALUE_LIMIT ? `${text.slice(0, SLACK_VALUE_LIMIT)}…` : text);\n\nexport interface SlackMessageOptions {\n /** The heading, as plain text (it is escaped). Default `New response: <title>`, or `Updated response: …` for an update. */\n heading?: string | undefined;\n /** An update of a submission delivered before. */\n update?: boolean | undefined;\n /** Lines shown before the answers, as `[label, value]` plain text (a location, a session). */\n lines?: readonly (readonly [string, string])[] | undefined;\n /** A link back to the response in the app: http(s) only. */\n link?: { url: string; text?: string | undefined } | null | undefined;\n /** Sensitive fields: `\"mask\"` (default), `\"omit\"` or `\"include\"`. A channel is usually wider than an inbox. */\n sensitive?: RowOptions[\"sensitive\"];\n /** Field keys left out (contact details, say). */\n omit?: readonly string[] | undefined;\n}\n\n/** The message Slack gets for one submission: `{ text }` in Slack mrkdwn. */\nexport function slackMessage(\n submission: DeliverySubmission,\n definition: FormDefinition,\n options: SlackMessageOptions = {},\n): { text: string } {\n const title = definition.title || definition.id;\n const heading = options.heading ?? `${options.update ? \"Updated response\" : \"New response\"}: ${title}`;\n const lines = [`*${escapeSlack(heading)}*`];\n for (const [label, value] of options.lines ?? []) {\n if (value.trim()) lines.push(`*${escapeSlack(label)}*: ${escapeSlack(cut(value))}`);\n }\n const { row, labels } = responseRow(submission, definition, { sensitive: options.sensitive ?? \"mask\" });\n const omit = new Set(options.omit ?? []);\n let answered = 0;\n for (const [key, label] of Object.entries(labels)) {\n const text = String(row[key] ?? \"\");\n if (!text || omit.has(key)) continue;\n answered++;\n lines.push(`*${escapeSlack(label || key)}*: ${escapeSlack(cut(text))}`);\n }\n if (!answered) lines.push(\"_No answers._\");\n const when = submission.submittedAt ? ` · ${escapeSlack(submission.submittedAt)}` : \"\";\n const link = options.link;\n lines.push(\n link && /^https?:\\/\\//i.test(link.url)\n ? `<${link.url.replace(/[<>|]/g, \"\")}|${escapeSlack(link.text ?? \"Open the response\").replace(/[|]/g, \"\")}>${when}`\n : `Response ${escapeSlack(submission.id)}${when}`,\n );\n return { text: lines.join(\"\\n\") };\n}\n\nexport interface SlackMessageInput {\n submission: DeliverySubmission;\n definition: FormDefinition;\n config: DestinationConfig;\n /** `DeliveryOptions.update`. */\n update: boolean;\n destinationId?: string | undefined;\n}\n\nexport interface SlackDestinationOptions extends HttpDeps {\n /**\n * The incoming webhook URL, when it is not `config.url`. Gets the config\n * and `{ destinationId }`.\n */\n url?: OptionResolver<string> | undefined;\n /** Resolves the host before every request; the delivery is refused unless every address is public. */\n resolveHost?: ResolveHost | undefined;\n /** The message's options per delivery (heading, extra lines, a link back). */\n message?: ((input: SlackMessageInput) => SlackMessageOptions | Promise<SlackMessageOptions>) | undefined;\n}\n\nexport function slackDestination(options: SlackDestinationOptions = {}): Destination {\n return {\n kind: \"slack\",\n async deliver(submission, definition, config, deliveryOptions: DeliveryOptions = {}): Promise<DeliveryResult> {\n try {\n const context = { destinationId: deliveryOptions.destinationId };\n const raw = options.url\n ? await resolveOption(\"The Slack webhook url\", options.url, config, context)\n : configString(config, \"url\");\n if (typeof raw !== \"string\" || !raw.trim()) throw new DeliveryError(\"The Slack destination has no url\");\n const url = parseHookUrl(raw, \"slack\");\n if (options.resolveHost) await checkHookHost(url, options.resolveHost);\n const update = deliveryOptions.update === true;\n const messageOptions = options.message\n ? await resolveOption(\n \"The Slack message\",\n () => options.message!({ submission, definition, config, update, destinationId: deliveryOptions.destinationId }),\n config,\n )\n : {};\n const body = JSON.stringify(slackMessage(submission, definition, { update, ...messageOptions }));\n const response = await timedFetch(\n options,\n url.toString(),\n {\n method: \"POST\",\n redirect: \"manual\",\n headers: { \"content-type\": \"application/json\", \"user-agent\": \"genesis-forms-slack/1\" },\n body,\n },\n deliveryOptions.signal,\n );\n discard(response);\n if (response.status >= 200 && response.status < 300) return { ok: true };\n if (response.status === 0 || (response.status >= 300 && response.status < 400)) {\n throw new DeliveryError(`Slack answered ${response.status || \"a redirect\"}: redirects are not followed`, {\n ...(response.status ? { status: response.status } : {}),\n });\n }\n throw httpError(\"Slack\", response);\n } catch (error) {\n return deliveryFailure(error);\n }\n },\n };\n}\n","/**\n * Sending by answer: a destination's `config.when`, a form `Condition`,\n * decides which submissions it gets. It is evaluated with the engine's own\n * `evaluate` against the submission's answers (by field id), its hidden\n * inputs and its context (trusted server inputs, read as hidden inputs and\n * winning over a hidden input of the same name). `createDeliveryRunner`\n * applies it before calling a destination; a submission that does not match\n * is recorded as filtered, not sent and not failed.\n */\nimport { evaluate, own } from \"../logic\";\nimport type { Condition, FieldBlock, FormDefinition, Json } from \"../types\";\nimport { DeliveryError, type DeliverySubmission, type DestinationConfig } from \"./types\";\n\nconst OPERATORS: ReadonlySet<string> = new Set([\"eq\", \"neq\", \"lt\", \"lte\", \"gt\", \"gte\", \"in\", \"contains\", \"answered\", \"empty\"]);\n/** How deep `all` / `any` / `not` may nest in a stored condition. */\nexport const MAX_CONDITION_DEPTH = 10;\n\nconst isObject = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null && !Array.isArray(v);\n\nfunction isOperand(v: unknown): boolean {\n if (!isObject(v)) return false;\n const keys = Object.keys(v);\n if (keys.length !== 1) return false;\n if (keys[0] === \"field\" || keys[0] === \"hidden\") return typeof v[keys[0]] === \"string\";\n return keys[0] === \"value\";\n}\n\n/** Whether a stored value has a `Condition`'s shape, nested at most `MAX_CONDITION_DEPTH` deep. */\nexport function isCondition(v: unknown, depth = 0): v is Condition {\n if (!isObject(v) || depth > MAX_CONDITION_DEPTH) return false;\n if (\"all\" in v) return Array.isArray(v[\"all\"]) && v[\"all\"].every((c) => isCondition(c, depth + 1));\n if (\"any\" in v) return Array.isArray(v[\"any\"]) && v[\"any\"].every((c) => isCondition(c, depth + 1));\n if (\"not\" in v) return isCondition(v[\"not\"], depth + 1);\n return (\n typeof v[\"op\"] === \"string\" &&\n OPERATORS.has(v[\"op\"]) &&\n isOperand(v[\"left\"]) &&\n (v[\"right\"] === undefined || isOperand(v[\"right\"]))\n );\n}\n\n/**\n * The destination's condition (`config.when`), or null when it has none. One\n * that can't be read throws a permanent `DeliveryError` rather than meaning\n * \"send everything\" or \"send nothing\".\n */\nexport function conditionOf(config: DestinationConfig): Condition | null {\n const when = config[\"when\"];\n if (when === undefined || when === null) return null;\n if (!isCondition(when)) throw new DeliveryError(\"The destination's condition can't be read\");\n return when;\n}\n\n/**\n * Whether a submission matches its destination's condition (true when there\n * is none). Throws a `DeliveryError` when the condition can't be read.\n */\nexport function passesCondition(\n submission: Pick<DeliverySubmission, \"answers\" | \"hidden\" | \"context\">,\n definition: FormDefinition,\n config: DestinationConfig,\n): boolean {\n const condition = conditionOf(config);\n if (!condition) return true;\n const fields = new Map<string, FieldBlock>();\n for (const block of definition.blocks) if (block.kind === \"field\") fields.set(block.id, block as FieldBlock);\n // No prototype, so a hidden input named __proto__ is just a name.\n const hidden = Object.create(null) as Record<string, Json>;\n for (const source of [submission.hidden, submission.context]) {\n for (const name of Object.keys(source ?? {})) {\n const value = own(source!, name);\n if (value !== undefined) hidden[name] = value;\n }\n }\n return evaluate(condition, { values: submission.answers, hidden, fields });\n}\n","/**\n * Google sign-in for a Sheet: a person's refresh token (from the app's own\n * OAuth consent flow, usually with the `drive.file` scope, which reaches only\n * the files they picked or created through the app) traded for a short-lived\n * access token at Google's token endpoint. Where the refresh token is kept,\n * and how it is encrypted, is the app's (see `sealSecret`); this module only\n * trades it. fetch only, no dependency.\n *\n * Use it with the sheet destination's `accessToken` option:\n *\n * sheetsDestination({\n * accessToken: async (config, { destinationId }) =>\n * googleOAuthAccessToken(client, await refreshTokenFor(destinationId)),\n * })\n */\nimport { GOOGLE_TOKEN_URL } from \"./google-auth\";\nimport { DeliveryError, discard, httpError, sha256Hex, timedFetch, type HttpDeps } from \"./types\";\n\n/** Google's scope for files the person picked or created through the app. */\nexport const DRIVE_FILE_SCOPE = \"https://www.googleapis.com/auth/drive.file\";\n\n/** The app's OAuth client, from the Google Cloud console. Server-side only. */\nexport interface GoogleOAuthClient {\n clientId: string;\n clientSecret: string;\n}\n\nexport interface GoogleOAuthTokenOptions extends HttpDeps {\n now?: (() => number) | undefined;\n signal?: AbortSignal | undefined;\n}\n\nexport interface RefreshedGoogleToken {\n accessToken: string;\n /** Seconds the access token is good for. */\n expiresIn: number;\n /** The scopes granted, space-separated. */\n scope: string;\n}\n\n/**\n * Trades a refresh token for an access token, uncached. `invalid_grant`\n * (access revoked, or the account gone) is a permanent failure saying to\n * connect the sheet again; 429 and 5xx are retryable. Never puts a token in\n * an error message.\n */\nexport async function refreshGoogleAccessToken(\n client: GoogleOAuthClient,\n refreshToken: string,\n options: GoogleOAuthTokenOptions = {},\n): Promise<RefreshedGoogleToken> {\n if (!client.clientId || !client.clientSecret) throw new DeliveryError(\"The Google OAuth client id or secret is not set\");\n if (!refreshToken) throw new DeliveryError(\"This sheet's Google connection is gone. Connect the sheet again.\");\n const response = await timedFetch(\n options,\n GOOGLE_TOKEN_URL,\n {\n method: \"POST\",\n // The body holds the refresh token and client secret: never follow a redirect with it.\n redirect: \"error\",\n headers: { \"content-type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: client.clientId,\n client_secret: client.clientSecret,\n }).toString(),\n },\n options.signal,\n );\n if (!response.ok) {\n const body = jsonObject(await response.json().catch(() => null)) as { error?: unknown };\n if (response.status === 400 && body.error === \"invalid_grant\") {\n throw new DeliveryError(\"Google access to this sheet was removed. Connect the sheet again.\", { status: 400 });\n }\n discard(response);\n throw httpError(\"Google token endpoint\", response);\n }\n const body = jsonObject(await response.json().catch(() => null)) as { access_token?: unknown; expires_in?: unknown; scope?: unknown };\n if (typeof body.access_token !== \"string\" || !body.access_token) {\n throw new DeliveryError(\"Google token endpoint returned no access token\", { retryable: true });\n }\n return {\n accessToken: body.access_token,\n expiresIn: typeof body.expires_in === \"number\" && body.expires_in > 0 ? body.expires_in : 3600,\n scope: typeof body.scope === \"string\" ? body.scope : DRIVE_FILE_SCOPE,\n };\n}\n\n/** A parsed JSON body as an object: `null`, a list or a scalar become `{}`. */\nfunction jsonObject(value: unknown): Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value) ? (value as Record<string, unknown>) : {};\n}\n\n// One per process. Keyed by a digest of the client and the refresh token, so\n// a hit is only ever for the same grant.\nconst cache = new Map<string, { token: string; expiresAt: number }>();\n\n/** Forgets cached OAuth access tokens (tests, or after a sheet is disconnected). */\nexport function clearGoogleOAuthTokenCache(): void {\n cache.clear();\n}\n\n/** A cached or fresh access token for a refresh token, cached until a minute before it expires. */\nexport async function googleOAuthAccessToken(\n client: GoogleOAuthClient,\n refreshToken: string | null | undefined,\n options: GoogleOAuthTokenOptions = {},\n): Promise<string> {\n if (!refreshToken) throw new DeliveryError(\"This sheet's Google connection is gone. Connect the sheet again.\");\n const now = options.now?.() ?? Date.now();\n const key = await sha256Hex(`${client.clientId}\\n${refreshToken}`);\n const hit = cache.get(key);\n if (hit && hit.expiresAt - 60_000 > now) return hit.token;\n const fresh = await refreshGoogleAccessToken(client, refreshToken, options);\n cache.set(key, { token: fresh.accessToken, expiresAt: now + fresh.expiresIn * 1000 });\n return fresh.accessToken;\n}\n","/**\n * Keeping a destination's secrets at rest: a webhook or Slack URL, a signing\n * secret, a Google refresh token. AES-256-GCM (WebCrypto) under a key derived\n * with HKDF-SHA-256 from one 32-byte app secret and a purpose string, so no\n * two purposes share a key; each ciphertext is bound to associated data (the\n * row it belongs to), so one moved onto another row does not decrypt.\n *\n * The sealed form is `v1.<iv>.<ciphertext and tag>`, base64url. Where it is\n * stored is the app's; the key never is.\n */\nimport { base64url, DeliveryError, fromBase64, type WebCryptoKey } from \"./types\";\n\nconst enc = new TextEncoder();\n\n/**\n * The 32 key bytes from base64 or base64url text (as `openssl rand -base64 32`\n * prints), or the bytes themselves. Throws a `DeliveryError` naming the\n * problem, never the key.\n */\nexport function secretKeyBytes(key: string | Uint8Array): Uint8Array<ArrayBuffer> {\n if (typeof key !== \"string\") {\n if (key.length !== 32) throw new DeliveryError(\"The encryption key must be 32 bytes\");\n return new Uint8Array(key);\n }\n const text = key.trim().replace(/=+$/, \"\");\n if (!text) throw new DeliveryError(\"The encryption key is not set\");\n let bytes: Uint8Array<ArrayBuffer>;\n try {\n bytes = fromBase64(text + \"=\".repeat((4 - (text.length % 4)) % 4));\n } catch {\n throw new DeliveryError(\"The encryption key is not base64\");\n }\n if (bytes.length !== 32) throw new DeliveryError(\"The encryption key must be 32 bytes\");\n return bytes;\n}\n\n/** Options for `deriveSecretKey`. */\nexport interface DeriveSecretKeyOptions {\n /**\n * The HKDF salt: bytes, or text taken as its UTF-8 bytes. Default empty,\n * which is what every key derived before this option existed used, so\n * leave it out to open those. For new keys a fixed, app-wide random value\n * (say 32 bytes from `openssl rand -base64 32`, kept as config) is\n * recommended (RFC 5869). It need not be secret, but must never change\n * once anything is sealed with it.\n */\n salt?: string | Uint8Array | undefined;\n}\n\n/**\n * An AES-GCM key for one purpose, derived from the app secret with HKDF-SHA-256\n * (`info` naming the purpose; the salt empty unless `options.salt` is given).\n * Use a different `info` for each kind of secret; keep it, and the salt,\n * fixed once anything is sealed with them.\n */\nexport async function deriveSecretKey(\n key: string | Uint8Array,\n info: string,\n options: DeriveSecretKeyOptions = {},\n): Promise<WebCryptoKey> {\n if (!info) throw new DeliveryError(\"A sealing key needs its purpose (info)\");\n const salt = typeof options.salt === \"string\" ? enc.encode(options.salt) : new Uint8Array(options.salt ?? new Uint8Array(0));\n const base = await crypto.subtle.importKey(\"raw\", secretKeyBytes(key), \"HKDF\", false, [\"deriveKey\"]);\n return crypto.subtle.deriveKey(\n { name: \"HKDF\", hash: \"SHA-256\", salt, info: enc.encode(info) },\n base,\n { name: \"AES-GCM\", length: 256 },\n false,\n [\"encrypt\", \"decrypt\"],\n );\n}\n\n/** Encrypts `plaintext` bound to `aad` (the row it belongs to): `v1.<iv>.<ciphertext>`. */\nexport async function sealSecret(key: WebCryptoKey, plaintext: string, aad: string): Promise<string> {\n const iv = crypto.getRandomValues(new Uint8Array(12));\n const sealed = await crypto.subtle.encrypt({ name: \"AES-GCM\", iv, additionalData: enc.encode(aad) }, key, enc.encode(plaintext));\n return `v1.${base64url(iv)}.${base64url(new Uint8Array(sealed))}`;\n}\n\n/**\n * Decrypts what `sealSecret` sealed with the same key and `aad`. Throws a\n * permanent `DeliveryError` for an unknown format, a wrong key (rotated?) or\n * a ciphertext from another row; never echoes the ciphertext.\n */\nexport async function openSecret(key: WebCryptoKey, sealed: string, aad: string): Promise<string> {\n const [version, iv, body, extra] = sealed.split(\".\");\n if (version !== \"v1\" || !iv || !body || extra !== undefined) throw new DeliveryError(\"The stored secret is not in a known format\");\n try {\n const plain = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: padded(iv), additionalData: enc.encode(aad) },\n key,\n padded(body),\n );\n return new TextDecoder().decode(plain);\n } catch {\n throw new DeliveryError(\"The stored secret could not be decrypted\");\n }\n}\n\nfunction padded(text: string): Uint8Array<ArrayBuffer> {\n return fromBase64(text + \"=\".repeat((4 - (text.length % 4)) % 4));\n}\n","/**\n * `@marktiderman/genesis-notifications/runner`: the one outbox runner. Claim a\n * batch of due jobs, send them (grouped, so a destination that takes many at\n * once gets one request), and record what happened. No dependencies.\n *\n * The store is the caller's (a SQL outbox claimed with SKIP LOCKED, a\n * queue): `claim` hands over leased jobs and `record` takes back outcomes.\n * The runner owns the rest: turning each send result into an outcome with a\n * retry time, jittered backoff, the deferral cap, and never throwing for one\n * job's failure. The notifier's push and email channels run on it, and so do\n * genesis-forms' destinations (Sheets, webhooks), each with its own claim.\n *\n * Outcomes:\n * - `sent`: delivered (or already there, on a redelivery: `alreadyThere`).\n * - `filtered`: the sender decided it doesn't apply; nothing sent, nothing to retry.\n * - `skipped`: deliberately not sent (`notSent`: a reason safe to store); never retried.\n * - `retry`: a retryable failure. With the service's own Retry-After it is\n * deferred without counting an attempt (`counted: false`), until\n * `maxDeferrals`; otherwise it backs off by attempt (`counted: true`), until\n * `maxAttempts`.\n * - `failed`: permanent, or out of attempts. With `disable: true` the receiver\n * asked to be switched off (a 410 Gone): stop sending to it.\n *\n * It never logs content, addresses or secrets: only what `label` gives and\n * the senders' safe error messages.\n *\n * @packageDocumentation\n */\n\n/** One claimed job. Extend it with what your sender needs. */\nexport interface RunnerJob {\n /** Stable across retries (an idempotency key is made from it). */\n id: string;\n /** This attempt's number, from 1. */\n attempt: number;\n /** Deferrals so far (outcomes with `counted: false`); pass it back so `maxDeferrals` holds. Default 0. */\n deferrals?: number | undefined;\n /** An earlier attempt may have gone through (its lease ran out): senders that can look first do. */\n redelivery?: boolean | undefined;\n}\n\n/** What a sender says about one job. */\nexport type JobResult =\n | {\n ok: true;\n /** Deliberately sent nothing; the reason, safe to store. Recorded as `skipped`. */\n notSent?: string | undefined;\n /** It was already there (a redelivery), so nothing was sent this time. */\n alreadyThere?: boolean | undefined;\n }\n | JobFailure;\n\nexport interface JobFailure {\n ok: false;\n /** The same request may succeed later (rate limited, the service down, a timeout). */\n retryable: boolean;\n /** The service said when to come back: retry after this many seconds, without counting an attempt. */\n retryAfterSeconds?: number | undefined;\n status?: number | undefined;\n /** The receiver asked to be switched off. Always with `retryable: false`. */\n disable?: true | undefined;\n /** Safe to store and log: never secrets, content or addresses. */\n error: string;\n}\n\nexport type JobOutcome =\n | { status: \"sent\"; alreadyThere?: boolean }\n | { status: \"filtered\" }\n | { status: \"skipped\"; reason: string }\n | {\n status: \"retry\";\n error: string;\n retryAt: Date;\n retryAfterSeconds: number;\n /** Whether this attempt counts toward `maxAttempts`. False when the service said when to come back. */\n counted: boolean;\n httpStatus?: number;\n }\n | { status: \"failed\"; error: string; httpStatus?: number; disable?: true };\n\nexport interface RunReport {\n claimed: number;\n sent: number;\n filtered: number;\n skipped: number;\n /** Retryable failures, backed off by attempt. */\n retrying: number;\n /** Retryable failures the service said when to retry; no attempt used. */\n deferred: number;\n failed: number;\n /** Recorded after the claim was lost (`record` resolved false). */\n stale: number;\n /** `record` threw. */\n unrecorded: number;\n}\n\nexport interface ClaimRequest<Filter> {\n limit: number;\n filter?: Filter | undefined;\n}\n\nexport interface SendContext {\n signal?: AbortSignal | undefined;\n}\n\nexport interface RunnerOptions<J extends RunnerJob, Filter = undefined> {\n /** Claims up to `limit` due jobs, each leased so no other runner sends it meanwhile. */\n claim(request: ClaimRequest<Filter>): Promise<readonly J[]>;\n /**\n * Sends one group of jobs (those with the same `group` key) and resolves one\n * result per job, in order, or `\"filtered\"`. A throw fails the whole group\n * with a retryable error.\n */\n send(group: readonly J[], context: SendContext): Promise<readonly (JobResult | \"filtered\")[]>;\n /** Jobs with the same key are sent together. Default: each job alone. */\n group?: ((job: J) => string) | undefined;\n /**\n * Records an outcome. Resolve `false` when the claim was no longer held: it\n * is counted as stale. A rejection is counted as unrecorded; the lease runs\n * out and the job comes back on its own.\n */\n record(job: J, outcome: JobOutcome): Promise<void | boolean>;\n now?: (() => number) | undefined;\n /** Safe lines (ids, kinds, short reasons). Default: nothing is logged. */\n log?: ((message: string) => void) | undefined;\n /** How a job is named in a log line, capitalised (\"Delivery d1 (email)\"). Default `Job <id>`. */\n label?: ((job: J) => string) | undefined;\n /** How a job is named when recording it failed (\"delivery d1\"). Default `job <id>`. */\n recordLabel?: ((job: J) => string) | undefined;\n /** Jobs claimed per run. Default 25. */\n batchSize?: number | undefined;\n /** Counted attempts before a retryable failure is given up. Default 8. */\n maxAttempts?: number | undefined;\n /** Deferrals allowed before a further one counts as an attempt. Default 24. */\n maxDeferrals?: number | undefined;\n /** Seconds to wait after a counted failed attempt. Default `defaultBackoff`. */\n backoff?: ((attempt: number) => number) | undefined;\n}\n\nexport interface RunOptions<Filter> {\n filter?: Filter | undefined;\n /** Overrides `batchSize` for this run. */\n limit?: number | undefined;\n /** Aborts the sends in flight. */\n signal?: AbortSignal | undefined;\n}\n\nexport interface Runner<Filter = undefined> {\n /** One claim, its sends and their records. Never rejects for a job's failure; a failing `claim` rejects. */\n run(options?: RunOptions<Filter>): Promise<RunReport>;\n}\n\nexport const DEFAULT_MAX_ATTEMPTS = 8;\nexport const DEFAULT_MAX_DEFERRALS = 24;\nexport const DEFAULT_BATCH_SIZE = 25;\n\n/**\n * 5 minutes, quadrupling each attempt, at most 24 hours: 5m, 20m, 80m, 5h20m,\n * 21h20m, then 24h; about 3 days across 8 attempts. Each wait is jittered by\n * up to ±20%, so jobs that failed together don't all come back at once.\n */\nexport function defaultBackoff(attempt: number, random?: () => number): number {\n const nominal = Math.min(24 * 3600, 300 * 4 ** Math.max(0, attempt - 1));\n // A function only: `[1, 2].map(defaultBackoff)` passes an index here.\n const r = typeof random === \"function\" ? random() : Math.random();\n return Math.round(nominal * (0.8 + 0.4 * Math.min(1, Math.max(0, r))));\n}\n\n/** Turns a send result into an outcome for a job on its `attempt`. */\nexport function jobOutcome(\n result: JobResult,\n attempt: number,\n options: {\n now?: number | undefined;\n maxAttempts?: number | undefined;\n backoff?: ((attempt: number) => number) | undefined;\n deferrals?: number | undefined;\n maxDeferrals?: number | undefined;\n } = {},\n): JobOutcome {\n if (result.ok) {\n if (result.notSent) return { status: \"skipped\", reason: result.notSent.slice(0, 500) };\n return result.alreadyThere ? { status: \"sent\", alreadyThere: true } : { status: \"sent\" };\n }\n const http = result.status !== undefined ? { httpStatus: result.status } : {};\n if (result.disable) return { status: \"failed\", error: result.error, ...http, disable: true };\n if (!result.retryable) return { status: \"failed\", error: result.error, ...http };\n const now = options.now ?? Date.now();\n if (result.retryAfterSeconds !== undefined && (options.deferrals ?? 0) < (options.maxDeferrals ?? DEFAULT_MAX_DEFERRALS)) {\n const seconds = Math.max(1, Math.ceil(result.retryAfterSeconds));\n return { status: \"retry\", error: result.error, retryAt: new Date(now + seconds * 1000), retryAfterSeconds: seconds, counted: false, ...http };\n }\n const max = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n if (attempt >= max) return { status: \"failed\", error: `${result.error} (gave up after ${attempt} attempts)`.slice(0, 500), ...http };\n const seconds = Math.max(1, Math.ceil((options.backoff ?? defaultBackoff)(attempt)));\n return { status: \"retry\", error: result.error, retryAt: new Date(now + seconds * 1000), retryAfterSeconds: seconds, counted: true, ...http };\n}\n\n/** A thrown error as a retryable failure with a safe message. */\nexport function failureOf(error: unknown): JobFailure {\n const e = error as { name?: unknown; message?: unknown; retryable?: unknown; retryAfterSeconds?: unknown; status?: unknown; disable?: unknown } | null;\n if (e && typeof e === \"object\" && typeof e.retryable === \"boolean\" && typeof e.message === \"string\") {\n return {\n ok: false,\n retryable: e.disable === true ? false : e.retryable,\n error: e.message.slice(0, 500),\n ...(typeof e.retryAfterSeconds === \"number\" ? { retryAfterSeconds: e.retryAfterSeconds } : {}),\n ...(typeof e.status === \"number\" ? { status: e.status } : {}),\n ...(e.disable === true ? { disable: true as const } : {}),\n };\n }\n const timeout = e && typeof e === \"object\" && (e.name === \"TimeoutError\" || e.name === \"AbortError\");\n return { ok: false, retryable: true, error: timeout ? \"Timed out\" : \"Unexpected error\" };\n}\n\n/**\n * The runner.\n *\n * @stability Beta\n */\nexport function createRunner<J extends RunnerJob, Filter = undefined>(options: RunnerOptions<J, Filter>): Runner<Filter> {\n const log = (message: string): void => {\n try {\n options.log?.(message);\n } catch {\n // A logger that throws never stops an outcome being recorded.\n }\n };\n const label = (job: J) => options.label?.(job) ?? `Job ${job.id}`;\n const recordLabel = (job: J) => options.recordLabel?.(job) ?? `job ${job.id}`;\n const now = () => options.now?.() ?? Date.now();\n\n return {\n async run(runOptions: RunOptions<Filter> = {}): Promise<RunReport> {\n const report: RunReport = { claimed: 0, sent: 0, filtered: 0, skipped: 0, retrying: 0, deferred: 0, failed: 0, stale: 0, unrecorded: 0 };\n const limit = runOptions.limit ?? options.batchSize ?? DEFAULT_BATCH_SIZE;\n const claimed = await options.claim({ limit, filter: runOptions.filter });\n report.claimed = claimed.length;\n\n const groups = new Map<string, J[]>();\n claimed.forEach((job, i) => {\n const key = options.group ? options.group(job) : `\\u0000${i}`;\n const list = groups.get(key) ?? [];\n list.push(job);\n groups.set(key, list);\n });\n\n await Promise.all(\n [...groups.values()].map(async (group) => {\n let results: readonly (JobResult | \"filtered\")[];\n try {\n results = await options.send(group, { signal: runOptions.signal });\n if (results.length !== group.length) throw new Error(\"send answered the wrong number of results\");\n } catch (error) {\n const failure = failureOf(error);\n results = group.map(() => failure);\n }\n const at = now();\n await Promise.all(\n group.map(async (job, i) => {\n const result = results[i]!;\n const outcome: JobOutcome =\n result === \"filtered\"\n ? { status: \"filtered\" }\n : jobOutcome(result, job.attempt, {\n now: at,\n maxAttempts: options.maxAttempts,\n backoff: options.backoff,\n deferrals: job.deferrals,\n maxDeferrals: options.maxDeferrals,\n });\n if (outcome.status === \"failed\" || outcome.status === \"retry\") {\n log(`${label(job)} ${outcome.status === \"failed\" ? \"failed\" : \"will be retried\"}: ${outcome.error}`);\n } else if (outcome.status === \"skipped\") {\n log(`${label(job)} skipped: ${outcome.reason}`);\n }\n let recorded: void | boolean;\n try {\n recorded = await options.record(job, outcome);\n } catch {\n report.unrecorded++;\n log(`Recording ${recordLabel(job)} failed`);\n return;\n }\n if (recorded === false) report.stale++;\n else if (outcome.status === \"sent\") report.sent++;\n else if (outcome.status === \"filtered\") report.filtered++;\n else if (outcome.status === \"skipped\") report.skipped++;\n else if (outcome.status === \"failed\") report.failed++;\n else if (outcome.counted) report.retrying++;\n else report.deferred++;\n }),\n );\n }),\n );\n return report;\n },\n };\n}\n","/**\n * The outbox runner: claim a batch of due deliveries, send each to its\n * destination, and record what happened. The store is the app's (a SQL\n * outbox, a queue, a KV list): it hands over claimed deliveries and takes\n * back outcomes, and decides how claims and leases work. The runner owns the\n * rest: the destination's condition (`config.when`), batching deliveries to\n * one destination into one request where the destination can, keeping its\n * state, and turning each result into an outcome with a retry time.\n *\n * Outcomes:\n * - `sent`: delivered (or already there, on a redelivery).\n * - `filtered`: the submission doesn't match the destination's condition; nothing was sent, nothing to retry.\n * - `skipped`: the destination deliberately sent nothing (`notSent`); never retried.\n * - `retry`: a retryable failure. With the service's own Retry-After it is\n * deferred without counting an attempt (`counted: false`); otherwise it backs\n * off by attempt (`counted: true`), until `maxAttempts`.\n * - `failed`: permanent, an unknown kind, or out of attempts. With `disable:\n * true` the receiver asked to be switched off (a webhook's 410 Gone): the\n * app should disable the destination rather than keep sending to it.\n *\n * It never throws for a delivery's failure, and never logs answers, contact\n * details or secrets: only ids, kinds and the destinations' safe messages.\n *\n * It is genesis-notifications' runner (`createRunner` from\n * `@marktiderman/genesis-notifications/runner`, bundled into this build so\n * forms keeps no dependencies), with forms' claim, grouping by destination\n * and destinations as its sender.\n */\nimport {\n DEFAULT_BATCH_SIZE as SHARED_BATCH_SIZE,\n DEFAULT_MAX_ATTEMPTS as SHARED_MAX_ATTEMPTS,\n DEFAULT_MAX_DEFERRALS as SHARED_MAX_DEFERRALS,\n createRunner,\n defaultBackoff as sharedBackoff,\n jobOutcome,\n type JobOutcome,\n type JobResult,\n type RunReport,\n} from \"@marktiderman/genesis-notifications/runner\";\nimport type { FormDefinition, Json } from \"../types\";\nimport { passesCondition } from \"./condition\";\nimport {\n deliveryFailure,\n type DeliveryItem,\n type DeliveryResult,\n type DeliverySubmission,\n type Destination,\n type DestinationConfig,\n} from \"./types\";\n\n/** One claimed delivery, as the app's store hands it over. */\nexport interface ClaimedDelivery {\n /** The delivery's id: stable across its retries (the email idempotency key, the webhook-id). */\n id: string;\n /** The destination's id. Deliveries to one destination are batched, and its state is kept by it. */\n destinationId: string;\n /** The destination's kind: a key of `destinations`. */\n kind: string;\n /** The destination's config (no secrets). */\n config: DestinationConfig;\n /** What the destination cached last time (`DeliveryResult.state`), as stored. */\n state?: Record<string, Json> | undefined;\n submission: DeliverySubmission;\n definition: FormDefinition;\n /** This delivery's attempt number, from 1 for its first. */\n attempt: number;\n /**\n * How many times it was deferred so far (outcomes with `counted: false`).\n * Keep and pass it back, so `maxDeferrals` can stop a service that answers\n * \"try later\" forever. Default 0.\n */\n deferrals?: number | undefined;\n /**\n * An earlier attempt may have gone through (it was claimed before and timed\n * out, or its lease ran out), so destinations that can look first do.\n */\n redelivery?: boolean | undefined;\n /** An update of a submission delivered before (an edit). */\n update?: boolean | undefined;\n}\n\nexport type DeliveryOutcome =\n | {\n status: \"sent\";\n /** It was already there (a redelivery), so nothing was sent this time. */\n alreadyThere?: boolean;\n }\n | { status: \"filtered\" }\n | {\n status: \"skipped\";\n /** Why, safe to store. */\n reason: string;\n }\n | {\n status: \"retry\";\n error: string;\n /** When to try again. */\n retryAt: Date;\n retryAfterSeconds: number;\n /** Whether this attempt counts toward `maxAttempts`. False when the service said when to come back. */\n counted: boolean;\n httpStatus?: number;\n }\n | {\n status: \"failed\";\n error: string;\n httpStatus?: number;\n /** The receiver asked to be switched off (a webhook's 410 Gone): disable the destination. */\n disable?: true;\n };\n\nexport interface ClaimRequest<Filter> {\n /** Most deliveries to claim. */\n limit: number;\n /** What `run` was given: the app's own narrowing (one response, one account). */\n filter?: Filter | undefined;\n}\n\nexport interface DeliveryRunnerOptions<Filter = undefined> {\n /** Claims up to `limit` due deliveries, each held (leased) so no other runner sends it meanwhile. */\n claim(request: ClaimRequest<Filter>): Promise<readonly ClaimedDelivery[]>;\n /**\n * Records an outcome. Resolve `false` when the claim was no longer held\n * (its lease ran out and another runner took it): it is counted as stale.\n * A rejection is logged and counted as unrecorded; the lease then runs out\n * and the delivery comes back on its own.\n */\n record(delivery: ClaimedDelivery, outcome: DeliveryOutcome): Promise<void | boolean>;\n /** Keeps a destination's new state (a sheet's header and last row). Failures are logged, never fatal. */\n saveState?: ((destinationId: string, state: Record<string, Json>) => Promise<void>) | undefined;\n /** The destinations by kind. */\n destinations: Readonly<Record<string, Destination>>;\n now?: (() => number) | undefined;\n /** Safe lines (ids, kinds, short reasons). Default: nothing is logged. */\n log?: ((message: string) => void) | undefined;\n /** Deliveries claimed per run. Default 25. */\n batchSize?: number | undefined;\n /** Counted attempts before a retryable failure is given up. Default `DEFAULT_MAX_ATTEMPTS` (8). */\n maxAttempts?: number | undefined;\n /**\n * Deferrals (Retry-After, no attempt counted) allowed before a further one\n * counts as an attempt and backs off. Default `DEFAULT_MAX_DEFERRALS` (24).\n */\n maxDeferrals?: number | undefined;\n /** Seconds to wait after a counted failed attempt. Default `defaultBackoff`. */\n backoff?: ((attempt: number) => number) | undefined;\n}\n\nexport interface DeliveryReport {\n claimed: number;\n sent: number;\n filtered: number;\n skipped: number;\n /** Retryable failures, backed off by attempt. */\n retrying: number;\n /** Retryable failures the service said when to retry; no attempt used. */\n deferred: number;\n failed: number;\n /** Recorded after the claim was lost (`record` resolved false). */\n stale: number;\n /** `record` threw. */\n unrecorded: number;\n}\n\nexport interface RunOptions<Filter> {\n filter?: Filter | undefined;\n /** Overrides `batchSize` for this run. */\n limit?: number | undefined;\n /** Aborts the sends in flight; their outcomes are recorded as retries. */\n signal?: AbortSignal | undefined;\n}\n\nexport interface DeliveryRunner<Filter = undefined> {\n /** One claim, its sends and their records. Never rejects for a delivery's failure; a failing `claim` rejects. */\n run(options?: RunOptions<Filter>): Promise<DeliveryReport>;\n}\n\n// Declared here (with their types written out) so this build's types stand alone.\nexport const DEFAULT_MAX_ATTEMPTS: number = SHARED_MAX_ATTEMPTS;\nexport const DEFAULT_MAX_DEFERRALS: number = SHARED_MAX_DEFERRALS;\nexport const DEFAULT_BATCH_SIZE: number = SHARED_BATCH_SIZE;\n\n/**\n * 5 minutes, quadrupling each attempt, at most 24 hours: 5m, 20m, 80m, 5h20m,\n * 21h20m, then 24h. Across the default 8 attempts that is about 3 days, as\n * Standard Webhooks suggests. Each wait is jittered by up to ±20%, so\n * deliveries that failed together (a receiver's outage) don't all come back\n * at once. `random` (default `Math.random`) is for tests.\n */\nexport const defaultBackoff: (attempt: number, random?: () => number) => number = sharedBackoff;\n\n// The shared runner's outcome and report are these, field for field.\ntype Same<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false;\nconst sameOutcome: Same<DeliveryOutcome, JobOutcome> = true;\nconst sameReport: Same<DeliveryReport, RunReport> = true;\nvoid sameOutcome;\nvoid sameReport;\n\n/** Turns a destination's result into an outcome for a delivery on its `attempt`. */\nexport function deliveryOutcome(\n result: DeliveryResult,\n attempt: number,\n options: {\n now?: number | undefined;\n maxAttempts?: number | undefined;\n backoff?: ((attempt: number) => number) | undefined;\n /** Deferrals so far (`ClaimedDelivery.deferrals`). */\n deferrals?: number | undefined;\n maxDeferrals?: number | undefined;\n } = {},\n): DeliveryOutcome {\n return jobOutcome(result.ok ? { ok: true, notSent: result.notSent } : result, attempt, options);\n}\n\nexport function createDeliveryRunner<Filter = undefined>(options: DeliveryRunnerOptions<Filter>): DeliveryRunner<Filter> {\n // App code: a logger that throws must never stop an outcome being recorded.\n const log = (message: string): void => {\n try {\n options.log?.(message);\n } catch {\n // Ignored.\n }\n };\n\n /** Sends one destination's deliveries; resolves one result per delivery, in order. */\n async function send(group: readonly ClaimedDelivery[], signal: AbortSignal | undefined): Promise<(DeliveryResult | \"filtered\")[]> {\n const first = group[0]!;\n const destination = options.destinations[first.kind];\n if (!destination) {\n return group.map(() => ({ ok: false, retryable: false, error: `No destination for kind ${first.kind}` }));\n }\n // The condition first: a submission that doesn't match is never sent.\n const results: (DeliveryResult | \"filtered\" | null)[] = group.map((d) => {\n try {\n return passesCondition(d.submission, d.definition, d.config) ? null : \"filtered\";\n } catch (error) {\n return deliveryFailure(error);\n }\n });\n const due = group.filter((_, i) => results[i] === null);\n let state = first.state;\n const keep = (result: DeliveryResult) => {\n if (result.ok && result.state) state = result.state;\n };\n const guard = async (call: () => Promise<DeliveryResult>): Promise<DeliveryResult> => {\n try {\n return await call();\n } catch (error) {\n // Destinations never throw; an app-written one might.\n return deliveryFailure(error);\n }\n };\n const base = { state, signal, destinationId: first.destinationId };\n let sent: DeliveryResult[];\n if (due.length > 1 && destination.deliverBatch) {\n const items: DeliveryItem[] = due.map((d) => ({ submission: d.submission, definition: d.definition, deliveryId: d.id, update: d.update }));\n const result = await guard(() =>\n destination.deliverBatch!(items, first.config, { ...base, redelivery: due.some((d) => d.redelivery) }),\n );\n keep(result);\n sent = due.map(() => result);\n } else {\n sent = [];\n for (const d of due) {\n const result = await guard(() =>\n destination.deliver(d.submission, d.definition, d.config, {\n ...base,\n state,\n deliveryId: d.id,\n redelivery: d.redelivery,\n update: d.update,\n }),\n );\n keep(result);\n sent.push(result);\n }\n }\n if (state !== first.state && state && options.saveState) {\n try {\n await options.saveState(first.destinationId, state);\n } catch {\n log(`Saving destination ${first.destinationId}'s state failed`);\n }\n }\n let next = 0;\n return results.map((r) => r ?? sent[next++]!);\n }\n\n return createRunner<ClaimedDelivery, Filter>({\n claim: options.claim,\n // One group per destination: a sheet gets one append for all its rows.\n group: (delivery) => delivery.destinationId,\n async send(group, { signal }) {\n const results = await send(group, signal);\n return results.map((result, i): JobResult | \"filtered\" => {\n if (result === \"filtered\") return result;\n if (!result.ok) return result;\n return { ok: true, notSent: result.notSent, alreadyThere: result.skipped?.includes(group[i]!.submission.id) && !result.notSent };\n });\n },\n record: options.record,\n now: options.now,\n log: options.log,\n label: (delivery) => `Delivery ${delivery.id} (${delivery.kind})`,\n recordLabel: (delivery) => `delivery ${delivery.id}`,\n batchSize: options.batchSize,\n maxAttempts: options.maxAttempts,\n maxDeferrals: options.maxDeferrals,\n backoff: options.backoff,\n });\n}\n"]}