@strictly/react-form 0.0.1 → 0.0.2

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.
Files changed (173) hide show
  1. package/.out/core/mobx/field_adapter.d.ts +7 -6
  2. package/.out/core/mobx/field_adapter_builder.d.ts +12 -13
  3. package/.out/core/mobx/field_adapter_builder.js +8 -12
  4. package/.out/core/mobx/field_adapters_of_values.d.ts +4 -0
  5. package/.out/core/mobx/flattened_adapters_of_fields.d.ts +2 -2
  6. package/.out/core/mobx/flattened_list_types_of_type.d.ts +8 -0
  7. package/.out/core/mobx/form_fields_of_field_adapters.d.ts +8 -0
  8. package/.out/core/mobx/form_presenter.d.ts +21 -24
  9. package/.out/core/mobx/form_presenter.js +64 -69
  10. package/.out/core/mobx/merge_field_adapters_with_two_way_converter.d.ts +13 -0
  11. package/.out/core/mobx/merge_field_adapters_with_two_way_converter.js +11 -0
  12. package/.out/core/mobx/merge_field_adapters_with_validators.d.ts +11 -0
  13. package/.out/core/mobx/merge_field_adapters_with_validators.js +45 -0
  14. package/.out/core/mobx/specs/fixtures.d.ts +7 -0
  15. package/.out/core/mobx/specs/fixtures.js +20 -0
  16. package/.out/core/mobx/specs/flattened_adapters_of_fields.tests.js +5 -2
  17. package/.out/core/mobx/specs/{flattened_list_type_defs_of.tests.js → flattened_list_types_of_types.tests.js} +7 -7
  18. package/.out/core/mobx/specs/form_presenter.tests.js +162 -60
  19. package/.out/core/mobx/specs/merge_field_adapters_with_two_way_converter.js +89 -0
  20. package/.out/core/mobx/specs/merge_field_adapters_with_validators.tests.js +172 -0
  21. package/.out/core/mobx/types.d.ts +2 -2
  22. package/.out/field_converters/chain_field_converter.d.ts +3 -3
  23. package/.out/field_converters/chain_field_converter.js +17 -12
  24. package/.out/field_converters/identity_converter.d.ts +3 -3
  25. package/.out/field_converters/identity_converter.js +10 -6
  26. package/.out/field_converters/integer_to_string_converter.d.ts +5 -4
  27. package/.out/field_converters/integer_to_string_converter.js +13 -6
  28. package/.out/field_converters/list_converter.d.ts +2 -2
  29. package/.out/field_converters/list_converter.js +6 -1
  30. package/.out/field_converters/maybe_identity_converter.d.ts +3 -3
  31. package/.out/field_converters/maybe_identity_converter.js +3 -1
  32. package/.out/field_converters/nullable_to_boolean_converter.d.ts +9 -8
  33. package/.out/field_converters/nullable_to_boolean_converter.js +13 -7
  34. package/.out/field_converters/select_value_type_converter.d.ts +20 -15
  35. package/.out/field_converters/select_value_type_converter.js +29 -14
  36. package/.out/field_converters/specs/chain_field_converter.tests.d.ts +1 -0
  37. package/.out/field_converters/specs/chain_field_converter.tests.js +251 -0
  38. package/.out/field_converters/trimming_string_converter.d.ts +3 -3
  39. package/.out/field_converters/trimming_string_converter.js +7 -3
  40. package/.out/field_converters/validating_converter.d.ts +3 -3
  41. package/.out/field_converters/validating_converter.js +7 -5
  42. package/.out/index.d.ts +9 -2
  43. package/.out/index.js +9 -2
  44. package/.out/mantine/create_checkbox.d.ts +2 -3
  45. package/.out/mantine/create_checkbox.js +6 -5
  46. package/.out/mantine/create_pill.js +2 -2
  47. package/.out/mantine/create_radio.js +1 -1
  48. package/.out/mantine/create_radio_group.d.ts +2 -3
  49. package/.out/mantine/create_radio_group.js +4 -3
  50. package/.out/mantine/create_text_input.d.ts +2 -3
  51. package/.out/mantine/create_text_input.js +6 -5
  52. package/.out/mantine/create_value_input.d.ts +2 -3
  53. package/.out/mantine/create_value_input.js +6 -5
  54. package/.out/mantine/error_renderer.d.ts +6 -0
  55. package/.out/mantine/error_renderer.js +5 -0
  56. package/.out/mantine/hooks.d.ts +9 -13
  57. package/.out/mantine/hooks.js +10 -15
  58. package/.out/mantine/specs/checkbox_hooks.stories.d.ts +7 -2
  59. package/.out/mantine/specs/checkbox_hooks.stories.js +33 -6
  60. package/.out/mantine/specs/list_hooks.stories.js +2 -2
  61. package/.out/mantine/specs/radio_group_hooks.stories.d.ts +7 -2
  62. package/.out/mantine/specs/radio_group_hooks.stories.js +33 -6
  63. package/.out/mantine/specs/select_hooks.stories.d.ts +8 -2
  64. package/.out/mantine/specs/select_hooks.stories.js +45 -8
  65. package/.out/mantine/specs/text_input_hooks.stories.d.ts +5 -1
  66. package/.out/mantine/specs/text_input_hooks.stories.js +23 -8
  67. package/.out/mantine/specs/value_input_hooks.stories.d.ts +7 -2
  68. package/.out/mantine/specs/value_input_hooks.stories.js +49 -15
  69. package/.out/mantine/types.d.ts +4 -1
  70. package/.out/tsconfig.tsbuildinfo +1 -1
  71. package/.out/types/error_of_field.d.ts +2 -0
  72. package/.out/types/error_of_field.js +1 -0
  73. package/.out/types/field.d.ts +1 -1
  74. package/.out/types/field_converters.d.ts +17 -10
  75. package/.out/types/field_converters.js +5 -5
  76. package/.out/types/flattened_validators_of_fields.d.ts +8 -0
  77. package/.out/types/flattened_validators_of_fields.js +1 -0
  78. package/.out/types/merge_validators.d.ts +7 -0
  79. package/.out/types/merge_validators.js +38 -0
  80. package/.out/types/specs/flattened_validators_of_fields.tests.d.ts +1 -0
  81. package/.out/types/specs/flattened_validators_of_fields.tests.js +16 -0
  82. package/.out/types/specs/merge_validators.tests.d.ts +1 -0
  83. package/.out/types/specs/merge_validators.tests.js +192 -0
  84. package/.out/util/partial.d.ts +11 -5
  85. package/.out/util/partial.js +55 -15
  86. package/.turbo/turbo-build.log +9 -9
  87. package/.turbo/turbo-check-types.log +1 -1
  88. package/.turbo/turbo-release$colon$exports.log +1 -1
  89. package/README.md +5 -1
  90. package/core/mobx/field_adapter.ts +15 -7
  91. package/core/mobx/field_adapter_builder.ts +39 -75
  92. package/core/mobx/field_adapters_of_values.ts +17 -0
  93. package/core/mobx/flattened_adapters_of_fields.ts +3 -3
  94. package/core/mobx/flattened_list_types_of_type.ts +17 -0
  95. package/core/mobx/form_fields_of_field_adapters.ts +16 -0
  96. package/core/mobx/form_presenter.ts +117 -104
  97. package/core/mobx/merge_field_adapters_with_two_way_converter.ts +68 -0
  98. package/core/mobx/merge_field_adapters_with_validators.ts +99 -0
  99. package/core/mobx/specs/fixtures.ts +73 -0
  100. package/core/mobx/specs/flattened_adapters_of_fields.tests.ts +23 -2
  101. package/core/mobx/specs/flattened_list_types_of_types.tests.ts +35 -0
  102. package/core/mobx/specs/form_presenter.tests.ts +248 -124
  103. package/core/mobx/specs/merge_field_adapters_with_two_way_converter.ts +140 -0
  104. package/core/mobx/specs/merge_field_adapters_with_validators.tests.ts +259 -0
  105. package/core/mobx/types.ts +3 -3
  106. package/dist/index.cjs +459 -211
  107. package/dist/index.d.cts +153 -111
  108. package/dist/index.d.ts +153 -111
  109. package/dist/index.js +453 -200
  110. package/field_converters/chain_field_converter.ts +37 -23
  111. package/field_converters/identity_converter.ts +14 -10
  112. package/field_converters/integer_to_string_converter.ts +15 -9
  113. package/field_converters/list_converter.ts +8 -3
  114. package/field_converters/maybe_identity_converter.ts +7 -4
  115. package/field_converters/nullable_to_boolean_converter.ts +23 -16
  116. package/field_converters/select_value_type_converter.ts +86 -26
  117. package/field_converters/specs/chain_field_converter.tests.ts +302 -0
  118. package/field_converters/trimming_string_converter.ts +11 -6
  119. package/field_converters/validating_converter.ts +21 -11
  120. package/index.ts +9 -2
  121. package/mantine/create_checkbox.tsx +15 -8
  122. package/mantine/create_list.tsx +1 -4
  123. package/mantine/create_pill.tsx +2 -2
  124. package/mantine/create_radio.tsx +1 -1
  125. package/mantine/create_radio_group.tsx +8 -6
  126. package/mantine/create_text_input.tsx +20 -8
  127. package/mantine/create_value_input.tsx +17 -8
  128. package/mantine/error_renderer.ts +15 -0
  129. package/mantine/hooks.tsx +25 -51
  130. package/mantine/specs/__snapshots__/checkbox_hooks.tests.tsx.snap +126 -0
  131. package/mantine/specs/__snapshots__/radio_group_hooks.tests.tsx.snap +356 -0
  132. package/mantine/specs/__snapshots__/select_hooks.tests.tsx.snap +208 -12
  133. package/mantine/specs/__snapshots__/text_input_hooks.tests.tsx.snap +45 -0
  134. package/mantine/specs/__snapshots__/value_input_hooks.tests.tsx.snap +194 -8
  135. package/mantine/specs/checkbox_hooks.stories.tsx +47 -7
  136. package/mantine/specs/list_hooks.stories.tsx +2 -2
  137. package/mantine/specs/radio_group_hooks.stories.tsx +47 -7
  138. package/mantine/specs/select_hooks.stories.tsx +55 -8
  139. package/mantine/specs/text_input_hooks.stories.tsx +32 -7
  140. package/mantine/specs/value_input_hooks.stories.tsx +57 -16
  141. package/mantine/types.ts +5 -1
  142. package/package.json +16 -4
  143. package/tsconfig.json +1 -0
  144. package/types/error_of_field.ts +3 -0
  145. package/types/field.ts +1 -1
  146. package/types/field_converters.ts +21 -10
  147. package/types/flattened_validators_of_fields.ts +34 -0
  148. package/types/merge_validators.ts +80 -0
  149. package/types/specs/error_type_of_field.tests.ts +2 -2
  150. package/types/specs/flattened_validators_of_fields.tests.ts +93 -0
  151. package/types/specs/merge_validators.tests.ts +267 -0
  152. package/util/partial.tsx +200 -16
  153. package/.out/core/mobx/flattened_list_type_defs_of.d.ts +0 -8
  154. package/.out/field_validators/minimum_string_length_field_validator.d.ts +0 -2
  155. package/.out/field_validators/minimum_string_length_field_validator.js +0 -8
  156. package/.out/types/error_type_of_field.d.ts +0 -2
  157. package/.out/types/field_validator.d.ts +0 -3
  158. package/.out/types/flattened_form_fields_of.d.ts +0 -9
  159. package/.out/types/specs/flattened_form_fields_of.tests.js +0 -13
  160. package/core/mobx/flattened_list_type_defs_of.ts +0 -17
  161. package/core/mobx/specs/flattened_list_type_defs_of.tests.ts +0 -35
  162. package/field_validators/minimum_string_length_field_validator.ts +0 -13
  163. package/mantine/specs/__snapshots__/check_box_hooks.tests.tsx.snap +0 -227
  164. package/types/error_type_of_field.ts +0 -3
  165. package/types/field_validator.ts +0 -7
  166. package/types/flattened_form_fields_of.ts +0 -16
  167. package/types/specs/flattened_form_fields_of.tests.ts +0 -43
  168. /package/.out/core/mobx/{flattened_list_type_defs_of.js → field_adapters_of_values.js} +0 -0
  169. /package/.out/core/mobx/{specs/flattened_list_type_defs_of.tests.d.ts → flattened_list_types_of_type.js} +0 -0
  170. /package/.out/{types/error_type_of_field.js → core/mobx/form_fields_of_field_adapters.js} +0 -0
  171. /package/.out/{types/field_validator.js → core/mobx/specs/flattened_list_types_of_types.tests.d.ts} +0 -0
  172. /package/.out/{types/flattened_form_fields_of.js → core/mobx/specs/merge_field_adapters_with_two_way_converter.d.ts} +0 -0
  173. /package/.out/{types/specs/flattened_form_fields_of.tests.d.ts → core/mobx/specs/merge_field_adapters_with_validators.tests.d.ts} +0 -0
