@sealcode/sealgen 0.18.8 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. package/.eslintrc.cjs +7 -2
  2. package/.xunit +75 -0
  3. package/@types/add-crud.d.sync-conflict-20250918-184311-TFDLWFG.ts +1 -0
  4. package/@types/builders/colors-builder.d.sync-conflict-20250918-184323-TFDLWFG.ts +10 -0
  5. package/@types/builders/colors-builder.d.ts +1 -1
  6. package/@types/builders/fonts-builder.d.sync-conflict-20250918-184322-TFDLWFG.ts +7 -0
  7. package/@types/builders/fonts-builder.d.ts +1 -1
  8. package/@types/controllers/table-add-button.d.ts +6 -0
  9. package/@types/controllers/table-add-button.stimulus.d.ts +6 -0
  10. package/@types/crud-field-snippets.d.sync-conflict-20250918-184323-TFDLWFG.ts +1 -0
  11. package/@types/crud-field-snippets.d.ts +1 -3
  12. package/@types/forms/controls/array.d.sync-conflict-20250918-184306-TFDLWFG.ts +33 -0
  13. package/@types/forms/controls/array.d.ts +1 -2
  14. package/@types/forms/controls/array.sync-conflict-20250918-222045-TFDLWFG.d.ts +33 -0
  15. package/@types/forms/controls/autocomplete.d.sync-conflict-20250918-222042-TFDLWFG.ts +22 -0
  16. package/@types/forms/controls/autocomplete.d.ts +1 -1
  17. package/@types/forms/controls/checkbox-group.d.sync-conflict-20250918-184319-TFDLWFG.ts +21 -0
  18. package/@types/forms/controls/checkbox-group.d.ts +3 -3
  19. package/@types/forms/controls/checkboxed-list-input.d.sync-conflict-20250918-184323-TFDLWFG.ts +21 -0
  20. package/@types/forms/controls/checkboxed-list-input.d.ts +3 -3
  21. package/@types/forms/controls/controls.d.ts +2 -2
  22. package/@types/forms/controls/derived-frame.d.sync-conflict-20250918-184314-TFDLWFG.ts +19 -0
  23. package/@types/forms/controls/derived-frame.d.ts +0 -1
  24. package/@types/forms/controls/dropdown.d.sync-conflict-20250918-222044-TFDLWFG.ts +30 -0
  25. package/@types/forms/controls/dropdown.d.ts +1 -1
  26. package/@types/forms/controls/file.d.sync-conflict-20250918-222045-TFDLWFG.ts +13 -0
  27. package/@types/forms/controls/file.d.ts +1 -2
  28. package/@types/forms/controls/form-control.d.sync-conflict-20250918-184322-TFDLWFG.ts +19 -0
  29. package/@types/forms/controls/form-control.d.sync-conflict-20250918-222046-TFDLWFG.ts +19 -0
  30. package/@types/forms/controls/form-control.d.ts +7 -3
  31. package/@types/forms/controls/image.d.ts +19 -0
  32. package/@types/forms/controls/image.test.d.ts +1 -0
  33. package/@types/forms/controls/multiple-files.d.sync-conflict-20250918-184318-TFDLWFG.ts +42 -0
  34. package/@types/forms/controls/multiple-files.d.ts +3 -0
  35. package/@types/forms/controls/multiple-images.d.ts +19 -0
  36. package/@types/forms/controls/number.d.sync-conflict-20250918-222046-TFDLWFG.ts +13 -0
  37. package/@types/forms/controls/number.d.ts +1 -1
  38. package/@types/forms/controls/photo.d.sync-conflict-20250918-184321-TFDLWFG.ts +19 -0
  39. package/@types/forms/controls/photo.d.ts +3 -5
  40. package/@types/forms/controls/simple-input.d.sync-conflict-20250918-184310-TFDLWFG.ts +33 -0
  41. package/@types/forms/controls/simple-input.d.sync-conflict-20250918-222042-TFDLWFG.ts +33 -0
  42. package/@types/forms/controls/simple-input.d.ts +5 -4
  43. package/@types/forms/controls/simple-input.sync-conflict-20250918-222045-TFDLWFG.d.ts +33 -0
  44. package/@types/forms/controls/single-reference.d.ts +3 -2
  45. package/@types/forms/controls/table.d.sync-conflict-20250918-184302-TFDLWFG.ts +39 -0
  46. package/@types/forms/controls/table.d.ts +8 -2
  47. package/@types/forms/controls/table.sync-conflict-20250918-222042-TFDLWFG.d.ts +39 -0
  48. package/@types/forms/controls/textarea.d.sync-conflict-20250918-222045-TFDLWFG.ts +25 -0
  49. package/@types/forms/controls/textarea.d.ts +3 -3
  50. package/@types/forms/fields/boolean.d.sync-conflict-20250918-184325-TFDLWFG.ts +22 -0
  51. package/@types/forms/fields/boolean.d.ts +6 -1
  52. package/@types/forms/fields/boolean.sync-conflict-20250918-222042-TFDLWFG.d.ts +22 -0
  53. package/@types/forms/fields/checkboxed-list.d.sync-conflict-20250918-184325-TFDLWFG.ts +23 -0
  54. package/@types/forms/fields/checkboxed-list.d.ts +3 -1
  55. package/@types/forms/fields/collection-field.d.sync-conflict-20250918-184319-TFDLWFG.ts +22 -0
  56. package/@types/forms/fields/collection-field.d.sync-conflict-20250918-222047-TFDLWFG.ts +22 -0
  57. package/@types/forms/fields/collection-field.d.ts +8 -1
  58. package/@types/forms/fields/color.d.ts +4 -0
  59. package/@types/forms/fields/coordinates.d.sync-conflict-20250918-222044-TFDLWFG.ts +14 -0
  60. package/@types/forms/fields/coordinates.d.ts +14 -0
  61. package/@types/forms/fields/date.d.ts +13 -0
  62. package/@types/forms/fields/datetime.d.sync-conflict-20250918-222050-TFDLWFG.ts +4 -0
  63. package/@types/forms/fields/datetime.d.ts +14 -0
  64. package/@types/forms/fields/deep-reverse-single-reference-list.d.ts +24 -0
  65. package/@types/forms/fields/deep-reverse-single-reference-table.d.ts +16 -0
  66. package/@types/forms/fields/email.d.sync-conflict-20250918-184303-TFDLWFG.ts +8 -0
  67. package/@types/forms/fields/email.d.ts +3 -0
  68. package/@types/forms/fields/enum-multiple-sealious.d.ts +16 -0
  69. package/@types/forms/fields/enum-multiple-sealious.sync-conflict-20250918-222047-TFDLWFG.d.ts +16 -0
  70. package/@types/forms/fields/field.d.sync-conflict-20250918-184306-TFDLWFG.ts +70 -0
  71. package/@types/forms/fields/field.d.ts +37 -5
  72. package/@types/forms/fields/fields.d.sync-conflict-20250918-184314-TFDLWFG.ts +29 -0
  73. package/@types/forms/fields/fields.d.ts +23 -8
  74. package/@types/forms/fields/file.d.sync-conflict-20250918-184310-TFDLWFG.ts +23 -0
  75. package/@types/forms/fields/file.d.sync-conflict-20250918-222046-TFDLWFG.ts +23 -0
  76. package/@types/forms/fields/file.d.ts +11 -5
  77. package/@types/forms/fields/file.sync-conflict-20250918-222049-TFDLWFG.d.ts +23 -0
  78. package/@types/forms/fields/float.d.ts +4 -0
  79. package/@types/forms/fields/get-field-for-sealious.d.sync-conflict-20250918-222046-TFDLWFG.ts +29 -0
  80. package/@types/forms/fields/get-field-for-sealious.d.ts +31 -0
  81. package/@types/forms/fields/get-field-for-sealious.sync-conflict-20250918-222042-TFDLWFG.d.ts +29 -0
  82. package/@types/forms/fields/html.d.ts +6 -0
  83. package/@types/forms/fields/image.d.sync-conflict-20250918-222042-TFDLWFG.ts +5 -0
  84. package/@types/forms/fields/image.d.ts +5 -0
  85. package/@types/forms/fields/int.d.ts +6 -0
  86. package/@types/forms/fields/json.d.ts +13 -0
  87. package/@types/forms/fields/markdown.d.ts +6 -0
  88. package/@types/forms/fields/multiple-files.d.sync-conflict-20250918-184304-TFDLWFG.ts +16 -0
  89. package/@types/forms/fields/multiple-files.d.ts +3 -1
  90. package/@types/forms/fields/number.d.sync-conflict-20250918-184317-TFDLWFG.ts +25 -0
  91. package/@types/forms/fields/number.d.sync-conflict-20250918-222047-TFDLWFG.ts +25 -0
  92. package/@types/forms/fields/number.d.ts +3 -1
  93. package/@types/forms/fields/password.d.ts +6 -0
  94. package/@types/forms/fields/pick-from-list-sealious.d.ts +11 -0
  95. package/@types/forms/fields/pick-from-list.d.sync-conflict-20250918-184322-TFDLWFG.ts +15 -0
  96. package/@types/forms/fields/pick-from-list.d.ts +4 -3
  97. package/@types/forms/fields/proxy-field.d.sync-conflict-20250918-184307-TFDLWFG.ts +15 -0
  98. package/@types/forms/fields/proxy-field.d.ts +3 -1
  99. package/@types/forms/fields/regexp.d.sync-conflict-20250918-184305-TFDLWFG.ts +21 -0
  100. package/@types/forms/fields/regexp.d.sync-conflict-20250918-222045-TFDLWFG.ts +21 -0
  101. package/@types/forms/fields/regexp.d.ts +6 -1
  102. package/@types/forms/fields/regexp.sync-conflict-20250918-222047-TFDLWFG.d.ts +21 -0
  103. package/@types/forms/fields/simple-form-field.d.sync-conflict-20250918-184309-TFDLWFG.ts +29 -0
  104. package/@types/forms/fields/simple-form-field.d.sync-conflict-20250918-222044-TFDLWFG.ts +29 -0
  105. package/@types/forms/fields/simple-form-field.d.ts +23 -3
  106. package/@types/forms/fields/simple-form-field.sync-conflict-20250918-222049-TFDLWFG.d.ts +29 -0
  107. package/@types/forms/fields/single-reference.d.ts +19 -0
  108. package/@types/forms/fields/single-reference.sync-conflict-20250918-222043-TFDLWFG.d.ts +10 -0
  109. package/@types/forms/fields/structured-array.d.sync-conflict-20250918-184302-TFDLWFG.ts +27 -0
  110. package/@types/forms/fields/structured-array.d.sync-conflict-20250918-222049-TFDLWFG.ts +27 -0
  111. package/@types/forms/fields/structured-array.d.ts +19 -10
  112. package/@types/forms/fields/structured-array.sync-conflict-20250918-222047-TFDLWFG.d.ts +27 -0
  113. package/@types/forms/fields/table.d.sync-conflict-20250918-184303-TFDLWFG.ts +16 -0
  114. package/@types/forms/fields/table.d.ts +3 -0
  115. package/@types/forms/fields/text.d.ts +6 -0
  116. package/@types/forms/fields/url.d.ts +6 -0
  117. package/@types/forms/form-types.d.sync-conflict-20250918-222045-TFDLWFG.ts +26 -0
  118. package/@types/forms/form-types.d.ts +2 -0
  119. package/@types/forms/form.d.sync-conflict-20250918-184315-TFDLWFG.ts +32 -0
  120. package/@types/forms/form.d.sync-conflict-20250918-222049-TFDLWFG.ts +32 -0
  121. package/@types/forms/form.d.ts +10 -7
  122. package/@types/forms/form.sync-conflict-20250918-222049-TFDLWFG.d.ts +33 -0
  123. package/@types/forms/form.test.d.sync-conflict-20250918-184318-TFDLWFG.ts +6 -0
  124. package/@types/forms/form.test.d.sync-conflict-20250918-222047-TFDLWFG.ts +6 -0
  125. package/@types/forms/form.test.d.ts +2 -2
  126. package/@types/forms/multiform.d.sync-conflict-20250918-184308-TFDLWFG.ts +23 -0
  127. package/@types/forms/multiform.d.ts +1 -1
  128. package/@types/forms/multiform.sync-conflict-20250918-222044-TFDLWFG.d.ts +23 -0
  129. package/@types/index.d.sync-conflict-20250918-184316-TFDLWFG.ts +46 -0
  130. package/@types/index.d.ts +2 -2
  131. package/@types/mount.d.sync-conflict-20250918-184320-TFDLWFG.ts +6 -0
  132. package/@types/page/list.d.sync-conflict-20250918-184318-TFDLWFG.ts +48 -0
  133. package/@types/page/list.d.sync-conflict-20250918-222046-TFDLWFG.ts +48 -0
  134. package/@types/page/list.d.ts +2 -2
  135. package/@types/page/list.sync-conflict-20250918-222048-TFDLWFG.d.ts +48 -0
  136. package/@types/page/mountable-with-fields.d.sync-conflict-20250918-184321-TFDLWFG.ts +42 -0
  137. package/@types/page/mountable-with-fields.d.sync-conflict-20250918-222046-TFDLWFG.ts +42 -0
  138. package/@types/page/mountable-with-fields.d.ts +3 -3
  139. package/@types/page/mountable-with-fields.sync-conflict-20250918-222044-TFDLWFG.d.ts +42 -0
  140. package/@types/page/mountable.d.sync-conflict-20250918-184306-TFDLWFG.ts +10 -0
  141. package/@types/page/page.d.sync-conflict-20250918-184320-TFDLWFG.ts +18 -0
  142. package/@types/page/props-parser.d.sync-conflict-20250918-184305-TFDLWFG.ts +15 -0
  143. package/@types/page/props-parser.d.ts +0 -1
  144. package/@types/page/stateful-page.d.sync-conflict-20250918-184326-TFDLWFG.ts +62 -0
  145. package/@types/templates/shared/shared-crud-form-fields.d.sync-conflict-20250918-184306-TFDLWFG.ts +1 -0
  146. package/@types/templates/shared/shared-crud-form-fields.d.ts +0 -67
  147. package/@types/test_utils/test-on-real-app.d.sync-conflict-20250918-184320-TFDLWFG.ts +26 -0
  148. package/@types/test_utils/test-on-real-app.d.ts +0 -1
  149. package/@types/utils/extract-fields-from-collection.d.sync-conflict-20250918-184312-TFDLWFG.ts +18 -0
  150. package/@types/utils/extract-fields-from-collection.d.ts +5 -1
  151. package/@types/utils/extract-fields-from-collection.sync-conflict-20250918-222045-TFDLWFG.d.ts +18 -0
  152. package/@types/utils/wrap-attributes.d.ts +3 -0
  153. package/README.md +5 -0
  154. package/assets/file-icon.svg +5 -0
  155. package/lib/add-crud.js +80 -89
  156. package/lib/add-list-route.test.js +1 -1
  157. package/lib/add-route.js +0 -7
  158. package/lib/build.js +3 -1
  159. package/lib/cli.js +2 -5
  160. package/lib/controllers/table-add-button.stimulus.js +35 -0
  161. package/lib/forms/controls/array.js +20 -16
  162. package/lib/forms/controls/big-radio-group.js +2 -2
  163. package/lib/forms/controls/checkbox-group.js +7 -7
  164. package/lib/forms/controls/checkboxed-list-input.js +9 -2
  165. package/lib/forms/controls/controls.js +2 -2
  166. package/lib/forms/controls/derived-frame.js +5 -1
  167. package/lib/forms/controls/derived.js +1 -1
  168. package/lib/forms/controls/dropdown.js +4 -1
  169. package/lib/forms/controls/editable-collection-subset.js +2 -2
  170. package/lib/forms/controls/file.js +26 -2
  171. package/lib/forms/controls/file.test.js +2 -2
  172. package/lib/forms/controls/hidden-input.js +4 -1
  173. package/lib/forms/controls/{photo.js → image.js} +6 -7
  174. package/lib/forms/controls/{photo.test.js → image.test.js} +6 -21
  175. package/lib/forms/controls/multiple-files.js +10 -1
  176. package/lib/forms/controls/{multiple-photos.js → multiple-images.js} +3 -3
  177. package/lib/forms/controls/simple-input.js +13 -12
  178. package/lib/forms/controls/single-reference.js +4 -0
  179. package/lib/forms/controls/table.js +66 -24
  180. package/lib/forms/controls/textarea.js +4 -2
  181. package/lib/forms/controls/tickable.js +13 -5
  182. package/lib/forms/fields/boolean.js +14 -0
  183. package/lib/forms/fields/checkboxed-list.js +4 -0
  184. package/lib/forms/fields/collection-field.js +9 -0
  185. package/lib/forms/fields/color.js +10 -0
  186. package/lib/forms/fields/coordinates.js +49 -0
  187. package/lib/forms/fields/date.js +34 -0
  188. package/lib/forms/fields/datetime.js +46 -0
  189. package/lib/forms/fields/deep-reverse-single-reference-list.js +81 -0
  190. package/lib/forms/fields/deep-reverse-single-reference-table.js +122 -0
  191. package/lib/forms/fields/email.js +7 -0
  192. package/lib/forms/fields/enum-multiple-sealious.js +32 -0
  193. package/lib/forms/fields/field.js +32 -4
  194. package/lib/forms/fields/field.test.js +5 -5
  195. package/lib/forms/fields/fields.js +23 -8
  196. package/lib/forms/fields/file.js +33 -9
  197. package/lib/forms/fields/file.test.js +4 -16
  198. package/lib/forms/fields/float.js +10 -0
  199. package/lib/forms/fields/get-field-for-sealious.js +213 -0
  200. package/lib/forms/fields/html.js +14 -0
  201. package/lib/forms/fields/image.js +13 -0
  202. package/lib/forms/fields/int.js +23 -0
  203. package/lib/forms/fields/json.js +31 -0
  204. package/lib/forms/fields/markdown.js +14 -0
  205. package/lib/forms/fields/multiple-files.js +4 -0
  206. package/lib/forms/fields/number.js +6 -0
  207. package/lib/forms/fields/password.js +13 -0
  208. package/lib/forms/fields/pick-from-list-sealious.js +17 -0
  209. package/lib/forms/fields/pick-from-list.js +6 -2
  210. package/lib/forms/fields/proxy-field.js +3 -0
  211. package/lib/forms/fields/regexp.js +14 -0
  212. package/lib/forms/fields/simple-form-field.js +60 -2
  213. package/lib/forms/fields/single-reference.js +44 -0
  214. package/lib/forms/fields/structured-array.js +63 -12
  215. package/lib/forms/fields/table.js +28 -1
  216. package/lib/forms/fields/text.js +17 -0
  217. package/lib/forms/fields/url.js +17 -0
  218. package/lib/forms/form.js +30 -13
  219. package/lib/forms/form.test.js +3 -4
  220. package/lib/forms/multiform.js +4 -2
  221. package/lib/forms/multiform.test.js +3 -3
  222. package/lib/generate-stimulus.js +1 -0
  223. package/lib/index.js +1 -0
  224. package/lib/make-hidden-inputs.js +1 -1
  225. package/lib/mount.js +11 -0
  226. package/lib/notifier.js +0 -1
  227. package/lib/page/list.js +15 -8
  228. package/lib/page/mountable-with-fields.js +14 -6
  229. package/lib/page/mountable-with-fields.test.js +1 -1
  230. package/lib/templates/form.js +8 -9
  231. package/lib/templates/multiform.js +4 -4
  232. package/lib/templates/page.js +0 -2
  233. package/lib/templates/shared/collection-create-form.js +28 -40
  234. package/lib/templates/shared/collection-edit-form.js +40 -77
  235. package/lib/templates/shared/collection-list.js +12 -20
  236. package/lib/templates/shared/shared-crud-form-fields.js +27 -95
  237. package/lib/test_utils/test-on-real-app.js +3 -3
  238. package/lib/utils/extract-fields-from-collection.js +60 -20
  239. package/lib/utils/make-slug.js +1 -1
  240. package/lib/utils/wrap-attributes.js +20 -0
  241. package/package.json +5 -4
  242. package/src/add-crud.ts +86 -97
  243. package/src/add-list-route.test.ts +1 -1
  244. package/src/add-route.ts +0 -7
  245. package/src/build.ts +3 -1
  246. package/src/cli.ts +3 -5
  247. package/src/controllers/table-add-button.stimulus.ts +35 -0
  248. package/src/forms/controls/array.ts +23 -20
  249. package/src/forms/controls/autocomplete.ts +1 -1
  250. package/src/forms/controls/big-radio-group.ts +2 -2
  251. package/src/forms/controls/checkbox-group.ts +9 -9
  252. package/src/forms/controls/checkboxed-list-input.ts +27 -15
  253. package/src/forms/controls/controls.ts +2 -2
  254. package/src/forms/controls/derived-frame.ts +5 -1
  255. package/src/forms/controls/derived.ts +1 -1
  256. package/src/forms/controls/dropdown.ts +5 -2
  257. package/src/forms/controls/editable-collection-subset.ts +2 -2
  258. package/src/forms/controls/file.test.ts +4 -2
  259. package/src/forms/controls/file.ts +31 -5
  260. package/src/forms/controls/form-control.ts +7 -2
  261. package/src/forms/controls/hidden-input.ts +4 -1
  262. package/src/forms/controls/{photo.test.ts → image.test.ts} +5 -22
  263. package/src/forms/controls/{photo.ts → image.ts} +3 -5
  264. package/src/forms/controls/multiple-files.ts +18 -1
  265. package/src/forms/controls/{multiple-photos.ts → multiple-images.ts} +1 -1
  266. package/src/forms/controls/number.ts +1 -1
  267. package/src/forms/controls/simple-input.ts +18 -34
  268. package/src/forms/controls/single-reference.ts +10 -2
  269. package/src/forms/controls/table.ts +90 -31
  270. package/src/forms/controls/textarea.ts +6 -4
  271. package/src/forms/controls/tickable.ts +13 -5
  272. package/src/forms/fields/boolean.ts +23 -1
  273. package/src/forms/fields/checkboxed-list.ts +11 -2
  274. package/src/forms/fields/collection-field.ts +16 -1
  275. package/src/forms/fields/color.ts +9 -0
  276. package/src/forms/fields/coordinates.ts +66 -0
  277. package/src/forms/fields/date.ts +50 -0
  278. package/src/forms/fields/datetime.ts +66 -0
  279. package/src/forms/fields/deep-reverse-single-reference-list.ts +136 -0
  280. package/src/forms/fields/deep-reverse-single-reference-table.ts +213 -0
  281. package/src/forms/fields/email.ts +9 -0
  282. package/src/forms/fields/enum-multiple-sealious.ts +48 -0
  283. package/src/forms/fields/field.test.ts +5 -5
  284. package/src/forms/fields/field.ts +94 -8
  285. package/src/forms/fields/fields.ts +23 -8
  286. package/src/forms/fields/file.test.ts +4 -16
  287. package/src/forms/fields/file.ts +43 -15
  288. package/src/forms/fields/float.ts +9 -0
  289. package/src/forms/fields/get-field-for-sealious.ts +304 -0
  290. package/src/forms/fields/html.ts +15 -0
  291. package/src/forms/fields/image.ts +12 -0
  292. package/src/forms/fields/int.ts +25 -0
  293. package/src/forms/fields/json.ts +48 -0
  294. package/src/forms/fields/markdown.ts +15 -0
  295. package/src/forms/fields/multiple-files.ts +10 -1
  296. package/src/forms/fields/number.ts +8 -1
  297. package/src/forms/fields/password.ts +17 -0
  298. package/src/forms/fields/pick-from-list-sealious.ts +22 -0
  299. package/src/forms/fields/pick-from-list.ts +7 -3
  300. package/src/forms/fields/proxy-field.ts +6 -1
  301. package/src/forms/fields/regexp.ts +27 -1
  302. package/src/forms/fields/simple-form-field.ts +95 -7
  303. package/src/forms/fields/single-reference.ts +62 -0
  304. package/src/forms/fields/structured-array.ts +115 -18
  305. package/src/forms/fields/table.ts +32 -1
  306. package/src/forms/fields/text.ts +18 -0
  307. package/src/forms/fields/url.ts +20 -0
  308. package/src/forms/form-types.ts +2 -0
  309. package/src/forms/form.test.ts +3 -4
  310. package/src/forms/form.ts +37 -16
  311. package/src/forms/forms.css +0 -85
  312. package/src/forms/multiform.test.ts +3 -3
  313. package/src/forms/multiform.ts +2 -0
  314. package/src/generate-stimulus.ts +1 -0
  315. package/src/index.ts +2 -1
  316. package/src/make-hidden-inputs.ts +1 -1
  317. package/src/mount.ts +14 -0
  318. package/src/notifier.ts +0 -1
  319. package/src/page/list.ts +15 -8
  320. package/src/page/mountable-with-fields.test.ts +1 -1
  321. package/src/page/mountable-with-fields.ts +18 -9
  322. package/src/register-external.ts +1 -1
  323. package/src/templates/form.ts +8 -9
  324. package/src/templates/multiform.ts +4 -4
  325. package/src/templates/page.ts +0 -2
  326. package/src/templates/shared/collection-create-form.ts +30 -66
  327. package/src/templates/shared/collection-edit-form.ts +41 -102
  328. package/src/templates/shared/collection-list.ts +12 -20
  329. package/src/templates/shared/item-delete.ts +0 -1
  330. package/src/templates/shared/shared-crud-form-fields.ts +37 -171
  331. package/src/test_utils/test-on-real-app.ts +4 -3
  332. package/src/utils/extract-fields-from-collection.ts +76 -25
  333. package/src/utils/make-slug.ts +1 -1
  334. package/src/utils/wrap-attributes.ts +17 -0
  335. package/lib/add-verbose-crud.js +0 -119
  336. package/lib/crud-field-snippets.js +0 -52
  337. package/lib/find-css-includes.js +0 -3
  338. package/lib/forms/controls/reverse-single-reference.js +0 -1
  339. package/lib/forms/fields/enum-multiple.js +0 -47
  340. package/lib/forms/fields/enum-multiple.test.js +0 -27
  341. package/lib/forms/fields/enum.js +0 -41
  342. package/lib/forms/fields/enum.test.js +0 -21
  343. package/lib/forms/fields/reverse-single-reference.js +0 -17
  344. package/lib/templates/shared/handlers/boolean.js +0 -14
  345. package/lib/templates/shared/handlers/date.js +0 -8
  346. package/lib/templates/shared/handlers/deep-reverse-single-reference.js +0 -209
  347. package/lib/templates/shared/handlers/default.js +0 -49
  348. package/lib/templates/shared/handlers/enum.js +0 -19
  349. package/lib/templates/shared/handlers/file.js +0 -23
  350. package/lib/templates/shared/handlers/image.js +0 -32
  351. package/lib/templates/shared/handlers/int.js +0 -11
  352. package/lib/templates/shared/handlers/jdd.js +0 -10
  353. package/lib/templates/shared/handlers/single-reference.js +0 -12
  354. package/lib/templates/shared/handlers/structured-array.js +0 -33
  355. package/src/add-verbose-crud.ts +0 -138
  356. package/src/crud-field-snippets.ts +0 -57
  357. package/src/find-css-includes.ts +0 -3
  358. package/src/forms/controls/reverse-single-reference.ts +0 -50
  359. package/src/forms/fields/enum-multiple.test.ts +0 -31
  360. package/src/forms/fields/enum-multiple.ts +0 -62
  361. package/src/forms/fields/enum.test.ts +0 -25
  362. package/src/forms/fields/enum.ts +0 -56
  363. package/src/forms/fields/reverse-single-reference.ts +0 -20
  364. package/src/templates/shared/handlers/boolean.ts +0 -18
  365. package/src/templates/shared/handlers/date.ts +0 -12
  366. package/src/templates/shared/handlers/deep-reverse-single-reference.ts +0 -244
  367. package/src/templates/shared/handlers/default.ts +0 -64
  368. package/src/templates/shared/handlers/enum.ts +0 -23
  369. package/src/templates/shared/handlers/file.ts +0 -27
  370. package/src/templates/shared/handlers/image.ts +0 -45
  371. package/src/templates/shared/handlers/int.ts +0 -15
  372. package/src/templates/shared/handlers/jdd.ts +0 -14
  373. package/src/templates/shared/handlers/single-reference.ts +0 -16
  374. package/src/templates/shared/handlers/structured-array.ts +0 -42
