@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
package/lib/forms/form.js DELETED
@@ -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 +0,0 @@
1
-
@@ -1,174 +0,0 @@
1
- import { is, predicates } from "@sealcode/ts-predicates";
2
- import { tempstream } from "tempstream";
3
- import { MountableWithFields } from "../page/mountable-with-fields.js";
4
- import { attribute } from "../sanitize.js";
5
- const FIELD_PREFIX_SEPARATOR = "___";
6
- export class Multiform extends MountableWithFields {
7
- constructor() {
8
- super(...arguments);
9
- this.controls = [];
10
- }
11
- init() {
12
- super.init();
13
- for (const [key, form] of Object.entries(this.forms)) {
14
- if (key !== attribute(key)) {
15
- throw new Error(`Form name "${key}" is not url-safe. Try: "${attribute(key)}"`);
16
- }
17
- form.makeOpenFormTag = () => `<div>`;
18
- form.makeCloseFormTag = () => `</div>`;
19
- form.field_names_prefix = key + FIELD_PREFIX_SEPARATOR;
20
- form.form_id = this.name;
21
- form.action = "./" + key;
22
- form.init();
23
- form.extractRawValues = async (context) => this.getSubformRawValues(context, key);
24
- const submit_button_id = this.name + "_" + key + "_submit";
25
- form.makeSubmitButton = () => /* HTML */ `<input
26
- type="submit"
27
- value="${form.submitButtonText}"
28
- formaction="${form.action}"
29
- id="${submit_button_id}"
30
- ${form.form_id ? `form="${form.form_id}"` : ""}
31
- /> `;
32
- }
33
- for (const form of Object.values(this.forms)) {
34
- for (const field of Object.values(form.fields)) {
35
- if (field.name.includes(FIELD_PREFIX_SEPARATOR)) {
36
- throw new Error(`A field name within multiform cannot contain '${FIELD_PREFIX_SEPARATOR}'`);
37
- }
38
- }
39
- }
40
- }
41
- async extractRawValues(ctx) {
42
- return ctx.$body || {};
43
- }
44
- async canAccess() {
45
- return {
46
- canAccess: true,
47
- message: "this view includes multiple forms and each of them have their unique access rules",
48
- };
49
- }
50
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
- getSubformsToRender(ctx) {
52
- const requested_frame = ctx.headers["turbo-frame"];
53
- if (!is(requested_frame, predicates.or(predicates.undefined, predicates.string))) {
54
- throw new Error("Wrong turbo-frame header value type");
55
- }
56
- const forms_to_render = requested_frame && this.forms[requested_frame]
57
- ? [[requested_frame, this.forms[requested_frame]]]
58
- : Object.entries(this.forms);
59
- return forms_to_render;
60
- }
61
- async renderSubform(ctx, sub_form_name, show_field_errors) {
62
- const form = this.forms[sub_form_name];
63
- const result = await form.canAccess(ctx);
64
- if (!result.canAccess) {
65
- return result.message;
66
- }
67
- return form.render(ctx, {
68
- raw_values: await this.getSubformRawValues(ctx, sub_form_name),
69
- messages: [],
70
- }, show_field_errors);
71
- }
72
- async getSubformRawValues(ctx, sub_form_name) {
73
- const result = Object.fromEntries(Object.entries(await this.extractRawValues(ctx))
74
- .filter(([key]) => key.startsWith(sub_form_name + FIELD_PREFIX_SEPARATOR))
75
- .map(([key, value]) => [
76
- key.slice((sub_form_name + FIELD_PREFIX_SEPARATOR).length),
77
- value,
78
- ]));
79
- return result;
80
- }
81
- async render(ctx, messages, prerenderedForms = {}, show_field_errors) {
82
- return tempstream /* HTML */ `${this.renderMessages(ctx, {
83
- raw_values: {},
84
- messages,
85
- })}
86
- <div class="forms">
87
- <form
88
- id="${this.name}"
89
- novalidate
90
- ${
91
- /* novalidate is here because all the subforms are actually one form and errors in one will prevent submitting all of the forms */ ""}
92
- method="POST"
93
- ></form>
94
- ${this.getSubformsToRender(ctx).map(([form_name]) => {
95
- const frame_form_id = this.name + "_" + form_name + "_frame_form";
96
- return tempstream /* HTML */ `<turbo-frame
97
- id="${form_name}"
98
- contains-subform
99
- subform-id="${frame_form_id}"
100
- >
101
- ${prerenderedForms[form_name] ||
102
- this.renderSubform(ctx, form_name, show_field_errors)}
103
- <form id="${frame_form_id}" method="POST"></form>
104
- </turbo-frame>`;
105
- })}
106
- </div>
107
- ${this.makeBottomScript()}`;
108
- }
109
- makeBottomScript() {
110
- // this script assigns each field to its corresponding form, instead of
111
- // the html-only version where all fields are attached to one meta-form
112
- return /* HTML */ ` <script>
113
- (function () {
114
- if (!window.subform_handlers) {
115
- window.subform_handlers = {};
116
- }
117
- if (window.subform_handlers["${this.name}"]) {
118
- return;
119
- }
120
- const handler = () => {
121
- document
122
- .querySelectorAll("turbo-frame[contains-subform]")
123
- .forEach((frame) => {
124
- frame_form_id = frame.getAttribute("subform-id");
125
- frame.querySelectorAll("input").forEach((input) => {
126
- input.setAttribute("form", frame_form_id);
127
- });
128
- });
129
- };
130
- window.subform_handlers["${this.name}"] = handler;
131
- document.documentElement.addEventListener(
132
- "turbo:load",
133
- handler
134
- );
135
- document.documentElement.addEventListener(
136
- "turbo:frame-render",
137
- handler
138
- );
139
- })();
140
- </script>`;
141
- }
142
- mount(router, path) {
143
- router.get(path, async (ctx) => {
144
- ctx.type = "html";
145
- ctx.body = await this.render(ctx, [], {}, false);
146
- });
147
- for (const [key, form] of Object.entries(this.forms)) {
148
- router.post(path + (path.endsWith("/") ? "" : "/") + key, async (ctx) => {
149
- const result = await form.canAccess(ctx);
150
- if (!result.canAccess) {
151
- ctx.body = this.renderError(ctx, {
152
- type: "access",
153
- message: result.message,
154
- });
155
- ctx.status = 403;
156
- return;
157
- }
158
- const reaction = await form.handlePost(ctx);
159
- if (reaction.action == "stay") {
160
- ctx.status = 422;
161
- const form_content = reaction.content;
162
- ctx.body = this.render(ctx, [], {
163
- [key]: form_content,
164
- }, true);
165
- }
166
- else if (reaction.action == "redirect") {
167
- ctx.status = 303;
168
- ctx.redirect(reaction.url);
169
- }
170
- });
171
- }
172
- }
173
- }
174
- //# sourceMappingURL=multiform.js.map