@sealcode/sealgen 0.18.8 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. package/.eslintrc.cjs +7 -2
  2. package/.xunit +75 -0
  3. package/@types/add-crud.d.sync-conflict-20250918-184311-TFDLWFG.ts +1 -0
  4. package/@types/builders/colors-builder.d.sync-conflict-20250918-184323-TFDLWFG.ts +10 -0
  5. package/@types/builders/colors-builder.d.ts +1 -1
  6. package/@types/builders/fonts-builder.d.sync-conflict-20250918-184322-TFDLWFG.ts +7 -0
  7. package/@types/builders/fonts-builder.d.ts +1 -1
  8. package/@types/controllers/table-add-button.d.ts +6 -0
  9. package/@types/controllers/table-add-button.stimulus.d.ts +6 -0
  10. package/@types/crud-field-snippets.d.sync-conflict-20250918-184323-TFDLWFG.ts +1 -0
  11. package/@types/crud-field-snippets.d.ts +1 -3
  12. package/@types/forms/controls/array.d.sync-conflict-20250918-184306-TFDLWFG.ts +33 -0
  13. package/@types/forms/controls/array.d.ts +1 -2
  14. package/@types/forms/controls/array.sync-conflict-20250918-222045-TFDLWFG.d.ts +33 -0
  15. package/@types/forms/controls/autocomplete.d.sync-conflict-20250918-222042-TFDLWFG.ts +22 -0
  16. package/@types/forms/controls/autocomplete.d.ts +1 -1
  17. package/@types/forms/controls/checkbox-group.d.sync-conflict-20250918-184319-TFDLWFG.ts +21 -0
  18. package/@types/forms/controls/checkbox-group.d.ts +3 -3
  19. package/@types/forms/controls/checkboxed-list-input.d.sync-conflict-20250918-184323-TFDLWFG.ts +21 -0
  20. package/@types/forms/controls/checkboxed-list-input.d.ts +3 -3
  21. package/@types/forms/controls/controls.d.ts +2 -2
  22. package/@types/forms/controls/derived-frame.d.sync-conflict-20250918-184314-TFDLWFG.ts +19 -0
  23. package/@types/forms/controls/derived-frame.d.ts +0 -1
  24. package/@types/forms/controls/dropdown.d.sync-conflict-20250918-222044-TFDLWFG.ts +30 -0
  25. package/@types/forms/controls/dropdown.d.ts +1 -1
  26. package/@types/forms/controls/file.d.sync-conflict-20250918-222045-TFDLWFG.ts +13 -0
  27. package/@types/forms/controls/file.d.ts +1 -2
  28. package/@types/forms/controls/form-control.d.sync-conflict-20250918-184322-TFDLWFG.ts +19 -0
  29. package/@types/forms/controls/form-control.d.sync-conflict-20250918-222046-TFDLWFG.ts +19 -0
  30. package/@types/forms/controls/form-control.d.ts +7 -3
  31. package/@types/forms/controls/image.d.ts +19 -0
  32. package/@types/forms/controls/image.test.d.ts +1 -0
  33. package/@types/forms/controls/multiple-files.d.sync-conflict-20250918-184318-TFDLWFG.ts +42 -0
  34. package/@types/forms/controls/multiple-files.d.ts +3 -0
  35. package/@types/forms/controls/multiple-images.d.ts +19 -0
  36. package/@types/forms/controls/number.d.sync-conflict-20250918-222046-TFDLWFG.ts +13 -0
  37. package/@types/forms/controls/number.d.ts +1 -1
  38. package/@types/forms/controls/photo.d.sync-conflict-20250918-184321-TFDLWFG.ts +19 -0
  39. package/@types/forms/controls/photo.d.ts +3 -5
  40. package/@types/forms/controls/simple-input.d.sync-conflict-20250918-184310-TFDLWFG.ts +33 -0
  41. package/@types/forms/controls/simple-input.d.sync-conflict-20250918-222042-TFDLWFG.ts +33 -0
  42. package/@types/forms/controls/simple-input.d.ts +5 -4
  43. package/@types/forms/controls/simple-input.sync-conflict-20250918-222045-TFDLWFG.d.ts +33 -0
  44. package/@types/forms/controls/single-reference.d.ts +3 -2
  45. package/@types/forms/controls/table.d.sync-conflict-20250918-184302-TFDLWFG.ts +39 -0
  46. package/@types/forms/controls/table.d.ts +8 -2
  47. package/@types/forms/controls/table.sync-conflict-20250918-222042-TFDLWFG.d.ts +39 -0
  48. package/@types/forms/controls/textarea.d.sync-conflict-20250918-222045-TFDLWFG.ts +25 -0
  49. package/@types/forms/controls/textarea.d.ts +3 -3
  50. package/@types/forms/fields/boolean.d.sync-conflict-20250918-184325-TFDLWFG.ts +22 -0
  51. package/@types/forms/fields/boolean.d.ts +6 -1
  52. package/@types/forms/fields/boolean.sync-conflict-20250918-222042-TFDLWFG.d.ts +22 -0
  53. package/@types/forms/fields/checkboxed-list.d.sync-conflict-20250918-184325-TFDLWFG.ts +23 -0
  54. package/@types/forms/fields/checkboxed-list.d.ts +3 -1
  55. package/@types/forms/fields/collection-field.d.sync-conflict-20250918-184319-TFDLWFG.ts +22 -0
  56. package/@types/forms/fields/collection-field.d.sync-conflict-20250918-222047-TFDLWFG.ts +22 -0
  57. package/@types/forms/fields/collection-field.d.ts +8 -1
  58. package/@types/forms/fields/color.d.ts +4 -0
  59. package/@types/forms/fields/coordinates.d.sync-conflict-20250918-222044-TFDLWFG.ts +14 -0
  60. package/@types/forms/fields/coordinates.d.ts +14 -0
  61. package/@types/forms/fields/date.d.ts +13 -0
  62. package/@types/forms/fields/datetime.d.sync-conflict-20250918-222050-TFDLWFG.ts +4 -0
  63. package/@types/forms/fields/datetime.d.ts +14 -0
  64. package/@types/forms/fields/deep-reverse-single-reference-list.d.ts +24 -0
  65. package/@types/forms/fields/deep-reverse-single-reference-table.d.ts +16 -0
  66. package/@types/forms/fields/email.d.sync-conflict-20250918-184303-TFDLWFG.ts +8 -0
  67. package/@types/forms/fields/email.d.ts +3 -0
  68. package/@types/forms/fields/enum-multiple-sealious.d.ts +16 -0
  69. package/@types/forms/fields/enum-multiple-sealious.sync-conflict-20250918-222047-TFDLWFG.d.ts +16 -0
  70. package/@types/forms/fields/field.d.sync-conflict-20250918-184306-TFDLWFG.ts +70 -0
  71. package/@types/forms/fields/field.d.ts +37 -5
  72. package/@types/forms/fields/fields.d.sync-conflict-20250918-184314-TFDLWFG.ts +29 -0
  73. package/@types/forms/fields/fields.d.ts +23 -8
  74. package/@types/forms/fields/file.d.sync-conflict-20250918-184310-TFDLWFG.ts +23 -0
  75. package/@types/forms/fields/file.d.sync-conflict-20250918-222046-TFDLWFG.ts +23 -0
  76. package/@types/forms/fields/file.d.ts +11 -5
  77. package/@types/forms/fields/file.sync-conflict-20250918-222049-TFDLWFG.d.ts +23 -0
  78. package/@types/forms/fields/float.d.ts +4 -0
  79. package/@types/forms/fields/get-field-for-sealious.d.sync-conflict-20250918-222046-TFDLWFG.ts +29 -0
  80. package/@types/forms/fields/get-field-for-sealious.d.ts +31 -0
  81. package/@types/forms/fields/get-field-for-sealious.sync-conflict-20250918-222042-TFDLWFG.d.ts +29 -0
  82. package/@types/forms/fields/html.d.ts +6 -0
  83. package/@types/forms/fields/image.d.sync-conflict-20250918-222042-TFDLWFG.ts +5 -0
  84. package/@types/forms/fields/image.d.ts +5 -0
  85. package/@types/forms/fields/int.d.ts +6 -0
  86. package/@types/forms/fields/json.d.ts +13 -0
  87. package/@types/forms/fields/markdown.d.ts +6 -0
  88. package/@types/forms/fields/multiple-files.d.sync-conflict-20250918-184304-TFDLWFG.ts +16 -0
  89. package/@types/forms/fields/multiple-files.d.ts +3 -1
  90. package/@types/forms/fields/number.d.sync-conflict-20250918-184317-TFDLWFG.ts +25 -0
  91. package/@types/forms/fields/number.d.sync-conflict-20250918-222047-TFDLWFG.ts +25 -0
  92. package/@types/forms/fields/number.d.ts +3 -1
  93. package/@types/forms/fields/password.d.ts +6 -0
  94. package/@types/forms/fields/pick-from-list-sealious.d.ts +11 -0
  95. package/@types/forms/fields/pick-from-list.d.sync-conflict-20250918-184322-TFDLWFG.ts +15 -0
  96. package/@types/forms/fields/pick-from-list.d.ts +4 -3
  97. package/@types/forms/fields/proxy-field.d.sync-conflict-20250918-184307-TFDLWFG.ts +15 -0
  98. package/@types/forms/fields/proxy-field.d.ts +3 -1
  99. package/@types/forms/fields/regexp.d.sync-conflict-20250918-184305-TFDLWFG.ts +21 -0
  100. package/@types/forms/fields/regexp.d.sync-conflict-20250918-222045-TFDLWFG.ts +21 -0
  101. package/@types/forms/fields/regexp.d.ts +6 -1
  102. package/@types/forms/fields/regexp.sync-conflict-20250918-222047-TFDLWFG.d.ts +21 -0
  103. package/@types/forms/fields/simple-form-field.d.sync-conflict-20250918-184309-TFDLWFG.ts +29 -0
  104. package/@types/forms/fields/simple-form-field.d.sync-conflict-20250918-222044-TFDLWFG.ts +29 -0
  105. package/@types/forms/fields/simple-form-field.d.ts +23 -3
  106. package/@types/forms/fields/simple-form-field.sync-conflict-20250918-222049-TFDLWFG.d.ts +29 -0
  107. package/@types/forms/fields/single-reference.d.ts +19 -0
  108. package/@types/forms/fields/single-reference.sync-conflict-20250918-222043-TFDLWFG.d.ts +10 -0
  109. package/@types/forms/fields/structured-array.d.sync-conflict-20250918-184302-TFDLWFG.ts +27 -0
  110. package/@types/forms/fields/structured-array.d.sync-conflict-20250918-222049-TFDLWFG.ts +27 -0
  111. package/@types/forms/fields/structured-array.d.ts +19 -10
  112. package/@types/forms/fields/structured-array.sync-conflict-20250918-222047-TFDLWFG.d.ts +27 -0
  113. package/@types/forms/fields/table.d.sync-conflict-20250918-184303-TFDLWFG.ts +16 -0
  114. package/@types/forms/fields/table.d.ts +3 -0
  115. package/@types/forms/fields/text.d.ts +6 -0
  116. package/@types/forms/fields/url.d.ts +6 -0
  117. package/@types/forms/form-types.d.sync-conflict-20250918-222045-TFDLWFG.ts +26 -0
  118. package/@types/forms/form-types.d.ts +2 -0
  119. package/@types/forms/form.d.sync-conflict-20250918-184315-TFDLWFG.ts +32 -0
  120. package/@types/forms/form.d.sync-conflict-20250918-222049-TFDLWFG.ts +32 -0
  121. package/@types/forms/form.d.ts +10 -7
  122. package/@types/forms/form.sync-conflict-20250918-222049-TFDLWFG.d.ts +33 -0
  123. package/@types/forms/form.test.d.sync-conflict-20250918-184318-TFDLWFG.ts +6 -0
  124. package/@types/forms/form.test.d.sync-conflict-20250918-222047-TFDLWFG.ts +6 -0
  125. package/@types/forms/form.test.d.ts +2 -2
  126. package/@types/forms/multiform.d.sync-conflict-20250918-184308-TFDLWFG.ts +23 -0
  127. package/@types/forms/multiform.d.ts +1 -1
  128. package/@types/forms/multiform.sync-conflict-20250918-222044-TFDLWFG.d.ts +23 -0
  129. package/@types/index.d.sync-conflict-20250918-184316-TFDLWFG.ts +46 -0
  130. package/@types/index.d.ts +2 -2
  131. package/@types/mount.d.sync-conflict-20250918-184320-TFDLWFG.ts +6 -0
  132. package/@types/page/list.d.sync-conflict-20250918-184318-TFDLWFG.ts +48 -0
  133. package/@types/page/list.d.sync-conflict-20250918-222046-TFDLWFG.ts +48 -0
  134. package/@types/page/list.d.ts +2 -2
  135. package/@types/page/list.sync-conflict-20250918-222048-TFDLWFG.d.ts +48 -0
  136. package/@types/page/mountable-with-fields.d.sync-conflict-20250918-184321-TFDLWFG.ts +42 -0
  137. package/@types/page/mountable-with-fields.d.sync-conflict-20250918-222046-TFDLWFG.ts +42 -0
  138. package/@types/page/mountable-with-fields.d.ts +3 -3
  139. package/@types/page/mountable-with-fields.sync-conflict-20250918-222044-TFDLWFG.d.ts +42 -0
  140. package/@types/page/mountable.d.sync-conflict-20250918-184306-TFDLWFG.ts +10 -0
  141. package/@types/page/page.d.sync-conflict-20250918-184320-TFDLWFG.ts +18 -0
  142. package/@types/page/props-parser.d.sync-conflict-20250918-184305-TFDLWFG.ts +15 -0
  143. package/@types/page/props-parser.d.ts +0 -1
  144. package/@types/page/stateful-page.d.sync-conflict-20250918-184326-TFDLWFG.ts +62 -0
  145. package/@types/templates/shared/shared-crud-form-fields.d.sync-conflict-20250918-184306-TFDLWFG.ts +1 -0
  146. package/@types/templates/shared/shared-crud-form-fields.d.ts +0 -67
  147. package/@types/test_utils/test-on-real-app.d.sync-conflict-20250918-184320-TFDLWFG.ts +26 -0
  148. package/@types/test_utils/test-on-real-app.d.ts +0 -1
  149. package/@types/utils/extract-fields-from-collection.d.sync-conflict-20250918-184312-TFDLWFG.ts +18 -0
  150. package/@types/utils/extract-fields-from-collection.d.ts +5 -1
  151. package/@types/utils/extract-fields-from-collection.sync-conflict-20250918-222045-TFDLWFG.d.ts +18 -0
  152. package/@types/utils/wrap-attributes.d.ts +3 -0
  153. package/README.md +5 -0
  154. package/assets/file-icon.svg +5 -0
  155. package/lib/add-crud.js +80 -89
  156. package/lib/add-list-route.test.js +1 -1
  157. package/lib/add-route.js +0 -7
  158. package/lib/build.js +3 -1
  159. package/lib/cli.js +2 -5
  160. package/lib/controllers/table-add-button.stimulus.js +35 -0
  161. package/lib/forms/controls/array.js +20 -16
  162. package/lib/forms/controls/big-radio-group.js +2 -2
  163. package/lib/forms/controls/checkbox-group.js +7 -7
  164. package/lib/forms/controls/checkboxed-list-input.js +9 -2
  165. package/lib/forms/controls/controls.js +2 -2
  166. package/lib/forms/controls/derived-frame.js +5 -1
  167. package/lib/forms/controls/derived.js +1 -1
  168. package/lib/forms/controls/dropdown.js +4 -1
  169. package/lib/forms/controls/editable-collection-subset.js +2 -2
  170. package/lib/forms/controls/file.js +26 -2
  171. package/lib/forms/controls/file.test.js +2 -2
  172. package/lib/forms/controls/hidden-input.js +4 -1
  173. package/lib/forms/controls/{photo.js → image.js} +6 -7
  174. package/lib/forms/controls/{photo.test.js → image.test.js} +6 -21
  175. package/lib/forms/controls/multiple-files.js +10 -1
  176. package/lib/forms/controls/{multiple-photos.js → multiple-images.js} +3 -3
  177. package/lib/forms/controls/simple-input.js +13 -12
  178. package/lib/forms/controls/single-reference.js +4 -0
  179. package/lib/forms/controls/table.js +66 -24
  180. package/lib/forms/controls/textarea.js +4 -2
  181. package/lib/forms/controls/tickable.js +13 -5
  182. package/lib/forms/fields/boolean.js +14 -0
  183. package/lib/forms/fields/checkboxed-list.js +4 -0
  184. package/lib/forms/fields/collection-field.js +9 -0
  185. package/lib/forms/fields/color.js +10 -0
  186. package/lib/forms/fields/coordinates.js +49 -0
  187. package/lib/forms/fields/date.js +34 -0
  188. package/lib/forms/fields/datetime.js +46 -0
  189. package/lib/forms/fields/deep-reverse-single-reference-list.js +81 -0
  190. package/lib/forms/fields/deep-reverse-single-reference-table.js +122 -0
  191. package/lib/forms/fields/email.js +7 -0
  192. package/lib/forms/fields/enum-multiple-sealious.js +32 -0
  193. package/lib/forms/fields/field.js +32 -4
  194. package/lib/forms/fields/field.test.js +5 -5
  195. package/lib/forms/fields/fields.js +23 -8
  196. package/lib/forms/fields/file.js +33 -9
  197. package/lib/forms/fields/file.test.js +4 -16
  198. package/lib/forms/fields/float.js +10 -0
  199. package/lib/forms/fields/get-field-for-sealious.js +213 -0
  200. package/lib/forms/fields/html.js +14 -0
  201. package/lib/forms/fields/image.js +13 -0
  202. package/lib/forms/fields/int.js +23 -0
  203. package/lib/forms/fields/json.js +31 -0
  204. package/lib/forms/fields/markdown.js +14 -0
  205. package/lib/forms/fields/multiple-files.js +4 -0
  206. package/lib/forms/fields/number.js +6 -0
  207. package/lib/forms/fields/password.js +13 -0
  208. package/lib/forms/fields/pick-from-list-sealious.js +17 -0
  209. package/lib/forms/fields/pick-from-list.js +6 -2
  210. package/lib/forms/fields/proxy-field.js +3 -0
  211. package/lib/forms/fields/regexp.js +14 -0
  212. package/lib/forms/fields/simple-form-field.js +60 -2
  213. package/lib/forms/fields/single-reference.js +44 -0
  214. package/lib/forms/fields/structured-array.js +63 -12
  215. package/lib/forms/fields/table.js +28 -1
  216. package/lib/forms/fields/text.js +17 -0
  217. package/lib/forms/fields/url.js +17 -0
  218. package/lib/forms/form.js +30 -13
  219. package/lib/forms/form.test.js +3 -4
  220. package/lib/forms/multiform.js +4 -2
  221. package/lib/forms/multiform.test.js +3 -3
  222. package/lib/generate-stimulus.js +1 -0
  223. package/lib/index.js +1 -0
  224. package/lib/make-hidden-inputs.js +1 -1
  225. package/lib/mount.js +11 -0
  226. package/lib/notifier.js +0 -1
  227. package/lib/page/list.js +15 -8
  228. package/lib/page/mountable-with-fields.js +14 -6
  229. package/lib/page/mountable-with-fields.test.js +1 -1
  230. package/lib/templates/form.js +8 -9
  231. package/lib/templates/multiform.js +4 -4
  232. package/lib/templates/page.js +0 -2
  233. package/lib/templates/shared/collection-create-form.js +28 -40
  234. package/lib/templates/shared/collection-edit-form.js +40 -77
  235. package/lib/templates/shared/collection-list.js +12 -20
  236. package/lib/templates/shared/shared-crud-form-fields.js +27 -95
  237. package/lib/test_utils/test-on-real-app.js +3 -3
  238. package/lib/utils/extract-fields-from-collection.js +60 -20
  239. package/lib/utils/make-slug.js +1 -1
  240. package/lib/utils/wrap-attributes.js +20 -0
  241. package/package.json +5 -4
  242. package/src/add-crud.ts +86 -97
  243. package/src/add-list-route.test.ts +1 -1
  244. package/src/add-route.ts +0 -7
  245. package/src/build.ts +3 -1
  246. package/src/cli.ts +3 -5
  247. package/src/controllers/table-add-button.stimulus.ts +35 -0
  248. package/src/forms/controls/array.ts +23 -20
  249. package/src/forms/controls/autocomplete.ts +1 -1
  250. package/src/forms/controls/big-radio-group.ts +2 -2
  251. package/src/forms/controls/checkbox-group.ts +9 -9
  252. package/src/forms/controls/checkboxed-list-input.ts +27 -15
  253. package/src/forms/controls/controls.ts +2 -2
  254. package/src/forms/controls/derived-frame.ts +5 -1
  255. package/src/forms/controls/derived.ts +1 -1
  256. package/src/forms/controls/dropdown.ts +5 -2
  257. package/src/forms/controls/editable-collection-subset.ts +2 -2
  258. package/src/forms/controls/file.test.ts +4 -2
  259. package/src/forms/controls/file.ts +31 -5
  260. package/src/forms/controls/form-control.ts +7 -2
  261. package/src/forms/controls/hidden-input.ts +4 -1
  262. package/src/forms/controls/{photo.test.ts → image.test.ts} +5 -22
  263. package/src/forms/controls/{photo.ts → image.ts} +3 -5
  264. package/src/forms/controls/multiple-files.ts +18 -1
  265. package/src/forms/controls/{multiple-photos.ts → multiple-images.ts} +1 -1
  266. package/src/forms/controls/number.ts +1 -1
  267. package/src/forms/controls/simple-input.ts +18 -34
  268. package/src/forms/controls/single-reference.ts +10 -2
  269. package/src/forms/controls/table.ts +90 -31
  270. package/src/forms/controls/textarea.ts +6 -4
  271. package/src/forms/controls/tickable.ts +13 -5
  272. package/src/forms/fields/boolean.ts +23 -1
  273. package/src/forms/fields/checkboxed-list.ts +11 -2
  274. package/src/forms/fields/collection-field.ts +16 -1
  275. package/src/forms/fields/color.ts +9 -0
  276. package/src/forms/fields/coordinates.ts +66 -0
  277. package/src/forms/fields/date.ts +50 -0
  278. package/src/forms/fields/datetime.ts +66 -0
  279. package/src/forms/fields/deep-reverse-single-reference-list.ts +136 -0
  280. package/src/forms/fields/deep-reverse-single-reference-table.ts +213 -0
  281. package/src/forms/fields/email.ts +9 -0
  282. package/src/forms/fields/enum-multiple-sealious.ts +48 -0
  283. package/src/forms/fields/field.test.ts +5 -5
  284. package/src/forms/fields/field.ts +94 -8
  285. package/src/forms/fields/fields.ts +23 -8
  286. package/src/forms/fields/file.test.ts +4 -16
  287. package/src/forms/fields/file.ts +43 -15
  288. package/src/forms/fields/float.ts +9 -0
  289. package/src/forms/fields/get-field-for-sealious.ts +304 -0
  290. package/src/forms/fields/html.ts +15 -0
  291. package/src/forms/fields/image.ts +12 -0
  292. package/src/forms/fields/int.ts +25 -0
  293. package/src/forms/fields/json.ts +48 -0
  294. package/src/forms/fields/markdown.ts +15 -0
  295. package/src/forms/fields/multiple-files.ts +10 -1
  296. package/src/forms/fields/number.ts +8 -1
  297. package/src/forms/fields/password.ts +17 -0
  298. package/src/forms/fields/pick-from-list-sealious.ts +22 -0
  299. package/src/forms/fields/pick-from-list.ts +7 -3
  300. package/src/forms/fields/proxy-field.ts +6 -1
  301. package/src/forms/fields/regexp.ts +27 -1
  302. package/src/forms/fields/simple-form-field.ts +95 -7
  303. package/src/forms/fields/single-reference.ts +62 -0
  304. package/src/forms/fields/structured-array.ts +115 -18
  305. package/src/forms/fields/table.ts +32 -1
  306. package/src/forms/fields/text.ts +18 -0
  307. package/src/forms/fields/url.ts +20 -0
  308. package/src/forms/form-types.ts +2 -0
  309. package/src/forms/form.test.ts +3 -4
  310. package/src/forms/form.ts +37 -16
  311. package/src/forms/forms.css +0 -85
  312. package/src/forms/multiform.test.ts +3 -3
  313. package/src/forms/multiform.ts +2 -0
  314. package/src/generate-stimulus.ts +1 -0
  315. package/src/index.ts +2 -1
  316. package/src/make-hidden-inputs.ts +1 -1
  317. package/src/mount.ts +14 -0
  318. package/src/notifier.ts +0 -1
  319. package/src/page/list.ts +15 -8
  320. package/src/page/mountable-with-fields.test.ts +1 -1
  321. package/src/page/mountable-with-fields.ts +18 -9
  322. package/src/register-external.ts +1 -1
  323. package/src/templates/form.ts +8 -9
  324. package/src/templates/multiform.ts +4 -4
  325. package/src/templates/page.ts +0 -2
  326. package/src/templates/shared/collection-create-form.ts +30 -66
  327. package/src/templates/shared/collection-edit-form.ts +41 -102
  328. package/src/templates/shared/collection-list.ts +12 -20
  329. package/src/templates/shared/item-delete.ts +0 -1
  330. package/src/templates/shared/shared-crud-form-fields.ts +37 -171
  331. package/src/test_utils/test-on-real-app.ts +4 -3
  332. package/src/utils/extract-fields-from-collection.ts +76 -25
  333. package/src/utils/make-slug.ts +1 -1
  334. package/src/utils/wrap-attributes.ts +17 -0
  335. package/lib/add-verbose-crud.js +0 -119
  336. package/lib/crud-field-snippets.js +0 -52
  337. package/lib/find-css-includes.js +0 -3
  338. package/lib/forms/controls/reverse-single-reference.js +0 -1
  339. package/lib/forms/fields/enum-multiple.js +0 -47
  340. package/lib/forms/fields/enum-multiple.test.js +0 -27
  341. package/lib/forms/fields/enum.js +0 -41
  342. package/lib/forms/fields/enum.test.js +0 -21
  343. package/lib/forms/fields/reverse-single-reference.js +0 -17
  344. package/lib/templates/shared/handlers/boolean.js +0 -14
  345. package/lib/templates/shared/handlers/date.js +0 -8
  346. package/lib/templates/shared/handlers/deep-reverse-single-reference.js +0 -209
  347. package/lib/templates/shared/handlers/default.js +0 -49
  348. package/lib/templates/shared/handlers/enum.js +0 -19
  349. package/lib/templates/shared/handlers/file.js +0 -23
  350. package/lib/templates/shared/handlers/image.js +0 -32
  351. package/lib/templates/shared/handlers/int.js +0 -11
  352. package/lib/templates/shared/handlers/jdd.js +0 -10
  353. package/lib/templates/shared/handlers/single-reference.js +0 -12
  354. package/lib/templates/shared/handlers/structured-array.js +0 -33
  355. package/src/add-verbose-crud.ts +0 -138
  356. package/src/crud-field-snippets.ts +0 -57
  357. package/src/find-css-includes.ts +0 -3
  358. package/src/forms/controls/reverse-single-reference.ts +0 -50
  359. package/src/forms/fields/enum-multiple.test.ts +0 -31
  360. package/src/forms/fields/enum-multiple.ts +0 -62
  361. package/src/forms/fields/enum.test.ts +0 -25
  362. package/src/forms/fields/enum.ts +0 -56
  363. package/src/forms/fields/reverse-single-reference.ts +0 -20
  364. package/src/templates/shared/handlers/boolean.ts +0 -18
  365. package/src/templates/shared/handlers/date.ts +0 -12
  366. package/src/templates/shared/handlers/deep-reverse-single-reference.ts +0 -244
  367. package/src/templates/shared/handlers/default.ts +0 -64
  368. package/src/templates/shared/handlers/enum.ts +0 -23
  369. package/src/templates/shared/handlers/file.ts +0 -27
  370. package/src/templates/shared/handlers/image.ts +0 -45
  371. package/src/templates/shared/handlers/int.ts +0 -15
  372. package/src/templates/shared/handlers/jdd.ts +0 -14
  373. package/src/templates/shared/handlers/single-reference.ts +0 -16
  374. package/src/templates/shared/handlers/structured-array.ts +0 -42
