@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
|
@@ -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,15 @@ export abstract class FormField<
|
|
|
88
91
|
return this;
|
|
89
92
|
}
|
|
90
93
|
|
|
94
|
+
public getValuePath() {
|
|
95
|
+
return this.value_path || this.name;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public setValuePath(path: string) {
|
|
99
|
+
this.value_path = path;
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
|
|
91
103
|
public async _validate(
|
|
92
104
|
ctx: Context,
|
|
93
105
|
value: ParsedValue
|
|
@@ -157,7 +169,7 @@ export abstract class FormField<
|
|
|
157
169
|
parsed: ParsedValue | null;
|
|
158
170
|
raw: FormDataValue;
|
|
159
171
|
}> {
|
|
160
|
-
const raw = all_form_values
|
|
172
|
+
const raw = getProperty(all_form_values, this.getValuePath());
|
|
161
173
|
if (raw == undefined || raw == null || raw == "") {
|
|
162
174
|
return {
|
|
163
175
|
parsed: null,
|
|
@@ -186,14 +198,14 @@ export abstract class FormField<
|
|
|
186
198
|
parsed: parsed_value,
|
|
187
199
|
...(validate ? { valid } : {}),
|
|
188
200
|
message,
|
|
189
|
-
raw
|
|
201
|
+
raw,
|
|
190
202
|
};
|
|
191
203
|
} else {
|
|
192
204
|
return { parsed: parsed_value, raw, message: "parsed" };
|
|
193
205
|
}
|
|
194
206
|
}
|
|
195
207
|
|
|
196
|
-
setMapToFilter(fn: (parsed: ParsedValue) => unknown) {
|
|
208
|
+
setMapToFilter(fn: (parsed: ParsedValue | null) => unknown) {
|
|
197
209
|
this.mapToFilter = fn;
|
|
198
210
|
return this;
|
|
199
211
|
}
|
|
@@ -209,7 +221,11 @@ export abstract class FormField<
|
|
|
209
221
|
|
|
210
222
|
abstract getControl(): DefaultFormControl;
|
|
211
223
|
|
|
212
|
-
getSealiousCreateValue(fctx: FormControlContext):
|
|
224
|
+
getSealiousCreateValue(fctx: FormControlContext): never {
|
|
225
|
+
throw new Error("This field does not have a default sealious mapping");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
parsedToSealious(parsed: ParsedValue): any {
|
|
213
229
|
throw new Error("This field does not have a default sealious mapping");
|
|
214
230
|
}
|
|
215
231
|
|
|
@@ -218,7 +234,9 @@ export abstract class FormField<
|
|
|
218
234
|
sealiousValue: SealiousValue | null,
|
|
219
235
|
item: CollectionItem<any>
|
|
220
236
|
): Promise<FormDataValue> {
|
|
221
|
-
throw new Error(
|
|
237
|
+
throw new Error(
|
|
238
|
+
`Field '${this.name}' does not have a default sealious mapping`
|
|
239
|
+
);
|
|
222
240
|
}
|
|
223
241
|
|
|
224
242
|
async postSealiousCreate(
|
|
@@ -252,7 +270,7 @@ export abstract class FormField<
|
|
|
252
270
|
): string {
|
|
253
271
|
return `${wrapKeyName(field_info.name)}: await ${
|
|
254
272
|
vars.form_fields
|
|
255
|
-
}${wrapAttribute(field_info.name)}.
|
|
273
|
+
}${wrapAttribute(field_info.name)}.parsedToSealious(data${wrapAttribute(field_info.name)})`;
|
|
256
274
|
}
|
|
257
275
|
|
|
258
276
|
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
|
|