@sealcode/sealgen 0.19.32 → 0.19.34
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/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 +26 -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
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
3
|
import { predicates } from "@sealcode/ts-predicates";
|
|
2
4
|
import { Context } from "koa";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
+
import {
|
|
6
|
+
CollectionItem,
|
|
7
|
+
Depromisify,
|
|
8
|
+
ExtractFieldDecoded,
|
|
9
|
+
ExtractFieldInput,
|
|
10
|
+
Field as SealiousField,
|
|
11
|
+
FieldTypes as SealiousFieldTypes,
|
|
12
|
+
} from "sealious";
|
|
13
|
+
import { FormControl } from "../controls/controls.js";
|
|
5
14
|
import { FormDataValue } from "../form-types.js";
|
|
6
15
|
|
|
7
16
|
import {
|
|
@@ -10,12 +19,42 @@ import {
|
|
|
10
19
|
FormFieldValidationResponse,
|
|
11
20
|
} from "./field.js";
|
|
12
21
|
import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
|
|
22
|
+
import { TextBasedSimpleField } from "./simple-form-field.js";
|
|
23
|
+
import { Image as ImageField } from "./image.js";
|
|
24
|
+
import { wrapAttribute, wrapKeyName } from "../../utils/wrap-attributes.js";
|
|
25
|
+
import { StructuredSealiousField } from "./structured.js";
|
|
26
|
+
|
|
27
|
+
export function sealiousFieldToFormField(
|
|
28
|
+
sealiousField: SealiousField<any>,
|
|
29
|
+
field_name: string,
|
|
30
|
+
prefix: string
|
|
31
|
+
): FormField {
|
|
32
|
+
const name = prefix ? `${prefix}[${field_name}]` : field_name;
|
|
33
|
+
let formfield: FormField = new TextBasedSimpleField(false);
|
|
34
|
+
if (sealiousField instanceof SealiousFieldTypes.Image) {
|
|
35
|
+
formfield = new ImageField(false);
|
|
36
|
+
}
|
|
37
|
+
if (sealiousField instanceof SealiousFieldTypes.Structured) {
|
|
38
|
+
formfield = new StructuredSealiousField(sealiousField);
|
|
39
|
+
}
|
|
40
|
+
formfield.setName(name);
|
|
41
|
+
formfield.setLabel(field_name);
|
|
42
|
+
if (prefix) {
|
|
43
|
+
formfield.setValuePath(prefix + "." + field_name);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return formfield;
|
|
47
|
+
}
|
|
13
48
|
|
|
14
49
|
export class CollectionField<
|
|
15
|
-
|
|
16
|
-
F extends Field<any>,
|
|
50
|
+
F extends SealiousField<any>,
|
|
17
51
|
Required extends boolean,
|
|
18
|
-
> extends FormField<
|
|
52
|
+
> extends FormField<
|
|
53
|
+
Required,
|
|
54
|
+
ExtractFieldDecoded<F>,
|
|
55
|
+
FormControl,
|
|
56
|
+
ExtractFieldInput<F>
|
|
57
|
+
> {
|
|
19
58
|
constructor(
|
|
20
59
|
required: Required,
|
|
21
60
|
public sealiousField: F
|
|
@@ -28,9 +67,9 @@ export class CollectionField<
|
|
|
28
67
|
async parse(
|
|
29
68
|
ctx: Context,
|
|
30
69
|
raw_value: FormDataValue
|
|
31
|
-
): Promise<FieldParseResult<ExtractFieldDecoded<F
|
|
70
|
+
): Promise<FieldParseResult<ExtractFieldDecoded<F>>> {
|
|
32
71
|
if (raw_value === undefined) {
|
|
33
|
-
return { parsable: true, parsed_value:
|
|
72
|
+
return { parsable: true, parsed_value: {} as any, error: null };
|
|
34
73
|
}
|
|
35
74
|
const encoded_value = (await this.sealiousField.encode(
|
|
36
75
|
ctx.$context,
|
|
@@ -55,7 +94,7 @@ export class CollectionField<
|
|
|
55
94
|
): Promise<FormFieldValidationResponse> {
|
|
56
95
|
const { valid, reason } = await this.sealiousField.checkValue(
|
|
57
96
|
ctx.$context,
|
|
58
|
-
value,
|
|
97
|
+
this.parsedToSealious(value),
|
|
59
98
|
undefined,
|
|
60
99
|
null,
|
|
61
100
|
undefined
|
|
@@ -63,13 +102,36 @@ export class CollectionField<
|
|
|
63
102
|
return { valid, message: reason || (!valid ? "Wrong value" : "") };
|
|
64
103
|
}
|
|
65
104
|
|
|
105
|
+
async parsedToSealious(parsed: unknown): Promise<ExtractFieldInput<F>> {
|
|
106
|
+
return sealiousFieldToFormField(
|
|
107
|
+
this.sealiousField,
|
|
108
|
+
this.name,
|
|
109
|
+
""
|
|
110
|
+
).parsedToSealious(parsed) as ExtractFieldInput<F>;
|
|
111
|
+
}
|
|
112
|
+
|
|
66
113
|
public getEmptyValue(): ExtractFieldDecoded<F> {
|
|
67
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
68
114
|
return "" as unknown as ExtractFieldDecoded<F>;
|
|
69
115
|
}
|
|
70
116
|
|
|
71
|
-
|
|
72
|
-
|
|
117
|
+
async sealiousValueToForm(
|
|
118
|
+
ctx: Context,
|
|
119
|
+
value: any,
|
|
120
|
+
item: CollectionItem<any>
|
|
121
|
+
): Promise<FormDataValue> {
|
|
122
|
+
return sealiousFieldToFormField(
|
|
123
|
+
this.sealiousField,
|
|
124
|
+
this.name,
|
|
125
|
+
""
|
|
126
|
+
).sealiousValueToForm(ctx, value, item);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
getControl(): FormControl {
|
|
130
|
+
return sealiousFieldToFormField(
|
|
131
|
+
this.sealiousField,
|
|
132
|
+
this.name,
|
|
133
|
+
""
|
|
134
|
+
).getControl();
|
|
73
135
|
}
|
|
74
136
|
|
|
75
137
|
generateFieldDeclaration(
|
|
@@ -80,4 +142,19 @@ export class CollectionField<
|
|
|
80
142
|
field_info.is_required
|
|
81
143
|
)}, ${vars.sealious_field})`;
|
|
82
144
|
}
|
|
145
|
+
|
|
146
|
+
generateInitialValue(
|
|
147
|
+
field_info: ExtractedFieldInfo,
|
|
148
|
+
vars: {
|
|
149
|
+
form_field_types: string;
|
|
150
|
+
form_fields: string;
|
|
151
|
+
}
|
|
152
|
+
): string {
|
|
153
|
+
// compared to the version in native field, we add the third argument here
|
|
154
|
+
return `${wrapKeyName(field_info.name)}: await ${
|
|
155
|
+
vars.form_fields
|
|
156
|
+
}${wrapAttribute(field_info.name)}.sealiousValueToForm(ctx, item.get("${
|
|
157
|
+
field_info.name
|
|
158
|
+
}"), item)`;
|
|
159
|
+
}
|
|
83
160
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Context } from "koa";
|
|
2
|
-
import { FormControl
|
|
2
|
+
import { FormControl } from "../controls/form-control.js";
|
|
3
3
|
import { SimpleInput } from "../controls/simple-input.js";
|
|
4
4
|
import { FormDataValue } from "../form-types.js";
|
|
5
5
|
import { FieldParseResult } from "./field.js";
|
|
@@ -39,13 +39,9 @@ export class Coordinates<
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
async
|
|
43
|
-
|
|
42
|
+
async parsedToSealious(
|
|
43
|
+
parsed: [number, number]
|
|
44
44
|
): Promise<[number, number] | undefined> {
|
|
45
|
-
const { parsed } = await this.getParsedValue(
|
|
46
|
-
fctx.ctx,
|
|
47
|
-
fctx.data.raw_values
|
|
48
|
-
);
|
|
49
45
|
return parsed || undefined;
|
|
50
46
|
}
|
|
51
47
|
|
package/src/forms/fields/date.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Context } from "koa";
|
|
2
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
3
2
|
import { SimpleInput, SimpleInputOptions } from "../controls/simple-input.js";
|
|
4
3
|
import { FormDataValue } from "../form-types.js";
|
|
5
4
|
import { FieldParseResult } from "./field.js";
|
|
@@ -36,16 +35,7 @@ export class DateField<Required extends boolean> extends SimpleFormField<
|
|
|
36
35
|
});
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
async
|
|
40
|
-
fctx: FormControlContext
|
|
41
|
-
): Promise<string | null> {
|
|
42
|
-
const { parsed } = await this.getParsedValue(
|
|
43
|
-
fctx.ctx,
|
|
44
|
-
fctx.data.raw_values
|
|
45
|
-
);
|
|
46
|
-
if (!parsed) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
38
|
+
async parsedToSealious(parsed: Date): Promise<string | null> {
|
|
49
39
|
return `${parsed.getFullYear()}-${(parsed.getMonth() + 1)
|
|
50
40
|
.toString()
|
|
51
41
|
.padStart(2, "0")}-${parsed.getDate().toString().padStart(2, "0")}`;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Context } from "koa";
|
|
2
2
|
import { SimpleInput } from "../controls/controls.js";
|
|
3
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
4
3
|
import { FormDataValue } from "../form-types.js";
|
|
5
4
|
import { FieldParseResult } from "./field.js";
|
|
6
5
|
import { SimpleFormField } from "./simple-form-field.js";
|
|
@@ -30,16 +29,7 @@ export class DateTime<Required extends boolean> extends SimpleFormField<
|
|
|
30
29
|
return { parsable: true, error: null, parsed_value };
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
async
|
|
34
|
-
fctx: FormControlContext
|
|
35
|
-
): Promise<number | null> {
|
|
36
|
-
const { parsed } = await this.getParsedValue(
|
|
37
|
-
fctx.ctx,
|
|
38
|
-
fctx.data.raw_values
|
|
39
|
-
);
|
|
40
|
-
if (parsed == null) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
32
|
+
async parsedToSealious(parsed: Date): Promise<number | null> {
|
|
43
33
|
return new Date(parsed).getTime();
|
|
44
34
|
}
|
|
45
35
|
|
|
@@ -32,7 +32,7 @@ export class DeepReverseSingleReferenceList extends CheckboxedListField<
|
|
|
32
32
|
this.item_label_getter = getter;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
parsedToSealious(): never {
|
|
36
36
|
throw new Error(
|
|
37
37
|
"This field is not set directly through field value, but instead relies on postSealiousCreate and postSealiousEdit"
|
|
38
38
|
);
|
|
@@ -10,7 +10,6 @@ import { Table } from "./table.js";
|
|
|
10
10
|
import { Table as TableControl } from "../controls/table.js";
|
|
11
11
|
import { Context } from "koa";
|
|
12
12
|
import { FormDataValue, FormData } from "../form-types.js";
|
|
13
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
14
13
|
import { HiddenInput } from "../controls/hidden-input.js";
|
|
15
14
|
import { FormField } from "./field.js";
|
|
16
15
|
|
|
@@ -87,7 +86,7 @@ export class DeepReverseSingleReferenceTable extends Table<
|
|
|
87
86
|
});
|
|
88
87
|
}
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
parsedToSealious(_value: any): Promise<unknown> {
|
|
91
90
|
throw new Error("Method not implemented.");
|
|
92
91
|
}
|
|
93
92
|
|
|
@@ -2,7 +2,6 @@ import { FieldTypes as SealiousFieldTypes } from "sealious";
|
|
|
2
2
|
import { Context } from "koa";
|
|
3
3
|
import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
|
|
4
4
|
import { CheckboxedListField } from "./checkboxed-list.js";
|
|
5
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
6
5
|
import { FormDataValue } from "../form-types.js";
|
|
7
6
|
|
|
8
7
|
export class EnumMultipleSealious<
|
|
@@ -26,11 +25,7 @@ export class EnumMultipleSealious<
|
|
|
26
25
|
return `new ${vars.form_field_types}.${this.constructor.name}(${vars.sealious_field})`;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
async
|
|
30
|
-
const { parsed } = await this.getParsedValue(
|
|
31
|
-
fctx.ctx,
|
|
32
|
-
fctx.data.raw_values
|
|
33
|
-
);
|
|
28
|
+
async parsedToSealious(parsed: Record<string, unknown>): Promise<Values[]> {
|
|
34
29
|
const result = Object.entries(parsed || {})
|
|
35
30
|
.filter(([, value]) => value == "on")
|
|
36
31
|
.map(([key]) => key as Values);
|
|
@@ -8,6 +8,8 @@ import { FormDataValue, FormData } from "../form-types.js";
|
|
|
8
8
|
import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
|
|
9
9
|
import { wrapAttribute, wrapKeyName } from "../../utils/wrap-attributes.js";
|
|
10
10
|
|
|
11
|
+
import { getProperty } from "dot-prop";
|
|
12
|
+
|
|
11
13
|
export type FormFieldValidationResponse = { valid: boolean; message: string };
|
|
12
14
|
|
|
13
15
|
export type FormDisplayInfo<C extends Collection> = {
|
|
@@ -65,6 +67,7 @@ export abstract class FormField<
|
|
|
65
67
|
SealiousValue = any,
|
|
66
68
|
> {
|
|
67
69
|
name!: string;
|
|
70
|
+
value_path: string | undefined;
|
|
68
71
|
label!: string;
|
|
69
72
|
constructor(public readonly required: Required) {}
|
|
70
73
|
predicate: Predicate = predicates.unknown;
|
|
@@ -88,6 +91,17 @@ export abstract class FormField<
|
|
|
88
91
|
return this;
|
|
89
92
|
}
|
|
90
93
|
|
|
94
|
+
public getValuePath() {
|
|
95
|
+
return (this.value_path || this.name)
|
|
96
|
+
.replaceAll("][", ".")
|
|
97
|
+
.replaceAll("[", ".");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public setValuePath(path: string) {
|
|
101
|
+
this.value_path = path;
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
public async _validate(
|
|
92
106
|
ctx: Context,
|
|
93
107
|
value: ParsedValue
|
|
@@ -157,7 +171,7 @@ export abstract class FormField<
|
|
|
157
171
|
parsed: ParsedValue | null;
|
|
158
172
|
raw: FormDataValue;
|
|
159
173
|
}> {
|
|
160
|
-
const raw = all_form_values
|
|
174
|
+
const raw = getProperty(all_form_values, this.getValuePath());
|
|
161
175
|
if (raw == undefined || raw == null || raw == "") {
|
|
162
176
|
return {
|
|
163
177
|
parsed: null,
|
|
@@ -186,14 +200,14 @@ export abstract class FormField<
|
|
|
186
200
|
parsed: parsed_value,
|
|
187
201
|
...(validate ? { valid } : {}),
|
|
188
202
|
message,
|
|
189
|
-
raw
|
|
203
|
+
raw,
|
|
190
204
|
};
|
|
191
205
|
} else {
|
|
192
206
|
return { parsed: parsed_value, raw, message: "parsed" };
|
|
193
207
|
}
|
|
194
208
|
}
|
|
195
209
|
|
|
196
|
-
setMapToFilter(fn: (parsed: ParsedValue) => unknown) {
|
|
210
|
+
setMapToFilter(fn: (parsed: ParsedValue | null) => unknown) {
|
|
197
211
|
this.mapToFilter = fn;
|
|
198
212
|
return this;
|
|
199
213
|
}
|
|
@@ -209,7 +223,11 @@ export abstract class FormField<
|
|
|
209
223
|
|
|
210
224
|
abstract getControl(): DefaultFormControl;
|
|
211
225
|
|
|
212
|
-
getSealiousCreateValue(fctx: FormControlContext):
|
|
226
|
+
getSealiousCreateValue(fctx: FormControlContext): never {
|
|
227
|
+
throw new Error("This field does not have a default sealious mapping");
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
parsedToSealious(parsed: ParsedValue): any {
|
|
213
231
|
throw new Error("This field does not have a default sealious mapping");
|
|
214
232
|
}
|
|
215
233
|
|
|
@@ -218,7 +236,9 @@ export abstract class FormField<
|
|
|
218
236
|
sealiousValue: SealiousValue | null,
|
|
219
237
|
item: CollectionItem<any>
|
|
220
238
|
): Promise<FormDataValue> {
|
|
221
|
-
throw new Error(
|
|
239
|
+
throw new Error(
|
|
240
|
+
`Field '${this.name}' does not have a default sealious mapping`
|
|
241
|
+
);
|
|
222
242
|
}
|
|
223
243
|
|
|
224
244
|
async postSealiousCreate(
|
|
@@ -252,7 +272,7 @@ export abstract class FormField<
|
|
|
252
272
|
): string {
|
|
253
273
|
return `${wrapKeyName(field_info.name)}: await ${
|
|
254
274
|
vars.form_fields
|
|
255
|
-
}${wrapAttribute(field_info.name)}.
|
|
275
|
+
}${wrapAttribute(field_info.name)}.parsedToSealious(data${wrapAttribute(field_info.name)})`;
|
|
256
276
|
}
|
|
257
277
|
|
|
258
278
|
generateInitialValue(
|
package/src/forms/fields/file.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { FilePointer, PathFilePointer } from "@sealcode/file-manager";
|
|
|
4
4
|
import { FormDataValue } from "../form-types.js";
|
|
5
5
|
import { FieldParseResult, FormField } from "./field.js";
|
|
6
6
|
import { File as FileControl } from "../controls/file.js";
|
|
7
|
-
import { FormControl
|
|
7
|
+
import { FormControl } from "../controls/form-control.js";
|
|
8
|
+
import { ImageValue } from "sealious";
|
|
8
9
|
|
|
9
10
|
export type FileContainer = {
|
|
10
11
|
old: FilePointer | null;
|
|
@@ -45,7 +46,7 @@ export class File<Required extends boolean> extends FormField<
|
|
|
45
46
|
raw_value,
|
|
46
47
|
"old",
|
|
47
48
|
predicates.instanceOf(PathFilePointer)
|
|
48
|
-
)
|
|
49
|
+
) && raw_value.old
|
|
49
50
|
) ?
|
|
50
51
|
await ctx.$app.fileManager.toPointer(raw_value.old)
|
|
51
52
|
: null;
|
|
@@ -88,13 +89,9 @@ export class File<Required extends boolean> extends FormField<
|
|
|
88
89
|
return new FileControl(this, { label: this.name, autocomplete: false });
|
|
89
90
|
}
|
|
90
91
|
|
|
91
|
-
async
|
|
92
|
-
|
|
92
|
+
async parsedToSealious(
|
|
93
|
+
value: FileContainer
|
|
93
94
|
): Promise<FilePointer | undefined> {
|
|
94
|
-
const { parsed: value } = await this.getParsedValue(
|
|
95
|
-
fctx.ctx,
|
|
96
|
-
fctx.data.raw_values
|
|
97
|
-
);
|
|
98
95
|
const pointer = value?.new || value?.old || undefined;
|
|
99
96
|
if (this.required && !pointer) {
|
|
100
97
|
throw new Error("File is required, but no value is provided");
|
|
@@ -104,11 +101,14 @@ export class File<Required extends boolean> extends FormField<
|
|
|
104
101
|
|
|
105
102
|
async sealiousValueToForm(
|
|
106
103
|
ctx: Context,
|
|
107
|
-
sealiousValue: FilePointer | string | null
|
|
104
|
+
sealiousValue: FilePointer | ImageValue | string | null
|
|
108
105
|
): Promise<{ old: FilePointer | undefined } | Record<string, never>> {
|
|
109
106
|
if (!sealiousValue) {
|
|
110
107
|
return {};
|
|
111
108
|
}
|
|
109
|
+
if (sealiousValue instanceof ImageValue) {
|
|
110
|
+
return { old: sealiousValue.toFile() };
|
|
111
|
+
}
|
|
112
112
|
if (typeof sealiousValue == "string") {
|
|
113
113
|
sealiousValue = await ctx.$app.fileManager.fromToken(sealiousValue);
|
|
114
114
|
}
|
package/src/forms/fields/int.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
2
1
|
import { NumberBasedSimpleField } from "./simple-form-field.js";
|
|
3
2
|
|
|
4
3
|
export class Int<
|
|
@@ -8,16 +7,7 @@ export class Int<
|
|
|
8
7
|
super(required, "number");
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
async
|
|
12
|
-
fctx: FormControlContext
|
|
13
|
-
): Promise<number | undefined> {
|
|
14
|
-
const { parsed } = await this.getParsedValue(
|
|
15
|
-
fctx.ctx,
|
|
16
|
-
fctx.data.raw_values
|
|
17
|
-
);
|
|
18
|
-
if (parsed == null) {
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
10
|
+
async parsedToSealious(parsed: number): Promise<number | undefined> {
|
|
21
11
|
if (isNaN(parsed)) {
|
|
22
12
|
return undefined;
|
|
23
13
|
} else return parsed;
|
package/src/forms/fields/json.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Context } from "koa";
|
|
2
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
3
2
|
import { Textarea } from "../controls/textarea.js";
|
|
4
3
|
import { FormDataValue } from "../form-types.js";
|
|
5
4
|
import { FieldParseResult } from "./field.js";
|
|
@@ -36,13 +35,9 @@ export class JSONField<Required extends boolean> extends SimpleFormField<
|
|
|
36
35
|
};
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
async
|
|
40
|
-
|
|
38
|
+
async parsedToSealious(
|
|
39
|
+
parsed: Record<string, unknown>
|
|
41
40
|
): Promise<Record<string, unknown> | null> {
|
|
42
|
-
const { parsed } = await this.getParsedValue(
|
|
43
|
-
fctx.ctx,
|
|
44
|
-
fctx.data.raw_values
|
|
45
|
-
);
|
|
46
41
|
return parsed;
|
|
47
42
|
}
|
|
48
43
|
}
|
|
@@ -7,7 +7,6 @@ import { FormDataValue } from "../form-types.js";
|
|
|
7
7
|
import { FieldParseResult, FormField } from "./field.js";
|
|
8
8
|
import { PickFromListField } from "./pick-from-list.js";
|
|
9
9
|
import { PhoneNumberWithoutCountryCode } from "./phone-number.js";
|
|
10
|
-
import { FormControlContext } from "../../index.js";
|
|
11
10
|
|
|
12
11
|
export class PhoneNumberWithCountryCode<
|
|
13
12
|
Required extends boolean,
|
|
@@ -57,11 +56,9 @@ export class PhoneNumberWithCountryCode<
|
|
|
57
56
|
});
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
async
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
fctx.data.raw_values
|
|
64
|
-
);
|
|
59
|
+
async parsedToSealious(
|
|
60
|
+
parsed: SealiousFieldTypes.PhoneNumberValue
|
|
61
|
+
): Promise<string> {
|
|
65
62
|
if (!parsed) {
|
|
66
63
|
return "";
|
|
67
64
|
}
|
|
@@ -3,7 +3,6 @@ import { Context } from "koa";
|
|
|
3
3
|
import { SimpleInput } from "../controls/simple-input.js";
|
|
4
4
|
import { FormDataValue } from "../form-types.js";
|
|
5
5
|
import { FieldParseResult, FormField } from "./field.js";
|
|
6
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
7
6
|
|
|
8
7
|
export class RegExpField<Required extends boolean> extends FormField<
|
|
9
8
|
Required,
|
|
@@ -62,11 +61,7 @@ export class RegExpField<Required extends boolean> extends FormField<
|
|
|
62
61
|
return new SimpleInput(this, { label: this.label || this.name });
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
async
|
|
66
|
-
const { parsed } = await this.getParsedValue(
|
|
67
|
-
fctx.ctx,
|
|
68
|
-
fctx.data.raw_values
|
|
69
|
-
);
|
|
64
|
+
async parsedToSealious(parsed: string): Promise<string> {
|
|
70
65
|
return parsed || "";
|
|
71
66
|
}
|
|
72
67
|
|
|
@@ -4,9 +4,8 @@ import { Context } from "koa";
|
|
|
4
4
|
import { predicates } from "@sealcode/ts-predicates";
|
|
5
5
|
import { FieldParseResult, FormField } from "./field.js";
|
|
6
6
|
import { SimpleInput } from "../controls/simple-input.js";
|
|
7
|
-
import { FormControl } from "../controls/controls.js";
|
|
7
|
+
import { FormControl, Textarea } from "../controls/controls.js";
|
|
8
8
|
import { CollectionItem } from "sealious";
|
|
9
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
10
9
|
|
|
11
10
|
export abstract class SimpleFormField<
|
|
12
11
|
Required extends boolean,
|
|
@@ -56,17 +55,8 @@ export class TextBasedSimpleField<
|
|
|
56
55
|
};
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
async
|
|
60
|
-
|
|
61
|
-
): Promise<string | null> {
|
|
62
|
-
if (this.disabled) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
const { parsed } = await this.getParsedValue(
|
|
66
|
-
fctx.ctx,
|
|
67
|
-
fctx.data.raw_values
|
|
68
|
-
);
|
|
69
|
-
return parsed || "";
|
|
58
|
+
async parsedToSealious(value: string): Promise<string> {
|
|
59
|
+
return value || "";
|
|
70
60
|
}
|
|
71
61
|
|
|
72
62
|
async postSealiousCreate(
|
|
@@ -84,7 +74,7 @@ export class TextBasedSimpleField<
|
|
|
84
74
|
): Promise<void> {}
|
|
85
75
|
|
|
86
76
|
getControl(): DefaultControl {
|
|
87
|
-
return new
|
|
77
|
+
return new Textarea(this, {
|
|
88
78
|
label: this.label || this.name,
|
|
89
79
|
type: this.type,
|
|
90
80
|
}) as unknown as DefaultControl;
|
|
@@ -110,14 +100,8 @@ export class NumberBasedSimpleField<
|
|
|
110
100
|
};
|
|
111
101
|
}
|
|
112
102
|
|
|
113
|
-
async
|
|
114
|
-
|
|
115
|
-
): Promise<number | undefined> {
|
|
116
|
-
const { parsed } = await this.getParsedValue(
|
|
117
|
-
fctx.ctx,
|
|
118
|
-
fctx.data.raw_values
|
|
119
|
-
);
|
|
120
|
-
return parsed || 0;
|
|
103
|
+
async parsedToSealious(value: number): Promise<number | undefined> {
|
|
104
|
+
return value || 0;
|
|
121
105
|
}
|
|
122
106
|
|
|
123
107
|
async postSealiousCreate(): Promise<void> {}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Collection,
|
|
3
|
+
ExtractFieldInput,
|
|
4
|
+
FieldTypes as SealiousFieldTypes,
|
|
5
|
+
} from "sealious";
|
|
2
6
|
import { CollectionField } from "./collection-field.js";
|
|
3
7
|
import { SingleReferenceDropdown } from "../controls/single-reference.js";
|
|
4
|
-
import { FormControlContext } from "../controls/form-control.js";
|
|
5
8
|
import { Context } from "koa";
|
|
6
9
|
import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
|
|
7
10
|
import { toPascalCase } from "js-convert-case";
|
|
@@ -18,14 +21,8 @@ export class SingleReference<
|
|
|
18
21
|
});
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
async
|
|
22
|
-
|
|
23
|
-
): Promise<string | undefined> {
|
|
24
|
-
const { parsed } = await this.getParsedValue(
|
|
25
|
-
fctx.ctx,
|
|
26
|
-
fctx.data.raw_values
|
|
27
|
-
);
|
|
28
|
-
return parsed || undefined;
|
|
24
|
+
async parsedToSealious(parsed: string): Promise<ExtractFieldInput<F>> {
|
|
25
|
+
return (parsed || "") as ExtractFieldInput<F>;
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
async sealiousValueToForm(_ctx: Context, value: string | null) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
4
3
|
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
5
4
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
@@ -14,7 +13,7 @@ import {
|
|
|
14
13
|
sealiousToFormField,
|
|
15
14
|
SealiousToFormField,
|
|
16
15
|
} from "./get-field-for-sealious.js";
|
|
17
|
-
import { FormControl
|
|
16
|
+
import { FormControl } from "../controls/form-control.js";
|
|
18
17
|
import { ExtractedFieldInfo } from "../../utils/extract-fields-from-collection.js";
|
|
19
18
|
import { Table } from "./table.js";
|
|
20
19
|
|
|
@@ -73,11 +72,7 @@ export class StructuredArray<
|
|
|
73
72
|
return `new ${vars.form_field_types}.${this.constructor.name}(${vars.sealious_field})`;
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
async
|
|
77
|
-
const { parsed } = await this.getParsedValue(
|
|
78
|
-
fctx.ctx,
|
|
79
|
-
fctx.data.raw_values
|
|
80
|
-
);
|
|
75
|
+
async parsedToSealious(parsed: any): Promise<any> {
|
|
81
76
|
return parsed || this.getEmptyValue();
|
|
82
77
|
}
|
|
83
78
|
|