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

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 (644) hide show
  1. package/CHANGELOG.md +345 -0
  2. package/README.md +45 -1402
  3. package/dist/actions/body/converters.d.ts +20 -0
  4. package/dist/actions/body/converters.js +57 -0
  5. package/dist/actions/body/converters.js.map +1 -0
  6. package/dist/actions/body/escapeHtml.d.ts +6 -0
  7. package/dist/actions/body/escapeHtml.js +14 -0
  8. package/dist/actions/body/escapeHtml.js.map +1 -0
  9. package/dist/actions/body/serializeBody.d.ts +55 -0
  10. package/dist/actions/body/serializeBody.js +78 -0
  11. package/dist/actions/body/serializeBody.js.map +1 -0
  12. package/dist/actions/body/serializeSlate.js +31 -0
  13. package/dist/actions/body/serializeSlate.js.map +1 -0
  14. package/dist/actions/body/textOfBody.d.ts +13 -0
  15. package/dist/actions/body/textOfBody.js +35 -0
  16. package/dist/actions/body/textOfBody.js.map +1 -0
  17. package/dist/actions/body/wildcards.d.ts +10 -0
  18. package/dist/actions/body/wildcards.js +33 -0
  19. package/dist/actions/body/wildcards.js.map +1 -0
  20. package/dist/actions/buildActionBlocks.js +22 -0
  21. package/dist/actions/buildActionBlocks.js.map +1 -0
  22. package/dist/actions/builtin/confirmation.js +52 -0
  23. package/dist/actions/builtin/confirmation.js.map +1 -0
  24. package/dist/actions/builtin/emailAction.d.ts +17 -0
  25. package/dist/actions/builtin/emailAction.js +83 -0
  26. package/dist/actions/builtin/emailAction.js.map +1 -0
  27. package/dist/actions/builtin/emailTeam.js +22 -0
  28. package/dist/actions/builtin/emailTeam.js.map +1 -0
  29. package/dist/actions/builtin/index.d.ts +22 -0
  30. package/dist/actions/builtin/index.js +27 -0
  31. package/dist/actions/builtin/index.js.map +1 -0
  32. package/dist/actions/builtin/signedWebhook.js +53 -0
  33. package/dist/actions/builtin/signedWebhook.js.map +1 -0
  34. package/dist/actions/defineAction.d.ts +37 -0
  35. package/dist/actions/defineAction.js +6 -0
  36. package/dist/actions/defineAction.js.map +1 -0
  37. package/dist/actions/dispatch.js +49 -0
  38. package/dist/actions/dispatch.js.map +1 -0
  39. package/dist/actions/emailRecipients.d.ts +12 -0
  40. package/dist/actions/emailRecipients.js +116 -0
  41. package/dist/actions/emailRecipients.js.map +1 -0
  42. package/dist/actions/fromAddresses.d.ts +21 -0
  43. package/dist/actions/fromAddresses.js +74 -0
  44. package/dist/actions/fromAddresses.js.map +1 -0
  45. package/dist/actions/registry.d.ts +17 -0
  46. package/dist/actions/registry.js +12 -0
  47. package/dist/actions/registry.js.map +1 -0
  48. package/dist/actions/runActions.d.ts +9 -0
  49. package/dist/actions/runActions.js +43 -0
  50. package/dist/actions/runActions.js.map +1 -0
  51. package/dist/actions/sign.d.ts +7 -0
  52. package/dist/actions/sign.js +9 -0
  53. package/dist/actions/sign.js.map +1 -0
  54. package/dist/actions/task.js +87 -0
  55. package/dist/actions/task.js.map +1 -0
  56. package/dist/aggregation/aggregateResponses.d.ts +40 -0
  57. package/dist/aggregation/aggregateResponses.js +80 -0
  58. package/dist/aggregation/aggregateResponses.js.map +1 -0
  59. package/dist/aggregation/aggregateRows.d.ts +10 -0
  60. package/dist/aggregation/aggregateRows.js +64 -0
  61. package/dist/aggregation/aggregateRows.js.map +1 -0
  62. package/dist/aggregation/resolveResultsRequest.d.ts +61 -0
  63. package/dist/aggregation/resolveResultsRequest.js +113 -0
  64. package/dist/aggregation/resolveResultsRequest.js.map +1 -0
  65. package/dist/aggregation/types.d.ts +39 -0
  66. package/dist/calc/computeCalcFields.d.ts +15 -0
  67. package/dist/calc/computeCalcFields.js +28 -0
  68. package/dist/calc/computeCalcFields.js.map +1 -0
  69. package/dist/calc/evaluate.d.ts +8 -0
  70. package/dist/calc/evaluate.js +58 -0
  71. package/dist/calc/evaluate.js.map +1 -0
  72. package/dist/calc/normalizeCalc.d.ts +8 -0
  73. package/dist/calc/normalizeCalc.js +87 -0
  74. package/dist/calc/normalizeCalc.js.map +1 -0
  75. package/dist/calc/types.d.ts +34 -0
  76. package/dist/calc/types.js +22 -0
  77. package/dist/calc/types.js.map +1 -0
  78. package/dist/client/ByteSizeField.d.ts +29 -0
  79. package/dist/client/ByteSizeField.js +58 -0
  80. package/dist/client/ByteSizeField.js.map +1 -0
  81. package/dist/client/ClosePollButton.d.ts +15 -0
  82. package/dist/client/ClosePollButton.js +80 -0
  83. package/dist/client/ClosePollButton.js.map +1 -0
  84. package/dist/client/CondensedArray.d.ts +15 -0
  85. package/dist/client/CondensedArray.js +97 -0
  86. package/dist/client/CondensedArray.js.map +1 -0
  87. package/dist/client/ConditionBuilder.js +122 -0
  88. package/dist/client/ConditionBuilder.js.map +1 -0
  89. package/dist/client/ConditionRow.js +150 -0
  90. package/dist/client/ConditionRow.js.map +1 -0
  91. package/dist/client/ConsentBlockLabel.d.ts +15 -0
  92. package/dist/client/ConsentBlockLabel.js +71 -0
  93. package/dist/client/ConsentBlockLabel.js.map +1 -0
  94. package/dist/client/ConsentSourceRowLabel.d.ts +9 -0
  95. package/dist/client/ConsentSourceRowLabel.js +21 -0
  96. package/dist/client/ConsentSourceRowLabel.js.map +1 -0
  97. package/dist/client/EndpointOptionsSelect.d.ts +46 -0
  98. package/dist/client/EndpointOptionsSelect.js +106 -0
  99. package/dist/client/EndpointOptionsSelect.js.map +1 -0
  100. package/dist/client/FieldBlockLabel.d.ts +18 -0
  101. package/dist/client/FieldBlockLabel.js +34 -0
  102. package/dist/client/FieldBlockLabel.js.map +1 -0
  103. package/dist/client/FieldNameSelect.d.ts +37 -0
  104. package/dist/client/FieldNameSelect.js +72 -0
  105. package/dist/client/FieldNameSelect.js.map +1 -0
  106. package/dist/client/FlowBuilder.d.ts +15 -0
  107. package/dist/client/FlowBuilder.js +457 -0
  108. package/dist/client/FlowBuilder.js.map +1 -0
  109. package/dist/client/FormConditionField.d.ts +21 -0
  110. package/dist/client/FormConditionField.js +30 -0
  111. package/dist/client/FormConditionField.js.map +1 -0
  112. package/dist/client/RecipientsSelect.d.ts +31 -0
  113. package/dist/client/RecipientsSelect.js +174 -0
  114. package/dist/client/RecipientsSelect.js.map +1 -0
  115. package/dist/client/RuleDescription.d.ts +21 -0
  116. package/dist/client/RuleDescription.js +19 -0
  117. package/dist/client/RuleDescription.js.map +1 -0
  118. package/dist/client/admin.css +275 -0
  119. package/dist/client/endpointOptions.js +29 -0
  120. package/dist/client/endpointOptions.js.map +1 -0
  121. package/dist/client/flowAuthoring.js +142 -0
  122. package/dist/client/flowAuthoring.js.map +1 -0
  123. package/dist/client/synthesizeClientField.js +57 -0
  124. package/dist/client/synthesizeClientField.js.map +1 -0
  125. package/dist/client/toStaticLabel.js +13 -0
  126. package/dist/client/toStaticLabel.js.map +1 -0
  127. package/dist/collections/buttonFields.d.ts +34 -0
  128. package/dist/collections/buttonFields.js +35 -0
  129. package/dist/collections/buttonFields.js.map +1 -0
  130. package/dist/collections/cells/FieldCountCell.d.ts +15 -0
  131. package/dist/collections/cells/FieldCountCell.js +18 -0
  132. package/dist/collections/cells/FieldCountCell.js.map +1 -0
  133. package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
  134. package/dist/collections/cells/FlowStepsCell.js +17 -0
  135. package/dist/collections/cells/FlowStepsCell.js.map +1 -0
  136. package/dist/collections/formSubmissions.js +204 -0
  137. package/dist/collections/formSubmissions.js.map +1 -0
  138. package/dist/collections/forms.js +482 -0
  139. package/dist/collections/forms.js.map +1 -0
  140. package/dist/collections/formsEndpoints.js +101 -0
  141. package/dist/collections/formsEndpoints.js.map +1 -0
  142. package/dist/collections/redirectFields.d.ts +29 -0
  143. package/dist/conditions/conditionType.js +21 -0
  144. package/dist/conditions/conditionType.js.map +1 -0
  145. package/dist/conditions/evaluate.d.ts +17 -0
  146. package/dist/conditions/evaluate.js +94 -0
  147. package/dist/conditions/evaluate.js.map +1 -0
  148. package/dist/conditions/fieldTypes.d.ts +11 -0
  149. package/dist/{fieldTypes-CzhhJXjg.js → conditions/fieldTypes.js} +6 -3
  150. package/dist/conditions/fieldTypes.js.map +1 -0
  151. package/dist/conditions/normalizeConditions.js +61 -0
  152. package/dist/conditions/normalizeConditions.js.map +1 -0
  153. package/dist/conditions/types.d.ts +8 -0
  154. package/dist/consent/applyConsentStatements.d.ts +14 -0
  155. package/dist/consent/applyConsentStatements.js +17 -0
  156. package/dist/consent/applyConsentStatements.js.map +1 -0
  157. package/dist/consent/captureConsent.d.ts +55 -0
  158. package/dist/consent/captureConsent.js +73 -0
  159. package/dist/consent/captureConsent.js.map +1 -0
  160. package/dist/consent/consentSourcesField.d.ts +66 -0
  161. package/dist/consent/consentSourcesField.js +90 -0
  162. package/dist/consent/consentSourcesField.js.map +1 -0
  163. package/dist/consent/resolveConsentEntries.d.ts +24 -0
  164. package/dist/consent/resolveConsentEntries.js +40 -0
  165. package/dist/consent/resolveConsentEntries.js.map +1 -0
  166. package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
  167. package/dist/consent/resolveConsentSourcesRequest.js +54 -0
  168. package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
  169. package/dist/consent/resolveConsentStatements.d.ts +45 -0
  170. package/dist/consent/resolveConsentStatements.js +44 -0
  171. package/dist/consent/resolveConsentStatements.js.map +1 -0
  172. package/dist/consent/resolvePublishedVersionRef.d.ts +23 -0
  173. package/dist/consent/resolvePublishedVersionRef.js +30 -0
  174. package/dist/consent/resolvePublishedVersionRef.js.map +1 -0
  175. package/dist/consent/types.d.ts +61 -0
  176. package/dist/email/departments.d.ts +59 -0
  177. package/dist/email/departments.js +87 -0
  178. package/dist/email/departments.js.map +1 -0
  179. package/dist/email/departmentsField.d.ts +53 -0
  180. package/dist/email/departmentsField.js +73 -0
  181. package/dist/email/departmentsField.js.map +1 -0
  182. package/dist/events/noopSink.js +6 -0
  183. package/dist/events/noopSink.js.map +1 -0
  184. package/dist/events/resolveEventSink.js +8 -0
  185. package/dist/events/resolveEventSink.js.map +1 -0
  186. package/dist/events/types.d.ts +31 -0
  187. package/dist/exports/client.d.ts +15 -21
  188. package/dist/exports/client.js +15 -319
  189. package/dist/exports/i18n.d.ts +6 -138
  190. package/dist/exports/i18n.js +6 -3
  191. package/dist/exports/react.d.ts +63 -550
  192. package/dist/exports/react.js +55 -1563
  193. package/dist/exports/rsc.d.ts +9 -16
  194. package/dist/exports/rsc.js +9 -55
  195. package/dist/exports/types.d.ts +36 -5
  196. package/dist/fields/buildFieldBlocks.js +80 -0
  197. package/dist/fields/buildFieldBlocks.js.map +1 -0
  198. package/dist/fields/builtin/calculation.js +144 -0
  199. package/dist/fields/builtin/calculation.js.map +1 -0
  200. package/dist/fields/builtin/checkbox.js +21 -0
  201. package/dist/fields/builtin/checkbox.js.map +1 -0
  202. package/dist/fields/builtin/consent.js +47 -0
  203. package/dist/fields/builtin/consent.js.map +1 -0
  204. package/dist/fields/builtin/country.d.ts +13 -0
  205. package/dist/fields/builtin/country.js +30 -0
  206. package/dist/fields/builtin/country.js.map +1 -0
  207. package/dist/fields/builtin/date.js +31 -0
  208. package/dist/fields/builtin/date.js.map +1 -0
  209. package/dist/fields/builtin/email.js +18 -0
  210. package/dist/fields/builtin/email.js.map +1 -0
  211. package/dist/fields/builtin/file.d.ts +15 -0
  212. package/dist/fields/builtin/file.js +127 -0
  213. package/dist/fields/builtin/file.js.map +1 -0
  214. package/dist/fields/builtin/index.d.ts +26 -0
  215. package/dist/fields/builtin/index.js +49 -0
  216. package/dist/fields/builtin/index.js.map +1 -0
  217. package/dist/fields/builtin/message.js +30 -0
  218. package/dist/fields/builtin/message.js.map +1 -0
  219. package/dist/fields/builtin/number.js +17 -0
  220. package/dist/fields/builtin/number.js.map +1 -0
  221. package/dist/fields/builtin/repeater.js +49 -0
  222. package/dist/fields/builtin/repeater.js.map +1 -0
  223. package/dist/fields/builtin/select.js +49 -0
  224. package/dist/fields/builtin/select.js.map +1 -0
  225. package/dist/fields/builtin/state.d.ts +13 -0
  226. package/dist/fields/builtin/state.js +30 -0
  227. package/dist/fields/builtin/state.js.map +1 -0
  228. package/dist/fields/builtin/text.js +13 -0
  229. package/dist/fields/builtin/text.js.map +1 -0
  230. package/dist/fields/builtin/textarea.js +13 -0
  231. package/dist/fields/builtin/textarea.js.map +1 -0
  232. package/dist/fields/data/regions.d.ts +21 -0
  233. package/dist/fields/data/regions.js +1238 -0
  234. package/dist/fields/data/regions.js.map +1 -0
  235. package/dist/fields/defineFormField.d.ts +13 -0
  236. package/dist/fields/defineFormField.js +12 -0
  237. package/dist/fields/defineFormField.js.map +1 -0
  238. package/dist/fields/fieldKey.d.ts +15 -0
  239. package/dist/fields/fieldKey.js +16 -0
  240. package/dist/fields/fieldKey.js.map +1 -0
  241. package/dist/fields/fieldNamesOfType.js +30 -0
  242. package/dist/fields/fieldNamesOfType.js.map +1 -0
  243. package/dist/fields/instanceOptions.js +20 -0
  244. package/dist/fields/instanceOptions.js.map +1 -0
  245. package/dist/fields/localizedIf.d.ts +13 -0
  246. package/dist/fields/localizedIf.js +12 -0
  247. package/dist/fields/localizedIf.js.map +1 -0
  248. package/dist/fields/registry.d.ts +12 -0
  249. package/dist/fields/registry.js +39 -0
  250. package/dist/fields/registry.js.map +1 -0
  251. package/dist/fields/sharedConfig.js +151 -0
  252. package/dist/fields/sharedConfig.js.map +1 -0
  253. package/dist/fields/types.d.ts +152 -0
  254. package/dist/flow/engine.d.ts +19 -0
  255. package/dist/flow/engine.js +29 -0
  256. package/dist/flow/engine.js.map +1 -0
  257. package/dist/flow/normalizeFlow.js +54 -0
  258. package/dist/flow/normalizeFlow.js.map +1 -0
  259. package/dist/flow/stepLabel.js +15 -0
  260. package/dist/flow/stepLabel.js.map +1 -0
  261. package/dist/flow/types.d.ts +32 -0
  262. package/dist/flow/types.js +11 -0
  263. package/dist/flow/types.js.map +1 -0
  264. package/dist/form/pollState.d.ts +22 -0
  265. package/dist/form/pollState.js +17 -0
  266. package/dist/form/pollState.js.map +1 -0
  267. package/dist/form/toFormDocument.d.ts +102 -0
  268. package/dist/form/toFormDocument.js +87 -0
  269. package/dist/form/toFormDocument.js.map +1 -0
  270. package/dist/form/types.d.ts +65 -0
  271. package/dist/index.d.ts +88 -4
  272. package/dist/index.js +111 -1898
  273. package/dist/index.js.map +1 -1
  274. package/dist/options.d.ts +229 -0
  275. package/dist/plugin/access.js +12 -0
  276. package/dist/plugin/access.js.map +1 -0
  277. package/dist/plugin/applyRegistryConfig.d.ts +11 -0
  278. package/dist/plugin/applyRegistryConfig.js +20 -0
  279. package/dist/plugin/applyRegistryConfig.js.map +1 -0
  280. package/dist/plugin/collectionOverrides.d.ts +22 -0
  281. package/dist/plugin/customState.js +26 -0
  282. package/dist/plugin/customState.js.map +1 -0
  283. package/dist/plugin/registerCollections.js +60 -0
  284. package/dist/plugin/registerCollections.js.map +1 -0
  285. package/dist/plugin/registerTranslations.js +19 -0
  286. package/dist/plugin/registerTranslations.js.map +1 -0
  287. package/dist/plugin/uploadsCollection.d.ts +16 -0
  288. package/dist/plugin/uploadsCollection.js +53 -0
  289. package/dist/plugin/uploadsCollection.js.map +1 -0
  290. package/dist/poll/applyPollOptions.js +18 -0
  291. package/dist/poll/applyPollOptions.js.map +1 -0
  292. package/dist/poll/buildPollOptionSourceFields.js +50 -0
  293. package/dist/poll/buildPollOptionSourceFields.js.map +1 -0
  294. package/dist/poll/closeJob.d.ts +52 -0
  295. package/dist/poll/closeJob.js +119 -0
  296. package/dist/poll/closeJob.js.map +1 -0
  297. package/dist/poll/definePollOptionSource.d.ts +44 -0
  298. package/dist/poll/definePollOptionSource.js +6 -0
  299. package/dist/poll/definePollOptionSource.js.map +1 -0
  300. package/dist/poll/definePollType.d.ts +34 -0
  301. package/dist/poll/definePollType.js +6 -0
  302. package/dist/poll/definePollType.js.map +1 -0
  303. package/dist/poll/effectivePollOptions.d.ts +38 -0
  304. package/dist/poll/effectivePollOptions.js +64 -0
  305. package/dist/poll/effectivePollOptions.js.map +1 -0
  306. package/dist/poll/mostVoted.d.ts +21 -0
  307. package/dist/poll/mostVoted.js +32 -0
  308. package/dist/poll/mostVoted.js.map +1 -0
  309. package/dist/poll/outcomeBeforeChange.js +91 -0
  310. package/dist/poll/outcomeBeforeChange.js.map +1 -0
  311. package/dist/poll/outcomeFields.d.ts +38 -0
  312. package/dist/poll/outcomeFields.js +52 -0
  313. package/dist/poll/outcomeFields.js.map +1 -0
  314. package/dist/poll/pollTypeRegistry.d.ts +34 -0
  315. package/dist/poll/pollTypeRegistry.js +69 -0
  316. package/dist/poll/pollTypeRegistry.js.map +1 -0
  317. package/dist/poll/registry.d.ts +17 -0
  318. package/dist/poll/registry.js +12 -0
  319. package/dist/poll/registry.js.map +1 -0
  320. package/dist/poll/resolvePollCloseRequest.js +105 -0
  321. package/dist/poll/resolvePollCloseRequest.js.map +1 -0
  322. package/dist/poll/resolvePollOptions.d.ts +29 -0
  323. package/dist/poll/resolvePollOptions.js +52 -0
  324. package/dist/poll/resolvePollOptions.js.map +1 -0
  325. package/dist/poll/resolvePollOptionsRequest.js +50 -0
  326. package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
  327. package/dist/poll/resolvePollOutcome.d.ts +34 -0
  328. package/dist/poll/resolvePollOutcome.js +76 -0
  329. package/dist/poll/resolvePollOutcome.js.map +1 -0
  330. package/dist/poll/resultsField.js +21 -0
  331. package/dist/poll/resultsField.js.map +1 -0
  332. package/dist/prefill/valuesFromSearchParams.d.ts +18 -0
  333. package/dist/prefill/valuesFromSearchParams.js +41 -0
  334. package/dist/prefill/valuesFromSearchParams.js.map +1 -0
  335. package/dist/presentations/defaults.d.ts +33 -0
  336. package/dist/presentations/defaults.js +35 -0
  337. package/dist/presentations/defaults.js.map +1 -0
  338. package/dist/presentations/types.d.ts +19 -0
  339. package/dist/react/Form.d.ts +128 -0
  340. package/dist/react/Form.js +619 -0
  341. package/dist/react/Form.js.map +1 -0
  342. package/dist/react/FormContext.d.ts +59 -0
  343. package/dist/react/FormContext.js +14 -0
  344. package/dist/react/FormContext.js.map +1 -0
  345. package/dist/react/FormControls.d.ts +55 -0
  346. package/dist/react/FormControls.js +56 -0
  347. package/dist/react/FormControls.js.map +1 -0
  348. package/dist/react/FormFields.d.ts +18 -0
  349. package/dist/react/FormFields.js +114 -0
  350. package/dist/react/FormFields.js.map +1 -0
  351. package/dist/react/FormLayout.d.ts +22 -0
  352. package/dist/react/FormLayout.js +15 -0
  353. package/dist/react/FormLayout.js.map +1 -0
  354. package/dist/react/FormResults.d.ts +28 -0
  355. package/dist/react/FormResults.js +93 -0
  356. package/dist/react/FormResults.js.map +1 -0
  357. package/dist/react/FormSteps.d.ts +17 -0
  358. package/dist/react/FormSteps.js +35 -0
  359. package/dist/react/FormSteps.js.map +1 -0
  360. package/dist/react/Honeypot.d.ts +22 -0
  361. package/dist/react/Honeypot.js +38 -0
  362. package/dist/react/Honeypot.js.map +1 -0
  363. package/dist/react/Poll.d.ts +43 -0
  364. package/dist/react/Poll.js +135 -0
  365. package/dist/react/Poll.js.map +1 -0
  366. package/dist/react/captcha/HcaptchaCaptcha.d.ts +28 -0
  367. package/dist/react/captcha/HcaptchaCaptcha.js +53 -0
  368. package/dist/react/captcha/HcaptchaCaptcha.js.map +1 -0
  369. package/dist/react/captcha/RecaptchaCaptcha.d.ts +41 -0
  370. package/dist/react/captcha/RecaptchaCaptcha.js +93 -0
  371. package/dist/react/captcha/RecaptchaCaptcha.js.map +1 -0
  372. package/dist/react/captcha/TurnstileCaptcha.d.ts +28 -0
  373. package/dist/react/captcha/TurnstileCaptcha.js +53 -0
  374. package/dist/react/captcha/TurnstileCaptcha.js.map +1 -0
  375. package/dist/react/captcha/types.d.ts +8 -0
  376. package/dist/react/captcha/useCaptchaScript.js +45 -0
  377. package/dist/react/captcha/useCaptchaScript.js.map +1 -0
  378. package/dist/react/captcha/vendors.js +8 -0
  379. package/dist/react/captcha/vendors.js.map +1 -0
  380. package/dist/react/cn.d.ts +6 -0
  381. package/dist/react/cn.js +8 -0
  382. package/dist/react/cn.js.map +1 -0
  383. package/dist/react/contract.d.ts +31 -0
  384. package/dist/react/contract.js +7 -0
  385. package/dist/react/contract.js.map +1 -0
  386. package/dist/react/events.js +14 -0
  387. package/dist/react/events.js.map +1 -0
  388. package/dist/react/fetchResults.d.ts +25 -0
  389. package/dist/react/fetchResults.js +31 -0
  390. package/dist/react/fetchResults.js.map +1 -0
  391. package/dist/react/presentation/Backdrop.d.ts +18 -0
  392. package/dist/react/presentation/Backdrop.js +14 -0
  393. package/dist/react/presentation/Backdrop.js.map +1 -0
  394. package/dist/react/presentation/DialogSurface.d.ts +35 -0
  395. package/dist/react/presentation/DialogSurface.js +53 -0
  396. package/dist/react/presentation/DialogSurface.js.map +1 -0
  397. package/dist/react/presentation/presentations.d.ts +7 -0
  398. package/dist/react/presentation/presentations.js +32 -0
  399. package/dist/react/presentation/presentations.js.map +1 -0
  400. package/dist/react/presentation/registry.d.ts +11 -0
  401. package/dist/react/presentation/registry.js +12 -0
  402. package/dist/react/presentation/registry.js.map +1 -0
  403. package/dist/react/presentation/types.d.ts +19 -0
  404. package/dist/react/presentation/useDismiss.d.ts +19 -0
  405. package/dist/react/presentation/useDismiss.js +33 -0
  406. package/dist/react/presentation/useDismiss.js.map +1 -0
  407. package/dist/react/presentation/useFocusTrap.d.ts +8 -0
  408. package/dist/react/presentation/useFocusTrap.js +35 -0
  409. package/dist/react/presentation/useFocusTrap.js.map +1 -0
  410. package/dist/react/presentation/useScrollLock.d.ts +6 -0
  411. package/dist/react/presentation/useScrollLock.js +18 -0
  412. package/dist/react/presentation/useScrollLock.js.map +1 -0
  413. package/dist/react/primitives/Checkbox.d.ts +28 -0
  414. package/dist/react/primitives/Checkbox.js +21 -0
  415. package/dist/react/primitives/Checkbox.js.map +1 -0
  416. package/dist/react/primitives/FieldShell.d.ts +29 -0
  417. package/dist/react/primitives/FieldShell.js +44 -0
  418. package/dist/react/primitives/FieldShell.js.map +1 -0
  419. package/dist/react/primitives/Input.d.ts +30 -0
  420. package/dist/react/primitives/Input.js +21 -0
  421. package/dist/react/primitives/Input.js.map +1 -0
  422. package/dist/react/primitives/Select.d.ts +34 -0
  423. package/dist/react/primitives/Select.js +26 -0
  424. package/dist/react/primitives/Select.js.map +1 -0
  425. package/dist/react/primitives/Textarea.d.ts +28 -0
  426. package/dist/react/primitives/Textarea.js +20 -0
  427. package/dist/react/primitives/Textarea.js.map +1 -0
  428. package/dist/react/recall.js +20 -0
  429. package/dist/react/recall.js.map +1 -0
  430. package/dist/react/registry.d.ts +16 -0
  431. package/dist/react/registry.js +16 -0
  432. package/dist/react/registry.js.map +1 -0
  433. package/dist/react/renderers/calculation.js +27 -0
  434. package/dist/react/renderers/calculation.js.map +1 -0
  435. package/dist/react/renderers/checkbox.js +32 -0
  436. package/dist/react/renderers/checkbox.js.map +1 -0
  437. package/dist/react/renderers/consent.js +97 -0
  438. package/dist/react/renderers/consent.js.map +1 -0
  439. package/dist/react/renderers/date.js +33 -0
  440. package/dist/react/renderers/date.js.map +1 -0
  441. package/dist/react/renderers/email.js +34 -0
  442. package/dist/react/renderers/email.js.map +1 -0
  443. package/dist/react/renderers/file.js +107 -0
  444. package/dist/react/renderers/file.js.map +1 -0
  445. package/dist/react/renderers/index.d.ts +8 -0
  446. package/dist/react/renderers/index.js +35 -0
  447. package/dist/react/renderers/index.js.map +1 -0
  448. package/dist/react/renderers/message.js +41 -0
  449. package/dist/react/renderers/message.js.map +1 -0
  450. package/dist/react/renderers/number.js +37 -0
  451. package/dist/react/renderers/number.js.map +1 -0
  452. package/dist/react/renderers/region.js +43 -0
  453. package/dist/react/renderers/region.js.map +1 -0
  454. package/dist/react/renderers/repeater.js +131 -0
  455. package/dist/react/renderers/repeater.js.map +1 -0
  456. package/dist/react/renderers/select.js +35 -0
  457. package/dist/react/renderers/select.js.map +1 -0
  458. package/dist/react/renderers/text.js +34 -0
  459. package/dist/react/renderers/text.js.map +1 -0
  460. package/dist/react/renderers/textarea.js +33 -0
  461. package/dist/react/renderers/textarea.js.map +1 -0
  462. package/dist/react/resolveForm.js +16 -0
  463. package/dist/react/resolveForm.js.map +1 -0
  464. package/dist/react/state.d.ts +52 -0
  465. package/dist/react/state.js +125 -0
  466. package/dist/react/state.js.map +1 -0
  467. package/dist/react/submitForm.d.ts +31 -0
  468. package/dist/react/submitForm.js +58 -0
  469. package/dist/react/submitForm.js.map +1 -0
  470. package/dist/react/uploadFile.d.ts +23 -0
  471. package/dist/react/uploadFile.js +39 -0
  472. package/dist/react/uploadFile.js.map +1 -0
  473. package/dist/react/useField.d.ts +13 -0
  474. package/dist/react/useField.js +49 -0
  475. package/dist/react/useField.js.map +1 -0
  476. package/dist/react/useFormState.d.ts +8 -0
  477. package/dist/react/useFormState.js +9 -0
  478. package/dist/react/useFormState.js.map +1 -0
  479. package/dist/react/useFormStep.d.ts +8 -0
  480. package/dist/react/useFormStep.js +9 -0
  481. package/dist/react/useFormStep.js.map +1 -0
  482. package/dist/react/validateField.js +27 -0
  483. package/dist/react/validateField.js.map +1 -0
  484. package/dist/recall/interpolate.d.ts +11 -0
  485. package/dist/recall/interpolate.js +17 -0
  486. package/dist/recall/interpolate.js.map +1 -0
  487. package/dist/recall/resolver.d.ts +22 -0
  488. package/dist/recall/resolver.js +48 -0
  489. package/dist/recall/resolver.js.map +1 -0
  490. package/dist/spam/captcha.d.ts +13 -0
  491. package/dist/spam/captcha.js +12 -0
  492. package/dist/spam/captcha.js.map +1 -0
  493. package/dist/spam/clientIp.js +9 -0
  494. package/dist/spam/clientIp.js.map +1 -0
  495. package/dist/spam/constants.d.ts +12 -0
  496. package/dist/spam/constants.js +21 -0
  497. package/dist/spam/constants.js.map +1 -0
  498. package/dist/spam/identify.d.ts +12 -0
  499. package/dist/spam/identify.js +17 -0
  500. package/dist/spam/identify.js.map +1 -0
  501. package/dist/spam/providers/hcaptcha.d.ts +17 -0
  502. package/dist/spam/providers/hcaptcha.js +18 -0
  503. package/dist/spam/providers/hcaptcha.js.map +1 -0
  504. package/dist/spam/providers/recaptcha.d.ts +23 -0
  505. package/dist/spam/providers/recaptcha.js +23 -0
  506. package/dist/spam/providers/recaptcha.js.map +1 -0
  507. package/dist/spam/providers/siteverify.js +34 -0
  508. package/dist/spam/providers/siteverify.js.map +1 -0
  509. package/dist/spam/providers/turnstile.d.ts +17 -0
  510. package/dist/spam/providers/turnstile.js +18 -0
  511. package/dist/spam/providers/turnstile.js.map +1 -0
  512. package/dist/spam/rateLimiter.d.ts +18 -0
  513. package/dist/spam/rateLimiter.js +41 -0
  514. package/dist/spam/rateLimiter.js.map +1 -0
  515. package/dist/spam/reserved.js +30 -0
  516. package/dist/spam/reserved.js.map +1 -0
  517. package/dist/spam/resolveSpam.d.ts +12 -0
  518. package/dist/spam/resolveSpam.js +43 -0
  519. package/dist/spam/resolveSpam.js.map +1 -0
  520. package/dist/spam/spamGuard.js +81 -0
  521. package/dist/spam/spamGuard.js.map +1 -0
  522. package/dist/spam/types.d.ts +88 -0
  523. package/dist/spam/uploadHooks.js +33 -0
  524. package/dist/spam/uploadHooks.js.map +1 -0
  525. package/dist/submissions/SubmissionAnswers.d.ts +14 -0
  526. package/dist/submissions/SubmissionAnswers.js +137 -0
  527. package/dist/submissions/SubmissionAnswers.js.map +1 -0
  528. package/dist/submissions/SubmissionAnswersClient.js +178 -0
  529. package/dist/submissions/SubmissionAnswersClient.js.map +1 -0
  530. package/dist/submissions/coerceBoolean.js +14 -0
  531. package/dist/submissions/coerceBoolean.js.map +1 -0
  532. package/dist/submissions/createSubmission.d.ts +36 -0
  533. package/dist/submissions/createSubmission.js +26 -0
  534. package/dist/submissions/createSubmission.js.map +1 -0
  535. package/dist/submissions/runSubmission.d.ts +10 -0
  536. package/dist/submissions/runSubmission.js +306 -0
  537. package/dist/submissions/runSubmission.js.map +1 -0
  538. package/dist/submissions/types.d.ts +41 -0
  539. package/dist/submissions/validateSubmission.js +110 -0
  540. package/dist/submissions/validateSubmission.js.map +1 -0
  541. package/dist/submissions/votedCookie.d.ts +13 -0
  542. package/dist/submissions/votedCookie.js +27 -0
  543. package/dist/submissions/votedCookie.js.map +1 -0
  544. package/dist/translations/clientRuntimeKeys.d.ts +17 -0
  545. package/dist/translations/clientRuntimeKeys.js +46 -0
  546. package/dist/translations/clientRuntimeKeys.js.map +1 -0
  547. package/dist/translations/de.d.ts +12 -0
  548. package/dist/translations/de.js +309 -0
  549. package/dist/translations/de.js.map +1 -0
  550. package/dist/translations/en.d.ts +12 -0
  551. package/dist/translations/en.js +309 -0
  552. package/dist/translations/en.js.map +1 -0
  553. package/dist/translations/index.d.ts +23 -0
  554. package/dist/translations/index.js +37 -0
  555. package/dist/translations/index.js.map +1 -0
  556. package/dist/translations/keys.d.ts +308 -0
  557. package/dist/translations/keys.js +308 -0
  558. package/dist/translations/keys.js.map +1 -0
  559. package/dist/translations/makeTranslate.d.ts +15 -0
  560. package/dist/translations/makeTranslate.js +20 -0
  561. package/dist/translations/makeTranslate.js.map +1 -0
  562. package/dist/translations/server.js +32 -0
  563. package/dist/translations/server.js.map +1 -0
  564. package/dist/translations/useTranslation.js +12 -0
  565. package/dist/translations/useTranslation.js.map +1 -0
  566. package/dist/uploads/captureFileRef.d.ts +34 -0
  567. package/dist/uploads/captureFileRef.js +43 -0
  568. package/dist/uploads/captureFileRef.js.map +1 -0
  569. package/dist/uploads/formatBytes.d.ts +9 -0
  570. package/dist/uploads/formatBytes.js +25 -0
  571. package/dist/uploads/formatBytes.js.map +1 -0
  572. package/dist/uploads/resolveFileRef.d.ts +26 -0
  573. package/dist/uploads/resolveFileRef.js +45 -0
  574. package/dist/uploads/resolveFileRef.js.map +1 -0
  575. package/dist/uploads/types.d.ts +19 -0
  576. package/dist/validation/buildRuleBlocks.js +47 -0
  577. package/dist/validation/buildRuleBlocks.js.map +1 -0
  578. package/dist/validation/builtin/email.js +20 -0
  579. package/dist/validation/builtin/email.js.map +1 -0
  580. package/dist/validation/builtin/index.d.ts +14 -0
  581. package/dist/validation/builtin/index.js +38 -0
  582. package/dist/validation/builtin/index.js.map +1 -0
  583. package/dist/validation/builtin/matchesField.js +16 -0
  584. package/dist/validation/builtin/matchesField.js.map +1 -0
  585. package/dist/validation/builtin/max.js +22 -0
  586. package/dist/validation/builtin/max.js.map +1 -0
  587. package/dist/validation/builtin/maxDate.js +24 -0
  588. package/dist/validation/builtin/maxDate.js.map +1 -0
  589. package/dist/validation/builtin/maxLength.js +27 -0
  590. package/dist/validation/builtin/maxLength.js.map +1 -0
  591. package/dist/validation/builtin/min.js +22 -0
  592. package/dist/validation/builtin/min.js.map +1 -0
  593. package/dist/validation/builtin/minDate.js +24 -0
  594. package/dist/validation/builtin/minDate.js.map +1 -0
  595. package/dist/validation/builtin/minLength.js +27 -0
  596. package/dist/validation/builtin/minLength.js.map +1 -0
  597. package/dist/validation/builtin/notAlreadySubmitted.js +34 -0
  598. package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -0
  599. package/dist/validation/builtin/oneOf.js +35 -0
  600. package/dist/validation/builtin/oneOf.js.map +1 -0
  601. package/dist/validation/builtin/pattern.js +50 -0
  602. package/dist/validation/builtin/pattern.js.map +1 -0
  603. package/dist/validation/builtin/url.js +23 -0
  604. package/dist/validation/builtin/url.js.map +1 -0
  605. package/dist/validation/builtin/validateDateBound.js +18 -0
  606. package/dist/validation/builtin/validateDateBound.js.map +1 -0
  607. package/dist/validation/builtin/validateRegexParams.js +44 -0
  608. package/dist/validation/builtin/validateRegexParams.js.map +1 -0
  609. package/dist/validation/defineValidationRule.d.ts +12 -0
  610. package/dist/validation/defineValidationRule.js +11 -0
  611. package/dist/validation/defineValidationRule.js.map +1 -0
  612. package/dist/validation/emailPattern.js +10 -0
  613. package/dist/validation/emailPattern.js.map +1 -0
  614. package/dist/validation/fieldTargetParam.d.ts +22 -0
  615. package/dist/validation/fieldTargetParam.js +38 -0
  616. package/dist/validation/fieldTargetParam.js.map +1 -0
  617. package/dist/validation/message.js +14 -0
  618. package/dist/validation/message.js.map +1 -0
  619. package/dist/validation/registry.d.ts +11 -0
  620. package/dist/validation/registry.js +13 -0
  621. package/dist/validation/registry.js.map +1 -0
  622. package/dist/validation/runValidation.js +90 -0
  623. package/dist/validation/runValidation.js.map +1 -0
  624. package/dist/validation/types.d.ts +70 -0
  625. package/dist/validation/validateUrl.js +22 -0
  626. package/dist/validation/validateUrl.js.map +1 -0
  627. package/package.json +12 -7
  628. package/styles/form-builder.css +21 -11
  629. package/dist/constants-B-BUfetP.d.ts +0 -288
  630. package/dist/exports/client.js.map +0 -1
  631. package/dist/exports/react.js.map +0 -1
  632. package/dist/exports/rsc.js.map +0 -1
  633. package/dist/fieldTypes-B8jkNRob.d.ts +0 -188
  634. package/dist/fieldTypes-CzhhJXjg.js.map +0 -1
  635. package/dist/index-DfFYGbVF.d.ts +0 -481
  636. package/dist/keys-N5xGiUsh.js +0 -132
  637. package/dist/keys-N5xGiUsh.js.map +0 -1
  638. package/dist/registry-CoCyhtvB.js +0 -282
  639. package/dist/registry-CoCyhtvB.js.map +0 -1
  640. package/dist/resolver-OeQyVH2N.js +0 -665
  641. package/dist/resolver-OeQyVH2N.js.map +0 -1
  642. package/dist/translations-edMqq_2e.js +0 -152
  643. package/dist/translations-edMqq_2e.js.map +0 -1
  644. package/dist/types-DsJ_6kGJ.d.ts +0 -23
