@strictly/react-form 0.0.13 → 0.0.15
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 +1 -0
- package/.out/core/mobx/form_model.d.ts +8 -3
- package/.out/core/mobx/form_model.js +23 -15
- package/.out/core/mobx/hooks.d.ts +2 -2
- package/.out/core/mobx/merge_field_adapters_with_two_way_converter.d.ts +2 -2
- package/.out/core/mobx/merge_field_adapters_with_validators.d.ts +1 -1
- package/.out/core/mobx/specs/form_model.tests.js +26 -21
- package/.out/core/mobx/specs/sub_form_field_adapters.tests.js +14 -21
- package/.out/core/mobx/sub_form_field_adapters.d.ts +5 -6
- package/.out/core/mobx/sub_form_field_adapters.js +6 -11
- package/.out/core/mobx/types.d.ts +3 -3
- package/.out/index.d.ts +2 -0
- package/.out/index.js +2 -0
- package/.out/mantine/field_view.d.ts +18 -0
- package/.out/mantine/field_view.js +16 -0
- package/.out/tsconfig.tsbuildinfo +1 -1
- package/.out/types/merge_validators.d.ts +1 -1
- package/.out/util/empty.d.ts +1 -0
- package/.out/util/empty.js +3 -0
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-check-types.log +1 -1
- package/core/mobx/field_adapter.ts +9 -0
- package/core/mobx/form_model.ts +35 -16
- package/core/mobx/hooks.tsx +2 -2
- package/core/mobx/merge_field_adapters_with_two_way_converter.ts +2 -1
- package/core/mobx/merge_field_adapters_with_validators.ts +1 -1
- package/core/mobx/specs/form_model.tests.ts +35 -20
- package/core/mobx/specs/sub_form_field_adapters.tests.ts +14 -34
- package/core/mobx/sub_form_field_adapters.ts +11 -26
- package/core/mobx/types.ts +10 -7
- package/dist/index.cjs +99 -67
- package/dist/index.d.cts +38 -15
- package/dist/index.d.ts +38 -15
- package/dist/index.js +77 -49
- package/index.ts +2 -0
- package/mantine/field_view.tsx +39 -0
- package/package.json +1 -1
- package/types/merge_validators.ts +2 -2
- package/util/empty.tsx +3 -0
|
@@ -3,5 +3,5 @@ import { type Simplify } from 'type-fest';
|
|
|
3
3
|
export type MergedOfValidators<Validators1 extends Partial<Readonly<Record<Keys, Validator>>>, Validators2 extends Partial<Readonly<Record<Keys, Validator>>>, Keys extends string = Extract<keyof Validators1 | keyof Validators2, string>> = Simplify<{
|
|
4
4
|
readonly [K in Keys]: undefined extends Validators1[K] ? undefined extends Validators2[K] ? never : Validators2[K] : undefined extends Validators2[K] ? Validators1[K] : MergedOfValidator<NonNullable<Validators1[K]>, NonNullable<Validators2[K]>>;
|
|
5
5
|
}>;
|
|
6
|
-
export type MergedOfValidator<Validator1 extends Validator, Validator2 extends Validator> = Validator1 extends Validator<infer V, infer E1, infer P, infer
|
|
6
|
+
export type MergedOfValidator<Validator1 extends Validator, Validator2 extends Validator> = Validator1 extends Validator<infer V, infer E1, infer P, infer C1> ? Validator2 extends Validator<V, infer E2, P, infer C2> ? Validator<V, E1 | E2, P, C1 & C2> : never : never;
|
|
7
7
|
export declare function mergeValidators<Validators1 extends Partial<Readonly<Record<Keys, Validator>>>, Validators2 extends Partial<Readonly<Record<Keys, Validator>>>, Keys extends string = Extract<keyof Validators1 | keyof Validators2, string>>(validators1: Validators1, validators2: Validators2): MergedOfValidators<Validators1, Validators2, Keys>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Empty(): null;
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -7,12 +7,12 @@ $ tsup
|
|
|
7
7
|
[34mCLI[39m Target: es6
|
|
8
8
|
[34mCJS[39m Build start
|
|
9
9
|
[34mESM[39m Build start
|
|
10
|
-
[32mESM[39m [1mdist/index.js [22m[32m55.
|
|
11
|
-
[32mESM[39m ⚡️ Build success in
|
|
12
|
-
[32mCJS[39m [1mdist/index.cjs [22m[32m59.
|
|
13
|
-
[32mCJS[39m ⚡️ Build success in
|
|
10
|
+
[32mESM[39m [1mdist/index.js [22m[32m55.85 KB[39m
|
|
11
|
+
[32mESM[39m ⚡️ Build success in 136ms
|
|
12
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m59.76 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 141ms
|
|
14
14
|
[34mDTS[39m Build start
|
|
15
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
-
[32mDTS[39m [1mdist/index.d.cts [22m[
|
|
17
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
18
|
-
Done in 10.
|
|
15
|
+
[32mDTS[39m ⚡️ Build success in 9792ms
|
|
16
|
+
[32mDTS[39m [1mdist/index.d.cts [22m[32m37.63 KB[39m
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m37.63 KB[39m
|
|
18
|
+
Done in 10.91s.
|
|
@@ -38,3 +38,12 @@ export type ValuePathOfFieldAdapter<C extends FieldAdapter> = C extends FieldAda
|
|
|
38
38
|
infer ValuePath
|
|
39
39
|
> ? ValuePath
|
|
40
40
|
: never
|
|
41
|
+
|
|
42
|
+
export type ContextOfFieldAdapter<F extends FieldAdapter> = F extends FieldAdapter<
|
|
43
|
+
infer _From,
|
|
44
|
+
infer _To,
|
|
45
|
+
infer _E,
|
|
46
|
+
infer _P,
|
|
47
|
+
infer Context
|
|
48
|
+
> ? Context
|
|
49
|
+
: never
|
package/core/mobx/form_model.ts
CHANGED
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
type ReadonlyDeep,
|
|
36
36
|
type SimplifyDeep,
|
|
37
37
|
type StringKeyOf,
|
|
38
|
+
type UnionToIntersection,
|
|
38
39
|
type ValueOf,
|
|
39
40
|
} from 'type-fest'
|
|
40
41
|
import {
|
|
@@ -45,6 +46,7 @@ import {
|
|
|
45
46
|
UnreliableFieldConversionType,
|
|
46
47
|
} from 'types/field_converters'
|
|
47
48
|
import {
|
|
49
|
+
type ContextOfFieldAdapter,
|
|
48
50
|
type ErrorOfFieldAdapter,
|
|
49
51
|
type FieldAdapter,
|
|
50
52
|
type ToOfFieldAdapter,
|
|
@@ -102,13 +104,21 @@ export type ValuePathsToAdaptersOf<
|
|
|
102
104
|
}
|
|
103
105
|
: never
|
|
104
106
|
|
|
105
|
-
export
|
|
107
|
+
export type ContextOf<TypePathsToAdapters extends Partial<Readonly<Record<string, FieldAdapter>>>> =
|
|
108
|
+
UnionToIntersection<{
|
|
109
|
+
readonly [
|
|
110
|
+
K in keyof TypePathsToAdapters
|
|
111
|
+
]: TypePathsToAdapters[K] extends undefined ? undefined : ContextOfFieldAdapter<NonNullable<TypePathsToAdapters[K]>>
|
|
112
|
+
}[keyof TypePathsToAdapters]>
|
|
113
|
+
|
|
114
|
+
export abstract class FormModel<
|
|
106
115
|
T extends Type,
|
|
107
116
|
ValueToTypePaths extends Readonly<Record<string, string>>,
|
|
108
117
|
TypePathsToAdapters extends FlattenedTypePathsToAdaptersOf<
|
|
109
118
|
FlattenedValuesOfType<T, '*'>,
|
|
110
|
-
|
|
119
|
+
ContextType
|
|
111
120
|
>,
|
|
121
|
+
ContextType = ContextOf<TypePathsToAdapters>,
|
|
112
122
|
ValuePathsToAdapters extends ValuePathsToAdaptersOf<TypePathsToAdapters, ValueToTypePaths> = ValuePathsToAdaptersOf<
|
|
113
123
|
TypePathsToAdapters,
|
|
114
124
|
ValueToTypePaths
|
|
@@ -130,6 +140,7 @@ export class FormModel<
|
|
|
130
140
|
) {
|
|
131
141
|
this.value = mobxCopy(type, value)
|
|
132
142
|
this.flattenedTypeDefs = flattenTypesOfType(type)
|
|
143
|
+
const contextValue = this.toContext(value)
|
|
133
144
|
// pre-populate field overrides for consistent behavior when default information is overwritten
|
|
134
145
|
// then returned to
|
|
135
146
|
const conversions = flattenValueTo(
|
|
@@ -156,7 +167,8 @@ export class FormModel<
|
|
|
156
167
|
// no need to store a temporary value if the value cannot be written back
|
|
157
168
|
return
|
|
158
169
|
}
|
|
159
|
-
|
|
170
|
+
// cannot call this.context yet as the "this" pointer has not been fully created
|
|
171
|
+
return convert(value, valuePath, contextValue)
|
|
160
172
|
},
|
|
161
173
|
)
|
|
162
174
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
@@ -165,6 +177,13 @@ export class FormModel<
|
|
|
165
177
|
}) as FlattenedFieldOverrides<ValuePathsToAdapters>
|
|
166
178
|
}
|
|
167
179
|
|
|
180
|
+
@computed.struct
|
|
181
|
+
get context() {
|
|
182
|
+
return this.toContext(this.value)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
protected abstract toContext(value: ValueOfType<ReadonlyTypeOfType<T>>): ContextType
|
|
186
|
+
|
|
168
187
|
@computed
|
|
169
188
|
get fields(): SimplifyDeep<FlattenedConvertedFieldsOf<ValuePathsToAdapters>> {
|
|
170
189
|
return new Proxy<SimplifyDeep<FlattenedConvertedFieldsOf<ValuePathsToAdapters>>>(
|
|
@@ -248,14 +267,14 @@ export class FormModel<
|
|
|
248
267
|
? mobxCopy(
|
|
249
268
|
fieldTypeDef,
|
|
250
269
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
251
|
-
create(valuePath as string, this.
|
|
270
|
+
create(valuePath as string, this.context),
|
|
252
271
|
)
|
|
253
272
|
// fake values can't be copied
|
|
254
273
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
255
|
-
: create(valuePath as string, this.
|
|
274
|
+
: create(valuePath as string, this.context),
|
|
256
275
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
257
276
|
valuePath as string,
|
|
258
|
-
this.
|
|
277
|
+
this.context,
|
|
259
278
|
)
|
|
260
279
|
const error = this.errors[valuePath]
|
|
261
280
|
return {
|
|
@@ -341,7 +360,7 @@ export class FormModel<
|
|
|
341
360
|
: elementAdapter.create(
|
|
342
361
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
343
362
|
elementTypePath as string,
|
|
344
|
-
this.
|
|
363
|
+
this.context,
|
|
345
364
|
)
|
|
346
365
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
347
366
|
const originalList: any[] = accessor.value
|
|
@@ -486,7 +505,7 @@ export class FormModel<
|
|
|
486
505
|
assertExists(revert, 'setting value not supported {}', valuePath)
|
|
487
506
|
|
|
488
507
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
|
|
489
|
-
const conversion = revert(value, valuePath as any, this.
|
|
508
|
+
const conversion = revert(value, valuePath as any, this.context)
|
|
490
509
|
const accessor = this.getAccessorForValuePath(valuePath)
|
|
491
510
|
return runInAction(() => {
|
|
492
511
|
this.fieldOverrides[valuePath] = [value]
|
|
@@ -529,10 +548,10 @@ export class FormModel<
|
|
|
529
548
|
convert,
|
|
530
549
|
create,
|
|
531
550
|
} = adapter
|
|
532
|
-
const value = create(valuePath, this.
|
|
551
|
+
const value = create(valuePath, this.context)
|
|
533
552
|
const {
|
|
534
553
|
value: displayValue,
|
|
535
|
-
} = convert(value, valuePath, this.
|
|
554
|
+
} = convert(value, valuePath, this.context)
|
|
536
555
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
537
556
|
const key = valuePath as unknown as keyof ValuePathsToAdapters
|
|
538
557
|
runInAction(() => {
|
|
@@ -573,10 +592,10 @@ export class FormModel<
|
|
|
573
592
|
accessor != null
|
|
574
593
|
? accessor.value
|
|
575
594
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
576
|
-
: create(valuePath as string, this.
|
|
595
|
+
: create(valuePath as string, this.context),
|
|
577
596
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
578
597
|
valuePath as string,
|
|
579
|
-
this.
|
|
598
|
+
this.context,
|
|
580
599
|
)
|
|
581
600
|
const value = fieldOverride != null
|
|
582
601
|
? fieldOverride[0]
|
|
@@ -586,13 +605,13 @@ export class FormModel<
|
|
|
586
605
|
if (ignoreDefaultValue) {
|
|
587
606
|
const {
|
|
588
607
|
value: defaultDisplayValue,
|
|
589
|
-
} = convert(create(valuePath, this.
|
|
608
|
+
} = convert(create(valuePath, this.context), valuePath, this.context)
|
|
590
609
|
if (defaultDisplayValue === value) {
|
|
591
610
|
return true
|
|
592
611
|
}
|
|
593
612
|
}
|
|
594
613
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
595
|
-
const conversion = revert(value, valuePath as string, this.
|
|
614
|
+
const conversion = revert(value, valuePath as string, this.context)
|
|
596
615
|
return runInAction(() => {
|
|
597
616
|
switch (conversion.type) {
|
|
598
617
|
case UnreliableFieldConversionType.Failure:
|
|
@@ -645,14 +664,14 @@ export class FormModel<
|
|
|
645
664
|
const fieldOverride = this.fieldOverrides[adapterPath]
|
|
646
665
|
const {
|
|
647
666
|
value: storedValue,
|
|
648
|
-
} = convert(accessor.value, valuePath, this.
|
|
667
|
+
} = convert(accessor.value, valuePath, this.context)
|
|
649
668
|
const value = fieldOverride != null
|
|
650
669
|
? fieldOverride[0]
|
|
651
670
|
: storedValue
|
|
652
671
|
// TODO more nuanced comparison
|
|
653
672
|
const dirty = fieldOverride != null && fieldOverride[0] !== storedValue
|
|
654
673
|
|
|
655
|
-
const conversion = revert(value, valuePath, this.
|
|
674
|
+
const conversion = revert(value, valuePath, this.context)
|
|
656
675
|
switch (conversion.type) {
|
|
657
676
|
case UnreliableFieldConversionType.Failure:
|
|
658
677
|
this.errors[adapterPath] = conversion.error
|
package/core/mobx/hooks.tsx
CHANGED
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
} from './types'
|
|
14
14
|
|
|
15
15
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
-
type ValueOfModel<M extends FormModel<any, any, any, any>> = M extends FormModel<infer T, any, any, any>
|
|
16
|
+
type ValueOfModel<M extends FormModel<any, any, any, any, any>> = M extends FormModel<infer T, any, any, any, any>
|
|
17
17
|
? ValueOfType<ReadonlyTypeOfType<T>>
|
|
18
18
|
: never
|
|
19
19
|
|
|
20
20
|
export function useDefaultMobxFormHooks<
|
|
21
21
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
-
M extends FormModel<any, any, any, any>,
|
|
22
|
+
M extends FormModel<any, any, any, any, any>,
|
|
23
23
|
F extends FormFieldsOfModel<M> = FormFieldsOfModel<M>,
|
|
24
24
|
>(
|
|
25
25
|
model: M,
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from 'field_converters/chain_field_converter'
|
|
6
6
|
import { type TwoWayFieldConverter } from 'types/field_converters'
|
|
7
7
|
import {
|
|
8
|
+
type ContextOfFieldAdapter,
|
|
8
9
|
type ErrorOfFieldAdapter,
|
|
9
10
|
type FieldAdapter,
|
|
10
11
|
type FromOfFieldAdapter,
|
|
@@ -22,7 +23,7 @@ export type MergedOfFieldAdaptersWithTwoWayConverter<
|
|
|
22
23
|
ToOfFieldAdapter<FieldAdapters[K]>,
|
|
23
24
|
ErrorOfFieldAdapter<FieldAdapters[K]> | E,
|
|
24
25
|
ValuePathOfFieldAdapter<FieldAdapters[K]>,
|
|
25
|
-
Context
|
|
26
|
+
ContextOfFieldAdapter<FieldAdapters[K]> & Context
|
|
26
27
|
>
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -28,7 +28,7 @@ type MergedOfFieldAdapterWithValidator<
|
|
|
28
28
|
V extends Validator | undefined,
|
|
29
29
|
> = undefined extends V ? A
|
|
30
30
|
: A extends FieldAdapter<infer From, infer To, infer E1, infer P1, infer C1>
|
|
31
|
-
? V extends Validator<From, infer E2, infer P2, infer C2> ? FieldAdapter<From, To, E1 | E2, P1 | P2, C1
|
|
31
|
+
? V extends Validator<From, infer E2, infer P2, infer C2> ? FieldAdapter<From, To, E1 | E2, P1 | P2, C1 & C2>
|
|
32
32
|
: never
|
|
33
33
|
: never
|
|
34
34
|
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
object,
|
|
9
9
|
record,
|
|
10
10
|
stringType,
|
|
11
|
+
type Type,
|
|
11
12
|
union,
|
|
12
13
|
type ValueOfType,
|
|
13
14
|
type ValueToTypePathsOfType,
|
|
@@ -45,6 +46,21 @@ const originalIntegerToStringAdapter = adapterFromTwoWayConverter(
|
|
|
45
46
|
|
|
46
47
|
const originalBooleanToBooleanAdapter = identityAdapter(false)
|
|
47
48
|
|
|
49
|
+
class TestFormModel<
|
|
50
|
+
T extends Type,
|
|
51
|
+
ValueToTypePaths extends Readonly<Record<string, string>>,
|
|
52
|
+
TypePathsToAdapters extends FlattenedTypePathsToAdaptersOf<
|
|
53
|
+
FlattenedValuesOfType<T, '*'>,
|
|
54
|
+
{}
|
|
55
|
+
>,
|
|
56
|
+
> extends FormModel<T, ValueToTypePaths, TypePathsToAdapters, {}> {
|
|
57
|
+
override toContext() {
|
|
58
|
+
return {
|
|
59
|
+
ctx: true,
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
48
64
|
describe('all', function () {
|
|
49
65
|
const integerToStringAdapter = createMockedAdapter(
|
|
50
66
|
originalIntegerToStringAdapter,
|
|
@@ -171,7 +187,7 @@ describe('all', function () {
|
|
|
171
187
|
>
|
|
172
188
|
beforeEach(function () {
|
|
173
189
|
originalValue = 5
|
|
174
|
-
model = new
|
|
190
|
+
model = new TestFormModel<
|
|
175
191
|
typeof typeDef,
|
|
176
192
|
ValueToTypePathsOfType<typeof typeDef>,
|
|
177
193
|
typeof adapters
|
|
@@ -231,7 +247,7 @@ describe('all', function () {
|
|
|
231
247
|
readonly: false,
|
|
232
248
|
})
|
|
233
249
|
originalValue = 5
|
|
234
|
-
model = new
|
|
250
|
+
model = new TestFormModel<
|
|
235
251
|
typeof typeDef,
|
|
236
252
|
ValueToTypePathsOfType<typeof typeDef>,
|
|
237
253
|
typeof adapters
|
|
@@ -272,7 +288,7 @@ describe('all', function () {
|
|
|
272
288
|
4,
|
|
273
289
|
17,
|
|
274
290
|
]
|
|
275
|
-
model = new
|
|
291
|
+
model = new TestFormModel<
|
|
276
292
|
typeof typeDef,
|
|
277
293
|
ValueToTypePathsOfType<typeof typeDef>,
|
|
278
294
|
typeof adapters
|
|
@@ -350,7 +366,7 @@ describe('all', function () {
|
|
|
350
366
|
a: 1,
|
|
351
367
|
b: 2,
|
|
352
368
|
}
|
|
353
|
-
model = new
|
|
369
|
+
model = new TestFormModel<
|
|
354
370
|
typeof typeDef,
|
|
355
371
|
ValueToTypePathsOfType<typeof typeDef>,
|
|
356
372
|
typeof converters
|
|
@@ -420,7 +436,7 @@ describe('all', function () {
|
|
|
420
436
|
a: 1,
|
|
421
437
|
b: true,
|
|
422
438
|
}
|
|
423
|
-
model = new
|
|
439
|
+
model = new TestFormModel<
|
|
424
440
|
typeof typeDef,
|
|
425
441
|
ValueToTypePathsOfType<typeof typeDef>,
|
|
426
442
|
typeof converters
|
|
@@ -485,7 +501,7 @@ describe('all', function () {
|
|
|
485
501
|
typeof adapters
|
|
486
502
|
>
|
|
487
503
|
beforeEach(function () {
|
|
488
|
-
model = new
|
|
504
|
+
model = new TestFormModel<
|
|
489
505
|
typeof typeDef,
|
|
490
506
|
ValueToTypePathsOfType<typeof typeDef>,
|
|
491
507
|
typeof adapters
|
|
@@ -611,7 +627,7 @@ describe('all', function () {
|
|
|
611
627
|
3,
|
|
612
628
|
7,
|
|
613
629
|
]
|
|
614
|
-
model = new
|
|
630
|
+
model = new TestFormModel<
|
|
615
631
|
typeof typeDef,
|
|
616
632
|
ValueToTypePathsOfType<typeof typeDef>,
|
|
617
633
|
typeof converters
|
|
@@ -727,7 +743,7 @@ describe('all', function () {
|
|
|
727
743
|
let contextCopy: number[]
|
|
728
744
|
beforeEach(function () {
|
|
729
745
|
integerToStringAdapter.revert.mockImplementationOnce(function (_value, _path, context) {
|
|
730
|
-
contextCopy =
|
|
746
|
+
contextCopy = { ...context }
|
|
731
747
|
return {
|
|
732
748
|
type: UnreliableFieldConversionType.Success,
|
|
733
749
|
value: 1,
|
|
@@ -742,17 +758,16 @@ describe('all', function () {
|
|
|
742
758
|
expect(integerToStringAdapter.revert).toHaveBeenCalledWith(
|
|
743
759
|
'4',
|
|
744
760
|
'$.2',
|
|
745
|
-
|
|
746
|
-
|
|
761
|
+
{
|
|
762
|
+
ctx: true,
|
|
763
|
+
},
|
|
747
764
|
)
|
|
748
765
|
})
|
|
749
766
|
|
|
750
|
-
it('supplies the context
|
|
751
|
-
expect(contextCopy).toEqual(
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
7,
|
|
755
|
-
])
|
|
767
|
+
it('supplies the context', function () {
|
|
768
|
+
expect(contextCopy).toEqual({
|
|
769
|
+
ctx: true,
|
|
770
|
+
})
|
|
756
771
|
})
|
|
757
772
|
})
|
|
758
773
|
|
|
@@ -953,7 +968,7 @@ describe('all', function () {
|
|
|
953
968
|
>
|
|
954
969
|
beforeEach(function () {
|
|
955
970
|
originalValue = null
|
|
956
|
-
model = new
|
|
971
|
+
model = new TestFormModel<
|
|
957
972
|
typeof type,
|
|
958
973
|
ValueToTypePaths,
|
|
959
974
|
typeof adapters
|
|
@@ -1018,7 +1033,7 @@ describe('all', function () {
|
|
|
1018
1033
|
|
|
1019
1034
|
describe('isValuePathActive', function () {
|
|
1020
1035
|
describe('discriminator x', function () {
|
|
1021
|
-
const model = new
|
|
1036
|
+
const model = new TestFormModel<
|
|
1022
1037
|
typeof type,
|
|
1023
1038
|
ValueToTypePaths,
|
|
1024
1039
|
typeof adapters
|
|
@@ -1050,7 +1065,7 @@ describe('all', function () {
|
|
|
1050
1065
|
})
|
|
1051
1066
|
|
|
1052
1067
|
describe('discriminator y', function () {
|
|
1053
|
-
const model = new
|
|
1068
|
+
const model = new TestFormModel<
|
|
1054
1069
|
typeof type,
|
|
1055
1070
|
ValueToTypePaths,
|
|
1056
1071
|
typeof adapters
|
|
@@ -1102,7 +1117,7 @@ describe('all', function () {
|
|
|
1102
1117
|
>
|
|
1103
1118
|
beforeEach(function () {
|
|
1104
1119
|
originalValue = 1
|
|
1105
|
-
model = new
|
|
1120
|
+
model = new TestFormModel<
|
|
1106
1121
|
typeof typeDef,
|
|
1107
1122
|
JsonPaths,
|
|
1108
1123
|
typeof converters
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
list,
|
|
3
|
-
numberType,
|
|
4
|
-
object,
|
|
5
|
-
stringType,
|
|
6
|
-
} from '@strictly/define'
|
|
7
1
|
import { type FieldAdapter } from 'core/mobx/field_adapter'
|
|
8
2
|
import {
|
|
9
3
|
subFormFieldAdapters,
|
|
@@ -19,7 +13,6 @@ describe('subFormFieldAdapters', () => {
|
|
|
19
13
|
const adapters = subFormFieldAdapters(
|
|
20
14
|
{},
|
|
21
15
|
'$.a',
|
|
22
|
-
stringType,
|
|
23
16
|
)
|
|
24
17
|
|
|
25
18
|
it('equals expected type', () => {
|
|
@@ -35,19 +28,16 @@ describe('subFormFieldAdapters', () => {
|
|
|
35
28
|
const mockedFieldAdapter1 = mockDeep<Required<FieldAdapter<string, boolean, number, '$', string>>>()
|
|
36
29
|
const fieldAdapter1: FieldAdapter<string, boolean, number, '$', string> = mockedFieldAdapter1
|
|
37
30
|
|
|
38
|
-
const type = object().field('a', stringType)
|
|
39
31
|
const subAdapters = {
|
|
40
32
|
$: fieldAdapter1,
|
|
41
33
|
} as const
|
|
42
34
|
const adapters = subFormFieldAdapters<
|
|
43
35
|
typeof subAdapters,
|
|
44
36
|
'$.a',
|
|
45
|
-
{ '$.a': '$.a' }
|
|
46
|
-
typeof type
|
|
37
|
+
{ '$.a': '$.a' }
|
|
47
38
|
>(
|
|
48
39
|
subAdapters,
|
|
49
40
|
'$.a',
|
|
50
|
-
type,
|
|
51
41
|
)
|
|
52
42
|
|
|
53
43
|
beforeEach(() => {
|
|
@@ -58,9 +48,7 @@ describe('subFormFieldAdapters', () => {
|
|
|
58
48
|
// TODO toEqualTypeOf (cannot reason about revert optionality, seems to be a TS issue as they
|
|
59
49
|
// are both optional AFAICT)
|
|
60
50
|
expectTypeOf(adapters).toMatchTypeOf<{
|
|
61
|
-
'$.a': FieldAdapter<string, boolean, number, '$.a',
|
|
62
|
-
a: string,
|
|
63
|
-
}>,
|
|
51
|
+
'$.a': FieldAdapter<string, boolean, number, '$.a', string>,
|
|
64
52
|
}>()
|
|
65
53
|
})
|
|
66
54
|
|
|
@@ -76,7 +64,7 @@ describe('subFormFieldAdapters', () => {
|
|
|
76
64
|
}
|
|
77
65
|
mockedFieldAdapter1.convert.mockReturnValue(mockedReturnedValue)
|
|
78
66
|
|
|
79
|
-
const returnedValue = adapters['$.a'].convert('x', '$.a',
|
|
67
|
+
const returnedValue = adapters['$.a'].convert('x', '$.a', 'y')
|
|
80
68
|
expect(fieldAdapter1.convert).toHaveBeenCalledWith('x', '$', 'y')
|
|
81
69
|
expect(returnedValue).toEqual(mockedReturnedValue)
|
|
82
70
|
})
|
|
@@ -88,7 +76,7 @@ describe('subFormFieldAdapters', () => {
|
|
|
88
76
|
} as const
|
|
89
77
|
mockedFieldAdapter1.revert.mockReturnValue(mockedReturnedValue)
|
|
90
78
|
|
|
91
|
-
const returnedValue = adapters['$.a'].revert?.(true, '$.a',
|
|
79
|
+
const returnedValue = adapters['$.a'].revert?.(true, '$.a', 'y')
|
|
92
80
|
expect(fieldAdapter1.revert).toHaveBeenCalledWith(true, '$', 'y')
|
|
93
81
|
expect(returnedValue).toEqual(mockedReturnedValue)
|
|
94
82
|
})
|
|
@@ -97,7 +85,7 @@ describe('subFormFieldAdapters', () => {
|
|
|
97
85
|
const mockedReturnedValue = 'x'
|
|
98
86
|
mockedFieldAdapter1.create.mockReturnValue(mockedReturnedValue)
|
|
99
87
|
|
|
100
|
-
const returnedValue = adapters['$.a'].create('$.a',
|
|
88
|
+
const returnedValue = adapters['$.a'].create('$.a', 'y')
|
|
101
89
|
expect(fieldAdapter1.create).toHaveBeenCalledWith('$', 'y')
|
|
102
90
|
expect(returnedValue).toEqual(mockedReturnedValue)
|
|
103
91
|
})
|
|
@@ -109,15 +97,12 @@ describe('subFormFieldAdapters', () => {
|
|
|
109
97
|
const mockedFieldAdapter2 = mockDeep<FieldAdapter<number, boolean>>()
|
|
110
98
|
const fieldAdapter2: FieldAdapter<number, boolean> = mockedFieldAdapter2
|
|
111
99
|
|
|
112
|
-
const type = object()
|
|
113
|
-
.field('a', object().field('x', stringType).field('y', numberType))
|
|
114
100
|
const adapters = subFormFieldAdapters(
|
|
115
101
|
{
|
|
116
102
|
'$.x': fieldAdapter1,
|
|
117
103
|
'$.y': fieldAdapter2,
|
|
118
104
|
},
|
|
119
105
|
'$.a',
|
|
120
|
-
type,
|
|
121
106
|
)
|
|
122
107
|
|
|
123
108
|
beforeEach(() => {
|
|
@@ -141,12 +126,11 @@ describe('subFormFieldAdapters', () => {
|
|
|
141
126
|
})
|
|
142
127
|
|
|
143
128
|
describe('calls convert with correct paths and values', () => {
|
|
144
|
-
const subContext = {
|
|
145
|
-
x: 'a',
|
|
146
|
-
y: 1,
|
|
147
|
-
} as const
|
|
148
129
|
const context = {
|
|
149
|
-
a:
|
|
130
|
+
a: {
|
|
131
|
+
x: 'a',
|
|
132
|
+
y: 1,
|
|
133
|
+
},
|
|
150
134
|
}
|
|
151
135
|
|
|
152
136
|
it('calls $.a.x', () => {
|
|
@@ -158,7 +142,7 @@ describe('subFormFieldAdapters', () => {
|
|
|
158
142
|
mockedFieldAdapter1.convert.mockReturnValue(mockedReturnedValue)
|
|
159
143
|
|
|
160
144
|
const returnedValue = adapters['$.a.x'].convert('b', '$.a.x', context)
|
|
161
|
-
expect(fieldAdapter1.convert).toHaveBeenCalledWith('b', '$.x',
|
|
145
|
+
expect(fieldAdapter1.convert).toHaveBeenCalledWith('b', '$.x', context)
|
|
162
146
|
expect(returnedValue).toEqual(mockedReturnedValue)
|
|
163
147
|
})
|
|
164
148
|
|
|
@@ -171,7 +155,7 @@ describe('subFormFieldAdapters', () => {
|
|
|
171
155
|
mockedFieldAdapter2.convert.mockReturnValue(mockedReturnedValue)
|
|
172
156
|
|
|
173
157
|
const returnedValue = adapters['$.a.y'].convert(2, '$.a.y', context)
|
|
174
|
-
expect(fieldAdapter2.convert).toHaveBeenCalledWith(2, '$.y',
|
|
158
|
+
expect(fieldAdapter2.convert).toHaveBeenCalledWith(2, '$.y', context)
|
|
175
159
|
expect(returnedValue).toEqual(mockedReturnedValue)
|
|
176
160
|
})
|
|
177
161
|
})
|
|
@@ -180,7 +164,6 @@ describe('subFormFieldAdapters', () => {
|
|
|
180
164
|
describe('list adapter', () => {
|
|
181
165
|
const mockedFieldAdapter1 = mockDeep<Required<FieldAdapter<string, boolean, number, '$', string>>>()
|
|
182
166
|
const fieldAdapter1: FieldAdapter<string, boolean, number, '$', string> = mockedFieldAdapter1
|
|
183
|
-
const type = list(stringType)
|
|
184
167
|
const subAdapters = {
|
|
185
168
|
$: fieldAdapter1,
|
|
186
169
|
}
|
|
@@ -189,12 +172,10 @@ describe('subFormFieldAdapters', () => {
|
|
|
189
172
|
'$.*',
|
|
190
173
|
{
|
|
191
174
|
'$.*': `$.${number}`,
|
|
192
|
-
}
|
|
193
|
-
typeof type
|
|
175
|
+
}
|
|
194
176
|
>(
|
|
195
177
|
subAdapters,
|
|
196
178
|
'$.*',
|
|
197
|
-
type,
|
|
198
179
|
)
|
|
199
180
|
|
|
200
181
|
beforeEach(() => {
|
|
@@ -204,7 +185,7 @@ describe('subFormFieldAdapters', () => {
|
|
|
204
185
|
it('equals expected type', () => {
|
|
205
186
|
// TODO toEqualTypeOf (seems to be a TS error)
|
|
206
187
|
expectTypeOf(adapters).toMatchTypeOf<{
|
|
207
|
-
'$.*': FieldAdapter<string, boolean, number, `$.${number}`, string
|
|
188
|
+
'$.*': FieldAdapter<string, boolean, number, `$.${number}`, string>,
|
|
208
189
|
}>()
|
|
209
190
|
})
|
|
210
191
|
|
|
@@ -216,7 +197,6 @@ describe('subFormFieldAdapters', () => {
|
|
|
216
197
|
|
|
217
198
|
describe('calls convert with correct paths and values', () => {
|
|
218
199
|
const subContext = 'a'
|
|
219
|
-
const context = [subContext]
|
|
220
200
|
|
|
221
201
|
it('calls $.*', () => {
|
|
222
202
|
const mockedReturnedValue = {
|
|
@@ -226,7 +206,7 @@ describe('subFormFieldAdapters', () => {
|
|
|
226
206
|
}
|
|
227
207
|
mockedFieldAdapter1.convert.mockReturnValue(mockedReturnedValue)
|
|
228
208
|
|
|
229
|
-
const returnedValue = adapters['$.*'].convert('b', '$.0',
|
|
209
|
+
const returnedValue = adapters['$.*'].convert('b', '$.0', subContext)
|
|
230
210
|
expect(fieldAdapter1.convert).toHaveBeenCalledWith('b', '$', subContext)
|
|
231
211
|
expect(returnedValue).toEqual(mockedReturnedValue)
|
|
232
212
|
})
|