@sealcode/sealgen 0.15.32 → 0.15.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/src/page/mountable-with-fields.d.ts +2 -1
- package/@types/src/utils/utils.d.ts +1 -0
- package/@types/src/utils/with-fallback.d.ts +2 -0
- package/lib/page/mountable-with-fields.test.js +8 -4
- package/lib/utils/utils.js +1 -0
- package/lib/utils/with-fallback.js +21 -0
- package/package.json +1 -1
- package/src/page/mountable-with-fields.test.ts +9 -4
- package/src/page/mountable-with-fields.ts +9 -4
- package/src/utils/utils.ts +1 -0
- package/src/utils/with-fallback.ts +47 -0
|
@@ -11,6 +11,7 @@ export type PageErrorMessage = {
|
|
|
11
11
|
};
|
|
12
12
|
export type Fields = Record<string, FormField<boolean, any>>;
|
|
13
13
|
type Resolved<T> = T extends Promise<infer X> ? X : never;
|
|
14
|
+
type ParsedValue<T extends FormField> = Resolved<ReturnType<T["getValue"]>>["parsed"];
|
|
14
15
|
export declare abstract class MountableWithFields<F extends Fields = Fields> extends Mountable {
|
|
15
16
|
fields: F;
|
|
16
17
|
field_names_prefix: string;
|
|
@@ -34,7 +35,7 @@ export declare abstract class MountableWithFields<F extends Fields = Fields> ext
|
|
|
34
35
|
renderMessages(_: Context, data: FormData<keyof Fields>): FlatTemplatable;
|
|
35
36
|
abstract extractRawValues(ctx: Context): Promise<Record<string, FormDataValue>>;
|
|
36
37
|
getParsedValues(ctx: Context): Promise<{
|
|
37
|
-
[field in keyof F]:
|
|
38
|
+
[field in keyof F]: F[field] extends FormField<true> ? Exclude<ParsedValue<F[field]>, null> : ParsedValue<F[field]>;
|
|
38
39
|
}>;
|
|
39
40
|
getDatabaseValues(ctx: Context): Promise<ShapeToType<FieldsToShape<F>>>;
|
|
40
41
|
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare function withFallback<T1, T2 extends NonNullable<unknown>>(value1: T1, value2: T2): NonNullable<T1> | T2;
|
|
2
|
+
export declare function withFallback<T1, T2, T3 extends NonNullable<unknown>>(value1: T1, value2: T2, value3?: T3): NonNullable<T1> | NonNullable<T2> | T3;
|
|
@@ -2,8 +2,11 @@ import { Form } from "../forms/form.js";
|
|
|
2
2
|
import { FieldTypes } from "sealious";
|
|
3
3
|
import { CollectionField } from "../forms/fields/collection-field.js";
|
|
4
4
|
describe("mountable-with-fields", () => {
|
|
5
|
-
it("properly types the getParsedValues method", () => {
|
|
6
|
-
const fields = {
|
|
5
|
+
it("properly types the getParsedValues method and respects required status", () => {
|
|
6
|
+
const fields = {
|
|
7
|
+
not_required: new CollectionField(false, new FieldTypes.Text()),
|
|
8
|
+
required: new CollectionField(true, new FieldTypes.Text())
|
|
9
|
+
};
|
|
7
10
|
new class extends Form {
|
|
8
11
|
constructor() {
|
|
9
12
|
super(...arguments);
|
|
@@ -12,8 +15,9 @@ describe("mountable-with-fields", () => {
|
|
|
12
15
|
}
|
|
13
16
|
async onSubmit(ctx, form_values) {
|
|
14
17
|
const data = await this.getParsedValues(ctx);
|
|
15
|
-
data.
|
|
16
|
-
|
|
18
|
+
data.not_required?.trim();
|
|
19
|
+
data.required.trim();
|
|
20
|
+
const { parsed: data2 } = await this.fields.not_required.getValue(
|
|
17
21
|
ctx,
|
|
18
22
|
form_values.raw_values
|
|
19
23
|
);
|
package/lib/utils/utils.js
CHANGED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
function withFallback(value1, value2, value3) {
|
|
2
|
+
if (value3 !== void 0) {
|
|
3
|
+
if (value1 !== null && value1 !== void 0 && value2 !== null && value2 !== void 0) {
|
|
4
|
+
return value2;
|
|
5
|
+
} else {
|
|
6
|
+
return value3;
|
|
7
|
+
}
|
|
8
|
+
} else {
|
|
9
|
+
if (value1 !== null && value1 !== void 0) {
|
|
10
|
+
return value1;
|
|
11
|
+
} else if (value2 !== void 0 && value2 !== null) {
|
|
12
|
+
return value2;
|
|
13
|
+
} else {
|
|
14
|
+
throw new Error("No suitable fallback: ${arguments}");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
withFallback
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=with-fallback.js.map
|
package/package.json
CHANGED
|
@@ -5,16 +5,21 @@ import { CollectionField } from "../forms/fields/collection-field.js";
|
|
|
5
5
|
import { FormData } from "../forms/form-types.js";
|
|
6
6
|
|
|
7
7
|
describe("mountable-with-fields", () => {
|
|
8
|
-
it("properly types the getParsedValues method", () => {
|
|
9
|
-
const fields = {
|
|
8
|
+
it("properly types the getParsedValues method and respects required status", () => {
|
|
9
|
+
const fields = {
|
|
10
|
+
not_required: new CollectionField(false, new FieldTypes.Text()),
|
|
11
|
+
required: new CollectionField(true, new FieldTypes.Text()),
|
|
12
|
+
};
|
|
10
13
|
new (class extends Form<typeof fields, void> {
|
|
11
14
|
fields = fields;
|
|
12
15
|
controls = [];
|
|
13
16
|
async onSubmit(ctx: Context, form_values: FormData) {
|
|
14
17
|
const data = await this.getParsedValues(ctx);
|
|
15
18
|
// this should not throw a Typescript error
|
|
16
|
-
data.
|
|
17
|
-
|
|
19
|
+
data.not_required?.trim();
|
|
20
|
+
// this should work without the optional chaining:
|
|
21
|
+
data.required.trim();
|
|
22
|
+
const { parsed: data2 } = await this.fields.not_required.getValue(
|
|
18
23
|
ctx,
|
|
19
24
|
form_values.raw_values
|
|
20
25
|
);
|
|
@@ -19,6 +19,9 @@ export type PageErrorMessage = { type: "access" | "internal"; message: string };
|
|
|
19
19
|
export type Fields = Record<string, FormField<boolean, any>>;
|
|
20
20
|
|
|
21
21
|
type Resolved<T> = T extends Promise<infer X> ? X : never;
|
|
22
|
+
type ParsedValue<T extends FormField> = Resolved<
|
|
23
|
+
ReturnType<T["getValue"]>
|
|
24
|
+
>["parsed"];
|
|
22
25
|
|
|
23
26
|
export abstract class MountableWithFields<
|
|
24
27
|
F extends Fields = Fields
|
|
@@ -137,9 +140,9 @@ export abstract class MountableWithFields<
|
|
|
137
140
|
): Promise<Record<string, FormDataValue>>;
|
|
138
141
|
|
|
139
142
|
async getParsedValues(ctx: Context): Promise<{
|
|
140
|
-
[field in keyof F]:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
[field in keyof F]: F[field] extends FormField<true>
|
|
144
|
+
? Exclude<ParsedValue<F[field]>, null>
|
|
145
|
+
: ParsedValue<F[field]>;
|
|
143
146
|
}> {
|
|
144
147
|
const raw_values = await this.extractRawValues(ctx);
|
|
145
148
|
const result: Record<string, unknown> = {};
|
|
@@ -151,7 +154,9 @@ export abstract class MountableWithFields<
|
|
|
151
154
|
}
|
|
152
155
|
);
|
|
153
156
|
await Promise.all(promises);
|
|
154
|
-
|
|
157
|
+
// TODO: remove this any. I don't have the strenght to deal with it now.
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return
|
|
159
|
+
return result as any;
|
|
155
160
|
}
|
|
156
161
|
|
|
157
162
|
async getDatabaseValues(
|
package/src/utils/utils.ts
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// use this to more concisely define values with one or more fallbacks to use when they are null.
|
|
2
|
+
|
|
3
|
+
// If called with two args, the second one has to be non-null
|
|
4
|
+
// if called with three args, the third one has to be non-null
|
|
5
|
+
//
|
|
6
|
+
// in two-arg mode, if the first argument is not null, then it's returned and fallback is not used.
|
|
7
|
+
// if the first argument is null, then the second arg is returned
|
|
8
|
+
//
|
|
9
|
+
// in three-arg mode, the first value is never returned. If the first arg is not-null, then the second arg is returned (if it's not null). Otherwise the third arg is returned
|
|
10
|
+
|
|
11
|
+
export function withFallback<T1, T2 extends NonNullable<unknown>>(
|
|
12
|
+
value1: T1,
|
|
13
|
+
value2: T2
|
|
14
|
+
): NonNullable<T1> | T2;
|
|
15
|
+
export function withFallback<T1, T2, T3 extends NonNullable<unknown>>(
|
|
16
|
+
value1: T1,
|
|
17
|
+
value2: T2,
|
|
18
|
+
value3?: T3
|
|
19
|
+
): NonNullable<T1> | NonNullable<T2> | T3;
|
|
20
|
+
export function withFallback<T1, T2, T3 extends NonNullable<unknown>>(
|
|
21
|
+
value1: T1,
|
|
22
|
+
value2: T2,
|
|
23
|
+
value3?: T3
|
|
24
|
+
): NonNullable<T1> | NonNullable<T2> | T3 {
|
|
25
|
+
if (value3 !== undefined) {
|
|
26
|
+
// three arg mode
|
|
27
|
+
if (
|
|
28
|
+
value1 !== null &&
|
|
29
|
+
value1 !== undefined &&
|
|
30
|
+
value2 !== null &&
|
|
31
|
+
value2 !== undefined
|
|
32
|
+
) {
|
|
33
|
+
return value2;
|
|
34
|
+
} else {
|
|
35
|
+
return value3;
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
// two arg mode
|
|
39
|
+
if (value1 !== null && value1 !== undefined) {
|
|
40
|
+
return value1;
|
|
41
|
+
} else if (value2 !== undefined && value2 !== null) {
|
|
42
|
+
return value2;
|
|
43
|
+
} else {
|
|
44
|
+
throw new Error("No suitable fallback: ${arguments}");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|