@sealcode/sealgen 0.19.4 → 0.19.6

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 (67) hide show
  1. package/@types/forms/fields/field.d.ts +1 -0
  2. package/@types/forms/fields/fields.d.ts +2 -1
  3. package/@types/forms/fields/get-field-for-sealious.d.ts +3 -1
  4. package/@types/forms/fields/hybrid.d.ts +11 -0
  5. package/@types/forms/fields/item-draft.d.ts +20 -0
  6. package/@types/forms/form.d.ts +1 -0
  7. package/@types/forms/multiform.d.ts +2 -2
  8. package/@types/page/list.d.ts +5 -4
  9. package/@types/page/mountable-with-fields.d.ts +9 -2
  10. package/@types/page/mountable.d.ts +1 -1
  11. package/@types/page/page.d.ts +1 -1
  12. package/@types/templates/form.d.ts +2 -2
  13. package/lib/forms/controls/checkboxed-list-input.test.js +16 -12
  14. package/lib/forms/controls/file.test.js +2 -2
  15. package/lib/forms/controls/image.test.js +4 -4
  16. package/lib/forms/controls/single-reference.test.js +2 -2
  17. package/lib/forms/fields/field.js +1 -1
  18. package/lib/forms/fields/field.test.js +9 -6
  19. package/lib/forms/fields/fields.js +2 -1
  20. package/lib/forms/fields/file.test.js +2 -2
  21. package/lib/forms/fields/get-field-for-sealious.js +14 -0
  22. package/lib/forms/fields/hybrid.js +37 -0
  23. package/lib/forms/fields/item-draft.js +34 -0
  24. package/lib/forms/form.js +11 -5
  25. package/lib/forms/form.test.js +9 -9
  26. package/lib/forms/multiform.js +7 -4
  27. package/lib/forms/multiform.test.js +7 -7
  28. package/lib/mount.js +4 -1
  29. package/lib/page/list.js +9 -6
  30. package/lib/page/mountable-with-fields.js +16 -1
  31. package/lib/page/mountable-with-fields.test.js +2 -2
  32. package/lib/page/mountable.js +1 -1
  33. package/lib/page/page.js +1 -1
  34. package/lib/templates/form.js +9 -18
  35. package/lib/templates/shared/collection-create-form.js +8 -8
  36. package/lib/templates/shared/collection-edit-form.js +9 -9
  37. package/lib/templates/shared/collection-list.js +2 -1
  38. package/lib/templates/shared/shared-crud-form-fields.js +4 -4
  39. package/lib/utils/extract-fields-from-collection.js +3 -0
  40. package/package.json +1 -1
  41. package/src/forms/controls/checkboxed-list-input.test.ts +16 -12
  42. package/src/forms/controls/file.test.ts +2 -2
  43. package/src/forms/controls/image.test.ts +4 -4
  44. package/src/forms/controls/single-reference.test.ts +2 -2
  45. package/src/forms/fields/field.test.ts +9 -6
  46. package/src/forms/fields/field.ts +6 -7
  47. package/src/forms/fields/fields.ts +2 -1
  48. package/src/forms/fields/file.test.ts +2 -2
  49. package/src/forms/fields/get-field-for-sealious.ts +66 -100
  50. package/src/forms/fields/hybrid.ts +47 -0
  51. package/src/forms/fields/item-draft.ts +44 -0
  52. package/src/forms/form.test.ts +15 -15
  53. package/src/forms/form.ts +34 -26
  54. package/src/forms/multiform.test.ts +7 -7
  55. package/src/forms/multiform.ts +10 -7
  56. package/src/mount.ts +11 -7
  57. package/src/page/list.ts +33 -28
  58. package/src/page/mountable-with-fields.test.ts +2 -2
  59. package/src/page/mountable-with-fields.ts +26 -5
  60. package/src/page/mountable.ts +1 -1
  61. package/src/page/page.ts +1 -1
  62. package/src/templates/form.ts +9 -18
  63. package/src/templates/shared/collection-create-form.ts +8 -8
  64. package/src/templates/shared/collection-edit-form.ts +9 -9
  65. package/src/templates/shared/collection-list.ts +5 -4
  66. package/src/templates/shared/shared-crud-form-fields.ts +5 -5
  67. package/src/utils/extract-fields-from-collection.ts +3 -0
