@sealcode/sealgen 0.18.10 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/.eslintrc.cjs +7 -2
  2. package/.xunit +74 -69
  3. package/@types/add-crud.d.sync-conflict-20250918-184311-TFDLWFG.ts +1 -0
  4. package/@types/builders/colors-builder.d.sync-conflict-20250918-184323-TFDLWFG.ts +10 -0
  5. package/@types/builders/colors-builder.d.ts +1 -1
  6. package/@types/builders/fonts-builder.d.sync-conflict-20250918-184322-TFDLWFG.ts +7 -0
  7. package/@types/builders/fonts-builder.d.ts +1 -1
  8. package/@types/controllers/table-add-button.d.ts +6 -0
  9. package/@types/controllers/table-add-button.stimulus.d.ts +6 -0
  10. package/@types/crud-field-snippets.d.sync-conflict-20250918-184323-TFDLWFG.ts +1 -0
  11. package/@types/crud-field-snippets.d.ts +1 -3
  12. package/@types/forms/controls/array.d.sync-conflict-20250918-184306-TFDLWFG.ts +33 -0
  13. package/@types/forms/controls/array.d.ts +1 -3
  14. package/@types/forms/controls/array.sync-conflict-20250918-222045-TFDLWFG.d.ts +33 -0
  15. package/@types/forms/controls/autocomplete.d.sync-conflict-20250918-222042-TFDLWFG.ts +22 -0
  16. package/@types/forms/controls/autocomplete.d.ts +1 -1
  17. package/@types/forms/controls/checkbox-group.d.sync-conflict-20250918-184319-TFDLWFG.ts +21 -0
  18. package/@types/forms/controls/checkbox-group.d.ts +3 -3
  19. package/@types/forms/controls/checkboxed-list-input.d.sync-conflict-20250918-184323-TFDLWFG.ts +21 -0
  20. package/@types/forms/controls/checkboxed-list-input.d.ts +3 -3
  21. package/@types/forms/controls/controls.d.ts +2 -2
  22. package/@types/forms/controls/derived-frame.d.sync-conflict-20250918-184314-TFDLWFG.ts +19 -0
  23. package/@types/forms/controls/derived-frame.d.ts +0 -2
  24. package/@types/forms/controls/dropdown.d.sync-conflict-20250918-222044-TFDLWFG.ts +30 -0
  25. package/@types/forms/controls/dropdown.d.ts +1 -1
  26. package/@types/forms/controls/file.d.sync-conflict-20250918-222045-TFDLWFG.ts +13 -0
  27. package/@types/forms/controls/file.d.ts +1 -2
  28. package/@types/forms/controls/form-control.d.sync-conflict-20250918-184322-TFDLWFG.ts +19 -0
  29. package/@types/forms/controls/form-control.d.sync-conflict-20250918-222046-TFDLWFG.ts +19 -0
  30. package/@types/forms/controls/form-control.d.ts +7 -4
  31. package/@types/forms/controls/image.d.ts +19 -0
  32. package/@types/forms/controls/image.test.d.ts +1 -0
  33. package/@types/forms/controls/multiple-files.d.sync-conflict-20250918-184318-TFDLWFG.ts +42 -0
  34. package/@types/forms/controls/multiple-files.d.ts +3 -1
  35. package/@types/forms/controls/multiple-images.d.ts +19 -0
  36. package/@types/forms/controls/number.d.sync-conflict-20250918-222046-TFDLWFG.ts +13 -0
  37. package/@types/forms/controls/number.d.ts +1 -1
  38. package/@types/forms/controls/photo.d.sync-conflict-20250918-184321-TFDLWFG.ts +19 -0
  39. package/@types/forms/controls/photo.d.ts +3 -5
  40. package/@types/forms/controls/simple-input.d.sync-conflict-20250918-184310-TFDLWFG.ts +33 -0
  41. package/@types/forms/controls/simple-input.d.sync-conflict-20250918-222042-TFDLWFG.ts +33 -0
  42. package/@types/forms/controls/simple-input.d.ts +5 -4
  43. package/@types/forms/controls/simple-input.sync-conflict-20250918-222045-TFDLWFG.d.ts +33 -0
  44. package/@types/forms/controls/single-reference.d.ts +3 -2
  45. package/@types/forms/controls/table.d.sync-conflict-20250918-184302-TFDLWFG.ts +39 -0
  46. package/@types/forms/controls/table.d.ts +8 -3
  47. package/@types/forms/controls/table.sync-conflict-20250918-222042-TFDLWFG.d.ts +39 -0
  48. package/@types/forms/controls/textarea.d.sync-conflict-20250918-222045-TFDLWFG.ts +25 -0
  49. package/@types/forms/controls/textarea.d.ts +3 -3
  50. package/@types/forms/fields/boolean.d.sync-conflict-20250918-184325-TFDLWFG.ts +22 -0
  51. package/@types/forms/fields/boolean.d.ts +6 -1
  52. package/@types/forms/fields/boolean.sync-conflict-20250918-222042-TFDLWFG.d.ts +22 -0
  53. package/@types/forms/fields/checkboxed-list.d.sync-conflict-20250918-184325-TFDLWFG.ts +23 -0
  54. package/@types/forms/fields/checkboxed-list.d.ts +3 -1
  55. package/@types/forms/fields/collection-field.d.sync-conflict-20250918-184319-TFDLWFG.ts +22 -0
  56. package/@types/forms/fields/collection-field.d.sync-conflict-20250918-222047-TFDLWFG.ts +22 -0
  57. package/@types/forms/fields/collection-field.d.ts +8 -1
  58. package/@types/forms/fields/color.d.ts +4 -0
  59. package/@types/forms/fields/coordinates.d.sync-conflict-20250918-222044-TFDLWFG.ts +14 -0
  60. package/@types/forms/fields/coordinates.d.ts +14 -0
  61. package/@types/forms/fields/date.d.ts +13 -0
  62. package/@types/forms/fields/datetime.d.sync-conflict-20250918-222050-TFDLWFG.ts +4 -0
  63. package/@types/forms/fields/datetime.d.ts +14 -0
  64. package/@types/forms/fields/deep-reverse-single-reference-list.d.ts +24 -0
  65. package/@types/forms/fields/deep-reverse-single-reference-table.d.ts +16 -0
  66. package/@types/forms/fields/email.d.sync-conflict-20250918-184303-TFDLWFG.ts +8 -0
  67. package/@types/forms/fields/email.d.ts +3 -0
  68. package/@types/forms/fields/enum-multiple-sealious.d.ts +16 -0
  69. package/@types/forms/fields/enum-multiple-sealious.sync-conflict-20250918-222047-TFDLWFG.d.ts +16 -0
  70. package/@types/forms/fields/field.d.sync-conflict-20250918-184306-TFDLWFG.ts +70 -0
  71. package/@types/forms/fields/field.d.ts +37 -5
  72. package/@types/forms/fields/fields.d.sync-conflict-20250918-184314-TFDLWFG.ts +29 -0
  73. package/@types/forms/fields/fields.d.ts +23 -8
  74. package/@types/forms/fields/file.d.sync-conflict-20250918-184310-TFDLWFG.ts +23 -0
  75. package/@types/forms/fields/file.d.sync-conflict-20250918-222046-TFDLWFG.ts +23 -0
  76. package/@types/forms/fields/file.d.ts +11 -5
  77. package/@types/forms/fields/file.sync-conflict-20250918-222049-TFDLWFG.d.ts +23 -0
  78. package/@types/forms/fields/float.d.ts +4 -0
  79. package/@types/forms/fields/get-field-for-sealious.d.sync-conflict-20250918-222046-TFDLWFG.ts +29 -0
  80. package/@types/forms/fields/get-field-for-sealious.d.ts +31 -0
  81. package/@types/forms/fields/get-field-for-sealious.sync-conflict-20250918-222042-TFDLWFG.d.ts +29 -0
  82. package/@types/forms/fields/html.d.ts +6 -0
  83. package/@types/forms/fields/image.d.sync-conflict-20250918-222042-TFDLWFG.ts +5 -0
  84. package/@types/forms/fields/image.d.ts +5 -0
  85. package/@types/forms/fields/int.d.ts +6 -0
  86. package/@types/forms/fields/json.d.ts +13 -0
  87. package/@types/forms/fields/markdown.d.ts +6 -0
  88. package/@types/forms/fields/multiple-files.d.sync-conflict-20250918-184304-TFDLWFG.ts +16 -0
  89. package/@types/forms/fields/multiple-files.d.ts +3 -1
  90. package/@types/forms/fields/number.d.sync-conflict-20250918-184317-TFDLWFG.ts +25 -0
  91. package/@types/forms/fields/number.d.sync-conflict-20250918-222047-TFDLWFG.ts +25 -0
  92. package/@types/forms/fields/number.d.ts +3 -1
  93. package/@types/forms/fields/password.d.ts +6 -0
  94. package/@types/forms/fields/pick-from-list-sealious.d.ts +11 -0
  95. package/@types/forms/fields/pick-from-list.d.sync-conflict-20250918-184322-TFDLWFG.ts +15 -0
  96. package/@types/forms/fields/pick-from-list.d.ts +4 -3
  97. package/@types/forms/fields/proxy-field.d.sync-conflict-20250918-184307-TFDLWFG.ts +15 -0
  98. package/@types/forms/fields/proxy-field.d.ts +3 -1
  99. package/@types/forms/fields/regexp.d.sync-conflict-20250918-184305-TFDLWFG.ts +21 -0
  100. package/@types/forms/fields/regexp.d.sync-conflict-20250918-222045-TFDLWFG.ts +21 -0
  101. package/@types/forms/fields/regexp.d.ts +6 -1
  102. package/@types/forms/fields/regexp.sync-conflict-20250918-222047-TFDLWFG.d.ts +21 -0
  103. package/@types/forms/fields/simple-form-field.d.sync-conflict-20250918-184309-TFDLWFG.ts +29 -0
  104. package/@types/forms/fields/simple-form-field.d.sync-conflict-20250918-222044-TFDLWFG.ts +29 -0
  105. package/@types/forms/fields/simple-form-field.d.ts +23 -3
  106. package/@types/forms/fields/simple-form-field.sync-conflict-20250918-222049-TFDLWFG.d.ts +29 -0
  107. package/@types/forms/fields/single-reference.d.ts +19 -0
  108. package/@types/forms/fields/single-reference.sync-conflict-20250918-222043-TFDLWFG.d.ts +10 -0
  109. package/@types/forms/fields/structured-array.d.sync-conflict-20250918-184302-TFDLWFG.ts +27 -0
  110. package/@types/forms/fields/structured-array.d.sync-conflict-20250918-222049-TFDLWFG.ts +27 -0
  111. package/@types/forms/fields/structured-array.d.ts +19 -10
  112. package/@types/forms/fields/structured-array.sync-conflict-20250918-222047-TFDLWFG.d.ts +27 -0
  113. package/@types/forms/fields/table.d.sync-conflict-20250918-184303-TFDLWFG.ts +16 -0
  114. package/@types/forms/fields/table.d.ts +3 -0
  115. package/@types/forms/fields/text.d.ts +6 -0
  116. package/@types/forms/fields/url.d.ts +6 -0
  117. package/@types/forms/form-types.d.sync-conflict-20250918-222045-TFDLWFG.ts +26 -0
  118. package/@types/forms/form-types.d.ts +2 -0
  119. package/@types/forms/form.d.sync-conflict-20250918-184315-TFDLWFG.ts +32 -0
  120. package/@types/forms/form.d.sync-conflict-20250918-222049-TFDLWFG.ts +32 -0
  121. package/@types/forms/form.d.ts +10 -8
  122. package/@types/forms/form.sync-conflict-20250918-222049-TFDLWFG.d.ts +33 -0
  123. package/@types/forms/form.test.d.sync-conflict-20250918-184318-TFDLWFG.ts +6 -0
  124. package/@types/forms/form.test.d.sync-conflict-20250918-222047-TFDLWFG.ts +6 -0
  125. package/@types/forms/form.test.d.ts +2 -2
  126. package/@types/forms/multiform.d.sync-conflict-20250918-184308-TFDLWFG.ts +23 -0
  127. package/@types/forms/multiform.d.ts +1 -2
  128. package/@types/forms/multiform.sync-conflict-20250918-222044-TFDLWFG.d.ts +23 -0
  129. package/@types/index.d.sync-conflict-20250918-184316-TFDLWFG.ts +46 -0
  130. package/@types/index.d.ts +2 -2
  131. package/@types/mount.d.sync-conflict-20250918-184320-TFDLWFG.ts +6 -0
  132. package/@types/mount.d.ts +0 -1
  133. package/@types/page/list.d.sync-conflict-20250918-184318-TFDLWFG.ts +48 -0
  134. package/@types/page/list.d.sync-conflict-20250918-222046-TFDLWFG.ts +48 -0
  135. package/@types/page/list.d.ts +2 -2
  136. package/@types/page/list.sync-conflict-20250918-222048-TFDLWFG.d.ts +48 -0
  137. package/@types/page/mountable-with-fields.d.sync-conflict-20250918-184321-TFDLWFG.ts +42 -0
  138. package/@types/page/mountable-with-fields.d.sync-conflict-20250918-222046-TFDLWFG.ts +42 -0
  139. package/@types/page/mountable-with-fields.d.ts +3 -3
  140. package/@types/page/mountable-with-fields.sync-conflict-20250918-222044-TFDLWFG.d.ts +42 -0
  141. package/@types/page/mountable.d.sync-conflict-20250918-184306-TFDLWFG.ts +10 -0
  142. package/@types/page/mountable.d.ts +0 -1
  143. package/@types/page/page.d.sync-conflict-20250918-184320-TFDLWFG.ts +18 -0
  144. package/@types/page/page.d.ts +0 -1
  145. package/@types/page/props-parser.d.sync-conflict-20250918-184305-TFDLWFG.ts +15 -0
  146. package/@types/page/props-parser.d.ts +0 -1
  147. package/@types/page/stateful-page.d.sync-conflict-20250918-184326-TFDLWFG.ts +62 -0
  148. package/@types/page/stateful-page.d.ts +0 -1
  149. package/@types/templates/shared/shared-crud-form-fields.d.sync-conflict-20250918-184306-TFDLWFG.ts +1 -0
  150. package/@types/templates/shared/shared-crud-form-fields.d.ts +0 -67
  151. package/@types/test_utils/test-on-real-app.d.sync-conflict-20250918-184320-TFDLWFG.ts +26 -0
  152. package/@types/test_utils/test-on-real-app.d.ts +0 -1
  153. package/@types/utils/extract-fields-from-collection.d.sync-conflict-20250918-184312-TFDLWFG.ts +18 -0
  154. package/@types/utils/extract-fields-from-collection.d.ts +5 -1
  155. package/@types/utils/extract-fields-from-collection.sync-conflict-20250918-222045-TFDLWFG.d.ts +18 -0
  156. package/@types/utils/wrap-attributes.d.ts +3 -0
  157. package/README.md +5 -0
  158. package/assets/file-icon.svg +5 -0
  159. package/lib/add-crud.js +80 -89
  160. package/lib/add-list-route.test.js +1 -1
  161. package/lib/add-route.js +0 -7
  162. package/lib/build.js +3 -1
  163. package/lib/cli.js +2 -5
  164. package/lib/controllers/table-add-button.stimulus.js +35 -0
  165. package/lib/forms/controls/array.js +20 -16
  166. package/lib/forms/controls/big-radio-group.js +2 -2
  167. package/lib/forms/controls/checkbox-group.js +7 -7
  168. package/lib/forms/controls/checkboxed-list-input.js +9 -2
  169. package/lib/forms/controls/controls.js +2 -2
  170. package/lib/forms/controls/derived-frame.js +5 -1
  171. package/lib/forms/controls/derived.js +1 -1
  172. package/lib/forms/controls/dropdown.js +4 -1
  173. package/lib/forms/controls/editable-collection-subset.js +2 -2
  174. package/lib/forms/controls/file.js +26 -2
  175. package/lib/forms/controls/file.test.js +2 -2
  176. package/lib/forms/controls/hidden-input.js +4 -1
  177. package/lib/forms/controls/{photo.js → image.js} +6 -7
  178. package/lib/forms/controls/{photo.test.js → image.test.js} +6 -21
  179. package/lib/forms/controls/multiple-files.js +10 -1
  180. package/lib/forms/controls/{multiple-photos.js → multiple-images.js} +3 -3
  181. package/lib/forms/controls/simple-input.js +13 -12
  182. package/lib/forms/controls/single-reference.js +4 -0
  183. package/lib/forms/controls/table.js +66 -24
  184. package/lib/forms/controls/textarea.js +4 -2
  185. package/lib/forms/controls/tickable.js +13 -5
  186. package/lib/forms/fields/boolean.js +14 -0
  187. package/lib/forms/fields/checkboxed-list.js +4 -0
  188. package/lib/forms/fields/collection-field.js +9 -0
  189. package/lib/forms/fields/color.js +10 -0
  190. package/lib/forms/fields/coordinates.js +49 -0
  191. package/lib/forms/fields/date.js +34 -0
  192. package/lib/forms/fields/datetime.js +46 -0
  193. package/lib/forms/fields/deep-reverse-single-reference-list.js +81 -0
  194. package/lib/forms/fields/deep-reverse-single-reference-table.js +122 -0
  195. package/lib/forms/fields/email.js +7 -0
  196. package/lib/forms/fields/enum-multiple-sealious.js +32 -0
  197. package/lib/forms/fields/field.js +32 -4
  198. package/lib/forms/fields/field.test.js +5 -5
  199. package/lib/forms/fields/fields.js +23 -8
  200. package/lib/forms/fields/file.js +33 -9
  201. package/lib/forms/fields/file.test.js +4 -16
  202. package/lib/forms/fields/float.js +10 -0
  203. package/lib/forms/fields/get-field-for-sealious.js +213 -0
  204. package/lib/forms/fields/html.js +14 -0
  205. package/lib/forms/fields/image.js +13 -0
  206. package/lib/forms/fields/int.js +23 -0
  207. package/lib/forms/fields/json.js +31 -0
  208. package/lib/forms/fields/markdown.js +14 -0
  209. package/lib/forms/fields/multiple-files.js +4 -0
  210. package/lib/forms/fields/number.js +6 -0
  211. package/lib/forms/fields/password.js +13 -0
  212. package/lib/forms/fields/pick-from-list-sealious.js +17 -0
  213. package/lib/forms/fields/pick-from-list.js +6 -2
  214. package/lib/forms/fields/proxy-field.js +3 -0
  215. package/lib/forms/fields/regexp.js +14 -0
  216. package/lib/forms/fields/simple-form-field.js +60 -2
  217. package/lib/forms/fields/single-reference.js +44 -0
  218. package/lib/forms/fields/structured-array.js +63 -12
  219. package/lib/forms/fields/table.js +28 -1
  220. package/lib/forms/fields/text.js +17 -0
  221. package/lib/forms/fields/url.js +17 -0
  222. package/lib/forms/form.js +30 -13
  223. package/lib/forms/form.test.js +3 -4
  224. package/lib/forms/multiform.js +4 -2
  225. package/lib/forms/multiform.test.js +3 -3
  226. package/lib/generate-stimulus.js +1 -0
  227. package/lib/index.js +1 -0
  228. package/lib/make-hidden-inputs.js +1 -1
  229. package/lib/mount.js +11 -0
  230. package/lib/notifier.js +0 -1
  231. package/lib/page/list.js +15 -8
  232. package/lib/page/mountable-with-fields.js +14 -6
  233. package/lib/page/mountable-with-fields.test.js +1 -1
  234. package/lib/templates/form.js +8 -9
  235. package/lib/templates/multiform.js +4 -4
  236. package/lib/templates/page.js +0 -2
  237. package/lib/templates/shared/collection-create-form.js +28 -40
  238. package/lib/templates/shared/collection-edit-form.js +40 -77
  239. package/lib/templates/shared/collection-list.js +12 -20
  240. package/lib/templates/shared/shared-crud-form-fields.js +27 -95
  241. package/lib/test_utils/test-on-real-app.js +3 -3
  242. package/lib/utils/extract-fields-from-collection.js +60 -20
  243. package/lib/utils/make-slug.js +1 -1
  244. package/lib/utils/wrap-attributes.js +20 -0
  245. package/package.json +4 -3
  246. package/src/add-crud.ts +86 -97
  247. package/src/add-list-route.test.ts +1 -1
  248. package/src/add-route.ts +0 -7
  249. package/src/build.ts +3 -1
  250. package/src/cli.ts +3 -5
  251. package/src/controllers/table-add-button.stimulus.ts +35 -0
  252. package/src/forms/controls/array.ts +23 -20
  253. package/src/forms/controls/autocomplete.ts +1 -1
  254. package/src/forms/controls/big-radio-group.ts +2 -2
  255. package/src/forms/controls/checkbox-group.ts +9 -9
  256. package/src/forms/controls/checkboxed-list-input.ts +27 -15
  257. package/src/forms/controls/controls.ts +2 -2
  258. package/src/forms/controls/derived-frame.ts +5 -1
  259. package/src/forms/controls/derived.ts +1 -1
  260. package/src/forms/controls/dropdown.ts +5 -2
  261. package/src/forms/controls/editable-collection-subset.ts +2 -2
  262. package/src/forms/controls/file.test.ts +4 -2
  263. package/src/forms/controls/file.ts +31 -5
  264. package/src/forms/controls/form-control.ts +7 -2
  265. package/src/forms/controls/hidden-input.ts +4 -1
  266. package/src/forms/controls/{photo.test.ts → image.test.ts} +5 -22
  267. package/src/forms/controls/{photo.ts → image.ts} +3 -5
  268. package/src/forms/controls/multiple-files.ts +18 -1
  269. package/src/forms/controls/{multiple-photos.ts → multiple-images.ts} +1 -1
  270. package/src/forms/controls/number.ts +1 -1
  271. package/src/forms/controls/simple-input.ts +18 -34
  272. package/src/forms/controls/single-reference.ts +10 -2
  273. package/src/forms/controls/table.ts +90 -31
  274. package/src/forms/controls/textarea.ts +6 -4
  275. package/src/forms/controls/tickable.ts +13 -5
  276. package/src/forms/fields/boolean.ts +23 -1
  277. package/src/forms/fields/checkboxed-list.ts +11 -2
  278. package/src/forms/fields/collection-field.ts +16 -1
  279. package/src/forms/fields/color.ts +9 -0
  280. package/src/forms/fields/coordinates.ts +66 -0
  281. package/src/forms/fields/date.ts +50 -0
  282. package/src/forms/fields/datetime.ts +66 -0
  283. package/src/forms/fields/deep-reverse-single-reference-list.ts +136 -0
  284. package/src/forms/fields/deep-reverse-single-reference-table.ts +213 -0
  285. package/src/forms/fields/email.ts +9 -0
  286. package/src/forms/fields/enum-multiple-sealious.ts +48 -0
  287. package/src/forms/fields/field.test.ts +5 -5
  288. package/src/forms/fields/field.ts +94 -8
  289. package/src/forms/fields/fields.ts +23 -8
  290. package/src/forms/fields/file.test.ts +4 -16
  291. package/src/forms/fields/file.ts +43 -15
  292. package/src/forms/fields/float.ts +9 -0
  293. package/src/forms/fields/get-field-for-sealious.ts +304 -0
  294. package/src/forms/fields/html.ts +15 -0
  295. package/src/forms/fields/image.ts +12 -0
  296. package/src/forms/fields/int.ts +25 -0
  297. package/src/forms/fields/json.ts +48 -0
  298. package/src/forms/fields/markdown.ts +15 -0
  299. package/src/forms/fields/multiple-files.ts +10 -1
  300. package/src/forms/fields/number.ts +8 -1
  301. package/src/forms/fields/password.ts +17 -0
  302. package/src/forms/fields/pick-from-list-sealious.ts +22 -0
  303. package/src/forms/fields/pick-from-list.ts +7 -3
  304. package/src/forms/fields/proxy-field.ts +6 -1
  305. package/src/forms/fields/regexp.ts +27 -1
  306. package/src/forms/fields/simple-form-field.ts +95 -7
  307. package/src/forms/fields/single-reference.ts +62 -0
  308. package/src/forms/fields/structured-array.ts +115 -18
  309. package/src/forms/fields/table.ts +32 -1
  310. package/src/forms/fields/text.ts +18 -0
  311. package/src/forms/fields/url.ts +20 -0
  312. package/src/forms/form-types.ts +2 -0
  313. package/src/forms/form.test.ts +3 -4
  314. package/src/forms/form.ts +37 -16
  315. package/src/forms/forms.css +0 -85
  316. package/src/forms/multiform.test.ts +3 -3
  317. package/src/forms/multiform.ts +2 -0
  318. package/src/generate-stimulus.ts +1 -0
  319. package/src/index.ts +2 -1
  320. package/src/make-hidden-inputs.ts +1 -1
  321. package/src/mount.ts +14 -0
  322. package/src/notifier.ts +0 -1
  323. package/src/page/list.ts +15 -8
  324. package/src/page/mountable-with-fields.test.ts +1 -1
  325. package/src/page/mountable-with-fields.ts +18 -9
  326. package/src/register-external.ts +1 -1
  327. package/src/templates/form.ts +8 -9
  328. package/src/templates/multiform.ts +4 -4
  329. package/src/templates/page.ts +0 -2
  330. package/src/templates/shared/collection-create-form.ts +30 -66
  331. package/src/templates/shared/collection-edit-form.ts +41 -102
  332. package/src/templates/shared/collection-list.ts +12 -20
  333. package/src/templates/shared/item-delete.ts +0 -1
  334. package/src/templates/shared/shared-crud-form-fields.ts +37 -171
  335. package/src/test_utils/test-on-real-app.ts +4 -3
  336. package/src/utils/extract-fields-from-collection.ts +76 -25
  337. package/src/utils/make-slug.ts +1 -1
  338. package/src/utils/wrap-attributes.ts +17 -0
  339. package/lib/add-verbose-crud.js +0 -119
  340. package/lib/crud-field-snippets.js +0 -52
  341. package/lib/find-css-includes.js +0 -3
  342. package/lib/forms/controls/reverse-single-reference.js +0 -1
  343. package/lib/forms/fields/enum-multiple.js +0 -47
  344. package/lib/forms/fields/enum-multiple.test.js +0 -27
  345. package/lib/forms/fields/enum.js +0 -41
  346. package/lib/forms/fields/enum.test.js +0 -21
  347. package/lib/forms/fields/reverse-single-reference.js +0 -17
  348. package/lib/templates/shared/handlers/boolean.js +0 -14
  349. package/lib/templates/shared/handlers/date.js +0 -8
  350. package/lib/templates/shared/handlers/deep-reverse-single-reference.js +0 -209
  351. package/lib/templates/shared/handlers/default.js +0 -49
  352. package/lib/templates/shared/handlers/enum.js +0 -19
  353. package/lib/templates/shared/handlers/file.js +0 -23
  354. package/lib/templates/shared/handlers/image.js +0 -32
  355. package/lib/templates/shared/handlers/int.js +0 -11
  356. package/lib/templates/shared/handlers/jdd.js +0 -10
  357. package/lib/templates/shared/handlers/single-reference.js +0 -12
  358. package/lib/templates/shared/handlers/structured-array.js +0 -33
  359. package/src/add-verbose-crud.ts +0 -138
  360. package/src/crud-field-snippets.ts +0 -57
  361. package/src/find-css-includes.ts +0 -3
  362. package/src/forms/controls/reverse-single-reference.ts +0 -50
  363. package/src/forms/fields/enum-multiple.test.ts +0 -31
  364. package/src/forms/fields/enum-multiple.ts +0 -62
  365. package/src/forms/fields/enum.test.ts +0 -25
  366. package/src/forms/fields/enum.ts +0 -56
  367. package/src/forms/fields/reverse-single-reference.ts +0 -20
  368. package/src/templates/shared/handlers/boolean.ts +0 -18
  369. package/src/templates/shared/handlers/date.ts +0 -12
  370. package/src/templates/shared/handlers/deep-reverse-single-reference.ts +0 -244
  371. package/src/templates/shared/handlers/default.ts +0 -64
  372. package/src/templates/shared/handlers/enum.ts +0 -23
  373. package/src/templates/shared/handlers/file.ts +0 -27
  374. package/src/templates/shared/handlers/image.ts +0 -45
  375. package/src/templates/shared/handlers/int.ts +0 -15
  376. package/src/templates/shared/handlers/jdd.ts +0 -14
  377. package/src/templates/shared/handlers/single-reference.ts +0 -16
  378. package/src/templates/shared/handlers/structured-array.ts +0 -42
