@sealcode/sealgen 0.12.0 → 0.12.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 (268) hide show
  1. package/dist/notifier.js +1 -1
  2. package/package.json +2 -2
  3. package/src/notifier.ts +1 -1
  4. package/.madgerc +0 -7
  5. package/coverage/.tmp/coverage-15.json +0 -1
  6. package/coverage/.tmp/coverage-16.json +0 -1
  7. package/coverage/.tmp/coverage-17.json +0 -1
  8. package/coverage/.tmp/coverage-18.json +0 -1
  9. package/coverage/.tmp/coverage-19.json +0 -1
  10. package/coverage/.tmp/coverage-20.json +0 -1
  11. package/coverage/.tmp/coverage-21.json +0 -1
  12. package/coverage/.tmp/coverage-22.json +0 -1
  13. package/coverage/.tmp/coverage-23.json +0 -1
  14. package/coverage/.tmp/coverage-24.json +0 -1
  15. package/coverage/.tmp/coverage-25.json +0 -1
  16. package/coverage/.tmp/coverage-26.json +0 -1
  17. package/lib/add-collection.js +0 -24
  18. package/lib/add-jdd-component.js +0 -27
  19. package/lib/add-route.js +0 -65
  20. package/lib/add-route.test.js +0 -60
  21. package/lib/build.js +0 -187
  22. package/lib/cli.js +0 -35
  23. package/lib/components/components.js +0 -3
  24. package/lib/components/tabs.js +0 -88
  25. package/lib/components/toggle-modal.js +0 -46
  26. package/lib/example.test.js +0 -5
  27. package/lib/find-css-includes.js +0 -23
  28. package/lib/forms/controls/array.js +0 -140
  29. package/lib/forms/controls/autocomplete.js +0 -23
  30. package/lib/forms/controls/big-radio-group.js +0 -34
  31. package/lib/forms/controls/checkbox-group.js +0 -29
  32. package/lib/forms/controls/checkbox.js +0 -24
  33. package/lib/forms/controls/checkboxed-list-input.js +0 -35
  34. package/lib/forms/controls/collapsible-checkbox-group.js +0 -13
  35. package/lib/forms/controls/collapsible-field-group.js +0 -78
  36. package/lib/forms/controls/controls.js +0 -31
  37. package/lib/forms/controls/derived-frame.js +0 -52
  38. package/lib/forms/controls/derived.js +0 -77
  39. package/lib/forms/controls/dropdown.js +0 -55
  40. package/lib/forms/controls/editable-collection-subset.js +0 -68
  41. package/lib/forms/controls/field-group.js +0 -53
  42. package/lib/forms/controls/file.js +0 -35
  43. package/lib/forms/controls/form-control.js +0 -14
  44. package/lib/forms/controls/form-field-control.js +0 -9
  45. package/lib/forms/controls/form-header.js +0 -14
  46. package/lib/forms/controls/form-paragraph.js +0 -12
  47. package/lib/forms/controls/frame.js +0 -25
  48. package/lib/forms/controls/hidden-input.js +0 -14
  49. package/lib/forms/controls/html.js +0 -23
  50. package/lib/forms/controls/multiple-files.js +0 -160
  51. package/lib/forms/controls/multiple-photos.js +0 -33
  52. package/lib/forms/controls/number.js +0 -25
  53. package/lib/forms/controls/photo.js +0 -57
  54. package/lib/forms/controls/radio.js +0 -25
  55. package/lib/forms/controls/reverse-single-reference.js +0 -47
  56. package/lib/forms/controls/simple-input.js +0 -78
  57. package/lib/forms/controls/textarea.js +0 -33
  58. package/lib/forms/controls/tickable.js +0 -75
  59. package/lib/forms/fields/boolean.js +0 -51
  60. package/lib/forms/fields/boolean.test.js +0 -32
  61. package/lib/forms/fields/checkboxed-list.js +0 -40
  62. package/lib/forms/fields/collection-field.js +0 -29
  63. package/lib/forms/fields/email.js +0 -11
  64. package/lib/forms/fields/email.test.js +0 -20
  65. package/lib/forms/fields/enum-multiple.js +0 -47
  66. package/lib/forms/fields/enum-multiple.test.js +0 -27
  67. package/lib/forms/fields/enum.js +0 -39
  68. package/lib/forms/fields/enum.test.js +0 -21
  69. package/lib/forms/fields/existing-sealious-value.js +0 -16
  70. package/lib/forms/fields/field.js +0 -81
  71. package/lib/forms/fields/file.js +0 -53
  72. package/lib/forms/fields/multiple-files.js +0 -15
  73. package/lib/forms/fields/number.js +0 -45
  74. package/lib/forms/fields/number.test.js +0 -30
  75. package/lib/forms/fields/pick-from-list.js +0 -31
  76. package/lib/forms/fields/pick-from-list.test.js +0 -17
  77. package/lib/forms/fields/proxy-field.js +0 -20
  78. package/lib/forms/fields/regexp.js +0 -40
  79. package/lib/forms/fields/regexp.test.js +0 -21
  80. package/lib/forms/fields/reverse-single-reference.js +0 -14
  81. package/lib/forms/fields/simple-form-field.js +0 -20
  82. package/lib/forms/fields/structured-array.js +0 -18
  83. package/lib/forms/form.js +0 -176
  84. package/lib/forms/form.test.js +0 -1
  85. package/lib/forms/multiform.js +0 -174
  86. package/lib/forms/multiform.test.js +0 -426
  87. package/lib/generate-collections.js +0 -52
  88. package/lib/generate-components.js +0 -33
  89. package/lib/generate-routes.js +0 -75
  90. package/lib/index.js +0 -17
  91. package/lib/make-env.js +0 -14
  92. package/lib/make-hidden-inputs.js +0 -14
  93. package/lib/mount.js +0 -70
  94. package/lib/notifier.js +0 -19
  95. package/lib/page/access-control.js +0 -16
  96. package/lib/page/default-list-filters.js +0 -40
  97. package/lib/page/list.js +0 -183
  98. package/lib/page/mountable-with-fields.js +0 -85
  99. package/lib/page/mountable.js +0 -5
  100. package/lib/page/page.js +0 -26
  101. package/lib/page/props-parser.js +0 -23
  102. package/lib/page/sealious-list.js +0 -59
  103. package/lib/page/stateful-page.js +0 -97
  104. package/lib/remove-named-imports.js +0 -47
  105. package/lib/run.js +0 -2
  106. package/lib/sanitize.js +0 -10
  107. package/lib/src/add-collection.js +0 -24
  108. package/lib/src/add-jdd-component.js +0 -27
  109. package/lib/src/add-route.js +0 -65
  110. package/lib/src/add-route.test.js +0 -72
  111. package/lib/src/build.js +0 -142
  112. package/lib/src/cli.js +0 -37
  113. package/lib/src/components/components.js +0 -3
  114. package/lib/src/components/tabs.js +0 -88
  115. package/lib/src/components/toggle-modal.js +0 -46
  116. package/lib/src/example.test.js +0 -5
  117. package/lib/src/find-css-includes.js +0 -23
  118. package/lib/src/forms/controls/array.js +0 -141
  119. package/lib/src/forms/controls/autocomplete.js +0 -23
  120. package/lib/src/forms/controls/big-radio-group.js +0 -34
  121. package/lib/src/forms/controls/checkbox-group.js +0 -30
  122. package/lib/src/forms/controls/checkbox.js +0 -24
  123. package/lib/src/forms/controls/checkboxed-list-input.js +0 -35
  124. package/lib/src/forms/controls/collapsible-checkbox-group.js +0 -13
  125. package/lib/src/forms/controls/collapsible-field-group.js +0 -78
  126. package/lib/src/forms/controls/controls.js +0 -31
  127. package/lib/src/forms/controls/derived-frame.js +0 -52
  128. package/lib/src/forms/controls/derived.js +0 -77
  129. package/lib/src/forms/controls/dropdown.js +0 -55
  130. package/lib/src/forms/controls/editable-collection-subset.js +0 -68
  131. package/lib/src/forms/controls/field-group.js +0 -53
  132. package/lib/src/forms/controls/file.js +0 -35
  133. package/lib/src/forms/controls/form-control.js +0 -14
  134. package/lib/src/forms/controls/form-field-control.js +0 -9
  135. package/lib/src/forms/controls/form-header.js +0 -14
  136. package/lib/src/forms/controls/form-paragraph.js +0 -12
  137. package/lib/src/forms/controls/frame.js +0 -25
  138. package/lib/src/forms/controls/hidden-input.js +0 -14
  139. package/lib/src/forms/controls/html.js +0 -23
  140. package/lib/src/forms/controls/multiple-files.js +0 -160
  141. package/lib/src/forms/controls/multiple-photos.js +0 -33
  142. package/lib/src/forms/controls/number.js +0 -25
  143. package/lib/src/forms/controls/photo.js +0 -57
  144. package/lib/src/forms/controls/radio.js +0 -25
  145. package/lib/src/forms/controls/reverse-single-reference.js +0 -47
  146. package/lib/src/forms/controls/simple-input.js +0 -78
  147. package/lib/src/forms/controls/textarea.js +0 -33
  148. package/lib/src/forms/controls/tickable.js +0 -75
  149. package/lib/src/forms/fields/boolean.js +0 -51
  150. package/lib/src/forms/fields/boolean.test.js +0 -33
  151. package/lib/src/forms/fields/checkboxed-list.js +0 -40
  152. package/lib/src/forms/fields/collection-field.js +0 -29
  153. package/lib/src/forms/fields/email.js +0 -11
  154. package/lib/src/forms/fields/email.test.js +0 -20
  155. package/lib/src/forms/fields/enum-multiple.js +0 -47
  156. package/lib/src/forms/fields/enum-multiple.test.js +0 -27
  157. package/lib/src/forms/fields/enum.js +0 -39
  158. package/lib/src/forms/fields/enum.test.js +0 -21
  159. package/lib/src/forms/fields/existing-sealious-value.js +0 -16
  160. package/lib/src/forms/fields/field.js +0 -66
  161. package/lib/src/forms/fields/fields.js +0 -16
  162. package/lib/src/forms/fields/file.js +0 -53
  163. package/lib/src/forms/fields/multiple-files.js +0 -15
  164. package/lib/src/forms/fields/number.js +0 -45
  165. package/lib/src/forms/fields/number.test.js +0 -31
  166. package/lib/src/forms/fields/pick-from-list.js +0 -31
  167. package/lib/src/forms/fields/pick-from-list.test.js +0 -17
  168. package/lib/src/forms/fields/proxy-field.js +0 -20
  169. package/lib/src/forms/fields/regexp.js +0 -40
  170. package/lib/src/forms/fields/regexp.test.js +0 -21
  171. package/lib/src/forms/fields/reverse-single-reference.js +0 -14
  172. package/lib/src/forms/fields/simple-form-field.js +0 -19
  173. package/lib/src/forms/fields/structured-array.js +0 -18
  174. package/lib/src/forms/form-types.js +0 -2
  175. package/lib/src/forms/form.js +0 -176
  176. package/lib/src/forms/form.test.js +0 -271
  177. package/lib/src/forms/multiform.js +0 -174
  178. package/lib/src/forms/multiform.test.js +0 -430
  179. package/lib/src/generate-collections.js +0 -52
  180. package/lib/src/generate-components.js +0 -33
  181. package/lib/src/generate-routes.js +0 -75
  182. package/lib/src/hehe.test.js +0 -7
  183. package/lib/src/index.js +0 -19
  184. package/lib/src/make-env.js +0 -14
  185. package/lib/src/make-hidden-inputs.js +0 -14
  186. package/lib/src/mount.js +0 -70
  187. package/lib/src/notifier.js +0 -19
  188. package/lib/src/page/access-control.js +0 -16
  189. package/lib/src/page/default-list-filters.js +0 -40
  190. package/lib/src/page/list.js +0 -184
  191. package/lib/src/page/mountable-with-fields.js +0 -85
  192. package/lib/src/page/mountable.js +0 -5
  193. package/lib/src/page/page.js +0 -26
  194. package/lib/src/page/props-parser.js +0 -23
  195. package/lib/src/page/sealious-list.js +0 -59
  196. package/lib/src/page/stateful-page.js +0 -97
  197. package/lib/src/run.js +0 -2
  198. package/lib/src/sample-index.js +0 -3
  199. package/lib/src/sample-lib.js +0 -6
  200. package/lib/src/sanitize.js +0 -10
  201. package/lib/src/templates/collection.js +0 -12
  202. package/lib/src/templates/form.js +0 -57
  203. package/lib/src/templates/jdd-component.js +0 -39
  204. package/lib/src/templates/list.js +0 -139
  205. package/lib/src/templates/long-running-process.js +0 -60
  206. package/lib/src/templates/multiform.js +0 -55
  207. package/lib/src/templates/page.js +0 -23
  208. package/lib/src/templates/post.js +0 -22
  209. package/lib/src/templates/redirect.js +0 -23
  210. package/lib/src/templates/route-test.js +0 -54
  211. package/lib/src/templates/stateful-page.js +0 -66
  212. package/lib/src/templates/templates.js +0 -21
  213. package/lib/src/test_utils/locator_is_visible.js +0 -11
  214. package/lib/src/utils/assert-throws.js +0 -17
  215. package/lib/src/utils/base64.js +0 -7
  216. package/lib/src/utils/browser-creator.js +0 -10
  217. package/lib/src/utils/escape-url-params.js +0 -14
  218. package/lib/src/utils/exec.js +0 -22
  219. package/lib/src/utils/extract-fields-from-collection.js +0 -26
  220. package/lib/src/utils/format-external-url.js +0 -11
  221. package/lib/src/utils/import-path.js +0 -16
  222. package/lib/src/utils/input-wrapper.js +0 -15
  223. package/lib/src/utils/list-collections.js +0 -13
  224. package/lib/src/utils/make-slug.js +0 -6
  225. package/lib/src/utils/natural-numbers.js +0 -6
  226. package/lib/src/utils/prettier.js +0 -10
  227. package/lib/src/utils/question.js +0 -19
  228. package/lib/src/utils/render-attributes.js +0 -19
  229. package/lib/src/utils/sleep.js +0 -4
  230. package/lib/src/utils/translate.js +0 -6
  231. package/lib/src/utils/url-with-new-params.js +0 -5
  232. package/lib/src/utils/utils.js +0 -16
  233. package/lib/src/utils/walk.js +0 -23
  234. package/lib/src/vitest.config.js +0 -20
  235. package/lib/templates/collection.js +0 -12
  236. package/lib/templates/form.js +0 -57
  237. package/lib/templates/jdd-component.js +0 -39
  238. package/lib/templates/list.js +0 -139
  239. package/lib/templates/long-running-process.js +0 -60
  240. package/lib/templates/multiform.js +0 -55
  241. package/lib/templates/page.js +0 -23
  242. package/lib/templates/post.js +0 -22
  243. package/lib/templates/redirect.js +0 -23
  244. package/lib/templates/route-test.js +0 -54
  245. package/lib/templates/stateful-page.js +0 -66
  246. package/lib/templates/templates.js +0 -21
  247. package/lib/test_utils/locator_is_visible.js +0 -11
  248. package/lib/utils/assert-throws.js +0 -17
  249. package/lib/utils/base64.js +0 -7
  250. package/lib/utils/browser-creator.js +0 -10
  251. package/lib/utils/escape-url-params.js +0 -14
  252. package/lib/utils/exec.js +0 -22
  253. package/lib/utils/extract-fields-from-collection.js +0 -26
  254. package/lib/utils/format-external-url.js +0 -11
  255. package/lib/utils/import-path.js +0 -16
  256. package/lib/utils/input-wrapper.js +0 -15
  257. package/lib/utils/list-collections.js +0 -13
  258. package/lib/utils/make-slug.js +0 -6
  259. package/lib/utils/natural-numbers.js +0 -6
  260. package/lib/utils/prettier.js +0 -10
  261. package/lib/utils/question.js +0 -19
  262. package/lib/utils/render-attributes.js +0 -19
  263. package/lib/utils/sleep.js +0 -4
  264. package/lib/utils/translate.js +0 -6
  265. package/lib/utils/url-with-new-params.js +0 -5
  266. package/lib/utils/utils.js +0 -16
  267. package/lib/utils/walk.js +0 -23
  268. package/lib/vitest.config.js +0 -22
