@strictly/react-form 0.0.1 → 0.0.3
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/.out/core/mobx/field_adapter.d.ts +7 -6
- package/.out/core/mobx/field_adapter_builder.d.ts +12 -13
- package/.out/core/mobx/field_adapter_builder.js +8 -12
- package/.out/core/mobx/field_adapters_of_values.d.ts +4 -0
- package/.out/core/mobx/flattened_adapters_of_fields.d.ts +2 -2
- package/.out/core/mobx/flattened_list_types_of_type.d.ts +8 -0
- package/.out/core/mobx/form_fields_of_field_adapters.d.ts +8 -0
- package/.out/core/mobx/form_presenter.d.ts +21 -24
- package/.out/core/mobx/form_presenter.js +64 -69
- package/.out/core/mobx/merge_field_adapters_with_two_way_converter.d.ts +13 -0
- package/.out/core/mobx/merge_field_adapters_with_two_way_converter.js +11 -0
- package/.out/core/mobx/merge_field_adapters_with_validators.d.ts +11 -0
- package/.out/core/mobx/merge_field_adapters_with_validators.js +45 -0
- package/.out/core/mobx/specs/fixtures.d.ts +7 -0
- package/.out/core/mobx/specs/fixtures.js +20 -0
- package/.out/core/mobx/specs/flattened_adapters_of_fields.tests.js +5 -2
- package/.out/core/mobx/specs/{flattened_list_type_defs_of.tests.js → flattened_list_types_of_types.tests.js} +7 -7
- package/.out/core/mobx/specs/form_presenter.tests.js +162 -60
- package/.out/core/mobx/specs/merge_field_adapters_with_two_way_converter.js +89 -0
- package/.out/core/mobx/specs/merge_field_adapters_with_validators.tests.js +172 -0
- package/.out/core/mobx/types.d.ts +2 -2
- package/.out/field_converters/chain_field_converter.d.ts +3 -3
- package/.out/field_converters/chain_field_converter.js +17 -12
- package/.out/field_converters/identity_converter.d.ts +3 -3
- package/.out/field_converters/identity_converter.js +10 -6
- package/.out/field_converters/integer_to_string_converter.d.ts +5 -4
- package/.out/field_converters/integer_to_string_converter.js +13 -6
- package/.out/field_converters/list_converter.d.ts +2 -2
- package/.out/field_converters/list_converter.js +6 -1
- package/.out/field_converters/maybe_identity_converter.d.ts +3 -3
- package/.out/field_converters/maybe_identity_converter.js +3 -1
- package/.out/field_converters/nullable_to_boolean_converter.d.ts +9 -8
- package/.out/field_converters/nullable_to_boolean_converter.js +13 -7
- package/.out/field_converters/select_value_type_converter.d.ts +20 -15
- package/.out/field_converters/select_value_type_converter.js +29 -14
- package/.out/field_converters/specs/chain_field_converter.tests.d.ts +1 -0
- package/.out/field_converters/specs/chain_field_converter.tests.js +251 -0
- package/.out/field_converters/trimming_string_converter.d.ts +3 -3
- package/.out/field_converters/trimming_string_converter.js +7 -3
- package/.out/field_converters/validating_converter.d.ts +3 -3
- package/.out/field_converters/validating_converter.js +7 -5
- package/.out/index.d.ts +9 -2
- package/.out/index.js +9 -2
- package/.out/mantine/create_checkbox.d.ts +2 -3
- package/.out/mantine/create_checkbox.js +6 -5
- package/.out/mantine/create_pill.js +2 -2
- package/.out/mantine/create_radio.js +1 -1
- package/.out/mantine/create_radio_group.d.ts +2 -3
- package/.out/mantine/create_radio_group.js +4 -3
- package/.out/mantine/create_text_input.d.ts +2 -3
- package/.out/mantine/create_text_input.js +6 -5
- package/.out/mantine/create_value_input.d.ts +2 -3
- package/.out/mantine/create_value_input.js +6 -5
- package/.out/mantine/error_renderer.d.ts +6 -0
- package/.out/mantine/error_renderer.js +5 -0
- package/.out/mantine/hooks.d.ts +9 -13
- package/.out/mantine/hooks.js +10 -15
- package/.out/mantine/specs/checkbox_hooks.stories.d.ts +7 -2
- package/.out/mantine/specs/checkbox_hooks.stories.js +33 -6
- package/.out/mantine/specs/list_hooks.stories.js +2 -2
- package/.out/mantine/specs/radio_group_hooks.stories.d.ts +7 -2
- package/.out/mantine/specs/radio_group_hooks.stories.js +33 -6
- package/.out/mantine/specs/select_hooks.stories.d.ts +8 -2
- package/.out/mantine/specs/select_hooks.stories.js +45 -8
- package/.out/mantine/specs/text_input_hooks.stories.d.ts +5 -1
- package/.out/mantine/specs/text_input_hooks.stories.js +23 -8
- package/.out/mantine/specs/value_input_hooks.stories.d.ts +7 -2
- package/.out/mantine/specs/value_input_hooks.stories.js +49 -15
- package/.out/mantine/types.d.ts +4 -1
- package/.out/tsconfig.tsbuildinfo +1 -1
- package/.out/types/error_of_field.d.ts +2 -0
- package/.out/types/error_of_field.js +1 -0
- package/.out/types/field.d.ts +1 -1
- package/.out/types/field_converters.d.ts +17 -10
- package/.out/types/field_converters.js +5 -5
- package/.out/types/flattened_validators_of_fields.d.ts +8 -0
- package/.out/types/flattened_validators_of_fields.js +1 -0
- package/.out/types/merge_validators.d.ts +7 -0
- package/.out/types/merge_validators.js +38 -0
- package/.out/types/specs/flattened_validators_of_fields.tests.d.ts +1 -0
- package/.out/types/specs/flattened_validators_of_fields.tests.js +16 -0
- package/.out/types/specs/merge_validators.tests.d.ts +1 -0
- package/.out/types/specs/merge_validators.tests.js +192 -0
- package/.out/util/partial.d.ts +11 -5
- package/.out/util/partial.js +55 -15
- package/.turbo/turbo-build.log +9 -9
- package/.turbo/turbo-check-types.log +1 -1
- package/.turbo/turbo-release$colon$exports.log +1 -1
- package/README.md +5 -1
- package/core/mobx/field_adapter.ts +15 -7
- package/core/mobx/field_adapter_builder.ts +39 -75
- package/core/mobx/field_adapters_of_values.ts +17 -0
- package/core/mobx/flattened_adapters_of_fields.ts +3 -3
- package/core/mobx/flattened_list_types_of_type.ts +17 -0
- package/core/mobx/form_fields_of_field_adapters.ts +16 -0
- package/core/mobx/form_presenter.ts +117 -104
- package/core/mobx/merge_field_adapters_with_two_way_converter.ts +68 -0
- package/core/mobx/merge_field_adapters_with_validators.ts +99 -0
- package/core/mobx/specs/fixtures.ts +73 -0
- package/core/mobx/specs/flattened_adapters_of_fields.tests.ts +23 -2
- package/core/mobx/specs/flattened_list_types_of_types.tests.ts +35 -0
- package/core/mobx/specs/form_presenter.tests.ts +248 -124
- package/core/mobx/specs/merge_field_adapters_with_two_way_converter.ts +140 -0
- package/core/mobx/specs/merge_field_adapters_with_validators.tests.ts +259 -0
- package/core/mobx/types.ts +3 -3
- package/dist/index.cjs +527 -10412
- package/dist/index.d.cts +153 -111
- package/dist/index.d.ts +153 -111
- package/dist/index.js +527 -10420
- package/field_converters/chain_field_converter.ts +37 -23
- package/field_converters/identity_converter.ts +14 -10
- package/field_converters/integer_to_string_converter.ts +15 -9
- package/field_converters/list_converter.ts +8 -3
- package/field_converters/maybe_identity_converter.ts +7 -4
- package/field_converters/nullable_to_boolean_converter.ts +23 -16
- package/field_converters/select_value_type_converter.ts +86 -26
- package/field_converters/specs/chain_field_converter.tests.ts +302 -0
- package/field_converters/trimming_string_converter.ts +11 -6
- package/field_converters/validating_converter.ts +21 -11
- package/index.ts +9 -2
- package/mantine/create_checkbox.tsx +15 -8
- package/mantine/create_list.tsx +1 -4
- package/mantine/create_pill.tsx +2 -2
- package/mantine/create_radio.tsx +1 -1
- package/mantine/create_radio_group.tsx +8 -6
- package/mantine/create_text_input.tsx +20 -8
- package/mantine/create_value_input.tsx +17 -8
- package/mantine/error_renderer.ts +15 -0
- package/mantine/hooks.tsx +25 -51
- package/mantine/specs/__snapshots__/checkbox_hooks.tests.tsx.snap +126 -0
- package/mantine/specs/__snapshots__/radio_group_hooks.tests.tsx.snap +356 -0
- package/mantine/specs/__snapshots__/select_hooks.tests.tsx.snap +208 -12
- package/mantine/specs/__snapshots__/text_input_hooks.tests.tsx.snap +45 -0
- package/mantine/specs/__snapshots__/value_input_hooks.tests.tsx.snap +194 -8
- package/mantine/specs/checkbox_hooks.stories.tsx +47 -7
- package/mantine/specs/list_hooks.stories.tsx +2 -2
- package/mantine/specs/radio_group_hooks.stories.tsx +47 -7
- package/mantine/specs/select_hooks.stories.tsx +55 -8
- package/mantine/specs/text_input_hooks.stories.tsx +32 -7
- package/mantine/specs/value_input_hooks.stories.tsx +57 -16
- package/mantine/types.ts +5 -1
- package/package.json +20 -7
- package/tsconfig.json +1 -0
- package/types/error_of_field.ts +3 -0
- package/types/field.ts +1 -1
- package/types/field_converters.ts +21 -10
- package/types/flattened_validators_of_fields.ts +34 -0
- package/types/merge_validators.ts +80 -0
- package/types/specs/error_type_of_field.tests.ts +2 -2
- package/types/specs/flattened_validators_of_fields.tests.ts +93 -0
- package/types/specs/merge_validators.tests.ts +267 -0
- package/util/partial.tsx +200 -16
- package/.out/core/mobx/flattened_list_type_defs_of.d.ts +0 -8
- package/.out/field_validators/minimum_string_length_field_validator.d.ts +0 -2
- package/.out/field_validators/minimum_string_length_field_validator.js +0 -8
- package/.out/types/error_type_of_field.d.ts +0 -2
- package/.out/types/field_validator.d.ts +0 -3
- package/.out/types/flattened_form_fields_of.d.ts +0 -9
- package/.out/types/specs/flattened_form_fields_of.tests.js +0 -13
- package/core/mobx/flattened_list_type_defs_of.ts +0 -17
- package/core/mobx/specs/flattened_list_type_defs_of.tests.ts +0 -35
- package/field_validators/minimum_string_length_field_validator.ts +0 -13
- package/mantine/specs/__snapshots__/check_box_hooks.tests.tsx.snap +0 -227
- package/types/error_type_of_field.ts +0 -3
- package/types/field_validator.ts +0 -7
- package/types/flattened_form_fields_of.ts +0 -16
- package/types/specs/flattened_form_fields_of.tests.ts +0 -43
- /package/.out/core/mobx/{flattened_list_type_defs_of.js → field_adapters_of_values.js} +0 -0
- /package/.out/core/mobx/{specs/flattened_list_type_defs_of.tests.d.ts → flattened_list_types_of_type.js} +0 -0
- /package/.out/{types/error_type_of_field.js → core/mobx/form_fields_of_field_adapters.js} +0 -0
- /package/.out/{types/field_validator.js → core/mobx/specs/flattened_list_types_of_types.tests.d.ts} +0 -0
- /package/.out/{types/flattened_form_fields_of.js → core/mobx/specs/merge_field_adapters_with_two_way_converter.d.ts} +0 -0
- /package/.out/{types/specs/flattened_form_fields_of.tests.d.ts → core/mobx/specs/merge_field_adapters_with_validators.tests.d.ts} +0 -0
|
@@ -2,13 +2,14 @@ import {
|
|
|
2
2
|
UnreachableError,
|
|
3
3
|
} from '@strictly/base'
|
|
4
4
|
import {
|
|
5
|
-
type
|
|
6
|
-
|
|
7
|
-
type
|
|
8
|
-
|
|
5
|
+
type AnnotatedFieldConversion,
|
|
6
|
+
type AnnotatedFieldConverter,
|
|
7
|
+
type UnreliableFieldConversion,
|
|
8
|
+
UnreliableFieldConversionType,
|
|
9
|
+
type UnreliableFieldConverter,
|
|
9
10
|
} from 'types/field_converters'
|
|
10
11
|
|
|
11
|
-
export function
|
|
12
|
+
export function chainUnreliableFieldConverter<
|
|
12
13
|
From,
|
|
13
14
|
Intermediate,
|
|
14
15
|
To,
|
|
@@ -17,27 +18,27 @@ export function chainFieldConverter<
|
|
|
17
18
|
ValuePath extends string,
|
|
18
19
|
Context,
|
|
19
20
|
>(
|
|
20
|
-
from:
|
|
21
|
-
to:
|
|
22
|
-
):
|
|
23
|
-
return function (value: From, valuePath: ValuePath, context: Context):
|
|
21
|
+
from: UnreliableFieldConverter<From, Intermediate, E1, ValuePath, Context>,
|
|
22
|
+
to: UnreliableFieldConverter<Intermediate, To, E2, ValuePath, Context>,
|
|
23
|
+
): UnreliableFieldConverter<From, To, E1 | E2, ValuePath, Context> {
|
|
24
|
+
return function (value: From, valuePath: ValuePath, context: Context): UnreliableFieldConversion<To, E1 | E2> {
|
|
24
25
|
const fromConversion = from(value, valuePath, context)
|
|
25
26
|
switch (fromConversion.type) {
|
|
26
|
-
case
|
|
27
|
+
case UnreliableFieldConversionType.Success:
|
|
27
28
|
return to(fromConversion.value, valuePath, context)
|
|
28
|
-
case
|
|
29
|
+
case UnreliableFieldConversionType.Failure:
|
|
29
30
|
if (fromConversion.value != null) {
|
|
30
31
|
const toConversion = to(fromConversion.value[0], valuePath, context)
|
|
31
32
|
switch (toConversion.type) {
|
|
32
|
-
case
|
|
33
|
+
case UnreliableFieldConversionType.Success:
|
|
33
34
|
return {
|
|
34
|
-
type:
|
|
35
|
+
type: UnreliableFieldConversionType.Failure,
|
|
35
36
|
error: fromConversion.error,
|
|
36
37
|
value: [toConversion.value],
|
|
37
38
|
}
|
|
38
|
-
case
|
|
39
|
+
case UnreliableFieldConversionType.Failure:
|
|
39
40
|
return {
|
|
40
|
-
type:
|
|
41
|
+
type: UnreliableFieldConversionType.Failure,
|
|
41
42
|
error: fromConversion.error,
|
|
42
43
|
value: toConversion.value,
|
|
43
44
|
}
|
|
@@ -46,7 +47,7 @@ export function chainFieldConverter<
|
|
|
46
47
|
}
|
|
47
48
|
} else {
|
|
48
49
|
return {
|
|
49
|
-
type:
|
|
50
|
+
type: UnreliableFieldConversionType.Failure,
|
|
50
51
|
error: fromConversion.error,
|
|
51
52
|
value: null,
|
|
52
53
|
}
|
|
@@ -57,18 +58,31 @@ export function chainFieldConverter<
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
export function
|
|
61
|
+
export function chainAnnotatedFieldConverter<
|
|
61
62
|
From,
|
|
62
63
|
Intermediate,
|
|
63
64
|
To,
|
|
64
65
|
ValuePath extends string,
|
|
65
66
|
Context,
|
|
66
67
|
>(
|
|
67
|
-
from:
|
|
68
|
-
to:
|
|
69
|
-
):
|
|
70
|
-
return function (value: From, valuePath: ValuePath, context: Context):
|
|
71
|
-
const
|
|
72
|
-
|
|
68
|
+
from: AnnotatedFieldConverter<From, Intermediate, ValuePath, Context>,
|
|
69
|
+
to: AnnotatedFieldConverter<Intermediate, To, ValuePath, Context>,
|
|
70
|
+
): AnnotatedFieldConverter<From, To, ValuePath, Context> {
|
|
71
|
+
return function (value: From, valuePath: ValuePath, context: Context): AnnotatedFieldConversion {
|
|
72
|
+
const {
|
|
73
|
+
required: intermediateRequired,
|
|
74
|
+
readonly: intermediateDisabled,
|
|
75
|
+
value: intermediateValue,
|
|
76
|
+
} = from(value, valuePath, context)
|
|
77
|
+
const {
|
|
78
|
+
required: finalRequired,
|
|
79
|
+
readonly: finalDisabled,
|
|
80
|
+
value: finalValue,
|
|
81
|
+
} = to(intermediateValue, valuePath, context)
|
|
82
|
+
return {
|
|
83
|
+
value: finalValue,
|
|
84
|
+
required: intermediateRequired || finalRequired,
|
|
85
|
+
readonly: intermediateDisabled || finalDisabled,
|
|
86
|
+
}
|
|
73
87
|
}
|
|
74
88
|
}
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type
|
|
2
|
+
type AnnotatedFieldConverter,
|
|
3
|
+
UnreliableFieldConversionType,
|
|
4
|
+
type UnreliableFieldConverter,
|
|
5
5
|
} from 'types/field_converters'
|
|
6
6
|
|
|
7
|
-
export function
|
|
7
|
+
export function annotatedIdentityConverter<
|
|
8
8
|
V,
|
|
9
9
|
ValuePath extends string,
|
|
10
10
|
Context,
|
|
11
|
-
>():
|
|
11
|
+
>(required: boolean = false): AnnotatedFieldConverter<
|
|
12
12
|
V,
|
|
13
13
|
V,
|
|
14
14
|
ValuePath,
|
|
15
15
|
Context
|
|
16
16
|
> {
|
|
17
|
-
return function (
|
|
18
|
-
return
|
|
17
|
+
return function (value: V) {
|
|
18
|
+
return {
|
|
19
|
+
value,
|
|
20
|
+
required,
|
|
21
|
+
readonly: false,
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
export function
|
|
26
|
+
export function unreliableIdentityConverter<
|
|
23
27
|
V,
|
|
24
28
|
ValuePath extends string,
|
|
25
29
|
Context,
|
|
26
|
-
>():
|
|
30
|
+
>(): UnreliableFieldConverter<
|
|
27
31
|
V,
|
|
28
32
|
V,
|
|
29
33
|
never,
|
|
@@ -32,7 +36,7 @@ export function identityConverter<
|
|
|
32
36
|
> {
|
|
33
37
|
return function (value: V) {
|
|
34
38
|
return {
|
|
35
|
-
type:
|
|
39
|
+
type: UnreliableFieldConversionType.Success,
|
|
36
40
|
value,
|
|
37
41
|
}
|
|
38
42
|
}
|
|
@@ -1,30 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type
|
|
3
|
-
FieldConversionResult,
|
|
2
|
+
type AnnotatedFieldConversion,
|
|
4
3
|
type TwoWayFieldConverter,
|
|
4
|
+
type UnreliableFieldConversion,
|
|
5
|
+
UnreliableFieldConversionType,
|
|
5
6
|
} from 'types/field_converters'
|
|
6
7
|
|
|
7
8
|
export class IntegerToStringConverter<E, ValuePath extends string, Context>
|
|
8
9
|
implements TwoWayFieldConverter<number, string, E, ValuePath, Context>
|
|
9
10
|
{
|
|
10
|
-
constructor(private readonly isNanError: E) {
|
|
11
|
+
constructor(private readonly isNanError: E, private readonly base = 10) {
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
convert(from: number): string {
|
|
14
|
-
|
|
14
|
+
convert(from: number): AnnotatedFieldConversion<string> {
|
|
15
|
+
const value = Math.floor(from).toString()
|
|
16
|
+
return {
|
|
17
|
+
value,
|
|
18
|
+
required: false,
|
|
19
|
+
readonly: false,
|
|
20
|
+
}
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
revert(from: string):
|
|
18
|
-
const value = parseInt(from,
|
|
23
|
+
revert(from: string): UnreliableFieldConversion<number, E> {
|
|
24
|
+
const value = parseInt(from, this.base)
|
|
19
25
|
if (Number.isNaN(value)) {
|
|
20
26
|
return {
|
|
21
|
-
type:
|
|
27
|
+
type: UnreliableFieldConversionType.Failure,
|
|
22
28
|
error: this.isNanError,
|
|
23
29
|
value: null,
|
|
24
30
|
}
|
|
25
31
|
} else {
|
|
26
32
|
return {
|
|
27
|
-
type:
|
|
33
|
+
type: UnreliableFieldConversionType.Success,
|
|
28
34
|
value,
|
|
29
35
|
}
|
|
30
36
|
}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type AnnotatedFieldConverter } from 'types/field_converters'
|
|
2
2
|
|
|
3
3
|
export function listConverter<
|
|
4
4
|
E,
|
|
5
5
|
K extends string,
|
|
6
6
|
ValuePath extends string,
|
|
7
7
|
Context,
|
|
8
|
-
>():
|
|
8
|
+
>(): AnnotatedFieldConverter<readonly E[], K[], ValuePath, Context> {
|
|
9
9
|
return function (from: readonly E[], valuePath: ValuePath) {
|
|
10
|
-
|
|
10
|
+
const value = from.map(function (_v, i) {
|
|
11
11
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
12
12
|
return `${valuePath as string}.${i}` as K
|
|
13
13
|
})
|
|
14
|
+
return {
|
|
15
|
+
value,
|
|
16
|
+
required: false,
|
|
17
|
+
readonly: false,
|
|
18
|
+
}
|
|
14
19
|
}
|
|
15
20
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type
|
|
2
|
+
type AnnotatedFieldConversion,
|
|
3
3
|
type TwoWayFieldConverter,
|
|
4
|
+
type UnreliableFieldConversion,
|
|
4
5
|
} from 'types/field_converters'
|
|
5
6
|
|
|
6
7
|
export class MaybeIdentityConverter<From, To, E, ValuePath extends string, Context>
|
|
@@ -12,12 +13,14 @@ export class MaybeIdentityConverter<From, To, E, ValuePath extends string, Conte
|
|
|
12
13
|
) {
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
convert(from: From, valuePath: ValuePath, context: Context): To | From {
|
|
16
|
+
convert(from: From, valuePath: ValuePath, context: Context): AnnotatedFieldConversion<To | From> {
|
|
16
17
|
return this.converter.convert(from, valuePath, context)
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
revert(from: To | From, valuePath: ValuePath, context: Context):
|
|
20
|
-
const value = this.isFrom(from)
|
|
20
|
+
revert(from: To | From, valuePath: ValuePath, context: Context): UnreliableFieldConversion<From, E> {
|
|
21
|
+
const value = this.isFrom(from)
|
|
22
|
+
? this.converter.convert(from, valuePath, context).value
|
|
23
|
+
: from
|
|
21
24
|
return this.converter.revert(value, valuePath, context)
|
|
22
25
|
}
|
|
23
26
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
copy,
|
|
3
|
-
type
|
|
3
|
+
type ReadonlyTypeOfType,
|
|
4
4
|
type Type,
|
|
5
|
-
type
|
|
5
|
+
type ValueOfType,
|
|
6
6
|
} from '@strictly/define'
|
|
7
7
|
import {
|
|
8
|
-
type
|
|
9
|
-
FieldConversionResult,
|
|
8
|
+
type AnnotatedFieldConversion,
|
|
10
9
|
type TwoWayFieldConverterWithValueFactory,
|
|
10
|
+
type UnreliableFieldConversion,
|
|
11
|
+
UnreliableFieldConversionType,
|
|
11
12
|
} from 'types/field_converters'
|
|
12
13
|
|
|
13
14
|
export class NullableToBooleanConverter<
|
|
@@ -15,42 +16,48 @@ export class NullableToBooleanConverter<
|
|
|
15
16
|
E,
|
|
16
17
|
ValuePath extends string,
|
|
17
18
|
Context,
|
|
19
|
+
NullType extends null | undefined,
|
|
18
20
|
> implements TwoWayFieldConverterWithValueFactory<
|
|
19
|
-
|
|
21
|
+
ValueOfType<ReadonlyTypeOfType<T>> | NullType,
|
|
20
22
|
boolean,
|
|
21
23
|
E,
|
|
22
24
|
ValuePath,
|
|
23
25
|
Context
|
|
24
26
|
> {
|
|
25
|
-
readonly defaultValue:
|
|
27
|
+
readonly defaultValue: ValueOfType<ReadonlyTypeOfType<T>> | NullType
|
|
26
28
|
|
|
27
29
|
constructor(
|
|
28
30
|
private readonly typeDef: T,
|
|
29
|
-
private readonly prototype:
|
|
31
|
+
private readonly prototype: ValueOfType<ReadonlyTypeOfType<T>>,
|
|
32
|
+
private readonly nullType: NullType,
|
|
30
33
|
defaultToNull = true,
|
|
31
34
|
) {
|
|
32
|
-
this.defaultValue = defaultToNull ?
|
|
35
|
+
this.defaultValue = defaultToNull ? this.nullType : prototype
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
convert(from:
|
|
36
|
-
return
|
|
38
|
+
convert(from: ValueOfType<ReadonlyTypeOfType<T>> | NullType): AnnotatedFieldConversion<boolean> {
|
|
39
|
+
return {
|
|
40
|
+
value: from !== this.nullType,
|
|
41
|
+
required: false,
|
|
42
|
+
readonly: false,
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
45
|
|
|
39
|
-
revert(from: boolean):
|
|
46
|
+
revert(from: boolean): UnreliableFieldConversion<ValueOfType<ReadonlyTypeOfType<T>> | NullType, E> {
|
|
40
47
|
if (from) {
|
|
41
|
-
const value:
|
|
48
|
+
const value: ValueOfType<T> = copy(this.typeDef, this.prototype)
|
|
42
49
|
return {
|
|
43
|
-
type:
|
|
50
|
+
type: UnreliableFieldConversionType.Success,
|
|
44
51
|
value,
|
|
45
52
|
}
|
|
46
53
|
}
|
|
47
54
|
return {
|
|
48
|
-
type:
|
|
49
|
-
value:
|
|
55
|
+
type: UnreliableFieldConversionType.Success,
|
|
56
|
+
value: this.nullType,
|
|
50
57
|
}
|
|
51
58
|
}
|
|
52
59
|
|
|
53
|
-
create():
|
|
60
|
+
create(): ValueOfType<ReadonlyTypeOfType<T>> | NullType {
|
|
54
61
|
return this.defaultValue
|
|
55
62
|
}
|
|
56
63
|
}
|
|
@@ -1,31 +1,35 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type ExhaustiveArrayOfUnion,
|
|
2
3
|
reverse,
|
|
3
4
|
type StringKeyOf,
|
|
4
5
|
} from '@strictly/base'
|
|
5
6
|
import {
|
|
6
7
|
copy,
|
|
7
8
|
type LiteralTypeDef,
|
|
9
|
+
type ReadonlyTypeOfType,
|
|
8
10
|
type Type,
|
|
9
11
|
type UnionTypeDef,
|
|
10
|
-
type
|
|
12
|
+
type ValueOfType,
|
|
11
13
|
type ValueTypesOfDiscriminatedUnion,
|
|
12
14
|
} from '@strictly/define'
|
|
13
15
|
import {
|
|
14
|
-
type
|
|
15
|
-
FieldConversionResult,
|
|
16
|
+
type AnnotatedFieldConversion,
|
|
16
17
|
type TwoWayFieldConverterWithValueFactory,
|
|
18
|
+
type UnreliableFieldConversion,
|
|
19
|
+
UnreliableFieldConversionType,
|
|
17
20
|
} from 'types/field_converters'
|
|
18
21
|
|
|
19
22
|
export abstract class AbstractSelectValueTypeConverter<
|
|
20
23
|
T extends Type,
|
|
24
|
+
From extends ValueOfType<T> | undefined,
|
|
21
25
|
To extends string | null,
|
|
22
|
-
Values extends Readonly<Record<NonNullable<To>,
|
|
26
|
+
Values extends Readonly<Record<NonNullable<To>, From>>,
|
|
23
27
|
NoSuchValueError,
|
|
24
28
|
ValuePath extends string,
|
|
25
29
|
Context,
|
|
26
30
|
> implements TwoWayFieldConverterWithValueFactory<
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
From,
|
|
32
|
+
To,
|
|
29
33
|
NoSuchValueError,
|
|
30
34
|
ValuePath,
|
|
31
35
|
Context
|
|
@@ -33,50 +37,56 @@ export abstract class AbstractSelectValueTypeConverter<
|
|
|
33
37
|
constructor(
|
|
34
38
|
protected readonly typeDef: T,
|
|
35
39
|
protected readonly values: Values,
|
|
36
|
-
private readonly defaultValueKey: keyof Values | null,
|
|
40
|
+
private readonly defaultValueKey: keyof Values | null | undefined,
|
|
37
41
|
private readonly noSuchValueError: NoSuchValueError | null,
|
|
42
|
+
private readonly required: boolean,
|
|
38
43
|
) {
|
|
39
44
|
}
|
|
40
45
|
|
|
41
|
-
revert(from:
|
|
42
|
-
const prototype:
|
|
46
|
+
revert(from: To): UnreliableFieldConversion<From, NoSuchValueError> {
|
|
47
|
+
const prototype: From = from == null ? null! : this.values[from]
|
|
43
48
|
if (prototype == null && this.noSuchValueError != null) {
|
|
44
49
|
return {
|
|
45
|
-
type:
|
|
50
|
+
type: UnreliableFieldConversionType.Failure,
|
|
46
51
|
error: this.noSuchValueError,
|
|
47
52
|
value: null,
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
|
-
const value = prototype == null ?
|
|
55
|
+
const value = prototype == null ? prototype : copy(this.typeDef, prototype)
|
|
51
56
|
// TODO given we are dealing with strings, maybe we should have a check to make sure value is in the record
|
|
52
57
|
// of values?
|
|
53
58
|
return {
|
|
54
|
-
type:
|
|
59
|
+
type: UnreliableFieldConversionType.Success,
|
|
55
60
|
value: value!,
|
|
56
61
|
}
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
convert(from:
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
convert(from: From): AnnotatedFieldConversion<To> {
|
|
65
|
+
const value = from == null ? from! : this.doConvert(from)
|
|
66
|
+
return {
|
|
67
|
+
value,
|
|
68
|
+
required: this.required,
|
|
69
|
+
readonly: false,
|
|
62
70
|
}
|
|
63
|
-
return this.doConvert(from)
|
|
64
71
|
}
|
|
65
72
|
|
|
66
|
-
protected abstract doConvert(from:
|
|
73
|
+
protected abstract doConvert(from: NonNullable<ValueOfType<T>>): To
|
|
67
74
|
|
|
68
|
-
create():
|
|
75
|
+
create(): From {
|
|
69
76
|
return this.defaultValueKey != null ? this.values[this.defaultValueKey] : null!
|
|
70
77
|
}
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
export class SelectDiscriminatedUnionConverter<
|
|
74
81
|
U extends UnionTypeDef,
|
|
82
|
+
From extends ValueOfType<ReadonlyTypeOfType<Type<U>>> | (Required extends true ? never : undefined),
|
|
75
83
|
To extends StringKeyOf<U['unions']> | null,
|
|
76
84
|
ValuePath extends string,
|
|
77
85
|
Context,
|
|
86
|
+
Required extends boolean,
|
|
78
87
|
> extends AbstractSelectValueTypeConverter<
|
|
79
88
|
Type<U>,
|
|
89
|
+
From,
|
|
80
90
|
To,
|
|
81
91
|
ValueTypesOfDiscriminatedUnion<U>,
|
|
82
92
|
never,
|
|
@@ -84,19 +94,21 @@ export class SelectDiscriminatedUnionConverter<
|
|
|
84
94
|
Context
|
|
85
95
|
> {
|
|
86
96
|
constructor(
|
|
87
|
-
|
|
97
|
+
type: Type<U>,
|
|
88
98
|
values: ValueTypesOfDiscriminatedUnion<U>,
|
|
89
99
|
defaultValueKey: keyof U['unions'],
|
|
100
|
+
required: Required,
|
|
90
101
|
) {
|
|
91
102
|
super(
|
|
92
|
-
|
|
103
|
+
type,
|
|
93
104
|
values,
|
|
94
105
|
defaultValueKey,
|
|
95
106
|
null,
|
|
107
|
+
required,
|
|
96
108
|
)
|
|
97
109
|
}
|
|
98
110
|
|
|
99
|
-
protected override doConvert(from:
|
|
111
|
+
protected override doConvert(from: NonNullable<ValueOfType<Type<U>>>) {
|
|
100
112
|
const {
|
|
101
113
|
definition: {
|
|
102
114
|
discriminator,
|
|
@@ -108,15 +120,18 @@ export class SelectDiscriminatedUnionConverter<
|
|
|
108
120
|
|
|
109
121
|
export class SelectLiteralConverter<
|
|
110
122
|
L extends string | number | null,
|
|
123
|
+
From extends L | (Required extends true ? never : undefined),
|
|
111
124
|
To extends string | null,
|
|
112
|
-
Values extends Record<NonNullable<
|
|
125
|
+
Values extends Record<NonNullable<From>, NonNullable<To>>,
|
|
113
126
|
NoSuchValueError,
|
|
114
127
|
ValuePath extends string,
|
|
115
128
|
Context,
|
|
129
|
+
Required extends boolean,
|
|
116
130
|
> extends AbstractSelectValueTypeConverter<
|
|
117
131
|
Type<LiteralTypeDef<L>>,
|
|
132
|
+
From,
|
|
118
133
|
To,
|
|
119
|
-
Record<NonNullable<To>,
|
|
134
|
+
Record<NonNullable<To>, NonNullable<From>>,
|
|
120
135
|
NoSuchValueError,
|
|
121
136
|
ValuePath,
|
|
122
137
|
Context
|
|
@@ -124,18 +139,63 @@ export class SelectLiteralConverter<
|
|
|
124
139
|
constructor(
|
|
125
140
|
typeDef: Type<LiteralTypeDef<L>>,
|
|
126
141
|
private readonly valuesToStrings: Values,
|
|
127
|
-
defaultValue:
|
|
142
|
+
defaultValue: From,
|
|
128
143
|
noSuchValueError: NoSuchValueError | null,
|
|
144
|
+
required: Required,
|
|
129
145
|
) {
|
|
130
146
|
super(
|
|
131
147
|
typeDef,
|
|
132
148
|
reverse(valuesToStrings),
|
|
133
149
|
defaultValue && valuesToStrings[defaultValue],
|
|
134
150
|
noSuchValueError,
|
|
151
|
+
required,
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
protected override doConvert(from: NonNullable<From>) {
|
|
156
|
+
return this.valuesToStrings[from]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export class SelectStringConverter<
|
|
161
|
+
L extends string | null,
|
|
162
|
+
From extends L | undefined,
|
|
163
|
+
A extends readonly NonNullable<From>[],
|
|
164
|
+
NoSuchValueError,
|
|
165
|
+
ValuePath extends string,
|
|
166
|
+
Context,
|
|
167
|
+
> extends AbstractSelectValueTypeConverter<
|
|
168
|
+
Type<LiteralTypeDef<L>>,
|
|
169
|
+
From,
|
|
170
|
+
string | null,
|
|
171
|
+
Record<string, From>,
|
|
172
|
+
NoSuchValueError,
|
|
173
|
+
ValuePath,
|
|
174
|
+
Context
|
|
175
|
+
> {
|
|
176
|
+
constructor(
|
|
177
|
+
typeDef: Type<LiteralTypeDef<L>>,
|
|
178
|
+
allowedValues: ExhaustiveArrayOfUnion<NonNullable<From>, A>,
|
|
179
|
+
defaultValue: L | undefined,
|
|
180
|
+
noSuchValueError: NoSuchValueError | null,
|
|
181
|
+
required = false,
|
|
182
|
+
) {
|
|
183
|
+
super(
|
|
184
|
+
typeDef,
|
|
185
|
+
allowedValues.reduce<Record<string, From>>(
|
|
186
|
+
function (acc, value) {
|
|
187
|
+
acc[value] = value
|
|
188
|
+
return acc
|
|
189
|
+
},
|
|
190
|
+
{},
|
|
191
|
+
),
|
|
192
|
+
defaultValue,
|
|
193
|
+
noSuchValueError,
|
|
194
|
+
required,
|
|
135
195
|
)
|
|
136
196
|
}
|
|
137
197
|
|
|
138
|
-
protected override doConvert(from: L) {
|
|
139
|
-
return from
|
|
198
|
+
protected override doConvert(from: NonNullable<L>) {
|
|
199
|
+
return from
|
|
140
200
|
}
|
|
141
201
|
}
|