@sealcode/sealgen 0.18.10 → 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 (378) hide show
  1. package/.eslintrc.cjs +7 -2
  2. package/.xunit +74 -69
  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 -3
  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 -2
  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 -4
  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 -1
  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 -3
  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 -8
  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 -2
  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/mount.d.ts +0 -1
  133. package/@types/page/list.d.sync-conflict-20250918-184318-TFDLWFG.ts +48 -0
  134. package/@types/page/list.d.sync-conflict-20250918-222046-TFDLWFG.ts +48 -0
  135. package/@types/page/list.d.ts +2 -2
  136. package/@types/page/list.sync-conflict-20250918-222048-TFDLWFG.d.ts +48 -0
  137. package/@types/page/mountable-with-fields.d.sync-conflict-20250918-184321-TFDLWFG.ts +42 -0
  138. package/@types/page/mountable-with-fields.d.sync-conflict-20250918-222046-TFDLWFG.ts +42 -0
  139. package/@types/page/mountable-with-fields.d.ts +3 -3
  140. package/@types/page/mountable-with-fields.sync-conflict-20250918-222044-TFDLWFG.d.ts +42 -0
  141. package/@types/page/mountable.d.sync-conflict-20250918-184306-TFDLWFG.ts +10 -0
  142. package/@types/page/mountable.d.ts +0 -1
  143. package/@types/page/page.d.sync-conflict-20250918-184320-TFDLWFG.ts +18 -0
  144. package/@types/page/page.d.ts +0 -1
  145. package/@types/page/props-parser.d.sync-conflict-20250918-184305-TFDLWFG.ts +15 -0
  146. package/@types/page/props-parser.d.ts +0 -1
  147. package/@types/page/stateful-page.d.sync-conflict-20250918-184326-TFDLWFG.ts +62 -0
  148. package/@types/page/stateful-page.d.ts +0 -1
  149. package/@types/templates/shared/shared-crud-form-fields.d.sync-conflict-20250918-184306-TFDLWFG.ts +1 -0
  150. package/@types/templates/shared/shared-crud-form-fields.d.ts +0 -67
  151. package/@types/test_utils/test-on-real-app.d.sync-conflict-20250918-184320-TFDLWFG.ts +26 -0
  152. package/@types/test_utils/test-on-real-app.d.ts +0 -1
  153. package/@types/utils/extract-fields-from-collection.d.sync-conflict-20250918-184312-TFDLWFG.ts +18 -0
  154. package/@types/utils/extract-fields-from-collection.d.ts +5 -1
  155. package/@types/utils/extract-fields-from-collection.sync-conflict-20250918-222045-TFDLWFG.d.ts +18 -0
  156. package/@types/utils/wrap-attributes.d.ts +3 -0
  157. package/README.md +5 -0
  158. package/assets/file-icon.svg +5 -0
  159. package/lib/add-crud.js +80 -89
  160. package/lib/add-list-route.test.js +1 -1
  161. package/lib/add-route.js +0 -7
  162. package/lib/build.js +3 -1
  163. package/lib/cli.js +2 -5
  164. package/lib/controllers/table-add-button.stimulus.js +35 -0
  165. package/lib/forms/controls/array.js +20 -16
  166. package/lib/forms/controls/big-radio-group.js +2 -2
  167. package/lib/forms/controls/checkbox-group.js +7 -7
  168. package/lib/forms/controls/checkboxed-list-input.js +9 -2
  169. package/lib/forms/controls/controls.js +2 -2
  170. package/lib/forms/controls/derived-frame.js +5 -1
  171. package/lib/forms/controls/derived.js +1 -1
  172. package/lib/forms/controls/dropdown.js +4 -1
  173. package/lib/forms/controls/editable-collection-subset.js +2 -2
  174. package/lib/forms/controls/file.js +26 -2
  175. package/lib/forms/controls/file.test.js +2 -2
  176. package/lib/forms/controls/hidden-input.js +4 -1
  177. package/lib/forms/controls/{photo.js → image.js} +6 -7
  178. package/lib/forms/controls/{photo.test.js → image.test.js} +6 -21
  179. package/lib/forms/controls/multiple-files.js +10 -1
  180. package/lib/forms/controls/{multiple-photos.js → multiple-images.js} +3 -3
  181. package/lib/forms/controls/simple-input.js +13 -12
  182. package/lib/forms/controls/single-reference.js +4 -0
  183. package/lib/forms/controls/table.js +66 -24
  184. package/lib/forms/controls/textarea.js +4 -2
  185. package/lib/forms/controls/tickable.js +13 -5
  186. package/lib/forms/fields/boolean.js +14 -0
  187. package/lib/forms/fields/checkboxed-list.js +4 -0
  188. package/lib/forms/fields/collection-field.js +9 -0
  189. package/lib/forms/fields/color.js +10 -0
  190. package/lib/forms/fields/coordinates.js +49 -0
  191. package/lib/forms/fields/date.js +34 -0
  192. package/lib/forms/fields/datetime.js +46 -0
  193. package/lib/forms/fields/deep-reverse-single-reference-list.js +81 -0
  194. package/lib/forms/fields/deep-reverse-single-reference-table.js +122 -0
  195. package/lib/forms/fields/email.js +7 -0
  196. package/lib/forms/fields/enum-multiple-sealious.js +32 -0
  197. package/lib/forms/fields/field.js +32 -4
  198. package/lib/forms/fields/field.test.js +5 -5
  199. package/lib/forms/fields/fields.js +23 -8
  200. package/lib/forms/fields/file.js +33 -9
  201. package/lib/forms/fields/file.test.js +4 -16
  202. package/lib/forms/fields/float.js +10 -0
  203. package/lib/forms/fields/get-field-for-sealious.js +213 -0
  204. package/lib/forms/fields/html.js +14 -0
  205. package/lib/forms/fields/image.js +13 -0
  206. package/lib/forms/fields/int.js +23 -0
  207. package/lib/forms/fields/json.js +31 -0
  208. package/lib/forms/fields/markdown.js +14 -0
  209. package/lib/forms/fields/multiple-files.js +4 -0
  210. package/lib/forms/fields/number.js +6 -0
  211. package/lib/forms/fields/password.js +13 -0
  212. package/lib/forms/fields/pick-from-list-sealious.js +17 -0
  213. package/lib/forms/fields/pick-from-list.js +6 -2
  214. package/lib/forms/fields/proxy-field.js +3 -0
  215. package/lib/forms/fields/regexp.js +14 -0
  216. package/lib/forms/fields/simple-form-field.js +60 -2
  217. package/lib/forms/fields/single-reference.js +44 -0
  218. package/lib/forms/fields/structured-array.js +63 -12
  219. package/lib/forms/fields/table.js +28 -1
  220. package/lib/forms/fields/text.js +17 -0
  221. package/lib/forms/fields/url.js +17 -0
  222. package/lib/forms/form.js +30 -13
  223. package/lib/forms/form.test.js +3 -4
  224. package/lib/forms/multiform.js +4 -2
  225. package/lib/forms/multiform.test.js +3 -3
  226. package/lib/generate-stimulus.js +1 -0
  227. package/lib/index.js +1 -0
  228. package/lib/make-hidden-inputs.js +1 -1
  229. package/lib/mount.js +11 -0
  230. package/lib/notifier.js +0 -1
  231. package/lib/page/list.js +15 -8
  232. package/lib/page/mountable-with-fields.js +14 -6
  233. package/lib/page/mountable-with-fields.test.js +1 -1
  234. package/lib/templates/form.js +8 -9
  235. package/lib/templates/multiform.js +4 -4
  236. package/lib/templates/page.js +0 -2
  237. package/lib/templates/shared/collection-create-form.js +28 -40
  238. package/lib/templates/shared/collection-edit-form.js +40 -77
  239. package/lib/templates/shared/collection-list.js +12 -20
  240. package/lib/templates/shared/shared-crud-form-fields.js +27 -95
  241. package/lib/test_utils/test-on-real-app.js +3 -3
  242. package/lib/utils/extract-fields-from-collection.js +60 -20
  243. package/lib/utils/make-slug.js +1 -1
  244. package/lib/utils/wrap-attributes.js +20 -0
  245. package/package.json +4 -3
  246. package/src/add-crud.ts +86 -97
  247. package/src/add-list-route.test.ts +1 -1
  248. package/src/add-route.ts +0 -7
  249. package/src/build.ts +3 -1
  250. package/src/cli.ts +3 -5
  251. package/src/controllers/table-add-button.stimulus.ts +35 -0
  252. package/src/forms/controls/array.ts +23 -20
  253. package/src/forms/controls/autocomplete.ts +1 -1
  254. package/src/forms/controls/big-radio-group.ts +2 -2
  255. package/src/forms/controls/checkbox-group.ts +9 -9
  256. package/src/forms/controls/checkboxed-list-input.ts +27 -15
  257. package/src/forms/controls/controls.ts +2 -2
  258. package/src/forms/controls/derived-frame.ts +5 -1
  259. package/src/forms/controls/derived.ts +1 -1
  260. package/src/forms/controls/dropdown.ts +5 -2
  261. package/src/forms/controls/editable-collection-subset.ts +2 -2
  262. package/src/forms/controls/file.test.ts +4 -2
  263. package/src/forms/controls/file.ts +31 -5
  264. package/src/forms/controls/form-control.ts +7 -2
  265. package/src/forms/controls/hidden-input.ts +4 -1
  266. package/src/forms/controls/{photo.test.ts → image.test.ts} +5 -22
  267. package/src/forms/controls/{photo.ts → image.ts} +3 -5
  268. package/src/forms/controls/multiple-files.ts +18 -1
  269. package/src/forms/controls/{multiple-photos.ts → multiple-images.ts} +1 -1
  270. package/src/forms/controls/number.ts +1 -1
  271. package/src/forms/controls/simple-input.ts +18 -34
  272. package/src/forms/controls/single-reference.ts +10 -2
  273. package/src/forms/controls/table.ts +90 -31
  274. package/src/forms/controls/textarea.ts +6 -4
  275. package/src/forms/controls/tickable.ts +13 -5
  276. package/src/forms/fields/boolean.ts +23 -1
  277. package/src/forms/fields/checkboxed-list.ts +11 -2
  278. package/src/forms/fields/collection-field.ts +16 -1
  279. package/src/forms/fields/color.ts +9 -0
  280. package/src/forms/fields/coordinates.ts +66 -0
  281. package/src/forms/fields/date.ts +50 -0
  282. package/src/forms/fields/datetime.ts +66 -0
  283. package/src/forms/fields/deep-reverse-single-reference-list.ts +136 -0
  284. package/src/forms/fields/deep-reverse-single-reference-table.ts +213 -0
  285. package/src/forms/fields/email.ts +9 -0
  286. package/src/forms/fields/enum-multiple-sealious.ts +48 -0
  287. package/src/forms/fields/field.test.ts +5 -5
  288. package/src/forms/fields/field.ts +94 -8
  289. package/src/forms/fields/fields.ts +23 -8
  290. package/src/forms/fields/file.test.ts +4 -16
  291. package/src/forms/fields/file.ts +43 -15
  292. package/src/forms/fields/float.ts +9 -0
  293. package/src/forms/fields/get-field-for-sealious.ts +304 -0
  294. package/src/forms/fields/html.ts +15 -0
  295. package/src/forms/fields/image.ts +12 -0
  296. package/src/forms/fields/int.ts +25 -0
  297. package/src/forms/fields/json.ts +48 -0
  298. package/src/forms/fields/markdown.ts +15 -0
  299. package/src/forms/fields/multiple-files.ts +10 -1
  300. package/src/forms/fields/number.ts +8 -1
  301. package/src/forms/fields/password.ts +17 -0
  302. package/src/forms/fields/pick-from-list-sealious.ts +22 -0
  303. package/src/forms/fields/pick-from-list.ts +7 -3
  304. package/src/forms/fields/proxy-field.ts +6 -1
  305. package/src/forms/fields/regexp.ts +27 -1
  306. package/src/forms/fields/simple-form-field.ts +95 -7
  307. package/src/forms/fields/single-reference.ts +62 -0
  308. package/src/forms/fields/structured-array.ts +115 -18
  309. package/src/forms/fields/table.ts +32 -1
  310. package/src/forms/fields/text.ts +18 -0
  311. package/src/forms/fields/url.ts +20 -0
  312. package/src/forms/form-types.ts +2 -0
  313. package/src/forms/form.test.ts +3 -4
  314. package/src/forms/form.ts +37 -16
  315. package/src/forms/forms.css +0 -85
  316. package/src/forms/multiform.test.ts +3 -3
  317. package/src/forms/multiform.ts +2 -0
  318. package/src/generate-stimulus.ts +1 -0
  319. package/src/index.ts +2 -1
  320. package/src/make-hidden-inputs.ts +1 -1
  321. package/src/mount.ts +14 -0
  322. package/src/notifier.ts +0 -1
  323. package/src/page/list.ts +15 -8
  324. package/src/page/mountable-with-fields.test.ts +1 -1
  325. package/src/page/mountable-with-fields.ts +18 -9
  326. package/src/register-external.ts +1 -1
  327. package/src/templates/form.ts +8 -9
  328. package/src/templates/multiform.ts +4 -4
  329. package/src/templates/page.ts +0 -2
  330. package/src/templates/shared/collection-create-form.ts +30 -66
  331. package/src/templates/shared/collection-edit-form.ts +41 -102
  332. package/src/templates/shared/collection-list.ts +12 -20
  333. package/src/templates/shared/item-delete.ts +0 -1
  334. package/src/templates/shared/shared-crud-form-fields.ts +37 -171
  335. package/src/test_utils/test-on-real-app.ts +4 -3
  336. package/src/utils/extract-fields-from-collection.ts +76 -25
  337. package/src/utils/make-slug.ts +1 -1
  338. package/src/utils/wrap-attributes.ts +17 -0
  339. package/lib/add-verbose-crud.js +0 -119
  340. package/lib/crud-field-snippets.js +0 -52
  341. package/lib/find-css-includes.js +0 -3
  342. package/lib/forms/controls/reverse-single-reference.js +0 -1
  343. package/lib/forms/fields/enum-multiple.js +0 -47
  344. package/lib/forms/fields/enum-multiple.test.js +0 -27
  345. package/lib/forms/fields/enum.js +0 -41
  346. package/lib/forms/fields/enum.test.js +0 -21
  347. package/lib/forms/fields/reverse-single-reference.js +0 -17
  348. package/lib/templates/shared/handlers/boolean.js +0 -14
  349. package/lib/templates/shared/handlers/date.js +0 -8
  350. package/lib/templates/shared/handlers/deep-reverse-single-reference.js +0 -209
  351. package/lib/templates/shared/handlers/default.js +0 -49
  352. package/lib/templates/shared/handlers/enum.js +0 -19
  353. package/lib/templates/shared/handlers/file.js +0 -23
  354. package/lib/templates/shared/handlers/image.js +0 -32
  355. package/lib/templates/shared/handlers/int.js +0 -11
  356. package/lib/templates/shared/handlers/jdd.js +0 -10
  357. package/lib/templates/shared/handlers/single-reference.js +0 -12
  358. package/lib/templates/shared/handlers/structured-array.js +0 -33
  359. package/src/add-verbose-crud.ts +0 -138
  360. package/src/crud-field-snippets.ts +0 -57
  361. package/src/find-css-includes.ts +0 -3
  362. package/src/forms/controls/reverse-single-reference.ts +0 -50
  363. package/src/forms/fields/enum-multiple.test.ts +0 -31
  364. package/src/forms/fields/enum-multiple.ts +0 -62
  365. package/src/forms/fields/enum.test.ts +0 -25
  366. package/src/forms/fields/enum.ts +0 -56
  367. package/src/forms/fields/reverse-single-reference.ts +0 -20
  368. package/src/templates/shared/handlers/boolean.ts +0 -18
  369. package/src/templates/shared/handlers/date.ts +0 -12
  370. package/src/templates/shared/handlers/deep-reverse-single-reference.ts +0 -244
  371. package/src/templates/shared/handlers/default.ts +0 -64
  372. package/src/templates/shared/handlers/enum.ts +0 -23
  373. package/src/templates/shared/handlers/file.ts +0 -27
  374. package/src/templates/shared/handlers/image.ts +0 -45
  375. package/src/templates/shared/handlers/int.ts +0 -15
  376. package/src/templates/shared/handlers/jdd.ts +0 -14
  377. package/src/templates/shared/handlers/single-reference.ts +0 -16
  378. package/src/templates/shared/handlers/structured-array.ts +0 -42
