@sealcode/sealgen 0.19.32 → 0.19.33
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.
- package/@types/forms/controls/array.d.ts +1 -3
- package/@types/forms/controls/dropdown.d.ts +2 -2
- package/@types/forms/fields/CollectionField.d.ts +1 -0
- package/@types/forms/fields/boolean.d.ts +1 -2
- package/@types/forms/fields/collection-field.d.ts +12 -5
- package/@types/forms/fields/coordinates.d.ts +2 -2
- package/@types/forms/fields/date.d.ts +1 -2
- package/@types/forms/fields/datetime.d.ts +1 -2
- package/@types/forms/fields/deep-reverse-single-reference-list.d.ts +1 -1
- package/@types/forms/fields/deep-reverse-single-reference-table.d.ts +1 -2
- package/@types/forms/fields/enum-multiple-sealious.d.ts +1 -2
- package/@types/forms/fields/field.d.ts +6 -2
- package/@types/forms/fields/fields.d.ts +1 -0
- package/@types/forms/fields/file.d.ts +4 -3
- package/@types/forms/fields/int.d.ts +1 -2
- package/@types/forms/fields/json.d.ts +1 -2
- package/@types/forms/fields/phone-number-with-country-code.d.ts +1 -2
- package/@types/forms/fields/regexp.d.ts +1 -2
- package/@types/forms/fields/simple-form-field.d.ts +2 -3
- package/@types/forms/fields/single-reference.d.ts +2 -3
- package/@types/forms/fields/structured-array.d.ts +1 -2
- package/@types/forms/fields/structured.d.ts +19 -0
- package/@types/forms/fields/text.d.ts +1 -2
- package/@types/forms/fields/url.d.ts +1 -2
- package/lib/forms/controls/checkboxed-list-input.test.js +3 -3
- package/lib/forms/controls/field-group.js +3 -1
- package/lib/forms/controls/simple-input.js +6 -4
- package/lib/forms/fields/boolean.js +2 -6
- package/lib/forms/fields/collection-field.js +49 -5
- package/lib/forms/fields/coordinates.js +1 -5
- package/lib/forms/fields/date.js +1 -8
- package/lib/forms/fields/datetime.js +1 -8
- package/lib/forms/fields/deep-reverse-single-reference-list.js +1 -1
- package/lib/forms/fields/deep-reverse-single-reference-table.js +1 -1
- package/lib/forms/fields/enum-multiple-sealious.js +1 -5
- package/lib/forms/fields/field.js +17 -4
- package/lib/forms/fields/fields.js +1 -0
- package/lib/forms/fields/file.js +6 -6
- package/lib/forms/fields/int.js +1 -8
- package/lib/forms/fields/json.js +1 -5
- package/lib/forms/fields/phone-number-with-country-code.js +1 -5
- package/lib/forms/fields/regexp.js +1 -5
- package/lib/forms/fields/simple-form-field.js +6 -16
- package/lib/forms/fields/single-reference.js +2 -6
- package/lib/forms/fields/structured-array.js +1 -5
- package/lib/forms/fields/structured.js +107 -0
- package/lib/forms/fields/text.js +1 -5
- package/lib/forms/fields/url.js +2 -6
- package/lib/forms/form.js +2 -1
- package/lib/templates/shared/collection-create-form.js +4 -0
- package/lib/templates/shared/collection-edit-form.js +5 -0
- package/lib/utils/input-wrapper.js +2 -2
- package/package.json +3 -2
- package/src/forms/controls/checkboxed-list-input.test.ts +3 -3
- package/src/forms/controls/dropdown.ts +1 -1
- package/src/forms/controls/field-group.ts +9 -7
- package/src/forms/controls/simple-input.ts +19 -15
- package/src/forms/controls/textarea.ts +1 -1
- package/src/forms/fields/boolean.ts +2 -7
- package/src/forms/fields/collection-field.ts +88 -11
- package/src/forms/fields/coordinates.ts +3 -7
- package/src/forms/fields/date.ts +1 -11
- package/src/forms/fields/datetime.ts +1 -11
- package/src/forms/fields/deep-reverse-single-reference-list.ts +1 -1
- package/src/forms/fields/deep-reverse-single-reference-table.ts +1 -2
- package/src/forms/fields/enum-multiple-sealious.ts +1 -6
- package/src/forms/fields/field.ts +24 -6
- package/src/forms/fields/fields.ts +1 -0
- package/src/forms/fields/file.ts +9 -9
- package/src/forms/fields/int.ts +1 -11
- package/src/forms/fields/json.ts +2 -7
- package/src/forms/fields/phone-number-with-country-code.ts +3 -6
- package/src/forms/fields/regexp.ts +1 -6
- package/src/forms/fields/simple-form-field.ts +6 -22
- package/src/forms/fields/single-reference.ts +7 -10
- package/src/forms/fields/structured-array.ts +2 -7
- package/src/forms/fields/structured.ts +151 -0
- package/src/forms/fields/text.ts +1 -6
- package/src/forms/fields/url.ts +2 -9
- package/src/forms/form.ts +2 -1
- package/src/templates/shared/collection-create-form.ts +4 -0
- package/src/templates/shared/collection-edit-form.ts +5 -0
- package/src/utils/input-wrapper.ts +2 -2
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
+
import { is, predicates } from "@sealcode/ts-predicates";
|
|
5
|
+
import {
|
|
6
|
+
CollectionItem,
|
|
7
|
+
ExtractFieldDecoded,
|
|
8
|
+
ExtractFieldInput,
|
|
9
|
+
Field as SealiousField,
|
|
10
|
+
FieldTypes as SealiousFieldTypes,
|
|
11
|
+
} from "sealious";
|
|
12
|
+
import { FieldParseResult, FormField } from "./field.js";
|
|
13
|
+
import { FieldGroup, FormControl } from "../controls/controls.js";
|
|
14
|
+
import { Context } from "koa";
|
|
15
|
+
import { FormDataValue } from "../form-types.js";
|
|
16
|
+
import { sealiousFieldToFormField } from "./collection-field.js";
|
|
17
|
+
import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
|
|
18
|
+
|
|
19
|
+
export class StructuredSealiousField<
|
|
20
|
+
Structure extends Record<string, SealiousField<any>>,
|
|
21
|
+
F extends SealiousFieldTypes.Structured<Structure>,
|
|
22
|
+
> extends FormField<
|
|
23
|
+
false,
|
|
24
|
+
ExtractFieldDecoded<F>,
|
|
25
|
+
FormControl,
|
|
26
|
+
ExtractFieldInput<F>
|
|
27
|
+
> {
|
|
28
|
+
constructor(public sealiousField: F) {
|
|
29
|
+
super(false);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public getEmptyValue(): ExtractFieldDecoded<F> {
|
|
33
|
+
return {} as ExtractFieldDecoded<F>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async parse(
|
|
37
|
+
ctx: Context,
|
|
38
|
+
raw_value: FormDataValue
|
|
39
|
+
): Promise<FieldParseResult<ExtractFieldDecoded<F>>> {
|
|
40
|
+
const sealiousField = this
|
|
41
|
+
.sealiousField as SealiousFieldTypes.Structured<
|
|
42
|
+
Record<string, SealiousField<any>>
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
if (!is(raw_value, predicates.object)) {
|
|
46
|
+
raw_value = {};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const results = await Promise.all(
|
|
50
|
+
Object.entries(sealiousField.fields).map(async ([key, field]) => {
|
|
51
|
+
const formfield = sealiousFieldToFormField(
|
|
52
|
+
field,
|
|
53
|
+
key,
|
|
54
|
+
this.name
|
|
55
|
+
);
|
|
56
|
+
return <const>[
|
|
57
|
+
key,
|
|
58
|
+
await formfield.parse(
|
|
59
|
+
ctx,
|
|
60
|
+
((raw_value as Record<string, unknown>)[key] ||
|
|
61
|
+
"") as any
|
|
62
|
+
),
|
|
63
|
+
];
|
|
64
|
+
})
|
|
65
|
+
);
|
|
66
|
+
const parsable = results.every(([, r]) => r.parsable);
|
|
67
|
+
if (parsable) {
|
|
68
|
+
return {
|
|
69
|
+
parsable,
|
|
70
|
+
error: null,
|
|
71
|
+
parsed_value: Object.fromEntries(
|
|
72
|
+
results.map(([key, value]) => [key, value.parsed_value])
|
|
73
|
+
) as any,
|
|
74
|
+
};
|
|
75
|
+
} else
|
|
76
|
+
return {
|
|
77
|
+
parsable: <const>false,
|
|
78
|
+
parsed_value: null,
|
|
79
|
+
error: results.map(([, r]) => r.error).join("; "),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async parsedToSealious(parsed: Record<string, unknown> | null) {
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
85
|
+
return Object.fromEntries(
|
|
86
|
+
await Promise.all(
|
|
87
|
+
Object.entries(parsed as Record<string, any>).map(
|
|
88
|
+
async ([key, value]: [string, any]) => {
|
|
89
|
+
const sealious_field = this.sealiousField.fields[key]!;
|
|
90
|
+
const formfield = sealiousFieldToFormField(
|
|
91
|
+
sealious_field,
|
|
92
|
+
key,
|
|
93
|
+
this.name
|
|
94
|
+
);
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
96
|
+
return [key, await formfield.parsedToSealious(value)];
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async sealiousValueToForm(
|
|
104
|
+
ctx: Context,
|
|
105
|
+
sealiousValue: ExtractFieldDecoded<F> | ExtractFieldInput<F> | null,
|
|
106
|
+
item: CollectionItem<any>
|
|
107
|
+
): Promise<FormDataValue> {
|
|
108
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
109
|
+
return Object.fromEntries(
|
|
110
|
+
await Promise.all(
|
|
111
|
+
Object.entries(
|
|
112
|
+
(sealiousValue || {}) as Record<string, any>
|
|
113
|
+
).map(async ([key, value]: [string, any]) => {
|
|
114
|
+
const sealious_field = this.sealiousField.fields[key]!;
|
|
115
|
+
const formfield = sealiousFieldToFormField(
|
|
116
|
+
sealious_field,
|
|
117
|
+
key,
|
|
118
|
+
this.name
|
|
119
|
+
);
|
|
120
|
+
return [
|
|
121
|
+
key,
|
|
122
|
+
await formfield.sealiousValueToForm(ctx, value, item),
|
|
123
|
+
];
|
|
124
|
+
})
|
|
125
|
+
)
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
getControl() {
|
|
130
|
+
const structured = this.sealiousField;
|
|
131
|
+
return new FieldGroup(
|
|
132
|
+
Object.keys(structured.fields).map((key) => {
|
|
133
|
+
return sealiousFieldToFormField(
|
|
134
|
+
structured.fields[key]!,
|
|
135
|
+
key,
|
|
136
|
+
this.name
|
|
137
|
+
)
|
|
138
|
+
.setLabel(key)
|
|
139
|
+
.getControl();
|
|
140
|
+
}),
|
|
141
|
+
{ label: this.name }
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
generateFieldDeclaration(
|
|
146
|
+
_field_info: ExtractedFieldInfo,
|
|
147
|
+
vars: { form_field_types: string; sealious_field: string }
|
|
148
|
+
): string {
|
|
149
|
+
return `new ${vars.form_field_types}.${this.constructor.name}(${vars.sealious_field})`;
|
|
150
|
+
}
|
|
151
|
+
}
|
package/src/forms/fields/text.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
2
1
|
import { TextBasedSimpleField } from "./simple-form-field.js";
|
|
3
2
|
|
|
4
3
|
export class Text<
|
|
@@ -8,11 +7,7 @@ export class Text<
|
|
|
8
7
|
super(required, "text");
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
async
|
|
12
|
-
const { parsed } = await this.getParsedValue(
|
|
13
|
-
fctx.ctx,
|
|
14
|
-
fctx.data.raw_values
|
|
15
|
-
);
|
|
10
|
+
async parsedToSealious(parsed: string): Promise<string> {
|
|
16
11
|
return parsed || this.getEmptyValue();
|
|
17
12
|
}
|
|
18
13
|
}
|
package/src/forms/fields/url.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
2
1
|
import { TextBasedSimpleField } from "./simple-form-field.js";
|
|
3
2
|
|
|
4
3
|
export class URLField<
|
|
@@ -8,13 +7,7 @@ export class URLField<
|
|
|
8
7
|
super(required, "text");
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
async
|
|
12
|
-
|
|
13
|
-
): Promise<string | null> {
|
|
14
|
-
const { parsed } = await this.getParsedValue(
|
|
15
|
-
fctx.ctx,
|
|
16
|
-
fctx.data.raw_values
|
|
17
|
-
);
|
|
18
|
-
return parsed || null;
|
|
10
|
+
async parsedToSealious(parsed: string | null): Promise<string> {
|
|
11
|
+
return parsed || "";
|
|
19
12
|
}
|
|
20
13
|
}
|
package/src/forms/form.ts
CHANGED
|
@@ -280,10 +280,11 @@ export abstract class Form<
|
|
|
280
280
|
|
|
281
281
|
router.get(path, async (ctx) => {
|
|
282
282
|
ctx.type = "html";
|
|
283
|
+
const raw_values = await this.extractRawValues(ctx);
|
|
283
284
|
ctx.body = await this.render(
|
|
284
285
|
ctx,
|
|
285
286
|
{
|
|
286
|
-
raw_values
|
|
287
|
+
raw_values,
|
|
287
288
|
messages: [],
|
|
288
289
|
field_messages: {},
|
|
289
290
|
},
|
|
@@ -46,6 +46,10 @@ export async function createItemFormTemplate(
|
|
|
46
46
|
onsubmit: `
|
|
47
47
|
async onSubmit(ctx: Context, formData: FormData) {
|
|
48
48
|
const fctx = this.makeFormControlContext(ctx, formData, true);
|
|
49
|
+
const data = await this.getParsedValues(ctx);
|
|
50
|
+
if (!data) {
|
|
51
|
+
throw new Error("Error when parsing the form values");
|
|
52
|
+
}
|
|
49
53
|
|
|
50
54
|
const created = await ctx.$app.collections["${toKebabCase(
|
|
51
55
|
collection_name
|
|
@@ -61,6 +61,11 @@ export async function editItemFormTemplate(
|
|
|
61
61
|
throw new Error("Unknown id: " + id);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
const data = await this.getParsedValues(ctx);
|
|
65
|
+
if (!data) {
|
|
66
|
+
throw new Error("Error when parsing the form values");
|
|
67
|
+
}
|
|
68
|
+
|
|
64
69
|
|
|
65
70
|
item.setMultipleExtraSafe(
|
|
66
71
|
{
|
|
@@ -15,13 +15,13 @@ export async function inputWrapper(
|
|
|
15
15
|
modifiers: string[],
|
|
16
16
|
input: FlatTemplatable
|
|
17
17
|
): Promise<string> {
|
|
18
|
-
return tempstream /* HTML */ `<
|
|
18
|
+
return tempstream /* HTML */ `<label
|
|
19
19
|
class="form-input form-input--type-${type} form-input__wrapper ${getModifierClasses(
|
|
20
20
|
modifiers
|
|
21
21
|
)}"
|
|
22
22
|
>
|
|
23
23
|
${input}
|
|
24
|
-
</
|
|
24
|
+
</label>`;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export async function autoWrapInput(field: FormField, input: FlatTemplatable) {
|