@@ -1,31 +0,0 @@
1
- import { is, predicates } from "@sealcode/ts-predicates";
2
- import { SimpleFormField } from "./simple-form-field.js";
3
- export class PickFromListField extends SimpleFormField {
4
- constructor(required, generateOptions, customValidation = (ctx, value, instance) => instance.valueInList(ctx, value)) {
5
- super(required);
6
- this.required = required;
7
- this.generateOptions = generateOptions;
8
- this.customValidation = customValidation;
9
- this.predicate = predicates.string;
10
- }
11
- isValueValid(ctx, value) {
12
- return this.customValidation(ctx, value, this);
13
- }
14
- async valueInList(ctx, value) {
15
- const options = await this.generateOptions(ctx);
16
- if (!is(value, predicates.string)) {
17
- return { valid: false, message: "not a string" };
18
- }
19
- if (this.required && !options.map((o) => o.value).includes(value)) {
20
- return {
21
- valid: false,
22
- message: `"${value}" is not one of the options`,
23
- };
24
- }
25
- return { valid: true, message: "" };
26
- }
27
- getEmptyValue() {
28
- return "";
29
- }
30
- }
31
- //# sourceMappingURL=pick-from-list.js.map
@@ -1,17 +0,0 @@
1
- import assert from "assert";
2
- import { Fields } from "../../index.js";
3
- describe("pick-from-list field", () => {
4
- const ctx = {};
5
- it("validation logic", async () => {
6
- const field = new Fields.PickFromListField(true, async () => {
7
- return [
8
- { value: "samplev", label: "samplel" },
9
- { value: "samplevv", label: "samplell" },
10
- ];
11
- });
12
- assert.strictEqual((await field.isValueValid(ctx, 42)).valid, false);
13
- assert.strictEqual((await field.isValueValid(ctx, "samplevv")).valid, true);
14
- assert.strictEqual((await field.isValueValid(ctx, "notvalid")).valid, false);
15
- });
16
- });
17
- //# sourceMappingURL=pick-from-list.test.js.map
@@ -1,20 +0,0 @@
1
- import { FormField } from "./field.js";
2
- export class ProxyFormField extends FormField {
3
- constructor(required, name, empty_value, parsed_value) {
4
- super(required);
5
- this.name = name;
6
- this.empty_value = empty_value;
7
- this.parsed_value = parsed_value;
8
- }
9
- getEmptyValue() {
10
- return this.empty_value;
11
- }
12
- async parse() {
13
- return {
14
- parsable: true,
15
- error: null,
16
- parsed_value: this.parsed_value,
17
- };
18
- }
19
- }
20
- //# sourceMappingURL=proxy-field.js.map
@@ -1,40 +0,0 @@
1
- import { is, predicates } from "@sealcode/ts-predicates";
2
- import { FormField } from "./field.js";
3
- export class RegExpField extends FormField {
4
- constructor(required, regexp, error_message, default_value = "") {
5
- super(required);
6
- this.regexp = regexp;
7
- this.error_message = error_message;
8
- this.default_value = default_value;
9
- this.predicate = predicates.string;
10
- }
11
- async isValueValid(_, value) {
12
- if (!is(value, predicates.string)) {
13
- return { valid: false, message: "expected a string" };
14
- }
15
- if (this.regexp.exec(value)) {
16
- return { valid: true, message: "" };
17
- }
18
- return { valid: false, message: this.error_message };
19
- }
20
- async parse(_, value) {
21
- if (is(value, predicates.string)) {
22
- return {
23
- parsable: true,
24
- parsed_value: value,
25
- error: null,
26
- };
27
- }
28
- else {
29
- return {
30
- parsable: false,
31
- parsed_value: null,
32
- error: "Please enter a string",
33
- };
34
- }
35
- }
36
- getEmptyValue() {
37
- return this.default_value || "";
38
- }
39
- }
40
- //# sourceMappingURL=regexp.js.map
@@ -1,21 +0,0 @@
1
- import assert from "assert";
2
- import { Fields } from "../../index.js";
3
- describe("regexp field", () => {
4
- const ctx = {};
5
- it("validation logic", async () => {
6
- const field = new Fields.RegExpField(true, /^4/, "error");
7
- assert.strictEqual((await field.isValueValid(ctx, "42")).valid, true);
8
- assert.strictEqual((await field.isValueValid(ctx, "notvalid")).valid, false);
9
- assert.strictEqual((await field.isValueValid(ctx, 42)).valid, false);
10
- });
11
- it("parse function", async () => {
12
- const field = new Fields.RegExpField(true, /^4/, "error");
13
- const string_response = await field.parse(ctx, "42");
14
- const number_response = await field.parse(ctx, 42);
15
- assert.strictEqual(string_response.parsable, true);
16
- assert.strictEqual(string_response.parsed_value, "42");
17
- assert.strictEqual(number_response.parsable, false);
18
- assert.strictEqual(number_response.error, "Please enter a string");
19
- });
20
- });
21
- //# sourceMappingURL=regexp.test.js.map
@@ -1,14 +0,0 @@
1
- import { FormField } from "./field.js";
2
- export class ReverseSingleReference extends FormField {
3
- constructor(required, sealious_field) {
4
- super(required);
5
- this.sealious_field = sealious_field;
6
- }
7
- async parse(ctx, raw_value) {
8
- return { parsable: true, error: null, parsed_value: raw_value };
9
- }
10
- getEmptyValue() {
11
- return [];
12
- }
13
- }
14
- //# sourceMappingURL=reverse-single-reference.js.map
@@ -1,19 +0,0 @@
1
- import { predicates } from "@sealcode/ts-predicates";
2
- import { FormField } from "./field.js";
3
- export class SimpleFormField extends FormField {
4
- async parse(_, raw_value) {
5
- return {
6
- parsed_value: (raw_value || "").toString(),
7
- parsable: true,
8
- error: null,
9
- };
10
- }
11
- getEmptyValue() {
12
- return "";
13
- }
14
- constructor(required) {
15
- super(required);
16
- this.predicate = predicates.string;
17
- }
18
- }
19
- //# sourceMappingURL=simple-form-field.js.map
@@ -1,18 +0,0 @@
1
- import { FormField } from "./field.js";
2
- export class StructuredArrayField extends FormField {
3
- constructor(sealious_field) {
4
- super(true);
5
- this.sealious_field = sealious_field;
6
- }
7
- async parse(context, value) {
8
- return {
9
- parsable: true,
10
- error: null,
11
- parsed_value: value || [],
12
- };
13
- }
14
- getEmptyValue() {
15
- return [];
16
- }
17
- }
18
- //# sourceMappingURL=structured-array.js.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=form-types.js.map
@@ -1,176 +0,0 @@
1
- import { randomUUID } from "crypto";
2
- import Router from "@koa/router";
3
- import { tempstream } from "tempstream";
4
- import { hasFieldOfType, hasShape, is, predicates, } from "@sealcode/ts-predicates";
5
- import { MountableWithFields, } from "../page/mountable-with-fields.js";
6
- export class Form extends MountableWithFields {
7
- constructor() {
8
- super(...arguments);
9
- this.defaultSuccessMessage = "Done";
10
- this.submitButtonText = "Wyślij";
11
- this.action = "./";
12
- this.useTurbo = true;
13
- this.form_id = randomUUID();
14
- }
15
- async canAccess(
16
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
17
- _) {
18
- return { canAccess: true, message: "" };
19
- }
20
- async renderError(_, error) {
21
- return tempstream /* HTML */ `<div>${error.message}</div>`;
22
- }
23
- makeSubmitButton() {
24
- return /* HTML */ `<input
25
- type="submit"
26
- value="${this.submitButtonText}"
27
- formaction="${this.action}"
28
- ${this.form_id ? `form="${this.form_id}"` : ""}
29
- />`;
30
- }
31
- async render(ctx, data, show_field_errors) {
32
- return tempstream /* HTML */ `<div class="form-container">
33
- ${this.makeOpenFormTag(ctx)}
34
- ${!this.controls.some((control) => control.role == "messages")
35
- ? this.renderMessages(ctx, data)
36
- : ""}
37
- ${this.renderControls(this.makeFormControlContext(ctx, data, show_field_errors))}
38
- ${this.controls.some((control) => control.role == "submit")
39
- ? ""
40
- : this.makeSubmitButton()}
41
- ${this.makeCloseFormTag()}
42
- </div>`;
43
- }
44
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
45
- async makeFormClasses(_ctx) {
46
- return [];
47
- }
48
- makeOpenFormTag(ctx) {
49
- return tempstream `<form enctype="multipart/form-data" method="POST" id="${this.form_id}" action="${this.action}" class="${this.makeFormClasses(ctx).then((classes) => classes.join(" "))}" ${this.useTurbo ? "" : `data-turbo="false"`}></form><div class="form">`;
50
- }
51
- makeCloseFormTag() {
52
- return `</div>`;
53
- }
54
- async onValuesInvalid(ctx, form_messages, _field_errors) {
55
- const messages = form_messages.length
56
- ? form_messages
57
- : [{ type: "error", text: "Some fields are invalid" }];
58
- return {
59
- action: "stay",
60
- content: await this.render(ctx, {
61
- raw_values: await this.extractRawValues(ctx),
62
- messages,
63
- }, "show_field_errors" && true),
64
- messages,
65
- };
66
- }
67
- async onError(ctx, data, error) {
68
- let error_message = "Unknown error has occured";
69
- if (is(error, predicates.object) &&
70
- hasShape({ message: predicates.string }, error)) {
71
- error_message = error.message;
72
- }
73
- const messages = [{ type: "error", text: error_message }];
74
- return {
75
- action: "stay",
76
- content: await this.render(ctx, {
77
- raw_values: data.raw_values,
78
- messages,
79
- }, "show_field_errors" && true),
80
- };
81
- }
82
- async onSuccess(ctx, data, _submitResult) {
83
- const messages = [
84
- { type: "success", text: this.defaultSuccessMessage },
85
- ];
86
- return {
87
- action: "stay",
88
- content: await this.render(ctx, {
89
- raw_values: data.raw_values,
90
- messages,
91
- }, "show_field_errors" && false),
92
- messages,
93
- };
94
- }
95
- async getRawValuesOnSuccess(ctx) {
96
- return this.extractRawValues(ctx);
97
- }
98
- async handlePost(ctx) {
99
- const raw_values = await this.extractRawValues(ctx);
100
- const { valid, form_messages, field_errors } = await this.validate(ctx, raw_values);
101
- if (!valid) {
102
- return this.onValuesInvalid(ctx, form_messages, field_errors);
103
- }
104
- try {
105
- ctx.status = 303;
106
- const result = await this.onSubmit(ctx, {
107
- raw_values,
108
- messages: [],
109
- });
110
- return this.onSuccess(ctx, {
111
- raw_values: await this.getRawValuesOnSuccess(ctx),
112
- messages: [],
113
- }, result);
114
- }
115
- catch (e) {
116
- // eslint-disable-next-line no-console
117
- console.dir(e, { depth: 5 });
118
- const message = is(e, predicates.object) &&
119
- hasFieldOfType(e, "message", predicates.string)
120
- ? e?.message
121
- : is(e, predicates.string)
122
- ? e
123
- : "Wystąpił błąd";
124
- return this.onError(ctx, {
125
- raw_values,
126
- messages: [
127
- {
128
- type: "error",
129
- text: message,
130
- },
131
- ],
132
- }, e);
133
- }
134
- }
135
- mount(router, path) {
136
- router.use(path, async (ctx, next) => {
137
- const result = await this.canAccess(ctx);
138
- if (!result.canAccess) {
139
- ctx.body = this.renderError(ctx, {
140
- type: "access",
141
- message: result.message,
142
- });
143
- ctx.status = 403;
144
- return;
145
- }
146
- await next();
147
- });
148
- router.get(path, async (ctx) => {
149
- ctx.type = "html";
150
- ctx.body = await this.render(ctx, {
151
- raw_values: await this.extractRawValues(ctx),
152
- messages: [],
153
- }, "show_field_errors" && false);
154
- });
155
- router.post(path, async (ctx) => {
156
- const reaction = await this.handlePost(ctx);
157
- if (reaction.action == "stay") {
158
- ctx.status = 422;
159
- ctx.body = reaction.content;
160
- }
161
- else if (reaction.action == "redirect") {
162
- ctx.status = 303;
163
- ctx.redirect(reaction.url);
164
- }
165
- });
166
- const subrouter = new Router(); // for use with other subroutes that individual controls might register
167
- for (const control of this.controls) {
168
- control.mount(subrouter);
169
- }
170
- router.use(path, subrouter.routes(), subrouter.allowedMethods());
171
- }
172
- async extractRawValues(ctx) {
173
- return ctx.$body;
174
- }
175
- }
176
- //# sourceMappingURL=form.js.map
@@ -1,271 +0,0 @@
1
- import Router from "@koa/router";
2
- import { describe, it, beforeAll, afterAll, afterEach, beforeEach } from "vitest";
3
- import axios from "axios";
4
- import Koa from "koa";
5
- import { Controls, Fields, Form } from "../index.js";
6
- import { mount } from "../mount.js";
7
- import { locator_is_visible } from "../test_utils/locator_is_visible.js";
8
- import { getBrowser } from "../utils/browser-creator.js";
9
- import { assertThrowsAsync } from "../utils/utils.js";
10
- const fields = {
11
- text: new Fields.SimpleFormField(true),
12
- };
13
- export function form_factory(canAccessFun) {
14
- const result = new (class extends Form {
15
- constructor() {
16
- super(...arguments);
17
- this.fields = fields;
18
- this.submitButtonText = "Submit";
19
- this.controls = [
20
- new Controls.SimpleInput(fields.text, {
21
- label: "This is a test:",
22
- type: "password",
23
- }),
24
- ];
25
- }
26
- async onSubmit() {
27
- return;
28
- }
29
- })();
30
- if (canAccessFun)
31
- result.canAccess = canAccessFun;
32
- return result;
33
- }
34
- describe("form test", () => {
35
- let page;
36
- beforeAll(async () => {
37
- const browser = await getBrowser();
38
- const context = await browser.newContext();
39
- page = await context.newPage();
40
- });
41
- describe("basic tests", async () => {
42
- let server;
43
- beforeAll(async () => {
44
- const app = new Koa();
45
- const router = new Router();
46
- mount(router, "/", form_factory(), true);
47
- app.use(router.routes()).use(router.allowedMethods());
48
- server = app.listen(8080);
49
- await page.goto("http://localhost:8080");
50
- });
51
- afterAll(async () => {
52
- server.close();
53
- });
54
- it("does not allow to submit an empty form when there's a required field", async () => {
55
- await page.getByRole("button", { name: "Submit", exact: true }).click();
56
- await assertThrowsAsync(async () => {
57
- return page.getByText("Done").click({ timeout: 500 });
58
- });
59
- });
60
- it("allows to submit a form when all required fields have a value", async () => {
61
- await page.getByPlaceholder("password").click();
62
- await page.getByPlaceholder("password").fill("testpasswd");
63
- await page.getByRole("button", { name: "Submit", exact: true }).click();
64
- await page.getByText("Done").click();
65
- });
66
- it("does not allow submitting an empty form by circumventing HTML-based validation", async () => {
67
- const res_axios = await axios.post("http://localhost:8080", {
68
- text: "",
69
- }, {
70
- validateStatus: (status) => {
71
- if (status == 422)
72
- return true;
73
- return false;
74
- },
75
- });
76
- if (!res_axios.data.includes("Some fields are invalid")) {
77
- throw new Error("when sending a empty request with axios, the error didnt appear");
78
- }
79
- });
80
- });
81
- describe("canAccess tests", async () => {
82
- let server;
83
- afterEach(async () => {
84
- server.close();
85
- });
86
- it("allows visit when configured when canAccess returns true", async () => {
87
- const app = new Koa();
88
- const router = new Router();
89
- mount(router, "/", form_factory(async (ctx) => {
90
- return { canAccess: true, message: "" };
91
- }), true);
92
- app.use(router.routes()).use(router.allowedMethods());
93
- server = app.listen(8080);
94
- const response = await page.goto("http://localhost:8080");
95
- if (response?.status() != 200) {
96
- throw new Error(`Should return 200 status and it returns ${response?.status()}`);
97
- }
98
- });
99
- describe("declines access when canAccess returns false", async () => {
100
- const app = new Koa();
101
- const router = new Router();
102
- beforeAll(async () => {
103
- mount(router, "/", form_factory(async (ctx) => {
104
- console.log("CAN ACCESS? FALSE");
105
- return { canAccess: false, message: "" };
106
- }), true);
107
- app.use(router.routes()).use(router.allowedMethods());
108
- });
109
- beforeEach(async () => {
110
- server = app.listen(8080);
111
- });
112
- it("prevents the form from rendering", async () => {
113
- console.log("CONSOLELOG TEST");
114
- const response = await page.goto("http://localhost:8080");
115
- if (response?.status() != 403) {
116
- throw new Error(`Should return 403 status and it returns ${response?.status()}`);
117
- }
118
- });
119
- it("does not allow submitting of the form through axios", async () => {
120
- await axios.post("http://localhost:8080", {
121
- text: "sample",
122
- }, {
123
- validateStatus: (status) => {
124
- if (status == 403)
125
- return true;
126
- return false;
127
- },
128
- });
129
- });
130
- });
131
- it("passes the context to canAccess (false case)", async () => {
132
- const app = new Koa();
133
- const router = new Router();
134
- mount(router, "/", form_factory(async (ctx) => {
135
- return ctx.$context && ctx.$context.user_id
136
- ? { canAccess: true, message: "" }
137
- : { canAccess: false, message: "" };
138
- }), true);
139
- app.use(router.routes()).use(router.allowedMethods());
140
- server = app.listen(8080);
141
- const response = await page.goto("http://localhost:8080");
142
- if (response?.status() != 403) {
143
- throw new Error(`Should return 403 status and it returns ${response?.status()}`);
144
- }
145
- });
146
- it("passes the context to canAccess (true case)", async () => {
147
- const app = new Koa();
148
- const router = new Router();
149
- router.use(async (ctx, next) => {
150
- ctx.$context = {
151
- user_id: "miguel",
152
- };
153
- await next();
154
- });
155
- mount(router, "/", form_factory(async (ctx) => {
156
- return ctx.$context && ctx.$context.user_id
157
- ? { canAccess: true, message: "" }
158
- : { canAccess: false, message: "" };
159
- }), true);
160
- app.use(router.routes()).use(router.allowedMethods());
161
- server = app.listen(8080);
162
- const response = await page.goto("http://localhost:8080");
163
- if (response?.status() != 200) {
164
- throw new Error(`Should return 200 status and it returns ${response?.status()}`);
165
- }
166
- });
167
- });
168
- describe("validation e2e", async () => {
169
- describe("validation message", async () => {
170
- let server;
171
- beforeAll(async () => {
172
- const app = new Koa();
173
- const router = new Router();
174
- mount(router, "/", new (class extends Form {
175
- constructor() {
176
- super(...arguments);
177
- this.fields = fields;
178
- this.submitButtonText = "Submit";
179
- this.controls = [
180
- new Controls.SimpleInput(fields.text, {
181
- label: "This is a test:",
182
- type: "password",
183
- }),
184
- ];
185
- }
186
- async onSubmit() {
187
- return;
188
- }
189
- async validateValues(ctx, data) {
190
- if (data.text === "incorrect")
191
- return {
192
- valid: false,
193
- error: "Incorrect input",
194
- };
195
- return { valid: true, error: "" };
196
- }
197
- })(), true);
198
- app.use(router.routes()).use(router.allowedMethods());
199
- server = app.listen(8080);
200
- await page.goto("http://localhost:8080");
201
- });
202
- afterAll(async () => {
203
- server.close();
204
- });
205
- it("shows up when incorrect input is given", async () => {
206
- await page.getByPlaceholder("password").click();
207
- await page.getByPlaceholder("password").fill("incorrect");
208
- await page.getByRole("button", { name: "Submit" }).click();
209
- if (!(await locator_is_visible(page.getByText("Incorrect input"))))
210
- throw new Error("validation message doens't show up when input is incorrect");
211
- });
212
- it("doesn't show when correct input is given", async () => {
213
- await page.getByPlaceholder("password").click();
214
- await page.getByPlaceholder("password").fill("correct");
215
- await page.getByRole("button", { name: "Submit" }).click();
216
- await assertThrowsAsync(async () => {
217
- return page.getByText("Incorrect input").click({ timeout: 500 });
218
- });
219
- });
220
- });
221
- describe("field specific validation message", async () => {
222
- let server;
223
- beforeAll(async () => {
224
- const app = new Koa();
225
- const router = new Router();
226
- const fields = {
227
- text: new Fields.EmailField(true),
228
- };
229
- mount(router, "/", new (class extends Form {
230
- constructor() {
231
- super(...arguments);
232
- this.fields = fields;
233
- this.submitButtonText = "Submit";
234
- this.controls = [
235
- new Controls.SimpleInput(fields.text, {
236
- label: "This is a test:",
237
- type: "text",
238
- }),
239
- ];
240
- }
241
- async onSubmit() {
242
- return;
243
- }
244
- })(), true);
245
- app.use(router.routes()).use(router.allowedMethods());
246
- server = app.listen(8080);
247
- await page.goto("http://localhost:8080");
248
- });
249
- afterAll(async () => {
250
- server.close();
251
- });
252
- it("shows up when incorrect input is given", async () => {
253
- await page.getByPlaceholder("text").click();
254
- await page.getByPlaceholder("text").fill("notanemail");
255
- await page.getByRole("button", { name: "Submit" }).click();
256
- await page.getByText("Please enter a proper email address").click();
257
- });
258
- it("doesn't show up when correct input is given", async () => {
259
- await page.getByPlaceholder("text").click();
260
- await page.getByPlaceholder("text").fill("yes@an.email");
261
- await page.getByRole("button", { name: "Submit" }).click();
262
- assertThrowsAsync(async () => {
263
- return page
264
- .getByText("Please enter a proper email address")
265
- .click({ timeout: 500 });
266
- });
267
- });
268
- });
269
- });
270
- });
271
- //# sourceMappingURL=form.test.js.map