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

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 (372) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/README.md +3 -3
  3. package/dist/actions/body/serializeBody.d.ts +8 -5
  4. package/dist/actions/body/serializeBody.js.map +1 -1
  5. package/dist/actions/body/textOfBody.d.ts +13 -0
  6. package/dist/actions/body/textOfBody.js +35 -0
  7. package/dist/actions/body/textOfBody.js.map +1 -0
  8. package/dist/actions/builtin/confirmation.js +81 -48
  9. package/dist/actions/builtin/confirmation.js.map +1 -1
  10. package/dist/actions/builtin/emailTeam.js +67 -38
  11. package/dist/actions/builtin/emailTeam.js.map +1 -1
  12. package/dist/actions/builtin/index.d.ts +9 -3
  13. package/dist/actions/builtin/index.js +8 -5
  14. package/dist/actions/builtin/index.js.map +1 -1
  15. package/dist/actions/defineAction.d.ts +1 -1
  16. package/dist/actions/emailRecipients.d.ts +12 -0
  17. package/dist/actions/emailRecipients.js +72 -0
  18. package/dist/actions/emailRecipients.js.map +1 -0
  19. package/dist/actions/fromAddresses.d.ts +21 -0
  20. package/dist/actions/fromAddresses.js +74 -0
  21. package/dist/actions/fromAddresses.js.map +1 -0
  22. package/dist/actions/task.js +9 -8
  23. package/dist/actions/task.js.map +1 -1
  24. package/dist/aggregation/aggregateResponses.d.ts +9 -0
  25. package/dist/aggregation/aggregateResponses.js +8 -14
  26. package/dist/aggregation/aggregateResponses.js.map +1 -1
  27. package/dist/aggregation/resolveResultsRequest.d.ts +19 -6
  28. package/dist/aggregation/resolveResultsRequest.js +58 -12
  29. package/dist/aggregation/resolveResultsRequest.js.map +1 -1
  30. package/dist/calc/computeCalcFields.js +2 -1
  31. package/dist/calc/computeCalcFields.js.map +1 -1
  32. package/dist/client/ByteSizeField.d.ts +8 -0
  33. package/dist/client/ByteSizeField.js +3 -1
  34. package/dist/client/ByteSizeField.js.map +1 -1
  35. package/dist/client/ClosePollButton.d.ts +15 -0
  36. package/dist/client/ClosePollButton.js +80 -0
  37. package/dist/client/ClosePollButton.js.map +1 -0
  38. package/dist/client/CondensedArray.d.ts +15 -0
  39. package/dist/client/CondensedArray.js +97 -0
  40. package/dist/client/CondensedArray.js.map +1 -0
  41. package/dist/client/ConsentBlockLabel.d.ts +15 -0
  42. package/dist/client/ConsentBlockLabel.js +71 -0
  43. package/dist/client/ConsentBlockLabel.js.map +1 -0
  44. package/dist/client/ConsentSourceRowLabel.d.ts +9 -0
  45. package/dist/client/ConsentSourceRowLabel.js +21 -0
  46. package/dist/client/ConsentSourceRowLabel.js.map +1 -0
  47. package/dist/client/EndpointOptionsSelect.d.ts +46 -0
  48. package/dist/client/EndpointOptionsSelect.js +106 -0
  49. package/dist/client/EndpointOptionsSelect.js.map +1 -0
  50. package/dist/client/FieldBlockLabel.d.ts +18 -0
  51. package/dist/client/FieldBlockLabel.js +34 -0
  52. package/dist/client/FieldBlockLabel.js.map +1 -0
  53. package/dist/client/FieldNameSelect.d.ts +21 -4
  54. package/dist/client/FieldNameSelect.js +29 -15
  55. package/dist/client/FieldNameSelect.js.map +1 -1
  56. package/dist/client/FlowBuilder.d.ts +2 -1
  57. package/dist/client/FlowBuilder.js +63 -57
  58. package/dist/client/FlowBuilder.js.map +1 -1
  59. package/dist/client/RecipientsSelect.d.ts +31 -0
  60. package/dist/client/RecipientsSelect.js +174 -0
  61. package/dist/client/RecipientsSelect.js.map +1 -0
  62. package/dist/client/RuleDescription.d.ts +21 -0
  63. package/dist/client/RuleDescription.js +19 -0
  64. package/dist/client/RuleDescription.js.map +1 -0
  65. package/dist/client/admin.css +41 -0
  66. package/dist/client/endpointOptions.js +29 -0
  67. package/dist/client/endpointOptions.js.map +1 -0
  68. package/dist/client/flowAuthoring.js +114 -7
  69. package/dist/client/flowAuthoring.js.map +1 -1
  70. package/dist/client/synthesizeClientField.js +15 -8
  71. package/dist/client/synthesizeClientField.js.map +1 -1
  72. package/dist/collections/buttonFields.d.ts +34 -0
  73. package/dist/collections/buttonFields.js +35 -0
  74. package/dist/collections/buttonFields.js.map +1 -0
  75. package/dist/collections/cells/FieldCountCell.d.ts +15 -0
  76. package/dist/collections/cells/FieldCountCell.js +18 -0
  77. package/dist/collections/cells/FieldCountCell.js.map +1 -0
  78. package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
  79. package/dist/collections/cells/FlowStepsCell.js +17 -0
  80. package/dist/collections/cells/FlowStepsCell.js.map +1 -0
  81. package/dist/collections/formSubmissions.js +23 -17
  82. package/dist/collections/formSubmissions.js.map +1 -1
  83. package/dist/collections/forms.js +323 -134
  84. package/dist/collections/forms.js.map +1 -1
  85. package/dist/collections/redirectFields.d.ts +29 -0
  86. package/dist/consent/applyConsentStatements.d.ts +14 -0
  87. package/dist/consent/applyConsentStatements.js +17 -0
  88. package/dist/consent/applyConsentStatements.js.map +1 -0
  89. package/dist/consent/captureConsent.d.ts +31 -11
  90. package/dist/consent/captureConsent.js +53 -13
  91. package/dist/consent/captureConsent.js.map +1 -1
  92. package/dist/consent/consentSourcesField.d.ts +62 -0
  93. package/dist/consent/consentSourcesField.js +86 -0
  94. package/dist/consent/consentSourcesField.js.map +1 -0
  95. package/dist/consent/resolveConsentEntries.d.ts +24 -0
  96. package/dist/consent/resolveConsentEntries.js +43 -0
  97. package/dist/consent/resolveConsentEntries.js.map +1 -0
  98. package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
  99. package/dist/consent/resolveConsentSourcesRequest.js +55 -0
  100. package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
  101. package/dist/consent/resolveConsentStatements.d.ts +45 -0
  102. package/dist/consent/resolveConsentStatements.js +44 -0
  103. package/dist/consent/resolveConsentStatements.js.map +1 -0
  104. package/dist/consent/resolvePublishedVersionRef.d.ts +17 -11
  105. package/dist/consent/resolvePublishedVersionRef.js +13 -10
  106. package/dist/consent/resolvePublishedVersionRef.js.map +1 -1
  107. package/dist/consent/types.d.ts +53 -0
  108. package/dist/email/departments.d.ts +59 -0
  109. package/dist/email/departments.js +87 -0
  110. package/dist/email/departments.js.map +1 -0
  111. package/dist/email/departmentsField.d.ts +53 -0
  112. package/dist/email/departmentsField.js +73 -0
  113. package/dist/email/departmentsField.js.map +1 -0
  114. package/dist/exports/client.d.ts +11 -1
  115. package/dist/exports/client.js +11 -1
  116. package/dist/exports/react.d.ts +8 -3
  117. package/dist/exports/react.js +6 -2
  118. package/dist/exports/rsc.d.ts +3 -1
  119. package/dist/exports/rsc.js +4 -2
  120. package/dist/exports/types.d.ts +16 -8
  121. package/dist/fields/buildFieldBlocks.js +28 -13
  122. package/dist/fields/buildFieldBlocks.js.map +1 -1
  123. package/dist/fields/builtin/calculation.js +7 -0
  124. package/dist/fields/builtin/calculation.js.map +1 -1
  125. package/dist/fields/builtin/checkbox.js +8 -0
  126. package/dist/fields/builtin/checkbox.js.map +1 -1
  127. package/dist/fields/builtin/consent.js +32 -21
  128. package/dist/fields/builtin/consent.js.map +1 -1
  129. package/dist/fields/builtin/country.d.ts +13 -0
  130. package/dist/fields/builtin/country.js +30 -0
  131. package/dist/fields/builtin/country.js.map +1 -0
  132. package/dist/fields/builtin/date.js +2 -0
  133. package/dist/fields/builtin/date.js.map +1 -1
  134. package/dist/fields/builtin/file.js +14 -7
  135. package/dist/fields/builtin/file.js.map +1 -1
  136. package/dist/fields/builtin/index.d.ts +8 -6
  137. package/dist/fields/builtin/index.js +12 -11
  138. package/dist/fields/builtin/index.js.map +1 -1
  139. package/dist/fields/builtin/message.js +8 -4
  140. package/dist/fields/builtin/message.js.map +1 -1
  141. package/dist/fields/builtin/repeater.js +1 -0
  142. package/dist/fields/builtin/repeater.js.map +1 -1
  143. package/dist/fields/builtin/select.js +1 -0
  144. package/dist/fields/builtin/select.js.map +1 -1
  145. package/dist/fields/builtin/state.d.ts +13 -0
  146. package/dist/fields/builtin/state.js +30 -0
  147. package/dist/fields/builtin/state.js.map +1 -0
  148. package/dist/fields/data/regions.d.ts +21 -0
  149. package/dist/fields/data/regions.js +1238 -0
  150. package/dist/fields/data/regions.js.map +1 -0
  151. package/dist/fields/fieldKey.d.ts +15 -0
  152. package/dist/fields/fieldKey.js +16 -0
  153. package/dist/fields/fieldKey.js.map +1 -0
  154. package/dist/fields/fieldNamesOfType.js +13 -8
  155. package/dist/fields/fieldNamesOfType.js.map +1 -1
  156. package/dist/fields/instanceOptions.js +20 -0
  157. package/dist/fields/instanceOptions.js.map +1 -0
  158. package/dist/fields/registry.d.ts +1 -0
  159. package/dist/fields/registry.js +21 -2
  160. package/dist/fields/registry.js.map +1 -1
  161. package/dist/fields/sharedConfig.js +46 -9
  162. package/dist/fields/sharedConfig.js.map +1 -1
  163. package/dist/fields/types.d.ts +63 -5
  164. package/dist/flow/engine.d.ts +6 -4
  165. package/dist/flow/engine.js +11 -6
  166. package/dist/flow/engine.js.map +1 -1
  167. package/dist/flow/normalizeFlow.js +16 -7
  168. package/dist/flow/normalizeFlow.js.map +1 -1
  169. package/dist/flow/types.d.ts +12 -3
  170. package/dist/flow/types.js +11 -0
  171. package/dist/flow/types.js.map +1 -0
  172. package/dist/form/pollState.d.ts +4 -4
  173. package/dist/form/pollState.js.map +1 -1
  174. package/dist/form/toFormDocument.d.ts +54 -12
  175. package/dist/form/toFormDocument.js +56 -8
  176. package/dist/form/toFormDocument.js.map +1 -1
  177. package/dist/form/types.d.ts +31 -14
  178. package/dist/index.d.ts +153 -29
  179. package/dist/index.js +47 -15
  180. package/dist/index.js.map +1 -1
  181. package/dist/plugin/customState.js +26 -0
  182. package/dist/plugin/customState.js.map +1 -0
  183. package/dist/plugin/registerCollections.js +24 -13
  184. package/dist/plugin/registerCollections.js.map +1 -1
  185. package/dist/plugin/uploadsCollection.d.ts +5 -0
  186. package/dist/plugin/uploadsCollection.js +10 -1
  187. package/dist/plugin/uploadsCollection.js.map +1 -1
  188. package/dist/poll/applyPollOptions.js +3 -2
  189. package/dist/poll/applyPollOptions.js.map +1 -1
  190. package/dist/poll/buildPollOptionSourceFields.js +2 -5
  191. package/dist/poll/buildPollOptionSourceFields.js.map +1 -1
  192. package/dist/poll/closeJob.d.ts +52 -0
  193. package/dist/poll/closeJob.js +119 -0
  194. package/dist/poll/closeJob.js.map +1 -0
  195. package/dist/poll/definePollOptionSource.d.ts +10 -1
  196. package/dist/poll/definePollOptionSource.js.map +1 -1
  197. package/dist/poll/definePollType.d.ts +34 -0
  198. package/dist/poll/definePollType.js +6 -0
  199. package/dist/poll/definePollType.js.map +1 -0
  200. package/dist/poll/effectivePollOptions.d.ts +38 -0
  201. package/dist/poll/effectivePollOptions.js +64 -0
  202. package/dist/poll/effectivePollOptions.js.map +1 -0
  203. package/dist/poll/mostVoted.d.ts +21 -0
  204. package/dist/poll/mostVoted.js +32 -0
  205. package/dist/poll/mostVoted.js.map +1 -0
  206. package/dist/poll/outcomeBeforeChange.js +91 -0
  207. package/dist/poll/outcomeBeforeChange.js.map +1 -0
  208. package/dist/poll/outcomeFields.d.ts +38 -0
  209. package/dist/poll/outcomeFields.js +52 -0
  210. package/dist/poll/outcomeFields.js.map +1 -0
  211. package/dist/poll/pollTypeRegistry.d.ts +34 -0
  212. package/dist/poll/pollTypeRegistry.js +71 -0
  213. package/dist/poll/pollTypeRegistry.js.map +1 -0
  214. package/dist/poll/resolvePollCloseRequest.js +105 -0
  215. package/dist/poll/resolvePollCloseRequest.js.map +1 -0
  216. package/dist/poll/resolvePollOptions.d.ts +2 -1
  217. package/dist/poll/resolvePollOptions.js +5 -17
  218. package/dist/poll/resolvePollOptions.js.map +1 -1
  219. package/dist/poll/resolvePollOptionsRequest.js +51 -0
  220. package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
  221. package/dist/poll/resolvePollOutcome.d.ts +22 -9
  222. package/dist/poll/resolvePollOutcome.js +54 -14
  223. package/dist/poll/resolvePollOutcome.js.map +1 -1
  224. package/dist/poll/resultsField.js +21 -0
  225. package/dist/poll/resultsField.js.map +1 -0
  226. package/dist/prefill/valuesFromSearchParams.js +2 -1
  227. package/dist/prefill/valuesFromSearchParams.js.map +1 -1
  228. package/dist/react/Form.d.ts +8 -8
  229. package/dist/react/Form.js +74 -62
  230. package/dist/react/Form.js.map +1 -1
  231. package/dist/react/FormContext.d.ts +6 -4
  232. package/dist/react/FormContext.js.map +1 -1
  233. package/dist/react/FormControls.d.ts +3 -3
  234. package/dist/react/FormControls.js +3 -3
  235. package/dist/react/FormControls.js.map +1 -1
  236. package/dist/react/FormResults.d.ts +5 -5
  237. package/dist/react/FormResults.js +6 -6
  238. package/dist/react/FormResults.js.map +1 -1
  239. package/dist/react/Poll.d.ts +2 -2
  240. package/dist/react/Poll.js +5 -5
  241. package/dist/react/Poll.js.map +1 -1
  242. package/dist/react/contract.d.ts +2 -3
  243. package/dist/react/contract.js.map +1 -1
  244. package/dist/react/primitives/Checkbox.d.ts +4 -2
  245. package/dist/react/primitives/Checkbox.js +2 -1
  246. package/dist/react/primitives/Checkbox.js.map +1 -1
  247. package/dist/react/primitives/FieldShell.d.ts +2 -4
  248. package/dist/react/primitives/FieldShell.js +12 -19
  249. package/dist/react/primitives/FieldShell.js.map +1 -1
  250. package/dist/react/renderers/calculation.js +1 -2
  251. package/dist/react/renderers/calculation.js.map +1 -1
  252. package/dist/react/renderers/checkbox.js +1 -2
  253. package/dist/react/renderers/checkbox.js.map +1 -1
  254. package/dist/react/renderers/consent.js +78 -34
  255. package/dist/react/renderers/consent.js.map +1 -1
  256. package/dist/react/renderers/date.js +1 -3
  257. package/dist/react/renderers/date.js.map +1 -1
  258. package/dist/react/renderers/email.js +1 -2
  259. package/dist/react/renderers/email.js.map +1 -1
  260. package/dist/react/renderers/file.js +1 -2
  261. package/dist/react/renderers/file.js.map +1 -1
  262. package/dist/react/renderers/index.js +3 -0
  263. package/dist/react/renderers/index.js.map +1 -1
  264. package/dist/react/renderers/number.js +1 -2
  265. package/dist/react/renderers/number.js.map +1 -1
  266. package/dist/react/renderers/region.js +45 -0
  267. package/dist/react/renderers/region.js.map +1 -0
  268. package/dist/react/renderers/repeater.js +7 -10
  269. package/dist/react/renderers/repeater.js.map +1 -1
  270. package/dist/react/renderers/select.js +1 -2
  271. package/dist/react/renderers/select.js.map +1 -1
  272. package/dist/react/renderers/text.js +1 -2
  273. package/dist/react/renderers/text.js.map +1 -1
  274. package/dist/react/renderers/textarea.js +1 -2
  275. package/dist/react/renderers/textarea.js.map +1 -1
  276. package/dist/react/state.d.ts +0 -3
  277. package/dist/react/state.js +7 -11
  278. package/dist/react/state.js.map +1 -1
  279. package/dist/react/useField.d.ts +0 -1
  280. package/dist/react/useField.js +0 -1
  281. package/dist/react/useField.js.map +1 -1
  282. package/dist/react/useFormState.d.ts +1 -1
  283. package/dist/react/useFormState.js +1 -1
  284. package/dist/react/useFormState.js.map +1 -1
  285. package/dist/react/validateField.js +3 -6
  286. package/dist/react/validateField.js.map +1 -1
  287. package/dist/recall/interpolate.d.ts +4 -3
  288. package/dist/recall/interpolate.js +5 -4
  289. package/dist/recall/interpolate.js.map +1 -1
  290. package/dist/recall/resolver.d.ts +1 -1
  291. package/dist/recall/resolver.js +14 -2
  292. package/dist/recall/resolver.js.map +1 -1
  293. package/dist/spam/captcha.d.ts +1 -1
  294. package/dist/spam/captcha.js +1 -1
  295. package/dist/spam/captcha.js.map +1 -1
  296. package/dist/submissions/SubmissionAnswers.js +6 -2
  297. package/dist/submissions/SubmissionAnswers.js.map +1 -1
  298. package/dist/submissions/SubmissionAnswersClient.js +100 -64
  299. package/dist/submissions/SubmissionAnswersClient.js.map +1 -1
  300. package/dist/submissions/createSubmission.d.ts +36 -0
  301. package/dist/submissions/createSubmission.js +26 -0
  302. package/dist/submissions/createSubmission.js.map +1 -0
  303. package/dist/submissions/runSubmission.d.ts +10 -0
  304. package/dist/submissions/runSubmission.js +31 -19
  305. package/dist/submissions/runSubmission.js.map +1 -1
  306. package/dist/submissions/types.d.ts +11 -4
  307. package/dist/submissions/validateSubmission.js +39 -23
  308. package/dist/submissions/validateSubmission.js.map +1 -1
  309. package/dist/submissions/votedCookie.js +3 -3
  310. package/dist/submissions/votedCookie.js.map +1 -1
  311. package/dist/translations/de.js +104 -26
  312. package/dist/translations/de.js.map +1 -1
  313. package/dist/translations/en.js +105 -27
  314. package/dist/translations/en.js.map +1 -1
  315. package/dist/translations/keys.d.ts +99 -21
  316. package/dist/translations/keys.js +100 -22
  317. package/dist/translations/keys.js.map +1 -1
  318. package/dist/uploads/resolveFileRef.js +2 -1
  319. package/dist/uploads/resolveFileRef.js.map +1 -1
  320. package/dist/validation/buildRuleBlocks.js +18 -17
  321. package/dist/validation/buildRuleBlocks.js.map +1 -1
  322. package/dist/validation/builtin/email.js +1 -0
  323. package/dist/validation/builtin/email.js.map +1 -1
  324. package/dist/validation/builtin/matchesField.js +3 -7
  325. package/dist/validation/builtin/matchesField.js.map +1 -1
  326. package/dist/validation/builtin/max.js +1 -0
  327. package/dist/validation/builtin/max.js.map +1 -1
  328. package/dist/validation/builtin/maxDate.js +1 -0
  329. package/dist/validation/builtin/maxDate.js.map +1 -1
  330. package/dist/validation/builtin/maxLength.js +1 -0
  331. package/dist/validation/builtin/maxLength.js.map +1 -1
  332. package/dist/validation/builtin/min.js +1 -0
  333. package/dist/validation/builtin/min.js.map +1 -1
  334. package/dist/validation/builtin/minDate.js +1 -0
  335. package/dist/validation/builtin/minDate.js.map +1 -1
  336. package/dist/validation/builtin/minLength.js +1 -0
  337. package/dist/validation/builtin/minLength.js.map +1 -1
  338. package/dist/validation/builtin/notAlreadySubmitted.js +1 -0
  339. package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -1
  340. package/dist/validation/builtin/oneOf.js +1 -0
  341. package/dist/validation/builtin/oneOf.js.map +1 -1
  342. package/dist/validation/builtin/pattern.js +11 -2
  343. package/dist/validation/builtin/pattern.js.map +1 -1
  344. package/dist/validation/builtin/url.js +1 -0
  345. package/dist/validation/builtin/url.js.map +1 -1
  346. package/dist/validation/builtin/validateRegexParams.js +44 -0
  347. package/dist/validation/builtin/validateRegexParams.js.map +1 -0
  348. package/dist/validation/fieldTargetParam.d.ts +22 -0
  349. package/dist/validation/fieldTargetParam.js +38 -0
  350. package/dist/validation/fieldTargetParam.js.map +1 -0
  351. package/dist/validation/runValidation.js +8 -29
  352. package/dist/validation/runValidation.js.map +1 -1
  353. package/dist/validation/types.d.ts +5 -11
  354. package/package.json +6 -6
  355. package/dist/consent/buildConsentSourceConfig.js +0 -49
  356. package/dist/consent/buildConsentSourceConfig.js.map +0 -1
  357. package/dist/consent/builtin/index.d.ts +0 -17
  358. package/dist/consent/builtin/index.js +0 -21
  359. package/dist/consent/builtin/index.js.map +0 -1
  360. package/dist/consent/builtin/pageReference.js +0 -75
  361. package/dist/consent/builtin/pageReference.js.map +0 -1
  362. package/dist/consent/builtin/static.js +0 -48
  363. package/dist/consent/builtin/static.js.map +0 -1
  364. package/dist/consent/defineConsentSource.d.ts +0 -35
  365. package/dist/consent/defineConsentSource.js +0 -6
  366. package/dist/consent/defineConsentSource.js.map +0 -1
  367. package/dist/consent/registry.d.ts +0 -16
  368. package/dist/consent/registry.js +0 -16
  369. package/dist/consent/registry.js.map +0 -1
  370. package/dist/consent/resolveConsentLinks.d.ts +0 -19
  371. package/dist/consent/resolveConsentLinks.js +0 -26
  372. package/dist/consent/resolveConsentLinks.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regions.js","names":[],"sources":["../../../src/fields/data/regions.ts"],"sourcesContent":["/**\n * Fixed option sets for the built-in `country` and `state` field types: the author never authors\n * these, so unlike `select` they live in code, not per-instance config. A plain data module with no\n * dependencies, imported on both the server (validation, `format`, poll options) and the client (the\n * frontend renderer, the condition builder), so it must stay isomorphic. `value` is the stored code\n * and is the stable identity contract (never localize it); `label` is the English display name.\n */\n\n/** ISO 3166-1 alpha-2 codes with their English short names (every officially assigned code). */\nexport const COUNTRIES: { label: string; value: string }[] = [\n\t{ value: 'AF', label: 'Afghanistan' },\n\t{ value: 'AX', label: 'Åland Islands' },\n\t{ value: 'AL', label: 'Albania' },\n\t{ value: 'DZ', label: 'Algeria' },\n\t{ value: 'AS', label: 'American Samoa' },\n\t{ value: 'AD', label: 'Andorra' },\n\t{ value: 'AO', label: 'Angola' },\n\t{ value: 'AI', label: 'Anguilla' },\n\t{ value: 'AQ', label: 'Antarctica' },\n\t{ value: 'AG', label: 'Antigua and Barbuda' },\n\t{ value: 'AR', label: 'Argentina' },\n\t{ value: 'AM', label: 'Armenia' },\n\t{ value: 'AW', label: 'Aruba' },\n\t{ value: 'AU', label: 'Australia' },\n\t{ value: 'AT', label: 'Austria' },\n\t{ value: 'AZ', label: 'Azerbaijan' },\n\t{ value: 'BS', label: 'Bahamas' },\n\t{ value: 'BH', label: 'Bahrain' },\n\t{ value: 'BD', label: 'Bangladesh' },\n\t{ value: 'BB', label: 'Barbados' },\n\t{ value: 'BY', label: 'Belarus' },\n\t{ value: 'BE', label: 'Belgium' },\n\t{ value: 'BZ', label: 'Belize' },\n\t{ value: 'BJ', label: 'Benin' },\n\t{ value: 'BM', label: 'Bermuda' },\n\t{ value: 'BT', label: 'Bhutan' },\n\t{ value: 'BO', label: 'Bolivia' },\n\t{ value: 'BQ', label: 'Bonaire, Sint Eustatius and Saba' },\n\t{ value: 'BA', label: 'Bosnia and Herzegovina' },\n\t{ value: 'BW', label: 'Botswana' },\n\t{ value: 'BV', label: 'Bouvet Island' },\n\t{ value: 'BR', label: 'Brazil' },\n\t{ value: 'IO', label: 'British Indian Ocean Territory' },\n\t{ value: 'BN', label: 'Brunei Darussalam' },\n\t{ value: 'BG', label: 'Bulgaria' },\n\t{ value: 'BF', label: 'Burkina Faso' },\n\t{ value: 'BI', label: 'Burundi' },\n\t{ value: 'CV', label: 'Cabo Verde' },\n\t{ value: 'KH', label: 'Cambodia' },\n\t{ value: 'CM', label: 'Cameroon' },\n\t{ value: 'CA', label: 'Canada' },\n\t{ value: 'KY', label: 'Cayman Islands' },\n\t{ value: 'CF', label: 'Central African Republic' },\n\t{ value: 'TD', label: 'Chad' },\n\t{ value: 'CL', label: 'Chile' },\n\t{ value: 'CN', label: 'China' },\n\t{ value: 'CX', label: 'Christmas Island' },\n\t{ value: 'CC', label: 'Cocos (Keeling) Islands' },\n\t{ value: 'CO', label: 'Colombia' },\n\t{ value: 'KM', label: 'Comoros' },\n\t{ value: 'CG', label: 'Congo' },\n\t{ value: 'CD', label: 'Congo, Democratic Republic of the' },\n\t{ value: 'CK', label: 'Cook Islands' },\n\t{ value: 'CR', label: 'Costa Rica' },\n\t{ value: 'CI', label: \"Côte d'Ivoire\" },\n\t{ value: 'HR', label: 'Croatia' },\n\t{ value: 'CU', label: 'Cuba' },\n\t{ value: 'CW', label: 'Curaçao' },\n\t{ value: 'CY', label: 'Cyprus' },\n\t{ value: 'CZ', label: 'Czechia' },\n\t{ value: 'DK', label: 'Denmark' },\n\t{ value: 'DJ', label: 'Djibouti' },\n\t{ value: 'DM', label: 'Dominica' },\n\t{ value: 'DO', label: 'Dominican Republic' },\n\t{ value: 'EC', label: 'Ecuador' },\n\t{ value: 'EG', label: 'Egypt' },\n\t{ value: 'SV', label: 'El Salvador' },\n\t{ value: 'GQ', label: 'Equatorial Guinea' },\n\t{ value: 'ER', label: 'Eritrea' },\n\t{ value: 'EE', label: 'Estonia' },\n\t{ value: 'SZ', label: 'Eswatini' },\n\t{ value: 'ET', label: 'Ethiopia' },\n\t{ value: 'FK', label: 'Falkland Islands (Malvinas)' },\n\t{ value: 'FO', label: 'Faroe Islands' },\n\t{ value: 'FJ', label: 'Fiji' },\n\t{ value: 'FI', label: 'Finland' },\n\t{ value: 'FR', label: 'France' },\n\t{ value: 'GF', label: 'French Guiana' },\n\t{ value: 'PF', label: 'French Polynesia' },\n\t{ value: 'TF', label: 'French Southern Territories' },\n\t{ value: 'GA', label: 'Gabon' },\n\t{ value: 'GM', label: 'Gambia' },\n\t{ value: 'GE', label: 'Georgia' },\n\t{ value: 'DE', label: 'Germany' },\n\t{ value: 'GH', label: 'Ghana' },\n\t{ value: 'GI', label: 'Gibraltar' },\n\t{ value: 'GR', label: 'Greece' },\n\t{ value: 'GL', label: 'Greenland' },\n\t{ value: 'GD', label: 'Grenada' },\n\t{ value: 'GP', label: 'Guadeloupe' },\n\t{ value: 'GU', label: 'Guam' },\n\t{ value: 'GT', label: 'Guatemala' },\n\t{ value: 'GG', label: 'Guernsey' },\n\t{ value: 'GN', label: 'Guinea' },\n\t{ value: 'GW', label: 'Guinea-Bissau' },\n\t{ value: 'GY', label: 'Guyana' },\n\t{ value: 'HT', label: 'Haiti' },\n\t{ value: 'HM', label: 'Heard Island and McDonald Islands' },\n\t{ value: 'VA', label: 'Holy See' },\n\t{ value: 'HN', label: 'Honduras' },\n\t{ value: 'HK', label: 'Hong Kong' },\n\t{ value: 'HU', label: 'Hungary' },\n\t{ value: 'IS', label: 'Iceland' },\n\t{ value: 'IN', label: 'India' },\n\t{ value: 'ID', label: 'Indonesia' },\n\t{ value: 'IR', label: 'Iran' },\n\t{ value: 'IQ', label: 'Iraq' },\n\t{ value: 'IE', label: 'Ireland' },\n\t{ value: 'IM', label: 'Isle of Man' },\n\t{ value: 'IL', label: 'Israel' },\n\t{ value: 'IT', label: 'Italy' },\n\t{ value: 'JM', label: 'Jamaica' },\n\t{ value: 'JP', label: 'Japan' },\n\t{ value: 'JE', label: 'Jersey' },\n\t{ value: 'JO', label: 'Jordan' },\n\t{ value: 'KZ', label: 'Kazakhstan' },\n\t{ value: 'KE', label: 'Kenya' },\n\t{ value: 'KI', label: 'Kiribati' },\n\t{ value: 'KP', label: \"Korea, Democratic People's Republic of\" },\n\t{ value: 'KR', label: 'Korea, Republic of' },\n\t{ value: 'KW', label: 'Kuwait' },\n\t{ value: 'KG', label: 'Kyrgyzstan' },\n\t{ value: 'LA', label: \"Lao People's Democratic Republic\" },\n\t{ value: 'LV', label: 'Latvia' },\n\t{ value: 'LB', label: 'Lebanon' },\n\t{ value: 'LS', label: 'Lesotho' },\n\t{ value: 'LR', label: 'Liberia' },\n\t{ value: 'LY', label: 'Libya' },\n\t{ value: 'LI', label: 'Liechtenstein' },\n\t{ value: 'LT', label: 'Lithuania' },\n\t{ value: 'LU', label: 'Luxembourg' },\n\t{ value: 'MO', label: 'Macao' },\n\t{ value: 'MG', label: 'Madagascar' },\n\t{ value: 'MW', label: 'Malawi' },\n\t{ value: 'MY', label: 'Malaysia' },\n\t{ value: 'MV', label: 'Maldives' },\n\t{ value: 'ML', label: 'Mali' },\n\t{ value: 'MT', label: 'Malta' },\n\t{ value: 'MH', label: 'Marshall Islands' },\n\t{ value: 'MQ', label: 'Martinique' },\n\t{ value: 'MR', label: 'Mauritania' },\n\t{ value: 'MU', label: 'Mauritius' },\n\t{ value: 'YT', label: 'Mayotte' },\n\t{ value: 'MX', label: 'Mexico' },\n\t{ value: 'FM', label: 'Micronesia' },\n\t{ value: 'MD', label: 'Moldova' },\n\t{ value: 'MC', label: 'Monaco' },\n\t{ value: 'MN', label: 'Mongolia' },\n\t{ value: 'ME', label: 'Montenegro' },\n\t{ value: 'MS', label: 'Montserrat' },\n\t{ value: 'MA', label: 'Morocco' },\n\t{ value: 'MZ', label: 'Mozambique' },\n\t{ value: 'MM', label: 'Myanmar' },\n\t{ value: 'NA', label: 'Namibia' },\n\t{ value: 'NR', label: 'Nauru' },\n\t{ value: 'NP', label: 'Nepal' },\n\t{ value: 'NL', label: 'Netherlands' },\n\t{ value: 'NC', label: 'New Caledonia' },\n\t{ value: 'NZ', label: 'New Zealand' },\n\t{ value: 'NI', label: 'Nicaragua' },\n\t{ value: 'NE', label: 'Niger' },\n\t{ value: 'NG', label: 'Nigeria' },\n\t{ value: 'NU', label: 'Niue' },\n\t{ value: 'NF', label: 'Norfolk Island' },\n\t{ value: 'MK', label: 'North Macedonia' },\n\t{ value: 'MP', label: 'Northern Mariana Islands' },\n\t{ value: 'NO', label: 'Norway' },\n\t{ value: 'OM', label: 'Oman' },\n\t{ value: 'PK', label: 'Pakistan' },\n\t{ value: 'PW', label: 'Palau' },\n\t{ value: 'PS', label: 'Palestine, State of' },\n\t{ value: 'PA', label: 'Panama' },\n\t{ value: 'PG', label: 'Papua New Guinea' },\n\t{ value: 'PY', label: 'Paraguay' },\n\t{ value: 'PE', label: 'Peru' },\n\t{ value: 'PH', label: 'Philippines' },\n\t{ value: 'PN', label: 'Pitcairn' },\n\t{ value: 'PL', label: 'Poland' },\n\t{ value: 'PT', label: 'Portugal' },\n\t{ value: 'PR', label: 'Puerto Rico' },\n\t{ value: 'QA', label: 'Qatar' },\n\t{ value: 'RE', label: 'Réunion' },\n\t{ value: 'RO', label: 'Romania' },\n\t{ value: 'RU', label: 'Russian Federation' },\n\t{ value: 'RW', label: 'Rwanda' },\n\t{ value: 'BL', label: 'Saint Barthélemy' },\n\t{ value: 'SH', label: 'Saint Helena, Ascension and Tristan da Cunha' },\n\t{ value: 'KN', label: 'Saint Kitts and Nevis' },\n\t{ value: 'LC', label: 'Saint Lucia' },\n\t{ value: 'MF', label: 'Saint Martin (French part)' },\n\t{ value: 'PM', label: 'Saint Pierre and Miquelon' },\n\t{ value: 'VC', label: 'Saint Vincent and the Grenadines' },\n\t{ value: 'WS', label: 'Samoa' },\n\t{ value: 'SM', label: 'San Marino' },\n\t{ value: 'ST', label: 'Sao Tome and Principe' },\n\t{ value: 'SA', label: 'Saudi Arabia' },\n\t{ value: 'SN', label: 'Senegal' },\n\t{ value: 'RS', label: 'Serbia' },\n\t{ value: 'SC', label: 'Seychelles' },\n\t{ value: 'SL', label: 'Sierra Leone' },\n\t{ value: 'SG', label: 'Singapore' },\n\t{ value: 'SX', label: 'Sint Maarten (Dutch part)' },\n\t{ value: 'SK', label: 'Slovakia' },\n\t{ value: 'SI', label: 'Slovenia' },\n\t{ value: 'SB', label: 'Solomon Islands' },\n\t{ value: 'SO', label: 'Somalia' },\n\t{ value: 'ZA', label: 'South Africa' },\n\t{ value: 'GS', label: 'South Georgia and the South Sandwich Islands' },\n\t{ value: 'SS', label: 'South Sudan' },\n\t{ value: 'ES', label: 'Spain' },\n\t{ value: 'LK', label: 'Sri Lanka' },\n\t{ value: 'SD', label: 'Sudan' },\n\t{ value: 'SR', label: 'Suriname' },\n\t{ value: 'SJ', label: 'Svalbard and Jan Mayen' },\n\t{ value: 'SE', label: 'Sweden' },\n\t{ value: 'CH', label: 'Switzerland' },\n\t{ value: 'SY', label: 'Syrian Arab Republic' },\n\t{ value: 'TW', label: 'Taiwan' },\n\t{ value: 'TJ', label: 'Tajikistan' },\n\t{ value: 'TZ', label: 'Tanzania' },\n\t{ value: 'TH', label: 'Thailand' },\n\t{ value: 'TL', label: 'Timor-Leste' },\n\t{ value: 'TG', label: 'Togo' },\n\t{ value: 'TK', label: 'Tokelau' },\n\t{ value: 'TO', label: 'Tonga' },\n\t{ value: 'TT', label: 'Trinidad and Tobago' },\n\t{ value: 'TN', label: 'Tunisia' },\n\t{ value: 'TR', label: 'Türkiye' },\n\t{ value: 'TM', label: 'Turkmenistan' },\n\t{ value: 'TC', label: 'Turks and Caicos Islands' },\n\t{ value: 'TV', label: 'Tuvalu' },\n\t{ value: 'UG', label: 'Uganda' },\n\t{ value: 'UA', label: 'Ukraine' },\n\t{ value: 'AE', label: 'United Arab Emirates' },\n\t{ value: 'GB', label: 'United Kingdom' },\n\t{ value: 'US', label: 'United States of America' },\n\t{ value: 'UM', label: 'United States Minor Outlying Islands' },\n\t{ value: 'UY', label: 'Uruguay' },\n\t{ value: 'UZ', label: 'Uzbekistan' },\n\t{ value: 'VU', label: 'Vanuatu' },\n\t{ value: 'VE', label: 'Venezuela' },\n\t{ value: 'VN', label: 'Viet Nam' },\n\t{ value: 'VG', label: 'Virgin Islands (British)' },\n\t{ value: 'VI', label: 'Virgin Islands (U.S.)' },\n\t{ value: 'WF', label: 'Wallis and Futuna' },\n\t{ value: 'EH', label: 'Western Sahara' },\n\t{ value: 'YE', label: 'Yemen' },\n\t{ value: 'ZM', label: 'Zambia' },\n\t{ value: 'ZW', label: 'Zimbabwe' },\n]\n\n/** The 50 US states plus the District of Columbia, keyed by USPS code. Matches native's US-only `state` block. */\nexport const US_STATES: { label: string; value: string }[] = [\n\t{ value: 'AL', label: 'Alabama' },\n\t{ value: 'AK', label: 'Alaska' },\n\t{ value: 'AZ', label: 'Arizona' },\n\t{ value: 'AR', label: 'Arkansas' },\n\t{ value: 'CA', label: 'California' },\n\t{ value: 'CO', label: 'Colorado' },\n\t{ value: 'CT', label: 'Connecticut' },\n\t{ value: 'DE', label: 'Delaware' },\n\t{ value: 'DC', label: 'District of Columbia' },\n\t{ value: 'FL', label: 'Florida' },\n\t{ value: 'GA', label: 'Georgia' },\n\t{ value: 'HI', label: 'Hawaii' },\n\t{ value: 'ID', label: 'Idaho' },\n\t{ value: 'IL', label: 'Illinois' },\n\t{ value: 'IN', label: 'Indiana' },\n\t{ value: 'IA', label: 'Iowa' },\n\t{ value: 'KS', label: 'Kansas' },\n\t{ value: 'KY', label: 'Kentucky' },\n\t{ value: 'LA', label: 'Louisiana' },\n\t{ value: 'ME', label: 'Maine' },\n\t{ value: 'MD', label: 'Maryland' },\n\t{ value: 'MA', label: 'Massachusetts' },\n\t{ value: 'MI', label: 'Michigan' },\n\t{ value: 'MN', label: 'Minnesota' },\n\t{ value: 'MS', label: 'Mississippi' },\n\t{ value: 'MO', label: 'Missouri' },\n\t{ value: 'MT', label: 'Montana' },\n\t{ value: 'NE', label: 'Nebraska' },\n\t{ value: 'NV', label: 'Nevada' },\n\t{ value: 'NH', label: 'New Hampshire' },\n\t{ value: 'NJ', label: 'New Jersey' },\n\t{ value: 'NM', label: 'New Mexico' },\n\t{ value: 'NY', label: 'New York' },\n\t{ value: 'NC', label: 'North Carolina' },\n\t{ value: 'ND', label: 'North Dakota' },\n\t{ value: 'OH', label: 'Ohio' },\n\t{ value: 'OK', label: 'Oklahoma' },\n\t{ value: 'OR', label: 'Oregon' },\n\t{ value: 'PA', label: 'Pennsylvania' },\n\t{ value: 'RI', label: 'Rhode Island' },\n\t{ value: 'SC', label: 'South Carolina' },\n\t{ value: 'SD', label: 'South Dakota' },\n\t{ value: 'TN', label: 'Tennessee' },\n\t{ value: 'TX', label: 'Texas' },\n\t{ value: 'UT', label: 'Utah' },\n\t{ value: 'VT', label: 'Vermont' },\n\t{ value: 'VA', label: 'Virginia' },\n\t{ value: 'WA', label: 'Washington' },\n\t{ value: 'WV', label: 'West Virginia' },\n\t{ value: 'WI', label: 'Wisconsin' },\n\t{ value: 'WY', label: 'Wyoming' },\n]\n\nconst countryLabelByValue = new Map(COUNTRIES.map((country) => [country.value, country.label]))\nconst usStateLabelByValue = new Map(US_STATES.map((state) => [state.value, state.label]))\n\n/** The English name for an ISO country code, or `undefined` when the code is not a known country. */\nexport const countryLabel = (value: string): string | undefined => countryLabelByValue.get(value)\n\n/** The name for a US state/DC code, or `undefined` when the code is not a known state. */\nexport const usStateLabel = (value: string): string | undefined => usStateLabelByValue.get(value)\n\n/** Whether `value` is a known ISO country code. */\nexport const isCountryCode = (value: string): boolean => countryLabelByValue.has(value)\n\n/** Whether `value` is a known US state/DC code. */\nexport const isUsStateCode = (value: string): boolean => usStateLabelByValue.has(value)\n\nconst FIXED_FIELD_OPTIONS: Record<string, { label: string; value: string }[]> = {\n\tcountry: COUNTRIES,\n\tstate: US_STATES,\n}\n\n/**\n * The fixed option set a built-in field type carries in code (country/state), or `undefined` for\n * every other type. Lets surfaces that key off authored `options` (the condition builder) offer the\n * same choices for these types, which author none.\n */\nexport const fixedFieldOptions = (\n\tblockType: string\n): { label: string; value: string }[] | undefined => FIXED_FIELD_OPTIONS[blockType]\n"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { FormFieldInstance } from "../submissions/types.js";
2
+
3
+ //#region src/fields/fieldKey.d.ts
4
+ /**
5
+ * Stable identity for a field instance: its machine name, else the hidden block row `id` Payload
6
+ * injects into every row (bare blocks carry no name). Flow step assignments and React render keys
7
+ * use this, so name-based flows keep working for named fields while bare blocks are addressable
8
+ * by row id. Admin-authored rows always carry a client-generated id; a bare row created via
9
+ * `payload.create` without an explicit `id` gets one during the write, so it cannot be
10
+ * flow-referenced in that same call.
11
+ */
12
+ declare const fieldKey: (instance: FormFieldInstance) => string;
13
+ //#endregion
14
+ export { fieldKey };
15
+ //# sourceMappingURL=fieldKey.d.ts.map
@@ -0,0 +1,16 @@
1
+ //#region src/fields/fieldKey.ts
2
+ /** Whether the instance carries a machine name. Bare blocks (e.g. `message`) do not. */
3
+ const isNamedField = (instance) => typeof instance.name === "string";
4
+ /**
5
+ * Stable identity for a field instance: its machine name, else the hidden block row `id` Payload
6
+ * injects into every row (bare blocks carry no name). Flow step assignments and React render keys
7
+ * use this, so name-based flows keep working for named fields while bare blocks are addressable
8
+ * by row id. Admin-authored rows always carry a client-generated id; a bare row created via
9
+ * `payload.create` without an explicit `id` gets one during the write, so it cannot be
10
+ * flow-referenced in that same call.
11
+ */
12
+ const fieldKey = (instance) => instance.name ?? String(instance.id);
13
+ //#endregion
14
+ export { fieldKey, isNamedField };
15
+
16
+ //# sourceMappingURL=fieldKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fieldKey.js","names":[],"sources":["../../src/fields/fieldKey.ts"],"sourcesContent":["import type { FormFieldInstance } from '../submissions/types'\n\n/** A field instance guaranteed to carry a machine name (every value-bearing field). */\nexport type NamedFormFieldInstance = FormFieldInstance & { name: string }\n\n/** Whether the instance carries a machine name. Bare blocks (e.g. `message`) do not. */\nexport const isNamedField = (instance: FormFieldInstance): instance is NamedFormFieldInstance =>\n\ttypeof instance.name === 'string'\n\n/**\n * Stable identity for a field instance: its machine name, else the hidden block row `id` Payload\n * injects into every row (bare blocks carry no name). Flow step assignments and React render keys\n * use this, so name-based flows keep working for named fields while bare blocks are addressable\n * by row id. Admin-authored rows always carry a client-generated id; a bare row created via\n * `payload.create` without an explicit `id` gets one during the write, so it cannot be\n * flow-referenced in that same call.\n */\nexport const fieldKey = (instance: FormFieldInstance): string =>\n\tinstance.name ?? String(instance.id)\n"],"mappings":";;AAMA,MAAa,gBAAgB,aAC5B,OAAO,SAAS,SAAS;;;;;;;;;AAU1B,MAAa,YAAY,aACxB,SAAS,QAAQ,OAAO,SAAS,EAAE"}
@@ -1,25 +1,30 @@
1
1
  //#region src/fields/fieldNamesOfType.ts
2
2
  /**
3
- * Names of form `fields` blocks whose `blockType` is in `types`, trimmed and non-empty.
4
- * Server-safe and defensive: `fields` may be missing, non-array, or contain garbled rows
5
- * mid-edit. The single source of truth for which field names are selectable and valid as
6
- * a field reference (e.g. the confirmation action's `toField`), so client options and
7
- * server validation cannot drift apart.
3
+ * Trimmed, non-empty names of form `fields` rows, optionally filtered to a set of block `types`.
4
+ * Server-safe and defensive: `fields` may be missing, non-array, or contain garbled rows mid-edit.
5
+ * The single source of truth for which field names are selectable and valid as a field reference,
6
+ * so a picker's client options and its server-side existence check cannot drift apart. Any caller
7
+ * mounting `FieldNameSelect` (or validating its stored value) MUST resolve names through here with
8
+ * the same `types` argument (or lack of one) it hands the picker.
8
9
  */
9
- const fieldNamesOfType = (fields, types) => {
10
+ const collectNames = (fields, types) => {
10
11
  if (!Array.isArray(fields)) return [];
11
12
  const names = [];
12
13
  for (const row of fields) {
13
14
  if (!row || typeof row !== "object") continue;
14
15
  const { blockType, name } = row;
15
- if (typeof blockType !== "string" || !types.includes(blockType)) continue;
16
+ if (types && (typeof blockType !== "string" || !types.includes(blockType))) continue;
16
17
  if (typeof name !== "string") continue;
17
18
  const trimmed = name.trim();
18
19
  if (trimmed.length > 0) names.push(trimmed);
19
20
  }
20
21
  return names;
21
22
  };
23
+ /** Names of form `fields` blocks whose `blockType` is in `types`. */
24
+ const fieldNamesOfType = (fields, types) => collectNames(fields, types);
25
+ /** Names of every named form `fields` block, regardless of type. Bare (nameless) blocks are excluded. */
26
+ const fieldNames = (fields) => collectNames(fields, void 0);
22
27
  //#endregion
23
- export { fieldNamesOfType };
28
+ export { fieldNames, fieldNamesOfType };
24
29
 
25
30
  //# sourceMappingURL=fieldNamesOfType.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fieldNamesOfType.js","names":[],"sources":["../../src/fields/fieldNamesOfType.ts"],"sourcesContent":["/**\n * Names of form `fields` blocks whose `blockType` is in `types`, trimmed and non-empty.\n * Server-safe and defensive: `fields` may be missing, non-array, or contain garbled rows\n * mid-edit. The single source of truth for which field names are selectable and valid as\n * a field reference (e.g. the confirmation action's `toField`), so client options and\n * server validation cannot drift apart.\n */\nexport const fieldNamesOfType = (fields: unknown, types: readonly string[]): string[] => {\n\tif (!Array.isArray(fields)) {\n\t\treturn []\n\t}\n\tconst names: string[] = []\n\tfor (const row of fields) {\n\t\tif (!row || typeof row !== 'object') {\n\t\t\tcontinue\n\t\t}\n\t\tconst { blockType, name } = row as { blockType?: unknown; name?: unknown }\n\t\tif (typeof blockType !== 'string' || !types.includes(blockType)) {\n\t\t\tcontinue\n\t\t}\n\t\tif (typeof name !== 'string') {\n\t\t\tcontinue\n\t\t}\n\t\tconst trimmed = name.trim()\n\t\tif (trimmed.length > 0) {\n\t\t\tnames.push(trimmed)\n\t\t}\n\t}\n\treturn names\n}\n"],"mappings":";;;;;;;;AAOA,MAAa,oBAAoB,QAAiB,UAAuC;CACxF,IAAI,CAAC,MAAM,QAAQ,MAAM,GACxB,OAAO,CAAC;CAET,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,OAAO,QAAQ;EACzB,IAAI,CAAC,OAAO,OAAO,QAAQ,UAC1B;EAED,MAAM,EAAE,WAAW,SAAS;EAC5B,IAAI,OAAO,cAAc,YAAY,CAAC,MAAM,SAAS,SAAS,GAC7D;EAED,IAAI,OAAO,SAAS,UACnB;EAED,MAAM,UAAU,KAAK,KAAK;EAC1B,IAAI,QAAQ,SAAS,GACpB,MAAM,KAAK,OAAO;CAEpB;CACA,OAAO;AACR"}
1
+ {"version":3,"file":"fieldNamesOfType.js","names":[],"sources":["../../src/fields/fieldNamesOfType.ts"],"sourcesContent":["/**\n * Trimmed, non-empty names of form `fields` rows, optionally filtered to a set of block `types`.\n * Server-safe and defensive: `fields` may be missing, non-array, or contain garbled rows mid-edit.\n * The single source of truth for which field names are selectable and valid as a field reference,\n * so a picker's client options and its server-side existence check cannot drift apart. Any caller\n * mounting `FieldNameSelect` (or validating its stored value) MUST resolve names through here with\n * the same `types` argument (or lack of one) it hands the picker.\n */\nconst collectNames = (fields: unknown, types: readonly string[] | undefined): string[] => {\n\tif (!Array.isArray(fields)) {\n\t\treturn []\n\t}\n\tconst names: string[] = []\n\tfor (const row of fields) {\n\t\tif (!row || typeof row !== 'object') {\n\t\t\tcontinue\n\t\t}\n\t\tconst { blockType, name } = row as { blockType?: unknown; name?: unknown }\n\t\tif (types && (typeof blockType !== 'string' || !types.includes(blockType))) {\n\t\t\tcontinue\n\t\t}\n\t\tif (typeof name !== 'string') {\n\t\t\tcontinue\n\t\t}\n\t\tconst trimmed = name.trim()\n\t\tif (trimmed.length > 0) {\n\t\t\tnames.push(trimmed)\n\t\t}\n\t}\n\treturn names\n}\n\n/** Names of form `fields` blocks whose `blockType` is in `types`. */\nexport const fieldNamesOfType = (fields: unknown, types: readonly string[]): string[] =>\n\tcollectNames(fields, types)\n\n/** Names of every named form `fields` block, regardless of type. Bare (nameless) blocks are excluded. */\nexport const fieldNames = (fields: unknown): string[] => collectNames(fields, undefined)\n"],"mappings":";;;;;;;;;AAQA,MAAM,gBAAgB,QAAiB,UAAmD;CACzF,IAAI,CAAC,MAAM,QAAQ,MAAM,GACxB,OAAO,CAAC;CAET,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,OAAO,QAAQ;EACzB,IAAI,CAAC,OAAO,OAAO,QAAQ,UAC1B;EAED,MAAM,EAAE,WAAW,SAAS;EAC5B,IAAI,UAAU,OAAO,cAAc,YAAY,CAAC,MAAM,SAAS,SAAS,IACvE;EAED,IAAI,OAAO,SAAS,UACnB;EAED,MAAM,UAAU,KAAK,KAAK;EAC1B,IAAI,QAAQ,SAAS,GACpB,MAAM,KAAK,OAAO;CAEpB;CACA,OAAO;AACR;;AAGA,MAAa,oBAAoB,QAAiB,UACjD,aAAa,QAAQ,KAAK;;AAG3B,MAAa,cAAc,WAA8B,aAAa,QAAQ,KAAA,CAAS"}
@@ -0,0 +1,20 @@
1
+ //#region src/fields/instanceOptions.ts
2
+ /**
3
+ * Normalize a field instance's authored options to `{ value, label }` pairs, dropping entries
4
+ * without a string value and falling back to the value as label. Returns `undefined` when the
5
+ * instance declares no usable options, so callers can distinguish "not a choice field" from an
6
+ * empty choice set. Shared by response aggregation and poll outcome resolution so both read the
7
+ * same choice set from a form document.
8
+ */
9
+ const instanceOptionsOf = (field) => {
10
+ if (!Array.isArray(field.options)) return;
11
+ const options = field.options.filter((option) => typeof option?.value === "string").map((option) => ({
12
+ value: String(option.value),
13
+ label: option.label ?? String(option.value)
14
+ }));
15
+ return options.length > 0 ? options : void 0;
16
+ };
17
+ //#endregion
18
+ export { instanceOptionsOf };
19
+
20
+ //# sourceMappingURL=instanceOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instanceOptions.js","names":[],"sources":["../../src/fields/instanceOptions.ts"],"sourcesContent":["import type { FormFieldInstance } from '../submissions/types'\n\n/**\n * Normalize a field instance's authored options to `{ value, label }` pairs, dropping entries\n * without a string value and falling back to the value as label. Returns `undefined` when the\n * instance declares no usable options, so callers can distinguish \"not a choice field\" from an\n * empty choice set. Shared by response aggregation and poll outcome resolution so both read the\n * same choice set from a form document.\n */\nexport const instanceOptionsOf = (\n\tfield: FormFieldInstance\n): { value: string; label: string }[] | undefined => {\n\tif (!Array.isArray(field.options)) {\n\t\treturn undefined\n\t}\n\tconst options = (field.options as Array<{ label?: string; value?: string }>)\n\t\t.filter((option) => typeof option?.value === 'string')\n\t\t.map((option) => ({ value: String(option.value), label: option.label ?? String(option.value) }))\n\treturn options.length > 0 ? options : undefined\n}\n"],"mappings":";;;;;;;;AASA,MAAa,qBACZ,UACoD;CACpD,IAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,GAC/B;CAED,MAAM,UAAW,MAAM,QACrB,QAAQ,WAAW,OAAO,QAAQ,UAAU,QAAQ,EACpD,KAAK,YAAY;EAAE,OAAO,OAAO,OAAO,KAAK;EAAG,OAAO,OAAO,SAAS,OAAO,OAAO,KAAK;CAAE,EAAE;CAChG,OAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;AACvC"}
@@ -1,4 +1,5 @@
1
1
  import { AnyFormFieldDefinition } from "./types.js";
2
+ import { Payload } from "payload";
2
3
 
3
4
  //#region src/fields/registry.d.ts
4
5
  type FieldTypeRegistry = Map<string, AnyFormFieldDefinition>;
@@ -1,3 +1,4 @@
1
+ import { customStateOf, stashCustomState } from "../plugin/customState.js";
1
2
  //#region src/fields/registry.ts
2
3
  const buildRegistry = (definitions) => {
3
4
  const registry = /* @__PURE__ */ new Map();
@@ -5,9 +6,18 @@ const buildRegistry = (definitions) => {
5
6
  return registry;
6
7
  };
7
8
  /**
9
+ * A bare definition without `value: 'none'` would no-op silently: its instances are nameless,
10
+ * so `validate`/`schema` never run and no value is ever stored. Failing the boot makes the
11
+ * misconfiguration impossible to ship.
12
+ */
13
+ const assertBareContract = (definition) => {
14
+ if (definition.bare === true && definition.value !== "none") throw new Error(`form-builder: bare field types must be display-only (value: 'none'); '${definition.type}' declares value '${definition.value}'`);
15
+ };
16
+ /**
8
17
  * Resolve the active field-type registry from the built-in defaults and the plugin `fields` option.
9
18
  * `false` removes a type, `true` keeps the default, an object adds a new type or replaces an existing
10
- * one (its `type` is forced to the config key so an override cannot rename the slot).
19
+ * one (its `type` is forced to the config key so an override cannot rename the slot). Every resolved
20
+ * definition must honor the bare contract; a violation throws at plugin boot.
11
21
  */
12
22
  const resolveFieldTypes = (defaults, config = {}) => {
13
23
  const registry = buildRegistry(defaults);
@@ -16,9 +26,18 @@ const resolveFieldTypes = (defaults, config = {}) => {
16
26
  ...option,
17
27
  type
18
28
  });
29
+ for (const definition of registry.values()) assertBareContract(definition);
19
30
  return registry;
20
31
  };
32
+ /**
33
+ * Park the resolved field-type registry on the config so `resolveEffectivePollOptions` can look up
34
+ * a poll results field's definition (and its `resolveOptions`) at request time via `payload.config`,
35
+ * the same way poll option sources and consent sources are stashed for root-level helpers.
36
+ */
37
+ const stashFieldTypes = (custom, registry) => stashCustomState(custom, { fieldTypes: registry });
38
+ /** The field-type registry stashed at boot, or an empty registry when the plugin never booted. */
39
+ const fieldTypesOf = (payload) => customStateOf(payload).fieldTypes ?? /* @__PURE__ */ new Map();
21
40
  //#endregion
22
- export { buildRegistry, resolveFieldTypes };
41
+ export { buildRegistry, fieldTypesOf, resolveFieldTypes, stashFieldTypes };
23
42
 
24
43
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","names":[],"sources":["../../src/fields/registry.ts"],"sourcesContent":["import type { AnyFormFieldDefinition } from './types'\n\nexport type FieldTypeRegistry = Map<string, AnyFormFieldDefinition>\n\n/** Per-type opt-in: `false` removes a built-in, `true` keeps it, an object adds a new type or replaces one. */\nexport type FieldTypeOption = boolean | AnyFormFieldDefinition\n\nexport type FieldTypesConfig = Record<string, FieldTypeOption>\n\nexport const buildRegistry = (definitions: AnyFormFieldDefinition[]): FieldTypeRegistry => {\n\tconst registry: FieldTypeRegistry = new Map()\n\tfor (const definition of definitions) {\n\t\tregistry.set(definition.type, definition)\n\t}\n\treturn registry\n}\n\n/**\n * Resolve the active field-type registry from the built-in defaults and the plugin `fields` option.\n * `false` removes a type, `true` keeps the default, an object adds a new type or replaces an existing\n * one (its `type` is forced to the config key so an override cannot rename the slot).\n */\nexport const resolveFieldTypes = (\n\tdefaults: AnyFormFieldDefinition[],\n\tconfig: FieldTypesConfig = {}\n): FieldTypeRegistry => {\n\tconst registry = buildRegistry(defaults)\n\tfor (const [type, option] of Object.entries(config)) {\n\t\tif (option === false) {\n\t\t\tregistry.delete(type)\n\t\t} else if (option === true) {\n\t\t\t// keep the default; a no-op when no default exists for this key\n\t\t} else {\n\t\t\tregistry.set(type, { ...option, type })\n\t\t}\n\t}\n\treturn registry\n}\n"],"mappings":";AASA,MAAa,iBAAiB,gBAA6D;CAC1F,MAAM,2BAA8B,IAAI,IAAI;CAC5C,KAAK,MAAM,cAAc,aACxB,SAAS,IAAI,WAAW,MAAM,UAAU;CAEzC,OAAO;AACR;;;;;;AAOA,MAAa,qBACZ,UACA,SAA2B,CAAC,MACL;CACvB,MAAM,WAAW,cAAc,QAAQ;CACvC,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,MAAM,GACjD,IAAI,WAAW,OACd,SAAS,OAAO,IAAI;MACd,IAAI,WAAW,MAAM,CAE5B,OACC,SAAS,IAAI,MAAM;EAAE,GAAG;EAAQ;CAAK,CAAC;CAGxC,OAAO;AACR"}
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../src/fields/registry.ts"],"sourcesContent":["import type { Payload } from 'payload'\nimport { customStateOf, stashCustomState } from '../plugin/customState'\nimport type { AnyFormFieldDefinition } from './types'\n\nexport type FieldTypeRegistry = Map<string, AnyFormFieldDefinition>\n\n/** Per-type opt-in: `false` removes a built-in, `true` keeps it, an object adds a new type or replaces one. */\nexport type FieldTypeOption = boolean | AnyFormFieldDefinition\n\nexport type FieldTypesConfig = Record<string, FieldTypeOption>\n\nexport const buildRegistry = (definitions: AnyFormFieldDefinition[]): FieldTypeRegistry => {\n\tconst registry: FieldTypeRegistry = new Map()\n\tfor (const definition of definitions) {\n\t\tregistry.set(definition.type, definition)\n\t}\n\treturn registry\n}\n\n/**\n * A bare definition without `value: 'none'` would no-op silently: its instances are nameless,\n * so `validate`/`schema` never run and no value is ever stored. Failing the boot makes the\n * misconfiguration impossible to ship.\n */\nconst assertBareContract = (definition: AnyFormFieldDefinition): void => {\n\tif (definition.bare === true && definition.value !== 'none') {\n\t\tthrow new Error(\n\t\t\t`form-builder: bare field types must be display-only (value: 'none'); '${definition.type}' declares value '${definition.value}'`\n\t\t)\n\t}\n}\n\n/**\n * Resolve the active field-type registry from the built-in defaults and the plugin `fields` option.\n * `false` removes a type, `true` keeps the default, an object adds a new type or replaces an existing\n * one (its `type` is forced to the config key so an override cannot rename the slot). Every resolved\n * definition must honor the bare contract; a violation throws at plugin boot.\n */\nexport const resolveFieldTypes = (\n\tdefaults: AnyFormFieldDefinition[],\n\tconfig: FieldTypesConfig = {}\n): FieldTypeRegistry => {\n\tconst registry = buildRegistry(defaults)\n\tfor (const [type, option] of Object.entries(config)) {\n\t\tif (option === false) {\n\t\t\tregistry.delete(type)\n\t\t} else if (option === true) {\n\t\t\t// keep the default; a no-op when no default exists for this key\n\t\t} else {\n\t\t\tregistry.set(type, { ...option, type })\n\t\t}\n\t}\n\tfor (const definition of registry.values()) {\n\t\tassertBareContract(definition)\n\t}\n\treturn registry\n}\n\ntype FieldTypesCustomState = { fieldTypes: FieldTypeRegistry }\n\n/**\n * Park the resolved field-type registry on the config so `resolveEffectivePollOptions` can look up\n * a poll results field's definition (and its `resolveOptions`) at request time via `payload.config`,\n * the same way poll option sources and consent sources are stashed for root-level helpers.\n */\nexport const stashFieldTypes = (\n\tcustom: Record<string, unknown> | undefined,\n\tregistry: FieldTypeRegistry\n): Record<string, unknown> =>\n\tstashCustomState<FieldTypesCustomState>(custom, { fieldTypes: registry })\n\n/** The field-type registry stashed at boot, or an empty registry when the plugin never booted. */\nexport const fieldTypesOf = (payload: Payload): FieldTypeRegistry =>\n\tcustomStateOf<FieldTypesCustomState>(payload).fieldTypes ?? new Map()\n"],"mappings":";;AAWA,MAAa,iBAAiB,gBAA6D;CAC1F,MAAM,2BAA8B,IAAI,IAAI;CAC5C,KAAK,MAAM,cAAc,aACxB,SAAS,IAAI,WAAW,MAAM,UAAU;CAEzC,OAAO;AACR;;;;;;AAOA,MAAM,sBAAsB,eAA6C;CACxE,IAAI,WAAW,SAAS,QAAQ,WAAW,UAAU,QACpD,MAAM,IAAI,MACT,yEAAyE,WAAW,KAAK,oBAAoB,WAAW,MAAM,EAC/H;AAEF;;;;;;;AAQA,MAAa,qBACZ,UACA,SAA2B,CAAC,MACL;CACvB,MAAM,WAAW,cAAc,QAAQ;CACvC,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,MAAM,GACjD,IAAI,WAAW,OACd,SAAS,OAAO,IAAI;MACd,IAAI,WAAW,MAAM,CAE5B,OACC,SAAS,IAAI,MAAM;EAAE,GAAG;EAAQ;CAAK,CAAC;CAGxC,KAAK,MAAM,cAAc,SAAS,OAAO,GACxC,mBAAmB,UAAU;CAE9B,OAAO;AACR;;;;;;AASA,MAAa,mBACZ,QACA,aAEA,iBAAwC,QAAQ,EAAE,YAAY,SAAS,CAAC;;AAGzE,MAAa,gBAAgB,YAC5B,cAAqC,OAAO,EAAE,8BAAc,IAAI,IAAI"}
@@ -13,14 +13,37 @@ const conditionField = (name, labelKey, conditionTypes) => ({
13
13
  } } }
14
14
  });
15
15
  /**
16
- * Config every field instance carries regardless of type. `name` is the machine key written into
17
- * submissions; `width` is stored for the layout grid. Field types add their own `config` after
18
- * these inside the Field tab (see `fieldBlockTabs`). Content-bearing fields (`label`,
19
- * `placeholder`, `description`) are localized unless `localize` is false; identifiers and
20
- * behavior flags never are. The rows below are presentational only (unnamed, data paths stay
21
- * flat); `required` sits last, under `description`, per the admin layout.
16
+ * Let a lone row survivor span its row: Payload styles a row child with no `admin.width` as
17
+ * `flex: 1 1 auto` (see `mergeFieldStyles`), so dropping the key is the "fill the row" signal.
18
+ * Without this, omitting one half of a 50/50 row would strand the other half at 50%.
22
19
  */
23
- const sharedFieldConfig = (localize = true) => [
20
+ const spanRow = (field) => {
21
+ if (field.admin?.width === void 0) return field;
22
+ const { width: _width, ...admin } = field.admin;
23
+ return {
24
+ ...field,
25
+ admin
26
+ };
27
+ };
28
+ /**
29
+ * Drop the shared fields a type never uses, descending into the presentational rows so a nested
30
+ * field is reachable. An emptied row is dropped whole; a row pruned down to one field lets that
31
+ * field span it. A row that lost nothing is left exactly as authored, single-child rows included.
32
+ */
33
+ const applyOmissions = (fields, omit) => fields.flatMap((field) => {
34
+ if (field.type === "row") {
35
+ const kept = applyOmissions(field.fields, omit);
36
+ if (kept.length === 0) return [];
37
+ const strandsSurvivor = kept.length === 1 && kept.length < field.fields.length;
38
+ return [{
39
+ ...field,
40
+ fields: strandsSurvivor ? kept.map(spanRow) : kept
41
+ }];
42
+ }
43
+ return "name" in field && omit.has(field.name) ? [] : [field];
44
+ });
45
+ /** The full shared config, before a type's `omitShared` prunes it. See `sharedFieldConfig`. */
46
+ const baseSharedFieldConfig = (localize) => [
24
47
  {
25
48
  type: "row",
26
49
  fields: [{
@@ -87,12 +110,26 @@ const sharedFieldConfig = (localize = true) => [
87
110
  label: labelFor(keys.configRequired)
88
111
  }
89
112
  ];
90
- const fieldBlockTabs = ({ conditionTypes, typeConfig, validations, localize = true }) => ({
113
+ /**
114
+ * Config every field instance carries regardless of type. `name` is the machine key written into
115
+ * submissions; `width` is stored for the layout grid. Field types add their own `config` after
116
+ * these inside the Field tab (see `fieldBlockTabs`) and drop the ones they never read via
117
+ * `omitShared`, so an author is never offered a setting the renderer ignores. Content-bearing
118
+ * fields (`label`, `placeholder`, `description`) are localized unless `localize` is false;
119
+ * identifiers and behavior flags never are. The rows are presentational only (unnamed, data paths
120
+ * stay flat); `required` sits last, under `description`, per the admin layout.
121
+ */
122
+ const sharedFieldConfig = (localize = true, omitShared = []) => {
123
+ const omit = new Set(omitShared);
124
+ omit.delete("name");
125
+ return applyOmissions(baseSharedFieldConfig(localize), omit);
126
+ };
127
+ const fieldBlockTabs = ({ conditionTypes, typeConfig, validations, localize = true, omitShared }) => ({
91
128
  type: "tabs",
92
129
  tabs: [
93
130
  {
94
131
  label: labelFor(keys.tabField),
95
- fields: [...sharedFieldConfig(localize), ...typeConfig]
132
+ fields: [...sharedFieldConfig(localize, omitShared), ...typeConfig]
96
133
  },
97
134
  {
98
135
  label: labelFor(keys.tabValidation),
@@ -1 +1 @@
1
- {"version":3,"file":"sharedConfig.js","names":[],"sources":["../../src/fields/sharedConfig.ts"],"sourcesContent":["import type { Field } from 'payload'\nimport type { ConditionFieldType } from '../conditions/fieldTypes'\nimport { keys } from '../translations/keys'\nimport { labelFor } from '../translations/server'\nimport { localizedIf } from './localizedIf'\n\nconst CONDITION_FIELD_REF = '@10x-media/form-builder/client#FormConditionField'\n\nconst conditionField = (\n\tname: 'visibleWhen' | 'validateWhen',\n\tlabelKey: string,\n\tconditionTypes: Record<string, ConditionFieldType>\n): Field => ({\n\tname,\n\ttype: 'json',\n\tlabel: labelFor(labelKey),\n\tadmin: {\n\t\tcomponents: {\n\t\t\tField: { path: CONDITION_FIELD_REF, clientProps: { conditionTypes } },\n\t\t},\n\t},\n})\n\n/**\n * Config every field instance carries regardless of type. `name` is the machine key written into\n * submissions; `width` is stored for the layout grid. Field types add their own `config` after\n * these inside the Field tab (see `fieldBlockTabs`). Content-bearing fields (`label`,\n * `placeholder`, `description`) are localized unless `localize` is false; identifiers and\n * behavior flags never are. The rows below are presentational only (unnamed, data paths stay\n * flat); `required` sits last, under `description`, per the admin layout.\n */\nexport const sharedFieldConfig = (localize = true): Field[] => [\n\t{\n\t\ttype: 'row',\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'text',\n\t\t\t\trequired: true,\n\t\t\t\tlabel: labelFor(keys.configName),\n\t\t\t\tadmin: { width: '50%' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'label',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelFor(keys.configLabel),\n\t\t\t\tadmin: { width: '50%' },\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\ttype: 'row',\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: 'width',\n\t\t\t\ttype: 'select',\n\t\t\t\trequired: true,\n\t\t\t\tdefaultValue: 'full',\n\t\t\t\tlabel: labelFor(keys.configWidth),\n\t\t\t\tadmin: { width: '50%', isClearable: false },\n\t\t\t\toptions: [\n\t\t\t\t\t{ label: 'Full', value: 'full' },\n\t\t\t\t\t{ label: 'Half', value: 'half' },\n\t\t\t\t\t{ label: 'Third', value: 'third' },\n\t\t\t\t\t{ label: 'Two thirds', value: 'twoThirds' },\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'placeholder',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelFor(keys.configPlaceholder),\n\t\t\t\tadmin: { width: '50%' },\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: 'description',\n\t\ttype: 'textarea',\n\t\tlabel: labelFor(keys.configDescription),\n\t\t...localizedIf(localize),\n\t},\n\t{ name: 'required', type: 'checkbox', label: labelFor(keys.configRequired) },\n]\n\n/**\n * The single field of every field block: unnamed tabs (presentational only, data paths stay flat).\n * Field tab holds the shared basics plus the type's own config; Validation holds the rule blocks and\n * `validateWhen`; Advanced holds `visibleWhen` and `hidden`. `visibleWhen`/`validateWhen` store a\n * canonical Payload `Where`, edited by the native condition builder.\n */\ntype FieldBlockTabsArgs = {\n\tconditionTypes: Record<string, ConditionFieldType>\n\ttypeConfig: Field[]\n\tvalidations: Field\n\tlocalize?: boolean\n}\n\nexport const fieldBlockTabs = ({\n\tconditionTypes,\n\ttypeConfig,\n\tvalidations,\n\tlocalize = true,\n}: FieldBlockTabsArgs): Field => ({\n\ttype: 'tabs',\n\ttabs: [\n\t\t{\n\t\t\tlabel: labelFor(keys.tabField),\n\t\t\tfields: [...sharedFieldConfig(localize), ...typeConfig],\n\t\t},\n\t\t{\n\t\t\tlabel: labelFor(keys.tabValidation),\n\t\t\tfields: [\n\t\t\t\tvalidations,\n\t\t\t\tconditionField('validateWhen', keys.configValidateWhen, conditionTypes),\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tlabel: labelFor(keys.tabAdvanced),\n\t\t\tfields: [\n\t\t\t\tconditionField('visibleWhen', keys.configVisibleWhen, conditionTypes),\n\t\t\t\t{ name: 'hidden', type: 'checkbox', label: labelFor(keys.configHidden) },\n\t\t\t],\n\t\t},\n\t],\n})\n"],"mappings":";;;;AAMA,MAAM,sBAAsB;AAE5B,MAAM,kBACL,MACA,UACA,oBACY;CACZ;CACA,MAAM;CACN,OAAO,SAAS,QAAQ;CACxB,OAAO,EACN,YAAY,EACX,OAAO;EAAE,MAAM;EAAqB,aAAa,EAAE,eAAe;CAAE,EACrE,EACD;AACD;;;;;;;;;AAUA,MAAa,qBAAqB,WAAW,SAAkB;CAC9D;EACC,MAAM;EACN,QAAQ,CACP;GACC,MAAM;GACN,MAAM;GACN,UAAU;GACV,OAAO,SAAS,KAAK,UAAU;GAC/B,OAAO,EAAE,OAAO,MAAM;EACvB,GACA;GACC,MAAM;GACN,MAAM;GACN,OAAO,SAAS,KAAK,WAAW;GAChC,OAAO,EAAE,OAAO,MAAM;GACtB,GAAG,YAAY,QAAQ;EACxB,CACD;CACD;CACA;EACC,MAAM;EACN,QAAQ,CACP;GACC,MAAM;GACN,MAAM;GACN,UAAU;GACV,cAAc;GACd,OAAO,SAAS,KAAK,WAAW;GAChC,OAAO;IAAE,OAAO;IAAO,aAAa;GAAM;GAC1C,SAAS;IACR;KAAE,OAAO;KAAQ,OAAO;IAAO;IAC/B;KAAE,OAAO;KAAQ,OAAO;IAAO;IAC/B;KAAE,OAAO;KAAS,OAAO;IAAQ;IACjC;KAAE,OAAO;KAAc,OAAO;IAAY;GAC3C;EACD,GACA;GACC,MAAM;GACN,MAAM;GACN,OAAO,SAAS,KAAK,iBAAiB;GACtC,OAAO,EAAE,OAAO,MAAM;GACtB,GAAG,YAAY,QAAQ;EACxB,CACD;CACD;CACA;EACC,MAAM;EACN,MAAM;EACN,OAAO,SAAS,KAAK,iBAAiB;EACtC,GAAG,YAAY,QAAQ;CACxB;CACA;EAAE,MAAM;EAAY,MAAM;EAAY,OAAO,SAAS,KAAK,cAAc;CAAE;AAC5E;AAeA,MAAa,kBAAkB,EAC9B,gBACA,YACA,aACA,WAAW,YACsB;CACjC,MAAM;CACN,MAAM;EACL;GACC,OAAO,SAAS,KAAK,QAAQ;GAC7B,QAAQ,CAAC,GAAG,kBAAkB,QAAQ,GAAG,GAAG,UAAU;EACvD;EACA;GACC,OAAO,SAAS,KAAK,aAAa;GAClC,QAAQ,CACP,aACA,eAAe,gBAAgB,KAAK,oBAAoB,cAAc,CACvE;EACD;EACA;GACC,OAAO,SAAS,KAAK,WAAW;GAChC,QAAQ,CACP,eAAe,eAAe,KAAK,mBAAmB,cAAc,GACpE;IAAE,MAAM;IAAU,MAAM;IAAY,OAAO,SAAS,KAAK,YAAY;GAAE,CACxE;EACD;CACD;AACD"}
1
+ {"version":3,"file":"sharedConfig.js","names":[],"sources":["../../src/fields/sharedConfig.ts"],"sourcesContent":["import type { Field } from 'payload'\nimport type { ConditionFieldType } from '../conditions/fieldTypes'\nimport { keys } from '../translations/keys'\nimport { labelFor } from '../translations/server'\nimport { localizedIf } from './localizedIf'\nimport type { OmittableSharedField } from './types'\n\nconst CONDITION_FIELD_REF = '@10x-media/form-builder/client#FormConditionField'\n\nconst conditionField = (\n\tname: 'visibleWhen' | 'validateWhen',\n\tlabelKey: string,\n\tconditionTypes: Record<string, ConditionFieldType>\n): Field => ({\n\tname,\n\ttype: 'json',\n\tlabel: labelFor(labelKey),\n\tadmin: {\n\t\tcomponents: {\n\t\t\tField: { path: CONDITION_FIELD_REF, clientProps: { conditionTypes } },\n\t\t},\n\t},\n})\n\n/**\n * Let a lone row survivor span its row: Payload styles a row child with no `admin.width` as\n * `flex: 1 1 auto` (see `mergeFieldStyles`), so dropping the key is the \"fill the row\" signal.\n * Without this, omitting one half of a 50/50 row would strand the other half at 50%.\n */\nconst spanRow = <T extends Field>(field: T): T => {\n\tif (field.admin?.width === undefined) {\n\t\treturn field\n\t}\n\tconst { width: _width, ...admin } = field.admin\n\treturn { ...field, admin }\n}\n\n/**\n * Drop the shared fields a type never uses, descending into the presentational rows so a nested\n * field is reachable. An emptied row is dropped whole; a row pruned down to one field lets that\n * field span it. A row that lost nothing is left exactly as authored, single-child rows included.\n */\nconst applyOmissions = (fields: Field[], omit: ReadonlySet<string>): Field[] =>\n\tfields.flatMap((field): Field[] => {\n\t\tif (field.type === 'row') {\n\t\t\tconst kept = applyOmissions(field.fields, omit)\n\t\t\tif (kept.length === 0) {\n\t\t\t\treturn []\n\t\t\t}\n\t\t\tconst strandsSurvivor = kept.length === 1 && kept.length < field.fields.length\n\t\t\treturn [{ ...field, fields: strandsSurvivor ? kept.map(spanRow) : kept }]\n\t\t}\n\t\treturn 'name' in field && omit.has(field.name) ? [] : [field]\n\t})\n\n/** The full shared config, before a type's `omitShared` prunes it. See `sharedFieldConfig`. */\nconst baseSharedFieldConfig = (localize: boolean): Field[] => [\n\t{\n\t\ttype: 'row',\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'text',\n\t\t\t\trequired: true,\n\t\t\t\tlabel: labelFor(keys.configName),\n\t\t\t\tadmin: { width: '50%' },\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'label',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelFor(keys.configLabel),\n\t\t\t\tadmin: { width: '50%' },\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\ttype: 'row',\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: 'width',\n\t\t\t\ttype: 'select',\n\t\t\t\trequired: true,\n\t\t\t\tdefaultValue: 'full',\n\t\t\t\tlabel: labelFor(keys.configWidth),\n\t\t\t\tadmin: { width: '50%', isClearable: false },\n\t\t\t\toptions: [\n\t\t\t\t\t{ label: 'Full', value: 'full' },\n\t\t\t\t\t{ label: 'Half', value: 'half' },\n\t\t\t\t\t{ label: 'Third', value: 'third' },\n\t\t\t\t\t{ label: 'Two thirds', value: 'twoThirds' },\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'placeholder',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelFor(keys.configPlaceholder),\n\t\t\t\tadmin: { width: '50%' },\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t],\n\t},\n\t{\n\t\tname: 'description',\n\t\ttype: 'textarea',\n\t\tlabel: labelFor(keys.configDescription),\n\t\t...localizedIf(localize),\n\t},\n\t{ name: 'required', type: 'checkbox', label: labelFor(keys.configRequired) },\n]\n\n/**\n * Config every field instance carries regardless of type. `name` is the machine key written into\n * submissions; `width` is stored for the layout grid. Field types add their own `config` after\n * these inside the Field tab (see `fieldBlockTabs`) and drop the ones they never read via\n * `omitShared`, so an author is never offered a setting the renderer ignores. Content-bearing\n * fields (`label`, `placeholder`, `description`) are localized unless `localize` is false;\n * identifiers and behavior flags never are. The rows are presentational only (unnamed, data paths\n * stay flat); `required` sits last, under `description`, per the admin layout.\n */\nexport const sharedFieldConfig = (\n\tlocalize = true,\n\tomitShared: readonly OmittableSharedField[] = []\n): Field[] => {\n\tconst omit = new Set<string>(omitShared)\n\t// `name` is the storage key every read and write path gates on (`isNamedField`). The type\n\t// already excludes it; dropping it here too keeps an untyped caller from breaking storage.\n\tomit.delete('name')\n\treturn applyOmissions(baseSharedFieldConfig(localize), omit)\n}\n\n/**\n * The single field of every field block: unnamed tabs (presentational only, data paths stay flat).\n * Field tab holds the shared basics plus the type's own config; Validation holds the rule blocks and\n * `validateWhen`; Advanced holds `visibleWhen` and `hidden`. `visibleWhen`/`validateWhen` store a\n * canonical Payload `Where`, edited by the native condition builder.\n */\ntype FieldBlockTabsArgs = {\n\tconditionTypes: Record<string, ConditionFieldType>\n\ttypeConfig: Field[]\n\tvalidations: Field\n\tlocalize?: boolean\n\t/** See `FormFieldDefinition.omitShared`: shared basics this type never uses, left unauthored. */\n\tomitShared?: readonly OmittableSharedField[]\n}\n\nexport const fieldBlockTabs = ({\n\tconditionTypes,\n\ttypeConfig,\n\tvalidations,\n\tlocalize = true,\n\tomitShared,\n}: FieldBlockTabsArgs): Field => ({\n\ttype: 'tabs',\n\ttabs: [\n\t\t{\n\t\t\tlabel: labelFor(keys.tabField),\n\t\t\tfields: [...sharedFieldConfig(localize, omitShared), ...typeConfig],\n\t\t},\n\t\t{\n\t\t\tlabel: labelFor(keys.tabValidation),\n\t\t\tfields: [\n\t\t\t\tvalidations,\n\t\t\t\tconditionField('validateWhen', keys.configValidateWhen, conditionTypes),\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tlabel: labelFor(keys.tabAdvanced),\n\t\t\tfields: [\n\t\t\t\tconditionField('visibleWhen', keys.configVisibleWhen, conditionTypes),\n\t\t\t\t{ name: 'hidden', type: 'checkbox', label: labelFor(keys.configHidden) },\n\t\t\t],\n\t\t},\n\t],\n})\n"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
+ import { PollOption } from "../poll/definePollOptionSource.js";
2
+ import { FormFieldInstance } from "../submissions/types.js";
1
3
  import { FileRef } from "../uploads/types.js";
2
4
  import { ConditionFieldType } from "../conditions/fieldTypes.js";
3
- import { Field } from "payload";
5
+ import { Field, Payload, PayloadRequest } from "payload";
4
6
  import { StandardSchemaV1 } from "@standard-schema/spec";
5
7
 
6
8
  //#region src/fields/types.d.ts
@@ -23,6 +25,12 @@ type ValueKindTypeMap = {
23
25
  type ValueOfKind<K extends FormFieldValueKind> = ValueKindTypeMap[K];
24
26
  /** Resolved per-instance config values for a field type (loose at the DB boundary, narrowed by the author's generic). */
25
27
  type FormFieldConfigValues = Record<string, unknown>;
28
+ /**
29
+ * The shared config fields a type may drop via {@link FormFieldDefinition.omitShared}. `name` is
30
+ * deliberately absent and can never be dropped: it is the storage key every read and write path
31
+ * gates on (see `isNamedField`), so a named field without it would silently store nothing.
32
+ */
33
+ type OmittableSharedField = 'label' | 'placeholder' | 'description' | 'width' | 'required';
26
34
  /** A `t`-like resolver. The engine supplies one from the request i18n; the renderer will supply the client i18n. */
27
35
  type Translate = (key: string) => string;
28
36
  type FormFieldValidateArgs<K extends FormFieldValueKind, TConfig extends FormFieldConfigValues> = {
@@ -42,6 +50,16 @@ type FormFieldFormatArgs<K extends FormFieldValueKind, TConfig extends FormField
42
50
  t: Translate;
43
51
  };
44
52
  type FormFieldFormat<K extends FormFieldValueKind, TConfig extends FormFieldConfigValues> = (args: FormFieldFormatArgs<K, TConfig>) => string;
53
+ /** Arguments a {@link FormFieldDefinition.resolveOptions} implementation receives. */
54
+ type ResolveFieldOptionsArgs = {
55
+ /** The configured field instance, so the resolver can read the values the author selected. */instance: FormFieldInstance;
56
+ form: {
57
+ id: number | string;
58
+ title?: string;
59
+ };
60
+ payload: Payload;
61
+ req?: PayloadRequest;
62
+ };
45
63
  /**
46
64
  * A field type, authored once. `value` drives typed `validate`/`format`; `config` is a Payload
47
65
  * `Field[]` for the add-field drawer; `Field` is the client renderer import-map ref;
@@ -54,11 +72,46 @@ type FormFieldDefinition<K extends FormFieldValueKind = FormFieldValueKind, TCon
54
72
  config?: Field[];
55
73
  validate?: FormFieldValidate<K, TConfig>;
56
74
  format?: FormFieldFormat<K, TConfig>;
57
- Field?: string; /** Optional Standard Schema validator (Zod/Valibot/etc.), run by the engine after the intrinsic validator. */
75
+ Field?: string;
76
+ /**
77
+ * Import-map ref for a custom block row Label, replacing the default `FieldBlockLabel` for this
78
+ * type's add-field block. Receives the same `{ typeLabelKey }` clientProps. The `consent` type
79
+ * uses this to resolve and show the referenced source's name.
80
+ */
81
+ blockLabel?: string; /** Optional Standard Schema validator (Zod/Valibot/etc.), run by the engine after the intrinsic validator. */
58
82
  schema?: StandardSchemaV1;
59
83
  icon?: string;
60
84
  group?: string; /** How this field appears in the condition builder. Defaults from `value` (see `defaultConditionType`). */
61
85
  conditionType?: ConditionFieldType;
86
+ /**
87
+ * Bare definitions render without the shared chrome: no name/label/width/required/placeholder/
88
+ * description and no validation tabs; the definition's `config` IS the entire block. Instances
89
+ * are nameless (identified by Payload's hidden block row `id`, see `fieldKey`), so bare types
90
+ * must be display-only (`value: 'none'`): with no name there is nothing to validate or store.
91
+ */
92
+ bare?: boolean;
93
+ /**
94
+ * Shared config fields this type never uses, so authors are not offered a setting the renderer
95
+ * ignores (e.g. a placeholder on a checkbox). Unlike `bare`, which drops the shared chrome
96
+ * wholesale, this keeps the rest of it. An emptied layout row collapses and a lone survivor
97
+ * spans the row (see `sharedFieldConfig`).
98
+ */
99
+ omitShared?: OmittableSharedField[];
100
+ /**
101
+ * The type can be chosen as a poll's results field. Its instances must produce enumerable
102
+ * answers: either authored `options` or options resolved from a poll option source.
103
+ */
104
+ pollEligible?: boolean;
105
+ /**
106
+ * Source this `pollEligible` type's poll choices from the field instance itself, instead of
107
+ * authored `options` or a poll `optionSource`. A type that holds enumerable data (for example a
108
+ * `hasMany` relationship to the voteable records) returns one {@link PollOption} per selectable
109
+ * value, read from the live instance the author configured (so it can `payload.find` over the
110
+ * ids it holds). The result backs submission validation, the admin winner select, and results
111
+ * labeling exactly like a source would; it is consulted after an `optionSource` and before the
112
+ * instance's authored `options`.
113
+ */
114
+ resolveOptions?: (args: ResolveFieldOptionsArgs) => PollOption[] | Promise<PollOption[]>;
62
115
  };
63
116
  /** The erased shape stored in the heterogeneous registry. Value is `unknown`; config re-narrows per matched type at execution. */
64
117
  type AnyFormFieldValidate = (args: {
@@ -83,12 +136,17 @@ type AnyFormFieldDefinition = {
83
136
  config?: Field[];
84
137
  validate?: AnyFormFieldValidate;
85
138
  format?: AnyFormFieldFormat;
86
- Field?: string;
139
+ Field?: string; /** See `FormFieldDefinition.blockLabel`: import-map ref for a custom block row Label. */
140
+ blockLabel?: string;
87
141
  schema?: StandardSchemaV1;
88
142
  icon?: string;
89
143
  group?: string; /** How this field appears in the condition builder. Defaults from `value` (see `defaultConditionType`). */
90
- conditionType?: ConditionFieldType;
144
+ conditionType?: ConditionFieldType; /** See `FormFieldDefinition.bare`: the block is the definition's `config` alone, instances are nameless. */
145
+ bare?: boolean; /** See `FormFieldDefinition.omitShared`: shared config fields this type never uses, never authored. */
146
+ omitShared?: OmittableSharedField[]; /** See `FormFieldDefinition.pollEligible`: choosable as a poll's results field. */
147
+ pollEligible?: boolean; /** See `FormFieldDefinition.resolveOptions`: source poll choices from the instance itself. */
148
+ resolveOptions?: (args: ResolveFieldOptionsArgs) => PollOption[] | Promise<PollOption[]>;
91
149
  };
92
150
  //#endregion
93
- export { AnyFormFieldDefinition, FormFieldConfigValues, FormFieldDefinition, FormFieldFormat, FormFieldValidate, FormFieldValueKind, Translate };
151
+ export { AnyFormFieldDefinition, FormFieldConfigValues, FormFieldDefinition, FormFieldFormat, FormFieldValidate, FormFieldValueKind, OmittableSharedField, ResolveFieldOptionsArgs, Translate };
94
152
  //# sourceMappingURL=types.d.ts.map
@@ -3,14 +3,16 @@ import { FormFlow } from "./types.js";
3
3
  //#region src/flow/engine.d.ts
4
4
  /** The entry step id (the first step), or `undefined` for an empty flow. */
5
5
  declare const firstStepId: (flow: FormFlow) => string | undefined;
6
- /** The field machine names a step renders (empty for an unknown step). */
6
+ /** The field keys a step renders (names for named fields, block row ids for bare blocks; empty for an unknown step). */
7
7
  declare const stepFieldNames: (flow: FormFlow, id: string) => string[];
8
8
  /**
9
- * Resolve the next step id from the current step + answers: the first transition whose `when` matches
10
- * (via `evaluateCondition`), else the default `next`, else `undefined` (terminal). Pure + isomorphic.
9
+ * Resolve the next step id from the current step + answers. Precedence: the first transition whose
10
+ * `when` matches (via `evaluateCondition`) wins, else the step's `next` (a step id to jump to, or
11
+ * `null` for an explicit end), else the next step in array order (the last step ends the flow).
12
+ * Returns `undefined` when the flow ends here. Pure + isomorphic.
11
13
  */
12
14
  declare const resolveNextStepId: (flow: FormFlow, currentId: string, answers: Record<string, unknown>) => string | undefined;
13
- /** Whether the current step is terminal (no matching transition + no default next). */
15
+ /** Whether the flow ends at the current step (`resolveNextStepId` finds no step to advance to). */
14
16
  declare const isTerminalStepId: (flow: FormFlow, currentId: string, answers: Record<string, unknown>) => boolean;
15
17
  //#endregion
16
18
  export { firstStepId, isTerminalStepId, resolveNextStepId, stepFieldNames };
@@ -4,19 +4,24 @@ import { evaluateCondition } from "../conditions/evaluate.js";
4
4
  const firstStepId = (flow) => flow.steps[0]?.id;
5
5
  /** The step with the given id, or `undefined`. */
6
6
  const getStep = (flow, id) => flow.steps.find((step) => step.id === id);
7
- /** The field machine names a step renders (empty for an unknown step). */
7
+ /** The field keys a step renders (names for named fields, block row ids for bare blocks; empty for an unknown step). */
8
8
  const stepFieldNames = (flow, id) => getStep(flow, id)?.fields ?? [];
9
9
  /**
10
- * Resolve the next step id from the current step + answers: the first transition whose `when` matches
11
- * (via `evaluateCondition`), else the default `next`, else `undefined` (terminal). Pure + isomorphic.
10
+ * Resolve the next step id from the current step + answers. Precedence: the first transition whose
11
+ * `when` matches (via `evaluateCondition`) wins, else the step's `next` (a step id to jump to, or
12
+ * `null` for an explicit end), else the next step in array order (the last step ends the flow).
13
+ * Returns `undefined` when the flow ends here. Pure + isomorphic.
12
14
  */
13
15
  const resolveNextStepId = (flow, currentId, answers) => {
14
- const step = getStep(flow, currentId);
16
+ const index = flow.steps.findIndex((step) => step.id === currentId);
17
+ const step = flow.steps[index];
15
18
  if (!step) return;
16
19
  for (const transition of step.transitions ?? []) if (evaluateCondition(transition.when, answers)) return transition.to;
17
- return step.next;
20
+ if (step.next === null) return;
21
+ if (step.next !== void 0) return step.next;
22
+ return flow.steps[index + 1]?.id;
18
23
  };
19
- /** Whether the current step is terminal (no matching transition + no default next). */
24
+ /** Whether the flow ends at the current step (`resolveNextStepId` finds no step to advance to). */
20
25
  const isTerminalStepId = (flow, currentId, answers) => resolveNextStepId(flow, currentId, answers) === void 0;
21
26
  //#endregion
22
27
  export { firstStepId, isTerminalStepId, resolveNextStepId, stepFieldNames };
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","names":[],"sources":["../../src/flow/engine.ts"],"sourcesContent":["import { evaluateCondition } from '../conditions/evaluate'\nimport type { FlowStep, FormFlow } from './types'\n\n/** The entry step id (the first step), or `undefined` for an empty flow. */\nexport const firstStepId = (flow: FormFlow): string | undefined => flow.steps[0]?.id\n\n/** The step with the given id, or `undefined`. */\nexport const getStep = (flow: FormFlow, id: string): FlowStep | undefined =>\n\tflow.steps.find((step) => step.id === id)\n\n/** The field machine names a step renders (empty for an unknown step). */\nexport const stepFieldNames = (flow: FormFlow, id: string): string[] =>\n\tgetStep(flow, id)?.fields ?? []\n\n/**\n * Resolve the next step id from the current step + answers: the first transition whose `when` matches\n * (via `evaluateCondition`), else the default `next`, else `undefined` (terminal). Pure + isomorphic.\n */\nexport const resolveNextStepId = (\n\tflow: FormFlow,\n\tcurrentId: string,\n\tanswers: Record<string, unknown>\n): string | undefined => {\n\tconst step = getStep(flow, currentId)\n\tif (!step) {\n\t\treturn undefined\n\t}\n\tfor (const transition of step.transitions ?? []) {\n\t\tif (evaluateCondition(transition.when, answers)) {\n\t\t\treturn transition.to\n\t\t}\n\t}\n\treturn step.next\n}\n\n/** Whether the current step is terminal (no matching transition + no default next). */\nexport const isTerminalStepId = (\n\tflow: FormFlow,\n\tcurrentId: string,\n\tanswers: Record<string, unknown>\n): boolean => resolveNextStepId(flow, currentId, answers) === undefined\n"],"mappings":";;;AAIA,MAAa,eAAe,SAAuC,KAAK,MAAM,IAAI;;AAGlF,MAAa,WAAW,MAAgB,OACvC,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE;;AAGzC,MAAa,kBAAkB,MAAgB,OAC9C,QAAQ,MAAM,EAAE,GAAG,UAAU,CAAC;;;;;AAM/B,MAAa,qBACZ,MACA,WACA,YACwB;CACxB,MAAM,OAAO,QAAQ,MAAM,SAAS;CACpC,IAAI,CAAC,MACJ;CAED,KAAK,MAAM,cAAc,KAAK,eAAe,CAAC,GAC7C,IAAI,kBAAkB,WAAW,MAAM,OAAO,GAC7C,OAAO,WAAW;CAGpB,OAAO,KAAK;AACb;;AAGA,MAAa,oBACZ,MACA,WACA,YACa,kBAAkB,MAAM,WAAW,OAAO,MAAM,KAAA"}
1
+ {"version":3,"file":"engine.js","names":[],"sources":["../../src/flow/engine.ts"],"sourcesContent":["import { evaluateCondition } from '../conditions/evaluate'\nimport type { FlowStep, FormFlow } from './types'\n\n/** The entry step id (the first step), or `undefined` for an empty flow. */\nexport const firstStepId = (flow: FormFlow): string | undefined => flow.steps[0]?.id\n\n/** The step with the given id, or `undefined`. */\nexport const getStep = (flow: FormFlow, id: string): FlowStep | undefined =>\n\tflow.steps.find((step) => step.id === id)\n\n/** The field keys a step renders (names for named fields, block row ids for bare blocks; empty for an unknown step). */\nexport const stepFieldNames = (flow: FormFlow, id: string): string[] =>\n\tgetStep(flow, id)?.fields ?? []\n\n/**\n * Resolve the next step id from the current step + answers. Precedence: the first transition whose\n * `when` matches (via `evaluateCondition`) wins, else the step's `next` (a step id to jump to, or\n * `null` for an explicit end), else the next step in array order (the last step ends the flow).\n * Returns `undefined` when the flow ends here. Pure + isomorphic.\n */\nexport const resolveNextStepId = (\n\tflow: FormFlow,\n\tcurrentId: string,\n\tanswers: Record<string, unknown>\n): string | undefined => {\n\tconst index = flow.steps.findIndex((step) => step.id === currentId)\n\tconst step = flow.steps[index]\n\tif (!step) {\n\t\treturn undefined\n\t}\n\tfor (const transition of step.transitions ?? []) {\n\t\tif (evaluateCondition(transition.when, answers)) {\n\t\t\treturn transition.to\n\t\t}\n\t}\n\tif (step.next === null) {\n\t\treturn undefined\n\t}\n\tif (step.next !== undefined) {\n\t\treturn step.next\n\t}\n\treturn flow.steps[index + 1]?.id\n}\n\n/** Whether the flow ends at the current step (`resolveNextStepId` finds no step to advance to). */\nexport const isTerminalStepId = (\n\tflow: FormFlow,\n\tcurrentId: string,\n\tanswers: Record<string, unknown>\n): boolean => resolveNextStepId(flow, currentId, answers) === undefined\n"],"mappings":";;;AAIA,MAAa,eAAe,SAAuC,KAAK,MAAM,IAAI;;AAGlF,MAAa,WAAW,MAAgB,OACvC,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE;;AAGzC,MAAa,kBAAkB,MAAgB,OAC9C,QAAQ,MAAM,EAAE,GAAG,UAAU,CAAC;;;;;;;AAQ/B,MAAa,qBACZ,MACA,WACA,YACwB;CACxB,MAAM,QAAQ,KAAK,MAAM,WAAW,SAAS,KAAK,OAAO,SAAS;CAClE,MAAM,OAAO,KAAK,MAAM;CACxB,IAAI,CAAC,MACJ;CAED,KAAK,MAAM,cAAc,KAAK,eAAe,CAAC,GAC7C,IAAI,kBAAkB,WAAW,MAAM,OAAO,GAC7C,OAAO,WAAW;CAGpB,IAAI,KAAK,SAAS,MACjB;CAED,IAAI,KAAK,SAAS,KAAA,GACjB,OAAO,KAAK;CAEb,OAAO,KAAK,MAAM,QAAQ,IAAI;AAC/B;;AAGA,MAAa,oBACZ,MACA,WACA,YACa,kBAAkB,MAAM,WAAW,OAAO,MAAM,KAAA"}
@@ -1,14 +1,23 @@
1
1
  //#region src/flow/normalizeFlow.ts
2
2
  const isRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
3
3
  /**
4
- * Pure guard that normalizes a raw (possibly untrusted) flow value against the
5
- * form's current field list. Returns `undefined` when the flow is absent, empty,
6
- * or resolves to fewer than two steps (a single step is an ordinary form).
7
- * A field assigned to multiple steps keeps only its first occurrence in step order.
4
+ * Pure guard that normalizes a raw (possibly untrusted) flow value against the form's current
5
+ * field keys (machine names for named fields, block row ids for bare blocks; see `fieldKey`).
6
+ * Returns `undefined` when the flow is absent, empty, or resolves to fewer than two steps
7
+ * (a single step is an ordinary form). A field assigned to multiple steps keeps only its
8
+ * first occurrence in step order. `next: null` (explicit end of form) is preserved as distinct
9
+ * from an absent `next` (sequential fall-through); a `next` pointing at an unknown step is
10
+ * dropped to absent.
11
+ *
12
+ * A step is kept even when it ends up with no fields, which happens when every field it named was
13
+ * deleted from the form. Dropping it would be wrong twice over: a host can render its own content
14
+ * per step off `useFormStep()`, so an empty step is not necessarily an empty page, and dropping
15
+ * one would strand the `next` and transition targets that point at it. The visitor gets a page with
16
+ * only navigation on it, which is visible to the author in the flow builder and recoverable there.
8
17
  */
9
- const normalizeFlow = (raw, fieldNames) => {
18
+ const normalizeFlow = (raw, fieldKeys) => {
10
19
  if (!isRecord(raw) || !Array.isArray(raw.steps)) return;
11
- const knownFields = new Set(fieldNames);
20
+ const knownFields = new Set(fieldKeys);
12
21
  const rawSteps = raw.steps.filter((s) => isRecord(s) && typeof s.id === "string");
13
22
  const knownIds = new Set(rawSteps.map((s) => s.id));
14
23
  if (knownIds.size < 2) return;
@@ -24,7 +33,7 @@ const normalizeFlow = (raw, fieldNames) => {
24
33
  when: t.when,
25
34
  to: t.to
26
35
  }));
27
- const next = typeof s.next === "string" && knownIds.has(s.next) ? s.next : void 0;
36
+ const next = s.next === null ? null : typeof s.next === "string" && knownIds.has(s.next) ? s.next : void 0;
28
37
  const step = {
29
38
  id,
30
39
  fields