@@ -3,15 +3,20 @@ import { exec } from "./utils.js";
3
3
  const target_locreq = _locreq(process.cwd());
4
4
  import { promises as fs } from "fs";
5
5
  import { is, predicates } from "@sealcode/ts-predicates";
6
+ import { sealiousFieldInfoToFormField } from "../forms/fields/get-field-for-sealious.js";
6
7
  const counter = function* () {
7
8
  let i = 0;
8
9
  while (true) {
9
10
  yield i++;
10
11
  }
11
12
  }();
13
+ const cache = {};
12
14
  async function extract_fields_from_collection(collection_name) {
15
+ if (cache[collection_name]) {
16
+ return cache[collection_name];
17
+ }
13
18
  const extractor_code = `import {default as the_app} from "./app.js";
14
- const c = new the_app().collections["${collection_name}"];
19
+ const c = new the_app({}).collections["${collection_name}"];
15
20
  const fields = [];
16
21
  for (const field_name in c.fields){
17
22
  let field = c.fields[field_name];
@@ -21,14 +26,17 @@ for (const field_name in c.fields){
21
26
  let referencing_field = null;
22
27
  let intermediary_field_that_points_there = null;
23
28
  let is_readonly = false;
24
- let is_required = field.required;
29
+ let is_required = field.required || false;
25
30
  let subfields = [];
26
- if(["derived-value", "cached-value", "settable-by"].includes(type)){
31
+ if(["derived-value", "cached-value", "settable-by", "control-access"].includes(type)){
27
32
  type = field.virtual_field.typeName;
28
33
  }
29
34
  if(["derived-value", "cached-value", "reverse-single-reference"].includes(field.typeName)){
30
35
  is_readonly = true;
31
36
  }
37
+ if(type == "single-reference"){
38
+ target = field.target_collection;
39
+ }
32
40
  if(type == "deep-reverse-single-reference" || type =="reverse-single-reference"){
33
41
  target = field.target_collection;
34
42
  referencing_collection = field.referencing_collection;
@@ -46,24 +54,56 @@ for (const field_name in c.fields){
46
54
  `dist/back/___extract_fields--${counter.next().value || 0}.js`
47
55
  );
48
56
  await fs.writeFile(extractor_code_path, extractor_code);
49
- const { stdout } = await exec("node", [extractor_code_path]);
50
- await fs.unlink(extractor_code_path);
51
- const ret = JSON.parse(stdout);
52
- if (!is(
53
- ret,
54
- predicates.array(
55
- predicates.shape({
56
- name: predicates.string,
57
- type: predicates.string,
58
- is_readonly: predicates.boolean
59
- })
60
- )
61
- )) {
62
- throw new Error(
63
- "Encountered a problem while extracting the names of fields from collection. Got: " + stdout
57
+ const result = exec("node", [extractor_code_path]).then(async ({ stdout }) => {
58
+ await fs.unlink(extractor_code_path);
59
+ const ret = JSON.parse(stdout);
60
+ if (!is(
61
+ ret,
62
+ predicates.array(
63
+ predicates.shape({
64
+ name: predicates.string,
65
+ type: predicates.string,
66
+ is_readonly: predicates.boolean,
67
+ target: predicates.or(
68
+ predicates.string,
69
+ predicates.null
70
+ ),
71
+ referencing_collection: predicates.or(
72
+ predicates.string,
73
+ predicates.null
74
+ ),
75
+ referencing_field: predicates.or(
76
+ predicates.string,
77
+ predicates.null
78
+ ),
79
+ is_required: predicates.boolean,
80
+ intermediary_field_that_points_there: predicates.or(
81
+ predicates.string,
82
+ predicates.null
83
+ ),
84
+ subfields: predicates.array(
85
+ predicates.shape({ name: predicates.string })
86
+ )
87
+ })
88
+ )
89
+ )) {
90
+ throw new Error(
91
+ "Encountered a problem while extracting the names of fields from collection. Got: " + stdout
92
+ );
93
+ }
94
+ const result2 = await Promise.all(
95
+ ret.map(async (field_info) => ({
96
+ ...field_info,
97
+ form_field: await sealiousFieldInfoToFormField(field_info)
98
+ }))
64
99
  );
65
- }
66
- return ret;
100
+ return result2;
101
+ }).catch((e) => {
102
+ console.error("ERROR", e);
103
+ process.exit(1);
104
+ });
105
+ cache[collection_name] = result;
106
+ return result;
67
107
  }
68
108
  export {
69
109
  extract_fields_from_collection as default
@@ -1,5 +1,5 @@
1
1
  function makeSlug(t) {
2
- return t.replaceAll(/\P{General_Category=Letter}/g, "-").replaceAll(/-+/g, "-");
2
+ return t.replaceAll(/\P{General_Category=Letter}/gu, "-").replaceAll(/-+/g, "-");
3
3
  }
4
4
  export {
5
5
  makeSlug
@@ -0,0 +1,20 @@
1
+ function needsQuotes(str) {
2
+ try {
3
+ new Function(`var obj = { ${str}: 1 };`);
4
+ return false;
5
+ } catch {
6
+ return true;
7
+ }
8
+ }
9
+ function wrapAttribute(name) {
10
+ return needsQuotes(name) ? `["${name}"]` : `.${name}`;
11
+ }
12
+ function wrapKeyName(name) {
13
+ return needsQuotes(name) ? `["${name}"]` : `${name}`;
14
+ }
15
+ export {
16
+ needsQuotes,
17
+ wrapAttribute,
18
+ wrapKeyName
19
+ };
20
+ //# sourceMappingURL=wrap-attributes.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.18.8",
3
+ "version": "0.19.0",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -55,10 +55,10 @@
55
55
  "playwright": "^1.29.2",
56
56
  "source-map-support": "^0.5.21",
57
57
  "ts-node": "^10.9.1",
58
- "typescript": "^4.7",
58
+ "typescript": "5.9",
59
59
  "wait-port": "^1.0.4"
60
60
  },
61
- "types": "./@types/src/index.d.ts",
61
+ "types": "./@types/index.d.ts",
62
62
  "dependencies": {
63
63
  "@koa/router": "^12.0.1",
64
64
  "@sealcode/file-manager": "^1.0.2",
@@ -90,6 +90,7 @@
90
90
  "peerDependencies": {
91
91
  "koa": "^2.13.0",
92
92
  "koa-responsive-image-router": "^0.2.24",
93
- "sealious": "^0.21"
93
+ "sealious": "^0.21",
94
+ "stimulus": "^3.2.2"
94
95
  }
95
96
  }
package/src/add-crud.ts CHANGED
@@ -1,19 +1,16 @@
1
1
  import _locreq from "locreq";
2
- import prompts from "prompts";
3
-
4
2
  import { escape_url_params } from "./utils/escape-url-params.js";
3
+ import prompts from "prompts";
5
4
  import { toKebabCase, toPascalCase } from "js-convert-case";
6
5
  import { listCollections } from "./utils/list-collections.js";
7
- import {
8
- makeDefaultDisplayFields,
9
- makeDefaultFilterFields,
10
- } from "./templates/shared/collection-list.js";
6
+ import { collectionListTemplate } from "./templates/shared/collection-list.js";
11
7
  import { writeFile } from "./utils/write-file.js";
12
- import { extractCollectionClassname } from "./generate-collections.js";
13
- import extract_fields_from_collection from "./utils/extract-fields-from-collection.js";
14
- import { getFieldHandler } from "./templates/shared/shared-crud-form-fields.js";
8
+ import { curryImportPath, importPath } from "./utils/import-path.js";
9
+ import { sharedCrudFormFields } from "./templates/shared/shared-crud-form-fields.js";
15
10
  import { generateRoutes } from "./generate-routes.js";
16
- import { formatWithPrettier } from "./utils/prettier.js";
11
+ import { createItemFormTemplate } from "./templates/shared/collection-create-form.js";
12
+ import { editItemFormTemplate } from "./templates/shared/collection-edit-form.js";
13
+ import { itemDeleteTemplate } from "./templates/shared/item-delete.js";
17
14
 
18
15
  export async function addCRUD(
19
16
  params: Partial<{ [key in "collection" | "url"]: string }>,
@@ -38,7 +35,7 @@ export async function addCRUD(
38
35
  type: "text",
39
36
  name: "url",
40
37
  message:
41
- "Enter a full absolute path for the new route (for example: /admin/users/): ",
38
+ "Enter a full absolute path for the new route (for example: /admin/users/:id/edit): ",
42
39
  validate: (s: string) =>
43
40
  s.trim()[0] == "/" ? true : "Should start with a '/'",
44
41
  initial: function (_, { collection }: { collection: string }) {
@@ -46,103 +43,95 @@ export async function addCRUD(
46
43
  },
47
44
  },
48
45
  ]);
49
-
50
46
  const collection_name = response.collection as string;
51
47
  const url = response.url as string;
48
+ const list_action_name = toPascalCase(collection_name) + "CRUDList";
49
+ const create_action_name = toPascalCase(collection_name) + "CRUDCreate";
50
+ const edit_action_name = toPascalCase(collection_name) + "CRUDEdit";
51
+ const delete_action_name = toPascalCase(collection_name) + "CRUDDelete";
52
52
 
53
53
  /* create the list endpoint */
54
54
  const list_path = target_locreq.resolve(
55
- `src/back/routes/${escape_url_params(url)}/index.page.ts`
55
+ `src/back/routes/${escape_url_params(url)}/index.list.tsx`
56
56
  );
57
- const [uppercase_collection, collection_fields] = await Promise.all([
58
- extractCollectionClassname(
59
- target_locreq.resolve(
60
- "src/back/collections/" + collection_name + ".ts"
61
- )
62
- ),
63
- extract_fields_from_collection(collection_name),
64
- ]);
65
-
66
- const field_handler_results = await Promise.all(
67
- collection_fields.map(async (field) => {
68
- return getFieldHandler(
69
- collection_name,
70
- field,
71
- (p) => p,
72
- "edit_fields"
73
- );
74
- })
57
+ const list_content = await collectionListTemplate(
58
+ collection_name,
59
+ list_action_name,
60
+ list_path,
61
+ {
62
+ post_import_js: `import { ${create_action_name}URL, ${edit_action_name}URL, ${delete_action_name}URL } from "${importPath(
63
+ list_path,
64
+ "src/back/routes/urls.ts"
65
+ )}";`,
66
+ post_header_html: `<a href={${create_action_name}URL}> Create </a>`,
67
+ render_item: (
68
+ collection_name: string
69
+ ) => ` async renderItem(ctx: Context, item: CollectionItem<typeof ${toPascalCase(
70
+ collection_name
71
+ )}>) {
72
+ return <tr>
73
+ {displayFields.map(({ field, format }) => {
74
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
75
+ const value = item.get(field as any);
76
+ return <td>{format ? format(value, item) : value}</td>;
77
+ })}
78
+ <td><div class="sealious-list__actions">
79
+ <a href={${edit_action_name}URL(item.id)}>Edit</a>
80
+ <a data-turbo-method="POST" data-turbo-confirm="Delete item?" href={${delete_action_name}URL(item.id)}>Delete</a>
81
+ </div>
82
+ </td>
83
+ </tr>;
84
+ }`,
85
+ }
75
86
  );
