@sealcode/sealgen 0.18.10 → 0.19.2

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 (444) hide show
  1. package/.xunit +74 -69
  2. package/@types/add-crud.d.sync-conflict-20250918-184311-TFDLWFG.ts +1 -0
  3. package/@types/builders/colors-builder.d.sync-conflict-20250918-184323-TFDLWFG.ts +10 -0
  4. package/@types/builders/colors-builder.d.ts +1 -1
  5. package/@types/builders/fonts-builder.d.sync-conflict-20250918-184322-TFDLWFG.ts +7 -0
  6. package/@types/builders/fonts-builder.d.ts +1 -1
  7. package/@types/controllers/table-add-button.d.ts +6 -0
  8. package/@types/controllers/table-add-button.stimulus.d.ts +6 -0
  9. package/@types/crud-field-snippets.d.sync-conflict-20250918-184323-TFDLWFG.ts +1 -0
  10. package/@types/crud-field-snippets.d.ts +1 -3
  11. package/@types/forms/controls/array.d.sync-conflict-20250918-184306-TFDLWFG.ts +33 -0
  12. package/@types/forms/controls/array.d.ts +1 -3
  13. package/@types/forms/controls/array.sync-conflict-20250918-222045-TFDLWFG.d.ts +33 -0
  14. package/@types/forms/controls/autocomplete.d.sync-conflict-20250918-222042-TFDLWFG.ts +22 -0
  15. package/@types/forms/controls/autocomplete.d.ts +1 -1
  16. package/@types/forms/controls/checkbox-group.d.sync-conflict-20250918-184319-TFDLWFG.ts +21 -0
  17. package/@types/forms/controls/checkbox-group.d.ts +3 -3
  18. package/@types/forms/controls/checkboxed-list-input.d.sync-conflict-20250918-184323-TFDLWFG.ts +21 -0
  19. package/@types/forms/controls/checkboxed-list-input.d.ts +3 -3
  20. package/@types/forms/controls/controls.d.ts +2 -2
  21. package/@types/forms/controls/derived-frame.d.sync-conflict-20250918-184314-TFDLWFG.ts +19 -0
  22. package/@types/forms/controls/derived-frame.d.ts +0 -2
  23. package/@types/forms/controls/dropdown.d.sync-conflict-20250918-222044-TFDLWFG.ts +30 -0
  24. package/@types/forms/controls/dropdown.d.ts +1 -1
  25. package/@types/forms/controls/file.d.sync-conflict-20250918-222045-TFDLWFG.ts +13 -0
  26. package/@types/forms/controls/file.d.ts +1 -2
  27. package/@types/forms/controls/form-control.d.sync-conflict-20250918-184322-TFDLWFG.ts +19 -0
  28. package/@types/forms/controls/form-control.d.sync-conflict-20250918-222046-TFDLWFG.ts +19 -0
  29. package/@types/forms/controls/form-control.d.ts +7 -4
  30. package/@types/forms/controls/image.d.ts +19 -0
  31. package/@types/forms/controls/image.test.d.ts +1 -0
  32. package/@types/forms/controls/multiple-files.d.sync-conflict-20250918-184318-TFDLWFG.ts +42 -0
  33. package/@types/forms/controls/multiple-files.d.ts +3 -1
  34. package/@types/forms/controls/multiple-images.d.ts +19 -0
  35. package/@types/forms/controls/number.d.sync-conflict-20250918-222046-TFDLWFG.ts +13 -0
  36. package/@types/forms/controls/number.d.ts +1 -1
  37. package/@types/forms/controls/photo.d.sync-conflict-20250918-184321-TFDLWFG.ts +19 -0
  38. package/@types/forms/controls/photo.d.ts +3 -5
  39. package/@types/forms/controls/simple-input.d.sync-conflict-20250918-184310-TFDLWFG.ts +33 -0
  40. package/@types/forms/controls/simple-input.d.sync-conflict-20250918-222042-TFDLWFG.ts +33 -0
  41. package/@types/forms/controls/simple-input.d.ts +5 -4
  42. package/@types/forms/controls/simple-input.sync-conflict-20250918-222045-TFDLWFG.d.ts +33 -0
  43. package/@types/forms/controls/single-reference.d.ts +3 -2
  44. package/@types/forms/controls/table.d.sync-conflict-20250918-184302-TFDLWFG.ts +39 -0
  45. package/@types/forms/controls/table.d.ts +8 -3
  46. package/@types/forms/controls/table.sync-conflict-20250918-222042-TFDLWFG.d.ts +39 -0
  47. package/@types/forms/controls/textarea.d.sync-conflict-20250918-222045-TFDLWFG.ts +25 -0
  48. package/@types/forms/controls/textarea.d.ts +3 -3
  49. package/@types/forms/fields/boolean.d.sync-conflict-20250918-184325-TFDLWFG.ts +22 -0
  50. package/@types/forms/fields/boolean.d.ts +6 -1
  51. package/@types/forms/fields/boolean.sync-conflict-20250918-222042-TFDLWFG.d.ts +22 -0
  52. package/@types/forms/fields/checkboxed-list.d.sync-conflict-20250918-184325-TFDLWFG.ts +23 -0
  53. package/@types/forms/fields/checkboxed-list.d.ts +3 -1
  54. package/@types/forms/fields/collection-field.d.sync-conflict-20250918-184319-TFDLWFG.ts +22 -0
  55. package/@types/forms/fields/collection-field.d.sync-conflict-20250918-222047-TFDLWFG.ts +22 -0
  56. package/@types/forms/fields/collection-field.d.ts +8 -1
  57. package/@types/forms/fields/color.d.ts +4 -0
  58. package/@types/forms/fields/coordinates.d.sync-conflict-20250918-222044-TFDLWFG.ts +14 -0
  59. package/@types/forms/fields/coordinates.d.ts +14 -0
  60. package/@types/forms/fields/date.d.ts +13 -0
  61. package/@types/forms/fields/datetime.d.sync-conflict-20250918-222050-TFDLWFG.ts +4 -0
  62. package/@types/forms/fields/datetime.d.ts +14 -0
  63. package/@types/forms/fields/deep-reverse-single-reference-list.d.ts +20 -0
  64. package/@types/forms/fields/deep-reverse-single-reference-table.d.ts +16 -0
  65. package/@types/forms/fields/email.d.sync-conflict-20250918-184303-TFDLWFG.ts +8 -0
  66. package/@types/forms/fields/email.d.ts +3 -0
  67. package/@types/forms/fields/enum-multiple-sealious.d.ts +16 -0
  68. package/@types/forms/fields/enum-multiple-sealious.sync-conflict-20250918-222047-TFDLWFG.d.ts +16 -0
  69. package/@types/forms/fields/field.d.sync-conflict-20250918-184306-TFDLWFG.ts +70 -0
  70. package/@types/forms/fields/field.d.ts +37 -5
  71. package/@types/forms/fields/fields.d.sync-conflict-20250918-184314-TFDLWFG.ts +29 -0
  72. package/@types/forms/fields/fields.d.ts +23 -8
  73. package/@types/forms/fields/file.d.sync-conflict-20250918-184310-TFDLWFG.ts +23 -0
  74. package/@types/forms/fields/file.d.sync-conflict-20250918-222046-TFDLWFG.ts +23 -0
  75. package/@types/forms/fields/file.d.ts +11 -5
  76. package/@types/forms/fields/file.sync-conflict-20250918-222049-TFDLWFG.d.ts +23 -0
  77. package/@types/forms/fields/float.d.ts +4 -0
  78. package/@types/forms/fields/get-field-for-sealious.d.sync-conflict-20250918-222046-TFDLWFG.ts +29 -0
  79. package/@types/forms/fields/get-field-for-sealious.d.ts +31 -0
  80. package/@types/forms/fields/get-field-for-sealious.sync-conflict-20250918-222042-TFDLWFG.d.ts +29 -0
  81. package/@types/forms/fields/html.d.ts +6 -0
  82. package/@types/forms/fields/image.d.sync-conflict-20250918-222042-TFDLWFG.ts +5 -0
  83. package/@types/forms/fields/image.d.ts +5 -0
  84. package/@types/forms/fields/int.d.ts +6 -0
  85. package/@types/forms/fields/json.d.ts +13 -0
  86. package/@types/forms/fields/markdown.d.ts +6 -0
  87. package/@types/forms/fields/multiple-files.d.sync-conflict-20250918-184304-TFDLWFG.ts +16 -0
  88. package/@types/forms/fields/multiple-files.d.ts +3 -1
  89. package/@types/forms/fields/number.d.sync-conflict-20250918-184317-TFDLWFG.ts +25 -0
  90. package/@types/forms/fields/number.d.sync-conflict-20250918-222047-TFDLWFG.ts +25 -0
  91. package/@types/forms/fields/number.d.ts +3 -1
  92. package/@types/forms/fields/password.d.ts +5 -0
  93. package/@types/forms/fields/pick-from-list-sealious.d.ts +11 -0
  94. package/@types/forms/fields/pick-from-list.d.sync-conflict-20250918-184322-TFDLWFG.ts +15 -0
  95. package/@types/forms/fields/pick-from-list.d.ts +4 -3
  96. package/@types/forms/fields/proxy-field.d.sync-conflict-20250918-184307-TFDLWFG.ts +15 -0
  97. package/@types/forms/fields/proxy-field.d.ts +3 -1
  98. package/@types/forms/fields/regexp.d.sync-conflict-20250918-184305-TFDLWFG.ts +21 -0
  99. package/@types/forms/fields/regexp.d.sync-conflict-20250918-222045-TFDLWFG.ts +21 -0
  100. package/@types/forms/fields/regexp.d.ts +6 -1
  101. package/@types/forms/fields/regexp.sync-conflict-20250918-222047-TFDLWFG.d.ts +21 -0
  102. package/@types/forms/fields/simple-form-field.d.sync-conflict-20250918-184309-TFDLWFG.ts +29 -0
  103. package/@types/forms/fields/simple-form-field.d.sync-conflict-20250918-222044-TFDLWFG.ts +29 -0
  104. package/@types/forms/fields/simple-form-field.d.ts +23 -3
  105. package/@types/forms/fields/simple-form-field.sync-conflict-20250918-222049-TFDLWFG.d.ts +29 -0
  106. package/@types/forms/fields/single-reference.d.ts +19 -0
  107. package/@types/forms/fields/single-reference.sync-conflict-20250918-222043-TFDLWFG.d.ts +10 -0
  108. package/@types/forms/fields/structured-array.d.sync-conflict-20250918-184302-TFDLWFG.ts +27 -0
  109. package/@types/forms/fields/structured-array.d.sync-conflict-20250918-222049-TFDLWFG.ts +27 -0
  110. package/@types/forms/fields/structured-array.d.ts +19 -10
  111. package/@types/forms/fields/structured-array.sync-conflict-20250918-222047-TFDLWFG.d.ts +27 -0
  112. package/@types/forms/fields/table.d.sync-conflict-20250918-184303-TFDLWFG.ts +16 -0
  113. package/@types/forms/fields/table.d.ts +3 -0
  114. package/@types/forms/fields/text.d.ts +6 -0
  115. package/@types/forms/fields/url.d.ts +6 -0
  116. package/@types/forms/form-types.d.sync-conflict-20250918-222045-TFDLWFG.ts +26 -0
  117. package/@types/forms/form-types.d.ts +2 -0
  118. package/@types/forms/form.d.sync-conflict-20250918-184315-TFDLWFG.ts +32 -0
  119. package/@types/forms/form.d.sync-conflict-20250918-222049-TFDLWFG.ts +32 -0
  120. package/@types/forms/form.d.ts +10 -8
  121. package/@types/forms/form.sync-conflict-20250918-222049-TFDLWFG.d.ts +33 -0
  122. package/@types/forms/form.test.d.sync-conflict-20250918-184318-TFDLWFG.ts +6 -0
  123. package/@types/forms/form.test.d.sync-conflict-20250918-222047-TFDLWFG.ts +6 -0
  124. package/@types/forms/form.test.d.ts +2 -2
  125. package/@types/forms/multiform.d.sync-conflict-20250918-184308-TFDLWFG.ts +23 -0
  126. package/@types/forms/multiform.d.ts +1 -2
  127. package/@types/forms/multiform.sync-conflict-20250918-222044-TFDLWFG.d.ts +23 -0
  128. package/@types/index.d.sync-conflict-20250918-184316-TFDLWFG.ts +46 -0
  129. package/@types/index.d.ts +2 -2
  130. package/@types/mount.d.sync-conflict-20250918-184320-TFDLWFG.ts +6 -0
  131. package/@types/mount.d.ts +0 -1
  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/mountable.d.ts +0 -1
  142. package/@types/page/page.d.sync-conflict-20250918-184320-TFDLWFG.ts +18 -0
  143. package/@types/page/page.d.ts +0 -1
  144. package/@types/page/props-parser.d.sync-conflict-20250918-184305-TFDLWFG.ts +15 -0
  145. package/@types/page/props-parser.d.ts +0 -1
  146. package/@types/page/stateful-page.d.sync-conflict-20250918-184326-TFDLWFG.ts +62 -0
  147. package/@types/page/stateful-page.d.ts +0 -1
  148. package/@types/register-external.d.ts +2 -2
  149. package/@types/templates/form.d.ts +1 -3
  150. package/@types/templates/jdd-component.d.ts +1 -1
  151. package/@types/templates/page.d.ts +1 -1
  152. package/@types/templates/shared/shared-crud-form-fields.d.sync-conflict-20250918-184306-TFDLWFG.ts +1 -0
  153. package/@types/templates/shared/shared-crud-form-fields.d.ts +1 -68
  154. package/@types/templates/templates.d.ts +1 -21
  155. package/@types/test_utils/test-on-real-app.d.sync-conflict-20250918-184320-TFDLWFG.ts +26 -0
  156. package/@types/test_utils/test-on-real-app.d.ts +0 -1
  157. package/@types/utils/extract-fields-from-collection.d.sync-conflict-20250918-184312-TFDLWFG.ts +18 -0
  158. package/@types/utils/extract-fields-from-collection.d.ts +5 -1
  159. package/@types/utils/extract-fields-from-collection.sync-conflict-20250918-222045-TFDLWFG.d.ts +18 -0
  160. package/@types/utils/wrap-attributes.d.ts +3 -0
  161. package/README.md +5 -0
  162. package/assets/file-icon.svg +5 -0
  163. package/eslint.config.mjs +56 -0
  164. package/lib/add-crud.js +77 -89
  165. package/lib/add-jdd-component.js +3 -3
  166. package/lib/add-list-route.test.js +1 -1
  167. package/lib/add-route.js +2 -9
  168. package/lib/build.js +6 -4
  169. package/lib/builders/backend-ts-builder.js +0 -1
  170. package/lib/builders/colors-builder.js +11 -8
  171. package/lib/builders/fonts-builder.js +0 -1
  172. package/lib/builders/frontend-ts-builder.js +0 -1
  173. package/lib/cli.js +4 -7
  174. package/lib/components/tabs.js +36 -36
  175. package/lib/controllers/table-add-button.stimulus.js +35 -0
  176. package/lib/esbuild-plugins/rewrite-asset-imports.js +7 -10
  177. package/lib/forms/controls/array.js +25 -22
  178. package/lib/forms/controls/big-radio-group.js +2 -2
  179. package/lib/forms/controls/checkbox-group.js +7 -7
  180. package/lib/forms/controls/checkboxed-list-input.js +7 -1
  181. package/lib/forms/controls/checkboxed-list-input.test.js +6 -6
  182. package/lib/forms/controls/controls.js +2 -2
  183. package/lib/forms/controls/derived-frame.js +8 -4
  184. package/lib/forms/controls/derived.js +1 -1
  185. package/lib/forms/controls/dropdown.js +5 -3
  186. package/lib/forms/controls/editable-collection-subset.js +2 -2
  187. package/lib/forms/controls/file.js +26 -2
  188. package/lib/forms/controls/file.test.js +2 -2
  189. package/lib/forms/controls/form-control.js +1 -1
  190. package/lib/forms/controls/hidden-input.js +4 -1
  191. package/lib/forms/controls/{photo.js → image.js} +6 -7
  192. package/lib/forms/controls/{photo.test.js → image.test.js} +8 -23
  193. package/lib/forms/controls/multiple-files.js +10 -1
  194. package/lib/forms/controls/{multiple-photos.js → multiple-images.js} +3 -3
  195. package/lib/forms/controls/simple-input.js +13 -12
  196. package/lib/forms/controls/single-reference.js +4 -0
  197. package/lib/forms/controls/single-reference.test.js +1 -1
  198. package/lib/forms/controls/table.js +62 -25
  199. package/lib/forms/controls/textarea.js +5 -3
  200. package/lib/forms/controls/tickable.js +13 -5
  201. package/lib/forms/fields/boolean.js +14 -0
  202. package/lib/forms/fields/checkboxed-list.js +4 -0
  203. package/lib/forms/fields/collection-field.js +9 -0
  204. package/lib/forms/fields/color.js +10 -0
  205. package/lib/forms/fields/coordinates.js +49 -0
  206. package/lib/forms/fields/date.js +34 -0
  207. package/lib/forms/fields/datetime.js +46 -0
  208. package/lib/forms/fields/deep-reverse-single-reference-list.js +81 -0
  209. package/lib/forms/fields/deep-reverse-single-reference-table.js +122 -0
  210. package/lib/forms/fields/email.js +7 -0
  211. package/lib/forms/fields/enum-multiple-sealious.js +32 -0
  212. package/lib/forms/fields/field.js +32 -4
  213. package/lib/forms/fields/field.test.js +8 -8
  214. package/lib/forms/fields/fields.js +23 -8
  215. package/lib/forms/fields/file.js +33 -9
  216. package/lib/forms/fields/file.test.js +5 -17
  217. package/lib/forms/fields/float.js +10 -0
  218. package/lib/forms/fields/get-field-for-sealious.js +213 -0
  219. package/lib/forms/fields/html.js +14 -0
  220. package/lib/forms/fields/image.js +13 -0
  221. package/lib/forms/fields/int.js +23 -0
  222. package/lib/forms/fields/json.js +31 -0
  223. package/lib/forms/fields/markdown.js +14 -0
  224. package/lib/forms/fields/multiple-files.js +4 -0
  225. package/lib/forms/fields/number.js +6 -0
  226. package/lib/forms/fields/password.js +13 -0
  227. package/lib/forms/fields/pick-from-list-sealious.js +17 -0
  228. package/lib/forms/fields/pick-from-list.js +6 -2
  229. package/lib/forms/fields/proxy-field.js +3 -0
  230. package/lib/forms/fields/regexp.js +14 -0
  231. package/lib/forms/fields/simple-form-field.js +61 -2
  232. package/lib/forms/fields/single-reference.js +44 -0
  233. package/lib/forms/fields/structured-array.js +61 -12
  234. package/lib/forms/fields/table.js +29 -2
  235. package/lib/forms/fields/text.js +17 -0
  236. package/lib/forms/fields/url.js +17 -0
  237. package/lib/forms/form.js +30 -14
  238. package/lib/forms/form.test.js +5 -7
  239. package/lib/forms/multiform.js +10 -9
  240. package/lib/forms/multiform.test.js +5 -5
  241. package/lib/generate-collections.js +2 -3
  242. package/lib/generate-components.js +2 -3
  243. package/lib/generate-routes.js +3 -5
  244. package/lib/generate-routes.test.js +7 -16
  245. package/lib/generate-stimulus.js +4 -4
  246. package/lib/get-fonts.js +29 -27
  247. package/lib/index.js +1 -0
  248. package/lib/make-env.js +1 -1
  249. package/lib/make-hidden-inputs.js +4 -4
  250. package/lib/mount.js +11 -1
  251. package/lib/notifier.js +3 -4
  252. package/lib/page/list.js +20 -15
  253. package/lib/page/mountable-with-fields.js +14 -6
  254. package/lib/page/mountable-with-fields.test.js +1 -1
  255. package/lib/page/mountable.js +0 -1
  256. package/lib/page/page.js +0 -1
  257. package/lib/register-external.js +4 -4
  258. package/lib/templates/form.js +9 -10
  259. package/lib/templates/jdd-component.js +1 -1
  260. package/lib/templates/jdd-editor.js +1 -1
  261. package/lib/templates/multiform.js +4 -4
  262. package/lib/templates/page.js +1 -3
  263. package/lib/templates/shared/collection-create-form.js +31 -44
  264. package/lib/templates/shared/collection-edit-form.js +43 -81
  265. package/lib/templates/shared/collection-list.js +13 -21
  266. package/lib/templates/shared/shared-crud-form-fields.js +28 -98
  267. package/lib/test_utils/exec_async.js +3 -3
  268. package/lib/test_utils/test-on-real-app.js +12 -14
  269. package/lib/utils/extract-fields-from-collection.js +60 -20
  270. package/lib/utils/make-slug.js +1 -1
  271. package/lib/utils/wrap-attributes.js +20 -0
  272. package/lib/utils/write-file.js +1 -1
  273. package/package.json +11 -9
  274. package/src/add-collection.ts +1 -3
  275. package/src/add-crud.ts +84 -100
  276. package/src/add-jdd-component.ts +4 -5
  277. package/src/add-list-route.test.ts +1 -1
  278. package/src/add-route.ts +3 -13
  279. package/src/build.ts +6 -4
  280. package/src/builders/backend-ts-builder.ts +0 -1
  281. package/src/builders/builder.ts +4 -1
  282. package/src/builders/colors-builder.ts +11 -9
  283. package/src/builders/css-builder.ts +4 -1
  284. package/src/builders/fonts-builder.ts +0 -1
  285. package/src/builders/frontend-ts-builder.ts +0 -1
  286. package/src/cli.ts +5 -7
  287. package/src/components/tabs.ts +38 -37
  288. package/src/components/toggle-modal.ts +1 -1
  289. package/src/controllers/table-add-button.stimulus.ts +35 -0
  290. package/src/esbuild-plugins/rewrite-asset-imports.ts +7 -10
  291. package/src/forms/controls/array.ts +35 -36
  292. package/src/forms/controls/autocomplete.ts +2 -2
  293. package/src/forms/controls/big-radio-group.ts +4 -4
  294. package/src/forms/controls/checkbox-group.ts +10 -10
  295. package/src/forms/controls/checkboxed-list-input.test.ts +6 -6
  296. package/src/forms/controls/checkboxed-list-input.ts +16 -8
  297. package/src/forms/controls/controls.ts +2 -2
  298. package/src/forms/controls/derived-frame.ts +16 -11
  299. package/src/forms/controls/derived.ts +7 -6
  300. package/src/forms/controls/dropdown.ts +13 -13
  301. package/src/forms/controls/editable-collection-subset.ts +4 -3
  302. package/src/forms/controls/field-group.ts +1 -1
  303. package/src/forms/controls/file.test.ts +4 -2
  304. package/src/forms/controls/file.ts +30 -7
  305. package/src/forms/controls/form-control.ts +8 -3
  306. package/src/forms/controls/hidden-input.ts +5 -1
  307. package/src/forms/controls/html.ts +1 -0
  308. package/src/forms/controls/{photo.test.ts → image.test.ts} +7 -24
  309. package/src/forms/controls/{photo.ts → image.ts} +4 -6
  310. package/src/forms/controls/multiple-files.ts +23 -8
  311. package/src/forms/controls/{multiple-photos.ts → multiple-images.ts} +2 -2
  312. package/src/forms/controls/number.ts +1 -1
  313. package/src/forms/controls/simple-input.ts +21 -33
  314. package/src/forms/controls/single-reference.test.ts +1 -1
  315. package/src/forms/controls/single-reference.ts +11 -3
  316. package/src/forms/controls/table.ts +87 -33
  317. package/src/forms/controls/textarea.ts +7 -5
  318. package/src/forms/controls/tickable.ts +13 -7
  319. package/src/forms/fields/boolean.ts +27 -2
  320. package/src/forms/fields/checkboxed-list.ts +11 -2
  321. package/src/forms/fields/collection-field.ts +21 -3
  322. package/src/forms/fields/color.ts +9 -0
  323. package/src/forms/fields/coordinates.ts +66 -0
  324. package/src/forms/fields/date.ts +50 -0
  325. package/src/forms/fields/datetime.ts +66 -0
  326. package/src/forms/fields/deep-reverse-single-reference-list.ts +130 -0
  327. package/src/forms/fields/deep-reverse-single-reference-table.ts +213 -0
  328. package/src/forms/fields/email.ts +10 -1
  329. package/src/forms/fields/enum-multiple-sealious.ts +48 -0
  330. package/src/forms/fields/existing-sealious-value.ts +1 -1
  331. package/src/forms/fields/field.test.ts +8 -8
  332. package/src/forms/fields/field.ts +98 -11
  333. package/src/forms/fields/fields.ts +23 -8
  334. package/src/forms/fields/file.test.ts +5 -17
  335. package/src/forms/fields/file.ts +44 -16
  336. package/src/forms/fields/float.ts +9 -0
  337. package/src/forms/fields/get-field-for-sealious.ts +337 -0
  338. package/src/forms/fields/html.ts +15 -0
  339. package/src/forms/fields/image.ts +12 -0
  340. package/src/forms/fields/int.ts +25 -0
  341. package/src/forms/fields/json.ts +48 -0
  342. package/src/forms/fields/markdown.ts +15 -0
  343. package/src/forms/fields/multiple-files.ts +10 -1
  344. package/src/forms/fields/number.ts +10 -3
  345. package/src/forms/fields/password.ts +13 -0
  346. package/src/forms/fields/pick-from-list-sealious.ts +22 -0
  347. package/src/forms/fields/pick-from-list.ts +8 -4
  348. package/src/forms/fields/proxy-field.ts +7 -1
  349. package/src/forms/fields/regexp.ts +27 -1
  350. package/src/forms/fields/simple-form-field.ts +103 -7
  351. package/src/forms/fields/single-reference.ts +62 -0
  352. package/src/forms/fields/structured-array.ts +111 -18
  353. package/src/forms/fields/table.ts +39 -16
  354. package/src/forms/fields/text.ts +18 -0
  355. package/src/forms/fields/url.ts +20 -0
  356. package/src/forms/form-types.ts +5 -4
  357. package/src/forms/form.test.ts +5 -7
  358. package/src/forms/form.ts +42 -23
  359. package/src/forms/forms.css +0 -85
  360. package/src/forms/multiform.test.ts +9 -9
  361. package/src/forms/multiform.ts +12 -10
  362. package/src/generate-collections.ts +2 -3
  363. package/src/generate-components.ts +2 -3
  364. package/src/generate-routes.test.ts +7 -16
  365. package/src/generate-routes.ts +6 -10
  366. package/src/generate-stimulus.ts +4 -5
  367. package/src/get-fonts.ts +32 -30
  368. package/src/index.ts +2 -1
  369. package/src/make-env.ts +1 -1
  370. package/src/make-hidden-inputs.ts +8 -7
  371. package/src/mount.ts +16 -7
  372. package/src/notifier.ts +4 -7
  373. package/src/page/default-list-filters.ts +1 -0
  374. package/src/page/list.ts +33 -28
  375. package/src/page/mountable-with-fields.test.ts +1 -1
  376. package/src/page/mountable-with-fields.ts +21 -12
  377. package/src/page/mountable.ts +0 -1
  378. package/src/page/page.ts +2 -3
  379. package/src/page/props-parser.ts +1 -1
  380. package/src/page/sealious-list.ts +1 -1
  381. package/src/page/stateful-page.ts +6 -10
  382. package/src/register-external.ts +5 -5
  383. package/src/templates/form.ts +9 -11
  384. package/src/templates/jdd-component.ts +1 -1
  385. package/src/templates/jdd-editor.ts +2 -4
  386. package/src/templates/list.ts +0 -1
  387. package/src/templates/multiform.ts +4 -4
  388. package/src/templates/page.ts +1 -6
  389. package/src/templates/shared/collection-create-form.ts +34 -71
  390. package/src/templates/shared/collection-edit-form.ts +46 -108
  391. package/src/templates/shared/collection-list.ts +13 -21
  392. package/src/templates/shared/item-delete.ts +0 -1
  393. package/src/templates/shared/shared-crud-form-fields.ts +38 -177
  394. package/src/templates/templates.ts +5 -1
  395. package/src/test_utils/exec_async.ts +3 -4
  396. package/src/test_utils/test-on-real-app.ts +13 -14
  397. package/src/utils/browser-creator.js +0 -1
  398. package/src/utils/exec.ts +0 -1
  399. package/src/utils/extract-fields-from-collection.ts +76 -25
  400. package/src/utils/input-wrapper.ts +1 -1
  401. package/src/utils/make-slug.ts +1 -1
  402. package/src/utils/wrap-attributes.ts +17 -0
  403. package/src/utils/write-file.ts +1 -1
  404. package/.eslintrc.cjs +0 -39
  405. package/lib/add-verbose-crud.js +0 -119
  406. package/lib/crud-field-snippets.js +0 -52
  407. package/lib/find-css-includes.js +0 -3
  408. package/lib/forms/controls/reverse-single-reference.js +0 -1
  409. package/lib/forms/fields/enum-multiple.js +0 -47
  410. package/lib/forms/fields/enum-multiple.test.js +0 -27
  411. package/lib/forms/fields/enum.js +0 -41
  412. package/lib/forms/fields/enum.test.js +0 -21
  413. package/lib/forms/fields/reverse-single-reference.js +0 -17
  414. package/lib/templates/shared/handlers/boolean.js +0 -14
  415. package/lib/templates/shared/handlers/date.js +0 -8
  416. package/lib/templates/shared/handlers/deep-reverse-single-reference.js +0 -209
  417. package/lib/templates/shared/handlers/default.js +0 -49
  418. package/lib/templates/shared/handlers/enum.js +0 -19
  419. package/lib/templates/shared/handlers/file.js +0 -23
  420. package/lib/templates/shared/handlers/image.js +0 -32
  421. package/lib/templates/shared/handlers/int.js +0 -11
  422. package/lib/templates/shared/handlers/jdd.js +0 -10
  423. package/lib/templates/shared/handlers/single-reference.js +0 -12
  424. package/lib/templates/shared/handlers/structured-array.js +0 -33
  425. package/src/add-verbose-crud.ts +0 -138
  426. package/src/crud-field-snippets.ts +0 -57
  427. package/src/find-css-includes.ts +0 -3
  428. package/src/forms/controls/reverse-single-reference.ts +0 -50
  429. package/src/forms/fields/enum-multiple.test.ts +0 -31
  430. package/src/forms/fields/enum-multiple.ts +0 -62
  431. package/src/forms/fields/enum.test.ts +0 -25
  432. package/src/forms/fields/enum.ts +0 -56
  433. package/src/forms/fields/reverse-single-reference.ts +0 -20
  434. package/src/templates/shared/handlers/boolean.ts +0 -18
  435. package/src/templates/shared/handlers/date.ts +0 -12
  436. package/src/templates/shared/handlers/deep-reverse-single-reference.ts +0 -244
  437. package/src/templates/shared/handlers/default.ts +0 -64
  438. package/src/templates/shared/handlers/enum.ts +0 -23
  439. package/src/templates/shared/handlers/file.ts +0 -27
  440. package/src/templates/shared/handlers/image.ts +0 -45
  441. package/src/templates/shared/handlers/int.ts +0 -15
  442. package/src/templates/shared/handlers/jdd.ts +0 -14
  443. package/src/templates/shared/handlers/single-reference.ts +0 -16
  444. package/src/templates/shared/handlers/structured-array.ts +0 -42
