@strictly/react-form 0.0.10 → 0.0.12
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_builder.js +18 -6
- package/.out/core/mobx/{form_presenter.d.ts → form_model.d.ts} +15 -21
- package/.out/core/mobx/form_model.js +513 -0
- package/.out/core/mobx/hooks.d.ts +6 -25
- package/.out/core/mobx/hooks.js +14 -50
- package/.out/core/mobx/merge_field_adapters_with_validators.js +1 -5
- package/.out/core/mobx/specs/fixtures.js +2 -1
- package/.out/core/mobx/specs/{form_presenter.tests.js → form_model.tests.js} +52 -43
- package/.out/core/mobx/specs/sub_form_field_adapters.tests.js +2 -1
- package/.out/core/mobx/types.d.ts +4 -4
- package/.out/field_converters/integer_to_string_converter.js +12 -4
- package/.out/field_converters/maybe_identity_converter.js +12 -4
- package/.out/field_converters/nullable_to_boolean_converter.js +24 -7
- package/.out/field_converters/select_value_type_converter.js +36 -12
- package/.out/index.d.ts +1 -1
- package/.out/index.js +1 -1
- package/.out/mantine/create_checkbox.js +8 -4
- package/.out/mantine/create_fields_view.js +7 -4
- package/.out/mantine/create_form.js +1 -1
- package/.out/mantine/create_radio_group.js +8 -4
- package/.out/mantine/create_text_input.js +8 -4
- package/.out/mantine/create_value_input.js +8 -4
- package/.out/mantine/hooks.js +218 -92
- package/.out/mantine/specs/checkbox_hooks.stories.js +13 -1
- package/.out/mantine/specs/checkbox_hooks.tests.js +22 -9
- package/.out/mantine/specs/fields_view_hooks.stories.js +15 -2
- package/.out/mantine/specs/fields_view_hooks.tests.js +12 -3
- package/.out/mantine/specs/radio_group_hooks.stories.js +13 -1
- package/.out/mantine/specs/radio_group_hooks.tests.js +23 -10
- package/.out/mantine/specs/select_hooks.stories.js +13 -1
- package/.out/mantine/specs/text_input_hooks.stories.js +13 -1
- package/.out/mantine/specs/text_input_hooks.tests.js +18 -7
- package/.out/mantine/specs/value_input_hooks.stories.js +14 -2
- package/.out/tsconfig.tsbuildinfo +1 -1
- package/.out/tsup.config.js +2 -9
- package/.out/types/merge_validators.js +1 -4
- package/.out/util/partial.js +5 -5
- package/.out/vitest.workspace.js +2 -10
- 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/core/mobx/{form_presenter.ts → form_model.ts} +287 -329
- package/core/mobx/hooks.tsx +26 -123
- package/core/mobx/specs/{form_presenter.tests.ts → form_model.tests.ts} +101 -94
- package/core/mobx/types.ts +12 -12
- package/dist/index.cjs +639 -600
- package/dist/index.d.cts +51 -73
- package/dist/index.d.ts +51 -73
- package/dist/index.js +644 -601
- package/index.ts +1 -1
- package/mantine/hooks.tsx +2 -0
- package/package.json +1 -1
- package/.out/core/mobx/form_presenter.js +0 -422
- /package/.out/core/mobx/specs/{form_presenter.tests.d.ts → form_model.tests.d.ts} +0 -0
package/.out/core/mobx/hooks.js
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
|
-
import { useCallback,
|
|
2
|
-
|
|
3
|
-
export function useDefaultMobxFormHooks(presenter, value, { onValidFieldSubmit, onValidFormSubmit, FormFieldsView, } = {}) {
|
|
4
|
-
const model = useMemo(function () {
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
6
|
-
return presenter.createModel(value);
|
|
7
|
-
}, [
|
|
8
|
-
presenter,
|
|
9
|
-
value,
|
|
10
|
-
]);
|
|
1
|
+
import { useCallback, } from 'react';
|
|
2
|
+
export function useDefaultMobxFormHooks(model, { onValidFieldSubmit, onValidFormSubmit, } = {}) {
|
|
11
3
|
const onFieldValueChange = useCallback(function (path, value) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
model,
|
|
17
|
-
]);
|
|
4
|
+
// TODO do in one action
|
|
5
|
+
model.clearFieldError(path);
|
|
6
|
+
model.setFieldValue(path, value);
|
|
7
|
+
}, [model]);
|
|
18
8
|
const onFieldSubmit = useCallback(function (valuePath) {
|
|
19
|
-
if (
|
|
20
|
-
onValidFieldSubmit
|
|
9
|
+
if (model.validateField(valuePath)) {
|
|
10
|
+
onValidFieldSubmit === null || onValidFieldSubmit === void 0 ? void 0 : onValidFieldSubmit(valuePath);
|
|
21
11
|
}
|
|
22
12
|
return false;
|
|
23
13
|
}, [
|
|
24
|
-
presenter,
|
|
25
14
|
model,
|
|
26
15
|
onValidFieldSubmit,
|
|
27
16
|
]);
|
|
@@ -30,49 +19,24 @@ export function useDefaultMobxFormHooks(presenter, value, { onValidFieldSubmit,
|
|
|
30
19
|
// (e.g. changing a discriminator)
|
|
31
20
|
// TODO debounce?
|
|
32
21
|
setTimeout(function () {
|
|
33
|
-
if (
|
|
34
|
-
|
|
22
|
+
if (model.isValuePathActive(path)) {
|
|
23
|
+
model.validateField(path, true);
|
|
35
24
|
}
|
|
36
25
|
}, 100);
|
|
37
|
-
}, [
|
|
38
|
-
presenter,
|
|
39
|
-
model,
|
|
40
|
-
]);
|
|
26
|
+
}, [model]);
|
|
41
27
|
const onFormSubmit = useCallback(function () {
|
|
42
|
-
if (
|
|
43
|
-
onValidFormSubmit
|
|
28
|
+
if (model.validateAll()) {
|
|
29
|
+
onValidFormSubmit === null || onValidFormSubmit === void 0 ? void 0 : onValidFormSubmit(model.value);
|
|
44
30
|
}
|
|
45
31
|
}, [
|
|
46
|
-
presenter,
|
|
47
32
|
model,
|
|
48
33
|
onValidFormSubmit,
|
|
49
34
|
]);
|
|
50
|
-
|
|
51
|
-
if (FormFieldsView == null) {
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
return createUnsafePartialObserverComponent(FormFieldsView, () => {
|
|
55
|
-
return {
|
|
56
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
57
|
-
fields: model.fields,
|
|
58
|
-
onFieldBlur,
|
|
59
|
-
onFieldSubmit,
|
|
60
|
-
onFieldValueChange,
|
|
61
|
-
};
|
|
62
|
-
});
|
|
63
|
-
}, [
|
|
64
|
-
model,
|
|
65
|
-
FormFieldsView,
|
|
66
|
-
onFieldBlur,
|
|
67
|
-
onFieldSubmit,
|
|
68
|
-
onFieldValueChange,
|
|
69
|
-
]);
|
|
35
|
+
// TODO have option to automatically bind all these callbacks to a FieldsView parameter
|
|
70
36
|
return {
|
|
71
|
-
model,
|
|
72
37
|
onFieldValueChange,
|
|
73
38
|
onFieldSubmit,
|
|
74
39
|
onFieldBlur,
|
|
75
40
|
onFormSubmit,
|
|
76
|
-
FormFields,
|
|
77
41
|
};
|
|
78
42
|
}
|
|
@@ -35,11 +35,7 @@ export function mergeAdaptersWithValidators(adapters, validators) {
|
|
|
35
35
|
readonly: readonly1 || readonly2,
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
acc[key] = {
|
|
39
|
-
...adapter,
|
|
40
|
-
convert,
|
|
41
|
-
revert: adapter.revert && revert,
|
|
42
|
-
};
|
|
38
|
+
acc[key] = Object.assign(Object.assign({}, adapter), { convert, revert: adapter.revert && revert });
|
|
43
39
|
return acc;
|
|
44
40
|
}, {});
|
|
45
41
|
}
|
|
@@ -3,9 +3,10 @@ export function createMockedAdapter(_original) {
|
|
|
3
3
|
return mock();
|
|
4
4
|
}
|
|
5
5
|
export function resetMockAdapter({ convert, revert, create, }, mockedAdapter) {
|
|
6
|
+
var _a;
|
|
6
7
|
mockReset(mockedAdapter);
|
|
7
8
|
if (revert) {
|
|
8
|
-
mockedAdapter.revert
|
|
9
|
+
(_a = mockedAdapter.revert) === null || _a === void 0 ? void 0 : _a.mockImplementation(revert);
|
|
9
10
|
}
|
|
10
11
|
mockedAdapter.convert.mockImplementation(convert);
|
|
11
12
|
mockedAdapter.create.mockImplementation(create);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { expectDefinedAndReturn } from '@strictly/base';
|
|
2
2
|
import { booleanType, list, nullType, numberType, object, record, stringType, union, } from '@strictly/define';
|
|
3
3
|
import { adapterFromTwoWayConverter, identityAdapter, } from 'core/mobx/field_adapter_builder';
|
|
4
|
-
import { FormModel,
|
|
4
|
+
import { FormModel, } from 'core/mobx/form_model';
|
|
5
5
|
import { IntegerToStringConverter } from 'field_converters/integer_to_string_converter';
|
|
6
6
|
import { NullableToBooleanConverter } from 'field_converters/nullable_to_boolean_converter';
|
|
7
7
|
import { SelectDiscriminatedUnionConverter } from 'field_converters/select_value_type_converter';
|
|
@@ -9,11 +9,6 @@ import { prototypingFieldValueFactory } from 'field_value_factories/prototyping_
|
|
|
9
9
|
import { UnreliableFieldConversionType, } from 'types/field_converters';
|
|
10
10
|
import { createMockedAdapter, resetMockAdapter, } from './fixtures';
|
|
11
11
|
const IS_NAN_ERROR = 1;
|
|
12
|
-
class TestFormPresenter extends FormPresenter {
|
|
13
|
-
createModel(value) {
|
|
14
|
-
return new FormModel(this.type, value, this.adapters);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
12
|
const originalIntegerToStringAdapter = adapterFromTwoWayConverter(new IntegerToStringConverter(IS_NAN_ERROR), prototypingFieldValueFactory(0));
|
|
18
13
|
const originalBooleanToBooleanAdapter = identityAdapter(false);
|
|
19
14
|
describe('all', function () {
|
|
@@ -285,22 +280,21 @@ describe('all', function () {
|
|
|
285
280
|
});
|
|
286
281
|
// TODO union
|
|
287
282
|
});
|
|
288
|
-
describe('
|
|
283
|
+
describe('FormModel', function () {
|
|
289
284
|
describe('literal', function () {
|
|
290
285
|
const typeDef = numberType;
|
|
291
286
|
const adapters = {
|
|
292
287
|
$: integerToStringAdapter,
|
|
293
288
|
};
|
|
294
|
-
const presenter = new TestFormPresenter(typeDef, adapters);
|
|
295
289
|
const originalValue = 2;
|
|
296
290
|
let model;
|
|
297
291
|
beforeEach(function () {
|
|
298
|
-
model =
|
|
292
|
+
model = new FormModel(typeDef, originalValue, adapters);
|
|
299
293
|
});
|
|
300
294
|
describe('setFieldValueAndValidate', function () {
|
|
301
295
|
describe('success', function () {
|
|
302
296
|
beforeEach(function () {
|
|
303
|
-
|
|
297
|
+
model.setFieldValueAndValidate('$', '1');
|
|
304
298
|
});
|
|
305
299
|
it('does set the underlying value', function () {
|
|
306
300
|
expect(model.value).toEqual(1);
|
|
@@ -317,7 +311,7 @@ describe('all', function () {
|
|
|
317
311
|
describe('failure', function () {
|
|
318
312
|
describe('conversion fails', function () {
|
|
319
313
|
beforeEach(function () {
|
|
320
|
-
|
|
314
|
+
model.setFieldValueAndValidate('$', 'x');
|
|
321
315
|
});
|
|
322
316
|
it('does not set the underlying value', function () {
|
|
323
317
|
expect(model.value).toEqual(originalValue);
|
|
@@ -335,12 +329,13 @@ describe('all', function () {
|
|
|
335
329
|
const newValue = -1;
|
|
336
330
|
const errorCode = 65;
|
|
337
331
|
beforeEach(function () {
|
|
338
|
-
|
|
332
|
+
var _a;
|
|
333
|
+
(_a = integerToStringAdapter.revert) === null || _a === void 0 ? void 0 : _a.mockReturnValueOnce({
|
|
339
334
|
type: UnreliableFieldConversionType.Failure,
|
|
340
335
|
error: errorCode,
|
|
341
336
|
value: [newValue],
|
|
342
337
|
});
|
|
343
|
-
|
|
338
|
+
model.setFieldValueAndValidate('$', '-1');
|
|
344
339
|
});
|
|
345
340
|
it('does set the underlying value', function () {
|
|
346
341
|
expect(model.value).toEqual(newValue);
|
|
@@ -368,7 +363,7 @@ describe('all', function () {
|
|
|
368
363
|
],
|
|
369
364
|
])('setFieldValue to %s', function (newValue, expectedValue) {
|
|
370
365
|
beforeEach(function () {
|
|
371
|
-
|
|
366
|
+
model.setFieldValue('$', newValue);
|
|
372
367
|
});
|
|
373
368
|
it('does set the underlying value', function () {
|
|
374
369
|
expect(model.value).toEqual(expectedValue);
|
|
@@ -388,7 +383,6 @@ describe('all', function () {
|
|
|
388
383
|
const converters = {
|
|
389
384
|
'$.*': integerToStringAdapter,
|
|
390
385
|
};
|
|
391
|
-
const presenter = new TestFormPresenter(typeDef, converters);
|
|
392
386
|
let originalValue;
|
|
393
387
|
let model;
|
|
394
388
|
beforeEach(function () {
|
|
@@ -397,12 +391,12 @@ describe('all', function () {
|
|
|
397
391
|
3,
|
|
398
392
|
7,
|
|
399
393
|
];
|
|
400
|
-
model =
|
|
394
|
+
model = new FormModel(typeDef, originalValue, converters);
|
|
401
395
|
});
|
|
402
396
|
describe('setFieldValueAndValidate', function () {
|
|
403
397
|
describe('success', function () {
|
|
404
398
|
beforeEach(function () {
|
|
405
|
-
|
|
399
|
+
model.setFieldValueAndValidate('$.0', '100');
|
|
406
400
|
});
|
|
407
401
|
it('sets the underlying value', function () {
|
|
408
402
|
expect(model.value).toEqual([
|
|
@@ -422,7 +416,7 @@ describe('all', function () {
|
|
|
422
416
|
});
|
|
423
417
|
describe('failure', function () {
|
|
424
418
|
beforeEach(function () {
|
|
425
|
-
|
|
419
|
+
model.setFieldValueAndValidate('$.0', 'x');
|
|
426
420
|
});
|
|
427
421
|
it('does not set the underlying value', function () {
|
|
428
422
|
expect(model.value).toEqual(originalValue);
|
|
@@ -442,7 +436,7 @@ describe('all', function () {
|
|
|
442
436
|
'x',
|
|
443
437
|
])('setFieldValue to %s', function (newValue) {
|
|
444
438
|
beforeEach(function () {
|
|
445
|
-
|
|
439
|
+
model.setFieldValue('$.0', newValue);
|
|
446
440
|
});
|
|
447
441
|
it('does not set the underlying value', function () {
|
|
448
442
|
expect(model.value).toEqual(originalValue);
|
|
@@ -458,10 +452,10 @@ describe('all', function () {
|
|
|
458
452
|
});
|
|
459
453
|
describe('validate', function () {
|
|
460
454
|
beforeEach(function () {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
455
|
+
model.setFieldValue('$.0', 'x');
|
|
456
|
+
model.setFieldValue('$.1', '2');
|
|
457
|
+
model.setFieldValue('$.2', 'z');
|
|
458
|
+
model.validateAll();
|
|
465
459
|
});
|
|
466
460
|
it('contains errors for all invalid fields', function () {
|
|
467
461
|
expect(model.fields).toEqual(expect.objectContaining({
|
|
@@ -500,7 +494,7 @@ describe('all', function () {
|
|
|
500
494
|
});
|
|
501
495
|
});
|
|
502
496
|
it('supplies the full, previous context when converting', function () {
|
|
503
|
-
|
|
497
|
+
model.setFieldValueAndValidate('$.2', '4');
|
|
504
498
|
expect(integerToStringAdapter.revert).toHaveBeenCalledOnce();
|
|
505
499
|
expect(integerToStringAdapter.revert).toHaveBeenCalledWith('4', '$.2',
|
|
506
500
|
// uses the same pointer
|
|
@@ -520,7 +514,7 @@ describe('all', function () {
|
|
|
520
514
|
model.errors['$.0'] = 0;
|
|
521
515
|
model.errors['$.1'] = 1;
|
|
522
516
|
model.errors['$.2'] = 2;
|
|
523
|
-
|
|
517
|
+
model.addListItem('$', null, 0);
|
|
524
518
|
});
|
|
525
519
|
it('adds the list item to the underlying value', function () {
|
|
526
520
|
expect(model.value).toEqual([
|
|
@@ -548,7 +542,8 @@ describe('all', function () {
|
|
|
548
542
|
'7',
|
|
549
543
|
],
|
|
550
544
|
])('it reports the value of field %s as %s', function (path, fieldValue) {
|
|
551
|
-
|
|
545
|
+
var _a;
|
|
546
|
+
expect((_a = model.fields[path]) === null || _a === void 0 ? void 0 : _a.value).toBe(fieldValue);
|
|
552
547
|
});
|
|
553
548
|
it.each([
|
|
554
549
|
[
|
|
@@ -568,12 +563,13 @@ describe('all', function () {
|
|
|
568
563
|
2,
|
|
569
564
|
],
|
|
570
565
|
])('it reports the error of field %s', function (path, error) {
|
|
571
|
-
|
|
566
|
+
var _a;
|
|
567
|
+
expect((_a = model.fields[path]) === null || _a === void 0 ? void 0 : _a.error).toBe(error);
|
|
572
568
|
});
|
|
573
569
|
});
|
|
574
570
|
describe('add defined value', function () {
|
|
575
571
|
beforeEach(function () {
|
|
576
|
-
|
|
572
|
+
model.addListItem('$', [5]);
|
|
577
573
|
});
|
|
578
574
|
it('adds the expected value at the end', function () {
|
|
579
575
|
expect(model.fields).toEqual(expect.objectContaining({
|
|
@@ -609,7 +605,7 @@ describe('all', function () {
|
|
|
609
605
|
});
|
|
610
606
|
describe('remove first item', function () {
|
|
611
607
|
beforeEach(function () {
|
|
612
|
-
|
|
608
|
+
model.removeListItem('$.0');
|
|
613
609
|
});
|
|
614
610
|
it('updates the underlying value', function () {
|
|
615
611
|
expect(model.value).toEqual([
|
|
@@ -632,7 +628,7 @@ describe('all', function () {
|
|
|
632
628
|
});
|
|
633
629
|
describe('remove second item', function () {
|
|
634
630
|
beforeEach(function () {
|
|
635
|
-
|
|
631
|
+
model.removeListItem('$.1');
|
|
636
632
|
});
|
|
637
633
|
it('updates the underlying value', function () {
|
|
638
634
|
expect(model.value).toEqual([
|
|
@@ -653,6 +649,22 @@ describe('all', function () {
|
|
|
653
649
|
});
|
|
654
650
|
});
|
|
655
651
|
});
|
|
652
|
+
describe('remove two items', function () {
|
|
653
|
+
beforeEach(function () {
|
|
654
|
+
model.removeListItem('$.0', '$.1');
|
|
655
|
+
});
|
|
656
|
+
it('updates the underlying value', function () {
|
|
657
|
+
expect(model.value).toEqual([7]);
|
|
658
|
+
});
|
|
659
|
+
it('updates the field values and errors', function () {
|
|
660
|
+
expect(model.fields).toEqual({
|
|
661
|
+
'$.0': expect.objectContaining({
|
|
662
|
+
value: '7',
|
|
663
|
+
error: 2,
|
|
664
|
+
}),
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
});
|
|
656
668
|
});
|
|
657
669
|
});
|
|
658
670
|
// TODO record / object
|
|
@@ -666,12 +678,11 @@ describe('all', function () {
|
|
|
666
678
|
$: adapterFromTwoWayConverter(new NullableToBooleanConverter(type, [1], null)),
|
|
667
679
|
'$.*': integerToStringAdapter,
|
|
668
680
|
};
|
|
669
|
-
const presenter = new TestFormPresenter(type, adapters);
|
|
670
681
|
let originalValue;
|
|
671
682
|
let model;
|
|
672
683
|
beforeEach(function () {
|
|
673
684
|
originalValue = null;
|
|
674
|
-
model =
|
|
685
|
+
model = new FormModel(type, originalValue, adapters);
|
|
675
686
|
});
|
|
676
687
|
it('has the expected fields', function () {
|
|
677
688
|
expect(model.fields).toEqual({
|
|
@@ -686,7 +697,7 @@ describe('all', function () {
|
|
|
686
697
|
describe('setFieldValueAndValidate', function () {
|
|
687
698
|
describe('success', function () {
|
|
688
699
|
beforeEach(function () {
|
|
689
|
-
|
|
700
|
+
model.setFieldValueAndValidate('$', true);
|
|
690
701
|
});
|
|
691
702
|
it('sets the underlying value', function () {
|
|
692
703
|
expect(model.value).toEqual([1]);
|
|
@@ -714,13 +725,12 @@ describe('all', function () {
|
|
|
714
725
|
'$.x:a': identityAdapter(0).narrow,
|
|
715
726
|
'$.y:b': identityAdapter(false).narrow,
|
|
716
727
|
};
|
|
717
|
-
const presenter = new TestFormPresenter(type, adapters);
|
|
718
728
|
describe('isValuePathActive', function () {
|
|
719
729
|
describe('discriminator x', function () {
|
|
720
|
-
const model =
|
|
730
|
+
const model = new FormModel(type, {
|
|
721
731
|
d: 'x',
|
|
722
732
|
a: 1,
|
|
723
|
-
});
|
|
733
|
+
}, adapters);
|
|
724
734
|
it.each([
|
|
725
735
|
[
|
|
726
736
|
'$',
|
|
@@ -735,15 +745,15 @@ describe('all', function () {
|
|
|
735
745
|
false,
|
|
736
746
|
],
|
|
737
747
|
])('value path %s is active %s', function (path, expected) {
|
|
738
|
-
const isValid =
|
|
748
|
+
const isValid = model.isValuePathActive(path);
|
|
739
749
|
expect(isValid).toBe(expected);
|
|
740
750
|
});
|
|
741
751
|
});
|
|
742
752
|
describe('discriminator y', function () {
|
|
743
|
-
const model =
|
|
753
|
+
const model = new FormModel(type, {
|
|
744
754
|
d: 'y',
|
|
745
755
|
b: false,
|
|
746
|
-
});
|
|
756
|
+
}, adapters);
|
|
747
757
|
it.each([
|
|
748
758
|
[
|
|
749
759
|
'$',
|
|
@@ -758,7 +768,7 @@ describe('all', function () {
|
|
|
758
768
|
true,
|
|
759
769
|
],
|
|
760
770
|
])('value path %s is active %s', function (path, expected) {
|
|
761
|
-
const isValid =
|
|
771
|
+
const isValid = model.isValuePathActive(path);
|
|
762
772
|
expect(isValid).toBe(expected);
|
|
763
773
|
});
|
|
764
774
|
});
|
|
@@ -771,12 +781,11 @@ describe('all', function () {
|
|
|
771
781
|
$: integerToStringAdapter,
|
|
772
782
|
'$.fake': booleanToBooleanAdapter,
|
|
773
783
|
};
|
|
774
|
-
const presenter = new TestFormPresenter(typeDef, converters);
|
|
775
784
|
let originalValue;
|
|
776
785
|
let model;
|
|
777
786
|
beforeEach(function () {
|
|
778
787
|
originalValue = 1;
|
|
779
|
-
model =
|
|
788
|
+
model = new FormModel(typeDef, originalValue, converters);
|
|
780
789
|
});
|
|
781
790
|
it('returns the default value for the fake field', function () {
|
|
782
791
|
expect(model.fields['$.fake']).toEqual(expect.objectContaining({
|
|
@@ -785,7 +794,7 @@ describe('all', function () {
|
|
|
785
794
|
});
|
|
786
795
|
describe('setting fake field', function () {
|
|
787
796
|
beforeEach(function () {
|
|
788
|
-
|
|
797
|
+
model.setFieldValue('$.fake', true);
|
|
789
798
|
});
|
|
790
799
|
it('stores the new value', function () {
|
|
791
800
|
expect(model.fields['$.fake']).toEqual(expect.objectContaining({
|
|
@@ -43,12 +43,13 @@ describe('subFormFieldAdapters', () => {
|
|
|
43
43
|
expect(returnedValue).toEqual(mockedReturnedValue);
|
|
44
44
|
});
|
|
45
45
|
it('calls revert with the correct paths and values', () => {
|
|
46
|
+
var _a, _b;
|
|
46
47
|
const mockedReturnedValue = {
|
|
47
48
|
type: UnreliableFieldConversionType.Success,
|
|
48
49
|
value: 'ok',
|
|
49
50
|
};
|
|
50
51
|
mockedFieldAdapter1.revert.mockReturnValue(mockedReturnedValue);
|
|
51
|
-
const returnedValue = adapters['$.a'].revert
|
|
52
|
+
const returnedValue = (_b = (_a = adapters['$.a']).revert) === null || _b === void 0 ? void 0 : _b.call(_a, true, '$.a', { a: 'y' });
|
|
52
53
|
expect(fieldAdapter1.revert).toHaveBeenCalledWith(true, '$', 'y');
|
|
53
54
|
expect(returnedValue).toEqual(mockedReturnedValue);
|
|
54
55
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { type ToOfFieldAdapter } from './field_adapter';
|
|
2
|
-
import { type FlattenedConvertedFieldsOf, type
|
|
2
|
+
import { type FlattenedConvertedFieldsOf, type FormModel } from './form_model';
|
|
3
3
|
/**
|
|
4
4
|
* Used to extract the supported value paths from a presenter
|
|
5
5
|
*/
|
|
6
|
-
export type
|
|
6
|
+
export type ValuePathsOfModel<Presenter extends FormModel<any, any, any, any>> = Presenter extends FormModel<infer _1, infer _2, infer _3, infer ValuePathsToAdapters> ? keyof ValuePathsToAdapters : never;
|
|
7
7
|
/**
|
|
8
8
|
* Used to extract the render type (so the value that is passed to the view) of a given value path
|
|
9
9
|
* from a presenter
|
|
10
10
|
*/
|
|
11
|
-
export type
|
|
11
|
+
export type ToValueOfModelValuePath<Presenter extends FormModel<any, any, any, any>, K extends ValuePathsOfModel<Presenter>> = Presenter extends FormModel<infer _1, infer _2, infer _3, infer ValuePathsToAdapters> ? ToOfFieldAdapter<ValuePathsToAdapters[K]> : never;
|
|
12
12
|
/**
|
|
13
13
|
* Extracts the form fields from the presenter. The recommended way is to
|
|
14
14
|
* define the form fields explicitly and use that type to enforce the types
|
|
@@ -16,4 +16,4 @@ export type ToValueOfPresenterValuePath<Presenter extends FormPresenter<any, any
|
|
|
16
16
|
* is less typing, albeit at the cost of potentially getting type errors
|
|
17
17
|
* reported a long way away from the source
|
|
18
18
|
*/
|
|
19
|
-
export type
|
|
19
|
+
export type FormFieldsOfModel<Presenter extends FormModel<any, any, any, any>> = Presenter extends FormModel<infer _1, infer _2, infer _3, infer ValuePathsToAdapters> ? FlattenedConvertedFieldsOf<ValuePathsToAdapters> : never;
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { UnreliableFieldConversionType, } from 'types/field_converters';
|
|
2
2
|
export class IntegerToStringConverter {
|
|
3
|
-
isNanError;
|
|
4
|
-
base;
|
|
5
3
|
constructor(isNanError, base = 10) {
|
|
6
|
-
this
|
|
7
|
-
|
|
4
|
+
Object.defineProperty(this, "isNanError", {
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true,
|
|
8
|
+
value: isNanError
|
|
9
|
+
});
|
|
10
|
+
Object.defineProperty(this, "base", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
writable: true,
|
|
14
|
+
value: base
|
|
15
|
+
});
|
|
8
16
|
}
|
|
9
17
|
convert(from) {
|
|
10
18
|
const value = Math.floor(from).toString();
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
export class MaybeIdentityConverter {
|
|
2
|
-
converter;
|
|
3
|
-
isFrom;
|
|
4
2
|
constructor(converter, isFrom) {
|
|
5
|
-
this
|
|
6
|
-
|
|
3
|
+
Object.defineProperty(this, "converter", {
|
|
4
|
+
enumerable: true,
|
|
5
|
+
configurable: true,
|
|
6
|
+
writable: true,
|
|
7
|
+
value: converter
|
|
8
|
+
});
|
|
9
|
+
Object.defineProperty(this, "isFrom", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
writable: true,
|
|
13
|
+
value: isFrom
|
|
14
|
+
});
|
|
7
15
|
}
|
|
8
16
|
convert(from, valuePath, context) {
|
|
9
17
|
return this.converter.convert(from, valuePath, context);
|
|
@@ -1,14 +1,31 @@
|
|
|
1
1
|
import { copy, } from '@strictly/define';
|
|
2
2
|
import { UnreliableFieldConversionType, } from 'types/field_converters';
|
|
3
3
|
export class NullableToBooleanConverter {
|
|
4
|
-
typeDef;
|
|
5
|
-
prototype;
|
|
6
|
-
nullType;
|
|
7
|
-
defaultValue;
|
|
8
4
|
constructor(typeDef, prototype, nullType, defaultToNull = true) {
|
|
9
|
-
this
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
Object.defineProperty(this, "typeDef", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true,
|
|
9
|
+
value: typeDef
|
|
10
|
+
});
|
|
11
|
+
Object.defineProperty(this, "prototype", {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
writable: true,
|
|
15
|
+
value: prototype
|
|
16
|
+
});
|
|
17
|
+
Object.defineProperty(this, "nullType", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: nullType
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(this, "defaultValue", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
12
29
|
this.defaultValue = defaultToNull ? this.nullType : prototype;
|
|
13
30
|
}
|
|
14
31
|
convert(from) {
|
|
@@ -2,17 +2,37 @@ import { reverse, } from '@strictly/base';
|
|
|
2
2
|
import { copy, } from '@strictly/define';
|
|
3
3
|
import { UnreliableFieldConversionType, } from 'types/field_converters';
|
|
4
4
|
export class AbstractSelectValueTypeConverter {
|
|
5
|
-
typeDef;
|
|
6
|
-
values;
|
|
7
|
-
defaultValueKey;
|
|
8
|
-
noSuchValueError;
|
|
9
|
-
required;
|
|
10
5
|
constructor(typeDef, values, defaultValueKey, noSuchValueError, required) {
|
|
11
|
-
this
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
Object.defineProperty(this, "typeDef", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
writable: true,
|
|
10
|
+
value: typeDef
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(this, "values", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: values
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(this, "defaultValueKey", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
writable: true,
|
|
22
|
+
value: defaultValueKey
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(this, "noSuchValueError", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
writable: true,
|
|
28
|
+
value: noSuchValueError
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(this, "required", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: required
|
|
35
|
+
});
|
|
16
36
|
}
|
|
17
37
|
revert(from) {
|
|
18
38
|
const prototype = from == null ? null : this.values[from];
|
|
@@ -53,10 +73,14 @@ export class SelectDiscriminatedUnionConverter extends AbstractSelectValueTypeCo
|
|
|
53
73
|
}
|
|
54
74
|
}
|
|
55
75
|
export class SelectLiteralConverter extends AbstractSelectValueTypeConverter {
|
|
56
|
-
valuesToStrings;
|
|
57
76
|
constructor(typeDef, valuesToStrings, defaultValue, noSuchValueError, required) {
|
|
58
77
|
super(typeDef, reverse(valuesToStrings), defaultValue && valuesToStrings[defaultValue], noSuchValueError, required);
|
|
59
|
-
this
|
|
78
|
+
Object.defineProperty(this, "valuesToStrings", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
configurable: true,
|
|
81
|
+
writable: true,
|
|
82
|
+
value: valuesToStrings
|
|
83
|
+
});
|
|
60
84
|
}
|
|
61
85
|
doConvert(from) {
|
|
62
86
|
return this.valuesToStrings[from];
|
package/.out/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from './core/mobx/field_adapter_builder';
|
|
|
3
3
|
export * from './core/mobx/field_adapters_of_values';
|
|
4
4
|
export * from './core/mobx/flattened_adapters_of_fields';
|
|
5
5
|
export * from './core/mobx/form_fields_of_field_adapters';
|
|
6
|
-
export * from './core/mobx/
|
|
6
|
+
export * from './core/mobx/form_model';
|
|
7
7
|
export * from './core/mobx/hooks';
|
|
8
8
|
export * from './core/mobx/merge_field_adapters_with_two_way_converter';
|
|
9
9
|
export * from './core/mobx/merge_field_adapters_with_validators';
|
package/.out/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export * from './core/mobx/field_adapter_builder';
|
|
|
3
3
|
export * from './core/mobx/field_adapters_of_values';
|
|
4
4
|
export * from './core/mobx/flattened_adapters_of_fields';
|
|
5
5
|
export * from './core/mobx/form_fields_of_field_adapters';
|
|
6
|
-
export * from './core/mobx/
|
|
6
|
+
export * from './core/mobx/form_model';
|
|
7
7
|
export * from './core/mobx/hooks';
|
|
8
8
|
export * from './core/mobx/merge_field_adapters_with_two_way_converter';
|
|
9
9
|
export * from './core/mobx/merge_field_adapters_with_validators';
|