@@ -1,11 +1,9 @@
1
1
  import { toKebabCase, toPascalCase } from "js-convert-case";
2
2
  import { formTemplate } from "../form.js";
3
- import { curryImportPath } from "../../utils/import-path.js";
4
3
 
5
4
  import _locreq from "locreq";
6
5
  import extract_fields_from_collection from "../../utils/extract-fields-from-collection.js";
7
-
8
- import { getFieldHandler } from "./shared-crud-form-fields.js";
6
+ import { wrapAttribute } from "../../utils/wrap-attributes.js";
9
7
 
10
8
  export async function editItemFormTemplate(
11
9
  edit_action_name: string,
@@ -16,38 +14,19 @@ export async function editItemFormTemplate(
16
14
  const collection_fields = await extract_fields_from_collection(
17
15
  collection_name
18
16
  );
19
- const importPath = curryImportPath(newfilefullpath);
20
-
21
- const field_handler_results = await Promise.all(
22
- collection_fields.map(async (field) => {
23
- return getFieldHandler(collection_name, field, importPath);
24
- })
25
- );
17
+ const formFieldsVar = `${toPascalCase(collection_name)}FormFields`;
18
+ const collectionVar = `${toPascalCase(collection_name)}`;
26
19
 
27
20
  return formTemplate(edit_action_name, newfilefullpath, {
28
21
  success_message: "Changes saved!",
29
- postimport: `import {${toPascalCase(
30
- collection_name
31
- )}FormFields, ${toPascalCase(
22
+ postimport: `import {${formFieldsVar}, get${toPascalCase(
32
23
  collection_name
33
24
  )}FormControls }from "../shared.js";
34
- import { ${toPascalCase(collection_name)} } from "${importPath(
35
- "src/back/collections/collections.js"
36
- )}";
37
- import { ${list_action}URL, ${edit_action_name}URL } from "${importPath(
38
- "src/back/routes/urls.js"
39
- )}";
40
- import {tempstream} from "tempstream";
41
-
42
- ${Array.from(
43
- new Set(field_handler_results.map(({ imports }) => imports.edit))
44
- ).join("\n")}
45
-
46
- ${
47
- collection_fields.filter((e) => !e.is_required).length
48
- ? `import {withFallback} from "@sealcode/sealgen";`
49
- : ""
50
- }
25
+ import { ${collectionVar} } from "src/back/collections/collections.js";
26
+ import { ${list_action}URL } from "src/back/routes/urls.js";
27
+ import {tempstream} from "tempstream";
28
+ import type { FormDataValue } from "@sealcode/sealgen";
29
+ import type { CollectionInputWithAllKeys } from "sealious";
51
30
  `,
52
31
 
53
32
  fields: `...${toPascalCase(collection_name)}FormFields`,
@@ -55,7 +34,7 @@ export async function editItemFormTemplate(
55
34
  new Controls.FormHeader("Edit ${toPascalCase(
56
35
  collection_name
57
36
  )}"),
58
- ...${toPascalCase(collection_name)}FormControls`,
37
+ ...get${toPascalCase(collection_name)}FormControls()`,
59
38
 
60
39
  can_access: `canAccess = async (ctx: Context) => {
61
40
  const policy = ${toPascalCase(collection_name)}.getPolicy("edit");
@@ -64,8 +43,8 @@ export async function editItemFormTemplate(
64
43
  };`,
65
44
 
66
45
  onsubmit: `
67
- async onSubmit(ctx: Context) {
68
- const data = await this.getParsedValues(ctx);
46
+ async onSubmit(ctx: Context, formData: FormData) {
47
+ const fctx = this.makeFormControlContext(ctx, formData, true);
69
48
  const id = await this.getID(ctx);
70
49
  const {items: [item]} = await ctx.$app.collections["${toKebabCase(
71
50
  collection_name
@@ -78,50 +57,37 @@ export async function editItemFormTemplate(
78
57
  throw new Error("Unknown id: " + id);
79
58
  }
80
59
 
81
- if (!data) {
82
- throw new Error("Error when parsing the form values");
83
- }
84
60
 
85
- ${field_handler_results
86
- .map((result) => result.pre_edit)
87
- .filter((e) => e !== "")
88
- .join("\n")}
89
-
90
- item.setMultiple(
91
- {
92
- ${field_handler_results
93
- .filter((r) => !r.hide_sealious_value)
94
- .map((result) => result.sealious_value(result))
95
- .filter((e) => e != "")
96
- .join(",\n")}
97
- }
61
+ item.setMultipleExtraSafe(
62
+ {
63
+ ${collection_fields
64
+ .map((field_info) =>
65
+ field_info.form_field.generateCreateValueGetter(
66
+ field_info,
67
+ {
68
+ form_field_types: "FormFieldTypes",
69
+ sealious_field: `${collectionVar}.fields${wrapAttribute(
70
+ field_info.name
71
+ )}`,
72
+ form_fields: "fields",
73
+ }
74
+ )
75
+ )
76
+ .join(",\n")}
77
+ } as CollectionInputWithAllKeys<typeof ${collectionVar}>
98
78
  );
79
+
99
80
  await item.save(ctx.$context);
100
81
 
101
-
102
- ${
103
- field_handler_results
104
- .map((result) => result.post_edit)
105
- .filter((e) => e != "").length
106
- ? `// #### POST-EDIT ACTIONS ############`
107
- : ""
82
+ for(const field of Object.values(${formFieldsVar})){
83
+ await field.postSealiousEdit(ctx, item, formData)
108
84
  }
109
- ${field_handler_results
110
- .map((result) => result.post_edit)
111
- .filter((e) => e != "")
112
- .join("\n")}
113
85
  }
114
86
  `,
115
87
 
116
88
  other_methods: `
117
89
  async getID(ctx: Context): Promise<string>{
118
- // trying to automatically guess which param is the one that represents the ID
119
- // of the resource to edit.
120
- // If sealgen got it wrong, just return the param name that should be used here instead
121
- const param_name =
122
- ${edit_action_name}URL.params
123
- .find(param => param.toLowerCase().includes("id"))
124
- || ${edit_action_name}URL.params[0]
90
+ const param_name = "id";
125
91
  const id = ctx.params[param_name];
126
92
  if (!id) {
127
93
  throw new Error("Missing URL parameter: " + param_name);
@@ -130,7 +96,7 @@ export async function editItemFormTemplate(
130
96
  }
131
97
  `,
132
98
 
133
- get_initial_values: `async getInitialValues(ctx: Context) {
99
+ get_initial_values: `async getInitialValues(ctx: Context): Promise<{ [key in keyof typeof fields]: FormDataValue | undefined }> {
134
100
  const id = await this.getID(ctx);
135
101
 
136
102
  const {
@@ -146,42 +112,15 @@ export async function editItemFormTemplate(
146
112
  }
147
113
 
148
114
  return {
149
- ${field_handler_results
150
- .filter((r) => !r.hide_initial_value_edit)
151
- .map(({ initial_value_edit, is_required, name }) => {
152
- if (typeof initial_value_edit == "string") {
153
- if (initial_value_edit == "") {
154
- return "";
155
- }
156
- return `${name}: ${initial_value_edit}`;
157
- }
158
115
 
159
- const main_value = initial_value_edit.main_value;
160
- if (!main_value) {
161
- throw new Error(
162
- "Missing main_value for initial_value_edit"
163
- );
164
- }
165
- const { parsed_value, fallback_value } =
166
- initial_value_edit;
167
- if (is_required) {
168
- return `${name}: ${parsed_value || main_value}`;
169
- }
170
- if (main_value && parsed_value && fallback_value) {
171
- if (main_value == parsed_value) {
172
- return `${name}: withFallback(${main_value}, ${fallback_value})`;
173
- } else {
174
- return `${name}: withFallback(${main_value}, ${parsed_value}, ${fallback_value})`;
175
- }
176
- } else {
177
- console.error(initial_value_edit);
178
- throw new Error(
179
- "Missing field info for generating initial value"
180
- );
181
- }
116
+ ${collection_fields
117
+ .map((field_info) =>
118
+ field_info.form_field.generateInitialValue(field_info, {
119
+ form_field_types: "FieldTypes",
120
+ form_fields: "fields",
182
121
  })
183
- .filter((e) => e.trim() !== "")
184
- .join(",\n")}
122
+ )
123
+ .join(",\n")}
185
124
  };
186
125
  }
187
126
  `,
@@ -60,12 +60,12 @@ export function makeDefaultDisplayFields(
60
60
  return `{
61
61
  field: "${field.name}",
62
62
  label: "${field.name}",
63
- format: async (value: FilePointer) => {
64
- return imageRouter.image(await value.getPath(), {
63
+ format: async (value: FilePointer|null) => {
64
+ return value ? imageRouter.image(await value.getPath(), {
65
65
  container: { width: 45, height: 45 },
66
66
  crop: { width: 45, height: 45 },
67
67
  alt: "",
68
- });
68
+ }): "";
69
69
  },
70
70
  }`;
71
71
  }
@@ -118,7 +118,7 @@ import type { FlatTemplatable, Templatable } from "tempstream";
118
118
  import { TempstreamJSX, tempstream } from "tempstream";
119
119
  import { ${uppercase_collection} } from "src/back/collections/collections.js";
120
120
  import html from "src/back/html.js";
121
- import type { ListFilterRender } from "@sealcode/sealgen";
121
+ import type { ListFilterRender, FormDisplayInfo } from "@sealcode/sealgen";
122
122
  import {
123
123
  SealiousItemListPage,
124
124
  BaseListPageFields,
@@ -131,26 +131,18 @@ ${field_import_string}
131
131
 
132
132
  export const actionName = "${action_name}";
133
133
 
134
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
135
- const filterFields = [
136
- ${makeDefaultFilterFields(collection_fields)}
137
- ] as {
138
- field: keyof (typeof ${uppercase_collection})["fields"];
134
+ const filterFields:{
135
+ field: keyof (typeof HasAllFields)["fields"];
139
136
  render?: ListFilterRender;
140
- prepareValue?: (filter_value: unknown)=>unknown; // set this function to change what filter value is passed to Sealious
141
- }[];
137
+ prepareValue?: (filter_value: unknown) => unknown; // set this function to change what filter value is passed to Sealious
138
+ }[] = [
139
+ ${makeDefaultFilterFields(collection_fields)}
140
+ ];
142
141
 
143
142
 
144
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
145
- const displayFields = [
143
+ const displayFields: FormDisplayInfo<typeof ${uppercase_collection}>[] = [
146
144
  ${makeDefaultDisplayFields(collection_fields)}
147
- ] as {
148
- field: string;
149
- label: string;
150
- format?: (value: unknown, item: CollectionItem<typeof ${toPascalCase(
151
- collection_name
152
- )}>) => FlatTemplatable;
153
- }[];
145
+ ];
154
146
 
155
147
  export default new (class ${action_name}Page extends SealiousItemListPage<
156
148
  typeof ${uppercase_collection},
@@ -1,5 +1,4 @@
1
1
  import { toKebabCase, toPascalCase } from "js-convert-case";
2
- import { curryImportPath } from "../../utils/import-path.js";
3
2
  import { formatWithPrettier } from "../../utils/prettier.js";
4
3
 
5
4
  export function itemDeleteTemplate(
@@ -1,193 +1,59 @@
1
1
  import { toPascalCase } from "js-convert-case";
2
- import { extractCollectionClassname } from "../../generate-collections.js";
3
- import extract_fields_from_collection, {
4
- ExtractedFieldInfo,
5
- } from "../../utils/extract-fields-from-collection.js";
6
-
7
2
  import _locreq from "locreq";
8
- import { curryImportPath } from "../../utils/import-path.js";
3
+ import extract_fields_from_collection from "../../utils/extract-fields-from-collection.js";
9
4
  import { formatWithPrettier } from "../../utils/prettier.js";
10
- import { default_handler } from "./handlers/default.js";
11
- import { enum_handler } from "./handlers/enum.js";
12
- import { image_handler } from "./handlers/image.js";
13
- import { file_handler } from "./handlers/file.js";
14
- import { int_handler } from "./handlers/int.js";
15
- import { boolean_handler } from "./handlers/boolean.js";
16
- import { jdd_handler } from "./handlers/jdd.js";
17
- import { date_handler } from "./handlers/date.js";
18
- import { deep_reverse_single_reference_handler } from "./handlers/deep-reverse-single-reference.js";
19
- import { structured_array_handler } from "./handlers/structured-array.js";
20
- import { single_reference_handler } from "./handlers/single-reference.js";
21
- const target_locreq = _locreq(process.cwd());
22
-
23
- export type FieldHandlerResult = {
24
- imports: Partial<{ shared: string; edit: string }>;
25
- hide_field: boolean;
26
- field: string;
27
- hide_control: boolean;
28
- controls: string;
29
- is_required: boolean;
30
- is_required_expr: string;
31
- fields_var: string;
32
- top_level_shared: string;
33
- name: string;
34
- hide_initial_value_edit: boolean;
35
- initial_value_edit:
36
- | Partial<{
37
- main_value: string;
38
- parsed_value: string;
39
- fallback_value: string;
40
- }>
41
- | string;
42
- hide_initial_value_create: boolean;
43
- initial_value_create: string;
44
- pre_edit: string;
45
- post_edit: string;
46
- pre_create: string;
47
- post_create: string;
48
- sealious_value: (
49
- result: Exclude<FieldHandlerResult, "sealious_value">
50
- ) => string;
51
- hide_sealious_value: boolean;
52
- fallback_value_sealious: string;
53
- main_value_sealious: string;
54
- };
55
-
56
- export type FieldHandler<
57
- Defaults extends Partial<FieldHandlerResult>,
58
- Result extends Partial<FieldHandlerResult>
59
- > = (
60
- collection_name: string,
61
- field: ExtractedFieldInfo,
62
- importPath: (path: string) => string,
63
- defaults: Defaults,
64
- all_other_handlers: Record<
65
- string,
66
- | FieldHandler<FieldHandlerResult, Partial<FieldHandlerResult>>
67
- | undefined
68
- >,
69
- fields_var?: string
70
- ) => Promise<Result>;
71
-
72
- export const field_handlers: Record<
73
- Exclude<string, "default">,
74
- FieldHandler<FieldHandlerResult, Partial<FieldHandlerResult>> | undefined
75
- > & {
76
- default: FieldHandler<Record<string, never>, FieldHandlerResult>;
77
- } = {
78
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
79
- default: default_handler as any,
80
- enum: enum_handler,
81
- image: image_handler,
82
- file: file_handler,
83
- int: int_handler,
84
- boolean: boolean_handler,
85
- jdd: jdd_handler,
86
- date: date_handler,
87
- "deep-reverse-single-reference": deep_reverse_single_reference_handler,
88
- "structured-array": structured_array_handler,
89
- "single-reference": single_reference_handler,
90
- };
91
-
92
- export async function getFieldHandler(
93
- collection_name: string,
94
- field: ExtractedFieldInfo,
95
- importPath: (path: string) => string,
96
- fields_var?: string
97
- ) {
98
- const defaults = await field_handlers.default(
99
- collection_name,
100
- field,
101
- importPath,
102
- {},
103
- field_handlers,
104
- fields_var
105
- );
106
-
107
- const result = {
108
- ...defaults,
109
- ...((await field_handlers[field.type]?.(
110
- collection_name,
111
- field,
112
- importPath,
113
- defaults,
114
- field_handlers,
115
- fields_var
116
- )) || {}),
117
- };
118
- const result_initial_value_edit = result.initial_value_edit;
119
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
120
- result.initial_value_edit =
121
- typeof result_initial_value_edit == "string"
122
- ? result_initial_value_edit
123
- : {
124
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
- ...(defaults.initial_value_edit as any),
126
- ...result_initial_value_edit,
127
- };
128
- return result;
129
- }
5
+ import { wrapAttribute } from "../../utils/wrap-attributes.js";
130
6
 
131
7
  export async function sharedCrudFormFields(
132
8
  collection_name: string,
133
9
  newfilefullpath: string
134
10
  ) {
135
- const [uppercase_collection, collection_fields] = await Promise.all([
136
- extractCollectionClassname(
137
- target_locreq.resolve(
138
- "src/back/collections/" + collection_name + ".ts"
139
- )
140
- ),
141
- extract_fields_from_collection(collection_name),
142
- ]);
143
- const importPath = curryImportPath(newfilefullpath);
144
-
145
- const field_handler_results = await Promise.all(
146
- collection_fields.map(async (field) => {
147
- return getFieldHandler(collection_name, field, importPath);
148
- })
11
+ const collection_fields = await extract_fields_from_collection(
12
+ collection_name
149
13
  );
150
14
 
151
- const result = `import { Controls, Fields } from "@sealcode/sealgen";
152
- import { ${uppercase_collection} } from "${importPath(
153
- "src/back/collections/collections.js"
154
- )}";
15
+ const uppercase_collection = toPascalCase(collection_name);
155
16
 
17
+ const result = `import { Controls, Fields } from "@sealcode/sealgen";
18
+ import { ${uppercase_collection} } from "src/back/collections/collections.js";
156
19
  ${Array.from(
157
20
  new Set(
158
- field_handler_results
159
- .filter(
160
- ({ hide_field, hide_control }) => !hide_field && !hide_control
21
+ collection_fields
22
+ .map((field_info) =>
23
+ field_info.form_field.generateImportsForFieldList(field_info)
161
24
  )
162
- .map(({ imports }) => imports.shared || "")
163
- )
164
- ).join("\n")}
165
-
166
-
167
-
168
- export const ${toPascalCase(collection_name)}FormFields = <const>
169
- {
170
- ${field_handler_results
171
- .filter(({ hide_field }) => !hide_field)
172
- .map(({ field }) => field)
173
- .filter((e) => e != "")
25
+ .flat()
26
+ .map(
27
+ ({ what, from, as }) =>
28
+ `import {${what}${as ? ` as ${as}` : ""} } from "${from}"`
29
+ )
30
+ ).values()
31
+ ).join(";\n")}
32
+
33
+ export const ${toPascalCase(collection_name)}FormFields = <const>{
34
+ ${collection_fields
35
+ .map((field_info) => {
36
+ return `${
37
+ field_info.name
38
+ }: ${field_info.form_field.generateFieldDeclaration(field_info, {
39
+ form_field_types: "Fields",
40
+ sealious_field: `${uppercase_collection}.fields${wrapAttribute(
41
+ field_info.name
42
+ )}`,
43
+ })}`;
44
+ })
174
45
  .join(",\n")}
175
46
  };
176
47
 
177
- export const ${toPascalCase(collection_name)}FormControls = [
178
- ${field_handler_results
179
- .filter(({ hide_control }) => !hide_control)
180
- .map(({ controls }) => controls)
181
- .filter((e) => e != "")
48
+ const fields = ${toPascalCase(collection_name)}FormFields
49
+
50
+ export const get${toPascalCase(
51
+ collection_name
52
+ )}FormControls: () => Controls.FormControl[] = () => [
53
+ ${collection_fields
54
+ .map(({ name }) => `fields${wrapAttribute(name)}.getControl()`)
182
55
  .join(",\n")}
183
56
  ];
184
-
185
- ${Array.from(
186
- new Set(
187
- field_handler_results.map(({ top_level_shared }) => top_level_shared)
188
- )
189
- ).join("\n")}
190
-
191
57
  `;
192
58
  return formatWithPrettier(result);
193
59
  }
@@ -15,7 +15,9 @@ const locreq = _locreq(module_dirname(import.meta.url));
15
15
 
16
16
  export const callSealgenBin = () => `node ${locreq.resolve("lib/cli.js")}`;
17
17
 
18
- const sealious_minimal_commit = "833e70c";
18
+ const sealious_minimal_url =
19
+ "https://hub.sealcode.org/source/sealious-minimal.git";
20
+ const sealious_minimal_commit = "77e3794";
19
21
 
20
22
  export class RealAppTest {
21
23
  public node_pid: number;
@@ -33,7 +35,7 @@ export class RealAppTest {
33
35
  test_app.container_name = `sealgen-test-mongo-${timestamp}`;
34
36
  console.log("\tcloning sealious-minimal...");
35
37
  await execAsync(
36
- `git clone https://hub.sealcode.org/source/sealious-minimal.git ${test_app.app_path} && cd ${test_app.app_path} && git checkout ${sealious_minimal_commit}`
38
+ `git clone ${sealious_minimal_url} ${test_app.app_path} && cd ${test_app.app_path} && git checkout ${sealious_minimal_commit}`
37
39
  );
38
40
  console.log("\tinstalling dependencies and sealgen...");
39
41
  await execAsync(
@@ -160,7 +162,6 @@ export class RealAppTest {
160
162
  path: string,
161
163
  body: Record<string, unknown>
162
164
  ): Promise<{ status: number; response: string }> {
163
- console.debug("POST", path, body);
164
165
  return this.throwIfItKillsTheApp(async () => {
165
166
  const ret = await fetch(
166
167
  `http://localhost:${this.app_port}${path}`,
@@ -3,6 +3,8 @@ 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 { FormField } from "../forms/fields/field.js";
7
+ import { sealiousFieldInfoToFormField } from "../forms/fields/get-field-for-sealious.js";
6
8
 
7
9
  export type ExtractedFieldInfo = {
8
10
  name: string;
@@ -16,6 +18,10 @@ export type ExtractedFieldInfo = {
16
18
  subfields: { name: string }[];
17
19
  };
18
20
 
21
+ export type ExtractedFieldInfoWithFormField = ExtractedFieldInfo & {
22
+ form_field: FormField;
23
+ };
24
+
19
25
  const counter = (function* () {
20
26
  let i = 0;
21
27
  while (true) {
@@ -23,11 +29,19 @@ const counter = (function* () {
23
29
  }
24
30
  })();
25
31
 
32
+ const cache = {} as Record<
33
+ string,
34
+ Promise<ExtractedFieldInfoWithFormField[]> | undefined
35
+ >;
36
+
26
37
  export default async function extract_fields_from_collection(
27
38
  collection_name: string
28
- ): Promise<ExtractedFieldInfo[]> {
39
+ ): Promise<ExtractedFieldInfoWithFormField[]> {
40
+ if (cache[collection_name]) {
41
+ return cache[collection_name];
42
+ }
29
43
  const extractor_code = `import {default as the_app} from "./app.js";
30
- const c = new the_app().collections["${collection_name}"];
44
+ const c = new the_app({}).collections["${collection_name}"];
31
45
  const fields = [];
32
46
  for (const field_name in c.fields){
33
47
  let field = c.fields[field_name];
@@ -37,14 +51,17 @@ for (const field_name in c.fields){
37
51
  let referencing_field = null;
38
52
  let intermediary_field_that_points_there = null;
39
53
  let is_readonly = false;
40
- let is_required = field.required;
54
+ let is_required = field.required || false;
41
55
  let subfields = [];
42
- if(["derived-value", "cached-value", "settable-by"].includes(type)){
56
+ if(["derived-value", "cached-value", "settable-by", "control-access"].includes(type)){
43
57
  type = field.virtual_field.typeName;
44
58
  }
45
59
  if(["derived-value", "cached-value", "reverse-single-reference"].includes(field.typeName)){
46
60
  is_readonly = true;
47
61
  }
62
+ if(type == "single-reference"){
63
+ target = field.target_collection;
64
+ }
48
65
  if(type == "deep-reverse-single-reference" || type =="reverse-single-reference"){
49
66
  target = field.target_collection;
50
67
  referencing_collection = field.referencing_collection;
@@ -62,25 +79,59 @@ for (const field_name in c.fields){
62
79
  `dist/back/___extract_fields--${counter.next().value || 0}.js`
63
80
  );
64
81
  await fs.writeFile(extractor_code_path, extractor_code);
65
- const { stdout } = await exec("node", [extractor_code_path]);
66
- await fs.unlink(extractor_code_path);
67
- const ret = JSON.parse(stdout) as unknown;
68
- if (
69
- !is(
70
- ret,
71
- predicates.array(
72
- predicates.shape({
73
- name: predicates.string,
74
- type: predicates.string,
75
- is_readonly: predicates.boolean,
76
- })
77
- )
78
- )
79
- ) {
80
- throw new Error(
81
- "Encountered a problem while extracting the names of fields from collection. Got: " +
82
- stdout
83
- );
84
- }
85
- return ret as ExtractedFieldInfo[];
82
+ const result = exec("node", [extractor_code_path])
83
+ .then(async ({ stdout }) => {
84
+ await fs.unlink(extractor_code_path);
85
+ const ret = JSON.parse(stdout) as unknown;
86
+ if (
87
+ !is(
88
+ ret,
89
+ predicates.array(
90
+ predicates.shape({
91
+ name: predicates.string,
92
+ type: predicates.string,
93
+ is_readonly: predicates.boolean,
94
+ target: predicates.or(
95
+ predicates.string,
96
+ predicates.null
97
+ ),
98
+ referencing_collection: predicates.or(
99
+ predicates.string,
100
+ predicates.null
101
+ ),
102
+ referencing_field: predicates.or(
103
+ predicates.string,
104
+ predicates.null
105
+ ),
106
+ is_required: predicates.boolean,
107
+ intermediary_field_that_points_there: predicates.or(
108
+ predicates.string,
109
+ predicates.null
110
+ ),
111
+ subfields: predicates.array(
112
+ predicates.shape({ name: predicates.string })
113
+ ),
114
+ })
115
+ )
116
+ )
117
+ ) {
118
+ throw new Error(
119
+ "Encountered a problem while extracting the names of fields from collection. Got: " +
120
+ stdout
121
+ );
122
+ }
123
+ const result = (await Promise.all(
124
+ ret.map(async (field_info) => ({
125
+ ...field_info,
126
+ form_field: await sealiousFieldInfoToFormField(field_info),
127
+ }))
128
+ )) as ExtractedFieldInfoWithFormField[];
129
+ return result;
130
+ })
131
+ .catch((e) => {
132
+ console.error("ERROR", e);
133
+ process.exit(1);
134
+ });
135
+ cache[collection_name] = result;
136
+ return result;
86
137
  }
@@ -1,5 +1,5 @@
1
1
  export function makeSlug(t: string) {
2
2
  return t
3
- .replaceAll(/\P{General_Category=Letter}/g, "-")
3
+ .replaceAll(/\P{General_Category=Letter}/gu, "-")
4
4
  .replaceAll(/-+/g, "-");
5
5
  }