@@ -0,0 +1,140 @@
1
+ import { type FieldAdapter } from 'core/mobx/field_adapter'
2
+ import { identityAdapter } from 'core/mobx/field_adapter_builder'
3
+ import {
4
+ type MergedOfFieldAdaptersWithTwoWayConverter,
5
+ mergeFieldAdaptersWithTwoWayConverter,
6
+ } from 'core/mobx/merge_field_adapters_with_two_way_converter'
7
+ import {
8
+ annotatedIdentityConverter,
9
+ unreliableIdentityConverter,
10
+ } from 'field_converters/identity_converter'
11
+ import {
12
+ type TwoWayFieldConverter,
13
+ UnreliableFieldConversionType,
14
+ } from 'types/field_converters'
15
+ import {
16
+ createMockedAdapter,
17
+ createMockTwoWayFieldConverter,
18
+ resetMockAdapter,
19
+ resetMockTwoWayFieldConverter,
20
+ } from './fixtures'
21
+
22
+ const error1 = Symbol()
23
+ const error2 = Symbol()
24
+ const error3 = Symbol()
25
+ const error4 = Symbol()
26
+ const context = Symbol()
27
+
28
+ describe('MergedOfFieldAdapterWithTwoWayConverter', function () {
29
+ type T = {
30
+ readonly x: FieldAdapter<boolean, string, typeof error1, 'x', typeof context>,
31
+ readonly y: FieldAdapter<number, boolean, typeof error2, 'y', typeof context>,
32
+ readonly z: FieldAdapter<string, number, typeof error3, 'z', typeof context>,
33
+ }
34
+ type M = MergedOfFieldAdaptersWithTwoWayConverter<T, typeof error4, typeof context>
35
+
36
+ let m: {
37
+ readonly x: FieldAdapter<boolean, string, typeof error1 | typeof error4, 'x', typeof context>,
38
+ readonly y: FieldAdapter<number, boolean, typeof error2 | typeof error4, 'y', typeof context>,
39
+ readonly z: FieldAdapter<string, number, typeof error3 | typeof error4, 'z', typeof context>,
40
+ }
41
+
42
+ it('merges the errors', function () {
43
+ expectTypeOf<M>().toEqualTypeOf(m)
44
+ })
45
+ })
46
+
47
+ const originalIntegerAdapter = identityAdapter(0)
48
+ const originalBooleanAdapter = identityAdapter(false, true)
49
+
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ const originalConverter: TwoWayFieldConverter<any, any, typeof error4, string, typeof context> = {
52
+ convert: annotatedIdentityConverter(),
53
+ revert: unreliableIdentityConverter(),
54
+ }
55
+
56
+ describe('mergeFieldAdaptersWithTwoWayConverter', function () {
57
+ const integerAdapter = createMockedAdapter(
58
+ originalIntegerAdapter,
59
+ )
60
+ const booleanAdapter = createMockedAdapter(
61
+ originalBooleanAdapter,
62
+ )
63
+
64
+ beforeEach(function () {
65
+ resetMockAdapter(originalIntegerAdapter, integerAdapter)
66
+ resetMockAdapter(originalBooleanAdapter, booleanAdapter)
67
+ })
68
+
69
+ describe('two entries', function () {
70
+ const fieldAdapters = {
71
+ integerAdapter,
72
+ booleanAdapter,
73
+ }
74
+
75
+ const converter = createMockTwoWayFieldConverter(originalConverter)
76
+
77
+ beforeEach(function () {
78
+ resetMockTwoWayFieldConverter(originalConverter, converter)
79
+ })
80
+
81
+ const merged = mergeFieldAdaptersWithTwoWayConverter(fieldAdapters, converter)
82
+
83
+ describe('convert', function () {
84
+ let result: ReturnType<typeof merged.booleanAdapter.convert>
85
+
86
+ describe('success', function () {
87
+ // note don't really need to exercise this too extensively since most of
88
+ // the work is done in chainXFieldAdapter
89
+ beforeEach(function () {
90
+ result = merged.booleanAdapter.convert(true, 'booleanAdapter', context)
91
+ })
92
+
93
+ it('returns the same value on convert', function () {
94
+ expect(result).toEqual(expect.objectContaining({
95
+ value: true,
96
+ }))
97
+ })
98
+
99
+ it('calls the mocked converter', function () {
100
+ expect(converter.convert).toHaveBeenCalledOnce()
101
+ expect(converter.convert).toHaveBeenCalledWith(true, 'booleanAdapter', context)
102
+ })
103
+
104
+ it('calls the mocked adapter', function () {
105
+ expect(booleanAdapter.convert).toHaveBeenCalledOnce()
106
+ expect(booleanAdapter.convert).toHaveBeenCalledWith(true, 'booleanAdapter', context)
107
+ })
108
+ })
109
+ })
110
+
111
+ describe('revert', function () {
112
+ let result: ReturnType<NonNullable<typeof merged.booleanAdapter.revert>>
113
+
114
+ describe('success', function () {
115
+ // note don't really need to exercise this too extensively since most of
116
+ // the work is done in chainXFieldAdapter
117
+ beforeEach(function () {
118
+ result = merged.booleanAdapter.revert!(true, 'booleanAdapter', context)
119
+ })
120
+ })
121
+
122
+ it('returns the same value on revert', function () {
123
+ expect(result).toEqual(expect.objectContaining({
124
+ value: true,
125
+ type: UnreliableFieldConversionType.Success,
126
+ }))
127
+ })
128
+
129
+ it('calls the mocked converter', function () {
130
+ expect(converter.revert).toHaveBeenCalledOnce()
131
+ expect(converter.revert).toHaveBeenCalledWith(true, 'booleanAdapter', context)
132
+ })
133
+
134
+ it('calls the mocked adapter', function () {
135
+ expect(booleanAdapter.revert).toHaveBeenCalledOnce()
136
+ expect(booleanAdapter.revert).toHaveBeenCalledWith(true, 'booleanAdapter', context)
137
+ })
138
+ })
139
+ })
140
+ })
@@ -0,0 +1,259 @@
1
+ import {
2
+ expectDefined,
3
+ expectEquals,
4
+ } from '@strictly/base'
5
+ import {
6
+ type AnnotatedValidator,
7
+ type FunctionalValidator,
8
+ type Validator,
9
+ } from '@strictly/define'
10
+ import { type FieldAdapter } from 'core/mobx/field_adapter'
11
+ import {
12
+ identityAdapter,
13
+ } from 'core/mobx/field_adapter_builder'
14
+ import {
15
+ mergeAdaptersWithValidators,
16
+ type MergedOfFieldAdaptersWithValidators,
17
+ } from 'core/mobx/merge_field_adapters_with_validators'
18
+ import { UnreliableFieldConversionType } from 'types/field_converters'
19
+ import {
20
+ createMockedAdapter,
21
+ resetMockAdapter,
22
+ } from './fixtures'
23
+
24
+ const error1 = 'error 1'
25
+ const error2 = 'error 2'
26
+ const context = 'context 1'
27
+
28
+ describe('MergedOfFieldAdaptersWithValidators', function () {
29
+ describe('empty validators', function () {
30
+ type Adapters = {
31
+ readonly a: FieldAdapter<number, string, typeof error1, 'a', typeof context>,
32
+ }
33
+ type Validators = {}
34
+
35
+ type Merged = MergedOfFieldAdaptersWithValidators<Adapters, Validators>
36
+
37
+ it('does not change the adapters', function () {
38
+ expectTypeOf<Merged>().toEqualTypeOf<Adapters>()
39
+ })
40
+ })
41
+
42
+ describe('different errors', function () {
43
+ type Adapters = {
44
+ readonly a: FieldAdapter<number, string, typeof error1, 'a', typeof context>,
45
+ }
46
+ type Validators = {
47
+ readonly a: Validator<number, typeof error2, 'a', typeof context>,
48
+ }
49
+
50
+ type Merged = MergedOfFieldAdaptersWithValidators<Adapters, Validators>
51
+
52
+ it('merges the error types', function () {
53
+ expectTypeOf<Merged>().toEqualTypeOf<{
54
+ readonly a: FieldAdapter<number, string, typeof error1 | typeof error2, 'a', typeof context>,
55
+ }>()
56
+ })
57
+ })
58
+
59
+ describe('different paths', function () {
60
+ type Adapters = {
61
+ readonly a: FieldAdapter<number, string, typeof error1, string, typeof context>,
62
+ }
63
+ type Validators = {
64
+ readonly a: Validator<number, typeof error2, 'a', typeof context>,
65
+ }
66
+
67
+ type Merged = MergedOfFieldAdaptersWithValidators<Adapters, Validators>
68
+
69
+ it('merges the error types', function () {
70
+ expectTypeOf<Merged>().toEqualTypeOf<{
71
+ readonly a: FieldAdapter<number, string, typeof error1 | typeof error2, string, typeof context>,
72
+ }>()
73
+ })
74
+ })
75
+
76
+ describe('different values', function () {
77
+ type Adapters = {
78
+ readonly a: FieldAdapter<number, string, typeof error1, 'a', typeof context>,
79
+ }
80
+ type Validators = {
81
+ readonly a: Validator<boolean, typeof error2, 'a', typeof context>,
82
+ }
83
+
84
+ type Merged = MergedOfFieldAdaptersWithValidators<Adapters, Validators>
85
+
86
+ it('removes mismatched values', function () {
87
+ expectTypeOf<Merged>().toEqualTypeOf<{
88
+ readonly a: never,
89
+ }>()
90
+ })
91
+ })
92
+ })
93
+
94
+ const originalIntegerToIntegerAdapter = identityAdapter(0)
95
+ const originalBooleanToBooleanAdapter = identityAdapter(false, true)
96
+
97
+ describe('mergeFieldAdaptersWithValidators', function () {
98
+ const integerToIntegerAdapter = createMockedAdapter(
99
+ originalIntegerToIntegerAdapter,
100
+ )
101
+ const booleanToBooleanAdapter = createMockedAdapter(
102
+ originalBooleanToBooleanAdapter,
103
+ )
104
+
105
+ const failingValidator1 = vi.fn<FunctionalValidator>(function () {
106
+ return 'fail 1'
107
+ })
108
+
109
+ const failingValidator2 = vi.fn<FunctionalValidator>(function () {
110
+ return 'fail 2'
111
+ })
112
+
113
+ const requiredValidator: AnnotatedValidator = {
114
+ validate: () => null,
115
+ annotations: () => ({
116
+ required: true,
117
+ readonly: false,
118
+ }),
119
+ }
120
+
121
+ const readonlyValidator: AnnotatedValidator = {
122
+ validate: () => null,
123
+ annotations: () => ({
124
+ required: false,
125
+ readonly: true,
126
+ }),
127
+ }
128
+
129
+ beforeEach(function () {
130
+ resetMockAdapter(originalIntegerToIntegerAdapter, integerToIntegerAdapter)
131
+ resetMockAdapter(originalBooleanToBooleanAdapter, booleanToBooleanAdapter)
132
+ failingValidator1.mockClear()
133
+ failingValidator2.mockClear()
134
+ })
135
+
136
+ describe('record contents', function () {
137
+ describe('empty validators', function () {
138
+ const adapters = {
139
+ a: integerToIntegerAdapter,
140
+ b: booleanToBooleanAdapter,
141
+ } as const
142
+ const validators = {} as const
143
+
144
+ const merged = mergeAdaptersWithValidators(adapters, validators)
145
+ it('does not change the adapters', function () {
146
+ expect(merged).toEqual(adapters)
147
+ })
148
+ })
149
+
150
+ describe('populated validators', function () {
151
+ const adapters = {
152
+ a: integerToIntegerAdapter,
153
+ b: booleanToBooleanAdapter,
154
+ c: integerToIntegerAdapter,
155
+ d: integerToIntegerAdapter,
156
+ } as const
157
+ const validators = {
158
+ a: failingValidator1,
159
+ b: failingValidator2,
160
+ c: requiredValidator,
161
+ d: readonlyValidator,
162
+ } as const
163
+
164
+ const merged = mergeAdaptersWithValidators(adapters, validators)
165
+
166
+ describe('matching validators', function () {
167
+ it('has the same keys', function () {
168
+ expect([...Object.keys(adapters)]).toEqual([
169
+ 'a',
170
+ 'b',
171
+ 'c',
172
+ 'd',
173
+ ])
174
+ })
175
+ })
176
+
177
+ describe('revert', function () {
178
+ it.each([
179
+ [
180
+ 'a',
181
+ 'fail 1',
182
+ 1,
183
+ ],
184
+ [
185
+ 'b',
186
+ 'fail 2',
187
+ true,
188
+ ],
189
+ ] as const)('field %s fails with validation %s', function (key, error, value) {
190
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
191
+ const mergedAdapter: FieldAdapter<any, any, string, any> = merged[key]
192
+ expectDefined(mergedAdapter.revert)
193
+ const result = mergedAdapter.revert(value, key, null)
194
+ expectEquals(result.type, UnreliableFieldConversionType.Failure)
195
+ expect(result.error).toEqual(error)
196
+ })
197
+
198
+ it.each([
199
+ [
200
+ 'c',
201
+ 1,
202
+ ],
203
+ [
204
+ 'd',
205
+ true,
206
+ ],
207
+ ] as const)('field %s succeeds with value %s', function (key, value) {
208
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
209
+ const mergedAdapter: FieldAdapter<any, any, string, any> = merged[key]
210
+ expectDefined(mergedAdapter.revert)
211
+ const result = mergedAdapter.revert(value, key, null)
212
+ expectEquals(result.type, UnreliableFieldConversionType.Success)
213
+ expect(result.value).toEqual(value)
214
+ })
215
+ })
216
+
217
+ describe('convert', function () {
218
+ it.each([
219
+ [
220
+ 'a',
221
+ false,
222
+ false,
223
+ 1,
224
+ ],
225
+ [
226
+ 'b',
227
+ true,
228
+ false,
229
+ true,
230
+ ],
231
+ [
232
+ 'c',
233
+ true,
234
+ false,
235
+ 2,
236
+ ],
237
+ [
238
+ 'd',
239
+ false,
240
+ true,
241
+ 3,
242
+ ],
243
+ ] as const)(
244
+ 'field %s is required %s and readonly %s',
245
+ function (key, expectedRequired, expectedReadonly, value) {
246
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
247
+ const adapter: FieldAdapter<any, any, string, any> = merged[key]
248
+ const {
249
+ required,
250
+ readonly,
251
+ } = adapter.convert(value, key, null)
252
+ expect(required).toEqual(expectedRequired)
253
+ expect(readonly).toEqual(expectedReadonly)
254
+ },
255
+ )
256
+ })
257
+ })
258
+ })
259
+ })
@@ -1,5 +1,5 @@
1
1
  // TODO rename/split-out this file
2
- import { type ToTypeOfFieldAdapter } from './field_adapter'
2
+ import { type ToOfFieldAdapter } from './field_adapter'
3
3
  import {
4
4
  type FlattenedConvertedFieldsOf,
5
5
  type FormPresenter,
@@ -23,7 +23,7 @@ export type ValuePathsOfPresenter<
23
23
  * Used to extract the render type (so the value that is passed to the view) of a given value path
24
24
  * from a presenter
25
25
  */
26
- export type ToTypeOfPresenterValuePath<
26
+ export type ToValueOfPresenterValuePath<
27
27
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
28
  Presenter extends FormPresenter<any, any, any, any>,
29
29
  K extends ValuePathsOfPresenter<Presenter>,
@@ -32,7 +32,7 @@ export type ToTypeOfPresenterValuePath<
32
32
  infer _2,
33
33
  infer _3,
34
34
  infer ValuePathsToAdapters
35
- > ? ToTypeOfFieldAdapter<ValuePathsToAdapters[K]>
35
+ > ? ToOfFieldAdapter<ValuePathsToAdapters[K]>
36
36
  : never
37
37
 
38
38
  /**