@jsonforms/core 3.3.0 → 3.4.0-alpha.1
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/lib/actions/actions.d.ts +3 -4
- package/lib/generators/Generate.d.ts +1 -1
- package/lib/i18n/i18nUtil.d.ts +1 -1
- package/lib/i18n/index.d.ts +2 -2
- package/lib/i18n/selectors.d.ts +7 -0
- package/lib/index.d.ts +1 -1
- package/lib/jsonforms-core.cjs.js +1921 -1916
- package/lib/jsonforms-core.cjs.js.map +1 -1
- package/lib/jsonforms-core.esm.js +1606 -1604
- package/lib/jsonforms-core.esm.js.map +1 -1
- package/lib/{util → mappers}/cell.d.ts +1 -3
- package/lib/{util → mappers}/combinators.d.ts +1 -1
- package/lib/mappers/index.d.ts +4 -0
- package/lib/{util → mappers}/renderer.d.ts +20 -6
- package/lib/mappers/util.d.ts +10 -0
- package/lib/models/uischema.d.ts +0 -8
- package/lib/reducers/cells.d.ts +1 -6
- package/lib/reducers/config.d.ts +1 -1
- package/lib/reducers/core.d.ts +7 -25
- package/lib/reducers/default-data.d.ts +3 -1
- package/lib/reducers/i18n.d.ts +2 -5
- package/lib/reducers/index.d.ts +0 -1
- package/lib/reducers/middleware.d.ts +1 -1
- package/lib/reducers/reducers.d.ts +8 -16
- package/lib/reducers/renderers.d.ts +2 -6
- package/lib/reducers/uischemas.d.ts +2 -6
- package/lib/store/index.d.ts +4 -0
- package/lib/store/jsonFormsCore.d.ts +19 -0
- package/lib/{store.d.ts → store/store.d.ts} +28 -3
- package/lib/testers/testers.d.ts +1 -0
- package/lib/util/errors.d.ts +5 -0
- package/lib/{Helpers.d.ts → util/helpers.d.ts} +1 -1
- package/lib/util/index.d.ts +2 -5
- package/lib/util/label.d.ts +1 -13
- package/lib/util/path.d.ts +6 -2
- package/lib/util/runtime.d.ts +1 -10
- package/lib/util/schema.d.ts +1 -1
- package/lib/util/uischema.d.ts +10 -7
- package/lib/util/util.d.ts +1 -2
- package/lib/util/validator.d.ts +2 -1
- package/package.json +1 -1
- package/src/actions/actions.ts +3 -4
- package/src/generators/Generate.ts +1 -1
- package/src/generators/uischema.ts +1 -3
- package/src/i18n/i18nUtil.ts +7 -4
- package/src/i18n/index.ts +2 -2
- package/src/i18n/selectors.ts +67 -0
- package/src/index.ts +1 -2
- package/src/{util → mappers}/cell.ts +19 -15
- package/src/{util → mappers}/combinators.ts +3 -2
- package/src/mappers/index.ts +29 -0
- package/src/{util → mappers}/renderer.ts +140 -32
- package/src/mappers/util.ts +43 -0
- package/src/models/uischema.ts +0 -29
- package/src/reducers/cells.ts +1 -7
- package/src/reducers/config.ts +1 -1
- package/src/reducers/core.ts +33 -200
- package/src/reducers/default-data.ts +8 -2
- package/src/reducers/i18n.ts +3 -27
- package/src/reducers/index.ts +0 -1
- package/src/reducers/middleware.ts +1 -1
- package/src/reducers/reducers.ts +3 -31
- package/src/reducers/renderers.ts +2 -7
- package/src/reducers/uischemas.ts +2 -12
- package/src/{util/array.ts → store/index.ts} +5 -19
- package/src/store/jsonFormsCore.ts +72 -0
- package/src/{store.ts → store/store.ts} +36 -8
- package/src/testers/testers.ts +6 -0
- package/src/util/errors.ts +142 -0
- package/src/{Helpers.ts → util/helpers.ts} +3 -2
- package/src/util/index.ts +2 -5
- package/src/util/label.ts +1 -98
- package/src/util/path.ts +12 -15
- package/src/util/runtime.ts +1 -44
- package/src/util/schema.ts +1 -1
- package/src/util/uischema.ts +52 -16
- package/src/util/util.ts +1 -9
- package/src/util/validator.ts +15 -1
- package/lib/reducers/selectors.d.ts +0 -15
- package/lib/util/array.d.ts +0 -3
- package/src/reducers/selectors.ts +0 -64
- /package/lib/{i18n → store}/i18nTypes.d.ts +0 -0
- /package/lib/{util → store}/type.d.ts +0 -0
- /package/src/{i18n → store}/i18nTypes.ts +0 -0
- /package/src/{util → store}/type.ts +0 -0
package/src/reducers/core.ts
CHANGED
|
@@ -27,11 +27,7 @@ import cloneDeep from 'lodash/cloneDeep';
|
|
|
27
27
|
import setFp from 'lodash/fp/set';
|
|
28
28
|
import unsetFp from 'lodash/fp/unset';
|
|
29
29
|
import get from 'lodash/get';
|
|
30
|
-
import filter from 'lodash/filter';
|
|
31
30
|
import isEqual from 'lodash/isEqual';
|
|
32
|
-
import isFunction from 'lodash/isFunction';
|
|
33
|
-
import type Ajv from 'ajv';
|
|
34
|
-
import type { ErrorObject, ValidateFunction } from 'ajv';
|
|
35
31
|
import {
|
|
36
32
|
CoreActions,
|
|
37
33
|
INIT,
|
|
@@ -41,45 +37,17 @@ import {
|
|
|
41
37
|
SET_SCHEMA,
|
|
42
38
|
SET_UISCHEMA,
|
|
43
39
|
SET_VALIDATION_MODE,
|
|
40
|
+
UPDATE_CORE,
|
|
44
41
|
UPDATE_DATA,
|
|
45
42
|
UPDATE_ERRORS,
|
|
46
|
-
UPDATE_CORE,
|
|
47
43
|
UpdateCoreAction,
|
|
48
44
|
} from '../actions';
|
|
49
|
-
import {
|
|
50
|
-
import
|
|
45
|
+
import { JsonFormsCore, Reducer, ValidationMode } from '../store';
|
|
46
|
+
import Ajv, { ErrorObject } from 'ajv';
|
|
47
|
+
import { isFunction } from 'lodash';
|
|
48
|
+
import { createAjv, validate } from '../util';
|
|
51
49
|
|
|
52
|
-
export const
|
|
53
|
-
validator: ValidateFunction | undefined,
|
|
54
|
-
data: any
|
|
55
|
-
): ErrorObject[] => {
|
|
56
|
-
if (validator === undefined) {
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
const valid = validator(data);
|
|
60
|
-
if (valid) {
|
|
61
|
-
return [];
|
|
62
|
-
}
|
|
63
|
-
return validator.errors;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export type ValidationMode =
|
|
67
|
-
| 'ValidateAndShow'
|
|
68
|
-
| 'ValidateAndHide'
|
|
69
|
-
| 'NoValidation';
|
|
70
|
-
|
|
71
|
-
export interface JsonFormsCore {
|
|
72
|
-
data: any;
|
|
73
|
-
schema: JsonSchema;
|
|
74
|
-
uischema: UISchemaElement;
|
|
75
|
-
errors?: ErrorObject[];
|
|
76
|
-
additionalErrors?: ErrorObject[];
|
|
77
|
-
validator?: ValidateFunction;
|
|
78
|
-
ajv?: Ajv;
|
|
79
|
-
validationMode?: ValidationMode;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const initState: JsonFormsCore = {
|
|
50
|
+
export const initState: JsonFormsCore = {
|
|
83
51
|
data: {},
|
|
84
52
|
schema: {},
|
|
85
53
|
uischema: undefined,
|
|
@@ -90,32 +58,7 @@ const initState: JsonFormsCore = {
|
|
|
90
58
|
additionalErrors: [],
|
|
91
59
|
};
|
|
92
60
|
|
|
93
|
-
const
|
|
94
|
-
state: JsonFormsCore,
|
|
95
|
-
action?: InitAction | UpdateCoreAction
|
|
96
|
-
): Ajv => {
|
|
97
|
-
if (action) {
|
|
98
|
-
if (hasAjvOption(action.options)) {
|
|
99
|
-
// options object with ajv
|
|
100
|
-
return action.options.ajv;
|
|
101
|
-
} else if (action.options !== undefined) {
|
|
102
|
-
// it is not an option object => should be ajv itself => check for compile function
|
|
103
|
-
if (isFunction(action.options.compile)) {
|
|
104
|
-
return action.options;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return state.ajv ? state.ajv : createAjv();
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const hasAjvOption = (option: any): option is InitActionOptions => {
|
|
112
|
-
if (option) {
|
|
113
|
-
return option.ajv !== undefined;
|
|
114
|
-
}
|
|
115
|
-
return false;
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const getValidationMode = (
|
|
61
|
+
export const getValidationMode = (
|
|
119
62
|
state: JsonFormsCore,
|
|
120
63
|
action?: InitAction | UpdateCoreAction
|
|
121
64
|
): ValidationMode => {
|
|
@@ -141,7 +84,7 @@ const hasAdditionalErrorsOption = (
|
|
|
141
84
|
return false;
|
|
142
85
|
};
|
|
143
86
|
|
|
144
|
-
const getAdditionalErrors = (
|
|
87
|
+
export const getAdditionalErrors = (
|
|
145
88
|
state: JsonFormsCore,
|
|
146
89
|
action?: InitAction | UpdateCoreAction
|
|
147
90
|
): ErrorObject[] => {
|
|
@@ -151,6 +94,31 @@ const getAdditionalErrors = (
|
|
|
151
94
|
return state.additionalErrors;
|
|
152
95
|
};
|
|
153
96
|
|
|
97
|
+
export const getOrCreateAjv = (
|
|
98
|
+
state: JsonFormsCore,
|
|
99
|
+
action?: InitAction | UpdateCoreAction
|
|
100
|
+
): Ajv => {
|
|
101
|
+
if (action) {
|
|
102
|
+
if (hasAjvOption(action.options)) {
|
|
103
|
+
// options object with ajv
|
|
104
|
+
return action.options.ajv;
|
|
105
|
+
} else if (action.options !== undefined) {
|
|
106
|
+
// it is not an option object => should be ajv itself => check for compile function
|
|
107
|
+
if (isFunction(action.options.compile)) {
|
|
108
|
+
return action.options;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return state.ajv ? state.ajv : createAjv();
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const hasAjvOption = (option: any): option is InitActionOptions => {
|
|
116
|
+
if (option) {
|
|
117
|
+
return option.ajv !== undefined;
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
};
|
|
121
|
+
|
|
154
122
|
export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
155
123
|
state = initState,
|
|
156
124
|
action
|
|
@@ -329,138 +297,3 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
329
297
|
return state;
|
|
330
298
|
}
|
|
331
299
|
};
|
|
332
|
-
|
|
333
|
-
export const extractData = (state: JsonFormsCore) => get(state, 'data');
|
|
334
|
-
export const extractSchema = (state: JsonFormsCore) => get(state, 'schema');
|
|
335
|
-
export const extractUiSchema = (state: JsonFormsCore) => get(state, 'uischema');
|
|
336
|
-
export const extractAjv = (state: JsonFormsCore) => get(state, 'ajv');
|
|
337
|
-
|
|
338
|
-
const getInvalidProperty = (error: ErrorObject): string | undefined => {
|
|
339
|
-
switch (error.keyword) {
|
|
340
|
-
case 'required':
|
|
341
|
-
case 'dependencies':
|
|
342
|
-
return error.params.missingProperty;
|
|
343
|
-
case 'additionalProperties':
|
|
344
|
-
return error.params.additionalProperty;
|
|
345
|
-
default:
|
|
346
|
-
return undefined;
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
export const getControlPath = (error: ErrorObject) => {
|
|
351
|
-
// Up until AJV v7 the path property was called 'dataPath'
|
|
352
|
-
// With AJV v8 the property was renamed to 'instancePath'
|
|
353
|
-
let controlPath = (error as any).dataPath || error.instancePath || '';
|
|
354
|
-
|
|
355
|
-
// change '/' chars to '.'
|
|
356
|
-
controlPath = controlPath.replace(/\//g, '.');
|
|
357
|
-
|
|
358
|
-
const invalidProperty = getInvalidProperty(error);
|
|
359
|
-
if (invalidProperty !== undefined && !controlPath.endsWith(invalidProperty)) {
|
|
360
|
-
controlPath = `${controlPath}.${invalidProperty}`;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// remove '.' chars at the beginning of paths
|
|
364
|
-
controlPath = controlPath.replace(/^./, '');
|
|
365
|
-
|
|
366
|
-
// decode JSON Pointer escape sequences
|
|
367
|
-
controlPath = decode(controlPath);
|
|
368
|
-
return controlPath;
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
export const errorsAt =
|
|
372
|
-
(
|
|
373
|
-
instancePath: string,
|
|
374
|
-
schema: JsonSchema,
|
|
375
|
-
matchPath: (path: string) => boolean
|
|
376
|
-
) =>
|
|
377
|
-
(errors: ErrorObject[]): ErrorObject[] => {
|
|
378
|
-
// Get data paths of oneOf and anyOf errors to later determine whether an error occurred inside a subschema of oneOf or anyOf.
|
|
379
|
-
const combinatorPaths = filter(
|
|
380
|
-
errors,
|
|
381
|
-
(error) => error.keyword === 'oneOf' || error.keyword === 'anyOf'
|
|
382
|
-
).map((error) => getControlPath(error));
|
|
383
|
-
|
|
384
|
-
return filter(errors, (error) => {
|
|
385
|
-
// Filter errors that match any keyword that we don't want to show in the UI
|
|
386
|
-
// but keep the errors for oneOf enums
|
|
387
|
-
if (
|
|
388
|
-
filteredErrorKeywords.indexOf(error.keyword) !== -1 &&
|
|
389
|
-
!isOneOfEnumSchema(error.parentSchema)
|
|
390
|
-
) {
|
|
391
|
-
return false;
|
|
392
|
-
}
|
|
393
|
-
const controlPath = getControlPath(error);
|
|
394
|
-
let result = matchPath(controlPath);
|
|
395
|
-
// In anyOf and oneOf blocks with "primitive" (i.e. string, number etc.) or array subschemas,
|
|
396
|
-
// we want to make sure that errors are only shown for the correct subschema.
|
|
397
|
-
// Therefore, we compare the error's parent schema with the property's schema.
|
|
398
|
-
// In the primitive case the error's data path is the same for all subschemas:
|
|
399
|
-
// It directly points to the property defining the anyOf/oneOf.
|
|
400
|
-
// The same holds true for errors on the array level (e.g. min item amount).
|
|
401
|
-
// In contrast, this comparison must not be done for errors whose parent schema defines an object or a oneOf enum,
|
|
402
|
-
// because the parent schema can never match the property schema (e.g. for 'required' checks).
|
|
403
|
-
const parentSchema: JsonSchema | undefined = error.parentSchema;
|
|
404
|
-
if (
|
|
405
|
-
result &&
|
|
406
|
-
!isObjectSchema(parentSchema) &&
|
|
407
|
-
!isOneOfEnumSchema(parentSchema) &&
|
|
408
|
-
combinatorPaths.findIndex((p) => instancePath.startsWith(p)) !== -1
|
|
409
|
-
) {
|
|
410
|
-
result = result && isEqual(parentSchema, schema);
|
|
411
|
-
}
|
|
412
|
-
return result;
|
|
413
|
-
});
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* @returns true if the schema describes an object.
|
|
418
|
-
*/
|
|
419
|
-
const isObjectSchema = (schema?: JsonSchema): boolean => {
|
|
420
|
-
return schema?.type === 'object' || !!schema?.properties;
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* The error-type of an AJV error is defined by its `keyword` property.
|
|
425
|
-
* Certain errors are filtered because they don't fit to any rendered control.
|
|
426
|
-
* All of them have in common that we don't want to show them in the UI
|
|
427
|
-
* because controls will show the actual reason why they don't match their correponding sub schema.
|
|
428
|
-
* - additionalProperties: Indicates that a property is present that is not defined in the schema.
|
|
429
|
-
* Jsonforms only allows to edit defined properties. These errors occur if an oneOf doesn't match.
|
|
430
|
-
* - allOf: Indicates that not all of the allOf definitions match as a whole.
|
|
431
|
-
* - anyOf: Indicates that an anyOf definition itself is not valid because none of its subschemas matches.
|
|
432
|
-
* - oneOf: Indicates that an oneOf definition itself is not valid because not exactly one of its subschemas matches.
|
|
433
|
-
*/
|
|
434
|
-
const filteredErrorKeywords = [
|
|
435
|
-
'additionalProperties',
|
|
436
|
-
'allOf',
|
|
437
|
-
'anyOf',
|
|
438
|
-
'oneOf',
|
|
439
|
-
];
|
|
440
|
-
|
|
441
|
-
const getErrorsAt =
|
|
442
|
-
(
|
|
443
|
-
instancePath: string,
|
|
444
|
-
schema: JsonSchema,
|
|
445
|
-
matchPath: (path: string) => boolean
|
|
446
|
-
) =>
|
|
447
|
-
(state: JsonFormsCore): ErrorObject[] => {
|
|
448
|
-
const errors = state.errors ?? [];
|
|
449
|
-
const additionalErrors = state.additionalErrors ?? [];
|
|
450
|
-
return errorsAt(
|
|
451
|
-
instancePath,
|
|
452
|
-
schema,
|
|
453
|
-
matchPath
|
|
454
|
-
)(
|
|
455
|
-
state.validationMode === 'ValidateAndHide'
|
|
456
|
-
? additionalErrors
|
|
457
|
-
: [...errors, ...additionalErrors]
|
|
458
|
-
);
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
export const errorAt = (instancePath: string, schema: JsonSchema) =>
|
|
462
|
-
getErrorsAt(instancePath, schema, (path) => path === instancePath);
|
|
463
|
-
export const subErrorsAt = (instancePath: string, schema: JsonSchema) =>
|
|
464
|
-
getErrorsAt(instancePath, schema, (path) =>
|
|
465
|
-
path.startsWith(instancePath + '.')
|
|
466
|
-
);
|
|
@@ -23,13 +23,15 @@
|
|
|
23
23
|
THE SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
+
import get from 'lodash/get';
|
|
26
27
|
import {
|
|
27
28
|
ADD_DEFAULT_DATA,
|
|
28
|
-
RegisterDefaultDataAction,
|
|
29
29
|
REMOVE_DEFAULT_DATA,
|
|
30
|
+
RegisterDefaultDataAction,
|
|
30
31
|
UnregisterDefaultDataAction,
|
|
31
32
|
} from '../actions';
|
|
32
|
-
import type { Reducer } from '../
|
|
33
|
+
import type { Reducer } from '../store/type';
|
|
34
|
+
import { JsonFormsState } from '../store';
|
|
33
35
|
|
|
34
36
|
export interface JsonFormsDefaultDataRegistryEntry {
|
|
35
37
|
schemaPath: string;
|
|
@@ -56,6 +58,10 @@ export const defaultDataReducer: Reducer<
|
|
|
56
58
|
}
|
|
57
59
|
};
|
|
58
60
|
|
|
61
|
+
export const getDefaultData = (
|
|
62
|
+
state: JsonFormsState
|
|
63
|
+
): JsonFormsDefaultDataRegistryEntry[] =>
|
|
64
|
+
extractDefaultData(get(state, 'jsonforms.defaultData'));
|
|
59
65
|
export const extractDefaultData = (
|
|
60
66
|
state: JsonFormsDefaultDataRegistryEntry[]
|
|
61
67
|
): JsonFormsDefaultDataRegistryEntry[] => state;
|
package/src/reducers/i18n.ts
CHANGED
|
@@ -23,18 +23,15 @@
|
|
|
23
23
|
THE SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import {
|
|
27
|
-
defaultErrorTranslator,
|
|
28
|
-
defaultTranslator,
|
|
29
|
-
JsonFormsI18nState,
|
|
30
|
-
} from '../i18n';
|
|
26
|
+
import { defaultErrorTranslator, defaultTranslator } from '../i18n';
|
|
31
27
|
import {
|
|
32
28
|
I18nActions,
|
|
33
29
|
SET_LOCALE,
|
|
34
30
|
SET_TRANSLATOR,
|
|
35
31
|
UPDATE_I18N,
|
|
36
32
|
} from '../actions';
|
|
37
|
-
import
|
|
33
|
+
import { Reducer } from '../store/type';
|
|
34
|
+
import { JsonFormsI18nState } from '../store';
|
|
38
35
|
|
|
39
36
|
export const defaultJsonFormsI18nState: Required<JsonFormsI18nState> = {
|
|
40
37
|
locale: 'en',
|
|
@@ -83,24 +80,3 @@ export const i18nReducer: Reducer<JsonFormsI18nState, I18nActions> = (
|
|
|
83
80
|
return state;
|
|
84
81
|
}
|
|
85
82
|
};
|
|
86
|
-
|
|
87
|
-
export const fetchLocale = (state?: JsonFormsI18nState) => {
|
|
88
|
-
if (state === undefined) {
|
|
89
|
-
return undefined;
|
|
90
|
-
}
|
|
91
|
-
return state.locale;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export const fetchTranslator = (state?: JsonFormsI18nState) => {
|
|
95
|
-
if (state === undefined) {
|
|
96
|
-
return defaultTranslator;
|
|
97
|
-
}
|
|
98
|
-
return state.translate;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export const fetchErrorTranslator = (state?: JsonFormsI18nState) => {
|
|
102
|
-
if (state === undefined) {
|
|
103
|
-
return defaultErrorTranslator;
|
|
104
|
-
}
|
|
105
|
-
return state.translateError;
|
|
106
|
-
};
|
package/src/reducers/index.ts
CHANGED
package/src/reducers/reducers.ts
CHANGED
|
@@ -24,22 +24,18 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import type { ControlElement, UISchemaElement } from '../models';
|
|
27
|
-
import { coreReducer, errorAt, subErrorsAt } from './core';
|
|
28
27
|
import { defaultDataReducer } from './default-data';
|
|
29
28
|
import { rendererReducer } from './renderers';
|
|
30
|
-
import type { JsonFormsState } from '../store';
|
|
31
|
-
import type { JsonFormsUISchemaRegistryEntry } from './uischemas';
|
|
32
29
|
import { findMatchingUISchema, uischemaRegistryReducer } from './uischemas';
|
|
33
|
-
import {
|
|
30
|
+
import { i18nReducer } from './i18n';
|
|
34
31
|
|
|
35
32
|
import { Generate } from '../generators';
|
|
36
33
|
import type { JsonSchema } from '../models/jsonSchema';
|
|
37
34
|
|
|
38
35
|
import { cellReducer } from './cells';
|
|
39
36
|
import { configReducer } from './config';
|
|
40
|
-
import
|
|
41
|
-
import {
|
|
42
|
-
import type { ErrorTranslator, Translator } from '../i18n';
|
|
37
|
+
import { coreReducer } from './core';
|
|
38
|
+
import { JsonFormsUISchemaRegistryEntry } from '../store';
|
|
43
39
|
|
|
44
40
|
export const jsonFormsReducerConfig = {
|
|
45
41
|
core: coreReducer,
|
|
@@ -100,27 +96,3 @@ export const findUISchema = (
|
|
|
100
96
|
}
|
|
101
97
|
return uiSchema;
|
|
102
98
|
};
|
|
103
|
-
|
|
104
|
-
export const getErrorAt =
|
|
105
|
-
(instancePath: string, schema: JsonSchema) => (state: JsonFormsState) => {
|
|
106
|
-
return errorAt(instancePath, schema)(state.jsonforms.core);
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
export const getSubErrorsAt =
|
|
110
|
-
(instancePath: string, schema: JsonSchema) => (state: JsonFormsState) =>
|
|
111
|
-
subErrorsAt(instancePath, schema)(state.jsonforms.core);
|
|
112
|
-
|
|
113
|
-
export const getConfig = (state: JsonFormsState) => state.jsonforms.config;
|
|
114
|
-
|
|
115
|
-
export const getLocale = (state: JsonFormsState) =>
|
|
116
|
-
fetchLocale(get(state, 'jsonforms.i18n'));
|
|
117
|
-
|
|
118
|
-
export const getTranslator =
|
|
119
|
-
() =>
|
|
120
|
-
(state: JsonFormsState): Translator =>
|
|
121
|
-
fetchTranslator(get(state, 'jsonforms.i18n'));
|
|
122
|
-
|
|
123
|
-
export const getErrorTranslator =
|
|
124
|
-
() =>
|
|
125
|
-
(state: JsonFormsState): ErrorTranslator =>
|
|
126
|
-
fetchErrorTranslator(get(state, 'jsonforms.i18n'));
|
|
@@ -23,19 +23,14 @@
|
|
|
23
23
|
THE SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import type { RankedTester } from '../testers';
|
|
27
26
|
import {
|
|
28
27
|
ADD_RENDERER,
|
|
29
28
|
AddRendererAction,
|
|
30
29
|
REMOVE_RENDERER,
|
|
31
30
|
RemoveRendererAction,
|
|
32
31
|
} from '../actions';
|
|
33
|
-
import
|
|
34
|
-
|
|
35
|
-
export interface JsonFormsRendererRegistryEntry {
|
|
36
|
-
tester: RankedTester;
|
|
37
|
-
renderer: any;
|
|
38
|
-
}
|
|
32
|
+
import { Reducer } from '../store/type';
|
|
33
|
+
import { JsonFormsRendererRegistryEntry } from '../store';
|
|
39
34
|
|
|
40
35
|
type ValidRendererReducerActions = AddRendererAction | RemoveRendererAction;
|
|
41
36
|
|
|
@@ -28,18 +28,8 @@ import remove from 'lodash/remove';
|
|
|
28
28
|
import { ADD_UI_SCHEMA, REMOVE_UI_SCHEMA, UISchemaActions } from '../actions';
|
|
29
29
|
import { NOT_APPLICABLE } from '../testers';
|
|
30
30
|
import type { JsonSchema, UISchemaElement } from '../models';
|
|
31
|
-
import type { Reducer } from '../
|
|
32
|
-
|
|
33
|
-
export type UISchemaTester = (
|
|
34
|
-
schema: JsonSchema,
|
|
35
|
-
schemaPath: string,
|
|
36
|
-
path: string
|
|
37
|
-
) => number;
|
|
38
|
-
|
|
39
|
-
export interface JsonFormsUISchemaRegistryEntry {
|
|
40
|
-
tester: UISchemaTester;
|
|
41
|
-
uischema: UISchemaElement;
|
|
42
|
-
}
|
|
31
|
+
import type { Reducer } from '../store/type';
|
|
32
|
+
import { JsonFormsUISchemaRegistryEntry } from '../store';
|
|
43
33
|
|
|
44
34
|
export const uischemaRegistryReducer: Reducer<
|
|
45
35
|
JsonFormsUISchemaRegistryEntry[],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
The MIT License
|
|
3
3
|
|
|
4
|
-
Copyright (c)
|
|
4
|
+
Copyright (c) 2024-2024 EclipseSource Munich
|
|
5
5
|
https://github.com/eclipsesource/jsonforms
|
|
6
6
|
|
|
7
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -23,21 +23,7 @@
|
|
|
23
23
|
THE SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
} // Already at the top or bottom.
|
|
31
|
-
const indexes: number[] = [index, newIndex].sort((a, b) => a - b); // Sort the indixes
|
|
32
|
-
array.splice(indexes[0], 2, array[indexes[1]], array[indexes[0]]);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const moveUp = (array: any[], toMove: number) => {
|
|
36
|
-
move(array, toMove, -1);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const moveDown = (array: any[], toMove: number) => {
|
|
40
|
-
move(array, toMove, 1);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export { moveUp, moveDown };
|
|
26
|
+
export * from './store';
|
|
27
|
+
export * from './type';
|
|
28
|
+
export * from './i18nTypes';
|
|
29
|
+
export * from './jsonFormsCore';
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import Ajv, { ErrorObject } from 'ajv';
|
|
2
|
+
import { JsonSchema, UISchemaElement } from '../models';
|
|
3
|
+
import get from 'lodash/get';
|
|
4
|
+
import { errorsAt } from '../util';
|
|
5
|
+
import {
|
|
6
|
+
JsonFormsCellRendererRegistryEntry,
|
|
7
|
+
JsonFormsCore,
|
|
8
|
+
JsonFormsRendererRegistryEntry,
|
|
9
|
+
JsonFormsState,
|
|
10
|
+
JsonFormsUISchemaRegistryEntry,
|
|
11
|
+
} from './store';
|
|
12
|
+
|
|
13
|
+
const getErrorsAt =
|
|
14
|
+
(
|
|
15
|
+
instancePath: string,
|
|
16
|
+
schema: JsonSchema,
|
|
17
|
+
matchPath: (path: string) => boolean
|
|
18
|
+
) =>
|
|
19
|
+
(state: JsonFormsCore): ErrorObject[] => {
|
|
20
|
+
const errors = state.errors ?? [];
|
|
21
|
+
const additionalErrors = state.additionalErrors ?? [];
|
|
22
|
+
return errorsAt(
|
|
23
|
+
instancePath,
|
|
24
|
+
schema,
|
|
25
|
+
matchPath
|
|
26
|
+
)(
|
|
27
|
+
state.validationMode === 'ValidateAndHide'
|
|
28
|
+
? additionalErrors
|
|
29
|
+
: [...errors, ...additionalErrors]
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const errorAt = (instancePath: string, schema: JsonSchema) =>
|
|
34
|
+
getErrorsAt(instancePath, schema, (path) => path === instancePath);
|
|
35
|
+
export const subErrorsAt = (instancePath: string, schema: JsonSchema) =>
|
|
36
|
+
getErrorsAt(instancePath, schema, (path) =>
|
|
37
|
+
path.startsWith(instancePath + '.')
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
export const getErrorAt =
|
|
41
|
+
(instancePath: string, schema: JsonSchema) => (state: JsonFormsState) => {
|
|
42
|
+
return errorAt(instancePath, schema)(state.jsonforms.core);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const getSubErrorsAt =
|
|
46
|
+
(instancePath: string, schema: JsonSchema) => (state: JsonFormsState) =>
|
|
47
|
+
subErrorsAt(instancePath, schema)(state.jsonforms.core);
|
|
48
|
+
|
|
49
|
+
export const getData = (state: JsonFormsState) =>
|
|
50
|
+
extractData(get(state, 'jsonforms.core'));
|
|
51
|
+
export const getSchema = (state: JsonFormsState): JsonSchema =>
|
|
52
|
+
extractSchema(get(state, 'jsonforms.core'));
|
|
53
|
+
export const getUiSchema = (state: JsonFormsState): UISchemaElement =>
|
|
54
|
+
extractUiSchema(get(state, 'jsonforms.core'));
|
|
55
|
+
export const getAjv = (state: JsonFormsState): Ajv =>
|
|
56
|
+
extractAjv(get(state, 'jsonforms.core'));
|
|
57
|
+
export const getRenderers = (
|
|
58
|
+
state: JsonFormsState
|
|
59
|
+
): JsonFormsRendererRegistryEntry[] => get(state, 'jsonforms.renderers');
|
|
60
|
+
export const getCells = (
|
|
61
|
+
state: JsonFormsState
|
|
62
|
+
): JsonFormsCellRendererRegistryEntry[] => get(state, 'jsonforms.cells');
|
|
63
|
+
export const getUISchemas = (
|
|
64
|
+
state: JsonFormsState
|
|
65
|
+
): JsonFormsUISchemaRegistryEntry[] => get(state, 'jsonforms.uischemas');
|
|
66
|
+
|
|
67
|
+
export const extractData = (state: JsonFormsCore) => get(state, 'data');
|
|
68
|
+
export const extractSchema = (state: JsonFormsCore) => get(state, 'schema');
|
|
69
|
+
export const extractUiSchema = (state: JsonFormsCore) => get(state, 'uischema');
|
|
70
|
+
export const extractAjv = (state: JsonFormsCore) => get(state, 'ajv');
|
|
71
|
+
|
|
72
|
+
export const getConfig = (state: JsonFormsState) => state.jsonforms.config;
|
|
@@ -23,14 +23,11 @@
|
|
|
23
23
|
THE SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import type { Store } from './
|
|
27
|
-
import
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
JsonFormsUISchemaRegistryEntry,
|
|
32
|
-
} from './reducers';
|
|
33
|
-
import type { JsonFormsI18nState } from './i18n';
|
|
26
|
+
import type { Store } from './type';
|
|
27
|
+
import { RankedTester, UISchemaTester } from '../testers';
|
|
28
|
+
import { JsonSchema, UISchemaElement } from '../models';
|
|
29
|
+
import Ajv, { ErrorObject, ValidateFunction } from 'ajv';
|
|
30
|
+
import { JsonFormsI18nState } from './i18nTypes';
|
|
34
31
|
|
|
35
32
|
/**
|
|
36
33
|
* JSONForms store.
|
|
@@ -80,6 +77,37 @@ export interface JsonFormsSubStates {
|
|
|
80
77
|
[additionalState: string]: any;
|
|
81
78
|
}
|
|
82
79
|
|
|
80
|
+
export type ValidationMode =
|
|
81
|
+
| 'ValidateAndShow'
|
|
82
|
+
| 'ValidateAndHide'
|
|
83
|
+
| 'NoValidation';
|
|
84
|
+
|
|
85
|
+
export interface JsonFormsCore {
|
|
86
|
+
data: any;
|
|
87
|
+
schema: JsonSchema;
|
|
88
|
+
uischema: UISchemaElement;
|
|
89
|
+
errors?: ErrorObject[];
|
|
90
|
+
additionalErrors?: ErrorObject[];
|
|
91
|
+
validator?: ValidateFunction;
|
|
92
|
+
ajv?: Ajv;
|
|
93
|
+
validationMode?: ValidationMode;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface JsonFormsRendererRegistryEntry {
|
|
97
|
+
tester: RankedTester;
|
|
98
|
+
renderer: any;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface JsonFormsUISchemaRegistryEntry {
|
|
102
|
+
tester: UISchemaTester;
|
|
103
|
+
uischema: UISchemaElement;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface JsonFormsCellRendererRegistryEntry {
|
|
107
|
+
tester: RankedTester;
|
|
108
|
+
cell: any;
|
|
109
|
+
}
|
|
110
|
+
|
|
83
111
|
export interface JsonFormsExtendedState<T> extends JsonFormsState {
|
|
84
112
|
jsonforms: {
|
|
85
113
|
[subState: string]: T;
|
package/src/testers/testers.ts
CHANGED
|
@@ -81,6 +81,12 @@ export interface TesterContext {
|
|
|
81
81
|
config: any;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
export type UISchemaTester = (
|
|
85
|
+
schema: JsonSchema,
|
|
86
|
+
schemaPath: string,
|
|
87
|
+
path: string
|
|
88
|
+
) => number;
|
|
89
|
+
|
|
84
90
|
export const isControl = (uischema: any): uischema is ControlElement =>
|
|
85
91
|
!isEmpty(uischema) && uischema.scope !== undefined;
|
|
86
92
|
|