@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
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@ export * from "./forms/multiform.js";
16
16
  export * 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
 
20
21
  import { Context } from "koa";
21
22
  import { Readable } from "node:stream";
@@ -37,7 +38,7 @@ export interface HTMLHeadOptions {
37
38
  export interface HTMLArgs {
38
39
  ctx: Context;
39
40
  title: string | Promise<string>;
40
- body: string | Promise<string>;
41
+ body: string | Promise<string> | Readable;
41
42
  htmlOptions?: Partial<HTMLOptions>;
42
43
  makeHead?: (
43
44
  args: HTMLHeadOptions
package/src/make-env.ts CHANGED
@@ -11,5 +11,5 @@ GROUP_ID=${gid}
11
11
  `;
12
12
  const path = target_locreq.resolve(".env");
13
13
  await fs.writeFile(path, content);
14
- console.log("wrote .env");
14
+ console.info("Wrote .env");
15
15
  }
@@ -13,12 +13,13 @@ export function makeHiddenInputs(
13
13
  return tempstream`${Object.entries(fields)
14
14
  .filter(([key]) => !fields_to_skip.includes(key))
15
15
  .map(
16
- ([key, field]) => tempstream/* HTML */ `<input
17
- type="hidden"
18
- name="${key}"
19
- value="${field
20
- .getValue(ctx, values)
21
- .then((r) => attribute(JSON.stringify(r.raw) || ""))}"
22
- />`
16
+ ([key, field]) =>
17
+ tempstream /* HTML */ `<input
18
+ type="hidden"
19
+ name="${key}"
20
+ value="${field
21
+ .getParsedValue(ctx, values)
22
+ .then((r) => attribute(JSON.stringify(r.raw) || ""))}"
23
+ />`
23
24
  )}`;
24
25
  }
package/src/mount.ts CHANGED
@@ -4,11 +4,11 @@ import { FileManager } from "@sealcode/file-manager";
4
4
  import Koa, { Context } from "koa";
5
5
  import { Middlewares as SealiousMiddlewares } from "sealious";
6
6
  import { Mountable } from "./page/mountable.js";
7
+ import { KoaResponsiveImageRouter } from "koa-responsive-image-router";
7
8
 
8
9
  async function handleHtmlPromise(ctx: Context, next: Koa.Next) {
9
10
  await next();
10
11
  if (ctx.body instanceof Promise) {
11
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
12
12
  ctx.body = await ctx.body;
13
13
  }
14
14
  ctx.set("content-type", "text/html;charset=utf-8");
@@ -24,6 +24,17 @@ export function mount(
24
24
  : undefined
25
25
  ): void {
26
26
  const raw_url = typeof url === "string" ? url : url.rawURL;
27
+
28
+ const imageRouter = new KoaResponsiveImageRouter({
29
+ staticPath: "/tmp",
30
+ thumbnailSize: 10,
31
+ cacheManagerResolutionThreshold: 10,
32
+ imageStoragePath: "/tmp",
33
+ smartCropStoragePath: "/tmp",
34
+ });
35
+
36
+ const fileManager = new FileManager("/tmp", "/uploaded_files");
37
+
27
38
  const args = use_dummy_app
28
39
  ? [
29
40
  async (ctx: Context, next: any) => {
@@ -32,37 +43,35 @@ export function mount(
32
43
  // regard
33
44
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
34
45
  ctx.$app = {
46
+ fileManager,
47
+ imageRouter,
35
48
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
36
49
  Logger: new Proxy(
37
50
  {},
38
51
  {
39
52
  get: (_target: any, prop: any) => {
40
53
  if (prop === "info") {
41
- // eslint-disable-next-line @typescript-eslint/no-empty-function
42
54
  return () => {};
43
55
  } else {
44
- // eslint-disable-next-line @typescript-eslint/no-empty-function
45
56
  return () => {};
46
57
  }
47
58
  },
48
59
  }
49
60
  ),
50
61
  getString: (x: string) => x,
51
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
62
  } as any;
53
63
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
54
64
  await next();
55
65
  },
56
66
  SealiousMiddlewares.parseBody(file_manager),
57
67
  handleHtmlPromise,
58
- ]
68
+ ]
59
69
  : [
60
70
  SealiousMiddlewares.extractContext(),
61
71
  SealiousMiddlewares.parseBody(file_manager),
62
72
  handleHtmlPromise,
63
- ];
73
+ ];
64
74
 
65
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
66
75
  router.use(raw_url, ...args);
67
76
  mountable.init();
68
77
 
package/src/notifier.ts CHANGED
@@ -12,7 +12,6 @@ async function get_status(
12
12
  app_port: number
13
13
  ): Promise<{ started_at: number; status: string }> {
14
14
  const r = await fetch(`http://127.0.0.1:${app_port}/status.json`);
15
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
16
15
  return (await r.json()) as { started_at: number; status: string };
17
16
  }
18
17
 
@@ -21,7 +20,7 @@ async function wait_for_run_id_to_change(app_port: number) {
21
20
  try {
22
21
  const { started_at } = await get_status(app_port);
23
22
  first_timestamp = started_at;
24
- } catch (e) {
23
+ } catch (_e) {
25
24
  await wait_for_app_to_be_stable(app_port);
26
25
  return;
27
26
  }
@@ -30,7 +29,6 @@ async function wait_for_run_id_to_change(app_port: number) {
30
29
  throw new Error(APP_DOWN_ERROR_MESSAGE);
31
30
  }
32
31
 
33
- // eslint-disable-next-line no-constant-condition
34
32
  while (true) {
35
33
  // eslint-disable-next-line no-await-in-loop
36
34
  const { started_at } = await get_status(app_port).catch(() => ({
@@ -48,9 +46,8 @@ async function wait_for_app_to_be_stable(app_port: number, n = 3) {
48
46
  // eslint-disable-next-line no-console
49
47
  console.log("Waiting for app to be stable....");
50
48
  let counter = 0;
51
- // eslint-disable-next-line no-constant-condition
49
+
52
50
  while (true) {
53
- console.debug("notifier.ts:53");
54
51
  // eslint-disable-next-line no-await-in-loop
55
52
  const { status } = await get_status(app_port).catch(() => ({
56
53
  status: "down",
@@ -104,8 +101,8 @@ export function make_notifier(port: number, app_port: number) {
104
101
  });
105
102
  });
106
103
 
107
- console.log(
108
- "build notifier listening on websocket at port " + port.toString()
104
+ console.info(
105
+ "🔔 Build notifier listening on websocket at port " + port.toString()
109
106
  );
110
107
  return function notify(message: string) {
111
108
  sockets.forEach((s) => s.send(message));
@@ -1,3 +1,4 @@
1
+ /* eslint @typescript-eslint/no-explicit-any: "off" */
1
2
  import type { Context } from "koa";
2
3
  import { Field } from "sealious";
3
4
  import { FlatTemplatable } from "tempstream";
package/src/page/list.ts CHANGED
@@ -8,7 +8,7 @@ import { naturalNumbers, UrlWithNewParams } from "../utils/utils.js";
8
8
  import { makeHiddenInputs } from "../make-hidden-inputs.js";
9
9
  import qs from "qs";
10
10
  import { NumberField } from "../forms/fields/number.js";
11
- import { SimpleFormField } from "../forms/fields/simple-form-field.js";
11
+ import { TextBasedSimpleField } from "../forms/fields/simple-form-field.js";
12
12
  import { FormDataValue } from "../forms/form-types.js";
13
13
 
14
14
  export const BasePagePropsShape = <const>{};
@@ -19,7 +19,7 @@ export const DEFAULT_ITEMS_PER_PAGE = 12;
19
19
  export const BaseListPageFields = <const>{
20
20
  page: new NumberField(false, 1),
21
21
  itemsPerPage: new NumberField(false, DEFAULT_ITEMS_PER_PAGE),
22
- sort: new SimpleFormField(false),
22
+ sort: new TextBasedSimpleField(false),
23
23
  };
24
24
 
25
25
  export type ListSort = { field: string; order: "asc" | "desc" };
@@ -48,7 +48,7 @@ function encodeSort(field: string, order: "asc" | "desc"): string {
48
48
 
49
49
  export abstract class ListPage<
50
50
  ItemType,
51
- F extends typeof BaseListPageFields
51
+ F extends typeof BaseListPageFields,
52
52
  > extends Page<F> {
53
53
  abstract getItems(
54
54
  ctx: Context,
@@ -74,8 +74,8 @@ export abstract class ListPage<
74
74
 
75
75
  init(): void {
76
76
  super.init();
77
- for (const [fieldname, field] of Object.entries(this.filterFields)) {
78
- void field.init(fieldname);
77
+ for (const [, field] of Object.entries(this.filterFields)) {
78
+ void field.init();
79
79
  }
80
80
  }
81
81
 
@@ -85,12 +85,15 @@ export abstract class ListPage<
85
85
 
86
86
  async getPaginationConfig(ctx: Context) {
87
87
  const values = await this.extractRawValues(ctx);
88
- let { parsed: page } = await this.fields.page.getValue(ctx, values);
88
+ let { parsed: page } = await this.fields.page.getParsedValue(
89
+ ctx,
90
+ values
91
+ );
89
92
  if (!page) {
90
93
  page = 1;
91
94
  }
92
95
  const { parsed: itemsPerPage } =
93
- await this.fields.itemsPerPage.getValue(ctx, values);
96
+ await this.fields.itemsPerPage.getParsedValue(ctx, values);
94
97
  return { page, itemsPerPage };
95
98
  }
96
99
 
@@ -123,7 +126,7 @@ export abstract class ListPage<
123
126
  values
124
127
  );
125
128
 
126
- return tempstream/* HTML */ `<div class="list-pagination">
129
+ return tempstream /* HTML */ `<div class="list-pagination">
127
130
  <div class="list-pagination__left">
128
131
  ${page > 1
129
132
  ? this.renderPageButton(ctx, 1, "Pierwsza strona")
@@ -138,18 +141,18 @@ export abstract class ListPage<
138
141
  onchange="if (this.value) Turbo.visit(this.value)"
139
142
  >
140
143
  ${Array.from(naturalNumbers(1, totalIems)).map(
141
- (n) => /* HTML */ `<option
142
- value="${UrlWithNewParams(
143
- ctx,
144
- //eslint-disable-next-line @typescript-eslint/consistent-type-assertions
145
- this.propsParser.overwriteProp(ctx, {
146
- page: n,
147
- } as Partial<Record<string, unknown>>)
148
- )}"
149
- ${page === n ? "selected" : ""}
150
- >
151
- ${n}
152
- </option>`
144
+ (n) =>
145
+ /* HTML */ `<option
146
+ value="${UrlWithNewParams(
147
+ ctx,
148
+ this.propsParser.overwriteProp(ctx, {
149
+ page: n,
150
+ } as Partial<Record<string, unknown>>)
151
+ )}"
152
+ ${page === n ? "selected" : ""}
153
+ >
154
+ ${n}
155
+ </option>`
153
156
  )}
154
157
  </select>
155
158
  </div>
@@ -168,7 +171,6 @@ export abstract class ListPage<
168
171
  return /* HTML */ `<a
169
172
  href="${UrlWithNewParams(
170
173
  ctx,
171
- //eslint-disable-next-line @typescript-eslint/consistent-type-assertions
172
174
  this.propsParser.overwriteProp(ctx, {
173
175
  page,
174
176
  } as Partial<Record<string, unknown>>)
@@ -182,7 +184,7 @@ export abstract class ListPage<
182
184
  const raw_values = await this.extractRawValues(ctx);
183
185
  for (const [fieldname, field] of Object.entries(this.filterFields)) {
184
186
  // eslint-disable-next-line no-await-in-loop
185
- const { parsed } = await field.getValue(ctx, raw_values);
187
+ const { parsed } = await field.getParsedValue(ctx, raw_values);
186
188
  filter[fieldname] = field.mapToFilter(parsed);
187
189
  }
188
190
  return filter;
@@ -216,17 +218,20 @@ export abstract class ListPage<
216
218
 
217
219
  async renderFilters(ctx: Context): Promise<FlatTemplatable> {
218
220
  const values = await this.extractRawValues(ctx);
219
- return tempstream/* HTML */ `<form method="GET">
221
+ return tempstream /* HTML */ `<form method="GET">
220
222
  ${makeHiddenInputs(ctx, this.fields, values, [
221
223
  "page",
222
224
  ...Object.values(this.filterFields).map((f) => f.name),
223
225
  ])}
224
226
  ${this.filterControls.map((control) => {
225
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
226
227
  return control.render(
227
228
  this.makeFormControlContext(
228
229
  ctx,
229
- { raw_values: values, messages: [] },
230
+ {
231
+ raw_values: values,
232
+ messages: [],
233
+ field_messages: {},
234
+ },
230
235
  false
231
236
  )
232
237
  );
@@ -246,8 +251,8 @@ export abstract class ListPage<
246
251
  current_order === "asc" // cycles the sort order: null → "asc" → "desc" → null → ...
247
252
  ? "desc"
248
253
  : current_order === null
249
- ? "asc"
250
- : null;
254
+ ? "asc"
255
+ : null;
251
256
  return /* HTML */ `<th data-field="${field}">
252
257
  <a href="${this.makeSortLink(ctx, field, order)}"
253
258
  >${label}
@@ -265,7 +270,7 @@ export abstract class ListPage<
265
270
  ctx: Context,
266
271
  fields: { field: string; label?: string }[]
267
272
  ): FlatTemplatable {
268
- return tempstream/* HTML */ `<thead>
273
+ return tempstream /* HTML */ `<thead>
269
274
  <tr>
270
275
  ${fields.map(({ label, field }) =>
271
276
  this.renderHeading(ctx, field, label)
@@ -19,7 +19,7 @@ describe("mountable-with-fields", () => {
19
19
  data.not_required?.trim();
20
20
  // this should work without the optional chaining:
21
21
  data.required.trim();
22
- const { parsed: data2 } = await this.fields.not_required.getValue(
22
+ const { parsed: data2 } = await this.fields.not_required.getParsedValue(
23
23
  ctx,
24
24
  form_values.raw_values
25
25
  );
@@ -2,6 +2,7 @@ import { ShapeToType } from "@sealcode/ts-predicates";
2
2
  import { Context } from "koa";
3
3
  import { FlatTemplatable, tempstream } from "tempstream";
4
4
  import {
5
+ FieldMessages,
5
6
  FormControl,
6
7
  FormControlContext,
7
8
  } from "../forms/controls/form-control.js";
@@ -20,11 +21,11 @@ export type Fields = Record<string, FormField<boolean, any>>;
20
21
 
21
22
  type Resolved<T> = T extends Promise<infer X> ? X : never;
22
23
  type ParsedValue<T extends FormField> = Resolved<
23
- ReturnType<T["getValue"]>
24
+ ReturnType<T["getParsedValue"]>
24
25
  >["parsed"];
25
26
 
26
27
  export abstract class MountableWithFields<
27
- F extends Fields = Fields
28
+ F extends Fields = Fields,
28
29
  > extends Mountable {
29
30
  fields: F;
30
31
  field_names_prefix = ""; // useful for multiform, where many forms are merged into one and field assignment is made using the prefix
@@ -37,8 +38,9 @@ export abstract class MountableWithFields<
37
38
  }
38
39
 
39
40
  init(): void {
40
- for (const [name, field] of Object.entries(this.fields)) {
41
- void field.init(name);
41
+ for (const [field_name, field] of Object.entries(this.fields)) {
42
+ void field.init();
43
+ field.setName(field_name);
42
44
  }
43
45
  }
44
46
 
@@ -51,7 +53,7 @@ export abstract class MountableWithFields<
51
53
  ) {
52
54
  return new FormControlContext(
53
55
  ctx,
54
- data.raw_values,
56
+ data,
55
57
  data.messages,
56
58
  field_name_prefix,
57
59
  form_id,
@@ -81,10 +83,10 @@ export abstract class MountableWithFields<
81
83
  values: Record<string, FormDataValue>
82
84
  ): Promise<{
83
85
  valid: boolean;
84
- field_errors: Partial<Record<keyof Fields, string>>;
86
+ field_errors: FieldMessages;
85
87
  form_messages: FormMessage[];
86
88
  }> {
87
- const field_errors = {} as Record<keyof Fields, string>;
89
+ const field_errors = {} as FieldMessages;
88
90
  let valid = true;
89
91
  const form_messages = [] as FormMessage[];
90
92
 
@@ -92,10 +94,13 @@ export abstract class MountableWithFields<
92
94
  Object.keys(this.fields).map(async (key: keyof F) => {
93
95
  const field = this.fields[key];
94
96
  const { valid: fieldvalid, message: fieldmessage } =
95
- await field.getValue(ctx, values, true);
97
+ await field.getParsedValue(ctx, values, true);
96
98
  if (!fieldvalid) {
97
99
  valid = false;
98
- field_errors[field.name] = fieldmessage;
100
+ field_errors[field.name] = {
101
+ type: "error",
102
+ message: fieldmessage,
103
+ };
99
104
  }
100
105
  })
101
106
  );
@@ -111,7 +116,7 @@ export abstract class MountableWithFields<
111
116
  }
112
117
 
113
118
  public renderControls(fctx: FormControlContext): FlatTemplatable {
114
- return tempstream/* HTML */ `${this.controls.map((control) =>
119
+ return tempstream /* HTML */ `${this.controls.map((control) =>
115
120
  control.render(fctx)
116
121
  )}`;
117
122
  }
@@ -127,7 +132,7 @@ export abstract class MountableWithFields<
127
132
  _: Context,
128
133
  data: FormData<keyof Fields>
129
134
  ): FlatTemplatable {
130
- return tempstream/* HTML */ `<div class="form-messages">
135
+ return tempstream /* HTML */ `<div class="form-messages">
131
136
  ${data.messages.map(
132
137
  (message) =>
133
138
  `<div class="form-message form-message--${message.type}">${message.text}</div>`
@@ -149,7 +154,11 @@ export abstract class MountableWithFields<
149
154
  const promises = Object.entries(this.fields).map(
150
155
  async ([key, field]) => {
151
156
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
152
- const { parsed } = await field.getValue(ctx, raw_values, false);
157
+ const { parsed } = await field.getParsedValue(
158
+ ctx,
159
+ raw_values,
160
+ false
161
+ );
153
162
  result[key] = parsed;
154
163
  }
155
164
  );
@@ -3,7 +3,6 @@ import Router from "@koa/router";
3
3
  import { Context } from "koa";
4
4
 
5
5
  export abstract class Mountable {
6
- // eslint-disable-next-line @typescript-eslint/no-empty-function
7
6
  init(): void {}
8
7
  abstract mount(router: Router, path: string): void;
9
8
 
package/src/page/page.ts CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  import { AllQueryParams, PagePropsParser } from "./props-parser.js";
12
12
 
13
13
  export abstract class Page<
14
- F extends Fields = Record<string, never>
14
+ F extends Fields = Record<string, never>,
15
15
  > extends MountableWithFields<F> {
16
16
  propsParser: PagePropsParser<Record<keyof Fields, unknown>> =
17
17
  new AllQueryParams();
@@ -23,7 +23,6 @@ export abstract class Page<
23
23
  });
24
24
  }
25
25
 
26
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
27
26
  async canAccess(_: Context) {
28
27
  return { canAccess: true, message: "" };
29
28
  }
@@ -32,7 +31,7 @@ export abstract class Page<
32
31
  _: Context,
33
32
  error: PageErrorMessage
34
33
  ): Promise<FlatTemplatable> {
35
- return tempstream/* HTML */ `<div>${error.message}</div>`;
34
+ return tempstream /* HTML */ `<div>${error.message}</div>`;
36
35
  }
37
36
 
38
37
  public abstract render(ctx: Context): Promise<FlatTemplatable>;
@@ -22,7 +22,7 @@ export abstract class PagePropsParser<PropsType> {
22
22
  }
23
23
 
24
24
  export class AllQueryParams<
25
- PropsType extends BasePageProps
25
+ PropsType extends BasePageProps,
26
26
  > extends PagePropsParser<PropsType> {
27
27
  decode(ctx: Context): Record<string, FormDataValue> {
28
28
  return ctx.query;
@@ -18,7 +18,7 @@ import { is, predicates } from "@sealcode/ts-predicates";
18
18
 
19
19
  export abstract class SealiousItemListPage<
20
20
  C extends Collection,
21
- F extends typeof BaseListPageFields
21
+ F extends typeof BaseListPageFields,
22
22
  > extends ListPage<CollectionItem<C>, F> {
23
23
  constructor(public collection: C) {
24
24
  super();
@@ -34,7 +34,7 @@ export type StateAndMetadata<State, Actions> =
34
34
 
35
35
  export type StatefulPageActionArgument<
36
36
  State extends Record<string, unknown>,
37
- Args extends unknown[] = unknown[]
37
+ Args extends unknown[] = unknown[],
38
38
  > = {
39
39
  ctx: Context;
40
40
  state: State;
@@ -45,19 +45,15 @@ export type StatefulPageActionArgument<
45
45
 
46
46
  export type StatefulPageAction<
47
47
  State extends Record<string, unknown>,
48
- Args extends unknown[] = unknown[]
48
+ Args extends unknown[] = unknown[],
49
49
  > = (obj: StatefulPageActionArgument<State, Args>) => State | Promise<State>;
50
50
 
51
- export type ExtractStatefulPageActionArgs<X> = X extends StatefulPageAction<
52
- any,
53
- infer Args
54
- >
55
- ? Args
56
- : never;
51
+ export type ExtractStatefulPageActionArgs<X> =
52
+ X extends StatefulPageAction<any, infer Args> ? Args : never;
57
53
 
58
54
  export abstract class StatefulPage<
59
55
  State extends Record<string, unknown>,
60
- Actions extends Record<string, StatefulPageAction<State>>
56
+ Actions extends Record<string, StatefulPageAction<State>>,
61
57
  > extends Mountable {
62
58
  abstract actions: Actions;
63
59
  abstract getInitialState(ctx: Context): State | Promise<State>;
@@ -104,7 +100,7 @@ export abstract class StatefulPage<
104
100
  state: State,
105
101
  content: Templatable
106
102
  ): Promise<Templatable> {
107
- return tempstream/* HTML */ `<form
103
+ return tempstream /* HTML */ `<form
108
104
  action="./"
109
105
  method="POST"
110
106
  enctype="multipart/form-data"
@@ -70,11 +70,11 @@ async function updatePackageJson(
70
70
  }
71
71
 
72
72
  const pathToAdd = `node_modules/${moduleName}/${subdirectory}`;
73
- const existingPaths = packageJson.sealgen[type] as string[];
73
+ const existingPaths = packageJson.sealgen[type];
74
74
 
75
75
  // Check if the path is already present
76
76
  if (existingPaths.includes(pathToAdd)) {
77
- console.log(`${type} already contains: ${pathToAdd}`);
77
+ console.warn(`${type} already contains: ${pathToAdd}`);
78
78
  return;
79
79
  }
80
80
 
@@ -88,11 +88,11 @@ async function updatePackageJson(
88
88
  );
89
89
 
90
90
  await fs.writeFile(packageJsonPath, updatedContent);
91
- console.log(`Added ${pathToAdd} to ${type} in ${packageJsonPath}`);
91
+ console.info(`Added ${pathToAdd} to ${type} in ${packageJsonPath}`);
92
92
  }
93
93
 
94
94
  export async function registerExternalControllers(
95
- args: Record<string, string | boolean>
95
+ _args: Record<string, string | boolean>
96
96
  ): Promise<void> {
97
97
  // Extract positional arguments from process.argv since yargs doesn't handle them for these commands
98
98
  const moduleName = process.argv.at(3);
@@ -120,7 +120,7 @@ export async function registerExternalControllers(
120
120
  }
121
121
 
122
122
  export async function registerExternalStyles(
123
- args: Record<string, string | boolean>
123
+ _args: Record<string, string | boolean>
124
124
  ): Promise<void> {
125
125
  // Extract positional arguments from process.argv since yargs doesn't handle them for these commands
126
126
  const moduleName = process.argv.at(3);
@@ -1,13 +1,11 @@
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
 
5
3
  const defaults = {
6
4
  postimport: `
7
5
  import { Fields } from "@sealcode/sealgen";
8
6
  import type {FormDataValue} from "@sealcode/sealgen";`,
9
7
  fields: `
10
- password: new Fields.SimpleFormField(true),`,
8
+ password: new Fields.Password(true),`,
11
9
  controls: `
12
10
  new Controls.SimpleInput(fields.password, {
13
11
  label: "Password:",
@@ -18,8 +16,8 @@ const defaults = {
18
16
  data: Record<string, FormDataValue>
19
17
  ): Promise<{ valid: boolean; error: string }> {
20
18
  // just a silly example, please remove this with better logic
21
- const { parsed: email } = await this.fields.email.getValue(ctx, data);
22
- const { parsed: password } = await this.fields.password.getValue(ctx, data);
19
+ const { parsed: email } = await this.fields.email.getParsedValue(ctx, data);
20
+ const { parsed: password } = await this.fields.password.getParsedValue(ctx, data);
23
21
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
24
22
  if ((password || "").length > ((email as string) || "").length) {
25
23
  return { valid: false, error: "Password cannot be longer than email" };
@@ -45,15 +43,13 @@ const defaults = {
45
43
 
46
44
  export async function formTemplate(
47
45
  action_name: string,
48
- newfilefullpath: string,
49
- _params: Partial<typeof defaults> & { success_message: string } = defaults
46
+ _params: Partial<typeof defaults> = defaults
50
47
  ): Promise<string> {
51
48
  const params = { ...defaults, ..._params };
52
- const rel = curryImportPath(newfilefullpath);
53
49
  const content = `import type { Context } from "koa";
54
50
  import type { FormData } from "@sealcode/sealgen";
55
51
  import { Form, Controls, fieldsToShape } from "@sealcode/sealgen";
56
- import html from "${rel("src/back/html.js")}";
52
+ import html from "src/back/html.js";
57
53
 
58
54
  ${params.postimport}
59
55
 
@@ -63,6 +59,8 @@ const fields = {
63
59
  ${params.fields}
64
60
  };
65
61
 
62
+ Form.initFieldNames(fields);
63
+
66
64
  export const ${action_name}Shape = fieldsToShape(fields);
67
65
 
68
66
  export default new (class ${action_name}Form extends Form<typeof fields, void> {
@@ -84,5 +82,5 @@ export default new (class ${action_name}Form extends Form<typeof fields, void> {
84
82
  ${params.render}
85
83
  })();
86
84
  `;
87
- return Prettier.format(content, await getPrettierConfig());
85
+ return formatWithPrettier(content);
88
86
  }
@@ -1,6 +1,6 @@
1
1
  import { toKebabCase, toPascalCase } from "js-convert-case";
2
2
 
3
- export function jddComponentTemplate(component_name: string) {
3
+ export async function jddComponentTemplate(component_name: string) {
4
4
  return `import { TempstreamJSX } from "tempstream";
5
5
  import type { ComponentToHTMLArgs } from "@sealcode/jdd";
6
6
  import { Component, ComponentArguments } from "@sealcode/jdd";
@@ -12,9 +12,7 @@ export async function jddEditorTemplate(actionName: string) {
12
12
  name: "collection",
13
13
  message:
14
14
  "Which sealious collection do you like to add CRUD forms for?",
15
- choices: (
16
- await listCollections()
17
- ).map((collection) => ({
15
+ choices: (await listCollections()).map((collection) => ({
18
16
  title: collection,
19
17
  value: collection,
20
18
  })),
@@ -30,7 +28,7 @@ export async function jddEditorTemplate(actionName: string) {
30
28
  let field_name = "";
31
29
  if (jdd_fields.length == 1) {
32
30
  field_name = jdd_fields[0].name;
33
- console.log(
31
+ console.info(
34
32
  `Only one field of type JDD found: ${field_name}, so skipping the question...`
35
33
  );
36
34
  } else if (jdd_fields.length > 1) {
@@ -1,4 +1,3 @@
1
- import _locreq from "locreq";
2
1
  import prompts from "prompts";
3
2
  import { listCollections } from "../utils/list-collections.js";
4
3
  import { formatWithPrettier } from "../utils/prettier.js";