@@ -0,0 +1 @@
1
+ {"version":3,"file":"captureConsent.js","names":[],"sources":["../../src/consent/captureConsent.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\nimport type { Payload, PayloadRequest } from 'payload'\nimport { hasDraftsEnabled } from 'payload/shared'\nimport { textOfBody } from '../actions/body/textOfBody'\nimport type { FormFieldInstance } from '../submissions/types'\nimport { resolvePublishedVersionRef } from './resolvePublishedVersionRef'\nimport type { ConsentSourceEntry, ConsentSourcePage } from './types'\n\n/** What a submission snapshots of the agreed wording. `'hash'` and `'text'` combine as `'both'`. */\nexport type ConsentSnapshotMode = 'hash' | 'text' | 'both' | false\n\nexport type ConsentProof = {\n\tagreed: boolean\n\t/** The source `id` the field referenced; empty when the author never picked one. */\n\tsource: string\n\tpage?: ConsentSourcePage\n\tversionRef?: string\n\t/** The source label at submit time, so an audit names the statement even after a rename or delete. */\n\tname?: string\n\t/** sha256 of the statement plain text agreed to: tamper-evident and PII-free. */\n\tstatementHash?: string\n\t/** Plain-text snapshot of the statement agreed to, for a human-readable audit. */\n\tstatementText?: string\n\tat: string\n}\n\n/**\n * The authoritative consent proof, built at submit time from the server's own view of the source\n * (the field carries an id, never a statement, so there is nothing here the client could forge).\n *\n * Proof is id-based on purpose: it records which document was agreed to, so renaming, re-slugging,\n * or re-routing the policy leaves every past proof intact and resolvable. `snapshot` additionally\n * captures the agreed wording (a `statementHash`, the plain `statementText`, or both) plus the source\n * `name`, so an audit shows exactly what was agreed to independent of later edits; `false` keeps the\n * lean id-only proof. The snapshot is captured in every branch, including a refusal and a page-less\n * source.\n *\n * Time-of-check/time-of-use: a visitor reads the wording resolved when the form loaded, but the\n * snapshot here is re-resolved from the source at submit. If the source text changed in that window,\n * the proof records the submit-time wording, not the exact bytes rendered earlier. This is\n * deliberate, the server's live view is authoritative and the window is one visitor session; a form\n * that must freeze the exact wording agreed to should version the source (drafts give a `versionRef`\n * pinning the published version, below).\n *\n * `versionRef` is recorded only when the page's collection has drafts enabled, and then it is the\n * published version document's own id. Versions without drafts get no `versionRef`, because there\n * is no published/draft distinction to pin to: `_status` only exists under drafts, so a\n * published-version lookup there matches nothing, and recording that as a version reference would\n * be inventing one. Absent means absent, in both cases.\n *\n * `now` is injected by the caller (`new Date().toISOString()`) for testability.\n */\nexport const captureConsent = async (args: {\n\tfield: FormFieldInstance\n\tagreed: boolean\n\t/** The host's resolved sources for this request (see `resolveConsentEntries`). */\n\tentries: ConsentSourceEntry[]\n\tpayload: Payload\n\treq?: PayloadRequest\n\tnow: string\n\t/** What to snapshot of the agreed wording (plugin option `consent.snapshot`); defaults to `'both'`. */\n\tsnapshot?: ConsentSnapshotMode\n}): Promise<ConsentProof> => {\n\tconst source = typeof args.field.source === 'string' ? args.field.source : ''\n\tconst entry = source ? args.entries.find((candidate) => candidate.id === source) : undefined\n\tconst snapshot = args.snapshot ?? 'both'\n\n\t// Capture the agreed wording (and the source label) onto every proof branch. Kept out of the two\n\t// returns so a refusal and a page-less source are snapshotted the same as the happy path.\n\tconst withSnapshot = (proof: ConsentProof): ConsentProof => {\n\t\tif (!entry || snapshot === false) {\n\t\t\treturn proof\n\t\t}\n\t\tif (typeof entry.name === 'string' && entry.name.trim().length > 0) {\n\t\t\tproof.name = entry.name.trim()\n\t\t}\n\t\tconst text = textOfBody(entry.statement)\n\t\tif (text.length > 0) {\n\t\t\tif (snapshot === 'hash' || snapshot === 'both') {\n\t\t\t\tproof.statementHash = createHash('sha256').update(text).digest('hex')\n\t\t\t}\n\t\t\tif (snapshot === 'text' || snapshot === 'both') {\n\t\t\t\tproof.statementText = text\n\t\t\t}\n\t\t}\n\t\treturn proof\n\t}\n\n\tconst page = entry?.page\n\tif (!page) {\n\t\treturn withSnapshot({ agreed: args.agreed, source, at: args.now })\n\t}\n\t// `page.relationTo` is a runtime string; cast the key so the lookup type-checks against a host's\n\t// narrowed collection map (a consumer's generated `CollectionSlug`) as well as the plugin's own\n\t// broad one. The value is still guarded below, since an unregistered slug resolves to undefined.\n\tconst collection = args.payload.collections[page.relationTo as keyof Payload['collections']]\n\tconst versionRef =\n\t\tcollection && hasDraftsEnabled(collection.config)\n\t\t\t? await resolvePublishedVersionRef({\n\t\t\t\t\tpayload: args.payload,\n\t\t\t\t\tcollection: page.relationTo,\n\t\t\t\t\tid: page.id,\n\t\t\t\t\treq: args.req,\n\t\t\t\t})\n\t\t\t: null\n\treturn withSnapshot({\n\t\tagreed: args.agreed,\n\t\tsource,\n\t\tpage: { relationTo: page.relationTo, id: page.id },\n\t\t...(versionRef ? { versionRef } : {}),\n\t\tat: args.now,\n\t})\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,MAAa,iBAAiB,OAAO,SAUR;CAC5B,MAAM,SAAS,OAAO,KAAK,MAAM,WAAW,WAAW,KAAK,MAAM,SAAS;CAC3E,MAAM,QAAQ,SAAS,KAAK,QAAQ,MAAM,cAAc,UAAU,OAAO,MAAM,IAAI,KAAA;CACnF,MAAM,WAAW,KAAK,YAAY;CAIlC,MAAM,gBAAgB,UAAsC;EAC3D,IAAI,CAAC,SAAS,aAAa,OAC1B,OAAO;EAER,IAAI,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,SAAS,GAChE,MAAM,OAAO,MAAM,KAAK,KAAK;EAE9B,MAAM,OAAO,WAAW,MAAM,SAAS;EACvC,IAAI,KAAK,SAAS,GAAG;GACpB,IAAI,aAAa,UAAU,aAAa,QACvC,MAAM,gBAAgB,WAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;GAErE,IAAI,aAAa,UAAU,aAAa,QACvC,MAAM,gBAAgB;EAExB;EACA,OAAO;CACR;CAEA,MAAM,OAAO,OAAO;CACpB,IAAI,CAAC,MACJ,OAAO,aAAa;EAAE,QAAQ,KAAK;EAAQ;EAAQ,IAAI,KAAK;CAAI,CAAC;CAKlE,MAAM,aAAa,KAAK,QAAQ,YAAY,KAAK;CACjD,MAAM,aACL,cAAc,iBAAiB,WAAW,MAAM,IAC7C,MAAM,2BAA2B;EACjC,SAAS,KAAK;EACd,YAAY,KAAK;EACjB,IAAI,KAAK;EACT,KAAK,KAAK;CACX,CAAC,IACA;CACJ,OAAO,aAAa;EACnB,QAAQ,KAAK;EACb;EACA,MAAM;GAAE,YAAY,KAAK;GAAY,IAAI,KAAK;EAAG;EACjD,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;EACnC,IAAI,KAAK;CACV,CAAC;AACF"}
@@ -0,0 +1,66 @@
1
+ import { ArrayField, CollectionSlug, RichTextField } from "payload";
2
+
3
+ //#region src/consent/consentSourcesField.d.ts
4
+ type ConsentSourcesFieldOptions = {
5
+ /** Field name, i.e. what the row array is stored under. Defaults to `consentSources`. */name?: string; /** Field label. Defaults to the plugin's translated one. */
6
+ label?: ArrayField['label'];
7
+ /**
8
+ * Collections whose documents can be picked as a source's policy page. Omitted (the default):
9
+ * no page picker at all, so sources are statement-only and their proofs carry no page or
10
+ * version reference. Always stored polymorphically, even for a single slug (see below).
11
+ */
12
+ relationTo?: CollectionSlug | CollectionSlug[];
13
+ /**
14
+ * Whether the visitor-facing `statement` and `name` carry `localized: true`. Default `true`;
15
+ * Payload strips the flag on hosts without `localization`, so it is safe either way. Mirrors
16
+ * the plugin's `localizeContent` option, which this host-called factory cannot see.
17
+ */
18
+ localized?: boolean; /** Overrides the project's default richText editor for the `statement`, as `richText.editor` does plugin-side. */
19
+ editor?: RichTextField['editor'];
20
+ };
21
+ /**
22
+ * The consent sources array, for the host to place on any collection or global they own: a
23
+ * settings global, a tenants collection, a legal-pages parent, wherever the sources belong. The
24
+ * plugin never registers it and never guesses where it lives; a matching `consent.sources` resolver
25
+ * reads it back (see {@link ConsentSourcesResolver}), which is also where multi-tenant scoping goes:
26
+ * place this on the tenant-scoped document and have the resolver return only the sources of the
27
+ * tenant it derives from `req`.
28
+ *
29
+ * A row is a `name` (shown when picking the source on a form, and used as the policy link text
30
+ * beside the statement), the `statement` the visitor agrees to, and optionally the `page` that
31
+ * statement belongs to. The stable reference a consent field stores, and the only part that must
32
+ * outlive edits, is the row's own auto-assigned `id`: it survives a `name` edit or reordering,
33
+ * unlike a hand-authored key would. Authors fill in no version, no URL, and no document id by
34
+ * hand: the version is detected and recorded at submit time, and the page is a picker.
35
+ *
36
+ * `page` is always polymorphic, even when `relationTo` names a single collection, because a
37
+ * monomorphic relationship stores a bare id: the proof needs the collection alongside it to stay
38
+ * resolvable, and a host adding a second collection later would otherwise change the stored shape.
39
+ *
40
+ * ```ts
41
+ * // The host's own collection or global:
42
+ * fields: [consentSourcesField({ relationTo: ['pages', 'legal-notices'] })]
43
+ *
44
+ * // The plugin, reading it back:
45
+ * formBuilder({
46
+ * consent: {
47
+ * sources: async ({ req }) => {
48
+ * const settings = await req.payload.findGlobal({ slug: 'settings', depth: 0, locale: req.locale, req })
49
+ * return (settings.consentSources ?? []).map((row) => ({ ... }))
50
+ * },
51
+ * },
52
+ * })
53
+ * ```
54
+ *
55
+ * The resolver receives the whole form document, so derive tenant scoping from a field on it rather
56
+ * than reading the form back: reading the `forms` collection from the resolver re-enters this form's
57
+ * afterRead hook (the plugin guards against the resulting recursion, but the read is still wasted).
58
+ *
59
+ * A resolver reading its settings document must not thread the save's `req` into a `locale: 'all'`
60
+ * read from within a form's save validation: that flips `req.locale` to `all` and corrupts the
61
+ * localized write of the document being saved. It reads already-committed data, so no `req` is needed.
62
+ */
63
+ declare const consentSourcesField: (options?: ConsentSourcesFieldOptions) => ArrayField;
64
+ //#endregion
65
+ export { ConsentSourcesFieldOptions, consentSourcesField };
66
+ //# sourceMappingURL=consentSourcesField.d.ts.map
@@ -0,0 +1,90 @@
1
+ import { keys } from "../translations/keys.js";
2
+ import { labelForKey } from "../translations/server.js";
3
+ import { localizedIf } from "../fields/localizedIf.js";
4
+ //#region src/consent/consentSourcesField.ts
5
+ /**
6
+ * The consent sources array, for the host to place on any collection or global they own: a
7
+ * settings global, a tenants collection, a legal-pages parent, wherever the sources belong. The
8
+ * plugin never registers it and never guesses where it lives; a matching `consent.sources` resolver
9
+ * reads it back (see {@link ConsentSourcesResolver}), which is also where multi-tenant scoping goes:
10
+ * place this on the tenant-scoped document and have the resolver return only the sources of the
11
+ * tenant it derives from `req`.
12
+ *
13
+ * A row is a `name` (shown when picking the source on a form, and used as the policy link text
14
+ * beside the statement), the `statement` the visitor agrees to, and optionally the `page` that
15
+ * statement belongs to. The stable reference a consent field stores, and the only part that must
16
+ * outlive edits, is the row's own auto-assigned `id`: it survives a `name` edit or reordering,
17
+ * unlike a hand-authored key would. Authors fill in no version, no URL, and no document id by
18
+ * hand: the version is detected and recorded at submit time, and the page is a picker.
19
+ *
20
+ * `page` is always polymorphic, even when `relationTo` names a single collection, because a
21
+ * monomorphic relationship stores a bare id: the proof needs the collection alongside it to stay
22
+ * resolvable, and a host adding a second collection later would otherwise change the stored shape.
23
+ *
24
+ * ```ts
25
+ * // The host's own collection or global:
26
+ * fields: [consentSourcesField({ relationTo: ['pages', 'legal-notices'] })]
27
+ *
28
+ * // The plugin, reading it back:
29
+ * formBuilder({
30
+ * consent: {
31
+ * sources: async ({ req }) => {
32
+ * const settings = await req.payload.findGlobal({ slug: 'settings', depth: 0, locale: req.locale, req })
33
+ * return (settings.consentSources ?? []).map((row) => ({ ... }))
34
+ * },
35
+ * },
36
+ * })
37
+ * ```
38
+ *
39
+ * The resolver receives the whole form document, so derive tenant scoping from a field on it rather
40
+ * than reading the form back: reading the `forms` collection from the resolver re-enters this form's
41
+ * afterRead hook (the plugin guards against the resulting recursion, but the read is still wasted).
42
+ *
43
+ * A resolver reading its settings document must not thread the save's `req` into a `locale: 'all'`
44
+ * read from within a form's save validation: that flips `req.locale` to `all` and corrupts the
45
+ * localized write of the document being saved. It reads already-committed data, so no `req` is needed.
46
+ */
47
+ const consentSourcesField = (options = {}) => {
48
+ const localize = options.localized !== false;
49
+ const relationTo = options.relationTo && (!Array.isArray(options.relationTo) || options.relationTo.length > 0) ? options.relationTo : void 0;
50
+ const pageField = relationTo ? [{
51
+ name: "page",
52
+ type: "relationship",
53
+ relationTo: Array.isArray(relationTo) ? relationTo : [relationTo],
54
+ label: labelForKey(keys.consentSourcePage),
55
+ admin: { description: labelForKey(keys.consentSourcePageDescription) }
56
+ }] : [];
57
+ return {
58
+ name: options.name ?? "consentSources",
59
+ type: "array",
60
+ label: options.label ?? labelForKey(keys.consentSourcesField),
61
+ labels: {
62
+ singular: labelForKey(keys.consentSourceSingular),
63
+ plural: labelForKey(keys.consentSourcePlural)
64
+ },
65
+ admin: {
66
+ description: labelForKey(keys.consentSourcesFieldDescription),
67
+ components: { RowLabel: "@10x-media/form-builder/client#ConsentSourceRowLabel" }
68
+ },
69
+ fields: [
70
+ {
71
+ name: "name",
72
+ type: "text",
73
+ label: labelForKey(keys.consentSourceLabel),
74
+ ...localizedIf(localize)
75
+ },
76
+ {
77
+ name: "statement",
78
+ type: "richText",
79
+ label: labelForKey(keys.consentSourceStatement),
80
+ ...options.editor ? { editor: options.editor } : {},
81
+ ...localizedIf(localize)
82
+ },
83
+ ...pageField
84
+ ]
85
+ };
86
+ };
87
+ //#endregion
88
+ export { consentSourcesField };
89
+
90
+ //# sourceMappingURL=consentSourcesField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consentSourcesField.js","names":[],"sources":["../../src/consent/consentSourcesField.ts"],"sourcesContent":["import type { ArrayField, CollectionSlug, Field, RichTextField } from 'payload'\nimport { localizedIf } from '../fields/localizedIf'\nimport { keys } from '../translations/keys'\nimport { labelForKey } from '../translations/server'\n\nexport type ConsentSourcesFieldOptions = {\n\t/** Field name, i.e. what the row array is stored under. Defaults to `consentSources`. */\n\tname?: string\n\t/** Field label. Defaults to the plugin's translated one. */\n\tlabel?: ArrayField['label']\n\t/**\n\t * Collections whose documents can be picked as a source's policy page. Omitted (the default):\n\t * no page picker at all, so sources are statement-only and their proofs carry no page or\n\t * version reference. Always stored polymorphically, even for a single slug (see below).\n\t */\n\trelationTo?: CollectionSlug | CollectionSlug[]\n\t/**\n\t * Whether the visitor-facing `statement` and `name` carry `localized: true`. Default `true`;\n\t * Payload strips the flag on hosts without `localization`, so it is safe either way. Mirrors\n\t * the plugin's `localizeContent` option, which this host-called factory cannot see.\n\t */\n\tlocalized?: boolean\n\t/** Overrides the project's default richText editor for the `statement`, as `richText.editor` does plugin-side. */\n\teditor?: RichTextField['editor']\n}\n\n/**\n * The consent sources array, for the host to place on any collection or global they own: a\n * settings global, a tenants collection, a legal-pages parent, wherever the sources belong. The\n * plugin never registers it and never guesses where it lives; a matching `consent.sources` resolver\n * reads it back (see {@link ConsentSourcesResolver}), which is also where multi-tenant scoping goes:\n * place this on the tenant-scoped document and have the resolver return only the sources of the\n * tenant it derives from `req`.\n *\n * A row is a `name` (shown when picking the source on a form, and used as the policy link text\n * beside the statement), the `statement` the visitor agrees to, and optionally the `page` that\n * statement belongs to. The stable reference a consent field stores, and the only part that must\n * outlive edits, is the row's own auto-assigned `id`: it survives a `name` edit or reordering,\n * unlike a hand-authored key would. Authors fill in no version, no URL, and no document id by\n * hand: the version is detected and recorded at submit time, and the page is a picker.\n *\n * `page` is always polymorphic, even when `relationTo` names a single collection, because a\n * monomorphic relationship stores a bare id: the proof needs the collection alongside it to stay\n * resolvable, and a host adding a second collection later would otherwise change the stored shape.\n *\n * ```ts\n * // The host's own collection or global:\n * fields: [consentSourcesField({ relationTo: ['pages', 'legal-notices'] })]\n *\n * // The plugin, reading it back:\n * formBuilder({\n * consent: {\n * sources: async ({ req }) => {\n * const settings = await req.payload.findGlobal({ slug: 'settings', depth: 0, locale: req.locale, req })\n * return (settings.consentSources ?? []).map((row) => ({ ... }))\n * },\n * },\n * })\n * ```\n *\n * The resolver receives the whole form document, so derive tenant scoping from a field on it rather\n * than reading the form back: reading the `forms` collection from the resolver re-enters this form's\n * afterRead hook (the plugin guards against the resulting recursion, but the read is still wasted).\n *\n * A resolver reading its settings document must not thread the save's `req` into a `locale: 'all'`\n * read from within a form's save validation: that flips `req.locale` to `all` and corrupts the\n * localized write of the document being saved. It reads already-committed data, so no `req` is needed.\n */\nexport const consentSourcesField = (options: ConsentSourcesFieldOptions = {}): ArrayField => {\n\tconst localize = options.localized !== false\n\t// An empty `relationTo` array is treated as \"no page picker\", not a relationship field pointing\n\t// at nothing (which Payload rejects at boot).\n\tconst relationTo =\n\t\toptions.relationTo && (!Array.isArray(options.relationTo) || options.relationTo.length > 0)\n\t\t\t? options.relationTo\n\t\t\t: undefined\n\tconst pageField: Field[] = relationTo\n\t\t? [\n\t\t\t\t{\n\t\t\t\t\tname: 'page',\n\t\t\t\t\ttype: 'relationship',\n\t\t\t\t\trelationTo: Array.isArray(relationTo) ? relationTo : [relationTo],\n\t\t\t\t\tlabel: labelForKey(keys.consentSourcePage),\n\t\t\t\t\tadmin: { description: labelForKey(keys.consentSourcePageDescription) },\n\t\t\t\t},\n\t\t\t]\n\t\t: []\n\n\treturn {\n\t\tname: options.name ?? 'consentSources',\n\t\ttype: 'array',\n\t\tlabel: options.label ?? labelForKey(keys.consentSourcesField),\n\t\tlabels: {\n\t\t\tsingular: labelForKey(keys.consentSourceSingular),\n\t\t\tplural: labelForKey(keys.consentSourcePlural),\n\t\t},\n\t\tadmin: {\n\t\t\tdescription: labelForKey(keys.consentSourcesFieldDescription),\n\t\t\tcomponents: { RowLabel: '@10x-media/form-builder/client#ConsentSourceRowLabel' },\n\t\t},\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelForKey(keys.consentSourceLabel),\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'statement',\n\t\t\t\ttype: 'richText',\n\t\t\t\tlabel: labelForKey(keys.consentSourceStatement),\n\t\t\t\t...(options.editor ? { editor: options.editor } : {}),\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t\t...pageField,\n\t\t],\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoEA,MAAa,uBAAuB,UAAsC,CAAC,MAAkB;CAC5F,MAAM,WAAW,QAAQ,cAAc;CAGvC,MAAM,aACL,QAAQ,eAAe,CAAC,MAAM,QAAQ,QAAQ,UAAU,KAAK,QAAQ,WAAW,SAAS,KACtF,QAAQ,aACR,KAAA;CACJ,MAAM,YAAqB,aACxB,CACA;EACC,MAAM;EACN,MAAM;EACN,YAAY,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;EAChE,OAAO,YAAY,KAAK,iBAAiB;EACzC,OAAO,EAAE,aAAa,YAAY,KAAK,4BAA4B,EAAE;CACtE,CACD,IACC,CAAC;CAEJ,OAAO;EACN,MAAM,QAAQ,QAAQ;EACtB,MAAM;EACN,OAAO,QAAQ,SAAS,YAAY,KAAK,mBAAmB;EAC5D,QAAQ;GACP,UAAU,YAAY,KAAK,qBAAqB;GAChD,QAAQ,YAAY,KAAK,mBAAmB;EAC7C;EACA,OAAO;GACN,aAAa,YAAY,KAAK,8BAA8B;GAC5D,YAAY,EAAE,UAAU,uDAAuD;EAChF;EACA,QAAQ;GACP;IACC,MAAM;IACN,MAAM;IACN,OAAO,YAAY,KAAK,kBAAkB;IAC1C,GAAG,YAAY,QAAQ;GACxB;GACA;IACC,MAAM;IACN,MAAM;IACN,OAAO,YAAY,KAAK,sBAAsB;IAC9C,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;IACnD,GAAG,YAAY,QAAQ;GACxB;GACA,GAAG;EACJ;CACD;AACD"}
@@ -0,0 +1,24 @@
1
+ import { ConsentSourceEntry, ConsentSourcesResolver } from "./types.js";
2
+ import { Payload, PayloadRequest } from "payload";
3
+
4
+ //#region src/consent/resolveConsentEntries.d.ts
5
+ type ResolveConsentEntriesArgs = {
6
+ payload: Payload;
7
+ req: PayloadRequest; /** The whole form being resolved; forwarded to the resolver, which casts for non-standard fields (e.g. tenant). */
8
+ form: {
9
+ id: number | string;
10
+ title?: string | null;
11
+ }; /** Resolver override for plugin-internal callers; defaults to the one the plugin stashed on the config. */
12
+ sources?: ConsentSourcesResolver;
13
+ };
14
+ /**
15
+ * The host's consent sources for this request, or an empty list when no resolver is configured
16
+ * (in which case the `consent` field type is not registered either, so nothing can reference one).
17
+ * Throws whatever the resolver throws: every caller decides how to fail, and none of them fail open.
18
+ * Cached per request and form id, so one submission resolves the host's sources once no matter how
19
+ * many consent fields the form carries.
20
+ */
21
+ declare const resolveConsentEntries: (args: ResolveConsentEntriesArgs) => Promise<ConsentSourceEntry[]>;
22
+ //#endregion
23
+ export { ResolveConsentEntriesArgs, resolveConsentEntries };
24
+ //# sourceMappingURL=resolveConsentEntries.d.ts.map
@@ -0,0 +1,40 @@
1
+ import { customStateOf, stashCustomState } from "../plugin/customState.js";
2
+ //#region src/consent/resolveConsentEntries.ts
3
+ /** Park the host's resolver on the config so root-level helpers can find it via `payload.config`. */
4
+ const stashConsentSources = (custom, sources) => stashCustomState(custom, { consentSources: sources });
5
+ const consentSourcesOf = (payload) => customStateOf(payload).consentSources;
6
+ const CACHE_KEY = "formBuilderConsentSourcesCache";
7
+ const cacheOf = (req) => {
8
+ if (!req.context) return;
9
+ const existing = req.context[CACHE_KEY];
10
+ if (existing instanceof Map) return existing;
11
+ const created = /* @__PURE__ */ new Map();
12
+ req.context[CACHE_KEY] = created;
13
+ return created;
14
+ };
15
+ /**
16
+ * The host's consent sources for this request, or an empty list when no resolver is configured
17
+ * (in which case the `consent` field type is not registered either, so nothing can reference one).
18
+ * Throws whatever the resolver throws: every caller decides how to fail, and none of them fail open.
19
+ * Cached per request and form id, so one submission resolves the host's sources once no matter how
20
+ * many consent fields the form carries.
21
+ */
22
+ const resolveConsentEntries = async (args) => {
23
+ const { payload, req, form } = args;
24
+ const resolver = args.sources ?? consentSourcesOf(payload);
25
+ if (!resolver) return [];
26
+ const cache = cacheOf(req);
27
+ const cacheKey = String(form.id);
28
+ const cached = cache?.get(cacheKey);
29
+ if (cached) return cached;
30
+ const entries = await resolver({
31
+ req,
32
+ form
33
+ });
34
+ cache?.set(cacheKey, entries);
35
+ return entries;
36
+ };
37
+ //#endregion
38
+ export { resolveConsentEntries, stashConsentSources };
39
+
40
+ //# sourceMappingURL=resolveConsentEntries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveConsentEntries.js","names":[],"sources":["../../src/consent/resolveConsentEntries.ts"],"sourcesContent":["import type { Payload, PayloadRequest } from 'payload'\nimport { customStateOf, stashCustomState } from '../plugin/customState'\nimport type { ConsentSourceEntry, ConsentSourcesResolver } from './types'\n\ntype ConsentCustomState = { consentSources: ConsentSourcesResolver }\n\n/** Park the host's resolver on the config so root-level helpers can find it via `payload.config`. */\nexport const stashConsentSources = (\n\tcustom: Record<string, unknown> | undefined,\n\tsources: ConsentSourcesResolver\n): Record<string, unknown> =>\n\tstashCustomState<ConsentCustomState>(custom, { consentSources: sources })\n\nexport const consentSourcesOf = (payload: Payload): ConsentSourcesResolver | undefined =>\n\tcustomStateOf<ConsentCustomState>(payload).consentSources\n\nconst CACHE_KEY = 'formBuilderConsentSourcesCache'\n\ntype EntriesCache = Map<string, ConsentSourceEntry[]>\n\nconst cacheOf = (req: PayloadRequest): EntriesCache | undefined => {\n\tif (!req.context) {\n\t\treturn undefined\n\t}\n\tconst existing = req.context[CACHE_KEY]\n\tif (existing instanceof Map) {\n\t\treturn existing as EntriesCache\n\t}\n\tconst created: EntriesCache = new Map()\n\treq.context[CACHE_KEY] = created\n\treturn created\n}\n\nexport type ResolveConsentEntriesArgs = {\n\tpayload: Payload\n\treq: PayloadRequest\n\t/** The whole form being resolved; forwarded to the resolver, which casts for non-standard fields (e.g. tenant). */\n\tform: { id: number | string; title?: string | null }\n\t/** Resolver override for plugin-internal callers; defaults to the one the plugin stashed on the config. */\n\tsources?: ConsentSourcesResolver\n}\n\n/**\n * The host's consent sources for this request, or an empty list when no resolver is configured\n * (in which case the `consent` field type is not registered either, so nothing can reference one).\n * Throws whatever the resolver throws: every caller decides how to fail, and none of them fail open.\n * Cached per request and form id, so one submission resolves the host's sources once no matter how\n * many consent fields the form carries.\n */\nexport const resolveConsentEntries = async (\n\targs: ResolveConsentEntriesArgs\n): Promise<ConsentSourceEntry[]> => {\n\tconst { payload, req, form } = args\n\tconst resolver = args.sources ?? consentSourcesOf(payload)\n\tif (!resolver) {\n\t\treturn []\n\t}\n\tconst cache = cacheOf(req)\n\tconst cacheKey = String(form.id)\n\tconst cached = cache?.get(cacheKey)\n\tif (cached) {\n\t\treturn cached\n\t}\n\tconst entries = await resolver({ req, form })\n\tcache?.set(cacheKey, entries)\n\treturn entries\n}\n"],"mappings":";;;AAOA,MAAa,uBACZ,QACA,YAEA,iBAAqC,QAAQ,EAAE,gBAAgB,QAAQ,CAAC;AAEzE,MAAa,oBAAoB,YAChC,cAAkC,OAAO,EAAE;AAE5C,MAAM,YAAY;AAIlB,MAAM,WAAW,QAAkD;CAClE,IAAI,CAAC,IAAI,SACR;CAED,MAAM,WAAW,IAAI,QAAQ;CAC7B,IAAI,oBAAoB,KACvB,OAAO;CAER,MAAM,0BAAwB,IAAI,IAAI;CACtC,IAAI,QAAQ,aAAa;CACzB,OAAO;AACR;;;;;;;;AAkBA,MAAa,wBAAwB,OACpC,SACmC;CACnC,MAAM,EAAE,SAAS,KAAK,SAAS;CAC/B,MAAM,WAAW,KAAK,WAAW,iBAAiB,OAAO;CACzD,IAAI,CAAC,UACJ,OAAO,CAAC;CAET,MAAM,QAAQ,QAAQ,GAAG;CACzB,MAAM,WAAW,OAAO,KAAK,EAAE;CAC/B,MAAM,SAAS,OAAO,IAAI,QAAQ;CAClC,IAAI,QACH,OAAO;CAER,MAAM,UAAU,MAAM,SAAS;EAAE;EAAK;CAAK,CAAC;CAC5C,OAAO,IAAI,UAAU,OAAO;CAC5B,OAAO;AACR"}
@@ -0,0 +1,37 @@
1
+ import { ConsentSourcesResolver } from "./types.js";
2
+ import { Payload, PayloadRequest } from "payload";
3
+
4
+ //#region src/consent/resolveConsentSourcesRequest.d.ts
5
+ /** One selectable consent source for the consent field's `source` select. */
6
+ type ConsentSourceOption = {
7
+ label: string;
8
+ value: string;
9
+ };
10
+ type ResolveConsentSourcesRequestArgs = {
11
+ payload: Payload;
12
+ formId: number | string | undefined; /** Whether the caller is authenticated (an admin/user). */
13
+ isAuthed: boolean;
14
+ req: PayloadRequest;
15
+ resolver: ConsentSourcesResolver;
16
+ };
17
+ type ResolveConsentSourcesRequestResult = {
18
+ status: number;
19
+ body: {
20
+ options: ConsentSourceOption[];
21
+ } | {
22
+ errors: {
23
+ message: string;
24
+ }[];
25
+ };
26
+ };
27
+ /**
28
+ * Authorize and resolve the `GET /:id/consent-sources` request backing the consent `source` select:
29
+ * authenticated callers get the host's sources for this request (a multi-tenant resolver scoping by
30
+ * `req` therefore offers an author only their own tenant's), anonymous callers are always refused.
31
+ * Statuses mirror the poll-options endpoint: 400 missing id, 403 unauthenticated, 404 unknown form,
32
+ * 503 when the resolver throws (fail closed).
33
+ */
34
+ declare const resolveConsentSourcesRequest: (args: ResolveConsentSourcesRequestArgs) => Promise<ResolveConsentSourcesRequestResult>;
35
+ //#endregion
36
+ export { ConsentSourceOption, ResolveConsentSourcesRequestArgs, ResolveConsentSourcesRequestResult, resolveConsentSourcesRequest };
37
+ //# sourceMappingURL=resolveConsentSourcesRequest.d.ts.map
@@ -0,0 +1,54 @@
1
+ import { resolveConsentEntries } from "./resolveConsentEntries.js";
2
+ import { FORMS_SLUG } from "../collections/forms.js";
3
+ //#region src/consent/resolveConsentSourcesRequest.ts
4
+ /**
5
+ * Authorize and resolve the `GET /:id/consent-sources` request backing the consent `source` select:
6
+ * authenticated callers get the host's sources for this request (a multi-tenant resolver scoping by
7
+ * `req` therefore offers an author only their own tenant's), anonymous callers are always refused.
8
+ * Statuses mirror the poll-options endpoint: 400 missing id, 403 unauthenticated, 404 unknown form,
9
+ * 503 when the resolver throws (fail closed).
10
+ */
11
+ const resolveConsentSourcesRequest = async (args) => {
12
+ const { payload, formId, isAuthed, req, resolver } = args;
13
+ if (!isAuthed) return {
14
+ status: 403,
15
+ body: { errors: [{ message: "Forbidden" }] }
16
+ };
17
+ if (formId == null) return {
18
+ status: 400,
19
+ body: { errors: [{ message: "Missing form id" }] }
20
+ };
21
+ const form = await payload.findByID({
22
+ collection: FORMS_SLUG,
23
+ id: formId,
24
+ depth: 0,
25
+ req
26
+ }).catch(() => null);
27
+ if (!form) return {
28
+ status: 404,
29
+ body: { errors: [{ message: "Not found" }] }
30
+ };
31
+ try {
32
+ return {
33
+ status: 200,
34
+ body: { options: (await resolveConsentEntries({
35
+ payload,
36
+ req,
37
+ form,
38
+ sources: resolver
39
+ })).map((entry) => ({
40
+ label: entry.name ?? entry.id,
41
+ value: entry.id
42
+ })) }
43
+ };
44
+ } catch {
45
+ return {
46
+ status: 503,
47
+ body: { errors: [{ message: "Consent sources unavailable" }] }
48
+ };
49
+ }
50
+ };
51
+ //#endregion
52
+ export { resolveConsentSourcesRequest };
53
+
54
+ //# sourceMappingURL=resolveConsentSourcesRequest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveConsentSourcesRequest.js","names":[],"sources":["../../src/consent/resolveConsentSourcesRequest.ts"],"sourcesContent":["import type { Payload, PayloadRequest } from 'payload'\nimport { FORMS_SLUG } from '../collections/forms'\nimport { resolveConsentEntries } from './resolveConsentEntries'\nimport type { ConsentSourcesResolver } from './types'\n\n/** One selectable consent source for the consent field's `source` select. */\nexport type ConsentSourceOption = { label: string; value: string }\n\nexport type ResolveConsentSourcesRequestArgs = {\n\tpayload: Payload\n\tformId: number | string | undefined\n\t/** Whether the caller is authenticated (an admin/user). */\n\tisAuthed: boolean\n\treq: PayloadRequest\n\tresolver: ConsentSourcesResolver\n}\n\nexport type ResolveConsentSourcesRequestResult = {\n\tstatus: number\n\tbody: { options: ConsentSourceOption[] } | { errors: { message: string }[] }\n}\n\n/**\n * Authorize and resolve the `GET /:id/consent-sources` request backing the consent `source` select:\n * authenticated callers get the host's sources for this request (a multi-tenant resolver scoping by\n * `req` therefore offers an author only their own tenant's), anonymous callers are always refused.\n * Statuses mirror the poll-options endpoint: 400 missing id, 403 unauthenticated, 404 unknown form,\n * 503 when the resolver throws (fail closed).\n */\nexport const resolveConsentSourcesRequest = async (\n\targs: ResolveConsentSourcesRequestArgs\n): Promise<ResolveConsentSourcesRequestResult> => {\n\tconst { payload, formId, isAuthed, req, resolver } = args\n\tif (!isAuthed) {\n\t\treturn { status: 403, body: { errors: [{ message: 'Forbidden' }] } }\n\t}\n\tif (formId == null) {\n\t\treturn { status: 400, body: { errors: [{ message: 'Missing form id' }] } }\n\t}\n\t// Load under the caller's own read access (no overrideAccess): a tenant-scoped `forms.access.read`\n\t// then refuses a cross-tenant form id (null -> 404), so an authed user can never enumerate another\n\t// tenant's consent source labels/ids.\n\tconst form = await payload\n\t\t.findByID({ collection: FORMS_SLUG, id: formId, depth: 0, req })\n\t\t.catch(() => null)\n\tif (!form) {\n\t\treturn { status: 404, body: { errors: [{ message: 'Not found' }] } }\n\t}\n\ttry {\n\t\tconst entries = await resolveConsentEntries({ payload, req, form, sources: resolver })\n\t\treturn {\n\t\t\tstatus: 200,\n\t\t\tbody: {\n\t\t\t\toptions: entries.map((entry) => ({ label: entry.name ?? entry.id, value: entry.id })),\n\t\t\t},\n\t\t}\n\t} catch {\n\t\treturn { status: 503, body: { errors: [{ message: 'Consent sources unavailable' }] } }\n\t}\n}\n"],"mappings":";;;;;;;;;;AA6BA,MAAa,+BAA+B,OAC3C,SACiD;CACjD,MAAM,EAAE,SAAS,QAAQ,UAAU,KAAK,aAAa;CACrD,IAAI,CAAC,UACJ,OAAO;EAAE,QAAQ;EAAK,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS,YAAY,CAAC,EAAE;CAAE;CAEpE,IAAI,UAAU,MACb,OAAO;EAAE,QAAQ;EAAK,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS,kBAAkB,CAAC,EAAE;CAAE;CAK1E,MAAM,OAAO,MAAM,QACjB,SAAS;EAAE,YAAY;EAAY,IAAI;EAAQ,OAAO;EAAG;CAAI,CAAC,EAC9D,YAAY,IAAI;CAClB,IAAI,CAAC,MACJ,OAAO;EAAE,QAAQ;EAAK,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS,YAAY,CAAC,EAAE;CAAE;CAEpE,IAAI;EAEH,OAAO;GACN,QAAQ;GACR,MAAM,EACL,UAAS,MAJW,sBAAsB;IAAE;IAAS;IAAK;IAAM,SAAS;GAAS,CAAC,GAIlE,KAAK,WAAW;IAAE,OAAO,MAAM,QAAQ,MAAM;IAAI,OAAO,MAAM;GAAG,EAAE,EACrF;EACD;CACD,QAAQ;EACP,OAAO;GAAE,QAAQ;GAAK,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS,8BAA8B,CAAC,EAAE;EAAE;CACtF;AACD"}
@@ -0,0 +1,45 @@
1
+ import { ConsentSourcesResolver } from "./types.js";
2
+ import { Payload, PayloadRequest } from "payload";
3
+
4
+ //#region src/consent/resolveConsentStatements.d.ts
5
+ /** What a consent field shows the visitor, resolved from its source at request time. */
6
+ type ConsentStatement = {
7
+ /** Rich text state (or whatever the host's resolver returned), for the request's locale. */statement?: unknown; /** The policy link beside the statement, present only when the source carries both a `url` and a `label`. */
8
+ link?: {
9
+ label: string;
10
+ url: string;
11
+ };
12
+ };
13
+ /** Resolved statements keyed by consent field name, as `toFormDocument`'s `consentStatements` takes them. */
14
+ type ConsentStatements = Record<string, ConsentStatement>;
15
+ type ResolveConsentStatementsArgs = {
16
+ payload: Payload;
17
+ req: PayloadRequest; /** A loaded forms document; its consent fields' `source` ids drive resolution. The whole doc is forwarded to the resolver. */
18
+ form: {
19
+ id: number | string;
20
+ title?: string | null;
21
+ fields?: {
22
+ blockType: string;
23
+ name?: string;
24
+ [key: string]: unknown;
25
+ }[] | null;
26
+ }; /** Resolver override for plugin-internal callers; defaults to the one the plugin stashed on the config. */
27
+ sources?: ConsentSourcesResolver;
28
+ };
29
+ /**
30
+ * Resolve every consent field's statement for this request, ready to hand to
31
+ * `toFormDocument(doc, { consentStatements })`.
32
+ *
33
+ * The statement is a live reference, not a copy: a form stores only its source id, and the
34
+ * sentence the visitor reads is resolved here, in their locale, from whatever the source says
35
+ * right now. So correcting a policy sentence corrects every form referencing it, with nothing to
36
+ * re-save, and a form rendered without this step shows no statement at all rather than a stale one.
37
+ *
38
+ * Call it server-side (a Server Component, a route handler) before rendering `<Form>`. Throws
39
+ * whatever the host's resolver throws, so a page can decide between failing and rendering without
40
+ * consent; a submit resolves the source again regardless, and the proof is built from that.
41
+ */
42
+ declare const resolveConsentStatements: (args: ResolveConsentStatementsArgs) => Promise<ConsentStatements>;
43
+ //#endregion
44
+ export { ConsentStatement, ConsentStatements, ResolveConsentStatementsArgs, resolveConsentStatements };
45
+ //# sourceMappingURL=resolveConsentStatements.d.ts.map
@@ -0,0 +1,44 @@
1
+ import { resolveConsentEntries } from "./resolveConsentEntries.js";
2
+ //#region src/consent/resolveConsentStatements.ts
3
+ /**
4
+ * Resolve every consent field's statement for this request, ready to hand to
5
+ * `toFormDocument(doc, { consentStatements })`.
6
+ *
7
+ * The statement is a live reference, not a copy: a form stores only its source id, and the
8
+ * sentence the visitor reads is resolved here, in their locale, from whatever the source says
9
+ * right now. So correcting a policy sentence corrects every form referencing it, with nothing to
10
+ * re-save, and a form rendered without this step shows no statement at all rather than a stale one.
11
+ *
12
+ * Call it server-side (a Server Component, a route handler) before rendering `<Form>`. Throws
13
+ * whatever the host's resolver throws, so a page can decide between failing and rendering without
14
+ * consent; a submit resolves the source again regardless, and the proof is built from that.
15
+ */
16
+ const resolveConsentStatements = async (args) => {
17
+ const { payload, req, form, sources } = args;
18
+ const consentFields = (form.fields ?? []).filter((field) => field.blockType === "consent" && typeof field.name === "string" && field.name.length > 0);
19
+ if (consentFields.length === 0) return {};
20
+ const entries = await resolveConsentEntries({
21
+ payload,
22
+ req,
23
+ form,
24
+ sources
25
+ });
26
+ const statements = {};
27
+ for (const field of consentFields) {
28
+ const entry = entries.find((candidate) => candidate.id === field.source);
29
+ if (!entry) continue;
30
+ const label = typeof entry.name === "string" && entry.name.trim() !== "" ? entry.name : "";
31
+ statements[field.name] = {
32
+ ...entry.statement != null ? { statement: entry.statement } : {},
33
+ ...label && typeof entry.url === "string" && entry.url.length > 0 ? { link: {
34
+ label,
35
+ url: entry.url
36
+ } } : {}
37
+ };
38
+ }
39
+ return statements;
40
+ };
41
+ //#endregion
42
+ export { resolveConsentStatements };
43
+
44
+ //# sourceMappingURL=resolveConsentStatements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveConsentStatements.js","names":[],"sources":["../../src/consent/resolveConsentStatements.ts"],"sourcesContent":["import type { Payload, PayloadRequest } from 'payload'\nimport { resolveConsentEntries } from './resolveConsentEntries'\nimport type { ConsentSourcesResolver } from './types'\n\n/** What a consent field shows the visitor, resolved from its source at request time. */\nexport type ConsentStatement = {\n\t/** Rich text state (or whatever the host's resolver returned), for the request's locale. */\n\tstatement?: unknown\n\t/** The policy link beside the statement, present only when the source carries both a `url` and a `label`. */\n\tlink?: { label: string; url: string }\n}\n\n/** Resolved statements keyed by consent field name, as `toFormDocument`'s `consentStatements` takes them. */\nexport type ConsentStatements = Record<string, ConsentStatement>\n\nexport type ResolveConsentStatementsArgs = {\n\tpayload: Payload\n\treq: PayloadRequest\n\t/** A loaded forms document; its consent fields' `source` ids drive resolution. The whole doc is forwarded to the resolver. */\n\tform: {\n\t\tid: number | string\n\t\ttitle?: string | null\n\t\tfields?: { blockType: string; name?: string; [key: string]: unknown }[] | null\n\t}\n\t/** Resolver override for plugin-internal callers; defaults to the one the plugin stashed on the config. */\n\tsources?: ConsentSourcesResolver\n}\n\n/**\n * Resolve every consent field's statement for this request, ready to hand to\n * `toFormDocument(doc, { consentStatements })`.\n *\n * The statement is a live reference, not a copy: a form stores only its source id, and the\n * sentence the visitor reads is resolved here, in their locale, from whatever the source says\n * right now. So correcting a policy sentence corrects every form referencing it, with nothing to\n * re-save, and a form rendered without this step shows no statement at all rather than a stale one.\n *\n * Call it server-side (a Server Component, a route handler) before rendering `<Form>`. Throws\n * whatever the host's resolver throws, so a page can decide between failing and rendering without\n * consent; a submit resolves the source again regardless, and the proof is built from that.\n */\nexport const resolveConsentStatements = async (\n\targs: ResolveConsentStatementsArgs\n): Promise<ConsentStatements> => {\n\tconst { payload, req, form, sources } = args\n\tconst consentFields = (form.fields ?? []).filter(\n\t\t(field): field is { blockType: string; name: string; source?: unknown } =>\n\t\t\tfield.blockType === 'consent' && typeof field.name === 'string' && field.name.length > 0\n\t)\n\tif (consentFields.length === 0) {\n\t\treturn {}\n\t}\n\tconst entries = await resolveConsentEntries({ payload, req, form, sources })\n\tconst statements: ConsentStatements = {}\n\tfor (const field of consentFields) {\n\t\tconst entry = entries.find((candidate) => candidate.id === field.source)\n\t\tif (!entry) {\n\t\t\tcontinue\n\t\t}\n\t\t// The link needs a name of its own, so it takes the source's `name` and never falls back to\n\t\t// the `id`: the id is a machine identifier, and showing it as the words a visitor clicks is\n\t\t// worse than no link at all. A source with a url and no name simply has no link.\n\t\tconst label = typeof entry.name === 'string' && entry.name.trim() !== '' ? entry.name : ''\n\t\tstatements[field.name] = {\n\t\t\t...(entry.statement != null ? { statement: entry.statement } : {}),\n\t\t\t...(label && typeof entry.url === 'string' && entry.url.length > 0\n\t\t\t\t? { link: { label, url: entry.url } }\n\t\t\t\t: {}),\n\t\t}\n\t}\n\treturn statements\n}\n"],"mappings":";;;;;;;;;;;;;;;AAyCA,MAAa,2BAA2B,OACvC,SACgC;CAChC,MAAM,EAAE,SAAS,KAAK,MAAM,YAAY;CACxC,MAAM,iBAAiB,KAAK,UAAU,CAAC,GAAG,QACxC,UACA,MAAM,cAAc,aAAa,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,SAAS,CACzF;CACA,IAAI,cAAc,WAAW,GAC5B,OAAO,CAAC;CAET,MAAM,UAAU,MAAM,sBAAsB;EAAE;EAAS;EAAK;EAAM;CAAQ,CAAC;CAC3E,MAAM,aAAgC,CAAC;CACvC,KAAK,MAAM,SAAS,eAAe;EAClC,MAAM,QAAQ,QAAQ,MAAM,cAAc,UAAU,OAAO,MAAM,MAAM;EACvE,IAAI,CAAC,OACJ;EAKD,MAAM,QAAQ,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,MAAM,KAAK,MAAM,OAAO;EACxF,WAAW,MAAM,QAAQ;GACxB,GAAI,MAAM,aAAa,OAAO,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;GAChE,GAAI,SAAS,OAAO,MAAM,QAAQ,YAAY,MAAM,IAAI,SAAS,IAC9D,EAAE,MAAM;IAAE;IAAO,KAAK,MAAM;GAAI,EAAE,IAClC,CAAC;EACL;CACD;CACA,OAAO;AACR"}
@@ -0,0 +1,23 @@
1
+ import { Payload, PayloadRequest } from "payload";
2
+
3
+ //#region src/consent/resolvePublishedVersionRef.d.ts
4
+ type ResolvePublishedVersionRefArgs = {
5
+ payload: Payload;
6
+ collection: string;
7
+ id: number | string; /** Threaded into `findVersions` so a version written earlier in the same transaction is visible. */
8
+ req?: PayloadRequest;
9
+ };
10
+ /**
11
+ * The id of a document's latest published version, or null when nothing is published.
12
+ *
13
+ * Drafts-only, and deliberately not a versions check: `_status` exists only where
14
+ * `versions.drafts` is on (Payload adds the base version fields inside that branch when
15
+ * sanitizing), so on a collection with plain versions and no drafts this query matches nothing and
16
+ * returns null, which is indistinguishable from having no versions at all. Callers must decide the
17
+ * difference themselves with `hasDraftsEnabled` rather than reading null as "no versions" (see
18
+ * `captureConsent`). Never throws.
19
+ */
20
+ declare const resolvePublishedVersionRef: (args: ResolvePublishedVersionRefArgs) => Promise<string | null>;
21
+ //#endregion
22
+ export { ResolvePublishedVersionRefArgs, resolvePublishedVersionRef };
23
+ //# sourceMappingURL=resolvePublishedVersionRef.d.ts.map
@@ -0,0 +1,30 @@
1
+ //#region src/consent/resolvePublishedVersionRef.ts
2
+ /**
3
+ * The id of a document's latest published version, or null when nothing is published.
4
+ *
5
+ * Drafts-only, and deliberately not a versions check: `_status` exists only where
6
+ * `versions.drafts` is on (Payload adds the base version fields inside that branch when
7
+ * sanitizing), so on a collection with plain versions and no drafts this query matches nothing and
8
+ * returns null, which is indistinguishable from having no versions at all. Callers must decide the
9
+ * difference themselves with `hasDraftsEnabled` rather than reading null as "no versions" (see
10
+ * `captureConsent`). Never throws.
11
+ */
12
+ const resolvePublishedVersionRef = async (args) => {
13
+ try {
14
+ const doc = (await args.payload.findVersions({
15
+ collection: args.collection,
16
+ where: { and: [{ parent: { equals: args.id } }, { "version._status": { equals: "published" } }] },
17
+ sort: "-updatedAt",
18
+ limit: 1,
19
+ depth: 0,
20
+ req: args.req
21
+ }))?.docs?.[0];
22
+ return doc ? String(doc.id) : null;
23
+ } catch {
24
+ return null;
25
+ }
26
+ };
27
+ //#endregion
28
+ export { resolvePublishedVersionRef };
29
+
30
+ //# sourceMappingURL=resolvePublishedVersionRef.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolvePublishedVersionRef.js","names":[],"sources":["../../src/consent/resolvePublishedVersionRef.ts"],"sourcesContent":["import type { Payload, PayloadRequest } from 'payload'\n\nexport type ResolvePublishedVersionRefArgs = {\n\tpayload: Payload\n\tcollection: string\n\tid: number | string\n\t/** Threaded into `findVersions` so a version written earlier in the same transaction is visible. */\n\treq?: PayloadRequest\n}\n\n/**\n * The id of a document's latest published version, or null when nothing is published.\n *\n * Drafts-only, and deliberately not a versions check: `_status` exists only where\n * `versions.drafts` is on (Payload adds the base version fields inside that branch when\n * sanitizing), so on a collection with plain versions and no drafts this query matches nothing and\n * returns null, which is indistinguishable from having no versions at all. Callers must decide the\n * difference themselves with `hasDraftsEnabled` rather than reading null as \"no versions\" (see\n * `captureConsent`). Never throws.\n */\nexport const resolvePublishedVersionRef = async (\n\targs: ResolvePublishedVersionRefArgs\n): Promise<string | null> => {\n\ttry {\n\t\tconst result = await args.payload.findVersions({\n\t\t\tcollection: args.collection as never,\n\t\t\twhere: {\n\t\t\t\tand: [{ parent: { equals: args.id } }, { 'version._status': { equals: 'published' } }],\n\t\t\t},\n\t\t\tsort: '-updatedAt',\n\t\t\tlimit: 1,\n\t\t\tdepth: 0,\n\t\t\treq: args.req,\n\t\t})\n\t\tconst doc = result?.docs?.[0]\n\t\treturn doc ? String(doc.id) : null\n\t} catch {\n\t\treturn null\n\t}\n}\n"],"mappings":";;;;;;;;;;;AAoBA,MAAa,6BAA6B,OACzC,SAC4B;CAC5B,IAAI;EAWH,MAAM,OAAM,MAVS,KAAK,QAAQ,aAAa;GAC9C,YAAY,KAAK;GACjB,OAAO,EACN,KAAK,CAAC,EAAE,QAAQ,EAAE,QAAQ,KAAK,GAAG,EAAE,GAAG,EAAE,mBAAmB,EAAE,QAAQ,YAAY,EAAE,CAAC,EACtF;GACA,MAAM;GACN,OAAO;GACP,OAAO;GACP,KAAK,KAAK;EACX,CAAC,IACmB,OAAO;EAC3B,OAAO,MAAM,OAAO,IAAI,EAAE,IAAI;CAC/B,QAAQ;EACP,OAAO;CACR;AACD"}
@@ -0,0 +1,61 @@
1
+ import { PayloadRequest } from "payload";
2
+
3
+ //#region src/consent/types.d.ts
4
+ /** A document reference, kept id-based so renaming or re-slugging the page never breaks it. */
5
+ type ConsentSourcePage = {
6
+ relationTo: string;
7
+ id: number | string;
8
+ };
9
+ /**
10
+ * One consent source a form author can reference by `id`: the statement the visitor agrees to, and
11
+ * optionally the policy document that statement belongs to. Produced by the host's
12
+ * {@link ConsentSourcesResolver}, normally by mapping the rows of a placed `consentSourcesField()`.
13
+ *
14
+ * `id` is the array row's own auto-assigned identifier, so it survives name edits and reordering
15
+ * and is the stable reference stored on the consent field and in every proof. `statement` is rich
16
+ * text state (the visitor-facing sentence), already resolved for the request's locale by virtue of
17
+ * the resolver reading its own localized field under `req.locale`. `page` drives proof: an id and
18
+ * its collection, never a URL, so the document can be renamed, re-slugged, or re-routed without
19
+ * stranding past proofs. `url` is the visitor-facing link the renderer shows beside the statement;
20
+ * only the host knows how a document id maps to a public route, so the plugin never derives one.
21
+ */
22
+ type ConsentSourceEntry = {
23
+ id: string;
24
+ name?: string;
25
+ statement?: unknown;
26
+ page?: ConsentSourcePage;
27
+ url?: string;
28
+ };
29
+ /**
30
+ * Host seam resolving the consent sources a form's authors can reference (plugin option
31
+ * `consent.sources`). Without it there are no sources, so the `consent` field type is not
32
+ * registered at all.
33
+ *
34
+ * The intended shape: place `consentSourcesField()` on a collection or global you own, then read it
35
+ * back here. Multi-tenant hosts scope the read by the tenant derived from `req` (host header,
36
+ * cookie, or auth context) and return only that tenant's sources, so one tenant's statements are
37
+ * never selectable, resolvable, or provable under another's. Read under `req.locale` so the
38
+ * statement the visitor agrees to is the one they were shown.
39
+ *
40
+ * Do not thread the save's `req` into a `find({ locale: 'all' })` from within a form's save
41
+ * validation: it flips `req.locale` to `all` and corrupts the localized write of the document being
42
+ * saved. Read the settings document without the save's `req` (already-committed data, no transaction).
43
+ */
44
+ type ConsentSourcesResolver = (args: {
45
+ req: PayloadRequest;
46
+ /**
47
+ * The form document being read: `id`, `title`, and (at runtime) every other field. Derive
48
+ * multi-tenant scoping from a field on it, casting for non-standard fields (e.g.
49
+ * `(form as { tenant?: string }).tenant`), rather than reading the form back: reading the same
50
+ * `forms` collection from within this resolver re-enters the form's afterRead hook. The type is
51
+ * kept index-signature-free so a generated `Form` interface assigns without a cast. Treat `form`
52
+ * as read-only.
53
+ */
54
+ form: {
55
+ id: number | string;
56
+ title?: string | null;
57
+ };
58
+ }) => ConsentSourceEntry[] | Promise<ConsentSourceEntry[]>;
59
+ //#endregion
60
+ export { ConsentSourceEntry, ConsentSourcePage, ConsentSourcesResolver };
61
+ //# sourceMappingURL=types.d.ts.map