@jsonforms/core 3.0.0-alpha.1 → 3.0.0-beta.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/docs/assets/js/search.json +1 -1
- package/docs/globals.html +822 -405
- package/docs/index.html +69 -36
- package/docs/interfaces/addcellrendereraction.html +3 -3
- package/docs/interfaces/addrendereraction.html +3 -3
- package/docs/interfaces/adduischemaaction.html +3 -3
- package/docs/interfaces/arraycontrolprops.html +21 -21
- package/docs/interfaces/arraylayoutprops.html +21 -21
- package/docs/interfaces/cellprops.html +14 -14
- package/docs/interfaces/combinatorrendererprops.html +13 -13
- package/docs/interfaces/controlprops.html +16 -16
- package/docs/interfaces/controlstate.html +2 -2
- package/docs/interfaces/controlwithdetailprops.html +17 -17
- package/docs/interfaces/dispatchcellprops.html +13 -13
- package/docs/interfaces/dispatchcellstateprops.html +13 -13
- package/docs/interfaces/dispatchpropsofarraycontrol.html +4 -4
- package/docs/interfaces/dispatchpropsofcontrol.html +1 -1
- package/docs/interfaces/dispatchpropsofmultienumcontrol.html +2 -2
- package/docs/interfaces/enumcellprops.html +15 -15
- package/docs/interfaces/enumoption.html +2 -2
- package/docs/interfaces/initaction.html +6 -6
- package/docs/interfaces/initactionoptions.html +3 -3
- package/docs/interfaces/jsonformscore.html +7 -7
- package/docs/interfaces/{jsonformslocalestate.html → jsonformsi18nstate.html} +20 -20
- package/docs/interfaces/jsonformsprops.html +9 -9
- package/docs/interfaces/jsonformssubstates.html +11 -1
- package/docs/interfaces/layoutprops.html +10 -10
- package/docs/interfaces/ownpropsofcell.html +10 -10
- package/docs/interfaces/ownpropsofcontrol.html +9 -9
- package/docs/interfaces/ownpropsofenum.html +1 -1
- package/docs/interfaces/ownpropsofenumcell.html +11 -11
- package/docs/interfaces/ownpropsofjsonformsrenderer.html +8 -8
- package/docs/interfaces/ownpropsoflayout.html +9 -9
- package/docs/interfaces/ownpropsofmasterlistitem.html +6 -6
- package/docs/interfaces/ownpropsofrenderer.html +8 -8
- package/docs/interfaces/registerdefaultdataaction.html +3 -3
- package/docs/interfaces/removecellrendereraction.html +3 -3
- package/docs/interfaces/removerendereraction.html +3 -3
- package/docs/interfaces/removeuischemaaction.html +2 -2
- package/docs/interfaces/rendererprops.html +9 -9
- package/docs/interfaces/setajvaction.html +3 -3
- package/docs/interfaces/setconfigaction.html +2 -2
- package/docs/interfaces/setlocaleaction.html +3 -3
- package/docs/interfaces/setschemaaction.html +2 -2
- package/docs/interfaces/{setlocalizedschemasaction.html → settranslatoraction.html} +29 -15
- package/docs/interfaces/setuischemaaction.html +2 -2
- package/docs/interfaces/setvalidationmodeaction.html +2 -2
- package/docs/interfaces/statepropsofarraycontrol.html +17 -17
- package/docs/interfaces/statepropsofarraylayout.html +17 -17
- package/docs/interfaces/statepropsofcell.html +13 -13
- package/docs/interfaces/statepropsofcombinator.html +12 -12
- package/docs/interfaces/statepropsofcontrol.html +15 -15
- package/docs/interfaces/statepropsofcontrolwithdetail.html +16 -16
- package/docs/interfaces/statepropsofenumcell.html +14 -14
- package/docs/interfaces/statepropsofjsonformsrenderer.html +9 -9
- package/docs/interfaces/statepropsoflayout.html +10 -10
- package/docs/interfaces/statepropsofmasteritem.html +7 -7
- package/docs/interfaces/statepropsofrenderer.html +9 -9
- package/docs/interfaces/statepropsofscopedrenderer.html +12 -12
- package/docs/interfaces/unregisterdefaultdataaction.html +2 -2
- package/docs/interfaces/updateaction.html +3 -3
- package/docs/interfaces/updatecoreaction.html +6 -6
- package/docs/interfaces/updateerrorsaction.html +2 -2
- package/docs/interfaces/{setlocalizeduischemasaction.html → updatei18naction.html} +43 -15
- package/docs/interfaces/withclassname.html +1 -1
- package/lib/Helpers.d.ts +5 -5
- package/lib/actions/actions.d.ts +181 -177
- package/lib/actions/index.d.ts +1 -1
- package/lib/configDefault.d.ts +6 -6
- package/lib/generators/Generate.d.ts +6 -6
- package/lib/generators/index.d.ts +3 -3
- package/lib/generators/schema.d.ts +8 -8
- package/lib/generators/uischema.d.ts +12 -12
- package/lib/i18n/i18nTypes.d.ts +15 -0
- package/lib/i18n/i18nUtil.d.ts +18 -0
- package/lib/i18n/index.d.ts +2 -0
- package/lib/index.d.ts +11 -10
- package/lib/jsonforms-core.cjs.js +2445 -0
- package/lib/jsonforms-core.cjs.js.map +1 -0
- package/lib/jsonforms-core.esm.js +2164 -0
- package/lib/jsonforms-core.esm.js.map +1 -0
- package/lib/models/draft4.d.ts +198 -198
- package/lib/models/index.d.ts +5 -5
- package/lib/models/jsonSchema.d.ts +3 -3
- package/lib/models/jsonSchema4.d.ts +110 -110
- package/lib/models/jsonSchema7.d.ts +119 -119
- package/lib/models/uischema.d.ts +201 -201
- package/lib/reducers/cells.d.ts +11 -11
- package/lib/reducers/config.d.ts +3 -3
- package/lib/reducers/core.d.ts +24 -23
- package/lib/reducers/default-data.d.ts +10 -10
- package/lib/reducers/i18n.d.ts +8 -11
- package/lib/reducers/index.d.ts +9 -9
- package/lib/reducers/reducers.d.ts +29 -36
- package/lib/reducers/renderers.d.ts +10 -10
- package/lib/reducers/selectors.d.ts +15 -15
- package/lib/reducers/uischemas.d.ts +10 -10
- package/lib/store.d.ts +53 -52
- package/lib/testers/index.d.ts +1 -1
- package/lib/testers/testers.d.ts +203 -203
- package/lib/util/Formatted.d.ts +19 -19
- package/lib/util/array.d.ts +3 -3
- package/lib/util/cell.d.ts +79 -79
- package/lib/util/combinators.d.ts +10 -10
- package/lib/util/ids.d.ts +3 -3
- package/lib/util/index.d.ts +15 -15
- package/lib/util/label.d.ts +9 -9
- package/lib/util/path.d.ts +25 -25
- package/lib/util/renderer.d.ts +398 -387
- package/lib/util/resolvers.d.ts +25 -25
- package/lib/util/runtime.d.ts +18 -19
- package/lib/util/schema.d.ts +1 -1
- package/lib/util/type.d.ts +174 -174
- package/lib/util/uischema.d.ts +5 -5
- package/lib/util/util.d.ts +31 -31
- package/lib/util/validator.d.ts +3 -2
- package/package.json +18 -14
- package/rollup.config.js +44 -0
- package/src/actions/actions.ts +46 -36
- package/src/i18n/i18nTypes.ts +17 -0
- package/src/i18n/i18nUtil.ts +105 -0
- package/src/i18n/index.ts +2 -0
- package/src/index.ts +1 -0
- package/src/reducers/core.ts +70 -48
- package/src/reducers/i18n.ts +41 -35
- package/src/reducers/reducers.ts +10 -29
- package/src/reducers/selectors.ts +1 -1
- package/src/store.ts +4 -4
- package/src/util/cell.ts +26 -6
- package/src/util/renderer.ts +127 -38
- package/src/util/runtime.ts +1 -1
- package/src/util/util.ts +1 -1
- package/src/util/validator.ts +5 -9
- package/stats.html +3279 -0
- package/{lib/reducers/cells.js → test/i18n/i18nUtil.test.ts} +25 -17
- package/test/reducers/core.test.ts +31 -44
- package/test/util/cell.test.ts +2 -2
- package/test/util/renderer.test.ts +488 -35
- package/lib/Helpers.js +0 -32
- package/lib/Helpers.js.map +0 -1
- package/lib/actions/actions.js +0 -149
- package/lib/actions/actions.js.map +0 -1
- package/lib/actions/index.js +0 -29
- package/lib/actions/index.js.map +0 -1
- package/lib/configDefault.js +0 -47
- package/lib/configDefault.js.map +0 -1
- package/lib/generators/Generate.js +0 -34
- package/lib/generators/Generate.js.map +0 -1
- package/lib/generators/index.js +0 -31
- package/lib/generators/index.js.map +0 -1
- package/lib/generators/schema.js +0 -152
- package/lib/generators/schema.js.map +0 -1
- package/lib/generators/uischema.js +0 -166
- package/lib/generators/uischema.js.map +0 -1
- package/lib/index.js +0 -37
- package/lib/index.js.map +0 -1
- package/lib/jsonforms-core.js +0 -19
- package/lib/jsonforms-core.js.map +0 -1
- package/lib/models/draft4.js +0 -173
- package/lib/models/draft4.js.map +0 -1
- package/lib/models/index.js +0 -30
- package/lib/models/index.js.map +0 -1
- package/lib/models/jsonSchema.js +0 -27
- package/lib/models/jsonSchema.js.map +0 -1
- package/lib/models/jsonSchema4.js +0 -30
- package/lib/models/jsonSchema4.js.map +0 -1
- package/lib/models/jsonSchema7.js +0 -30
- package/lib/models/jsonSchema7.js.map +0 -1
- package/lib/models/uischema.js +0 -55
- package/lib/models/uischema.js.map +0 -1
- package/lib/reducers/cells.js.map +0 -1
- package/lib/reducers/config.js +0 -44
- package/lib/reducers/config.js.map +0 -1
- package/lib/reducers/core.js +0 -259
- package/lib/reducers/core.js.map +0 -1
- package/lib/reducers/default-data.js +0 -42
- package/lib/reducers/default-data.js.map +0 -1
- package/lib/reducers/i18n.js +0 -65
- package/lib/reducers/i18n.js.map +0 -1
- package/lib/reducers/index.js +0 -37
- package/lib/reducers/index.js.map +0 -1
- package/lib/reducers/reducers.js +0 -99
- package/lib/reducers/reducers.js.map +0 -1
- package/lib/reducers/renderers.js +0 -41
- package/lib/reducers/renderers.js.map +0 -1
- package/lib/reducers/selectors.js +0 -47
- package/lib/reducers/selectors.js.map +0 -1
- package/lib/reducers/uischemas.js +0 -57
- package/lib/reducers/uischemas.js.map +0 -1
- package/lib/store.js +0 -27
- package/lib/store.js.map +0 -1
- package/lib/testers/index.js +0 -29
- package/lib/testers/index.js.map +0 -1
- package/lib/testers/testers.js +0 -401
- package/lib/testers/testers.js.map +0 -1
- package/lib/util/Formatted.js +0 -27
- package/lib/util/Formatted.js.map +0 -1
- package/lib/util/array.js +0 -43
- package/lib/util/array.js.map +0 -1
- package/lib/util/cell.js +0 -133
- package/lib/util/cell.js.map +0 -1
- package/lib/util/combinators.js +0 -56
- package/lib/util/combinators.js.map +0 -1
- package/lib/util/ids.js +0 -50
- package/lib/util/ids.js.map +0 -1
- package/lib/util/index.js +0 -41
- package/lib/util/index.js.map +0 -1
- package/lib/util/label.js +0 -70
- package/lib/util/label.js.map +0 -1
- package/lib/util/path.js +0 -85
- package/lib/util/path.js.map +0 -1
- package/lib/util/renderer.js +0 -451
- package/lib/util/renderer.js.map +0 -1
- package/lib/util/resolvers.js +0 -165
- package/lib/util/resolvers.js.map +0 -1
- package/lib/util/runtime.js +0 -159
- package/lib/util/runtime.js.map +0 -1
- package/lib/util/schema.js +0 -40
- package/lib/util/schema.js.map +0 -1
- package/lib/util/type.js +0 -27
- package/lib/util/type.js.map +0 -1
- package/lib/util/uischema.js +0 -52
- package/lib/util/uischema.js.map +0 -1
- package/lib/util/util.js +0 -107
- package/lib/util/util.js.map +0 -1
- package/lib/util/validator.js +0 -36
- package/lib/util/validator.js.map +0 -1
- package/webpack.build.js +0 -13
package/src/actions/actions.ts
CHANGED
|
@@ -29,6 +29,7 @@ import { generateDefaultUISchema, generateJsonSchema } from '../generators';
|
|
|
29
29
|
|
|
30
30
|
import { RankedTester } from '../testers';
|
|
31
31
|
import { UISchemaTester, ValidationMode } from '../reducers';
|
|
32
|
+
import { ErrorTranslator, Translator } from '../i18n';
|
|
32
33
|
|
|
33
34
|
export const INIT: 'jsonforms/INIT' = 'jsonforms/INIT';
|
|
34
35
|
export const UPDATE_CORE: 'jsonforms/UPDATE_CORE' = `jsonforms/UPDATE_CORE`;
|
|
@@ -51,10 +52,10 @@ export const SET_VALIDATION_MODE: 'jsonforms/SET_VALIDATION_MODE' =
|
|
|
51
52
|
'jsonforms/SET_VALIDATION_MODE';
|
|
52
53
|
|
|
53
54
|
export const SET_LOCALE: 'jsonforms/SET_LOCALE' = `jsonforms/SET_LOCALE`;
|
|
54
|
-
export const
|
|
55
|
-
'jsonforms/
|
|
56
|
-
export const
|
|
57
|
-
'jsonforms/
|
|
55
|
+
export const SET_TRANSLATOR: 'jsonforms/SET_TRANSLATOR' =
|
|
56
|
+
'jsonforms/SET_TRANSLATOR';
|
|
57
|
+
export const UPDATE_I18N: 'jsonforms/UPDATE_I18N' =
|
|
58
|
+
'jsonforms/UPDATE_I18N';
|
|
58
59
|
|
|
59
60
|
export const ADD_DEFAULT_DATA: 'jsonforms/ADD_DEFAULT_DATA' = `jsonforms/ADD_DEFAULT_DATA`;
|
|
60
61
|
export const REMOVE_DEFAULT_DATA: 'jsonforms/REMOVE_DEFAULT_DATA' = `jsonforms/REMOVE_DEFAULT_DATA`;
|
|
@@ -85,7 +86,7 @@ export interface InitAction {
|
|
|
85
86
|
data: any;
|
|
86
87
|
schema: JsonSchema;
|
|
87
88
|
uischema: UISchemaElement;
|
|
88
|
-
options?: InitActionOptions | AJV
|
|
89
|
+
options?: InitActionOptions | AJV;
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
export interface UpdateCoreAction {
|
|
@@ -93,11 +94,11 @@ export interface UpdateCoreAction {
|
|
|
93
94
|
data?: any;
|
|
94
95
|
schema?: JsonSchema;
|
|
95
96
|
uischema?: UISchemaElement;
|
|
96
|
-
options?: InitActionOptions | AJV
|
|
97
|
+
options?: InitActionOptions | AJV;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
export interface InitActionOptions {
|
|
100
|
-
ajv?: AJV
|
|
101
|
+
ajv?: AJV;
|
|
101
102
|
validationMode?: ValidationMode;
|
|
102
103
|
}
|
|
103
104
|
|
|
@@ -110,7 +111,7 @@ export const init = (
|
|
|
110
111
|
data: any,
|
|
111
112
|
schema: JsonSchema = generateJsonSchema(data),
|
|
112
113
|
uischema?: UISchemaElement,
|
|
113
|
-
options?: InitActionOptions | AJV
|
|
114
|
+
options?: InitActionOptions | AJV
|
|
114
115
|
) => ({
|
|
115
116
|
type: INIT,
|
|
116
117
|
data,
|
|
@@ -124,7 +125,7 @@ export const updateCore = (
|
|
|
124
125
|
data: any,
|
|
125
126
|
schema: JsonSchema,
|
|
126
127
|
uischema?: UISchemaElement,
|
|
127
|
-
options?: AJV
|
|
128
|
+
options?: AJV | InitActionOptions
|
|
128
129
|
): UpdateCoreAction => ({
|
|
129
130
|
type: UPDATE_CORE,
|
|
130
131
|
data,
|
|
@@ -157,10 +158,10 @@ export const unregisterDefaultData = (schemaPath: string) => ({
|
|
|
157
158
|
|
|
158
159
|
export interface SetAjvAction {
|
|
159
160
|
type: 'jsonforms/SET_AJV';
|
|
160
|
-
ajv: AJV
|
|
161
|
+
ajv: AJV;
|
|
161
162
|
}
|
|
162
163
|
|
|
163
|
-
export const setAjv = (ajv: AJV
|
|
164
|
+
export const setAjv = (ajv: AJV) => ({
|
|
164
165
|
type: SET_AJV,
|
|
165
166
|
ajv
|
|
166
167
|
});
|
|
@@ -275,33 +276,21 @@ export const unregisterUISchema = (
|
|
|
275
276
|
};
|
|
276
277
|
};
|
|
277
278
|
|
|
278
|
-
export type
|
|
279
|
+
export type I18nActions =
|
|
279
280
|
| SetLocaleAction
|
|
280
|
-
|
|
|
281
|
-
|
|
|
281
|
+
| SetTranslatorAction
|
|
282
|
+
| UpdateI18nAction
|
|
282
283
|
|
|
283
284
|
export interface SetLocaleAction {
|
|
284
285
|
type: 'jsonforms/SET_LOCALE';
|
|
285
|
-
locale: string;
|
|
286
|
+
locale: string | undefined;
|
|
286
287
|
}
|
|
287
288
|
|
|
288
|
-
export const setLocale = (locale: string): SetLocaleAction => ({
|
|
289
|
+
export const setLocale = (locale: string | undefined): SetLocaleAction => ({
|
|
289
290
|
type: SET_LOCALE,
|
|
290
291
|
locale
|
|
291
292
|
});
|
|
292
293
|
|
|
293
|
-
export interface SetLocalizedSchemasAction {
|
|
294
|
-
type: 'jsonforms/SET_LOCALIZED_SCHEMAS';
|
|
295
|
-
localizedSchemas: Map<string, JsonSchema>;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
export const setLocalizedSchemas = (
|
|
299
|
-
localizedSchemas: Map<string, JsonSchema>
|
|
300
|
-
): SetLocalizedSchemasAction => ({
|
|
301
|
-
type: SET_LOCALIZED_SCHEMAS,
|
|
302
|
-
localizedSchemas
|
|
303
|
-
});
|
|
304
|
-
|
|
305
294
|
export interface SetSchemaAction {
|
|
306
295
|
type: 'jsonforms/SET_SCHEMA';
|
|
307
296
|
schema: JsonSchema;
|
|
@@ -312,16 +301,37 @@ export const setSchema = (schema: JsonSchema): SetSchemaAction => ({
|
|
|
312
301
|
schema
|
|
313
302
|
});
|
|
314
303
|
|
|
315
|
-
export interface
|
|
316
|
-
type: 'jsonforms/
|
|
317
|
-
|
|
304
|
+
export interface SetTranslatorAction {
|
|
305
|
+
type: 'jsonforms/SET_TRANSLATOR';
|
|
306
|
+
translator?: Translator;
|
|
307
|
+
errorTranslator?: ErrorTranslator;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export const setTranslator = (
|
|
311
|
+
translator?: Translator,
|
|
312
|
+
errorTranslator?: ErrorTranslator
|
|
313
|
+
): SetTranslatorAction => ({
|
|
314
|
+
type: SET_TRANSLATOR,
|
|
315
|
+
translator,
|
|
316
|
+
errorTranslator
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
export interface UpdateI18nAction {
|
|
320
|
+
type: 'jsonforms/UPDATE_I18N';
|
|
321
|
+
locale: string | undefined;
|
|
322
|
+
translator: Translator | undefined;
|
|
323
|
+
errorTranslator: ErrorTranslator | undefined;
|
|
318
324
|
}
|
|
319
325
|
|
|
320
|
-
export const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
326
|
+
export const updateI18n = (
|
|
327
|
+
locale: string | undefined,
|
|
328
|
+
translator: Translator | undefined,
|
|
329
|
+
errorTranslator: ErrorTranslator | undefined
|
|
330
|
+
): UpdateI18nAction => ({
|
|
331
|
+
type: UPDATE_I18N,
|
|
332
|
+
locale,
|
|
333
|
+
translator,
|
|
334
|
+
errorTranslator
|
|
325
335
|
});
|
|
326
336
|
|
|
327
337
|
export interface SetUISchemaAction {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ErrorObject } from 'ajv';
|
|
2
|
+
import { JsonSchema, UISchemaElement } from '../models';
|
|
3
|
+
|
|
4
|
+
export type Translator = {
|
|
5
|
+
(id: string, defaultMessage: string, values?: any): string;
|
|
6
|
+
(id: string, defaultMessage: undefined, values?: any): string | undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type ErrorTranslator = (error: ErrorObject, translate: Translator, uischema?: UISchemaElement) => string;
|
|
10
|
+
|
|
11
|
+
export interface JsonFormsI18nState {
|
|
12
|
+
locale?: string;
|
|
13
|
+
translate?: Translator;
|
|
14
|
+
translateError?: ErrorTranslator;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type i18nJsonSchema = JsonSchema & {i18n?: string};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ErrorObject } from 'ajv';
|
|
2
|
+
import { UISchemaElement } from '../models';
|
|
3
|
+
import { getControlPath } from '../reducers';
|
|
4
|
+
import { formatErrorMessage } from '../util';
|
|
5
|
+
import { i18nJsonSchema, ErrorTranslator, Translator } from './i18nTypes';
|
|
6
|
+
|
|
7
|
+
export const getI18nKeyPrefixBySchema = (
|
|
8
|
+
schema: i18nJsonSchema | undefined,
|
|
9
|
+
uischema: UISchemaElement | undefined
|
|
10
|
+
): string | undefined => {
|
|
11
|
+
return uischema?.options?.i18n ?? schema?.i18n ?? undefined;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Transforms a given path to a prefix which can be used for i18n keys.
|
|
16
|
+
* Returns 'root' for empty paths and removes array indices
|
|
17
|
+
*/
|
|
18
|
+
export const transformPathToI18nPrefix = (path: string) => {
|
|
19
|
+
return (
|
|
20
|
+
path
|
|
21
|
+
?.split('.')
|
|
22
|
+
.filter(segment => !/^\d+$/.test(segment))
|
|
23
|
+
.join('.') || 'root'
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const getI18nKeyPrefix = (
|
|
28
|
+
schema: i18nJsonSchema | undefined,
|
|
29
|
+
uischema: UISchemaElement | undefined,
|
|
30
|
+
path: string | undefined
|
|
31
|
+
): string | undefined => {
|
|
32
|
+
return (
|
|
33
|
+
getI18nKeyPrefixBySchema(schema, uischema) ??
|
|
34
|
+
transformPathToI18nPrefix(path)
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const getI18nKey = (
|
|
39
|
+
schema: i18nJsonSchema | undefined,
|
|
40
|
+
uischema: UISchemaElement | undefined,
|
|
41
|
+
path: string | undefined,
|
|
42
|
+
key: string
|
|
43
|
+
): string | undefined => {
|
|
44
|
+
return `${getI18nKeyPrefix(schema, uischema, path)}.${key}`;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const defaultTranslator: Translator = (_id: string, defaultMessage: string | undefined) => defaultMessage;
|
|
48
|
+
|
|
49
|
+
export const defaultErrorTranslator: ErrorTranslator = (error, t, uischema) => {
|
|
50
|
+
// check whether there is a special keyword message
|
|
51
|
+
const i18nKey = getI18nKey(
|
|
52
|
+
error.parentSchema,
|
|
53
|
+
uischema,
|
|
54
|
+
getControlPath(error),
|
|
55
|
+
`error.${error.keyword}`
|
|
56
|
+
);
|
|
57
|
+
const specializedKeywordMessage = t(i18nKey, undefined);
|
|
58
|
+
if (specializedKeywordMessage !== undefined) {
|
|
59
|
+
return specializedKeywordMessage;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// check whether there is a generic keyword message
|
|
63
|
+
const genericKeywordMessage = t(`error.${error.keyword}`, undefined);
|
|
64
|
+
if (genericKeywordMessage !== undefined) {
|
|
65
|
+
return genericKeywordMessage;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// check whether there is a customization for the default message
|
|
69
|
+
const messageCustomization = t(error.message, undefined);
|
|
70
|
+
if (messageCustomization !== undefined) {
|
|
71
|
+
return messageCustomization;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// rewrite required property messages (if they were not customized) as we place them next to the respective input
|
|
75
|
+
if (error.keyword === 'required' && error.message?.startsWith('must have required property')) {
|
|
76
|
+
return t('is a required property', 'is a required property');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return error.message;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Returns the determined error message for the given errors.
|
|
84
|
+
* All errors must correspond to the given schema, uischema or path.
|
|
85
|
+
*/
|
|
86
|
+
export const getCombinedErrorMessage = (
|
|
87
|
+
errors: ErrorObject[],
|
|
88
|
+
et: ErrorTranslator,
|
|
89
|
+
t: Translator,
|
|
90
|
+
schema?: i18nJsonSchema,
|
|
91
|
+
uischema?: UISchemaElement,
|
|
92
|
+
path?: string
|
|
93
|
+
) => {
|
|
94
|
+
if (errors.length > 0 && t) {
|
|
95
|
+
// check whether there is a special message which overwrites all others
|
|
96
|
+
const customErrorKey = getI18nKey(schema, uischema, path, 'error.custom');
|
|
97
|
+
const specializedErrorMessage = t(customErrorKey, undefined);
|
|
98
|
+
if (specializedErrorMessage !== undefined) {
|
|
99
|
+
return specializedErrorMessage;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return formatErrorMessage(
|
|
103
|
+
errors.map(error => et(error, t, uischema))
|
|
104
|
+
);
|
|
105
|
+
};
|
package/src/index.ts
CHANGED
package/src/reducers/core.ts
CHANGED
|
@@ -29,7 +29,7 @@ import get from 'lodash/get';
|
|
|
29
29
|
import filter from 'lodash/filter';
|
|
30
30
|
import isEqual from 'lodash/isEqual';
|
|
31
31
|
import isFunction from 'lodash/isFunction';
|
|
32
|
-
import
|
|
32
|
+
import Ajv, { ErrorObject, ValidateFunction } from 'ajv';
|
|
33
33
|
import {
|
|
34
34
|
CoreActions,
|
|
35
35
|
INIT,
|
|
@@ -47,28 +47,17 @@ import {
|
|
|
47
47
|
import { createAjv, Reducer } from '../util';
|
|
48
48
|
import { JsonSchema, UISchemaElement } from '../models';
|
|
49
49
|
|
|
50
|
-
const validate = (validator: ValidateFunction, data: any): ErrorObject[] => {
|
|
50
|
+
export const validate = (validator: ValidateFunction | undefined, data: any): ErrorObject[] => {
|
|
51
|
+
if (validator === undefined) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
51
54
|
const valid = validator(data);
|
|
52
55
|
if (valid) {
|
|
53
56
|
return [];
|
|
54
57
|
}
|
|
55
|
-
|
|
56
58
|
return validator.errors;
|
|
57
59
|
};
|
|
58
60
|
|
|
59
|
-
export const sanitizeErrors = (validator: ValidateFunction, data: any) => {
|
|
60
|
-
if (validator === alwaysValid) {
|
|
61
|
-
return [];
|
|
62
|
-
}
|
|
63
|
-
return validate(validator, data).map(error => {
|
|
64
|
-
error.dataPath = error.dataPath.replace(/\//g, '.').substr(1);
|
|
65
|
-
|
|
66
|
-
return error;
|
|
67
|
-
});
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const alwaysValid: ValidateFunction = () => true;
|
|
71
|
-
|
|
72
61
|
export type ValidationMode = 'ValidateAndShow' | 'ValidateAndHide' | 'NoValidation';
|
|
73
62
|
|
|
74
63
|
export interface JsonFormsCore {
|
|
@@ -86,9 +75,9 @@ const initState: JsonFormsCore = {
|
|
|
86
75
|
schema: {},
|
|
87
76
|
uischema: undefined,
|
|
88
77
|
errors: [],
|
|
89
|
-
validator:
|
|
78
|
+
validator: undefined,
|
|
90
79
|
ajv: undefined,
|
|
91
|
-
validationMode: 'ValidateAndShow'
|
|
80
|
+
validationMode: 'ValidateAndShow',
|
|
92
81
|
};
|
|
93
82
|
|
|
94
83
|
const reuseAjvForSchema = (ajv: Ajv, schema: JsonSchema): Ajv => {
|
|
@@ -154,8 +143,8 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
154
143
|
const thisAjv = getOrCreateAjv(state, action);
|
|
155
144
|
|
|
156
145
|
const validationMode = getValidationMode(state, action);
|
|
157
|
-
const v = validationMode === 'NoValidation' ?
|
|
158
|
-
const e =
|
|
146
|
+
const v = validationMode === 'NoValidation' ? undefined : thisAjv.compile(action.schema);
|
|
147
|
+
const e = validate(v, action.data);
|
|
159
148
|
|
|
160
149
|
return {
|
|
161
150
|
...state,
|
|
@@ -165,7 +154,7 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
165
154
|
errors: e,
|
|
166
155
|
validator: v,
|
|
167
156
|
ajv: thisAjv,
|
|
168
|
-
validationMode
|
|
157
|
+
validationMode,
|
|
169
158
|
};
|
|
170
159
|
}
|
|
171
160
|
case UPDATE_CORE: {
|
|
@@ -181,11 +170,11 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
181
170
|
// revalidate only if necessary
|
|
182
171
|
validator =
|
|
183
172
|
validationMode === 'NoValidation'
|
|
184
|
-
?
|
|
173
|
+
? undefined
|
|
185
174
|
: thisAjv.compile(action.schema);
|
|
186
|
-
errors =
|
|
175
|
+
errors = validate(validator, action.data);
|
|
187
176
|
} else if (state.data !== action.data) {
|
|
188
|
-
errors =
|
|
177
|
+
errors = validate(validator, action.data);
|
|
189
178
|
}
|
|
190
179
|
|
|
191
180
|
const stateChanged =
|
|
@@ -195,24 +184,24 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
195
184
|
state.ajv !== thisAjv ||
|
|
196
185
|
state.errors !== errors ||
|
|
197
186
|
state.validator !== validator ||
|
|
198
|
-
state.validationMode !== validationMode
|
|
187
|
+
state.validationMode !== validationMode
|
|
199
188
|
return stateChanged
|
|
200
189
|
? {
|
|
201
190
|
...state,
|
|
202
|
-
data:
|
|
203
|
-
schema:
|
|
204
|
-
uischema:
|
|
205
|
-
ajv: thisAjv
|
|
191
|
+
data: action.data,
|
|
192
|
+
schema: action.schema,
|
|
193
|
+
uischema: action.uischema,
|
|
194
|
+
ajv: thisAjv,
|
|
206
195
|
errors: isEqual(errors, state.errors) ? state.errors : errors,
|
|
207
|
-
validator: validator
|
|
208
|
-
validationMode: validationMode
|
|
196
|
+
validator: validator,
|
|
197
|
+
validationMode: validationMode,
|
|
209
198
|
}
|
|
210
199
|
: state;
|
|
211
200
|
}
|
|
212
201
|
case SET_AJV: {
|
|
213
202
|
const currentAjv = action.ajv;
|
|
214
|
-
const validator = state.validationMode === 'NoValidation' ?
|
|
215
|
-
const errors =
|
|
203
|
+
const validator = state.validationMode === 'NoValidation' ? undefined : currentAjv.compile(state.schema);
|
|
204
|
+
const errors = validate(validator, state.data);
|
|
216
205
|
return {
|
|
217
206
|
...state,
|
|
218
207
|
validator,
|
|
@@ -224,7 +213,7 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
224
213
|
const v = needsNewValidator
|
|
225
214
|
? reuseAjvForSchema(state.ajv, action.schema).compile(action.schema)
|
|
226
215
|
: state.validator;
|
|
227
|
-
const errors =
|
|
216
|
+
const errors = validate(v, state.data);
|
|
228
217
|
return {
|
|
229
218
|
...state,
|
|
230
219
|
validator: v,
|
|
@@ -244,7 +233,7 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
244
233
|
} else if (action.path === '') {
|
|
245
234
|
// empty path is ok
|
|
246
235
|
const result = action.updater(cloneDeep(state.data));
|
|
247
|
-
const errors =
|
|
236
|
+
const errors = validate(state.validator, result);
|
|
248
237
|
return {
|
|
249
238
|
...state,
|
|
250
239
|
data: result,
|
|
@@ -258,7 +247,7 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
258
247
|
newData,
|
|
259
248
|
state.data === undefined ? {} : state.data
|
|
260
249
|
);
|
|
261
|
-
const errors =
|
|
250
|
+
const errors = validate(state.validator, newState);
|
|
262
251
|
return {
|
|
263
252
|
...state,
|
|
264
253
|
data: newState,
|
|
@@ -277,17 +266,16 @@ export const coreReducer: Reducer<JsonFormsCore, CoreActions> = (
|
|
|
277
266
|
return state;
|
|
278
267
|
}
|
|
279
268
|
if (action.validationMode === 'NoValidation') {
|
|
280
|
-
const errors =
|
|
269
|
+
const errors = validate(undefined, state.data);
|
|
281
270
|
return {
|
|
282
271
|
...state,
|
|
283
|
-
validator: alwaysValid,
|
|
284
272
|
errors,
|
|
285
273
|
validationMode: action.validationMode
|
|
286
274
|
};
|
|
287
275
|
}
|
|
288
276
|
if (state.validationMode === 'NoValidation') {
|
|
289
277
|
const validator = reuseAjvForSchema(state.ajv, state.schema).compile(state.schema);
|
|
290
|
-
const errors =
|
|
278
|
+
const errors = validate(validator, state.data);
|
|
291
279
|
return {
|
|
292
280
|
...state,
|
|
293
281
|
validator,
|
|
@@ -310,6 +298,40 @@ export const extractSchema = (state: JsonFormsCore) => get(state, 'schema');
|
|
|
310
298
|
export const extractUiSchema = (state: JsonFormsCore) => get(state, 'uischema');
|
|
311
299
|
export const extractAjv = (state: JsonFormsCore) => get(state, 'ajv');
|
|
312
300
|
|
|
301
|
+
const getInvalidProperty = (error: ErrorObject): string | undefined => {
|
|
302
|
+
switch (error.keyword) {
|
|
303
|
+
case 'required':
|
|
304
|
+
case 'dependencies':
|
|
305
|
+
return error.params.missingProperty;
|
|
306
|
+
case 'additionalProperties':
|
|
307
|
+
return error.params.additionalProperty;
|
|
308
|
+
default:
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
export const getControlPath = (error: ErrorObject) => {
|
|
314
|
+
const dataPath = (error as any).dataPath;
|
|
315
|
+
// older AJV version
|
|
316
|
+
if (dataPath) {
|
|
317
|
+
return dataPath.replace(/\//g, '.').substr(1);
|
|
318
|
+
}
|
|
319
|
+
// dataPath was renamed to instancePath in AJV v8
|
|
320
|
+
var controlPath: string = error.instancePath;
|
|
321
|
+
|
|
322
|
+
// change '/' chars to '.'
|
|
323
|
+
controlPath = controlPath.replace(/\//g, '.');
|
|
324
|
+
|
|
325
|
+
const invalidProperty = getInvalidProperty(error);
|
|
326
|
+
if (invalidProperty !== undefined && !controlPath.endsWith(invalidProperty)) {
|
|
327
|
+
controlPath = `${controlPath}.${invalidProperty}`;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// remove '.' chars at the beginning of paths
|
|
331
|
+
controlPath = controlPath.replace(/^./, '');
|
|
332
|
+
return controlPath;
|
|
333
|
+
}
|
|
334
|
+
|
|
313
335
|
export const errorsAt = (
|
|
314
336
|
instancePath: string,
|
|
315
337
|
schema: JsonSchema,
|
|
@@ -319,15 +341,15 @@ export const errorsAt = (
|
|
|
319
341
|
const combinatorPaths = filter(
|
|
320
342
|
errors,
|
|
321
343
|
error => error.keyword === 'oneOf' || error.keyword === 'anyOf'
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
let result = matchPath(
|
|
344
|
+
).map(error => getControlPath(error));
|
|
345
|
+
|
|
346
|
+
return filter(errors, error => {
|
|
347
|
+
// Filter errors that match any keyword that we don't want to show in the UI
|
|
348
|
+
if (filteredErrorKeywords.indexOf(error.keyword) !== -1) {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
const controlPath = getControlPath(error);
|
|
352
|
+
let result = matchPath(controlPath);
|
|
331
353
|
// In anyOf and oneOf blocks with "primitive" (i.e. string, number etc.) or array subschemas,
|
|
332
354
|
// we want to make sure that errors are only shown for the correct subschema.
|
|
333
355
|
// Therefore, we compare the error's parent schema with the property's schema.
|
package/src/reducers/i18n.ts
CHANGED
|
@@ -23,66 +23,72 @@
|
|
|
23
23
|
THE SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
26
|
+
import { defaultErrorTranslator, defaultTranslator, JsonFormsI18nState } from '../i18n';
|
|
27
|
+
import { I18nActions, SET_LOCALE, SET_TRANSLATOR, UPDATE_I18N } from '../actions';
|
|
28
28
|
import { Reducer } from '../util';
|
|
29
29
|
|
|
30
|
-
export
|
|
31
|
-
locale
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const initState: JsonFormsLocaleState = {
|
|
37
|
-
locale: undefined,
|
|
38
|
-
localizedSchemas: new Map(),
|
|
39
|
-
localizedUISchemas: new Map()
|
|
30
|
+
export const defaultJsonFormsI18nState: JsonFormsI18nState = {
|
|
31
|
+
locale: 'en',
|
|
32
|
+
translate: defaultTranslator,
|
|
33
|
+
translateError: defaultErrorTranslator
|
|
40
34
|
};
|
|
41
35
|
|
|
42
|
-
export const i18nReducer: Reducer<
|
|
36
|
+
export const i18nReducer: Reducer<JsonFormsI18nState, I18nActions> = (state = defaultJsonFormsI18nState, action) => {
|
|
43
37
|
switch (action.type) {
|
|
44
|
-
case
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
38
|
+
case UPDATE_I18N: {
|
|
39
|
+
const locale = action.locale ?? defaultJsonFormsI18nState.locale;
|
|
40
|
+
const translate =
|
|
41
|
+
action.translator ?? defaultJsonFormsI18nState.translate;
|
|
42
|
+
const translateError =
|
|
43
|
+
action.errorTranslator ?? defaultJsonFormsI18nState.translateError;
|
|
44
|
+
|
|
45
|
+
if (
|
|
46
|
+
locale !== state.locale ||
|
|
47
|
+
translate !== state.translate ||
|
|
48
|
+
translateError !== state.translateError
|
|
49
|
+
) {
|
|
50
|
+
return {
|
|
51
|
+
...state,
|
|
52
|
+
locale,
|
|
53
|
+
translate,
|
|
54
|
+
translateError
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return state;
|
|
58
|
+
}
|
|
59
|
+
case SET_TRANSLATOR:
|
|
50
60
|
return {
|
|
51
61
|
...state,
|
|
52
|
-
|
|
62
|
+
translate: action.translator ?? defaultTranslator,
|
|
63
|
+
translateError: action.errorTranslator ?? defaultErrorTranslator
|
|
53
64
|
};
|
|
54
65
|
case SET_LOCALE:
|
|
55
66
|
return {
|
|
56
67
|
...state,
|
|
57
|
-
locale:
|
|
58
|
-
action.locale === undefined ? navigator.languages[0] : action.locale
|
|
68
|
+
locale: action.locale ?? navigator.languages[0]
|
|
59
69
|
};
|
|
60
70
|
default:
|
|
61
71
|
return state;
|
|
62
72
|
}
|
|
63
73
|
};
|
|
64
74
|
|
|
65
|
-
export const fetchLocale = (state?:
|
|
75
|
+
export const fetchLocale = (state?: JsonFormsI18nState) => {
|
|
66
76
|
if (state === undefined) {
|
|
67
77
|
return undefined;
|
|
68
78
|
}
|
|
69
79
|
return state.locale;
|
|
70
80
|
};
|
|
71
81
|
|
|
72
|
-
export const
|
|
73
|
-
state?: JsonFormsLocaleState
|
|
74
|
-
): JsonSchema => {
|
|
82
|
+
export const fetchTranslator = (state?: JsonFormsI18nState) => {
|
|
75
83
|
if (state === undefined) {
|
|
76
|
-
return
|
|
84
|
+
return defaultTranslator;
|
|
77
85
|
}
|
|
78
|
-
return state.
|
|
79
|
-
}
|
|
86
|
+
return state.translate;
|
|
87
|
+
}
|
|
80
88
|
|
|
81
|
-
export const
|
|
82
|
-
state?: JsonFormsLocaleState
|
|
83
|
-
): UISchemaElement => {
|
|
89
|
+
export const fetchErrorTranslator = (state?: JsonFormsI18nState) => {
|
|
84
90
|
if (state === undefined) {
|
|
85
|
-
return
|
|
91
|
+
return defaultErrorTranslator;
|
|
86
92
|
}
|
|
87
|
-
return state.
|
|
88
|
-
}
|
|
93
|
+
return state.translateError;
|
|
94
|
+
}
|