@@ -1,12 +1,10 @@
1
1
  import { hasFieldOfType, is, predicates } from "@sealcode/ts-predicates";
2
2
  import { Context } from "koa";
3
- import {
4
- FileManager,
5
- FilePointer,
6
- PathFilePointer,
7
- } from "@sealcode/file-manager";
3
+ import { FilePointer, PathFilePointer } from "@sealcode/file-manager";
8
4
  import { FormDataValue } from "../form-types.js";
9
5
  import { FieldParseResult, FormField } from "./field.js";
6
+ import { File as FileControl } from "../controls/file.js";
7
+ import { FormControl, FormControlContext } from "../controls/form-control.js";
10
8
 
11
9
  export type FileContainer = {
12
10
  old: FilePointer | null;
@@ -15,22 +13,20 @@ export type FileContainer = {
15
13
 
16
14
  export class File<Required extends boolean> extends FormField<
17
15
  Required,
18
- FileContainer
16
+ FileContainer,
17
+ FormControl
19
18
  > {
20
- constructor(
21
- public readonly required: Required,
22
- public file_manager: FileManager
23
- ) {
19
+ constructor(public readonly required: Required) {
24
20
  super(required);
25
21
  }
26
22
 
27
23
  async parse(
28
- _ctx: Context,
24
+ ctx: Context,
29
25
  raw_value: FormDataValue
30
26
  ): Promise<FieldParseResult<FileContainer>> {
31
27
  let result;
32
28
  if (is(raw_value, predicates.string)) {
33
- const file = await this.file_manager.fromToken(raw_value);
29
+ const file = await ctx.$app.fileManager.fromToken(raw_value);
34
30
  result = {
35
31
  parsed_value: { old: file, new: null },
36
32
  error: null,
@@ -48,7 +44,7 @@ export class File<Required extends boolean> extends FormField<
48
44
  "old",
49
45
  predicates.instanceOf(PathFilePointer)
50
46
  )
51
- ? await this.file_manager.toPointer(
47
+ ? await ctx.$app.fileManager.toPointer(
52
48
  raw_value.old as string | FilePointer
53
49
  )
54
50
  : null;
@@ -70,16 +66,48 @@ export class File<Required extends boolean> extends FormField<
70
66
  parsed_value: { old: old_file, new: new_file },
71
67
  };
72
68
  }
73
-
74
69
  return result;
75
70
  }
76
71
 
77
72
  async getDatabaseValue(ctx: Context, data: Record<string, FormDataValue>) {
78
- const { parsed } = await this.getValue(ctx, data);
73
+ const { parsed } = await this.getParsedValue(ctx, data);
79
74
  return parsed?.new || undefined;
80
75
  }
81
76
 
82
77
  getEmptyValue() {
83
78
  return { old: null, new: null };
84
79
  }
80
+
81
+ getControl(...args: any[]): FileControl {
82
+ return new FileControl(this, { label: this.name, autocomplete: false });
83
+ }
84
+
85
+ async getSealiousCreateValue(
86
+ fctx: FormControlContext
87
+ ): Promise<FilePointer | undefined> {
88
+ const { parsed: value } = await this.getParsedValue(
89
+ fctx.ctx,
90
+ fctx.data.raw_values
91
+ );
92
+ const pointer = value?.new || value?.old || undefined;
93
+ if (this.required && !pointer) {
94
+ throw new Error("File is required, but no value is provided");
95
+ }
96
+ return pointer;
97
+ }
98
+
99
+ async sealiousValueToForm(
100
+ ctx: Context,
101
+ sealiousValue: FilePointer | string | null
102
+ ): Promise<{ old: FilePointer | undefined } | Record<string, never>> {
103
+ if (!sealiousValue) {
104
+ return {};
105
+ }
106
+ if (typeof sealiousValue == "string") {
107
+ sealiousValue = await ctx.$app.fileManager.fromToken(sealiousValue);
108
+ }
109
+ return {
110
+ old: sealiousValue, // FilePointer
111
+ };
112
+ }
85
113
  }
@@ -0,0 +1,9 @@
1
+ import { NumberBasedSimpleField } from "./simple-form-field.js";
2
+
3
+ export class Float<
4
+ Required extends boolean
5
+ > extends NumberBasedSimpleField<Required> {
6
+ constructor(required: Required) {
7
+ super(required, "number");
8
+ }
9
+ }
@@ -0,0 +1,304 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
4
+ import {
5
+ Collection,
6
+ Field as SealiousField,
7
+ FieldTypes as SealiousFieldTypes,
8
+ RequiredField as SealiousRequiredField,
9
+ } from "sealious";
10
+ import { Boolean as BooleanField } from "./boolean.js";
11
+ import { SimpleFormField, TextBasedSimpleField } from "./simple-form-field.js";
12
+ import { File } from "./file.js";
13
+ import { CollectionField } from "./collection-field.js";
14
+ import { StructuredArray as StructuredArrayField } from "./structured-array.js";
15
+ import { Color } from "./color.js";
16
+ import { DateField } from "./date.js";
17
+ import { DateTime } from "./datetime.js";
18
+ import { EmailField } from "./email.js";
19
+ import { Float } from "./float.js";
20
+ import { HTML } from "./html.js";
21
+ import { Int } from "./int.js";
22
+ import { JSONField } from "./json.js";
23
+ import { Password } from "./password.js";
24
+ import { Text } from "./text.js";
25
+ import { Markdown } from "./markdown.js";
26
+ import { DeepReverseSingleReferenceTable } from "./deep-reverse-single-reference-table.js";
27
+ import { DeepReverseSingleReferenceList } from "./deep-reverse-single-reference-list.js";
28
+ import { Coordinates } from "./coordinates.js";
29
+ import { SimpleInput } from "../controls/simple-input.js";
30
+
31
+ import { FormField } from "./field.js";
32
+ import { PickFromListSealious } from "./pick-from-list-sealious.js";
33
+ import { SingleReference } from "./single-reference.js";
34
+ import extract_fields_from_collection, {
35
+ ExtractedFieldInfo,
36
+ } from "../../utils/extract-fields-from-collection.js";
37
+ import { EnumMultipleSealious } from "./enum-multiple-sealious.js";
38
+ import { URLField } from "./url.js";
39
+ import { Image } from "./image.js";
40
+
41
+ export type SealiousToFormField<T> = T extends SealiousFieldTypes.Boolean
42
+ ? BooleanField<false>
43
+ : T extends SealiousFieldTypes.Color
44
+ ? Color<false>
45
+ : T extends SealiousFieldTypes.ControlAccess<infer R>
46
+ ? SealiousToFormField<R>
47
+ : T extends SealiousFieldTypes.Date
48
+ ? DateField<false>
49
+ : T extends SealiousFieldTypes.DateTime
50
+ ? DateTime<false>
51
+ : T extends SealiousFieldTypes.DeepReverseSingleReference
52
+ ? DeepReverseSingleReferenceList | DeepReverseSingleReferenceTable
53
+ : T extends SealiousFieldTypes.DisallowUpdate<any, any, any, infer R>
54
+ ? SealiousToFormField<R>
55
+ : T extends SealiousFieldTypes.Email
56
+ ? EmailField<false>
57
+ : T extends SealiousFieldTypes.Enum<any>
58
+ ? PickFromListSealious<false>
59
+ : T extends SealiousFieldTypes.EnumMultiple<infer R>
60
+ ? R extends string[]
61
+ ? EnumMultipleSealious<R>
62
+ : TextBasedSimpleField<false>
63
+ : T extends SealiousFieldTypes.File
64
+ ? File<false>
65
+ : T extends SealiousFieldTypes.Float
66
+ ? Float<false>
67
+ : T extends SealiousFieldTypes.HTML
68
+ ? HTML<false>
69
+ : T extends SealiousFieldTypes.Image
70
+ ? Image<false>
71
+ : T extends SealiousFieldTypes.Int
72
+ ? Int<false>
73
+ : T extends SealiousFieldTypes.JsonObject
74
+ ? JSONField<false>
75
+ : T extends SealiousFieldTypes.JDD
76
+ ? TextBasedSimpleField<false, SimpleInput>
77
+ : T extends SealiousFieldTypes.Password
78
+ ? Password<false>
79
+ : T extends SealiousFieldTypes.ReverseSingleReference
80
+ ? TextBasedSimpleField<false, SimpleInput>
81
+ : T extends SealiousFieldTypes.SecretToken
82
+ ? TextBasedSimpleField<false, SimpleInput>
83
+ : T extends SealiousFieldTypes.SettableBy<infer R>
84
+ ? SealiousToFormField<R>
85
+ : T extends SealiousFieldTypes.SingleReference
86
+ ? SingleReference<Collection, boolean, T>
87
+ : T extends SealiousFieldTypes.Text
88
+ ? Text<false>
89
+ : T extends SealiousFieldTypes.Username
90
+ ? CollectionField<SealiousFieldTypes.Username, false>
91
+ : T extends SealiousFieldTypes.ValueExistingInCollection
92
+ ? SimpleFormField<false>
93
+ : T extends SealiousFieldTypes.ValueNotExistingInCollection
94
+ ? SimpleFormField<false>
95
+ : T extends SealiousRequiredField<any, any, any>
96
+ ? SimpleFormField<false>
97
+ : T extends SealiousFieldTypes.Url
98
+ ? URLField<false>
99
+ : T extends SealiousFieldTypes.Money
100
+ ? SimpleFormField<false>
101
+ : T extends SealiousFieldTypes.Markdown
102
+ ? Markdown<false>
103
+ : T extends SealiousFieldTypes.Coordinates
104
+ ? Coordinates<false>
105
+ : T extends SealiousFieldTypes.StructuredArray<infer R>
106
+ ? StructuredArrayField<R>
107
+ : TextBasedSimpleField<any>;
108
+
109
+ export function sealiousToFormField<SF extends SealiousField<any>>(
110
+ sealious_field: SF
111
+ ): SealiousToFormField<SF> {
112
+ if (sealious_field instanceof SealiousFieldTypes.Boolean) {
113
+ return new BooleanField(
114
+ sealious_field.required
115
+ ) as SealiousToFormField<SF>;
116
+ }
117
+ if (sealious_field instanceof SealiousFieldTypes.Color) {
118
+ return new Color(sealious_field.required) as SealiousToFormField<SF>;
119
+ }
120
+ if (sealious_field instanceof SealiousFieldTypes.ControlAccess) {
121
+ const target_field = sealious_field.virtual_field;
122
+ return sealiousToFormField(target_field) as SealiousToFormField<SF>;
123
+ }
124
+ if (sealious_field instanceof SealiousFieldTypes.Date) {
125
+ return new DateField(
126
+ sealious_field.required
127
+ ) as SealiousToFormField<SF>;
128
+ }
129
+ if (sealious_field instanceof SealiousFieldTypes.DateTime) {
130
+ return new DateTime(sealious_field.required) as SealiousToFormField<SF>;
131
+ }
132
+ if (
133
+ sealious_field instanceof SealiousFieldTypes.DeepReverseSingleReference
134
+ ) {
135
+ const referencing_collection =
136
+ sealious_field.collection.app.collections[
137
+ sealious_field.referencing_collection
138
+ ];
139
+ if (!referencing_collection) {
140
+ throw new Error(
141
+ "Unknown collection: " + sealious_field.referencing_collection
142
+ );
143
+ }
144
+ if (Object.keys(referencing_collection.fields).length == 2) {
145
+ return new DeepReverseSingleReferenceList(
146
+ sealious_field
147
+ ) as SealiousToFormField<SF>;
148
+ } else {
149
+ return new DeepReverseSingleReferenceTable(
150
+ sealious_field
151
+ ) as SealiousToFormField<SF>;
152
+ }
153
+ }
154
+ if (sealious_field instanceof SealiousFieldTypes.DisallowUpdate) {
155
+ return sealiousToFormField(
156
+ sealious_field.virtual_field
157
+ ) as SealiousToFormField<SF>;
158
+ }
159
+ if (sealious_field instanceof SealiousFieldTypes.Email) {
160
+ return new EmailField(
161
+ sealious_field.required
162
+ ) as SealiousToFormField<SF>;
163
+ }
164
+ if (sealious_field instanceof SealiousFieldTypes.Enum) {
165
+ return new PickFromListSealious(
166
+ sealious_field
167
+ ) as SealiousToFormField<SF>;
168
+ }
169
+ if (sealious_field instanceof SealiousFieldTypes.EnumMultiple) {
170
+ return new EnumMultipleSealious(
171
+ sealious_field
172
+ ) as SealiousToFormField<SF>;
173
+ }
174
+ if (sealious_field instanceof SealiousFieldTypes.File) {
175
+ return new File(sealious_field.required) as SealiousToFormField<SF>;
176
+ }
177
+ if (sealious_field instanceof SealiousFieldTypes.Float) {
178
+ return new Float(sealious_field.required) as SealiousToFormField<SF>;
179
+ }
180
+ if (sealious_field instanceof SealiousFieldTypes.HTML) {
181
+ return new HTML(sealious_field.required) as SealiousToFormField<SF>;
182
+ }
183
+ if (sealious_field instanceof SealiousFieldTypes.Image) {
184
+ return new Image(sealious_field.required) as SealiousToFormField<SF>;
185
+ }
186
+ if (sealious_field instanceof SealiousFieldTypes.Int) {
187
+ return new Int(sealious_field.required) as SealiousToFormField<SF>;
188
+ }
189
+ if (sealious_field instanceof SealiousFieldTypes.JsonObject) {
190
+ return new JSONField(
191
+ sealious_field.required
192
+ ) as SealiousToFormField<SF>;
193
+ }
194
+ if (sealious_field instanceof SealiousFieldTypes.Password) {
195
+ return new Password(sealious_field.required) as SealiousToFormField<SF>;
196
+ }
197
+ if (sealious_field instanceof SealiousFieldTypes.SettableBy) {
198
+ return sealiousToFormField(
199
+ sealious_field.virtual_field
200
+ ) as SealiousToFormField<SF>;
201
+ }
202
+ if (sealious_field instanceof SealiousFieldTypes.SingleReference) {
203
+ return new SingleReference(
204
+ false,
205
+ sealious_field
206
+ ) as unknown as SealiousToFormField<SF>;
207
+ }
208
+ if (sealious_field instanceof SealiousFieldTypes.Text) {
209
+ return new Text(sealious_field.required) as SealiousToFormField<SF>;
210
+ }
211
+ if (sealious_field instanceof SealiousFieldTypes.Username) {
212
+ return new Text(sealious_field.required) as SealiousToFormField<SF>;
213
+ }
214
+ if (sealious_field instanceof SealiousFieldTypes.Url) {
215
+ return new URLField(sealious_field.required) as SealiousToFormField<SF>;
216
+ }
217
+ if (sealious_field instanceof SealiousFieldTypes.Money) {
218
+ return new Float(sealious_field.required) as SealiousToFormField<SF>;
219
+ }
220
+ if (sealious_field instanceof SealiousFieldTypes.Markdown) {
221
+ return new Markdown(sealious_field.required) as SealiousToFormField<SF>;
222
+ }
223
+ if (sealious_field instanceof SealiousFieldTypes.Coordinates) {
224
+ return new Coordinates(
225
+ sealious_field.required
226
+ ) as SealiousToFormField<SF>;
227
+ }
228
+ if (sealious_field instanceof SealiousFieldTypes.StructuredArray) {
229
+ return new StructuredArrayField(
230
+ sealious_field
231
+ ) as SealiousToFormField<SF>;
232
+ }
233
+ return new TextBasedSimpleField(false) as SealiousToFormField<SF>;
234
+ }
235
+
236
+ export async function sealiousFieldInfoToFormField(
237
+ field_info: ExtractedFieldInfo
238
+ ): Promise<FormField> {
239
+ switch (field_info.type) {
240
+ case "boolean":
241
+ return new BooleanField(field_info.is_required);
242
+ case "color":
243
+ return new Color(field_info.is_required);
244
+ case "date":
245
+ return new DateField(field_info.is_required);
246
+ case "datetime":
247
+ return new DateTime(field_info.is_required);
248
+ case "deep-reverse-single-reference": {
249
+ const referencing_fields = await extract_fields_from_collection(
250
+ field_info.referencing_collection as string
251
+ );
252
+ if (referencing_fields.length == 2) {
253
+ return new DeepReverseSingleReferenceList({} as any);
254
+ } else {
255
+ return new DeepReverseSingleReferenceTable({} as any);
256
+ }
257
+ }
258
+ case "email":
259
+ return new EmailField(field_info.is_required);
260
+ case "enum":
261
+ return new PickFromListSealious({} as any);
262
+ case "enum-multiple":
263
+ return new EnumMultipleSealious({} as any);
264
+ case "file":
265
+ return new File(field_info.is_required);
266
+ case "float":
267
+ return new Float(field_info.is_required);
268
+ case "html":
269
+ return new HTML(field_info.is_required);
270
+ case "image":
271
+ return new Image(field_info.is_required);
272
+ case "int":
273
+ return new Int(field_info.is_required);
274
+ case "json-object":
275
+ return new JSONField(field_info.is_required);
276
+ case "password":
277
+ return new Password(field_info.is_required);
278
+ case "single-reference":
279
+ return new SingleReference(false, {} as any);
280
+ case "text":
281
+ return new Text(field_info.is_required);
282
+
283
+ case "username":
284
+ return new Text(field_info.is_required);
285
+
286
+ case "url":
287
+ return new URLField(field_info.is_required);
288
+ case "money":
289
+ return new Float(field_info.is_required);
290
+
291
+ case "markdown":
292
+ return new Markdown(field_info.is_required);
293
+ case "coordinates":
294
+ return new Coordinates(field_info.is_required);
295
+ case "structured-array":
296
+ // we don't need the full thing at this point, so we don't fill in the subfields
297
+ return new StructuredArrayField(
298
+ new SealiousFieldTypes.StructuredArray({})
299
+ );
300
+
301
+ default:
302
+ return new TextBasedSimpleField(false);
303
+ }
304
+ }
@@ -0,0 +1,15 @@
1
+ import { Textarea } from "../controls/textarea.js";
2
+ import { TextBasedSimpleField } from "./simple-form-field.js";
3
+
4
+ export class HTML<Required extends boolean> extends TextBasedSimpleField<
5
+ Required,
6
+ Textarea
7
+ > {
8
+ constructor(required: Required) {
9
+ super(required, "text");
10
+ }
11
+
12
+ getControl(): Textarea {
13
+ return new Textarea(this);
14
+ }
15
+ }
@@ -0,0 +1,12 @@
1
+ import { Image as ImageControl } from "../controls/image.js";
2
+ import { File as FileField } from "./file.js";
3
+ import { FileContainer } from "../fields/file.js";
4
+ import { FormField } from "./field.js";
5
+
6
+ export class Image<Required extends boolean> extends FileField<Required> {
7
+ getControl(): ImageControl {
8
+ return new ImageControl(
9
+ this as unknown as FormField<boolean, FileContainer>
10
+ );
11
+ }
12
+ }
@@ -0,0 +1,25 @@
1
+ import { FormControlContext } from "../controls/form-control.js";
2
+ import { NumberBasedSimpleField } from "./simple-form-field.js";
3
+
4
+ export class Int<
5
+ Required extends boolean
6
+ > extends NumberBasedSimpleField<Required> {
7
+ constructor(required: Required) {
8
+ super(required, "number");
9
+ }
10
+
11
+ async getSealiousCreateValue(
12
+ fctx: FormControlContext
13
+ ): Promise<number | undefined> {
14
+ const { parsed } = await this.getParsedValue(
15
+ fctx.ctx,
16
+ fctx.data.raw_values
17
+ );
18
+ if (parsed == null) {
19
+ return undefined;
20
+ }
21
+ if (isNaN(parsed)) {
22
+ return undefined;
23
+ } else return parsed;
24
+ }
25
+ }
@@ -0,0 +1,48 @@
1
+ import { Context } from "koa";
2
+ import { FormControlContext } from "../controls/form-control.js";
3
+ import { Textarea } from "../controls/textarea.js";
4
+ import { FormDataValue } from "../form-types.js";
5
+ import { FieldParseResult } from "./field.js";
6
+ import { SimpleFormField } from "./simple-form-field.js";
7
+
8
+ export class JSONField<Required extends boolean> extends SimpleFormField<
9
+ Required,
10
+ Textarea,
11
+ Record<string, unknown>
12
+ > {
13
+ constructor(required: Required) {
14
+ super(required, "text");
15
+ }
16
+
17
+ getControl(): Textarea {
18
+ return new Textarea(this);
19
+ }
20
+
21
+ public getEmptyValue(): Record<string, unknown> {
22
+ return {};
23
+ }
24
+
25
+ async parse(
26
+ ctx: Context,
27
+ raw_value: FormDataValue
28
+ ): Promise<FieldParseResult<Record<string, unknown>>> {
29
+ return {
30
+ parsable: true,
31
+ error: null,
32
+ parsed_value: JSON.parse(raw_value as string) as Record<
33
+ string,
34
+ unknown
35
+ >,
36
+ };
37
+ }
38
+
39
+ async getSealiousCreateValue(
40
+ fctx: FormControlContext
41
+ ): Promise<Record<string, unknown> | null> {
42
+ const { parsed } = await this.getParsedValue(
43
+ fctx.ctx,
44
+ fctx.data.raw_values
45
+ );
46
+ return parsed;
47
+ }
48
+ }
@@ -0,0 +1,15 @@
1
+ import { Textarea } from "../controls/textarea.js";
2
+ import { TextBasedSimpleField } from "./simple-form-field.js";
3
+
4
+ export class Markdown<Required extends boolean> extends TextBasedSimpleField<
5
+ Required,
6
+ Textarea
7
+ > {
8
+ constructor(required: Required) {
9
+ super(required, "text");
10
+ }
11
+
12
+ getControl(): Textarea {
13
+ return new Textarea(this);
14
+ }
15
+ }
@@ -1,8 +1,13 @@
1
1
  import { Context } from "koa";
2
2
  import { FieldTypes as SealiousFieldTypes } from "sealious";
3
3
  import { FormField } from "./field.js";
4
+ import { MultipleFiles as MultipleFilesControl } from "../controls/multiple-files.js";
4
5
 
5
- export class MultipleFiles extends FormField<false> {
6
+ export class MultipleFiles extends FormField<
7
+ false,
8
+ undefined,
9
+ MultipleFilesControl
10
+ > {
6
11
  constructor(
7
12
  public collection_field: SealiousFieldTypes.ReverseSingleReference,
8
13
  public getItemId: (ctx: Context) => Promise<string> | string
@@ -17,4 +22,8 @@ export class MultipleFiles extends FormField<false> {
17
22
  async parse() {
18
23
  return <const>{ parsed_value: undefined, parsable: true, error: null }; // the control is supposed to do the heavy lifting here
19
24
  }
25
+
26
+ getControl() {
27
+ return new MultipleFilesControl(this);
28
+ }
20
29
  }
@@ -1,12 +1,13 @@
1
1
  import { is, predicates } from "@sealcode/ts-predicates";
2
2
  import { Context } from "koa";
3
+ import { SimpleInput } from "../controls/simple-input.js";
3
4
  import { FormDataValue } from "../form-types.js";
4
5
  import { FieldParseResult, FormField } from "./field.js";
5
6
 
6
7
  export class NumberField<
7
8
  DefaultValue extends number | null = number,
8
9
  Required extends boolean = boolean
9
- > extends FormField<Required, number | DefaultValue> {
10
+ > extends FormField<Required, number | DefaultValue, SimpleInput> {
10
11
  constructor(
11
12
  required: Required,
12
13
  public default_value: DefaultValue,
@@ -67,4 +68,10 @@ export class NumberField<
67
68
  public getEmptyValue(): DefaultValue {
68
69
  return this.default_value;
69
70
  }
71
+
72
+ getControl(): SimpleInput {
73
+ return new SimpleInput(this as FormField<boolean, number>, {
74
+ type: "number",
75
+ });
76
+ }
70
77
  }
@@ -0,0 +1,17 @@
1
+ import { Context } from "koa";
2
+ import { TextBasedSimpleField } from "./simple-form-field.js";
3
+
4
+ export class Password<
5
+ Required extends boolean
6
+ > extends TextBasedSimpleField<Required> {
7
+ constructor(required: Required) {
8
+ super(required, "password");
9
+ }
10
+
11
+ async sealiousValueToForm(
12
+ ctx: Context,
13
+ value: unknown
14
+ ): Promise<undefined> {
15
+ return undefined;
16
+ }
17
+ }
@@ -0,0 +1,22 @@
1
+ import { FieldTypes as SealiousFieldTypes } from "sealious";
2
+ import { PickFromListField } from "./pick-from-list.js";
3
+ import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
4
+
5
+ export class PickFromListSealious<
6
+ Required extends boolean
7
+ > extends PickFromListField<Required> {
8
+ constructor(public sealious_field: SealiousFieldTypes.Enum<string>) {
9
+ super(sealious_field.required as Required, async (ctx) =>
10
+ sealious_field
11
+ .getAllowedValues(ctx.$app)
12
+ .map((value) => ({ value, label: value }))
13
+ );
14
+ }
15
+
16
+ generateFieldDeclaration(
17
+ field_info: ExtractedFieldInfo,
18
+ vars: { form_field_types: string; sealious_field: string }
19
+ ): string {
20
+ return `new ${vars.form_field_types}.${this.constructor.name}(${vars.sealious_field})`;
21
+ }
22
+ }
@@ -1,12 +1,12 @@
1
1
  import { is, predicates } from "@sealcode/ts-predicates";
2
2
  import { Context } from "koa";
3
- import type { DropdownOption } from "../controls/dropdown.js";
3
+ import { Dropdown, DropdownOption } from "../controls/dropdown.js";
4
4
  import { FormFieldValidationResponse } from "./field.js";
5
- import { SimpleFormField } from "./simple-form-field.js";
5
+ import { TextBasedSimpleField } from "./simple-form-field.js";
6
6
 
7
7
  export class PickFromListField<
8
8
  Required extends boolean
9
- > extends SimpleFormField<Required> {
9
+ > extends TextBasedSimpleField<Required, Dropdown> {
10
10
  constructor(
11
11
  public required: Required,
12
12
  public generateOptions: (ctx: Context) => Promise<DropdownOption[]>,
@@ -49,4 +49,8 @@ export class PickFromListField<
49
49
  public getEmptyValue(): string {
50
50
  return "";
51
51
  }
52
+
53
+ getControl(): Dropdown {
54
+ return new Dropdown(this);
55
+ }
52
56
  }
@@ -1,6 +1,7 @@
1
+ import { FormControl } from "../controls/form-control.js";
1
2
  import { FormField } from "./field.js";
2
3
 
3
- export class ProxyFormField<T> extends FormField<boolean, T> {
4
+ export class ProxyFormField<T> extends FormField<boolean, T, any> {
4
5
  constructor(
5
6
  required: boolean,
6
7
  public name: string,
@@ -21,4 +22,8 @@ export class ProxyFormField<T> extends FormField<boolean, T> {
21
22
  parsed_value: this.parsed_value,
22
23
  };
23
24
  }
25
+
26
+ getControl(): FormControl {
27
+ throw new Error("This field does not have a default control assigned");
28
+ }
24
29
  }