@abgov/jsonforms-components 0.0.1 → 1.2.0
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/index.esm.d.ts +1 -0
- package/index.esm.js +4831 -0
- package/package.json +8 -2
- package/src/index.d.ts +5 -0
- package/src/lib/Additional/HelpContent.d.ts +21 -0
- package/src/lib/Additional/styled-components.d.ts +1 -0
- package/src/lib/Cells/DateCell.d.ts +6 -0
- package/src/lib/Cells/IntegerCell.d.ts +6 -0
- package/src/lib/Cells/NumberCell.d.ts +6 -0
- package/src/lib/Cells/TextCell.d.ts +6 -0
- package/src/lib/Cells/TimeCell.d.ts +6 -0
- package/src/lib/Cells/index.d.ts +2 -0
- package/src/lib/Context/index.d.ts +39 -0
- package/src/lib/Controls/FileUploader/ContextMenu.d.ts +18 -0
- package/src/lib/Controls/FileUploader/FileUploaderControl.d.ts +4 -0
- package/src/lib/Controls/FileUploader/FileUploaderTester.d.ts +2 -0
- package/src/lib/Controls/FileUploader/styled-components.d.ts +1 -0
- package/src/lib/Controls/FormStepper/FormStepperControl.d.ts +14 -0
- package/src/lib/Controls/FormStepper/FormStepperTester.d.ts +2 -0
- package/src/lib/Controls/FormStepper/styled-components.d.ts +7 -0
- package/src/lib/Controls/Inputs/InputBaseControl.d.ts +7 -0
- package/src/lib/Controls/Inputs/InputBooleanControl.d.ts +6 -0
- package/src/lib/Controls/Inputs/InputBooleanRadioControl.d.ts +6 -0
- package/src/lib/Controls/Inputs/InputDateControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputDateTimeControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputEnum.d.ts +12 -0
- package/src/lib/Controls/Inputs/InputEnumAutoComplete.d.ts +10 -0
- package/src/lib/Controls/Inputs/InputEnumRadios.d.ts +12 -0
- package/src/lib/Controls/Inputs/InputIntegerControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputMultiLineTextControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputNumberControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputTextControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/InputTimeControl.d.ts +9 -0
- package/src/lib/Controls/Inputs/{type.ts → type.d.ts} +1 -1
- package/src/lib/Controls/ObjectArray/DeleteDialog.d.ts +12 -0
- package/src/lib/Controls/ObjectArray/ObjectArray.d.ts +6 -0
- package/src/lib/Controls/ObjectArray/ObjectArrayToolBar.d.ts +16 -0
- package/src/lib/Controls/ObjectArray/ObjectListControl.d.ts +24 -0
- package/src/lib/Controls/ObjectArray/styled-components.d.ts +3 -0
- package/src/lib/ErrorHandling/GoAErrorControl.d.ts +15 -0
- package/src/lib/ErrorHandling/{MessageControl.tsx → MessageControl.d.ts} +1 -8
- package/src/lib/ErrorHandling/errorCheck.d.ts +14 -0
- package/src/lib/ErrorHandling/schemaValidation.d.ts +11 -0
- package/src/lib/common/Grid.d.ts +11 -0
- package/src/lib/jsonforms-components.d.ts +4 -0
- package/src/lib/layouts/GroupControl.d.ts +5 -0
- package/src/lib/layouts/HorizontalLayoutControl.d.ts +5 -0
- package/src/lib/layouts/VerticalLayoutControl.d.ts +4 -0
- package/src/lib/util/layout.d.ts +8 -0
- package/src/lib/util/schemaUtils.d.ts +1 -0
- package/src/lib/util/stringUtils.d.ts +33 -0
- package/src/lib/util/style-component.d.ts +1 -0
- package/.babelrc +0 -12
- package/.eslintrc.json +0 -36
- package/.releaserc.json +0 -25
- package/jest.config.ts +0 -11
- package/project.json +0 -55
- package/rollup.config.js +0 -14
- package/src/index.ts +0 -166
- package/src/lib/Additional/HelpContent.tsx +0 -95
- package/src/lib/Additional/styled-components.ts +0 -27
- package/src/lib/Cells/DateCell.tsx +0 -10
- package/src/lib/Cells/IntegerCell.tsx +0 -10
- package/src/lib/Cells/NumberCell.tsx +0 -10
- package/src/lib/Cells/TextCell.tsx +0 -10
- package/src/lib/Cells/TimeCell.tsx +0 -10
- package/src/lib/Cells/index.tsx +0 -14
- package/src/lib/Context/index.tsx +0 -172
- package/src/lib/Controls/FileUploader/ContextMenu.tsx +0 -50
- package/src/lib/Controls/FileUploader/FileUploaderControl.tsx +0 -131
- package/src/lib/Controls/FileUploader/FileUploaderTester.tsx +0 -3
- package/src/lib/Controls/FileUploader/styled-components.tsx +0 -10
- package/src/lib/Controls/FormStepper/FormStepperControl.tsx +0 -269
- package/src/lib/Controls/FormStepper/FormStepperTester.tsx +0 -22
- package/src/lib/Controls/FormStepper/styled-components.tsx +0 -17
- package/src/lib/Controls/Inputs/InputBaseControl.tsx +0 -52
- package/src/lib/Controls/Inputs/InputBooleanControl.tsx +0 -67
- package/src/lib/Controls/Inputs/InputBooleanRadioControl.tsx +0 -74
- package/src/lib/Controls/Inputs/InputDateControl.tsx +0 -90
- package/src/lib/Controls/Inputs/InputDateTimeControl.tsx +0 -46
- package/src/lib/Controls/Inputs/InputEnum.tsx +0 -74
- package/src/lib/Controls/Inputs/InputEnumAutoComplete.tsx +0 -73
- package/src/lib/Controls/Inputs/InputEnumRadios.tsx +0 -43
- package/src/lib/Controls/Inputs/InputIntegerControl.tsx +0 -63
- package/src/lib/Controls/Inputs/InputMultiLineTextControl.tsx +0 -63
- package/src/lib/Controls/Inputs/InputNumberControl.tsx +0 -63
- package/src/lib/Controls/Inputs/InputTextControl.tsx +0 -62
- package/src/lib/Controls/Inputs/InputTimeControl.tsx +0 -46
- package/src/lib/Controls/Inputs/inputControl.spec.ts +0 -84
- package/src/lib/Controls/ObjectArray/DeleteDialog.tsx +0 -49
- package/src/lib/Controls/ObjectArray/ObjectArray.tsx +0 -59
- package/src/lib/Controls/ObjectArray/ObjectArrayToolBar.tsx +0 -51
- package/src/lib/Controls/ObjectArray/ObjectListControl.tsx +0 -368
- package/src/lib/Controls/ObjectArray/styled-components.tsx +0 -13
- package/src/lib/ErrorHandling/GoAErrorControl.tsx +0 -53
- package/src/lib/ErrorHandling/categorizationValidation.spec.ts +0 -98
- package/src/lib/ErrorHandling/controlValildation.spec.ts +0 -57
- package/src/lib/ErrorHandling/errorCheck.spec.ts +0 -185
- package/src/lib/ErrorHandling/errorCheck.tsx +0 -86
- package/src/lib/ErrorHandling/layoutValildation.spec.ts +0 -47
- package/src/lib/ErrorHandling/otherValildation.spec.ts +0 -74
- package/src/lib/ErrorHandling/schemaValidation.ts +0 -115
- package/src/lib/common/Grid.tsx +0 -55
- package/src/lib/jsonforms-components.module.scss +0 -7
- package/src/lib/jsonforms-components.spec.tsx +0 -10
- package/src/lib/jsonforms-components.tsx +0 -14
- package/src/lib/layouts/GroupControl.tsx +0 -25
- package/src/lib/layouts/HorizontalLayoutControl.tsx +0 -30
- package/src/lib/layouts/VerticalLayoutControl.tsx +0 -28
- package/src/lib/util/layout.tsx +0 -68
- package/src/lib/util/schemaUtils.ts +0 -9
- package/src/lib/util/stringUtils.ts +0 -98
- package/src/lib/util/style-component.ts +0 -8
- package/tsconfig.json +0 -20
- package/tsconfig.lib.json +0 -19
- package/tsconfig.spec.json +0 -20
- /package/src/lib/Additional/{index.ts → index.d.ts} +0 -0
- /package/src/lib/Controls/FileUploader/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/Controls/FormStepper/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/Controls/Inputs/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/Controls/ObjectArray/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/Controls/{index.tsx → index.d.ts} +0 -0
- /package/src/lib/layouts/{index.ts → index.d.ts} +0 -0
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The error control is invoked whenever no other control can be found. It is used to display
|
|
3
|
-
* an error to the developers indicating that they have misconfigured one or more of their schemas and
|
|
4
|
-
* that they need to take a close look. It will attempt to provide information to guide the developer
|
|
5
|
-
* toward fixing the error.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { ControlProps, JsonSchema, RankedTester, rankWith } from '@jsonforms/core';
|
|
10
|
-
import { withJsonFormsControlProps } from '@jsonforms/react';
|
|
11
|
-
import { isNullSchema, isValidJsonObject } from './errorCheck';
|
|
12
|
-
import { getUISchemaErrors } from './schemaValidation';
|
|
13
|
-
import { MessageControl } from './MessageControl';
|
|
14
|
-
|
|
15
|
-
const isValidJsonSchema = (schema: JsonSchema): string | null => {
|
|
16
|
-
if (isNullSchema(schema)) {
|
|
17
|
-
return '';
|
|
18
|
-
}
|
|
19
|
-
if (!isValidJsonObject(schema)) {
|
|
20
|
-
return 'Unable to render: json schema is not valid.';
|
|
21
|
-
}
|
|
22
|
-
return null;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
// Some 'errors' need not be reported, but we want to handle them
|
|
26
|
-
// here. e.g. A layout with empty elements should be quietly ignored.
|
|
27
|
-
// this is handled by the errors !== '' check.
|
|
28
|
-
const ErrorControl = (props: ControlProps): JSX.Element => {
|
|
29
|
-
const { schema, uischema } = props;
|
|
30
|
-
// Report data schema errors over ui schema ones, as errors in the former
|
|
31
|
-
// can cause cascading errors in the latter.
|
|
32
|
-
const dataSchemaErrors = isValidJsonSchema(schema);
|
|
33
|
-
if (dataSchemaErrors && dataSchemaErrors !== '') {
|
|
34
|
-
return <p>{dataSchemaErrors}</p>;
|
|
35
|
-
}
|
|
36
|
-
const uiSchemaErrors = getUISchemaErrors(uischema, schema);
|
|
37
|
-
if (uiSchemaErrors && uiSchemaErrors !== '') {
|
|
38
|
-
return MessageControl(uiSchemaErrors);
|
|
39
|
-
}
|
|
40
|
-
return <span />;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Note: by returning a rank of 1000, we are saying that this renderer is very important,
|
|
45
|
-
* one that must get used if there are any errors whatsoever.
|
|
46
|
-
*/
|
|
47
|
-
export const GoAErrorControlTester: RankedTester = rankWith(1000, (uischema, schema, context) => {
|
|
48
|
-
const validJsonSchema = isValidJsonSchema(schema);
|
|
49
|
-
const validUiSchema = getUISchemaErrors(uischema, schema);
|
|
50
|
-
return validUiSchema != null || validJsonSchema != null;
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
export default withJsonFormsControlProps(ErrorControl);
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
errCategorizationHasNoElements,
|
|
3
|
-
errCategorizationHasNoVariant,
|
|
4
|
-
errCategorizationHasNonCategories,
|
|
5
|
-
errNoElements,
|
|
6
|
-
getUISchemaErrors,
|
|
7
|
-
} from './schemaValidation';
|
|
8
|
-
|
|
9
|
-
const dataSchema = {
|
|
10
|
-
type: 'object',
|
|
11
|
-
properties: {
|
|
12
|
-
firstName: {
|
|
13
|
-
type: 'string',
|
|
14
|
-
},
|
|
15
|
-
birthDate: {
|
|
16
|
-
type: 'string',
|
|
17
|
-
format: 'date',
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const validCategorization = {
|
|
23
|
-
type: 'Categorization',
|
|
24
|
-
elements: [
|
|
25
|
-
{
|
|
26
|
-
type: 'Category',
|
|
27
|
-
elements: [
|
|
28
|
-
{
|
|
29
|
-
type: 'Category',
|
|
30
|
-
elements: [
|
|
31
|
-
{
|
|
32
|
-
type: 'Control',
|
|
33
|
-
scope: '#/properties/firstName',
|
|
34
|
-
},
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
options: { variant: 'stepper' },
|
|
41
|
-
};
|
|
42
|
-
const categorizationWithNoCategories = {
|
|
43
|
-
type: 'Categorization',
|
|
44
|
-
elements: [
|
|
45
|
-
{
|
|
46
|
-
type: 'Category',
|
|
47
|
-
elements: [{ type: 'Control', scope: '#/properties/firstName' }],
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
type: 'VerticalLayout',
|
|
51
|
-
elements: [{ type: 'Control', scope: '#/properties/birthDate' }],
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
options: { variant: 'stepper' },
|
|
55
|
-
};
|
|
56
|
-
const categorizationWithNoElements = {
|
|
57
|
-
type: 'Categorization',
|
|
58
|
-
options: { variant: 'stepper' },
|
|
59
|
-
};
|
|
60
|
-
const categoryHasNoElements = {
|
|
61
|
-
type: 'Categorization',
|
|
62
|
-
elements: [{ type: 'Category' }],
|
|
63
|
-
options: { variant: 'stepper' },
|
|
64
|
-
};
|
|
65
|
-
const categorizationWithNoVariant = {
|
|
66
|
-
type: 'Categorization',
|
|
67
|
-
elements: [{ type: 'Category', elements: [] }],
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
describe('check error processing', () => {
|
|
71
|
-
describe('categorization validation', () => {
|
|
72
|
-
it('ignores valid categorizations', () => {
|
|
73
|
-
const err = getUISchemaErrors(validCategorization, dataSchema);
|
|
74
|
-
expect(err).toBe(null);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('can detect non-category element', () => {
|
|
78
|
-
const err = getUISchemaErrors(categorizationWithNoCategories, dataSchema);
|
|
79
|
-
console.log(err);
|
|
80
|
-
expect(err).toMatch(errCategorizationHasNonCategories);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('can detect categorization without elements', () => {
|
|
84
|
-
const err = getUISchemaErrors(categorizationWithNoElements, dataSchema);
|
|
85
|
-
expect(err).toMatch(errCategorizationHasNoElements);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('can detect a Category with no elements', () => {
|
|
89
|
-
const err = getUISchemaErrors(categoryHasNoElements, dataSchema);
|
|
90
|
-
expect(err).toMatch(errNoElements('Category'));
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('can detect Categorization with no variant', () => {
|
|
94
|
-
const err = getUISchemaErrors(categorizationWithNoVariant, dataSchema);
|
|
95
|
-
expect(err).toMatch(errCategorizationHasNoVariant);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
});
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { errMalformedScope, errMissingScope, errUnknownScope, getUISchemaErrors } from './schemaValidation';
|
|
2
|
-
|
|
3
|
-
const dataSchema = {
|
|
4
|
-
type: 'object',
|
|
5
|
-
properties: {
|
|
6
|
-
firstName: {
|
|
7
|
-
type: 'string',
|
|
8
|
-
},
|
|
9
|
-
birthDate: {
|
|
10
|
-
type: 'string',
|
|
11
|
-
format: 'date',
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const validControl = {
|
|
17
|
-
type: 'Control',
|
|
18
|
-
scope: '#/properties/firstName',
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const malformedScope = {
|
|
22
|
-
type: 'Control',
|
|
23
|
-
scope: '#properties/firstName',
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const unknownScope = {
|
|
27
|
-
type: 'Control',
|
|
28
|
-
scope: '#/properties/ouch/unknown/scope',
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const missingScope = {
|
|
32
|
-
type: 'Control',
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
describe('check error processing', () => {
|
|
36
|
-
describe('control validation', () => {
|
|
37
|
-
it('ignores valid control schema', () => {
|
|
38
|
-
const err = getUISchemaErrors(validControl, dataSchema);
|
|
39
|
-
expect(err).toBe(null);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('has malformed scope', () => {
|
|
43
|
-
const err = getUISchemaErrors(malformedScope, dataSchema);
|
|
44
|
-
expect(err).toBe(errMalformedScope(malformedScope.scope));
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('has unknown scope', () => {
|
|
48
|
-
const err = getUISchemaErrors(unknownScope, dataSchema);
|
|
49
|
-
expect(err).toBe(errUnknownScope(unknownScope.scope));
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('has missing scope', () => {
|
|
53
|
-
const err = getUISchemaErrors(missingScope, dataSchema);
|
|
54
|
-
expect(err).toBe(errMissingScope);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
});
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
hasElements,
|
|
3
|
-
hasVariant,
|
|
4
|
-
isCategorization,
|
|
5
|
-
isControlWithNoScope,
|
|
6
|
-
isEmptyElements,
|
|
7
|
-
isKnownType,
|
|
8
|
-
isLayoutType,
|
|
9
|
-
isScopedPrefixed,
|
|
10
|
-
isValidScope,
|
|
11
|
-
} from './errorCheck';
|
|
12
|
-
|
|
13
|
-
const dataSchema = {
|
|
14
|
-
type: 'object',
|
|
15
|
-
properties: {
|
|
16
|
-
firstName: {
|
|
17
|
-
type: 'string',
|
|
18
|
-
},
|
|
19
|
-
birthDate: {
|
|
20
|
-
type: 'string',
|
|
21
|
-
format: 'date',
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// Note: The number in the description is the element index, and it
|
|
27
|
-
// is used to refer to the element in the unit tests. Please keep them
|
|
28
|
-
// up to date.
|
|
29
|
-
const uiSchema = {
|
|
30
|
-
type: 'VerticalLayout',
|
|
31
|
-
elements: [
|
|
32
|
-
{
|
|
33
|
-
type: 'Control',
|
|
34
|
-
scope: '#/properties/firstName',
|
|
35
|
-
description: 'valid scope test (0)',
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
type: 'Control',
|
|
39
|
-
scope: '#/properties/lastName',
|
|
40
|
-
description: 'missing property test (1)',
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
type: 'Control',
|
|
44
|
-
scope: '#/properties/birthDate',
|
|
45
|
-
description: 'Date test (2)',
|
|
46
|
-
options: {
|
|
47
|
-
componentProps: {
|
|
48
|
-
name: 'Calendar name',
|
|
49
|
-
min: '2023-02-01',
|
|
50
|
-
max: '2025-02-01',
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
type: 'Bob',
|
|
56
|
-
scope: 'properties/bob',
|
|
57
|
-
description: 'malformed scope test (3)',
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
type: 'Control',
|
|
61
|
-
description: 'missing scope test (4)',
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
type: 'HorizontalLayout',
|
|
65
|
-
description: 'Layout with no elements (5)',
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
type: 'VerticalLayout',
|
|
69
|
-
elements: [],
|
|
70
|
-
description: 'Layout with empty elements (6)',
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
type: 'Categorization',
|
|
74
|
-
description: 'Valid Categorization (7)',
|
|
75
|
-
elements: [
|
|
76
|
-
{
|
|
77
|
-
type: 'Category',
|
|
78
|
-
elements: [
|
|
79
|
-
{
|
|
80
|
-
type: 'Category',
|
|
81
|
-
elements: [
|
|
82
|
-
{
|
|
83
|
-
type: 'Control',
|
|
84
|
-
scope: '#/properties/firstName',
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
|
-
},
|
|
88
|
-
],
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
options: {
|
|
92
|
-
variant: 'stepper',
|
|
93
|
-
},
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
describe('check error processing', () => {
|
|
99
|
-
describe('data schema', () => {
|
|
100
|
-
it('parses correctly', () => {
|
|
101
|
-
expect(dataSchema).toEqual(
|
|
102
|
-
expect.objectContaining({
|
|
103
|
-
type: 'object',
|
|
104
|
-
properties: expect.objectContaining({
|
|
105
|
-
firstName: expect.objectContaining({ type: 'string' }),
|
|
106
|
-
}),
|
|
107
|
-
})
|
|
108
|
-
);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
describe('ui schema', () => {
|
|
113
|
-
it('parses correctly', () => {
|
|
114
|
-
expect(uiSchema).toEqual(
|
|
115
|
-
expect.objectContaining({
|
|
116
|
-
type: 'VerticalLayout',
|
|
117
|
-
elements: expect.arrayContaining([
|
|
118
|
-
expect.objectContaining({ scope: expect.stringContaining('#/properties/firstName') }),
|
|
119
|
-
expect.objectContaining({ scope: expect.stringContaining('#/properties/birthDate') }),
|
|
120
|
-
]),
|
|
121
|
-
})
|
|
122
|
-
);
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
describe('testing scope', () => {
|
|
127
|
-
it('can verify valid scope', () => {
|
|
128
|
-
const isValid = isValidScope(uiSchema.elements[0], dataSchema);
|
|
129
|
-
expect(isValid).toBe(true);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('can detect missing property', () => {
|
|
133
|
-
const isValid = isValidScope(uiSchema.elements[1], dataSchema);
|
|
134
|
-
expect(isValid).toBe(false);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('can detect malformed scope', () => {
|
|
138
|
-
const isValid = isScopedPrefixed(uiSchema.elements[3].scope as string);
|
|
139
|
-
expect(isValid).toBe(false);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('can detect missing scope', () => {
|
|
143
|
-
const isValid = isControlWithNoScope(uiSchema.elements[4]);
|
|
144
|
-
expect(isValid).toBe(true);
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
describe('testing layout', () => {
|
|
149
|
-
it('can verify a valid layout', () => {
|
|
150
|
-
const isValid = isLayoutType(uiSchema);
|
|
151
|
-
expect(isValid).toBe(true);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it('can verify layout has elements', () => {
|
|
155
|
-
const isValid = hasElements(uiSchema);
|
|
156
|
-
expect(isValid).toBe(true);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it('can detect layout without elements', () => {
|
|
160
|
-
const subSchema = uiSchema.elements[5];
|
|
161
|
-
const isValid = isKnownType(subSchema) && hasElements(subSchema);
|
|
162
|
-
expect(isValid).toBe(false);
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it('can detect layout with an empty set of elements', () => {
|
|
166
|
-
const subSchema = uiSchema.elements[6];
|
|
167
|
-
const isValid = isKnownType(subSchema) && isEmptyElements(subSchema);
|
|
168
|
-
expect(isValid).toBe(true);
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe('testing categorization', () => {
|
|
173
|
-
it('can verify categorization', () => {
|
|
174
|
-
const subSchema = uiSchema.elements[7];
|
|
175
|
-
const isValid = isCategorization(subSchema);
|
|
176
|
-
expect(isValid).toBe(true);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it('can detect categorization variant', () => {
|
|
180
|
-
const subSchema = uiSchema.elements[7];
|
|
181
|
-
const isValid = hasVariant(subSchema);
|
|
182
|
-
expect(isValid).toBe(true);
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
});
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { JsonSchema, UISchemaElement, hasType, isControl } from '@jsonforms/core';
|
|
2
|
-
|
|
3
|
-
export const isNullSchema = (schema: unknown): boolean => {
|
|
4
|
-
return schema === undefined || schema === null;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export const isValidScope = (uiSchema: UISchemaElement, schema: JsonSchema): boolean => {
|
|
8
|
-
if (!('scope' in uiSchema)) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
const scopeComponents = (uiSchema.scope as string).split('/');
|
|
12
|
-
// get rid of the '#' at the beginning of scope
|
|
13
|
-
scopeComponents.shift();
|
|
14
|
-
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
-
let obj = schema as any;
|
|
17
|
-
// iterate through the schema to ensure each property exists
|
|
18
|
-
for (const key of scopeComponents) {
|
|
19
|
-
if (obj && typeof obj === 'object' && key in obj) {
|
|
20
|
-
obj = obj[key];
|
|
21
|
-
} else {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return true;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const isLayoutType = (schema: UISchemaElement): boolean => {
|
|
29
|
-
return (
|
|
30
|
-
hasType(schema, 'VerticalLayout') ||
|
|
31
|
-
hasType(schema, 'HorizontalLayout') ||
|
|
32
|
-
hasType(schema, 'Categorization') ||
|
|
33
|
-
hasType(schema, 'Group')
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export const isKnownType = (schema: UISchemaElement): boolean => {
|
|
38
|
-
return (
|
|
39
|
-
hasType(schema, 'Control') || isLayoutType(schema) || hasType(schema, 'HelpContent') || isListWithDetail(schema)
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const isListWithDetail = (schema: UISchemaElement): boolean => {
|
|
44
|
-
return hasType(schema, 'ListWithDetail');
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export const isScopedPrefixed = (scope: string): boolean => {
|
|
48
|
-
const scopeComponents = scope.split('/');
|
|
49
|
-
return scopeComponents.length > 1 && scopeComponents[0] === '#';
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export const isEmptyObject = (schema: object): boolean => {
|
|
53
|
-
return Object.keys(schema).length === 0;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export const isControlWithNoScope = (uiSchema: UISchemaElement): boolean => {
|
|
57
|
-
return 'type' in uiSchema && uiSchema.type === 'Control' && !('scope' in uiSchema);
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export const isCategorization = (uiSchema: UISchemaElement): boolean => {
|
|
61
|
-
return uiSchema.type === 'Categorization';
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const hasElements = (schema: object): boolean => {
|
|
65
|
-
return 'elements' in schema && Array.isArray(schema.elements);
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const isEmptyElements = (schema: object): boolean => {
|
|
69
|
-
return (
|
|
70
|
-
'elements' in schema &&
|
|
71
|
-
schema.elements !== undefined &&
|
|
72
|
-
schema.elements !== null &&
|
|
73
|
-
Object.keys(schema.elements).length === 0
|
|
74
|
-
);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const hasVariant = (schema: UISchemaElement): boolean => {
|
|
78
|
-
return 'options' in schema && schema.options !== undefined && schema.options !== null && 'variant' in schema.options;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export const isValidJsonObject = (schema: JsonSchema): boolean => {
|
|
82
|
-
return (
|
|
83
|
-
(typeof schema === 'object' && Object.keys(schema).length === 0) ||
|
|
84
|
-
('properties' in schema && (('type' in schema && schema.type === 'object') || !('type' in schema)))
|
|
85
|
-
);
|
|
86
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { errNoElements, getUISchemaErrors } from './schemaValidation';
|
|
2
|
-
|
|
3
|
-
const dataSchema = {
|
|
4
|
-
type: 'object',
|
|
5
|
-
properties: {
|
|
6
|
-
firstName: {
|
|
7
|
-
type: 'string',
|
|
8
|
-
},
|
|
9
|
-
birthDate: {
|
|
10
|
-
type: 'string',
|
|
11
|
-
format: 'date',
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const validLayout = {
|
|
17
|
-
type: 'VerticalLayout',
|
|
18
|
-
elements: [{ type: 'Control', scope: '#/properties/firstName' }],
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const hasNoElements = {
|
|
22
|
-
type: 'HorizontalLayout',
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const hasEmptyElement = {
|
|
26
|
-
type: 'HorizontalLayout',
|
|
27
|
-
elements: [],
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
describe('check error processing', () => {
|
|
31
|
-
describe('layout validation', () => {
|
|
32
|
-
it('ignores valid layout schema', () => {
|
|
33
|
-
const err = getUISchemaErrors(validLayout, dataSchema);
|
|
34
|
-
expect(err).toBe(null);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('has no elements', () => {
|
|
38
|
-
const err = getUISchemaErrors(hasNoElements, dataSchema);
|
|
39
|
-
expect(err).toBe(errNoElements(hasNoElements.type));
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('has empty elements', () => {
|
|
43
|
-
const err = getUISchemaErrors(hasEmptyElement, dataSchema);
|
|
44
|
-
expect(err).toBe(errNoElements(hasEmptyElement.type));
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
});
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { UISchemaElement } from '@jsonforms/core';
|
|
2
|
-
import {
|
|
3
|
-
errMissingScope,
|
|
4
|
-
errMissingType,
|
|
5
|
-
errUnknownScope,
|
|
6
|
-
errUnknownType,
|
|
7
|
-
getUISchemaErrors,
|
|
8
|
-
} from './schemaValidation';
|
|
9
|
-
|
|
10
|
-
const dataSchema = {
|
|
11
|
-
type: 'object',
|
|
12
|
-
properties: {
|
|
13
|
-
firstName: {
|
|
14
|
-
type: 'string',
|
|
15
|
-
},
|
|
16
|
-
birthDate: {
|
|
17
|
-
type: 'string',
|
|
18
|
-
format: 'date',
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const missingType = {
|
|
24
|
-
elements: [{ type: 'Control', scope: '#/properties/firstName' }],
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const unknownType = {
|
|
28
|
-
type: 'BobsYerUncle',
|
|
29
|
-
elements: [{ type: 'Control', scope: '#/properties/firstName' }],
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const validListWithDetails = {
|
|
33
|
-
type: 'ListWithDetail',
|
|
34
|
-
scope: '#/properties/firstName',
|
|
35
|
-
};
|
|
36
|
-
const listWithDetailsNoScope = {
|
|
37
|
-
type: 'ListWithDetail',
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const listWithDetailsInvalidScope = {
|
|
41
|
-
type: 'ListWithDetail',
|
|
42
|
-
scope: '#/properties/Yabadabadooo',
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
describe('check error processing', () => {
|
|
46
|
-
describe('type validation', () => {
|
|
47
|
-
it('detects missing type', () => {
|
|
48
|
-
const err = getUISchemaErrors(missingType as unknown as UISchemaElement, dataSchema);
|
|
49
|
-
expect(err).toBe(errMissingType);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('detects unknown type', () => {
|
|
53
|
-
const err = getUISchemaErrors(unknownType, dataSchema);
|
|
54
|
-
expect(err).toBe(errUnknownType(unknownType.type));
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
describe('List with Detail validation', () => {
|
|
59
|
-
it('likes valid ListWithDetails', () => {
|
|
60
|
-
const err = getUISchemaErrors(validListWithDetails, dataSchema);
|
|
61
|
-
expect(err).toBe(null);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('detects no scope', () => {
|
|
65
|
-
const err = getUISchemaErrors(listWithDetailsNoScope, dataSchema);
|
|
66
|
-
expect(err).toBe(errMissingScope);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('detects unknown scope', () => {
|
|
70
|
-
const err = getUISchemaErrors(listWithDetailsInvalidScope, dataSchema);
|
|
71
|
-
expect(err).toBe(errUnknownScope(listWithDetailsInvalidScope.scope));
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
});
|