@sealcode/sealgen 0.15.1 → 0.15.3

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 (200) hide show
  1. package/.eslintrc.cjs +38 -0
  2. package/.xunit +53 -0
  3. package/@types/src/page/stateful-page.d.ts +4 -2
  4. package/build.js +1 -1
  5. package/{dist → lib}/add-route.test.js +2 -2
  6. package/{dist → lib}/build.js +3 -3
  7. package/{dist → lib}/builder.js +3 -0
  8. package/lib/cli.js +39 -0
  9. package/{dist → lib}/esbuild-plugins/load-assets.js +2 -2
  10. package/{dist → lib}/forms/controls/array.js +1 -2
  11. package/{dist → lib}/forms/controls/autocomplete.js +8 -10
  12. package/{dist → lib}/forms/controls/checkboxed-list-input.test.js +3 -2
  13. package/{dist → lib}/forms/controls/collapsible-field-group.js +2 -1
  14. package/{dist → lib}/forms/controls/editable-collection-subset.js +6 -4
  15. package/{dist → lib}/forms/controls/field-group.js +1 -1
  16. package/{dist → lib}/forms/controls/file.js +2 -5
  17. package/{dist → lib}/forms/controls/form-control.js +2 -1
  18. package/{dist → lib}/forms/controls/photo.js +1 -1
  19. package/{dist → lib}/forms/controls/photo.test.js +5 -7
  20. package/{dist → lib}/forms/controls/textarea.js +1 -1
  21. package/{dist → lib}/forms/fields/boolean.test.js +0 -1
  22. package/{dist → lib}/forms/fields/field.js +2 -5
  23. package/{dist → lib}/forms/fields/file.js +8 -2
  24. package/{dist → lib}/forms/fields/structured-array.js +1 -1
  25. package/{dist → lib}/forms/form.test.js +8 -9
  26. package/{dist → lib}/forms/multiform.test.js +14 -14
  27. package/{dist → lib}/generate-components.js +1 -1
  28. package/{dist → lib}/generate-routes.test.js +1 -0
  29. package/{dist → lib}/generate-stimulus.js +1 -1
  30. package/lib/index.js +25 -0
  31. package/{dist → lib}/mount.js +4 -3
  32. package/{dist → lib}/notifier.js +3 -1
  33. package/{dist → lib}/page/list.js +1 -1
  34. package/{dist → lib}/page/mountable-with-fields.js +1 -1
  35. package/{dist → lib}/page/sealious-list.js +2 -2
  36. package/{dist → lib}/page/stateful-page.js +37 -19
  37. package/{dist → lib}/templates/jdd-component.js +2 -2
  38. package/{dist → lib}/utils/extract-fields-from-collection.js +16 -1
  39. package/package.json +19 -14
  40. package/src/add-route.test.ts +2 -2
  41. package/src/add-route.ts +2 -2
  42. package/src/build.ts +3 -3
  43. package/src/builder.ts +3 -2
  44. package/src/esbuild-plugins/load-assets.ts +5 -4
  45. package/src/esbuild-plugins/rewrite-asset-imports.ts +4 -3
  46. package/src/forms/controls/array.ts +5 -3
  47. package/src/forms/controls/autocomplete.ts +2 -2
  48. package/src/forms/controls/checkbox-group.ts +1 -5
  49. package/src/forms/controls/checkboxed-list-input.test.ts +3 -2
  50. package/src/forms/controls/checkboxed-list-input.ts +0 -1
  51. package/src/forms/controls/collapsible-field-group.ts +4 -2
  52. package/src/forms/controls/derived.ts +1 -1
  53. package/src/forms/controls/dropdown.ts +3 -3
  54. package/src/forms/controls/editable-collection-subset.ts +10 -4
  55. package/src/forms/controls/field-group.ts +1 -1
  56. package/src/forms/controls/file.ts +1 -1
  57. package/src/forms/controls/form-control.ts +2 -1
  58. package/src/forms/controls/hidden-input.ts +0 -2
  59. package/src/forms/controls/multiple-files.ts +8 -5
  60. package/src/forms/controls/number.ts +1 -1
  61. package/src/forms/controls/photo.test.ts +6 -7
  62. package/src/forms/controls/photo.ts +3 -6
  63. package/src/forms/controls/simple-input.ts +3 -5
  64. package/src/forms/controls/textarea.ts +3 -8
  65. package/src/forms/controls/tickable.ts +2 -4
  66. package/src/forms/fields/boolean.test.ts +0 -1
  67. package/src/forms/fields/existing-sealious-value.ts +1 -0
  68. package/src/forms/fields/field.ts +5 -8
  69. package/src/forms/fields/file.ts +13 -6
  70. package/src/forms/fields/structured-array.ts +2 -2
  71. package/src/forms/form.test.ts +9 -10
  72. package/src/forms/form.ts +1 -1
  73. package/src/forms/multiform.test.ts +14 -14
  74. package/src/forms/multiform.ts +2 -1
  75. package/src/generate-components.ts +1 -2
  76. package/src/generate-routes.test.ts +1 -0
  77. package/src/generate-stimulus.ts +1 -1
  78. package/src/get-fonts.ts +2 -0
  79. package/src/mount.ts +8 -3
  80. package/src/notifier.ts +3 -1
  81. package/src/page/list.ts +1 -1
  82. package/src/page/mountable-with-fields.ts +3 -1
  83. package/src/page/sealious-list.ts +3 -2
  84. package/src/page/stateful-page.ts +53 -24
  85. package/src/templates/jdd-component.ts +2 -2
  86. package/src/utils/extract-fields-from-collection.ts +19 -1
  87. package/src/utils/translate.ts +1 -1
  88. package/src/utils/utils.ts +2 -0
  89. package/test.cjs +54 -0
  90. package/tsconfig.json +3 -4
  91. package/dist/back/routes/sample.page.js +0 -17
  92. package/dist/back/routes/sample.test.js +0 -39
  93. package/dist/hehe.test.js +0 -7
  94. package/dist/sample-index.js +0 -3
  95. package/dist/sample-lib.js +0 -9
  96. package/dist/vitest.config.js +0 -23
  97. package/src/vitest.config.ts +0 -21
  98. /package/{dist → lib}/add-collection.js +0 -0
  99. /package/{dist → lib}/add-jdd-component.js +0 -0
  100. /package/{dist → lib}/add-route.js +0 -0
  101. /package/{dist → lib}/components/components.js +0 -0
  102. /package/{dist → lib}/components/tabs.js +0 -0
  103. /package/{dist → lib}/components/toggle-modal.js +0 -0
  104. /package/{dist → lib}/embeddable-file-extensions.js +0 -0
  105. /package/{dist → lib}/esbuild-plugins/rewrite-asset-imports.js +0 -0
  106. /package/{dist → lib}/example.test.js +0 -0
  107. /package/{dist → lib}/find-css-includes.js +0 -0
  108. /package/{dist → lib}/forms/controls/big-radio-group.js +0 -0
  109. /package/{dist → lib}/forms/controls/checkbox-group.js +0 -0
  110. /package/{dist → lib}/forms/controls/checkbox.js +0 -0
  111. /package/{dist → lib}/forms/controls/checkboxed-list-input.js +0 -0
  112. /package/{dist → lib}/forms/controls/collapsible-checkbox-group.js +0 -0
  113. /package/{dist → lib}/forms/controls/controls.js +0 -0
  114. /package/{dist → lib}/forms/controls/derived-frame.js +0 -0
  115. /package/{dist → lib}/forms/controls/derived.js +0 -0
  116. /package/{dist → lib}/forms/controls/dropdown.js +0 -0
  117. /package/{dist → lib}/forms/controls/form-field-control.js +0 -0
  118. /package/{dist → lib}/forms/controls/form-header.js +0 -0
  119. /package/{dist → lib}/forms/controls/form-paragraph.js +0 -0
  120. /package/{dist → lib}/forms/controls/frame.js +0 -0
  121. /package/{dist → lib}/forms/controls/hidden-input.js +0 -0
  122. /package/{dist → lib}/forms/controls/html.js +0 -0
  123. /package/{dist → lib}/forms/controls/multiple-files.js +0 -0
  124. /package/{dist → lib}/forms/controls/multiple-photos.js +0 -0
  125. /package/{dist → lib}/forms/controls/number.js +0 -0
  126. /package/{dist → lib}/forms/controls/radio.js +0 -0
  127. /package/{dist → lib}/forms/controls/reverse-single-reference.js +0 -0
  128. /package/{dist → lib}/forms/controls/simple-input.js +0 -0
  129. /package/{dist → lib}/forms/controls/tickable.js +0 -0
  130. /package/{dist → lib}/forms/fields/boolean.js +0 -0
  131. /package/{dist → lib}/forms/fields/checkboxed-list.js +0 -0
  132. /package/{dist → lib}/forms/fields/collection-field.js +0 -0
  133. /package/{dist → lib}/forms/fields/email.js +0 -0
  134. /package/{dist → lib}/forms/fields/email.test.js +0 -0
  135. /package/{dist → lib}/forms/fields/enum-multiple.js +0 -0
  136. /package/{dist → lib}/forms/fields/enum-multiple.test.js +0 -0
  137. /package/{dist → lib}/forms/fields/enum.js +0 -0
  138. /package/{dist → lib}/forms/fields/enum.test.js +0 -0
  139. /package/{dist → lib}/forms/fields/existing-sealious-value.js +0 -0
  140. /package/{dist → lib}/forms/fields/fields.js +0 -0
  141. /package/{dist → lib}/forms/fields/multiple-files.js +0 -0
  142. /package/{dist → lib}/forms/fields/number.js +0 -0
  143. /package/{dist → lib}/forms/fields/number.test.js +0 -0
  144. /package/{dist → lib}/forms/fields/pick-from-list.js +0 -0
  145. /package/{dist → lib}/forms/fields/pick-from-list.test.js +0 -0
  146. /package/{dist → lib}/forms/fields/proxy-field.js +0 -0
  147. /package/{dist → lib}/forms/fields/regexp.js +0 -0
  148. /package/{dist → lib}/forms/fields/regexp.test.js +0 -0
  149. /package/{dist → lib}/forms/fields/reverse-single-reference.js +0 -0
  150. /package/{dist → lib}/forms/fields/simple-form-field.js +0 -0
  151. /package/{dist → lib}/forms/form-types.js +0 -0
  152. /package/{dist → lib}/forms/form.js +0 -0
  153. /package/{dist → lib}/forms/multiform.js +0 -0
  154. /package/{dist → lib}/generate-collections.js +0 -0
  155. /package/{dist → lib}/generate-routes.js +0 -0
  156. /package/{dist → lib}/get-fonts.js +0 -0
  157. /package/{dist → lib}/koa.d.js +0 -0
  158. /package/{dist → lib}/make-env.js +0 -0
  159. /package/{dist → lib}/make-hidden-inputs.js +0 -0
  160. /package/{dist → lib}/page/access-control.js +0 -0
  161. /package/{dist → lib}/page/default-list-filters.js +0 -0
  162. /package/{dist → lib}/page/mountable.js +0 -0
  163. /package/{dist → lib}/page/page.js +0 -0
  164. /package/{dist → lib}/page/props-parser.js +0 -0
  165. /package/{dist → lib}/run.js +0 -0
  166. /package/{dist → lib}/sanitize.js +0 -0
  167. /package/{dist → lib}/target-locreq.js +0 -0
  168. /package/{dist → lib}/templates/collection.js +0 -0
  169. /package/{dist → lib}/templates/form.js +0 -0
  170. /package/{dist → lib}/templates/list.js +0 -0
  171. /package/{dist → lib}/templates/long-running-process.js +0 -0
  172. /package/{dist → lib}/templates/multiform.js +0 -0
  173. /package/{dist → lib}/templates/page.js +0 -0
  174. /package/{dist → lib}/templates/post.js +0 -0
  175. /package/{dist → lib}/templates/redirect.js +0 -0
  176. /package/{dist → lib}/templates/route-test.js +0 -0
  177. /package/{dist → lib}/templates/stateful-page.js +0 -0
  178. /package/{dist → lib}/templates/stimulus-controller.js +0 -0
  179. /package/{dist → lib}/templates/templates.js +0 -0
  180. /package/{dist → lib}/test_utils/locator_is_visible.js +0 -0
  181. /package/{dist → lib}/utils/assert-throws.js +0 -0
  182. /package/{dist → lib}/utils/base64.js +0 -0
  183. /package/{dist → lib}/utils/browser-creator.js +0 -0
  184. /package/{dist → lib}/utils/escape-url-params.js +0 -0
  185. /package/{dist → lib}/utils/exec.js +0 -0
  186. /package/{dist → lib}/utils/format-external-url.js +0 -0
  187. /package/{dist → lib}/utils/import-path.js +0 -0
  188. /package/{dist → lib}/utils/input-wrapper.js +0 -0
  189. /package/{dist → lib}/utils/list-collections.js +0 -0
  190. /package/{dist → lib}/utils/make-slug.js +0 -0
  191. /package/{dist → lib}/utils/module-dirname.js +0 -0
  192. /package/{dist → lib}/utils/natural-numbers.js +0 -0
  193. /package/{dist → lib}/utils/prettier.js +0 -0
  194. /package/{dist → lib}/utils/question.js +0 -0
  195. /package/{dist → lib}/utils/render-attributes.js +0 -0
  196. /package/{dist → lib}/utils/sleep.js +0 -0
  197. /package/{dist → lib}/utils/translate.js +0 -0
  198. /package/{dist → lib}/utils/url-with-new-params.js +0 -0
  199. /package/{dist → lib}/utils/utils.js +0 -0
  200. /package/{dist → lib}/utils/walk.js +0 -0
