@earthranger/react-native-jsonforms-formatter 0.1.0 → 1.0.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/README.md +94 -16
- package/dist/bundle.js +1 -0
- package/dist/common/mockData/formatterMockData.d.ts +50 -0
- package/dist/common/mockData/formatterMockData.d.ts.map +1 -0
- package/dist/src/generateUISchema.d.ts +5 -0
- package/dist/src/generateUISchema.d.ts.map +1 -0
- package/{src/index.ts → dist/src/index.d.ts} +1 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/utils/stringUtils.d.ts +2 -0
- package/dist/src/utils/stringUtils.d.ts.map +1 -0
- package/dist/src/utils/utils.d.ts +43 -0
- package/dist/src/utils/utils.d.ts.map +1 -0
- package/dist/src/validateJsonSchema.d.ts +2 -0
- package/dist/src/validateJsonSchema.d.ts.map +1 -0
- package/dist/test/JsonFormatter.test.d.ts +2 -0
- package/dist/test/JsonFormatter.test.d.ts.map +1 -0
- package/package.json +16 -7
- package/ jest.config.js +0 -4
- package/.eslintrc.cjs +0 -18
- package/.githooks/pre-commit +0 -3
- package/.github/CODEOWNERS +0 -2
- package/.github/workflows/npm-build.yml +0 -40
- package/babel.config.cjs +0 -6
- package/extJestSetup.js +0 -3
- package/src/__test__/JsonFormatter.test.tsx +0 -168
- package/src/common/mockData/formatterMockData.ts +0 -770
- package/src/common/mockData/jsonSchemaExpectedMock.json +0 -318
- package/src/common/mockData/jsonSchemaFielSetMock.json +0 -972
- package/src/common/mockData/jsonSchemaMock.json +0 -250
- package/src/common/mockData/uiSchemaExpectedMock.json +0 -103
- package/src/common/mockData/uiSchemaFielSetExpectedMock.json +0 -297
- package/src/generateUISchema.ts +0 -164
- package/src/utils/utils.ts +0 -83
- package/src/validateJsonSchema.ts +0 -275
- package/tsconfig.json +0 -32
package/src/generateUISchema.ts
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
// External Dependencies
|
|
2
|
-
import { isEmpty } from 'lodash-es';
|
|
3
|
-
|
|
4
|
-
// Internal Dependencies
|
|
5
|
-
import {
|
|
6
|
-
DateTimeFormat,
|
|
7
|
-
ElementDisplay,
|
|
8
|
-
getFieldSetTitleKey,
|
|
9
|
-
isFieldSet,
|
|
10
|
-
isFieldSetTitleWithoutItems, isPropertyKey,
|
|
11
|
-
isSchemaFieldSet, PropertyFormat,
|
|
12
|
-
} from './utils/utils';
|
|
13
|
-
|
|
14
|
-
// Enums
|
|
15
|
-
enum SchemaTypes {
|
|
16
|
-
Number = 'number',
|
|
17
|
-
String = 'string',
|
|
18
|
-
Array = 'array',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const getBaseUIObject = (key: string, title: string, options: any = {}) => (
|
|
22
|
-
{
|
|
23
|
-
type: 'Control',
|
|
24
|
-
scope: `#/properties/${key}`,
|
|
25
|
-
label: title,
|
|
26
|
-
...options && { options },
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const getDateTimeControlFormat = (key: string, jsonSchema: any, fieldSetItem: any = undefined) => {
|
|
30
|
-
try {
|
|
31
|
-
const definitionObject = fieldSetItem
|
|
32
|
-
|| jsonSchema.definition.find((object: any) => (object.key === key));
|
|
33
|
-
|
|
34
|
-
if (definitionObject.fieldHtmlClass === 'date-time-picker json-schema'
|
|
35
|
-
|| (definitionObject && (definitionObject.type || '') === 'datetime')) {
|
|
36
|
-
if (jsonSchema.schema.properties[key].format === 'date') {
|
|
37
|
-
return DateTimeFormat.Date;
|
|
38
|
-
}
|
|
39
|
-
return DateTimeFormat.DateTime;
|
|
40
|
-
}
|
|
41
|
-
if (definitionObject.fieldHtmlClass === 'date-picker json-schema'
|
|
42
|
-
|| jsonSchema.schema.properties[key].format === 'date') {
|
|
43
|
-
return DateTimeFormat.Date;
|
|
44
|
-
}
|
|
45
|
-
} catch {
|
|
46
|
-
return undefined;
|
|
47
|
-
}
|
|
48
|
-
return undefined;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export const generateUISchema = (schema: any) => {
|
|
52
|
-
const elements: Object[] = [];
|
|
53
|
-
|
|
54
|
-
if (isSchemaFieldSet(schema.definition)) {
|
|
55
|
-
elements.push(...getFieldSetsElements(schema));
|
|
56
|
-
} else {
|
|
57
|
-
Object.keys(schema.schema.properties).forEach((key: string) => {
|
|
58
|
-
const element = getUIElement(key, schema);
|
|
59
|
-
if (element) {
|
|
60
|
-
elements.push(element);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
type: 'Category',
|
|
66
|
-
elements,
|
|
67
|
-
};
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const getFieldSetsElements = (schema: any) => {
|
|
71
|
-
const elements: Object[] = [];
|
|
72
|
-
|
|
73
|
-
schema.definition.forEach((item: any) => {
|
|
74
|
-
if (typeof item === 'string') {
|
|
75
|
-
elements.push(getBaseUIObject(item, schema.schema.properties[item].title || ''));
|
|
76
|
-
} else if (item instanceof Object) {
|
|
77
|
-
switch (true) {
|
|
78
|
-
case isFieldSetTitleWithoutItems(item):
|
|
79
|
-
elements.push(getBaseUIObject(
|
|
80
|
-
getFieldSetTitleKey(item.title),
|
|
81
|
-
item.title,
|
|
82
|
-
getElementOptions(PropertyFormat.FormLabel),
|
|
83
|
-
));
|
|
84
|
-
break;
|
|
85
|
-
case isFieldSet(item):
|
|
86
|
-
if (item.title) {
|
|
87
|
-
elements.push(getBaseUIObject(
|
|
88
|
-
getFieldSetTitleKey(item.title),
|
|
89
|
-
item.title,
|
|
90
|
-
getElementOptions(PropertyFormat.FormLabel),
|
|
91
|
-
));
|
|
92
|
-
}
|
|
93
|
-
item.items.forEach((value: any) => {
|
|
94
|
-
if (value instanceof Object) {
|
|
95
|
-
const element = getUIElement(value.key || '', schema, value);
|
|
96
|
-
if (element) {
|
|
97
|
-
elements.push(element);
|
|
98
|
-
}
|
|
99
|
-
} else if (typeof value === 'string') {
|
|
100
|
-
const element = getUIElement(value, schema);
|
|
101
|
-
if (element) {
|
|
102
|
-
elements.push(element);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
break;
|
|
107
|
-
case isPropertyKey(item):
|
|
108
|
-
// eslint-disable-next-line no-case-declarations
|
|
109
|
-
const element = getUIElement(item.key, schema);
|
|
110
|
-
if (element) {
|
|
111
|
-
elements.push(element);
|
|
112
|
-
}
|
|
113
|
-
break;
|
|
114
|
-
default:
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
return elements;
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
const getElementOptions = (format: string = '', display: string = '') => {
|
|
123
|
-
if (isEmpty(format)) {
|
|
124
|
-
return {};
|
|
125
|
-
}
|
|
126
|
-
const options = { format };
|
|
127
|
-
if (!isEmpty(display)) {
|
|
128
|
-
// @ts-ignore
|
|
129
|
-
options.display = display;
|
|
130
|
-
}
|
|
131
|
-
return options;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const getUIElement = (key: string, schema: any, fieldSetItem: any = undefined) => {
|
|
135
|
-
let options = {};
|
|
136
|
-
switch (schema.schema.properties[key].type as SchemaTypes) {
|
|
137
|
-
case SchemaTypes.Number:
|
|
138
|
-
return getBaseUIObject(key, schema.schema.properties[key].title || '');
|
|
139
|
-
|
|
140
|
-
case SchemaTypes.String:
|
|
141
|
-
// eslint-disable-next-line no-case-declarations
|
|
142
|
-
const dateTimeFormat = getDateTimeControlFormat(key, schema, fieldSetItem);
|
|
143
|
-
if (!isEmpty(dateTimeFormat)) {
|
|
144
|
-
options = getElementOptions(PropertyFormat.DateTime, dateTimeFormat);
|
|
145
|
-
} else if (schema.schema.properties[key].display
|
|
146
|
-
&& schema.schema.properties[key].display === ElementDisplay.Header) {
|
|
147
|
-
options = getElementOptions(PropertyFormat.FormLabel);
|
|
148
|
-
}
|
|
149
|
-
return getBaseUIObject(key, schema.schema.properties[key].title || '', options);
|
|
150
|
-
|
|
151
|
-
case SchemaTypes.Array:
|
|
152
|
-
if (schema.schema.properties[key].items.enum
|
|
153
|
-
&& schema.schema.properties[key].items.enumNames) {
|
|
154
|
-
options = getElementOptions(PropertyFormat.MultiSelect);
|
|
155
|
-
} else if (schema.schema.properties[key].items) {
|
|
156
|
-
options = getElementOptions(PropertyFormat.RepeatableField);
|
|
157
|
-
}
|
|
158
|
-
return getBaseUIObject(key, schema.schema.properties[key].title || '', options);
|
|
159
|
-
default:
|
|
160
|
-
break;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return undefined;
|
|
164
|
-
};
|
package/src/utils/utils.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-named-as-default */
|
|
2
|
-
// External Dependencies
|
|
3
|
-
import { isEmpty } from 'lodash-es';
|
|
4
|
-
|
|
5
|
-
export enum DateTimeFormat {
|
|
6
|
-
DateTime = 'date-time',
|
|
7
|
-
Date = 'date',
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export enum PropertyFormat {
|
|
11
|
-
DateTime = 'date-time',
|
|
12
|
-
MultiSelect = 'multiselect',
|
|
13
|
-
RepeatableField = 'repeatable-field',
|
|
14
|
-
FormLabel = 'form-label',
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export enum ElementDisplay {
|
|
18
|
-
Header = 'header',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const FIELD_SET = 'fieldset';
|
|
22
|
-
export const HELP_VALUE = 'helpvalue';
|
|
23
|
-
|
|
24
|
-
export const REQUIRED_PROPERTY = 'required';
|
|
25
|
-
export const CHECKBOXES = 'checkboxes';
|
|
26
|
-
export const INACTIVE_ENUM = 'inactive_enum';
|
|
27
|
-
export const DISABLED_ENUM = 'inactive_titleMap';
|
|
28
|
-
export const STRING_TYPE = 'string';
|
|
29
|
-
export const ARRAY_TYPE = 'array';
|
|
30
|
-
|
|
31
|
-
export const isObject = (item: any) => item instanceof Object;
|
|
32
|
-
|
|
33
|
-
export const isString = (item: any) => typeof item === STRING_TYPE;
|
|
34
|
-
export const isSchemaFieldSet = (definition: any[]) => {
|
|
35
|
-
if (definition.length === 0) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
const fieldSet = definition.find((item: any) => isObject(item)
|
|
39
|
-
&& item && (item.type || '') === FIELD_SET);
|
|
40
|
-
return fieldSet !== undefined;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const isFieldSetTitle = (item: any) => isObject(item) && item.type === FIELD_SET
|
|
44
|
-
&& !isEmpty(item.title);
|
|
45
|
-
|
|
46
|
-
export const isFieldSetTitleWithoutItems = (item: any) => isObject(item) && item.type === FIELD_SET
|
|
47
|
-
&& item.items.length === 0 && !isEmpty(item.title);
|
|
48
|
-
|
|
49
|
-
export const isFieldSet = (item: any) => isObject(item) && item.type === FIELD_SET && item.items.length > 0;
|
|
50
|
-
|
|
51
|
-
export const isCheckbox = (item: any) => isObject(item) && item.type === CHECKBOXES;
|
|
52
|
-
|
|
53
|
-
export const isPropertyKey = (item: any) => !isEmpty(item.key);
|
|
54
|
-
|
|
55
|
-
export const getFieldSetTitleKey = (title: string) => {
|
|
56
|
-
const key = title.toLowerCase().replace(/[\s\\/\\%]/gi, '_');
|
|
57
|
-
return `fieldset__title_${key}`;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
export const getSchemaValidations = (stringSchema: string) => ({
|
|
61
|
-
hasCheckboxes: hasCheckboxes(stringSchema),
|
|
62
|
-
hasInactiveChoices: hasInactiveChoices(stringSchema),
|
|
63
|
-
hasDisabledChoices: hasDisabledChoices(stringSchema),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
export const isArrayProperty = (property: any) => property.type === ARRAY_TYPE && !property.items?.enum
|
|
67
|
-
&& !property.items?.enumNames;
|
|
68
|
-
|
|
69
|
-
export const isRequiredProperty = (property: any) => property.required === 'true' || property.required > 0;
|
|
70
|
-
|
|
71
|
-
const hasCheckboxes = (stringSchema: string) => stringSchema.includes(CHECKBOXES);
|
|
72
|
-
|
|
73
|
-
const hasInactiveChoices = (stringSchema: string) => stringSchema.includes(INACTIVE_ENUM);
|
|
74
|
-
|
|
75
|
-
const hasDisabledChoices = (stringSchema: string) => stringSchema.includes(DISABLED_ENUM);
|
|
76
|
-
|
|
77
|
-
export const isInactiveChoice = (item: any) => item.type === STRING_TYPE
|
|
78
|
-
&& item.enum?.length > 0 && item.inactive_enum?.length > 0;
|
|
79
|
-
|
|
80
|
-
export const isDisabledChoice = (item: any) => isObject(item) && item.type === CHECKBOXES && item.inactive_titleMap?.length > 0
|
|
81
|
-
&& item.titleMap?.length > 0;
|
|
82
|
-
|
|
83
|
-
export const hasEnumDuplicatedItems = (options: string[]) => (new Set(options).size !== options.length);
|
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
// Internal Dependencies
|
|
2
|
-
import {
|
|
3
|
-
ElementDisplay,
|
|
4
|
-
getFieldSetTitleKey,
|
|
5
|
-
getSchemaValidations,
|
|
6
|
-
hasEnumDuplicatedItems,
|
|
7
|
-
HELP_VALUE,
|
|
8
|
-
isArrayProperty,
|
|
9
|
-
isCheckbox,
|
|
10
|
-
isDisabledChoice,
|
|
11
|
-
isFieldSet,
|
|
12
|
-
isFieldSetTitle,
|
|
13
|
-
isInactiveChoice,
|
|
14
|
-
isObject,
|
|
15
|
-
isPropertyKey,
|
|
16
|
-
isRequiredProperty,
|
|
17
|
-
isSchemaFieldSet,
|
|
18
|
-
isString,
|
|
19
|
-
REQUIRED_PROPERTY,
|
|
20
|
-
} from './utils/utils';
|
|
21
|
-
|
|
22
|
-
const specialCharactersInKey = /[^\w\n\s_"](?=[^:\n\s{}[]]*:[\t\n\s]*(\{|\[)+)/g;
|
|
23
|
-
const emptyEnumRegex = '\\"enum\\"\\n*\\s*\\:\\n*\\s*\\[\\n*\\s*\\]';
|
|
24
|
-
const emptyEnumValue = '"enum": ["0"]';
|
|
25
|
-
const emptyEnumNamesRegex = '\\"enumNames\\"\\n*\\s*\\:\\n*\\s*\\{\\n*\\s*\\}';
|
|
26
|
-
const emptyEnumNamesValue = '"enumNames": {"0":"No Options"}';
|
|
27
|
-
const emptyTitleMapRegex = '\\"titleMap\\"\\n*\\s*\\:\\n*\\s*\\[\\n*\\s*\\]';
|
|
28
|
-
const emptyTitleMapValue = '"titleMap": [{"value":"no_option", "name":"No Option"}]';
|
|
29
|
-
const minParamRegex = /"minimum"(?:[^\\"]|\\\\|\\")*"\d+\.*\d*"/g;
|
|
30
|
-
const maxParamRegex = /"maximum"(?:[^\\"]|\\\\|\\")*"\d+\.*\d*"/g;
|
|
31
|
-
const doubleSingleQuotesRegex = /"(?=[^"]*(?:"[^"]*)?$)/g;
|
|
32
|
-
|
|
33
|
-
const getSchemaForCheckbox = (
|
|
34
|
-
definition: any,
|
|
35
|
-
title: string,
|
|
36
|
-
required: boolean,
|
|
37
|
-
defaultValue: string,
|
|
38
|
-
) => ({
|
|
39
|
-
type: 'array',
|
|
40
|
-
uniqueItems: true,
|
|
41
|
-
isHidden: false,
|
|
42
|
-
...required && { required },
|
|
43
|
-
title: title || definition.title,
|
|
44
|
-
items: {
|
|
45
|
-
enum: definition.titleMap.map((item: any) => item.value),
|
|
46
|
-
enumNames: definition.titleMap.map((item: any) => item.name),
|
|
47
|
-
},
|
|
48
|
-
...defaultValue && { default: defaultValue },
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const getTitleProperty = (title: string) => ({
|
|
52
|
-
type: 'string',
|
|
53
|
-
readOnly: true,
|
|
54
|
-
isHidden: false,
|
|
55
|
-
display: ElementDisplay.Header,
|
|
56
|
-
title,
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const getPropertyVisibility = (property: any) => property?.isHidden || false;
|
|
60
|
-
|
|
61
|
-
const cleanUpRequiredProperty = (schema: any) => {
|
|
62
|
-
const requiredProperties = [];
|
|
63
|
-
|
|
64
|
-
// Iterate over the properties to get clean enum data
|
|
65
|
-
for (const key of Object.keys(schema.properties)) {
|
|
66
|
-
const property = schema.properties[key];
|
|
67
|
-
if (isRequiredProperty(property)) {
|
|
68
|
-
requiredProperties.push(key);
|
|
69
|
-
delete schema.properties[key].required;
|
|
70
|
-
}
|
|
71
|
-
if (isArrayProperty(property)) {
|
|
72
|
-
cleanUpRequiredProperty(property.items);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (requiredProperties.length > 0) {
|
|
77
|
-
// eslint-disable-next-line no-param-reassign
|
|
78
|
-
schema.required = requiredProperties;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return schema;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const formatDefinitionInSchema = (schema: any) => {
|
|
85
|
-
if (schema.schema.definition) {
|
|
86
|
-
const { definition } = schema.schema;
|
|
87
|
-
delete schema.schema.definition;
|
|
88
|
-
schema.definition = definition;
|
|
89
|
-
return schema;
|
|
90
|
-
}
|
|
91
|
-
return schema;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const formatSchemaRepeatableFieldLayout = (schema: any) => {
|
|
95
|
-
const properties: any = {};
|
|
96
|
-
let headerCount = 0;
|
|
97
|
-
|
|
98
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
99
|
-
for (const item of schema.definition) {
|
|
100
|
-
if (isString(item)) {
|
|
101
|
-
properties[item] = schema.schema.properties[item];
|
|
102
|
-
delete schema.schema.properties[item];
|
|
103
|
-
} else if (isObject(item)) {
|
|
104
|
-
if (item.helpvalue) {
|
|
105
|
-
const property = `help_value_${headerCount}`;
|
|
106
|
-
headerCount += 1;
|
|
107
|
-
properties[property] = getTitleProperty((item.helpvalue || '').replace(/(<.+?>)/g, ''));
|
|
108
|
-
} else if (item.key) {
|
|
109
|
-
properties[item.key] = schema.schema.properties[item.key];
|
|
110
|
-
delete schema.schema.properties[item.key];
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
schema.schema.properties = Object.assign(properties, schema.schema.properties);
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// eslint-disable-next-line max-len
|
|
119
|
-
const cleanUpInactiveEnumChoice = (property: any) => property.enum.filter((choice: any) => !property.inactive_enum.includes(choice));
|
|
120
|
-
|
|
121
|
-
// eslint-disable-next-line max-len
|
|
122
|
-
const cleanUpDisabledEnumChoice = (definitionItem: any) => definitionItem.titleMap.filter((item: any) => !definitionItem.inactive_titleMap.includes(item.value));
|
|
123
|
-
|
|
124
|
-
const validateJSON = (stringSchema: string) => {
|
|
125
|
-
if (stringSchema.match(specialCharactersInKey) !== null) {
|
|
126
|
-
throw Error('Special characters not supported in JSON Schema');
|
|
127
|
-
}
|
|
128
|
-
// Invalid double quotes
|
|
129
|
-
stringSchema = stringSchema.replace(/([“”])/g, '"');
|
|
130
|
-
// Empty enum choices
|
|
131
|
-
stringSchema = stringSchema.replace(new RegExp(emptyEnumRegex, 'g'), emptyEnumValue);
|
|
132
|
-
// Empty enumNames choices
|
|
133
|
-
stringSchema = stringSchema.replace(new RegExp(emptyEnumNamesRegex, 'g'), emptyEnumNamesValue);
|
|
134
|
-
// Empty titleMap choices
|
|
135
|
-
stringSchema = stringSchema.replace(new RegExp(emptyTitleMapRegex, 'g'), emptyTitleMapValue);
|
|
136
|
-
// Numeric ranges
|
|
137
|
-
stringSchema = stringSchema.replace(minParamRegex, (match: string) => match.replace(doubleSingleQuotesRegex, ''));
|
|
138
|
-
stringSchema = stringSchema.replace(maxParamRegex, (match: string) => match.replace(doubleSingleQuotesRegex, ''));
|
|
139
|
-
|
|
140
|
-
return stringSchema;
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
const cleanUpJTD = (validations: any, schema: any) => {
|
|
144
|
-
if (isSchemaFieldSet(schema.definition)) {
|
|
145
|
-
validateFieldSetDefinition(validations, schema);
|
|
146
|
-
} else if (schema.definition?.length > 0) {
|
|
147
|
-
for (const item of schema.definition) {
|
|
148
|
-
validateDefinition(validations, item, schema);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
const validateFieldSetDefinition = (validations: any, schema: any) => {
|
|
154
|
-
for (const item of schema.definition) {
|
|
155
|
-
switch (true) {
|
|
156
|
-
case isString(item):
|
|
157
|
-
break;
|
|
158
|
-
// Create field set header
|
|
159
|
-
case isFieldSetTitle(item):
|
|
160
|
-
{
|
|
161
|
-
const key = getFieldSetTitleKey(item.title);
|
|
162
|
-
schema.schema.properties[key] = getTitleProperty(item.title);
|
|
163
|
-
}
|
|
164
|
-
break;
|
|
165
|
-
// Format field-set sub-items
|
|
166
|
-
case isFieldSet(item):
|
|
167
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
168
|
-
for (const subItem of item.items) {
|
|
169
|
-
validateDefinition(validations, subItem, schema, item);
|
|
170
|
-
}
|
|
171
|
-
break;
|
|
172
|
-
default:
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const validateDefinition = (validations: any, item: any, schema: any, parentItem?: any) => {
|
|
179
|
-
const { hasCheckboxes, hasDisabledChoices } = validations;
|
|
180
|
-
// Set property visibility
|
|
181
|
-
if (isString(item) && schema.schema.properties[item]) {
|
|
182
|
-
schema.schema.properties[item].isHidden = getPropertyVisibility(schema.schema.properties[item]);
|
|
183
|
-
} else {
|
|
184
|
-
// Set property visibility
|
|
185
|
-
if ((isObject(item) || isPropertyKey(item))
|
|
186
|
-
&& item.key
|
|
187
|
-
&& schema.schema.properties[item.key]
|
|
188
|
-
) {
|
|
189
|
-
// eslint-disable-next-line max-len
|
|
190
|
-
schema.schema.properties[item.key].isHidden = getPropertyVisibility(schema.schema.properties[item.key]);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Clean up disabled choices
|
|
194
|
-
if (hasDisabledChoices && isDisabledChoice(item)) {
|
|
195
|
-
if (parentItem) {
|
|
196
|
-
const parentIndex = schema.definition.indexOf(parentItem);
|
|
197
|
-
const childIndex = schema.definition[parentIndex].items.indexOf(item);
|
|
198
|
-
schema.definition[parentIndex].items[childIndex].titleMap = cleanUpDisabledEnumChoice(item);
|
|
199
|
-
} else {
|
|
200
|
-
// eslint-disable-next-line max-len
|
|
201
|
-
schema.definition[schema.definition.indexOf(item)].titleMap = cleanUpDisabledEnumChoice(item);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Generate checkbox data in schema
|
|
206
|
-
if (hasCheckboxes && isCheckbox(item)) {
|
|
207
|
-
schema.schema.properties[item.key] = getSchemaForCheckbox(
|
|
208
|
-
item,
|
|
209
|
-
schema.schema.properties[item.key].title || '',
|
|
210
|
-
schema.schema.properties[item.key].required || false,
|
|
211
|
-
schema.schema.properties[item.key].default || false,
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
const validateSchema = (validations: any, schema: any) => {
|
|
218
|
-
const { hasInactiveChoices, hasEnums } = validations;
|
|
219
|
-
if (hasInactiveChoices) {
|
|
220
|
-
for (const key of Object.keys(schema.schema.properties)) {
|
|
221
|
-
const property = schema.schema.properties[key];
|
|
222
|
-
// Clean up inactive choices
|
|
223
|
-
if (isInactiveChoice(property)) {
|
|
224
|
-
schema.schema.properties[key].enum = cleanUpInactiveEnumChoice(property);
|
|
225
|
-
|
|
226
|
-
if (schema.schema.properties[key].enum.length === 0) {
|
|
227
|
-
schema.schema.properties[key].enum = ['0'];
|
|
228
|
-
schema.schema.properties[key].enumNames = { 0: 'No Options' };
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (hasEnums) {
|
|
235
|
-
for (const key of Object.keys(schema.schema.properties)) {
|
|
236
|
-
// Detect duplicated enum items
|
|
237
|
-
if (
|
|
238
|
-
schema.schema.properties[key].enum?.length > 0
|
|
239
|
-
&& hasEnumDuplicatedItems(schema.schema.properties[key].enum)
|
|
240
|
-
) {
|
|
241
|
-
throw new Error('Duplicated items');
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
export const validateJSONSchema = (stringSchema: string) => {
|
|
248
|
-
// Validate/Remove JSON issues
|
|
249
|
-
stringSchema = validateJSON(stringSchema);
|
|
250
|
-
|
|
251
|
-
const schema = JSON.parse(stringSchema);
|
|
252
|
-
|
|
253
|
-
// $schema and id make JSON forms crash
|
|
254
|
-
delete schema.schema.$schema;
|
|
255
|
-
delete schema.schema.id;
|
|
256
|
-
|
|
257
|
-
// Definition array should be at the same level as a schema object
|
|
258
|
-
formatDefinitionInSchema(schema);
|
|
259
|
-
|
|
260
|
-
const schemaValidations = getSchemaValidations(stringSchema);
|
|
261
|
-
|
|
262
|
-
validateSchema(schemaValidations, schema);
|
|
263
|
-
|
|
264
|
-
// JSON forms library does not support JSON Type Definition JTD
|
|
265
|
-
cleanUpJTD(schemaValidations, schema);
|
|
266
|
-
|
|
267
|
-
if (stringSchema.includes(HELP_VALUE)) {
|
|
268
|
-
formatSchemaRepeatableFieldLayout(schema);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (stringSchema.includes(REQUIRED_PROPERTY)) {
|
|
272
|
-
schema.schema = cleanUpRequiredProperty(schema.schema);
|
|
273
|
-
}
|
|
274
|
-
return schema;
|
|
275
|
-
};
|
package/tsconfig.json
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
/* Basic Options */
|
|
4
|
-
"target": "ES2021",
|
|
5
|
-
"module": "ESNext",
|
|
6
|
-
"lib": ["es2017"],
|
|
7
|
-
"declaration": true,
|
|
8
|
-
"declarationMap": true,
|
|
9
|
-
"sourceMap": true,
|
|
10
|
-
"outDir": "dist",
|
|
11
|
-
"rootDir": "src/",
|
|
12
|
-
"noEmit": true,
|
|
13
|
-
"isolatedModules": true,
|
|
14
|
-
|
|
15
|
-
/* Strict Type-Checking Options */
|
|
16
|
-
"strict": true,
|
|
17
|
-
|
|
18
|
-
/* Module Resolution Options */
|
|
19
|
-
"moduleResolution": "node",
|
|
20
|
-
"types": ["node", "jest"],
|
|
21
|
-
"allowSyntheticDefaultImports": true,
|
|
22
|
-
"esModuleInterop": true,
|
|
23
|
-
"skipLibCheck": true,
|
|
24
|
-
"resolveJsonModule": true
|
|
25
|
-
},
|
|
26
|
-
"include": [
|
|
27
|
-
"src/"
|
|
28
|
-
],
|
|
29
|
-
"exclude": [
|
|
30
|
-
"node_modules", "babel.config.cjs", "metro.config.js", "jest.config.js"
|
|
31
|
-
]
|
|
32
|
-
}
|