@@ -1,5 +1,9 @@
1
1
  import { is, predicates } from "@sealcode/ts-predicates";
2
2
  import { FormField } from "./field.js";
3
+ import {
4
+ Table as TableControl,
5
+ TABLE_COLUMN_FIELD_INDEX_PLACEHOLDER
6
+ } from "../controls/table.js";
3
7
  class Table extends FormField {
4
8
  constructor(columns) {
5
9
  super(false);
@@ -8,6 +12,15 @@ class Table extends FormField {
8
12
  getEmptyValue() {
9
13
  return [];
10
14
  }
15
+ setName(name) {
16
+ super.setName(name);
17
+ for (const [column_name, field] of Object.entries(this.columns)) {
18
+ field.setName(
19
+ `${this.name}[${TABLE_COLUMN_FIELD_INDEX_PLACEHOLDER}][${column_name}]`
20
+ );
21
+ }
22
+ return this;
23
+ }
11
24
  async parse(ctx, raw_value) {
12
25
  if (!is(raw_value, predicates.object)) {
13
26
  return {
@@ -21,7 +34,6 @@ class Table extends FormField {
21
34
  const row_data = raw_value[row_number];
22
35
  const parsed_row = {};
23
36
  if (!is(row_data, predicates.object)) {
24
- console.log("table.ts<fields>:55", this.name);
25
37
  throw new Error(`Expected object, got ${String(row_data)}`);
26
38
  }
27
39
  for (const key in row_data) {
@@ -56,6 +68,21 @@ class Table extends FormField {
56
68
  const ret = { parsed_value: result, parsable: true, error: null };
57
69
  return ret;
58
70
  }
71
+ getControl() {
72
+ return new TableControl(this, {
73
+ label: this.name,
74
+ subfield_controls: Object.fromEntries(
75
+ Object.entries(this.columns).map(([column_name, field]) => [
76
+ column_name,
77
+ field.getControl()
78
+ ])
79
+ ),
80
+ allow_adding: true,
81
+ make_new_row: async () => Object.fromEntries(
82
+ Object.keys(this.columns).map((key) => [key, ""])
83
+ )
84
+ });
85
+ }
59
86
  }
60
87
  export {
61
88
  Table
@@ -0,0 +1,17 @@
1
+ import { TextBasedSimpleField } from "./simple-form-field.js";
2
+ class Text extends TextBasedSimpleField {
3
+ constructor(required) {
4
+ super(required, "text");
5
+ }
6
+ async getSealiousCreateValue(fctx) {
7
+ const { parsed } = await this.getParsedValue(
8
+ fctx.ctx,
9
+ fctx.data.raw_values
10
+ );
11
+ return parsed || this.getEmptyValue();
12
+ }
13
+ }
14
+ export {
15
+ Text
16
+ };
17
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1,17 @@
1
+ import { TextBasedSimpleField } from "./simple-form-field.js";
2
+ class URLField extends TextBasedSimpleField {
3
+ constructor(required) {
4
+ super(required, "text");
5
+ }
6
+ async getSealiousCreateValue(fctx) {
7
+ const { parsed } = await this.getParsedValue(
8
+ fctx.ctx,
9
+ fctx.data.raw_values
10
+ );
11
+ return parsed || null;
12
+ }
13
+ }
14
+ export {
15
+ URLField
16
+ };
17
+ //# sourceMappingURL=url.js.map
package/lib/forms/form.js CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  import {
11
11
  MountableWithFields
12
12
  } from "../page/mountable-with-fields.js";
13
+ import { Errors as SealiousErrors } from "sealious";
13
14
  class Form extends MountableWithFields {
14
15
  constructor() {
15
16
  super(...arguments);
@@ -59,7 +60,7 @@ class Form extends MountableWithFields {
59
60
  makeCloseFormTag() {
60
61
  return `</div>`;
61
62
  }
62
- async onValuesInvalid(ctx, form_messages, _field_errors) {
63
+ async onValuesInvalid(ctx, form_messages, field_errors) {
63
64
  const messages = form_messages.length ? form_messages : [{ type: "error", text: "Some fields are invalid" }];
64
65
  return {
65
66
  action: "stay",
@@ -67,7 +68,8 @@ class Form extends MountableWithFields {
67
68
  ctx,
68
69
  {
69
70
  raw_values: await this.extractRawValues(ctx),
70
- messages
71
+ messages,
72
+ field_messages: field_errors
71
73
  },
72
74
  true
73
75
  ),
@@ -76,9 +78,18 @@ class Form extends MountableWithFields {
76
78
  }
77
79
  async onError(ctx, data, error) {
78
80
  let error_message = "Unknown error has occured";
81
+ let field_messages = {};
79
82
  if (is(error, predicates.object) && hasShape({ message: predicates.string }, error)) {
80
83
  error_message = error.message;
81
84
  }
85
+ if (error instanceof SealiousErrors.FieldsError) {
86
+ field_messages = Object.fromEntries(
87
+ Object.entries(error.field_messages).map(([key, value]) => {
88
+ const message = value?.message || "";
89
+ return [key, { type: "error", message }];
90
+ })
91
+ );
92
+ }
82
93
  const messages = [{ type: "error", text: error_message }];
83
94
  return {
84
95
  action: "stay",
@@ -86,7 +97,8 @@ class Form extends MountableWithFields {
86
97
  ctx,
87
98
  {
88
99
  raw_values: data.raw_values,
89
- messages
100
+ messages,
101
+ field_messages
90
102
  },
91
103
  true
92
104
  )
@@ -102,7 +114,8 @@ class Form extends MountableWithFields {
102
114
  ctx,
103
115
  {
104
116
  raw_values: await this.getInitialValues(ctx),
105
- messages
117
+ messages,
118
+ field_messages: {}
106
119
  },
107
120
  false
108
121
  ),
@@ -119,23 +132,21 @@ class Form extends MountableWithFields {
119
132
  raw_values
120
133
  );
121
134
  if (!valid) {
122
- console.debug("Form values invalid: ", {
123
- form_messages,
124
- field_errors
125
- });
126
135
  return this.onValuesInvalid(ctx, form_messages, field_errors);
127
136
  }
128
137
  try {
129
138
  ctx.status = 303;
130
139
  const result = await this.onSubmit(ctx, {
131
140
  raw_values,
132
- messages: []
141
+ messages: [],
142
+ field_messages: {}
133
143
  });
134
144
  return this.onSuccess(
135
145
  ctx,
136
146
  {
137
147
  raw_values: await this.getRawValuesOnSuccess(ctx),
138
- messages: []
148
+ messages: [],
149
+ field_messages: {}
139
150
  },
140
151
  result
141
152
  );
@@ -151,7 +162,8 @@ class Form extends MountableWithFields {
151
162
  type: "error",
152
163
  text: message
153
164
  }
154
- ]
165
+ ],
166
+ field_messages: {}
155
167
  },
156
168
  e
157
169
  );
@@ -181,13 +193,13 @@ class Form extends MountableWithFields {
181
193
  ctx,
182
194
  {
183
195
  raw_values: await this.extractRawValues(ctx),
184
- messages: []
196
+ messages: [],
197
+ field_messages: {}
185
198
  },
186
199
  false
187
200
  );
188
201
  });
189
202
  router.post(path, async (ctx) => {
190
- console.log("REGULAR FORM HANDLE");
191
203
  const reaction = ctx.override_reaction || await this.handlePost(ctx);
192
204
  if (reaction.action == "stay") {
193
205
  ctx.status = 422;
@@ -201,6 +213,11 @@ class Form extends MountableWithFields {
201
213
  async extractRawValues(ctx) {
202
214
  return Object.keys(ctx.$body).length ? ctx.$body : this.getInitialValues(ctx);
203
215
  }
216
+ static initFieldNames(fields) {
217
+ for (const [field_name, field] of Object.entries(fields)) {
218
+ field.setName(field_name);
219
+ }
220
+ }
204
221
  }
205
222
  export {
206
223
  Form
@@ -7,10 +7,10 @@ import { locator_is_visible } from "../test_utils/locator_is_visible.js";
7
7
  import { getBrowser } from "../utils/browser-creator.js";
8
8
  import { assertThrowsAsync } from "../utils/utils.js";
9
9
  import getPort from "get-port";
10
- import { SimpleFormField } from "./fields/simple-form-field.js";
10
+ import { TextBasedSimpleField } from "./fields/simple-form-field.js";
11
11
  import { expect as PlaywritghtExpect } from "@playwright/test";
12
12
  const fields = {
13
- text: new Fields.SimpleFormField(true)
13
+ text: new Fields.TextBasedSimpleField(true)
14
14
  };
15
15
  function form_factory(canAccessFun) {
16
16
  const result = new class extends Form {
@@ -121,7 +121,6 @@ describe("form test", () => {
121
121
  "/",
122
122
  form_factory(
123
123
  async (ctx) => {
124
- console.log("CAN ACCESS? FALSE");
125
124
  return { canAccess: false, message: "" };
126
125
  }
127
126
  ),
@@ -322,7 +321,7 @@ describe("form test", () => {
322
321
  const app = new Koa();
323
322
  const router = new Router();
324
323
  const fields2 = {
325
- title: new SimpleFormField(true)
324
+ title: new TextBasedSimpleField(true)
326
325
  };
327
326
  mount(
328
327
  router,
@@ -78,7 +78,8 @@ class Multiform extends MountableWithFields {
78
78
  ctx,
79
79
  {
80
80
  raw_values: await this.getSubformRawValues(ctx, sub_form_name),
81
- messages: []
81
+ messages: [],
82
+ field_messages: {}
82
83
  },
83
84
  show_field_errors
84
85
  );
@@ -97,7 +98,8 @@ class Multiform extends MountableWithFields {
97
98
  async render(ctx, messages, prerenderedForms = {}, show_field_errors) {
98
99
  return tempstream`${this.renderMessages(ctx, {
99
100
  raw_values: {},
100
- messages
101
+ messages,
102
+ field_messages: {}
101
103
  })}
102
104
  <div class="forms">
103
105
  <form
@@ -8,7 +8,7 @@ import { Multiform } from "./multiform.js";
8
8
  import { assertThrowsAsync } from "../utils/utils.js";
9
9
  import { form_factory } from "./form.test.js";
10
10
  import { getBrowser } from "../utils/browser-creator.js";
11
- import { SimpleFormField } from "./fields/simple-form-field.js";
11
+ import { TextBasedSimpleField } from "./fields/simple-form-field.js";
12
12
  import { Form } from "./form.js";
13
13
  import { FormHeader } from "./controls/form-header.js";
14
14
  import { SimpleInput } from "./controls/simple-input.js";
@@ -17,7 +17,7 @@ import getPort from "get-port";
17
17
  const port = await getPort();
18
18
  console.log(`Using port ${port} form multiform.test.ts`);
19
19
  const fields1 = {
20
- email: new SimpleFormField(true)
20
+ email: new TextBasedSimpleField(true)
21
21
  };
22
22
  const form1 = new class extends Form {
23
23
  constructor() {
@@ -31,7 +31,7 @@ const form1 = new class extends Form {
31
31
  }
32
32
  }();
33
33
  const fields2 = {
34
- name: new SimpleFormField(true)
34
+ name: new TextBasedSimpleField(true)
35
35
  };
36
36
  const form2 = new class extends Form {
37
37
  constructor() {
@@ -12,6 +12,7 @@ async function generateStimulusControllers(controller_dirs) {
12
12
  target_locreq.resolve("src/"),
13
13
  ...controller_dirs
14
14
  ];
15
+ console.log("Looking for controllers in ", stimulus_search_dirs);
15
16
  const controller_names = (await Promise.all(stimulus_search_dirs.map((dir) => recursive(dir)))).flat().filter((c) => c.endsWith(".stimulus.ts")).sort();
16
17
  const controller_data = controller_names.map(
17
18
  (p) => "./" + path.relative(target_locreq.resolve(dirname(output_file)), p).replace(/\.[tj]sx?$/, ".js")
package/lib/index.js CHANGED
@@ -16,6 +16,7 @@ export * from "./forms/multiform.js";
16
16
  import * as Components from "./components/components.js";
17
17
  export * from "./mount.js";
18
18
  export * from "./page/default-list-filters.js";
19
+ export * from "./forms/fields/get-field-for-sealious.js";
19
20
  export {
20
21
  Components,
21
22
  Controls,
@@ -5,7 +5,7 @@ function makeHiddenInputs(ctx, fields, values, fields_to_skip) {
5
5
  ([key, field]) => tempstream`<input
6
6
  type="hidden"
7
7
  name="${key}"
8
- value="${field.getValue(ctx, values).then((r) => attribute(JSON.stringify(r.raw) || ""))}"
8
+ value="${field.getParsedValue(ctx, values).then((r) => attribute(JSON.stringify(r.raw) || ""))}"
9
9
  />`
10
10
  )}`;
11
11
  }
package/lib/mount.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { FileManager } from "@sealcode/file-manager";
2
2
  import { Middlewares as SealiousMiddlewares } from "sealious";
3
+ import { KoaResponsiveImageRouter } from "koa-responsive-image-router";
3
4
  async function handleHtmlPromise(ctx, next) {
4
5
  await next();
5
6
  if (ctx.body instanceof Promise) {
@@ -9,9 +10,19 @@ async function handleHtmlPromise(ctx, next) {
9
10
  }
10
11
  function mount(router, url, mountable, use_dummy_app = false, file_manager = use_dummy_app ? new FileManager("/tmp", "/uploaded_files") : void 0) {
11
12
  const raw_url = typeof url === "string" ? url : url.rawURL;
13
+ const imageRouter = new KoaResponsiveImageRouter({
14
+ staticPath: "/tmp",
15
+ thumbnailSize: 10,
16
+ cacheManagerResolutionThreshold: 10,
17
+ imageStoragePath: "/tmp",
18
+ smartCropStoragePath: "/tmp"
19
+ });
20
+ const fileManager = new FileManager("/tmp", "/uploaded_files");
12
21
  const args = use_dummy_app ? [
13
22
  async (ctx, next) => {
14
23
  ctx.$app = {
24
+ fileManager,
25
+ imageRouter,
15
26
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
16
27
  Logger: new Proxy(
17
28
  {},
package/lib/notifier.js CHANGED
@@ -34,7 +34,6 @@ async function wait_for_app_to_be_stable(app_port, n = 3) {
34
34
  console.log("Waiting for app to be stable....");
35
35
  let counter = 0;
36
36
  while (true) {
37
- console.debug("notifier.ts:53");
38
37
  const { status } = await get_status(app_port).catch(() => ({
39
38
  status: "down"
40
39
  }));
package/lib/page/list.js CHANGED
@@ -4,13 +4,13 @@ import { naturalNumbers, UrlWithNewParams } from "../utils/utils.js";
4
4
  import { makeHiddenInputs } from "../make-hidden-inputs.js";
5
5
  import qs from "qs";
6
6
  import { NumberField } from "../forms/fields/number.js";
7
- import { SimpleFormField } from "../forms/fields/simple-form-field.js";
7
+ import { TextBasedSimpleField } from "../forms/fields/simple-form-field.js";
8
8
  const BasePagePropsShape = {};
9
9
  const DEFAULT_ITEMS_PER_PAGE = 12;
10
10
  const BaseListPageFields = {
11
11
  page: new NumberField(false, 1),
12
12
  itemsPerPage: new NumberField(false, DEFAULT_ITEMS_PER_PAGE),
13
- sort: new SimpleFormField(false)
13
+ sort: new TextBasedSimpleField(false)
14
14
  };
15
15
  const SORT_SEPARATOR = ":";
16
16
  function decodeSort(s) {
@@ -40,8 +40,8 @@ class ListPage extends Page {
40
40
  }
41
41
  init() {
42
42
  super.init();
43
- for (const [fieldname, field] of Object.entries(this.filterFields)) {
44
- void field.init(fieldname);
43
+ for (const [, field] of Object.entries(this.filterFields)) {
44
+ void field.init();
45
45
  }
46
46
  }
47
47
  renderListContainer(_, content) {
@@ -49,11 +49,14 @@ class ListPage extends Page {
49
49
  }
50
50
  async getPaginationConfig(ctx) {
51
51
  const values = await this.extractRawValues(ctx);
52
- let { parsed: page } = await this.fields.page.getValue(ctx, values);
52
+ let { parsed: page } = await this.fields.page.getParsedValue(
53
+ ctx,
54
+ values
55
+ );
53
56
  if (!page) {
54
57
  page = 1;
55
58
  }
56
- const { parsed: itemsPerPage } = await this.fields.itemsPerPage.getValue(ctx, values);
59
+ const { parsed: itemsPerPage } = await this.fields.itemsPerPage.getParsedValue(ctx, values);
57
60
  return { page, itemsPerPage };
58
61
  }
59
62
  async renderItems(ctx, values, items) {
@@ -127,7 +130,7 @@ class ListPage extends Page {
127
130
  const filter = {};
128
131
  const raw_values = await this.extractRawValues(ctx);
129
132
  for (const [fieldname, field] of Object.entries(this.filterFields)) {
130
- const { parsed } = await field.getValue(ctx, raw_values);
133
+ const { parsed } = await field.getParsedValue(ctx, raw_values);
131
134
  filter[fieldname] = field.mapToFilter(parsed);
132
135
  }
133
136
  return filter;
@@ -163,7 +166,11 @@ class ListPage extends Page {
163
166
  return control.render(
164
167
  this.makeFormControlContext(
165
168
  ctx,
166
- { raw_values: values, messages: [] },
169
+ {
170
+ raw_values: values,
171
+ messages: [],
172
+ field_messages: {}
173
+ },
167
174
  false
168
175
  )
169
176
  );
@@ -13,14 +13,15 @@ class MountableWithFields extends Mountable {
13
13
  this.fields = {};
14
14
  }
15
15
  init() {
16
- for (const [name, field] of Object.entries(this.fields)) {
17
- void field.init(name);
16
+ for (const [field_name, field] of Object.entries(this.fields)) {
17
+ void field.init();
18
+ field.setName(field_name);
18
19
  }
19
20
  }
20
21
  makeFormControlContext(ctx, data, validate, field_name_prefix = this.field_names_prefix, form_id = this.form_id) {
21
22
  return new FormControlContext(
22
23
  ctx,
23
- data.raw_values,
24
+ data,
24
25
  data.messages,
25
26
  field_name_prefix,
26
27
  form_id,
@@ -44,10 +45,13 @@ class MountableWithFields extends Mountable {
44
45
  await Promise.all(
45
46
  Object.keys(this.fields).map(async (key) => {
46
47
  const field = this.fields[key];
47
- const { valid: fieldvalid, message: fieldmessage } = await field.getValue(ctx, values, true);
48
+ const { valid: fieldvalid, message: fieldmessage } = await field.getParsedValue(ctx, values, true);
48
49
  if (!fieldvalid) {
49
50
  valid = false;
50
- field_errors[field.name] = fieldmessage;
51
+ field_errors[field.name] = {
52
+ type: "error",
53
+ message: fieldmessage
54
+ };
51
55
  }
52
56
  })
53
57
  );
@@ -81,7 +85,11 @@ class MountableWithFields extends Mountable {
81
85
  const result = {};
82
86
  const promises = Object.entries(this.fields).map(
83
87
  async ([key, field]) => {
84
- const { parsed } = await field.getValue(ctx, raw_values, false);
88
+ const { parsed } = await field.getParsedValue(
89
+ ctx,
90
+ raw_values,
91
+ false
92
+ );
85
93
  result[key] = parsed;
86
94
  }
87
95
  );
@@ -17,7 +17,7 @@ describe("mountable-with-fields", () => {
17
17
  const data = await this.getParsedValues(ctx);
18
18
  data.not_required?.trim();
19
19
  data.required.trim();
20
- const { parsed: data2 } = await this.fields.not_required.getValue(
20
+ const { parsed: data2 } = await this.fields.not_required.getParsedValue(
21
21
  ctx,
22
22
  form_values.raw_values
23
23
  );
@@ -1,12 +1,10 @@
1
- import Prettier from "prettier";
2
- import { curryImportPath } from "../utils/import-path.js";
3
- import { getPrettierConfig } from "../utils/prettier.js";
1
+ import { formatWithPrettier } from "../utils/prettier.js";
4
2
  const defaults = {
5
3
  postimport: `
6
4
  import { Fields } from "@sealcode/sealgen";
7
5
  import type {FormDataValue} from "@sealcode/sealgen";`,
8
6
  fields: `
9
- password: new Fields.SimpleFormField(true),`,
7
+ password: new Fields.Password(true),`,
10
8
  controls: `
11
9
  new Controls.SimpleInput(fields.password, {
12
10
  label: "Password:",
@@ -17,8 +15,8 @@ const defaults = {
17
15
  data: Record<string, FormDataValue>
18
16
  ): Promise<{ valid: boolean; error: string }> {
19
17
  // just a silly example, please remove this with better logic
20
- const { parsed: email } = await this.fields.email.getValue(ctx, data);
21
- const { parsed: password } = await this.fields.password.getValue(ctx, data);
18
+ const { parsed: email } = await this.fields.email.getParsedValue(ctx, data);
19
+ const { parsed: password } = await this.fields.password.getParsedValue(ctx, data);
22
20
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
23
21
  if ((password || "").length > ((email as string) || "").length) {
24
22
  return { valid: false, error: "Password cannot be longer than email" };
@@ -43,11 +41,10 @@ const defaults = {
43
41
  };
44
42
  async function formTemplate(action_name, newfilefullpath, _params = defaults) {
45
43
  const params = { ...defaults, ..._params };
46
- const rel = curryImportPath(newfilefullpath);
47
44
  const content = `import type { Context } from "koa";
48
45
  import type { FormData } from "@sealcode/sealgen";
49
46
  import { Form, Controls, fieldsToShape } from "@sealcode/sealgen";
50
- import html from "${rel("src/back/html.js")}";
47
+ import html from "src/back/html.js";
51
48
 
52
49
  ${params.postimport}
53
50
 
@@ -57,6 +54,8 @@ const fields = {
57
54
  ${params.fields}
58
55
  };
59
56
 
57
+ Form.initFieldNames(fields);
58
+
60
59
  export const ${action_name}Shape = fieldsToShape(fields);
61
60
 
62
61
  export default new (class ${action_name}Form extends Form<typeof fields, void> {
@@ -78,7 +77,7 @@ export default new (class ${action_name}Form extends Form<typeof fields, void> {
78
77
  ${params.render}
79
78
  })();
80
79
  `;
81
- return Prettier.format(content, await getPrettierConfig());
80
+ return formatWithPrettier(content);
82
81
  }
83
82
  export {
84
83
  formTemplate
@@ -9,8 +9,8 @@ import { FlatTemplatable } from "tempstream";
9
9
  export const actionName = "${action_name}";
10
10
 
11
11
  const fields1 = {
12
- email: new Fields.SimpleFormField(true),
13
- password: new Fields.SimpleFormField(true),
12
+ email: new Fields.TextBasedSimpleField(true),
13
+ password: new Fields.TextBasedSimpleField(true),
14
14
  };
15
15
 
16
16
  const form1 = new (class extends Form<typeof fields1, unknown> {
@@ -26,8 +26,8 @@ const form1 = new (class extends Form<typeof fields1, unknown> {
26
26
  })();
27
27
 
28
28
  const fields2 = {
29
- name: new Fields.SimpleFormField(true),
30
- surname: new Fields.SimpleFormField(true),
29
+ name: new Fields.TextBasedSimpleField(true),
30
+ surname: new Fields.TextBasedSimpleField(true),
31
31
  };
32
32
 
33
33
  const form2 = new (class extends Form<typeof fields2, unknown> {
@@ -1,6 +1,4 @@
1
- import { curryImportPath } from "../utils/import-path.js";
2
1
  async function pageTemplate(action_name, newfilefullpath) {
3
- const rel = curryImportPath(newfilefullpath);
4
2
  return `import type { Context } from "koa";
5
3
  import { TempstreamJSX } from "tempstream";
6
4
  import { Page } from "@sealcode/sealgen";
@@ -1,70 +1,58 @@
1
1
  import { toKebabCase, toPascalCase } from "js-convert-case";
2
2
  import { formTemplate } from "../form.js";
3
- import { curryImportPath } from "../../utils/import-path.js";
4
3
  import extract_fields_from_collection from "../../utils/extract-fields-from-collection.js";
5
- import { getFieldHandler } from "./shared-crud-form-fields.js";
4
+ import { wrapAttribute } from "../../utils/wrap-attributes.js";
6
5
  async function createItemFormTemplate(create_action_name, newfilefullpath, collection_name, list_action) {
7
6
  const collection_fields = await extract_fields_from_collection(
8
7
  collection_name
9
8
  );
10
- const importPath = curryImportPath(newfilefullpath);
11
- const field_handler_results = await Promise.all(
12
- collection_fields.map(
13
- (field) => getFieldHandler(collection_name, field, importPath)
14
- )
15
- );
16
- const post_create_actions = field_handler_results.map(({ post_create }) => post_create).filter((e) => e != "");
9
+ const formFieldsVar = `${toPascalCase(collection_name)}FormFields`;
17
10
  return formTemplate(create_action_name, newfilefullpath, {
18
11
  success_message: "Created!",
19
- postimport: `import {${toPascalCase(
20
- collection_name
21
- )}FormFields, ${toPascalCase(
12
+ postimport: `import {${formFieldsVar}, get${toPascalCase(
22
13
  collection_name
23
14
  )}FormControls }from "./shared.js";
24
15
 
25
- import { ${toPascalCase(collection_name)} } from "${importPath(
26
- "src/back/collections/collections.js"
27
- )}";
28
-
29
- import { ${list_action}URL } from "${importPath("src/back/routes/urls.js")}";
16
+ import { ${toPascalCase(
17
+ collection_name
18
+ )} } from "src/back/collections/collections.js";
30
19
 
31
- import {tempstream} from "tempstream";
20
+ import { ${list_action}URL } from "src/back/routes/urls.js";
21
+ import {tempstream} from "tempstream";
32
22
  `,
33
23
  fields: `...${toPascalCase(collection_name)}FormFields`,
34
24
  controls: `
35
25
  new Controls.FormHeader("Create ${toPascalCase(
36
26
  collection_name
37
27
  )}"),
38
- ...${toPascalCase(collection_name)}FormControls`,
28
+ ...get${toPascalCase(collection_name)}FormControls()`,
39
29
  can_access: `canAccess = async (ctx: Context) => {
40
30
  const policy = ${toPascalCase(collection_name)}.getPolicy("create");
41
31
  const response = await policy.check(ctx.$context);
42
32
  return { canAccess: response?.allowed || false, message: response?.reason || "" };
43
33
  };`,
44
- get_initial_values: field_handler_results.filter((r) => !r.hide_initial_value_create).map(({ initial_value_create }) => initial_value_create).filter((e) => e != "").length ? `getInitialValues(ctx: Context){
45
- return {
46
- ${field_handler_results.filter((r) => !r.hide_initial_value_create).map(
47
- ({ initial_value_create }) => initial_value_create
48
- ).join(",\n")}
49
- }
50
- }` : ``,
34
+ get_initial_values: "",
51
35
  onsubmit: `
52
- async onSubmit(ctx: Context) {
53
- const data = await this.getParsedValues(ctx);
54
- if (!data) {
55
- throw new Error("Error when parsing the form values");
56
- }
36
+ async onSubmit(ctx: Context, formData: FormData) {
37
+ const fctx = this.makeFormControlContext(ctx, formData, true);
57
38
 
58
- ${field_handler_results.map(({ pre_create }) => pre_create).filter((e) => e !== "").join("\n")}
59
-
60
- ${post_create_actions.length ? `const created = ` : ""} await ctx.$app.collections["${toKebabCase(collection_name)}"].create(
39
+ const created = await ctx.$app.collections["${toKebabCase(
40
+ collection_name
41
+ )}"].createExtraSafe(
61
42
  ctx.$context,
62
- {
63
- ${field_handler_results.filter((result) => !result.hide_sealious_value).map((result) => result.sealious_value(result)).filter((e) => e != "").join(",\n")}
64
- }
65
- );
66
- ${post_create_actions.length ? `/* ==== POST CREATE ACTIONS ==== */` : ""}
67
- ${post_create_actions.join("\n")}
43
+ {
44
+ ${collection_fields.map(
45
+ (field_info) => field_info.form_field.generateCreateValueGetter(field_info, {
46
+ form_field_types: formFieldsVar,
47
+ sealious_field: `fields${wrapAttribute(field_info.name)}`,
48
+ form_fields: "fields"
49
+ })
50
+ ).join(",\n")}
51
+ });
52
+
53
+ for(const field of Object.values(${formFieldsVar})){
54
+ await field.postSealiousCreate(ctx, created, formData)
55
+ }
68
56
  }
69
57
  `,
70
58
  render: ` async render(ctx: Context, data: FormData, show_field_errors: boolean) {