package/.eslintrc.cjs ADDED
@@ -0,0 +1,38 @@
1
+ module.exports = {
2
+ env: { node: true },
3
+ parser: "@typescript-eslint/parser",
4
+ plugins: ["@typescript-eslint", "prettier"],
5
+ extends: [
6
+ "eslint:recommended",
7
+ "plugin:@typescript-eslint/recommended",
8
+ "plugin:@typescript-eslint/recommended-requiring-type-checking",
9
+ "plugin:prettier/recommended",
10
+ ],
11
+ ignorePatterns: [".eslintrc.js", "src/**/*.test.ts", "@types/*"],
12
+ parserOptions: {
13
+ sourceType: "module",
14
+ ecmaFeatures: {
15
+ modules: true,
16
+ },
17
+ project: ["./tsconfig.json"],
18
+ },
19
+ rules: {
20
+ "@typescript-eslint/require-await": 0,
21
+ "no-await-in-loop": 2,
22
+ "@typescript-eslint/no-unused-vars": ["warn", { args: "none", "varsIgnorePattern": "^_", }],
23
+ },
24
+ settings: { jsdoc: { mode: "typescript" } },
25
+ overrides: [
26
+ {
27
+ files: ["*.subtest.ts", "*.test.ts"],
28
+ rules: {
29
+ "@typescript-eslint/no-unsafe-member-access": 0,
30
+ "prefer-const": 0,
31
+ "@typescript-eslint/no-unsafe-call": 0,
32
+ "@typescript-eslint/no-unsafe-return": 0,
33
+ "@typescript-eslint/no-unsafe-assignment": 0,
34
+ "no-await-in-loop": 1, // sometimes it's easier to debug when requests run sequentially
35
+ },
36
+ },
37
+ ],
38
+ };
package/.xunit ADDED
@@ -0,0 +1,53 @@
1
+ <testsuite name="Mocha Tests" tests="51" failures="0" errors="0" skipped="0" timestamp="Mon, 29 Apr 2024 11:24:39 GMT" time="19.296">
2
+ <testcase classname="add route test" name="creates minimal sealious app" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/add-route.test.js" time="7.334"/>
3
+ <testcase classname="empty test" name="empty test" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/example.test.js" time="0"/>
4
+ <testcase classname="checkboxed-list basic tests" name="sends the values" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/controls/checkboxed-list-input.test.js" time="1.12"/>
5
+ <testcase classname="photo-control basic tests" name="sends the old photo if it wasn&#x27;t changed and it has an initial value" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/controls/photo.test.js" time="0.248"/>
6
+ <testcase classname="boolean field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/boolean.test.js" time="0.001"/>
7
+ <testcase classname="boolean field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/boolean.test.js" time="0"/>
8
+ <testcase classname="email field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/email.test.js" time="0.001"/>
9
+ <testcase classname="email field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/email.test.js" time="0"/>
10
+ <testcase classname="enum-multiple field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum-multiple.test.js" time="0.001"/>
11
+ <testcase classname="enum-multiple field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum-multiple.test.js" time="0"/>
12
+ <testcase classname="enum field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum.test.js" time="0"/>
13
+ <testcase classname="enum field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/enum.test.js" time="0"/>
14
+ <testcase classname="number field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/number.test.js" time="0.001"/>
15
+ <testcase classname="number field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/number.test.js" time="0"/>
16
+ <testcase classname="pick-from-list field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/pick-from-list.test.js" time="0"/>
17
+ <testcase classname="regexp field" name="validation logic" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/regexp.test.js" time="0"/>
18
+ <testcase classname="regexp field" name="parse function" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/fields/regexp.test.js" time="0"/>
19
+ <testcase classname="form test basic tests" name="does not allow to submit an empty form when there&#x27;s a required field" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.573"/>
20
+ <testcase classname="form test basic tests" name="allows to submit a form when all required fields have a value" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.194"/>
21
+ <testcase classname="form test basic tests" name="does not allow submitting an empty form by circumventing HTML-based validation" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.014"/>
22
+ <testcase classname="form test canAccess tests" name="allows visit when configured when canAccess returns true" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.011"/>
23
+ <testcase classname="form test canAccess tests" name="passes the context to canAccess (false case)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.013"/>
24
+ <testcase classname="form test canAccess tests" name="passes the context to canAccess (true case)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.011"/>
25
+ <testcase classname="form test canAccess tests declines access when canAccess returns false" name="prevents the form from rendering" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.007"/>
26
+ <testcase classname="form test canAccess tests declines access when canAccess returns false" name="does not allow submitting of the form through axios" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.002"/>
27
+ <testcase classname="form test validation e2e validation message" name="shows up when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.221"/>
28
+ <testcase classname="form test validation e2e validation message" name="doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.627"/>
29
+ <testcase classname="form test validation e2e field specific validation message" name="shows up when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.197"/>
30
+ <testcase classname="form test validation e2e field specific validation message" name="doesn&#x27;t show up when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.151"/>
31
+ <testcase classname="form test getInitialValues tests" name="fills the form with values from getInitialValues" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/form.test.js" time="0.035"/>
32
+ <testcase classname="multiform test basic tests turbolinks + js enabled" name="checking whether only one submit handler is run" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.561"/>
33
+ <testcase classname="multiform test basic tests turbolinks + js enabled" name="checking whether the input in the not submitted form prevails" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.003"/>
34
+ <testcase classname="multiform test basic tests turbolinks + js disabled" name="checking whether only one submit handler is run" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.572"/>
35
+ <testcase classname="multiform test basic tests turbolinks + js disabled" name="checking whether the input in the not submitted form prevails" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.003"/>
36
+ <testcase classname="multiform test canAccess allow access to both forms when both canAccess return true" name="check wether it renders" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.436"/>
37
+ <testcase classname="multiform test canAccess allow access to both forms when both canAccess return true" name="check wether you can submit through http (axios)" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.005"/>
38
+ <testcase classname="multiform test canAccess deny access to both forms" name="check wether forms didnt render" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.642"/>
39
+ <testcase classname="multiform test canAccess deny access to both forms" name="check wether it&#x27;s possible to submit through http" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.004"/>
40
+ <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether form1 renders" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.359"/>
41
+ <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether it&#x27;s possible to submit to form1 through http" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.003"/>
42
+ <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether form2 does not render" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.323"/>
43
+ <testcase classname="multiform test canAccess allow access to one form, deny to the other" name="check wether it&#x27;s possible to submit to form2 through http" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.003"/>
44
+ <testcase classname="multiform test validation e2e basic tests" name="js enabled" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="1.12"/>
45
+ <testcase classname="multiform test validation e2e basic tests" name="js disabled" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.859"/>
46
+ <testcase classname="multiform test validation e2e field specific validation js enabled" name="validation message shows when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.213"/>
47
+ <testcase classname="multiform test validation e2e field specific validation js enabled" name="validation message doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.137"/>
48
+ <testcase classname="multiform test validation e2e field specific validation js disabled" name="validation message shows when incorrect input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.239"/>
49
+ <testcase classname="multiform test validation e2e field specific validation js disabled" name="validation message doesn&#x27;t show when correct input is given" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/forms/multiform.test.js" time="0.212"/>
50
+ <testcase classname="generate routes" name="handles a url with params" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/generate-routes.test.js" time="0.127"/>
51
+ <testcase classname="generate routes" name="handles polish characters in the url" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/generate-routes.test.js" time="0"/>
52
+ <testcase classname="generate routes" name="handles a url with params and diacritics" file="/home/kuba/projects/sealcode/sealgen/lib-instrumented/generate-routes.test.js" time="0.007"/>
53
+ </testsuite>
@@ -1,6 +1,6 @@
1
1
  /// <reference types="koa__router" />