@@ -23,8 +23,8 @@ const form1 = new class extends Form {
23
23
  constructor() {
24
24
  super(...arguments);
25
25
  this.defaultSuccessMessage = "Form1 done!";
26
- this.controls = [new FormHeader("form1"), new SimpleInput(fields1.email)];
27
- this.fields = fields1;
26
+ this.getControls = () => [new FormHeader("form1"), new SimpleInput(fields1.email)];
27
+ this.getFields = () => fields1;
28
28
  }
29
29
  onSubmit() {
30
30
  return;
@@ -37,8 +37,8 @@ const form2 = new class extends Form {
37
37
  constructor() {
38
38
  super(...arguments);
39
39
  this.defaultSuccessMessage = "Form2 done!";
40
- this.controls = [new FormHeader("form2"), new SimpleInput(fields2.name)];
41
- this.fields = fields2;
40
+ this.getControls = () => [new FormHeader("form2"), new SimpleInput(fields2.name)];
41
+ this.getFields = () => fields2;
42
42
  }
43
43
  onSubmit() {
44
44
  return;
@@ -375,7 +375,7 @@ describe("multiform test", () => {
375
375
  super(...arguments);
376
376
  this.fields = fields1;
377
377
  this.submitButtonText = "Submit";
378
- this.controls = [
378
+ this.getControls = () => [
379
379
  new SimpleInput(fields1.email, {
380
380
  label: "This is a test:",
381
381
  type: "text"
@@ -442,9 +442,9 @@ describe("multiform test", () => {
442
442
  form1: new class extends Form {
443
443
  constructor() {
444
444
  super(...arguments);
445
- this.fields = fields;
445
+ this.getFields = () => fields;
446
446
  this.submitButtonText = "Submit";
447
- this.controls = [
447
+ this.getControls = () => [
448
448
  new SimpleInput(fields.text, {
449
449
  label: "This is a test:",
450
450
  type: "text"
package/lib/mount.js CHANGED
@@ -50,7 +50,10 @@ function mount(router, url, mountable, use_dummy_app = false, file_manager = use
50
50
  handleHtmlPromise
51
51
  ];
52
52
  router.use(raw_url, ...args);
53
- mountable.init();
53
+ router.use(raw_url, async (_ctx, next) => {
54
+ mountable.init(raw_url, router);
55
+ await next();
56
+ });
54
57
  router.get(raw_url.slice(0, -1), async (ctx, next) => {
55
58
  const url2 = ctx.URL;
56
59
  if (!url2.pathname.endsWith("/")) {
package/lib/page/list.js CHANGED
@@ -1,10 +1,10 @@
1
- import { tempstream } from "tempstream";
2
- import { Page } from "./page.js";
3
- import { naturalNumbers, UrlWithNewParams } from "../utils/utils.js";
4
- import { makeHiddenInputs } from "../make-hidden-inputs.js";
5
1
  import qs from "qs";
2
+ import { tempstream } from "tempstream";
6
3
  import { NumberField } from "../forms/fields/number.js";
7
4
  import { TextBasedSimpleField } from "../forms/fields/simple-form-field.js";
5
+ import { makeHiddenInputs } from "../make-hidden-inputs.js";
6
+ import { naturalNumbers, UrlWithNewParams } from "../utils/utils.js";
7
+ import { Page } from "./page.js";
8
8
  const BasePagePropsShape = {};
9
9
  const DEFAULT_ITEMS_PER_PAGE = 12;
10
10
  const BaseListPageFields = {
@@ -38,8 +38,11 @@ class ListPage extends Page {
38
38
  this.filterFields = {};
39
39
  this.filterControls = [];
40
40
  }
41
- init() {
42
- super.init();
41
+ init(path, router) {
42
+ if (this.initialized) {
43
+ return;
44
+ }
45
+ super.init(path, router);
43
46
  for (const [, field] of Object.entries(this.filterFields)) {
44
47
  void field.init();
45
48
  }
@@ -6,17 +6,32 @@ import { Mountable } from "./mountable.js";
6
6
  class MountableWithFields extends Mountable {
7
7
  constructor() {
8
8
  super();
9
+ this.initialized = false;
9
10
  this.field_names_prefix = "";
10
11
  // useful for multiform, where many forms are merged into one and field assignment is made using the prefix
11
12
  this.form_id = "";
12
13
  if (!this.fields)
13
14
  this.fields = {};
14
15
  }
15
- init() {
16
+ /** most routes should be setup using .mount(), but mount runs before
17
+ initialization so we don't yet have controls, app, etc ready for dynamic
18
+ routes **/
19
+ init(path, router) {
20
+ super.init(path, router);
21
+ if (this.initialized) {
22
+ return;
23
+ }
24
+ if (this.getFields) {
25
+ this.fields = this.getFields();
26
+ } else if (!this.fields) {
27
+ throw new Error("Fields not defined and getter not provided");
28
+ }
29
+ this.controls = this.getControls(this.fields);
16
30
  for (const [field_name, field] of Object.entries(this.fields)) {
17
31
  void field.init();
18
32
  field.setName(field_name);
19
33
  }
34
+ this.initialized = true;
20
35
  }
21
36
  makeFormControlContext(ctx, data, validate, field_name_prefix = this.field_names_prefix, form_id = this.form_id) {
22
37
  return new FormControlContext(
@@ -10,8 +10,8 @@ describe("mountable-with-fields", () => {
10
10
  new class extends Form {
11
11
  constructor() {
12
12
  super(...arguments);
13
- this.fields = fields;
14
- this.controls = [];
13
+ this.getFields = () => fields;
14
+ this.getControls = () => [];
15
15
  }
16
16
  async onSubmit(ctx, form_values) {
17
17
  const data = await this.getParsedValues(ctx);
@@ -1,5 +1,5 @@
1
1
  class Mountable {
2
- init() {
2
+ init(_path, _router) {
3
3
  }
4
4
  }
5
5
  export {
package/lib/page/page.js CHANGED
@@ -7,7 +7,7 @@ class Page extends MountableWithFields {
7
7
  constructor() {
8
8
  super(...arguments);
9
9
  this.propsParser = new AllQueryParams();
10
- this.controls = [];
10
+ this.getControls = () => [];
11
11
  }
12
12
  mount(router, path) {
13
13
  router.get(path, async (ctx) => {
@@ -3,13 +3,12 @@ const defaults = {
3
3
  postimport: `
4
4
  import { Fields } from "@sealcode/sealgen";
5
5
  import type {FormDataValue} from "@sealcode/sealgen";`,
6
- fields: `
7
- password: new Fields.Password(true),`,
8
- controls: `
9
- new Controls.SimpleInput(fields.password, {
6
+ get_fields: `()=>(<const>{ password: new Fields.Password(true) })`,
7
+ get_controls: `
8
+ ()=><const>[new Controls.SimpleInput(fields.password, {
10
9
  label: "Password:",
11
10
  type: "password",
12
- }),`,
11
+ })],`,
13
12
  validate_method: `async validateValues(
14
13
  ctx: Context,
15
14
  data: Record<string, FormDataValue>
@@ -43,28 +42,20 @@ async function formTemplate(action_name, _params = defaults) {
43
42
  const params = { ...defaults, ..._params };
44
43
  const content = `import type { Context } from "koa";
45
44
  import type { FormData } from "@sealcode/sealgen";
46
- import { Form, Controls, fieldsToShape } from "@sealcode/sealgen";
45
+ import { Form, Controls } from "@sealcode/sealgen";
47
46
  import html from "src/back/html.js";
48
47
 
49
48
  ${params.postimport}
50
49
 
51
50
  export const actionName = "${action_name}";
52
51
 
53
- const fields = {
54
- ${params.fields}
55
- };
56
-
57
- Form.initFieldNames(fields);
58
-
59
- export const ${action_name}Shape = fieldsToShape(fields);
52
+ const getFields = ${params.get_fields};
60
53
 
61
- export default new (class ${action_name}Form extends Form<typeof fields, void> {
54
+ export default new (class ${action_name}Form extends Form<ReturnType<typeof getFields>, void> {
62
55
  defaultSuccessMessage = "Formularz wype\u0142niony poprawnie";
63
- fields = fields;
56
+ getFields = getFields;
64
57
 
65
- controls = [
66
- ${params.controls}
67
- ];
58
+ getControls = ${params.get_controls};
68
59
 
69
60
  ${params.other_methods}
70
61
 
@@ -4,10 +4,10 @@ import extract_fields_from_collection from "../../utils/extract-fields-from-coll
4
4
  import { wrapAttribute } from "../../utils/wrap-attributes.js";
5
5
  async function createItemFormTemplate(create_action_name, newfilefullpath, collection_name, list_action) {
6
6
  const collection_fields = await extract_fields_from_collection(collection_name);
7
- const formFieldsVar = `${toPascalCase(collection_name)}FormFields`;
7
+ const formFieldsGetterVar = `get${toPascalCase(collection_name)}FormFields`;
8
8
  return formTemplate(create_action_name, {
9
9
  success_message: "Created!",
10
- postimport: `import {${formFieldsVar}, get${toPascalCase(
10
+ postimport: `import {${formFieldsGetterVar}, get${toPascalCase(
11
11
  collection_name
12
12
  )}FormControls }from "./shared.js";
13
13
 
@@ -18,12 +18,12 @@ async function createItemFormTemplate(create_action_name, newfilefullpath, colle
18
18
  import { ${list_action}URL } from "src/back/routes/urls.js";
19
19
  import {tempstream} from "tempstream";
20
20
  `,
21
- fields: `...${toPascalCase(collection_name)}FormFields`,
22
- controls: `
21
+ get_fields: `get${toPascalCase(collection_name)}FormFields`,
22
+ get_controls: `(fields: ReturnType<typeof getFields>)=>[
23
23
  new Controls.FormHeader("Create ${toPascalCase(
24
24
  collection_name
25
25
  )}"),
26
- ...get${toPascalCase(collection_name)}FormControls()`,
26
+ ...get${toPascalCase(collection_name)}FormControls(this.fields)]`,
27
27
  can_access: `canAccess = async (ctx: Context) => {
28
28
  const policy = ${toPascalCase(collection_name)}.getPolicy("create");
29
29
  const response = await policy.check(ctx.$context);
@@ -41,14 +41,14 @@ async function createItemFormTemplate(create_action_name, newfilefullpath, colle
41
41
  {
42
42
  ${collection_fields.map(
43
43
  (field_info) => field_info.form_field.generateCreateValueGetter(field_info, {
44
- form_field_types: formFieldsVar,
44
+ form_field_types: "FormFieldTypes",
45
45
  sealious_field: `fields${wrapAttribute(field_info.name)}`,
46
- form_fields: "fields"
46
+ form_fields: "this.fields"
47
47
  })
48
48
  ).join(",\n")}
49
49
  });
50
50
 
51
- for(const field of Object.values(${formFieldsVar})){
51
+ for(const field of Object.values(this.fields)){
52
52
  // eslint-disable-next-line no-await-in-loop
53
53
  await field.postSealiousCreate(ctx, created, formData)
54
54
  }
@@ -4,11 +4,11 @@ import extract_fields_from_collection from "../../utils/extract-fields-from-coll
4
4
  import { wrapAttribute } from "../../utils/wrap-attributes.js";
5
5
  async function editItemFormTemplate(edit_action_name, newfilefullpath, collection_name, list_action) {
6
6
  const collection_fields = await extract_fields_from_collection(collection_name);
7
- const formFieldsVar = `${toPascalCase(collection_name)}FormFields`;
7
+ const formFieldsGetterVar = `get${toPascalCase(collection_name)}FormFields`;
8
8
  const collectionVar = `${toPascalCase(collection_name)}`;
9
9
  return formTemplate(edit_action_name, {
10
10
  success_message: "Changes saved!",
11
- postimport: `import {${formFieldsVar}, get${toPascalCase(
11
+ postimport: `import {${formFieldsGetterVar}, get${toPascalCase(
12
12
  collection_name
13
13
  )}FormControls }from "../shared.js";
14
14
  import { ${collectionVar} } from "src/back/collections/collections.js";
@@ -17,12 +17,12 @@ async function editItemFormTemplate(edit_action_name, newfilefullpath, collectio
17
17
  import type { FormDataValue } from "@sealcode/sealgen";
18
18
  import type { CollectionInputWithAllKeys } from "sealious";
19
19
  `,
20
- fields: `...${toPascalCase(collection_name)}FormFields`,
21
- controls: `
20
+ get_fields: formFieldsGetterVar,
21
+ get_controls: `(fields: ReturnType<typeof getFields>)=>[
22
22
  new Controls.FormHeader("Edit ${toPascalCase(
23
23
  collection_name
24
24
  )}"),
25
- ...get${toPascalCase(collection_name)}FormControls()`,
25
+ ...get${toPascalCase(collection_name)}FormControls(this.fields)]`,
26
26
  can_access: `canAccess = async (ctx: Context) => {
27
27
  const policy = ${toPascalCase(collection_name)}.getPolicy("edit");
28
28
  const response = await policy.check(ctx.$context);
@@ -54,7 +54,7 @@ async function editItemFormTemplate(edit_action_name, newfilefullpath, collectio
54
54
  sealious_field: `${collectionVar}.fields${wrapAttribute(
55
55
  field_info.name
56
56
  )}`,
57
- form_fields: "fields"
57
+ form_fields: "this.fields"
58
58
  }
59
59
  )
60
60
  ).join(",\n")}
@@ -63,7 +63,7 @@ async function editItemFormTemplate(edit_action_name, newfilefullpath, collectio
63
63
 
64
64
  await item.save(ctx.$context);
65
65
 
66
- for(const field of Object.values(${formFieldsVar})){
66
+ for(const field of Object.values(this.fields)){
67
67
  // eslint-disable-next-line no-await-in-loop
68
68
  await field.postSealiousEdit(ctx, item, formData)
69
69
  }
@@ -79,7 +79,7 @@ async function editItemFormTemplate(edit_action_name, newfilefullpath, collectio
79
79
  return id
80
80
  }
81
81
  `,
82
- get_initial_values: `async getInitialValues(ctx: Context): Promise<{ [key in keyof typeof fields]: FormDataValue | undefined }> {
82
+ get_initial_values: `async getInitialValues(ctx: Context): Promise<{ [key in keyof typeof this.fields]: FormDataValue | undefined }> {
83
83
  const id = await this.getID(ctx);
84
84
 
85
85
  const {
@@ -99,7 +99,7 @@ async function editItemFormTemplate(edit_action_name, newfilefullpath, collectio
99
99
  ${collection_fields.map(
100
100
  (field_info) => field_info.form_field.generateInitialValue(field_info, {
101
101
  form_field_types: "FieldTypes",
102
- form_fields: "fields"
102
+ form_fields: "this.fields"
103
103
  })
104
104
  ).join(",\n")}
105
105
  };
@@ -121,7 +121,8 @@ export default new (class ${action_name}Page extends SealiousItemListPage<
121
121
  typeof ${uppercase_collection},
122
122
  typeof BaseListPageFields
123
123
  > {
124
- fields = BaseListPageFields;
124
+ getFields = ()=>BaseListPageFields;
125
+ getControls = ()=>[];
125
126
 
126
127
  async renderFilters(ctx: Context): Promise<FlatTemplatable> {
127
128
  const query_params = qs.parse(ctx.search.slice(1));
@@ -12,12 +12,12 @@ ${Array.from(
12
12
  collection_fields.map(
13
13
  (field_info) => field_info.form_field.generateImportsForFieldList(field_info)
14
14
  ).flat().map(
15
- ({ what, from, as }) => `import {${what}${as ? ` as ${as}` : ""} } from "${from}"`
15
+ ({ what, from, as, type }) => `import ${type ? "type " : ""}{${what}${as ? ` as ${as}` : ""} } from "${from}"`
16
16
  )
17
17
  ).values()
18
18
  ).join(";\n")}
19
19
 
20
- export const ${toPascalCase(collection_name)}FormFields = <const>{
20
+ export const get${toPascalCase(collection_name)}FormFields = () => <const>{
21
21
  ${collection_fields.map((field_info) => {
22
22
  return `${field_info.name}: ${field_info.form_field.generateFieldDeclaration(field_info, {
23
23
  form_field_types: "Fields",
@@ -28,11 +28,11 @@ export const ${toPascalCase(collection_name)}FormFields = <const>{
28
28
  }).join(",\n")}
29
29
  };
30
30
 
31
- const fields = ${toPascalCase(collection_name)}FormFields
31
+ const getFields = get${toPascalCase(collection_name)}FormFields
32
32
 
33
33
  export const get${toPascalCase(
34
34
  collection_name
35
- )}FormControls: () => Controls.FormControl[] = () => [
35
+ )}FormControls: (fields: ReturnType<typeof getFields>) => Controls.FormControl[] = (fields) => [
36
36
  ${collection_fields.map(({ name }) => `fields${wrapAttribute(name)}.getControl()`).join(",\n")}
37
37
  ];
38
38
  `;
@@ -36,6 +36,9 @@ for (const field_name in c.fields){
36
36
  }
37
37
  if(type == "single-reference"){
38
38
  target = field.target_collection;
39
+ }
40
+ if(type == "item-draft"){
41
+ target = field.target_collection_name;
39
42
  }
40
43
  if(type == "deep-reverse-single-reference" || type =="reverse-single-reference"){
41
44
  target = field.target_collection;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sealcode/sealgen",
3
- "version": "0.19.4",
3
+ "version": "0.19.6",
4
4
  "description": "Module to automate adding routes and collections to a sealious application",
5
5
  "main": "lib/index.js",
6
6
  "type": "module",
@@ -42,8 +42,8 @@ describe("checkboxed-list", () => {
42
42
  router,
43
43
  "/",
44
44
  new (class extends Form<typeof fields, unknown> {
45
- fields = fields;
46
- controls = [new CheckboxedListInput(fields.syllables)];
45
+ getFields = () => fields;
46
+ getControls = () => [new CheckboxedListInput(fields.syllables)];
47
47
 
48
48
  async onSubmit(ctx: Context) {
49
49
  received_values = await this.getParsedValues(ctx);
@@ -91,8 +91,8 @@ describe("checkboxed-list", () => {
91
91
  router,
92
92
  "/",
93
93
  new (class extends Form<typeof fields, unknown> {
94
- fields = fields;
95
- controls = [new CheckboxedListInput(fields.syllables)];
94
+ getFields = () => fields;
95
+ getControls = () => [new CheckboxedListInput(fields.syllables)];
96
96
 
97
97
  async onSubmit(ctx: Context) {
98
98
  submit_called = true;
@@ -138,8 +138,8 @@ describe("checkboxed-list", () => {
138
138
  router,
139
139
  "/",
140
140
  new (class extends Form<typeof fields, unknown> {
141
- fields = fields;
142
- controls = [new CheckboxedListInput(fields.syllables)];
141
+ getFields = () => fields;
142
+ getControls = () => [new CheckboxedListInput(fields.syllables)];
143
143
 
144
144
  async onSubmit(ctx: Context) {
145
145
  submit_called = true;
@@ -186,8 +186,8 @@ describe("checkboxed-list", () => {
186
186
  router,
187
187
  "/",
188
188
  new (class extends Form<typeof fields, unknown> {
189
- fields = fields;
190
- controls = [new CheckboxedListInput(fields.syllables)];
189
+ getFields = () => fields;
190
+ getControls = () => [new CheckboxedListInput(fields.syllables)];
191
191
 
192
192
  async onSubmit(ctx: Context) {
193
193
  submit_called = true;
@@ -232,8 +232,10 @@ describe("checkboxed-list", () => {
232
232
  router,
233
233
  "/",
234
234
  new (class extends Form<typeof fields, unknown> {
235
- fields = fields;
236
- controls = [new CheckboxedListInput(fields.syllables, { label: "ABC" })];
235
+ getFields = () => fields;
236
+ getControls = () => [
237
+ new CheckboxedListInput(fields.syllables, { label: "ABC" }),
238
+ ];
237
239
 
238
240
  async onSubmit(ctx: Context) {
239
241
  // noop
@@ -283,8 +285,10 @@ describe("checkboxed-list", () => {
283
285
  router,
284
286
  "/",
285
287
  new (class extends Form<typeof fields, unknown> {
286
- fields = fields;
287
- controls = [new CheckboxedListInput(fields.syllables, { label: "Letters" })];
288
+ getFields = () => fields;
289
+ getControls = () => [
290
+ new CheckboxedListInput(fields.syllables, { label: "Letters" }),
291
+ ];
288
292
 
289
293
  async onSubmit(ctx: Context) {
290
294
  // noop
@@ -41,8 +41,8 @@ describe("file-control", () => {
41
41
  router,
42
42
  "/",
43
43
  new (class extends Form<typeof fields, unknown> {
44
- fields = fields;
45
- controls = [new Controls.File(fields.file)];
44
+ getFields = () => fields;
45
+ getControls = () => [new Controls.File(fields.file)];
46
46
 
47
47
  async onSubmit(_ctx: Context) {
48
48
  submit_called = true;
@@ -41,8 +41,8 @@ describe("photo-control", () => {
41
41
  router,
42
42
  "/",
43
43
  new (class extends Form<typeof fields, unknown> {
44
- fields = fields;
45
- controls = [new Image(fields.photo)];
44
+ getFields = () => fields;
45
+ getControls = () => [new Image(fields.photo)];
46
46
 
47
47
  async onSubmit(ctx: Context) {
48
48
  const data = await this.getParsedValues(ctx);
@@ -94,8 +94,8 @@ describe("photo-control", () => {
94
94
  router,
95
95
  "/",
96
96
  new (class extends Form<typeof fields, unknown> {
97
- fields = fields;
98
- controls = [new Image(fields.photo)];
97
+ getFields = () => fields;
98
+ getControls = () => [new Image(fields.photo)];
99
99
 
100
100
  async onSubmit(ctx: Context) {
101
101
  submit_called = true;
@@ -41,8 +41,8 @@ describe("single-reference.test", () => {
41
41
  form_file_path,
42
42
  await formTemplate("SomeForm", {
43
43
  postimport: `import {Comments} from "../collections/collections.js"; import {Fields} from "@sealcode/sealgen";`,
44
- fields: `article: new Fields.CollectionField(true, Comments.fields.article),`,
45
- controls: `new Controls.SingleReferenceDropdown(fields.article, {getLabel: item=>item.get("title")}),`,
44
+ get_fields: `()=>(<const>{article: new Fields.CollectionField(true, Comments.fields.article)})`,
45
+ get_controls: `(fields)=>[new Controls.SingleReferenceDropdown(fields.article, {getLabel: item=>item.get("title")})]`,
46
46
  validate_method: "",
47
47
  success_message: "Submit OK",
48
48
  })
@@ -39,8 +39,8 @@ describe("basic field", () => {
39
39
  router,
40
40
  "/",
41
41
  new (class extends Form<typeof fields, unknown> {
42
- fields = fields;
43
- controls = [new SimpleInput(fields.text)];
42
+ getFields = () => fields;
43
+ getControls = () => [new SimpleInput(fields.text)];
44
44
 
45
45
  async onSubmit(ctx: Context, data: FormData) {
46
46
  received_values = await this.getParsedValues(ctx);
@@ -93,8 +93,8 @@ describe("basic field", () => {
93
93
  router,
94
94
  "/",
95
95
  new (class extends Form<typeof fields, unknown> {
96
- fields = fields;
97
- controls = [new SimpleInput(fields.text)];
96
+ getFields = () => fields;
97
+ getControls = () => [new SimpleInput(fields.text)];
98
98
 
99
99
  async onSubmit() {
100
100
  //noop
@@ -135,8 +135,11 @@ describe("basic field", () => {
135
135
  router,
136
136
  "/",
137
137
  new (class extends Form<typeof fields, unknown> {
138
- fields = fields;
139
- controls = [new SimpleInput(fields.text), new Checkbox(fields.checkbox)];
138
+ getFields = () => fields;
139
+ getControls = () => [
140
+ new SimpleInput(fields.text),
141
+ new Checkbox(fields.checkbox),
142
+ ];
140
143
 
141
144
  async onSubmit() {
142
145
  submit_called = true;
@@ -25,9 +25,8 @@ export type FormFieldValidationFn<ValueType> = (
25
25
  export type FieldParsedValue<T> = T extends FormField<infer R> ? R : never;
26
26
 
27
27
  export type GetPredicate<F extends FormField> =
28
- F extends FormField<true>
29
- ? F["predicate"]
30
- : F["predicate"] | typeof predicates.undefined;
28
+ F extends FormField<true> ? F["predicate"]
29
+ : F["predicate"] | typeof predicates.undefined;
31
30
 
32
31
  // for quickly testing GetPredicate conditonally applying the undefined predicate:
33
32
  // const f = new SimpleFormField(true);
@@ -156,9 +155,8 @@ export abstract class FormField<
156
155
  if (raw == undefined || raw == null || raw == "") {
157
156
  return {
158
157
  parsed: null,
159
- message: this.required
160
- ? "empty value, but field is required"
161
- : "",
158
+ message:
159
+ this.required ? "empty value, but field is required" : "",
162
160
  raw,
163
161
  ...(validate ? { valid: !this.required } : {}),
164
162
  };
@@ -262,13 +260,14 @@ export abstract class FormField<
262
260
  vars.form_fields
263
261
  }${wrapAttribute(field_info.name)}.sealiousValueToForm(ctx, item.get("${
264
262
  field_info.name
265
- }"))`;
263
+ }"), item)`;
266
264
  }
267
265
 
268
266
  generateImportsForFieldList(field_info: ExtractedFieldInfo): {
269
267
  what: string;
270
268
  from: string;
271
269
  as?: string;
270
+ type?: boolean;
272
271
  }[] {
273
272
  return [];
274
273
  }
@@ -15,13 +15,14 @@ export * from "./float.js";
15
15
  export * from "./html.js";
16
16
  export * from "./image.js";
17
17
  export * from "./int.js";
18
+ export * from "./item-draft.js";
18
19
  export * from "./json.js";
19
20
  export * from "./markdown.js";
20
21
  export * from "./multiple-files.js";
21
22
  export * from "./number.js";
22
23
  export * from "./password.js";
23
- export * from "./phone-number.js";
24
24
  export * from "./phone-number-with-country-code.js";
25
+ export * from "./phone-number.js";
25
26
  export * from "./pick-from-list-sealious.js";
26
27
  export * from "./pick-from-list.js";
27
28
  export * from "./regexp.js";
@@ -41,8 +41,8 @@ describe("file field", () => {
41
41
  router,
42
42
  "/",
43
43
  new (class extends Form<typeof fields, unknown> {
44
- fields = fields;
45
- controls = [new Image(fields.file)];
44
+ getFields = () => fields;
45
+ getControls = () => [new Image(fields.file)];
46
46
 
47
47
  async onSubmit(ctx: Context) {
48
48
  received_values = await this.getParsedValues(ctx);