87
+ await writeFile(list_path, list_content);
76
88
 
77
- const list_content = `import { CRUD } from "@sealcode/crud-ui";
78
- import type { CollectionItem } from "sealious";
79
- import type { ListFilterRender } from "@sealcode/sealgen";
80
- import { Controls, DefaultListFilters, Fields } from "@sealcode/sealgen";
81
- import { ${toPascalCase(
82
- collection_name
83
- )} } from "src/back/collections/collections.js";
84
- import html from "src/back/html.js";
85
-
86
- export const actionName = "${toPascalCase(collection_name)}CRUD";
87
-
88
- const edit_fields = <const>
89
- {
90
- ${field_handler_results
91
- .filter(({ hide_field }) => !hide_field)
92
- .map(({ field }) => field)
93
- .filter((e) => e != "")
94
- .join(",\n")}
95
- };
96
-
97
-
98
- const edit_controls = [
99
- ${field_handler_results
100
- .filter(({ hide_control }) => !hide_control)
101
- .map(({ controls }) => controls)
102
- .filter((e) => e != "")
103
- .join(",\n")}
104
- ]
89
+ /* create the shared fields file */
90
+ const fields_path = target_locreq.resolve(
91
+ `src/back/routes/${escape_url_params(url)}/shared.ts`
92
+ );
93
+ const fields_content = await sharedCrudFormFields(
94
+ collection_name,
95
+ fields_path
96
+ );
97
+ await writeFile(fields_path, fields_content);
105
98
 
106
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
107
- const fields_for_display = [
108
- ${makeDefaultDisplayFields(collection_fields)}
109
- ] as {
110
- field: keyof (typeof ${toPascalCase(collection_name)})["fields"];
111
- label: string;
112
- format?: (value: unknown, item: CollectionItem<typeof ${toPascalCase(
113
- collection_name
114
- )}>) => string | Promise<string>;
115
- }[];
99
+ /* create the create endpoint */
100
+ const create_path = target_locreq.resolve(
101
+ `src/back/routes/${escape_url_params(url)}/create.form.ts`
102
+ );
103
+ const create_content = await createItemFormTemplate(
104
+ create_action_name,
105
+ create_path,
106
+ collection_name,
107
+ list_action_name
108
+ );
109
+ await writeFile(create_path, create_content);
116
110
 
117
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
118
- const fields_for_filters = [
119
- ${makeDefaultFilterFields(collection_fields)}
120
- ] as {
121
- field: keyof (typeof ${uppercase_collection})["fields"];
122
- render?: ListFilterRender;
123
- prepareValue?: (filter_value: unknown)=>unknown; // set this function to change what filter value is passed to Sealious
124
- }[];
111
+ /* create the edit endpoint */
112
+ const edit_path = target_locreq.resolve(
113
+ `src/back/routes/${escape_url_params(url)}/[id]/edit.form.ts`
114
+ );
115
+ const edit_content = await editItemFormTemplate(
116
+ edit_action_name,
117
+ edit_path,
118
+ collection_name,
119
+ list_action_name
120
+ );
121
+ await writeFile(edit_path, edit_content);
125
122
 
126
- export default new CRUD({
127
- collection: ${toPascalCase(collection_name)},
128
- nice_collection_name: "${toPascalCase(collection_name)}",
129
- fields_for_display,
130
- fields_for_filters,
131
- html,
132
- list_title: "${toPascalCase(collection_name)} list",
133
- edit_title: "Edit",
134
- edit_button_text: "Edit",
135
- delete_button_text: "Delete",
136
- back_to_list_button_text: "← Back to ${toPascalCase(collection_name)} list",
137
- edit_fields,
138
- edit_controls,
139
- form_value_to_sealious_value: {},
140
- sealious_value_to_form_value: {},
141
- post_edit: async () => {},
142
- post_create: async () => {},
143
- });
144
- `;
145
- await writeFile(list_path, await formatWithPrettier(list_content));
123
+ /* create the actual delete endpoint */
124
+ const delete_path = target_locreq.resolve(
125
+ `src/back/routes/${escape_url_params(url)}/[id]/delete.page.tsx`
126
+ );
127
+ const base_import_path = curryImportPath(delete_path);
128
+ const delete_content = await itemDeleteTemplate(
129
+ delete_action_name,
130
+ collection_name,
131
+ list_action_name,
132
+ base_import_path
133
+ );
134
+ await writeFile(delete_path, delete_content);
146
135
 