2
2
  import Router from "@koa/router";
3
- import { BaseContext } from "koa";
3
+ import { BaseContext, Context } from "koa";
4
4
  import { Templatable } from "tempstream";
5
5
  import { ExtractTail } from "../utils/utils.js";
6
6
  import { Mountable } from "./mountable.js";
@@ -31,7 +31,7 @@ export declare abstract class StatefulPage<State extends Record<string, unknown>
31
31
  }>;
32
32
  constructor();
33
33
  abstract wrapInLayout(ctx: BaseContext, content: Templatable, state: State): Templatable;
34
- wrapInForm(state: State, content: Templatable): Templatable;
34
+ wrapInForm(context: Context, state: State, content: Templatable): Promise<Templatable>;
35
35
  extractActionAndLabel<ActionName extends keyof Actions>(action_description: StatefulPageActionDescription<ActionName>): {
36
36
  action: string;
37
37
  label: string;
@@ -46,6 +46,8 @@ export declare abstract class StatefulPage<State extends Record<string, unknown>
46
46
  rerender(): string;
47
47
  preprocessState(values: State): Promise<State>;
48
48
  preprocessOverrides(state: State, values: Record<string, unknown>): Promise<Record<string, unknown>>;
49
+ serializeState(_context: BaseContext, state: State): Promise<string>;
50
+ deserializeState(_context: BaseContext, s: string): Promise<State>;
49
51
  extractState(ctx: BaseContext): Promise<StateAndMetadata<State, Actions>>;
50
52
  mount(router: Router, path: string): void;
51
53
  }