@@ -39,7 +39,7 @@ describe("single-reference.test", () => {
39
39
  const form_file_path = "src/back/routes/some-form.form.ts";
40
40
  await test_app.addFile(
41
41
  form_file_path,
42
- await formTemplate("SomeForm", form_file_path, {
42
+ await formTemplate("SomeForm", {
43
43
  postimport: `import {Comments} from "../collections/collections.js"; import {Fields} from "@sealcode/sealgen";`,
44
44
  fields: `article: new Fields.CollectionField(true, Comments.fields.article),`,
45
45
  controls: `new Controls.SingleReferenceDropdown(fields.article, {getLabel: item=>item.get("title")}),`,
@@ -1,11 +1,12 @@
1
- import SealiousSingleReference from "sealious/@types/app/base-chips/field-types/single-reference.js";
1
+ import { FieldTypes as SealiousFieldTypes } from "sealious";
2
2
  import { CollectionField } from "../fields/collection-field.js";
3
3
  import { DropdownOptions, FreeformDropdown } from "./dropdown.js";
4
4
  import { Collection, CollectionItem } from "sealious";
5
5
 
6
6
  export class SingleReferenceDropdown<
7
- F extends SealiousSingleReference,
8
- Required extends boolean
7
+ TargetCollection extends Collection,
8
+ F extends SealiousFieldTypes.SingleReference,
9
+ Required extends boolean,
9
10
  > extends FreeformDropdown {
10
11
  constructor(
11
12
  public field: CollectionField<F, Required>,
@@ -38,4 +39,11 @@ export class SingleReferenceDropdown<
38
39
  options
39
40
  );
40
41
  }
42
+
43
+ setOptionLabelGetter(
44
+ getter: (item: CollectionItem<TargetCollection>) => string
45
+ ): this {
46
+ this.options.getLabel = getter;
47
+ return this;
48
+ }
41
49
  }
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
2
2
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
3
  /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
4
5
  import Router from "@koa/router";
5
6
  import { hasShape, is, predicates } from "@sealcode/ts-predicates";
6
7
  import { Context } from "koa";
@@ -10,19 +11,14 @@ import { FormField } from "../fields/field.js";
10
11
  import {
11
12
  ExtractFormFieldParsed,
12
13
  Table as TableField,
13
- TableFieldParsed,
14
14
  } from "../fields/table.js";
15
15
  import { FormReaction } from "../form-types.js";
16
16
  import { Form } from "../form.js";
17
17
  import { FormControl, FormControlContext } from "./form-control.js";
18
18
 
19
19
  export type TableControlOptions<F extends Record<string, FormField>> = {
20
- render_fields: {
21
- [field_name in keyof F]: (
22
- fctx: FormControlContext,
23
- name: string,
24
- value: string
25
- ) => FlatTemplatable | Promise<FlatTemplatable>;
20
+ subfield_controls: {
21
+ [field_name in keyof F]: FormControl;
26
22
  };
27
23
  allow_removing?: boolean;
28
24
  label_add?: string;
@@ -38,7 +34,8 @@ export type TableControlOptions<F extends Record<string, FormField>> = {
38
34
  }
39
35
  );
40
36
 
41
- const TO_REPLACE = "____$$$$";
37
+ export const TABLE_COLUMN_FIELD_INDEX_PLACEHOLDER =
38
+ "TABLE_ROW_INDEX________________";
42
39
 
43
40
  export class Table<F extends Record<string, FormField>> extends FormControl {
44
41
  role = <const>"input";
@@ -50,15 +47,41 @@ export class Table<F extends Record<string, FormField>> extends FormControl {
50
47
  }
51
48
 
52
49
  async render(fctx: FormControlContext): Promise<FlatTemplatable> {
53
- let { parsed: rows } = await this.table_field.getValue(
54
- fctx.ctx,
55
- fctx.data
56
- );
50
+ let rows = fctx.data.raw_values?.[this.table_field.name] as any[];
57
51
  if (!rows) {
58
52
  rows = [];
59
53
  }
60
54
 
61
- const make_row = (
55
+ const get_row_fctx = (
56
+ row:
57
+ | {
58
+ [field_name in keyof F]: ExtractFormFieldParsed<
59
+ F[field_name]
60
+ >;
61
+ }
62
+ | null,
63
+ row_index: number | string
64
+ ) => {
65
+ return typeof row_index == "number"
66
+ ? {
67
+ data: {
68
+ raw_values:
69
+ (Object.fromEntries(
70
+ Object.entries(
71
+ row as Record<string, unknown>
72
+ ).map(([key, value]) => [
73
+ this.table_field.columns[key].name,
74
+ value,
75
+ ])
76
+ ) as any) || {},
77
+ messages: [],
78
+ field_messages: {},
79
+ },
80
+ }
81
+ : {};
82
+ };
83
+
84
+ const make_row = async (
62
85
  row:
63
86
  | {
64
87
  [field_name in keyof F]: ExtractFormFieldParsed<
@@ -69,14 +92,21 @@ export class Table<F extends Record<string, FormField>> extends FormControl {
69
92
  row_index: number | string
70
93
  ) => {
71
94
  return /* HTML */ tempstream`<tr>
72
- ${Object.entries(this.table_field.columns).map(([key]) => {
73
- return tempstream`<td>${this.options.render_fields[key](
74
- fctx,
75
- `${this.table_field.name}[${row_index}][${key}]`,
76
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
77
- (row?.[key] as string) || ""
78
- )}</td>`;
79
- })}
95
+ ${Promise.all(
96
+ Object.entries(this.table_field.columns)
97
+ .map(([column_name]) => {
98
+ const inner_fctx = get_row_fctx(row, row_index);
99
+ return tempstream`<td>${this.options.subfield_controls[
100
+ column_name
101
+ ].render({ ...fctx, ...inner_fctx })}</td>`;
102
+ })
103
+ .map(async (html) =>
104
+ (await html).replaceAll(
105
+ TABLE_COLUMN_FIELD_INDEX_PLACEHOLDER,
106
+ row_index.toString()
107
+ )
108
+ )
109
+ )}
80
110
  ${
81
111
  this.options.allow_removing
82
112
  ? /* HTML */ `<td>
@@ -103,13 +133,13 @@ export class Table<F extends Record<string, FormField>> extends FormControl {
103
133
  )}"
104
134
  />
105
135
  </noscript>
106
- </td>`
136
+ </td>`
107
137
  : ""
108
138
  }
109
139
  </tr>`;
110
140
  };
111
141
 
112
- return tempstream/* HTML */ `<turbo-frame
142
+ return tempstream /* HTML */ `<turbo-frame
113
143
  id="${this.getFrameID()}"
114
144
  class="${[
115
145
  "form-input__wrapper",
@@ -136,27 +166,25 @@ export class Table<F extends Record<string, FormField>> extends FormControl {
136
166
  ${rows?.map((row, index) => make_row(row, index))}
137
167
  </tbody>
138
168
  </table>
139
- <template> ${make_row(null, TO_REPLACE)} </template>
169
+ <template>
170
+ ${make_row(null, TABLE_COLUMN_FIELD_INDEX_PLACEHOLDER)}
171
+ </template>
140
172
 
141
173
  ${
142
174
  /* because of https://github.com/ljharb/qs/issues/252 we have to
143
175
  put the indexes in the field names */
144
176
  this.options.allow_adding
145
177
  ? /* HTML */ `<button
146
- onclick="const template = this.closest('turbo-frame').querySelector('template');
147
- const tbody = this.closest('turbo-frame').querySelector('tbody');
148
- const orig_template = template.innerHTML;
149
- template.innerHTML = orig_template.replaceAll('${TO_REPLACE}', tbody.querySelectorAll('tr').length);
150
- tbody.appendChild(template.cloneNode(true).content);
151
- template.innerHTML = orig_template;"
178
+ data-controller="table-add-button"
179
+ data-action="click->table-add-button#addRow"
180
+ data-table-placeholder="${TABLE_COLUMN_FIELD_INDEX_PLACEHOLDER}"
152
181
  >
153
- add
182
+ ${this.options.label_add || "add"}
154
183
  </button>
155
184
  <noscript>
156
185
  <input
157
186
  type="submit"
158
- value="${this.options.label_add ||
159
- "add"}"
187
+ value="add"
160
188
  form="${fctx.form_id}"
161
189
  formnovalidate
162
190
  formaction="${this.getActionURL(
@@ -249,6 +277,7 @@ template.innerHTML = orig_template;"
249
277
  {
250
278
  raw_values: await form.extractRawValues(ctx),
251
279
  messages: [],
280
+ field_messages: {},
252
281
  },
253
282
  false
254
283
  ),
@@ -256,4 +285,29 @@ template.innerHTML = orig_template;"
256
285
  await next();
257
286
  });
258
287
  }
288
+
289
+ setAllowRemoving(value: boolean) {
290
+ this.options.allow_removing = value;
291
+ return this;
292
+ }
293
+
294
+ setAllowAdding(value: boolean) {
295
+ this.options.allow_adding = value;
296
+ return this;
297
+ }
298
+
299
+ setLabel(value: string) {
300
+ this.options.label = value;
301
+ return this;
302
+ }
303
+
304
+ setRemoveLabel(value: string) {
305
+ this.options.label_remove = value;
306
+ return this;
307
+ }
308
+
309
+ setAddLabel(value: string) {
310
+ this.options.label_add = value;
311
+ return this;
312
+ }
259
313
  }
@@ -4,9 +4,9 @@ import { FormDataValue } from "../form-types.js";
4
4
  import { FormControlContext } from "./form-control.js";
5
5
  import { SimpleInput, SimpleInputOptions } from "./simple-input.js";
6
6
 
7
- export class Textarea extends SimpleInput<string | null> {
7
+ export class Textarea extends SimpleInput {
8
8
  constructor(
9
- public field: FormField<boolean, string | null>,
9
+ public field: FormField<boolean>,
10
10
  public options: SimpleInputOptions & {
11
11
  label?: string;
12
12
  rows?: number;
@@ -22,7 +22,7 @@ export class Textarea extends SimpleInput<string | null> {
22
22
  return this.options.description
23
23
  ? /* HTML */ `<div class="form-input__description">
24
24
  ${this.options.description}
25
- </div>`
25
+ </div>`
26
26
  : "";
27
27
  }
28
28
 
@@ -49,7 +49,9 @@ export class Textarea extends SimpleInput<string | null> {
49
49
  attributes: string,
50
50
  data: Record<string, FormDataValue>
51
51
  ) {
52
- const { parsed: value } = await this.field.getValue(ctx, data);
53
- return /* HTML */ `<textarea ${attributes}>${value || ""}</textarea>`;
52
+ const { parsed: value } = await this.field.getParsedValue(ctx, data);
53
+ return /* HTML */ `<textarea ${attributes}>
54
+ ${String(value) || ""}</textarea
55
+ >`;
54
56
  }
55
57
  }
@@ -65,28 +65,34 @@ export abstract class Tickable<T> extends FormFieldControl {
65
65
  }
66
66
 
67
67
  async render(fctx: FormControlContext): Promise<FlatTemplatable> {
68
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
69
68
  const {
70
69
  parsed: _parsed,
71
70
  valid,
72
71
  message,
73
- } = await this.field.getValue(fctx.ctx, fctx.data, true);
72
+ } = await this.field.getParsedValue(
73
+ fctx.ctx,
74
+ fctx.data.raw_values,
75
+ true
76
+ );
74
77
  const parsed = _parsed === null ? this.options.default_value : _parsed;
75
78
 
76
- const value = this.getValueAttribute(fctx.ctx, fctx.data, parsed);
77
- const id = this.makeInputID(fctx.ctx, fctx.data, parsed);
79
+ const value = this.getValueAttribute(
80
+ fctx.ctx,
81
+ fctx.data.raw_values,
82
+ parsed
83
+ );
84
+ const id = this.makeInputID(fctx.ctx, fctx.data.raw_values, parsed);
78
85
  const label =
79
86
  this.options.label != undefined
80
87
  ? this.options.label
81
88
  : this.field.name;
82
89
 
83
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
84
90
  const readonly = this.options.readonly || false;
85
91
  const required = this.field.required;
86
92
 
87
93
  return inputWrapper(
88
94
  this.type,
89
- this.getWrapperClasses(fctx.ctx, fctx.data, parsed),
95
+ this.getWrapperClasses(fctx.ctx, fctx.data.raw_values, parsed),
90
96
 
91
97
  /* HTML */ `
92
98
  <input
@@ -96,7 +102,7 @@ export abstract class Tickable<T> extends FormFieldControl {
96
102
  this.field.name}"
97
103
  ${value ? `value="${attribute(value)}"` : ""}
98
104
  ${fctx.form_id ? `form="${fctx.form_id}"` : ""}
99
- ${this.isChecked(fctx.ctx, fctx.data, parsed)
105
+ ${this.isChecked(fctx.ctx, fctx.data.raw_values, parsed)
100
106
  ? "checked"
101
107
  : ""}
102
108
  ${readonly ? "readonly" : ""}
@@ -1,17 +1,23 @@
1
1
  import { is, predicates } from "@sealcode/ts-predicates";
2
2
  import { Context } from "koa";
3
+ import { Checkbox } from "../controls/checkbox.js";
3
4
  import { FormDataValue } from "../form-types.js";
4
5
  import { FieldParseResult, FormField } from "./field.js";
6
+ import { FormControlContext } from "../controls/form-control.js";
5
7
 
6
8
  const truthy = ["true", "on", "yes", "1"];
7
9
  const falsy = ["false", "off", "no", "0"];
8
10
 
9
11
  export class Boolean<Required extends boolean> extends FormField<
10
12
  Required,
11
- boolean
13
+ boolean,
14
+ Checkbox
12
15
  > {
13
16
  predicate = predicates.boolean;
14
- constructor(required: Required, public error_message: string = "") {
17
+ constructor(
18
+ required: Required,
19
+ public error_message: string = ""
20
+ ) {
15
21
  super(required);
16
22
  }
17
23
 
@@ -60,4 +66,23 @@ export class Boolean<Required extends boolean> extends FormField<
60
66
  public getEmptyValue(): boolean {
61
67
  return false;
62
68
  }
69
+
70
+ public getControl(): Checkbox {
71
+ return new Checkbox(this, { label: this.name });
72
+ }
73
+
74
+ async getSealiousCreateValue(fctx: FormControlContext): Promise<boolean> {
75
+ const { parsed } = await this.getParsedValue(
76
+ fctx.ctx,
77
+ fctx.data.raw_values
78
+ );
79
+ return !!parsed;
80
+ }
81
+
82
+ async sealiousValueToForm(
83
+ _: Context,
84
+ value: boolean | null
85
+ ): Promise<FormDataValue> {
86
+ return value ? "true" : "false";
87
+ }
63
88
  }
@@ -1,5 +1,6 @@
1
1
  import { is, predicates } from "@sealcode/ts-predicates";
2
2
  import { Context } from "koa";
3
+ import { CheckboxedListInput } from "../controls/checkboxed-list-input.js";
3
4
  import { FormDataValue } from "../form-types.js";
4
5
  import {
5
6
  FieldParseResult,
@@ -13,9 +14,13 @@ export type CheckboxedListItem = {
13
14
  group?: string;
14
15
  };
15
16
 
16
- export class CheckboxedListField<Required extends boolean> extends FormField<
17
+ export class CheckboxedListField<
18
+ Required extends boolean,
19
+ Values extends string,
20
+ > extends FormField<
17
21
  Required,
18
- Record<string, "on">
22
+ Record<Values, "on">,
23
+ CheckboxedListInput<Values>
19
24
  > {
20
25
  constructor(
21
26
  public required: Required,
@@ -67,4 +72,8 @@ export class CheckboxedListField<Required extends boolean> extends FormField<
67
72
  public getEmptyValue(): Record<string, "on"> {
68
73
  return {};
69
74
  }
75
+
76
+ getControl(): CheckboxedListInput<Values> {
77
+ return new CheckboxedListInput(this, { label: this.name });
78
+ }
70
79
  }
@@ -1,6 +1,7 @@
1
1
  import { predicates } from "@sealcode/ts-predicates";
2
2
  import { Context } from "koa";
3
3
  import { Depromisify, ExtractFieldDecoded, Field } from "sealious";
4
+ import { SimpleInput } from "../controls/controls.js";
4
5
  import { FormDataValue } from "../form-types.js";
5
6
 
6
7
  import {
@@ -8,13 +9,17 @@ import {
8
9
  FormField,
9
10
  FormFieldValidationResponse,
10
11
  } from "./field.js";
12
+ import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
11
13
 
12
14
  export class CollectionField<
13
15
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
16
  F extends Field<any>,
15
- Required extends boolean
16
- > extends FormField<Required, ExtractFieldDecoded<F> | null> {
17
- constructor(required: Required, public sealiousField: F) {
17
+ Required extends boolean,
18
+ > extends FormField<Required, ExtractFieldDecoded<F> | null, SimpleInput> {
19
+ constructor(
20
+ required: Required,
21
+ public sealiousField: F
22
+ ) {
18
23
  super(required);
19
24
  }
20
25
 
@@ -62,4 +67,17 @@ export class CollectionField<
62
67
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
63
68
  return "" as unknown as ExtractFieldDecoded<F>;
64
69
  }
70
+
71
+ getControl(): SimpleInput {
72
+ return new SimpleInput(this);
73
+ }
74
+
75
+ generateFieldDeclaration(
76
+ field_info: ExtractedFieldInfo,
77
+ vars: { form_field_types: string; sealious_field: string }
78
+ ): string {
79
+ return `new ${vars.form_field_types}.${this.constructor.name}(${String(
80
+ field_info.is_required
81
+ )}, ${vars.sealious_field})`;
82
+ }
65
83
  }
@@ -0,0 +1,9 @@
1
+ import { TextBasedSimpleField } from "./simple-form-field.js";
2
+
3
+ export class Color<
4
+ Required extends boolean,
5
+ > extends TextBasedSimpleField<Required> {
6
+ constructor(required: Required) {
7
+ super(required, "color");
8
+ }
9
+ }
@@ -0,0 +1,66 @@
1
+ import { Context } from "koa";
2
+ import { FormControl, FormControlContext } from "../controls/form-control.js";
3
+ import { SimpleInput } from "../controls/simple-input.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 Coordinates<
9
+ Required extends boolean,
10
+ DefaultControl extends FormControl = SimpleInput,
11
+ > extends SimpleFormField<Required, DefaultControl, [number, number]> {
12
+ async parse(
13
+ _: Context,
14
+ raw_value: FormDataValue
15
+ ): Promise<FieldParseResult<[number, number]>> {
16
+ if (typeof raw_value == "string") {
17
+ return {
18
+ parsed_value: raw_value
19
+ ?.split(",")
20
+ .map((e) => parseFloat(e)) as [number, number],
21
+ parsable: true,
22
+ error: null,
23
+ };
24
+ }
25
+ if (Array.isArray(raw_value)) {
26
+ return {
27
+ parsed_value: raw_value.map((e) => parseFloat(e)) as [
28
+ number,
29
+ number,
30
+ ],
31
+ parsable: true,
32
+ error: null,
33
+ };
34
+ }
35
+ return {
36
+ parsed_value: null,
37
+ parsable: false,
38
+ error: "should be an array or string",
39
+ };
40
+ }
41
+
42
+ async getSealiousCreateValue(
43
+ fctx: FormControlContext
44
+ ): Promise<[number, number] | undefined> {
45
+ const { parsed } = await this.getParsedValue(
46
+ fctx.ctx,
47
+ fctx.data.raw_values
48
+ );
49
+ return parsed || undefined;
50
+ }
51
+
52
+ async postSealiousCreate(): Promise<void> {}
53
+
54
+ async postSealiousEdit(): Promise<void> {}
55
+
56
+ getControl(): DefaultControl {
57
+ return new SimpleInput(this, {
58
+ label: this.name,
59
+ type: this.type,
60
+ }) as unknown as DefaultControl;
61
+ }
62
+
63
+ public getEmptyValue(): [number, number] {
64
+ return [0, 0];
65
+ }
66
+ }
@@ -0,0 +1,50 @@
1
+ import { Context } from "koa";
2
+ import { FormControlContext } from "../controls/form-control.js";
3
+ import { SimpleInput, SimpleInputOptions } from "../controls/simple-input.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 DateField<Required extends boolean> extends SimpleFormField<
9
+ Required,
10
+ SimpleInput,
11
+ Date
12
+ > {
13
+ constructor(required: Required) {
14
+ super(required, "date");
15
+ }
16
+
17
+ public getEmptyValue(): Date {
18
+ return new Date("1970-01-01 00:00");
19
+ }
20
+
21
+ async parse(
22
+ ctx: Context,
23
+ raw_value: FormDataValue
24
+ ): Promise<FieldParseResult<Date>> {
25
+ return {
26
+ error: null,
27
+ parsable: true,
28
+ parsed_value: new Date(raw_value as string),
29
+ };
30
+ }
31
+
32
+ getControl(): SimpleInput<SimpleInputOptions> {
33
+ return new SimpleInput(this, { label: this.name, type: this.type });
34
+ }
35
+
36
+ async getSealiousCreateValue(
37
+ fctx: FormControlContext
38
+ ): Promise<string | null> {
39
+ const { parsed } = await this.getParsedValue(
40
+ fctx.ctx,
41
+ fctx.data.raw_values
42
+ );
43
+ if (!parsed) {
44
+ return null;
45
+ }
46
+ return `${parsed.getFullYear()}-${(parsed.getMonth() + 1)
47
+ .toString()
48
+ .padStart(2, "0")}-${parsed.getDate().toString().padStart(2, "0")}`;
49
+ }
50
+ }
@@ -0,0 +1,66 @@
1
+ import { Context } from "koa";
2
+ import { SimpleInput } from "../controls/controls.js";
3
+ import { FormControlContext } from "../controls/form-control.js";
4
+ import { FormDataValue } from "../form-types.js";
5
+ import { FieldParseResult } from "./field.js";
6
+ import { SimpleFormField } from "./simple-form-field.js";
7
+
8
+ function pad(n: number) {
9
+ return String(n).padStart(2, "0");
10
+ }
11
+
12
+ export class DateTime<Required extends boolean> extends SimpleFormField<
13
+ Required,
14
+ SimpleInput,
15
+ Date | null
16
+ > {
17
+ constructor(required: Required) {
18
+ super(required, "datetime-local");
19
+ }
20
+
21
+ public getEmptyValue(): Date | null {
22
+ return null;
23
+ }
24
+
25
+ async parse(
26
+ ctx: Context,
27
+ raw_value: FormDataValue
28
+ ): Promise<FieldParseResult<Date | null>> {
29
+ const parsed_value = new Date(raw_value as string);
30
+ return { parsable: true, error: null, parsed_value };
31
+ }
32
+
33
+ async getSealiousCreateValue(
34
+ fctx: FormControlContext
35
+ ): Promise<number | null> {
36
+ const { parsed } = await this.getParsedValue(
37
+ fctx.ctx,
38
+ fctx.data.raw_values
39
+ );
40
+ if (parsed == null) {
41
+ return null;
42
+ }
43
+ return new Date(parsed).getTime();
44
+ }
45
+
46
+ getControl(): SimpleInput {
47
+ return new SimpleInput(this, {
48
+ label: this.name,
49
+ type: this.type,
50
+ });
51
+ }
52
+
53
+ async sealiousValueToForm(
54
+ ctx: Context,
55
+ value: number | null
56
+ ): Promise<FormDataValue> {
57
+ if (value == null) {
58
+ return "";
59
+ }
60
+ const d = new Date(value);
61
+
62
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(
63
+ d.getDate()
64
+ )}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
65
+ }
66
+ }