147
136
  await generateRoutes();
148
137
  }
@@ -4,7 +4,7 @@ import { RealAppTest } from "./test_utils/test-on-real-app.js";
4
4
  import { collectionTemplate } from "./templates/collection.js";
5
5
  import assert from "node:assert";
6
6
 
7
- describe("single-reference.test", () => {
7
+ describe("single-reference", () => {
8
8
  let page: Page;
9
9
  before(async () => {
10
10
  const browser = await getBrowser();
package/src/add-route.ts CHANGED
@@ -2,7 +2,6 @@ import { existsSync, promises as fs } from "fs";
2
2
  import _locreq from "locreq";
3
3
  import { resolve } from "path";
4
4
  import { generateRoutes } from "./generate-routes.js";
5
- import { testTemplate } from "./templates/route-test.js";
6
5
  import { escape_url_params } from "./utils/escape-url-params.js";
7
6
  import prompts from "prompts";
8
7
  import { Templates } from "./templates/templates.js";
@@ -81,12 +80,6 @@ export async function addRoute(
81
80
  }
82
81
  await fs.mkdir(resolve(file_path, "../"), { recursive: true });
83
82
  await fs.writeFile(file_path, await template(action, file_path));
84
- if (mode !== "lpr" && mode !== "jdd-editor") {
85
- await fs.writeFile(
86
- test_file_path,
87
- await testTemplate(action, file_path)
88
- );
89
- }
90
83
  // eslint-disable-next-line no-console
91
84
  console.log(`${file_path} created`);
92
85
  // eslint-disable-next-line no-console
package/src/build.ts CHANGED
@@ -94,7 +94,9 @@ async function build(watch: boolean): Promise<void> {
94
94
  ];
95
95
  await Promise.all(builders.map((b) => b.build()));
96
96
  if (watch) {
97
- const watcher = chokidar.watch("src", { ignoreInitial: true });
97
+ const watcher = chokidar.watch(["src", ...controller_dirs], {
98
+ ignoreInitial: true,
99
+ });
98
100
  const port = await get_notifier_port();
99
101
  const notifier = make_notifier(port, 8080); // TODO: parse the app config to get the actual port
100
102
  await write_notifier_config(watch, port);
package/src/cli.ts CHANGED
@@ -1,17 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import yargs from "yargs/yargs";
3
3
  import { addCollection } from "./add-collection.js";
4
- import { addCRUD } from "./add-crud.js";
5
4
  import { addJDDComponent } from "./add-jdd-component.js";
6
5
  import { addRoute } from "./add-route.js";
7
- import { addVerboseCRUD } from "./add-verbose-crud.js";
6
+ import { addCRUD } from "./add-crud.js";
8
7
  import { buildProject } from "./build.js";
9
8
  import { generateCollections } from "./generate-collections.js";
10
9
  import { generateComponents } from "./generate-components.js";
11
10
  import { generateRoutes } from "./generate-routes.js";
12
11
  import { getFonts } from "./get-fonts.js";
13
12
  import { makeEnv } from "./make-env.js";
14
- import { crudFieldSnippets } from "./crud-field-snippets.js";
13
+
15
14
  import {
16
15
  registerExternalControllers,
17
16
  registerExternalStyles,
@@ -23,7 +22,6 @@ const actions: Record<
23
22
  > = {
24
23
  "add-collection": addCollection,
25
24
  "add-route": addRoute,
26
- "add-verbose-crud": addVerboseCRUD,
27
25
  "add-crud": addCRUD,
28
26
  "generate-collections": generateCollections,
29
27
  "generate-components": generateComponents,
@@ -40,7 +38,7 @@ const actions: Record<
40
38
  "make-env": makeEnv,
41
39
  "add-component": addJDDComponent,
42
40
  "get-fonts": getFonts,
43
- "crud-field-snippets": crudFieldSnippets,
41
+ // "crud-field-snippets": crudFieldSnippets,
44
42
  "register-external-controllers": registerExternalControllers,
45
43
  "register-external-styles": registerExternalStyles,
46
44
  };
@@ -0,0 +1,35 @@
1
+ /// <reference lib="dom" />
2
+ import { Controller } from "stimulus";
3
+
4
+ export default class extends Controller {
5
+ static targets = ["textarea"];
6
+ defaultRowsNumber = 20;
7
+
8
+ addRow() {
9
+ const template = this.element
10
+ .closest("turbo-frame")
11
+ ?.querySelector("template");
12
+ if (!template) {
13
+ throw new Error("Couldn't find template");
14
+ }
15
+ const tbody = this.element
16
+ .closest("turbo-frame")
17
+ ?.querySelector("tbody");
18
+ if (!tbody) {
19
+ throw new Error("tbody not found");
20
+ }
21
+
22
+ const orig_template = template.innerHTML;
23
+ const placeholder = this.element.getAttribute("data-table-placeholder");
24
+ if (!placeholder) {
25
+ throw new Error("Could find placeholder attribute");
26
+ }
27
+ template.innerHTML = orig_template.replaceAll(
28
+ placeholder,
29
+ String(tbody.querySelectorAll("tr").length)
30
+ );
31
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
32
+ tbody.appendChild((template.cloneNode(true) as any).content);
33
+ template.innerHTML = orig_template;
34
+ }
35
+ }
@@ -6,8 +6,8 @@ import qs from "qs";
6
6
  import { Field, FieldsetOutput } from "sealious";
7
7
  import { tempstream } from "tempstream";
8
8
  import { FormField } from "../fields/field.js";
9
- import { SimpleFormField } from "../fields/simple-form-field.js";
10
- import { StructuredArrayField } from "../fields/structured-array.js";
9
+ import { TextBasedSimpleField } from "../fields/simple-form-field.js";
10
+ import { StructuredArray as StructuredArrayField } from "../fields/structured-array.js";
11
11
  import { FormDataValue } from "../form-types.js";
12
12
  import { Derived } from "./derived.js";
13
13
  import { FormControl, FormControlContext } from "./form-control.js";
@@ -58,7 +58,7 @@ export class StructuredArray<
58
58
  }
59
59
 
60
60
  makeSubfield(_field_name: string): FormField {
61
- return new SimpleFormField(false);
61
+ return new TextBasedSimpleField(false);
62
62
  }
63
63
 
64
64
  async renderItemControl(
@@ -70,12 +70,12 @@ export class StructuredArray<
70
70
  ) {
71
71
  const fctx = {
72
72
  ctx,
73
- data: {},
73
+ data: { raw_values: {}, messages: [], field_messages: {} },
74
74
  messages: [],
75
75
  field_name_prefix: "",
76
76
  form_id,
77
77
  validate: false,
78
- };
78
+ } as FormControlContext;
79
79
  if (Array.isArray(control)) {
80
80
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
81
81
  const [constructor, field_name, params] = control;
@@ -86,9 +86,7 @@ export class StructuredArray<
86
86
  );
87
87
  return "";
88
88
  }
89
- await field.init(
90
- `${this.field.name}[data][${index}][${field_name}]`
91
- );
89
+ field.setName(`${this.field.name}[data][${index}][${field_name}]`);
92
90
  const hidden_shadow = new Derived(
93
91
  [field],
94
92
  async (
@@ -107,10 +105,22 @@ export class StructuredArray<
107
105
  );
108
106
  return tempstream`${new constructor(field, params).render({
109
107
  ...fctx,
110
- data: { [field.name]: item[field_name] as FormDataValue },
108
+ data: {
109
+ raw_values: {
110
+ [field.name]: item[field_name] as FormDataValue,
111
+ },
112
+ messages: [],
113
+ field_messages: {},
114
+ },
111
115
  })}${hidden_shadow.render({
112
116
  ...fctx,
113
- data: { [field.name]: item[field_name] as FormDataValue },
117
+ data: {
118
+ raw_values: {
119
+ [field.name]: item[field_name] as FormDataValue,
120
+ },
121
+ messages: [],
122
+ field_messages: {},
123
+ },
114
124
  form_id: this.getInnerFormID(),
115
125
  })}`;
116
126
  } else {
@@ -140,9 +150,8 @@ export class StructuredArray<
140
150
  }
141
151
 
142
152
  async getItems(ctx: Context, raw_values: Record<string, FormDataValue>) {
143
- return (await this.field.getValue(ctx, raw_values)).parsed as Promise<
144
- FieldsetOutput<Subfields>[]
145
- >;
153
+ return (await this.field.getParsedValue(ctx, raw_values))
154
+ .parsed as FieldsetOutput<Subfields>[];
146
155
  }
147
156
 
148
157
  async _render(
@@ -170,7 +179,7 @@ export class StructuredArray<
170
179
  }
171
180
 
172
181
  render(fctx: FormControlContext) {
173
- return this._render(fctx.ctx, fctx.form_id, fctx.data);
182
+ return this._render(fctx.ctx, fctx.form_id, fctx.data.raw_values);
174
183
  }
175
184
 
176
185
  async getTargetItemID(ctx: Context): Promise<string> {
@@ -179,7 +188,6 @@ export class StructuredArray<
179
188
  }
180
189
 
181
190
  mount(router: Router) {
182
- console.log("mounting!", this.getActionURL());
183
191
  router.post(this.getActionURL(), async (ctx) => {
184
192
  const form_id = ctx.query.form_id;
185
193
  if (typeof form_id != "string") {
@@ -198,7 +206,6 @@ export class StructuredArray<
198
206
  const field_data = (ctx.$body as Record<string, unknown>)[
199
207
  this.field.name
200
208
  ] || { data: [] };
201
- console.log({ action: field_data });
202
209
  if (
203
210
  !hasShape(
204
211
  {
@@ -215,10 +222,6 @@ export class StructuredArray<
215
222
  ...ctx.$body.action,
216
223
  data: field_data.data || [],
217
224
  });
218
- console.log("ACTION", {
219
- ...ctx.$body.action,
220
- data: field_data.data || [],
221
- });
222
225
  await item.save(ctx.$context);
223
226
  console.log(await item.getDecodedBody(ctx.$context, {}));
224
227
  ctx.body = this._render(
@@ -4,7 +4,7 @@ import { PickFromListField } from "../fields/pick-from-list.js";
4
4
  import { FormControlContext } from "./form-control.js";
5
5
  import { SimpleInput } from "./simple-input.js";
6
6
 
7
- export class Autocomplete extends SimpleInput<string | null> {
7
+ export class Autocomplete extends SimpleInput {
8
8
  constructor(
9
9
  public field: PickFromListField<boolean>,
10
10
  public options: { id?: string; label?: string; placeholder?: string }
@@ -19,9 +19,9 @@ export class BigRadioGroup extends FormFieldControl {
19
19
  }
20
20
 
21
21
  async render(fctx: FormControlContext): Promise<FlatTemplatable> {
22
- const { raw: current_value } = await this.field.getValue(
22
+ const { raw: current_value } = await this.field.getParsedValue(
23
23
  fctx.ctx,
24
- fctx.data
24
+ fctx.data.raw_values
25
25
  );
26
26
  return tempstream/* HTML */ `<div class="bigradios">
27
27
  ${Object.entries(this.options).map(([key, { description }]) => {