package/build.js CHANGED
@@ -11,7 +11,7 @@ const args = {
11
11
  entryPoints,
12
12
  sourcemap: true,
13
13
  bundle: false,
14
- outdir: "./dist/",
14
+ outdir: "./lib/",
15
15
  logLevel: "info",
16
16
  platform: "node",
17
17
  target: "es2022",
@@ -46,7 +46,7 @@ describe("add route test", () => {
46
46
  it("creates minimal sealious app", async function() {
47
47
  console.log(" cloning sealious-minimal...");
48
48
  await execAsync(
49
- `git clone https://hub.sealcode.org/source/sealious-minimal.git ${app_path} && cd ${app_path} && git checkout 710b873`
49
+ `git clone https://hub.sealcode.org/source/sealious-minimal.git ${app_path} && cd ${app_path} && git checkout 5b33aac`
50
50
  );
51
51
  console.log(" installing dependencies and sealgen...");
52
52
  await execAsync(
@@ -93,6 +93,6 @@ describe("add route test", () => {
93
93
  if (res.status != 200) {
94
94
  throw new Error("url generated by add-route exists but doesnt return 200");
95
95
  }
96
- }, 25e4);
96
+ });
97
97
  });
98
98
  //# sourceMappingURL=add-route.test.js.map
@@ -40,19 +40,19 @@ async function build(watch) {
40
40
  const port = await get_notifier_port();
41
41
  const notifier = make_notifier(port);
42
42
  await write_notifier_config(watch, port);
43
- watcher.on("all", async (_, file_path) => {
43
+ watcher.on("all", (_, file_path) => {
44
44
  console.log("Detected a change!", file_path);
45
45
  builders.forEach((builder) => {
46
46
  const owns_a_file = builder.ownsFile(file_path);
47
47
  if (owns_a_file) {
48
- builder.build(notifier);
48
+ void builder.build(notifier);
49
49
  }
50
50
  });
51
51
  });
52
52
  } else {
53
53
  await write_notifier_config(watch);
54
54
  builders.forEach((builder) => {
55
- builder.dispose();
55
+ void builder.dispose();
56
56
  });
57
57
  }
58
58
  }
@@ -71,6 +71,7 @@ class FontsBuilder extends Builder {
71
71
  ownsFile(file_path) {
72
72
  return file_path == FONTS_CONFIG_PATH;
73
73
  }
74
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
74
75
  async dispose() {
75
76
  }
76
77
  async _build() {
@@ -84,6 +85,7 @@ class BackendTSBuilder extends Builder {
84
85
  ownsFile(file_path) {
85
86
  return (file_path.endsWith(".ts") || file_path.endsWith(".tsx")) && !file_path.endsWith("src/back/collections/collections.ts") && !file_path.endsWith("src/back/routes/routes.ts") && !file_path.endsWith("src/back/routes/urls.ts") && !file_path.endsWith("stimulus.ts") && !file_path.startsWith("src/front");
86
87
  }
88
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
87
89
  async dispose() {
88
90
  }
89
91
  async _build() {
@@ -121,6 +123,7 @@ class FrontendTSBuilder extends Builder {
121
123
  ownsFile(file_path) {
122
124
  return file_path.startsWith("src/front") || file_path.endsWith(".stimulus.ts");
123
125
  }
126
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
124
127
  async dispose() {
125
128
  }
126
129
  async _build() {
package/lib/cli.js ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import { addCollection } from "./add-collection.js";
3
+ import { addJDDComponent } from "./add-jdd-component.js";
4
+ import { addRoute } from "./add-route.js";
5
+ import { buildProject } from "./build.js";
6
+ import { generate_css_includes } from "./find-css-includes.js";
7
+ import { generateCollections } from "./generate-collections.js";
8
+ import { generateComponents } from "./generate-components.js";
9
+ import { generateRoutes } from "./generate-routes.js";
10
+ import { makeEnv } from "./make-env.js";
11
+ import yargs from "yargs/yargs";
12
+ import { getFonts } from "./get-fonts.js";
13
+ import { generateStimulusControllers } from "./generate-stimulus.js";
14
+ const actions = {
15
+ "add-collection": addCollection,
16
+ "add-route": addRoute,
17
+ "generate-collections": generateCollections,
18
+ "generate-components": generateComponents,
19
+ "generate-routes": generateRoutes,
20
+ "generate-css-includes": generate_css_includes,
21
+ build: buildProject,
22
+ default: async function() {
23
+ console.log("Usage: `npx sealgen <action>`");
24
+ console.log(
25
+ `Available actions: ${Object.keys(actions).filter((e) => e != "default").join(", ")}`
26
+ );
27
+ },
28
+ "make-env": makeEnv,
29
+ "add-component": addJDDComponent,
30
+ "get-fonts": getFonts,
31
+ "generate-stimulus": generateStimulusControllers
32
+ };
33
+ void async function() {
34
+ const action = process.argv.at(2);
35
+ const fn = actions[action || "default"] || actions.default;
36
+ const args = yargs(process.argv).argv;
37
+ await fn(args);
38
+ }();
39
+ //# sourceMappingURL=cli.js.map
@@ -9,7 +9,7 @@ function addSuffix(filename, suffix) {
9
9
  return filename.replace(/(\.[a-zA-Z0-9]+)?$/, suffix + "$1");
10
10
  }
11
11
  async function makeResourceURL(file_path) {
12
- const hash_base = file_path + (await fs.stat(file_path)).mtimeMs;
12
+ const hash_base = file_path + (await fs.stat(file_path)).mtimeMs.toString();
13
13
  const hash = md5(hash_base);
14
14
  const public_url = "dist/" + addSuffix(basename(file_path), "-" + hash.slice(0, 8));
15
15
  const public_dir = "public";
@@ -29,7 +29,7 @@ const load_assets_plugin = {
29
29
  )
30
30
  },
31
31
  async (args) => {
32
- let contents = `export const url = "${await makeResourceURL(
32
+ const contents = `export const url = "${await makeResourceURL(
33
33
  args.path
34
34
  )}";
35
35
 
@@ -26,7 +26,6 @@ class StructuredArray extends FormFieldControl {
26
26
  return {};
27
27
  }
28
28
  makeSubfield(_field_name) {
29
- const fields = this;
30
29
  return new SimpleFormField(false);
31
30
  }
32
31
  async renderItemControl(ctx, form_id, control, item, index) {
@@ -123,7 +122,7 @@ class StructuredArray extends FormFieldControl {
123
122
  mount(router) {
124
123
  console.log("mounting!", this.getActionURL());
125
124
  router.post(this.getActionURL(), async (ctx) => {
126
- let form_id = ctx.query.form_id;
125
+ const form_id = ctx.query.form_id;
127
126
  if (typeof form_id != "string") {
128
127
  throw new Error("Missing form_id query param");
129
128
  }
@@ -1,3 +1,4 @@
1
+ import { tempstream } from "tempstream";
1
2
  import { SimpleInput } from "./simple-input.js";
2
3
  class Autocomplete extends SimpleInput {
3
4
  constructor(field, options) {
@@ -15,17 +16,14 @@ class Autocomplete extends SimpleInput {
15
16
  };
16
17
  }
17
18
  async postInput(ctx) {
18
- return (
19
- /* HTML */
20
- `<datalist id="${this.getListID()}">
19
+ return tempstream`<datalist id="${this.getListID()}">
21
20
  ${(await this.field.generateOptions(ctx)).map(
22
- ({ value }) => (
23
- /* HTML */
24
- `<option>${value}</option>`
25
- )
26
- )}
27
- </datalist>`
28
- );
21
+ ({ value }) => (
22
+ /* HTML */
23
+ `<option>${value}</option>`
24
+ )
25
+ )}
26
+ </datalist>`;
29
27
  }
30
28
  }
31
29
  export {
@@ -6,12 +6,13 @@ import { CheckboxedListField } from "../fields/checkboxed-list.js";
6
6
  import { Form } from "../form.js";
7
7
  import { CheckboxedListInput } from "./checkboxed-list-input.js";
8
8
  import { getBrowser } from "../../utils/browser-creator.js";
9
- describe.only("checkboxed-list", () => {
9
+ import assert from "assert";
10
+ describe("checkboxed-list", () => {
10
11
  describe("basic tests", async () => {
11
12
  let server;
12
13
  let browser;
13
14
  let page;
14
- afterAll(() => {
15
+ afterEach(() => {
15
16
  server.close();
16
17
  });
17
18
  it("sends the values", async () => {
@@ -1,3 +1,4 @@
1
+ import { tempstream } from "tempstream";
1
2
  import { FieldGroup } from "./field-group.js";
2
3
  import { randomUUID } from "crypto";
3
4
  class CollapsibleFieldGroup extends FieldGroup {
@@ -11,7 +12,7 @@ class CollapsibleFieldGroup extends FieldGroup {
11
12
  this.collapseID = this.options.groupID + "collapse";
12
13
  }
13
14
  getGroupLabelProps() {
14
- return super.getGroupLabelProps() + ` for="${this.collapseID}"`;
15
+ return tempstream`${super.getGroupLabelProps()} for="${this.collapseID}"`;
15
16
  }
16
17
  preLabelContainer() {
17
18
  return (
@@ -29,7 +29,10 @@ class EditableCollectionSubset extends FormFieldControl {
29
29
  method="POST"
30
30
  action="${fctx.ctx.path}"
31
31
  >
32
- <span>${text}</span>
32
+ <span
33
+ >${// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
34
+ text}</span
35
+ >
33
36
  <input
34
37
  type="hidden"
35
38
  name="${this.field.name}"
@@ -61,9 +64,8 @@ class EditableCollectionSubset extends FormFieldControl {
61
64
  value
62
65
  )
63
66
  ).map(
64
- ([value, text]) => `<option value="${attribute(
65
- value
66
- )}">${text}</option>`
67
+ ([value, text]) => `<option value="${attribute(value)}">${// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
68
+ text}</option>`
67
69
  )
68
70
  )}
69
71
  </select>
@@ -34,7 +34,7 @@ class FieldGroup extends FormFieldControl {
34
34
  ${this.preLabelContainer()}
35
35
  <div class="field-group__label-container">
36
36
  ${this.preLabel()}
37
- ${label ? `<label ${this.getGroupLabelProps()}>${label}</label>` : ""}
37
+ ${label ? tempstream`<label ${this.getGroupLabelProps()}>${label}</label>` : ""}
38
38
  ${this.postLabel()}
39
39
  </div>
40
40
  ${this.preFields()}
@@ -11,12 +11,9 @@ class File extends SimpleInput {
11
11
  if (!file) {
12
12
  return empty_container;
13
13
  }
14
- return (
15
- /* HTML */
16
- `<div class="${class_name}">
14
+ return tempstream`<div class="${class_name}">
17
15
  ${file.getOriginalFilename()}
18
- </div>`
19
- );
16
+ </div>`;
20
17
  }
21
18
  async preInput(fctx, data) {
22
19
  const { parsed } = await this.field.getValue(fctx.ctx, data);
@@ -9,7 +9,8 @@ class FormControlContext {
9
9
  }
10
10
  }
11
11
  class FormControl {
12
- mount(router) {
12
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
13
+ mount(_router) {
13
14
  }
14
15
  }
15
16
  export {
@@ -9,7 +9,7 @@ class Photo extends File {
9
9
  async getImgStyle() {
10
10
  return "width: 100px; height: 100px; object-fit: contain";
11
11
  }
12
- async renderFilePreview(ctx, file) {
12
+ async renderFilePreview(_ctx, file) {
13
13
  const class_name = "file_preview";
14
14
  const empty_container = `<div class="${class_name}"></div>`;
15
15
  if (!file) {
@@ -10,13 +10,14 @@ import { KoaResponsiveImageRouter } from "koa-responsive-image-router";
10
10
  import _locreq from "locreq";
11
11
  import { module_dirname } from "../../utils/module-dirname.js";
12
12
  import { FileManager, PathFilePointer } from "@sealcode/file-manager";
13
+ import assert from "node:assert";
13
14
  const locreq = _locreq(module_dirname(import.meta.url));
14
- describe("photo-controll", () => {
15
+ describe("photo-control", () => {
15
16
  describe("basic tests", async () => {
16
17
  let server;
17
18
  let browser;
18
19
  let page;
19
- afterAll(() => {
20
+ after(() => {
20
21
  server.close();
21
22
  });
22
23
  it("sends the old photo if it wasn't changed and it has an initial value", async () => {
@@ -45,12 +46,10 @@ describe("photo-controll", () => {
45
46
  this.controls = [new Photo(fields.photo, imageRouter)];
46
47
  }
47
48
  async onSubmit(ctx) {
48
- console.log("OnSubmit!");
49
49
  const data = await this.getParsedValues(ctx);
50
- console.log({ data });
51
50
  received_photo = data.photo;
52
51
  }
53
- async getInitialValues(ctx) {
52
+ async getInitialValues(_ctx) {
54
53
  const file = new PathFilePointer(
55
54
  new FileManager("/tmp", "/uploaded_files"),
56
55
  locreq.resolve("assets/important.png")
@@ -73,9 +72,8 @@ describe("photo-controll", () => {
73
72
  page = await context.newPage();
74
73
  await page.goto(`http://localhost:${port}`);
75
74
  await page.getByRole("button", { name: "Wy\u015Blij" }).click();
76
- console.log({ received_photo });
77
75
  assert(received_photo !== void 0 && received_photo.old !== null);
78
76
  });
79
- });
77
+ }).timeout(99999999999);
80
78
  });
81
79
  //# sourceMappingURL=photo.test.js.map
@@ -30,7 +30,7 @@ class Textarea extends SimpleInput {
30
30
  const { parsed: value } = await this.field.getValue(ctx, data);
31
31
  return (
32
32
  /* HTML */
33
- `<textarea ${attributes}>${value}</textarea>`
33
+ `<textarea ${attributes}>${value || ""}</textarea>`
34
34
  );
35
35
  }
36
36
  }
@@ -1,4 +1,3 @@
1
- import { describe, it } from "vitest";
2
1
  import assert from "assert";
3
2
  import { Fields } from "../../index.js";
4
3
  describe("boolean field", () => {
@@ -28,7 +28,7 @@ class FormField {
28
28
  }
29
29
  return this.isValueValid(ctx, value);
30
30
  }
31
- async isValueValid(ctx, value) {
31
+ async isValueValid(_ctx, _value) {
32
32
  return { valid: true, message: "" };
33
33
  }
34
34
  async getValue(ctx, all_form_values) {
@@ -54,10 +54,7 @@ class FormField {
54
54
  message: parse_error || "Error"
55
55
  };
56
56
  }
57
- const { valid, message } = await this._validate(
58
- ctx,
59
- parsed_value
60
- );
57
+ const { valid, message } = await this._validate(ctx, parsed_value);
61
58
  return {
62
59
  parsed: parsed_value,
63
60
  valid,
@@ -7,7 +7,7 @@ class File extends FormField {
7
7
  this.required = required;
8
8
  this.file_manager = file_manager;
9
9
  }
10
- async parse(ctx, raw_value) {
10
+ async parse(_ctx, raw_value) {
11
11
  let result;
12
12
  if (is(raw_value, predicates.string)) {
13
13
  const file = await this.file_manager.fromToken(raw_value);
@@ -23,7 +23,13 @@ class File extends FormField {
23
23
  parsable: false
24
24
  };
25
25
  } else {
26
- const old_file = hasFieldOfType(raw_value, "old", predicates.string) ? await this.file_manager.fromToken(raw_value.old) : null;
26
+ const old_file = hasFieldOfType(
27
+ raw_value,
28
+ "old",
29
+ predicates.or(predicates.string, predicates.object)
30
+ ) ? await this.file_manager.toPointer(
31
+ raw_value.old
32
+ ) : null;
27
33
  const new_file = hasFieldOfType(
28
34
  raw_value,
29
35
  "new",
@@ -4,7 +4,7 @@ class StructuredArrayField extends FormField {
4
4
  super(true);
5
5
  this.sealious_field = sealious_field;
6
6
  }
7
- async parse(context, value) {
7
+ async parse(_context, value) {
8
8
  return {
9
9
  parsable: true,
10
10
  error: null,
@@ -1,5 +1,4 @@
1
1
  import Router from "@koa/router";
2
- import { describe, it, beforeAll, afterAll, afterEach, beforeEach } from "vitest";
3
2
  import axios from "axios";
4
3
  import Koa from "koa";
5
4
  import { Controls, Fields, Form } from "../index.js";
@@ -38,14 +37,14 @@ const port = await getPort();
38
37
  console.log("Using port " + port + " for form.test.ts");
39
38
  describe("form test", () => {
40
39
  let page;
41
- beforeAll(async () => {
40
+ before(async () => {
42
41
  const browser = await getBrowser();
43
42
  const context = await browser.newContext();
44
43
  page = await context.newPage();
45
44
  });
46
45
  describe("basic tests", async () => {
47
46
  let server;
48
- beforeAll(async () => {
47
+ before(async () => {
49
48
  const app = new Koa();
50
49
  const router = new Router();
51
50
  mount(router, "/", form_factory(), true);
@@ -53,7 +52,7 @@ describe("form test", () => {
53
52
  server = app.listen(port);
54
53
  await page.goto(`http://localhost:${port}`);
55
54
  });
56
- afterAll(async () => {
55
+ after(async () => {
57
56
  server.close();
58
57
  });
59
58
  it("does not allow to submit an empty form when there's a required field", async () => {
@@ -115,7 +114,7 @@ describe("form test", () => {
115
114
  describe("declines access when canAccess returns false", async () => {
116
115
  const app = new Koa();
117
116
  const router = new Router();
118
- beforeAll(async () => {
117
+ before(async () => {
119
118
  mount(
120
119
  router,
121
120
  "/",
@@ -206,7 +205,7 @@ describe("form test", () => {
206
205
  describe("validation e2e", async () => {
207
206
  describe("validation message", async () => {
208
207
  let server;
209
- beforeAll(async () => {
208
+ before(async () => {
210
209
  const app = new Koa();
211
210
  const router = new Router();
212
211
  mount(
@@ -242,7 +241,7 @@ describe("form test", () => {
242
241
  server = app.listen(port);
243
242
  await page.goto(`http://localhost:${port}`);
244
243
  });
245
- afterAll(async () => {
244
+ after(async () => {
246
245
  server.close();
247
246
  });
248
247
  it("shows up when incorrect input is given", async () => {
@@ -263,7 +262,7 @@ describe("form test", () => {
263
262
  });
264
263
  describe("field specific validation message", async () => {
265
264
  let server;
266
- beforeAll(async () => {
265
+ before(async () => {
267
266
  const app = new Koa();
268
267
  const router = new Router();
269
268
  const fields2 = {
@@ -294,7 +293,7 @@ describe("form test", () => {
294
293
  server = app.listen(port);
295
294
  await page.goto(`http://localhost:${port}`);
296
295
  });
297
- afterAll(async () => {
296
+ after(async () => {
298
297
  server.close();
299
298
  });
300
299
  it("shows up when incorrect input is given", async () => {