@jsonforms/core 3.4.0-alpha.0 → 3.4.0-alpha.2

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.
Files changed (85) hide show
  1. package/lib/actions/actions.d.ts +3 -4
  2. package/lib/generators/Generate.d.ts +1 -1
  3. package/lib/i18n/i18nUtil.d.ts +1 -1
  4. package/lib/i18n/index.d.ts +2 -2
  5. package/lib/i18n/selectors.d.ts +7 -0
  6. package/lib/index.d.ts +1 -1
  7. package/lib/jsonforms-core.cjs.js +1922 -1917
  8. package/lib/jsonforms-core.cjs.js.map +1 -1
  9. package/lib/jsonforms-core.esm.js +1607 -1605
  10. package/lib/jsonforms-core.esm.js.map +1 -1
  11. package/lib/{util → mappers}/cell.d.ts +1 -3
  12. package/lib/{util → mappers}/combinators.d.ts +1 -1
  13. package/lib/mappers/index.d.ts +4 -0
  14. package/lib/{util → mappers}/renderer.d.ts +17 -6
  15. package/lib/mappers/util.d.ts +10 -0
  16. package/lib/models/uischema.d.ts +0 -8
  17. package/lib/reducers/cells.d.ts +1 -6
  18. package/lib/reducers/config.d.ts +1 -1
  19. package/lib/reducers/core.d.ts +7 -25
  20. package/lib/reducers/default-data.d.ts +3 -1
  21. package/lib/reducers/i18n.d.ts +2 -5
  22. package/lib/reducers/index.d.ts +0 -1
  23. package/lib/reducers/middleware.d.ts +1 -1
  24. package/lib/reducers/reducers.d.ts +8 -16
  25. package/lib/reducers/renderers.d.ts +2 -6
  26. package/lib/reducers/uischemas.d.ts +2 -6
  27. package/lib/store/index.d.ts +4 -0
  28. package/lib/store/jsonFormsCore.d.ts +19 -0
  29. package/lib/{store.d.ts → store/store.d.ts} +28 -3
  30. package/lib/testers/testers.d.ts +1 -0
  31. package/lib/util/errors.d.ts +5 -0
  32. package/lib/{Helpers.d.ts → util/helpers.d.ts} +1 -1
  33. package/lib/util/index.d.ts +2 -5
  34. package/lib/util/label.d.ts +1 -13
  35. package/lib/util/path.d.ts +6 -2
  36. package/lib/util/runtime.d.ts +1 -10
  37. package/lib/util/schema.d.ts +1 -1
  38. package/lib/util/uischema.d.ts +10 -7
  39. package/lib/util/util.d.ts +1 -2
  40. package/lib/util/validator.d.ts +2 -1
  41. package/package.json +1 -1
  42. package/src/actions/actions.ts +3 -4
  43. package/src/generators/Generate.ts +1 -1
  44. package/src/generators/uischema.ts +1 -3
  45. package/src/i18n/i18nUtil.ts +7 -4
  46. package/src/i18n/index.ts +2 -2
  47. package/src/i18n/selectors.ts +67 -0
  48. package/src/index.ts +1 -2
  49. package/src/{util → mappers}/cell.ts +19 -15
  50. package/src/{util → mappers}/combinators.ts +3 -2
  51. package/src/mappers/index.ts +29 -0
  52. package/src/{util → mappers}/renderer.ts +139 -33
  53. package/src/mappers/util.ts +43 -0
  54. package/src/models/uischema.ts +0 -29
  55. package/src/reducers/cells.ts +1 -7
  56. package/src/reducers/config.ts +1 -1
  57. package/src/reducers/core.ts +33 -200
  58. package/src/reducers/default-data.ts +8 -2
  59. package/src/reducers/i18n.ts +3 -27
  60. package/src/reducers/index.ts +0 -1
  61. package/src/reducers/middleware.ts +1 -1
  62. package/src/reducers/reducers.ts +3 -31
  63. package/src/reducers/renderers.ts +2 -7
  64. package/src/reducers/uischemas.ts +2 -12
  65. package/src/{util/array.ts → store/index.ts} +5 -19
  66. package/src/store/jsonFormsCore.ts +72 -0
  67. package/src/{store.ts → store/store.ts} +36 -8
  68. package/src/testers/testers.ts +6 -0
  69. package/src/util/errors.ts +142 -0
  70. package/src/{Helpers.ts → util/helpers.ts} +3 -2
  71. package/src/util/index.ts +2 -5
  72. package/src/util/label.ts +1 -98
  73. package/src/util/path.ts +12 -15
  74. package/src/util/runtime.ts +1 -44
  75. package/src/util/schema.ts +1 -1
  76. package/src/util/uischema.ts +52 -16
  77. package/src/util/util.ts +1 -9
  78. package/src/util/validator.ts +15 -1
  79. package/lib/reducers/selectors.d.ts +0 -15
  80. package/lib/util/array.d.ts +0 -3
  81. package/src/reducers/selectors.ts +0 -64
  82. /package/lib/{i18n → store}/i18nTypes.d.ts +0 -0
  83. /package/lib/{util → store}/type.d.ts +0 -0
  84. /package/src/{i18n → store}/i18nTypes.ts +0 -0
  85. /package/src/{util → store}/type.ts +0 -0
@@ -1,28 +1,28 @@
1
1
  import isEmpty from 'lodash/isEmpty';
2
2
  import startCase from 'lodash/startCase';
3
3
  import keys from 'lodash/keys';
4
+ import range from 'lodash/range';
5
+ import get from 'lodash/get';
6
+ import has from 'lodash/has';
7
+ import find from 'lodash/find';
8
+ import isArray from 'lodash/isArray';
9
+ import includes from 'lodash/includes';
10
+ import Ajv from 'ajv';
11
+ import addFormats from 'ajv-formats';
12
+ import filter from 'lodash/filter';
13
+ import isEqual from 'lodash/isEqual';
4
14
  import merge from 'lodash/merge';
5
15
  import cloneDeep from 'lodash/cloneDeep';
6
16
  import setFp from 'lodash/fp/set';
7
17
  import unsetFp from 'lodash/fp/unset';
8
- import get from 'lodash/get';
9
- import filter from 'lodash/filter';
10
- import isEqual from 'lodash/isEqual';
11
- import isFunction from 'lodash/isFunction';
18
+ import { isFunction, isEqual as isEqual$1 } from 'lodash';
12
19
  import maxBy from 'lodash/maxBy';
13
20
  import remove from 'lodash/remove';
14
21
  import endsWith from 'lodash/endsWith';
15
22
  import last from 'lodash/last';
16
- import isArray from 'lodash/isArray';
17
23
  import reduce from 'lodash/reduce';
18
24
  import toPairs from 'lodash/toPairs';
19
- import includes from 'lodash/includes';
20
25
  import isUndefined from 'lodash/isUndefined';
21
- import find from 'lodash/find';
22
- import range from 'lodash/range';
23
- import has from 'lodash/has';
24
- import Ajv from 'ajv';
25
- import addFormats from 'ajv-formats';
26
26
 
27
27
  const ADDITIONAL_PROPERTIES = 'additionalProperties';
28
28
  const REQUIRED_PROPERTIES = 'required';
@@ -140,6 +140,181 @@ instance, options = {}) => {
140
140
  return gen.schemaObject(instance);
141
141
  };
142
142
 
143
+ const usedIds = new Set();
144
+ const makeId = (idBase, iteration) => iteration <= 1 ? idBase : idBase + iteration.toString();
145
+ const isUniqueId = (idBase, iteration) => {
146
+ const newID = makeId(idBase, iteration);
147
+ return !usedIds.has(newID);
148
+ };
149
+ const createId = (proposedId) => {
150
+ if (proposedId === undefined) {
151
+ proposedId = 'undefined';
152
+ }
153
+ let tries = 0;
154
+ while (!isUniqueId(proposedId, tries)) {
155
+ tries++;
156
+ }
157
+ const newID = makeId(proposedId, tries);
158
+ usedIds.add(newID);
159
+ return newID;
160
+ };
161
+ const removeId = (id) => usedIds.delete(id);
162
+ const clearAllIds = () => usedIds.clear();
163
+
164
+ const compose = (path1, path2) => {
165
+ let p1 = path1;
166
+ if (!isEmpty(path1) && !isEmpty(path2) && !path2.startsWith('[')) {
167
+ p1 = path1 + '.';
168
+ }
169
+ if (isEmpty(p1)) {
170
+ return path2;
171
+ }
172
+ else if (isEmpty(path2)) {
173
+ return p1;
174
+ }
175
+ else {
176
+ return `${p1}${path2}`;
177
+ }
178
+ };
179
+ const toDataPathSegments = (schemaPath) => {
180
+ const s = schemaPath
181
+ .replace(/(anyOf|allOf|oneOf)\/[\d]+\//g, '')
182
+ .replace(/(then|else)\//g, '');
183
+ const segments = s.split('/');
184
+ const decodedSegments = segments.map(decode);
185
+ const startFromRoot = decodedSegments[0] === '#' || decodedSegments[0] === '';
186
+ const startIndex = startFromRoot ? 2 : 1;
187
+ return range(startIndex, decodedSegments.length, 2).map((idx) => decodedSegments[idx]);
188
+ };
189
+ const toDataPath = (schemaPath) => {
190
+ return toDataPathSegments(schemaPath).join('.');
191
+ };
192
+ const encode = (segment) => segment?.replace(/~/g, '~0').replace(/\//g, '~1');
193
+ const decode = (pointerSegment) => pointerSegment?.replace(/~1/g, '/').replace(/~0/, '~');
194
+ const getPropPath = (path) => {
195
+ return `/properties/${path
196
+ .split('.')
197
+ .map((p) => encode(p))
198
+ .join('/properties/')}`;
199
+ };
200
+
201
+ const deriveLabel = (controlElement, schemaElement) => {
202
+ if (schemaElement && typeof schemaElement.title === 'string') {
203
+ return schemaElement.title;
204
+ }
205
+ if (typeof controlElement.scope === 'string') {
206
+ const ref = controlElement.scope;
207
+ const label = decode(ref.substr(ref.lastIndexOf('/') + 1));
208
+ return startCase(label);
209
+ }
210
+ return '';
211
+ };
212
+ const createCleanLabel = (label) => {
213
+ return startCase(label.replace('_', ' '));
214
+ };
215
+ const createLabelDescriptionFrom = (withLabel, schema) => {
216
+ const labelProperty = withLabel.label;
217
+ if (typeof labelProperty === 'boolean') {
218
+ return labelDescription(deriveLabel(withLabel, schema), labelProperty);
219
+ }
220
+ if (typeof labelProperty === 'string') {
221
+ return labelDescription(labelProperty, true);
222
+ }
223
+ if (typeof labelProperty === 'object') {
224
+ const label = typeof labelProperty.text === 'string'
225
+ ? labelProperty.text
226
+ : deriveLabel(withLabel, schema);
227
+ const show = typeof labelProperty.show === 'boolean' ? labelProperty.show : true;
228
+ return labelDescription(label, show);
229
+ }
230
+ return labelDescription(deriveLabel(withLabel, schema), true);
231
+ };
232
+ const labelDescription = (text, show) => ({
233
+ text: text,
234
+ show: show,
235
+ });
236
+
237
+ const isObjectSchema$1 = (schema) => {
238
+ return schema.properties !== undefined;
239
+ };
240
+ const isArraySchema = (schema) => {
241
+ return schema.type === 'array' && schema.items !== undefined;
242
+ };
243
+ const resolveData = (instance, dataPath) => {
244
+ if (isEmpty(dataPath)) {
245
+ return instance;
246
+ }
247
+ const dataPathSegments = dataPath.split('.');
248
+ return dataPathSegments.reduce((curInstance, decodedSegment) => {
249
+ if (!curInstance ||
250
+ !Object.prototype.hasOwnProperty.call(curInstance, decodedSegment)) {
251
+ return undefined;
252
+ }
253
+ return curInstance[decodedSegment];
254
+ }, instance);
255
+ };
256
+ const findAllRefs = (schema, result = {}, resolveTuples = false) => {
257
+ if (isObjectSchema$1(schema)) {
258
+ Object.keys(schema.properties).forEach((key) => findAllRefs(schema.properties[key], result));
259
+ }
260
+ if (isArraySchema(schema)) {
261
+ if (Array.isArray(schema.items)) {
262
+ if (resolveTuples) {
263
+ const items = schema.items;
264
+ items.forEach((child) => findAllRefs(child, result));
265
+ }
266
+ }
267
+ else {
268
+ findAllRefs(schema.items, result);
269
+ }
270
+ }
271
+ if (Array.isArray(schema.anyOf)) {
272
+ const anyOf = schema.anyOf;
273
+ anyOf.forEach((child) => findAllRefs(child, result));
274
+ }
275
+ if (schema.$ref !== undefined) {
276
+ result[schema.$ref] = schema;
277
+ }
278
+ return result;
279
+ };
280
+ const invalidSegment = (pathSegment) => pathSegment === '#' || pathSegment === undefined || pathSegment === '';
281
+ const resolveSchema = (schema, schemaPath, rootSchema) => {
282
+ const segments = schemaPath?.split('/').map(decode);
283
+ return resolveSchemaWithSegments(schema, segments, rootSchema);
284
+ };
285
+ const resolveSchemaWithSegments = (schema, pathSegments, rootSchema) => {
286
+ if (isEmpty(schema)) {
287
+ return undefined;
288
+ }
289
+ if (schema.$ref) {
290
+ schema = resolveSchema(rootSchema, schema.$ref, rootSchema);
291
+ }
292
+ if (!pathSegments || pathSegments.length === 0) {
293
+ return schema;
294
+ }
295
+ const [segment, ...remainingSegments] = pathSegments;
296
+ if (invalidSegment(segment)) {
297
+ return resolveSchemaWithSegments(schema, remainingSegments, rootSchema);
298
+ }
299
+ const singleSegmentResolveSchema = get(schema, segment);
300
+ const resolvedSchema = resolveSchemaWithSegments(singleSegmentResolveSchema, remainingSegments, rootSchema);
301
+ if (resolvedSchema) {
302
+ return resolvedSchema;
303
+ }
304
+ if (segment === 'properties' || segment === 'items') {
305
+ let alternativeResolveResult = undefined;
306
+ const subSchemas = [].concat(schema.oneOf ?? [], schema.allOf ?? [], schema.anyOf ?? [], schema.then ?? [], schema.else ?? []);
307
+ for (const subSchema of subSchemas) {
308
+ alternativeResolveResult = resolveSchemaWithSegments(subSchema, [segment, ...remainingSegments], rootSchema);
309
+ if (alternativeResolveResult) {
310
+ break;
311
+ }
312
+ }
313
+ return alternativeResolveResult;
314
+ }
315
+ return undefined;
316
+ };
317
+
143
318
  const Draft4 = {
144
319
  id: 'http://json-schema.org/draft-04/schema#',
145
320
  $schema: 'http://json-schema.org/draft-04/schema#',
@@ -294,6 +469,57 @@ var RuleEffect;
294
469
  RuleEffect["ENABLE"] = "ENABLE";
295
470
  RuleEffect["DISABLE"] = "DISABLE";
296
471
  })(RuleEffect || (RuleEffect = {}));
472
+
473
+ const setReadonlyPropertyValue = (value) => (child) => {
474
+ if (!child.options) {
475
+ child.options = {};
476
+ }
477
+ child.options.readonly = value;
478
+ };
479
+ const setReadonly = (uischema) => {
480
+ iterateSchema(uischema, setReadonlyPropertyValue(true));
481
+ };
482
+ const unsetReadonly = (uischema) => {
483
+ iterateSchema(uischema, setReadonlyPropertyValue(false));
484
+ };
485
+ const iterateSchema = (uischema, toApply) => {
486
+ if (isEmpty(uischema)) {
487
+ return;
488
+ }
489
+ if (isLayout(uischema)) {
490
+ uischema.elements.forEach((child) => iterateSchema(child, toApply));
491
+ return;
492
+ }
493
+ toApply(uischema);
494
+ };
495
+ const findUiControl = (uiSchema, path) => {
496
+ if (isControlElement(uiSchema)) {
497
+ if (isScoped(uiSchema) && uiSchema.scope.endsWith(getPropPath(path))) {
498
+ return uiSchema;
499
+ }
500
+ else if (uiSchema.options?.detail) {
501
+ return findUiControl(uiSchema.options.detail, path);
502
+ }
503
+ }
504
+ if (isLayout(uiSchema)) {
505
+ for (const elem of uiSchema.elements) {
506
+ const result = findUiControl(elem, path);
507
+ if (result !== undefined)
508
+ return result;
509
+ }
510
+ }
511
+ return undefined;
512
+ };
513
+ const composeWithUi = (scopableUi, path) => {
514
+ if (!isScoped(scopableUi)) {
515
+ return path ?? '';
516
+ }
517
+ const segments = toDataPathSegments(scopableUi.scope);
518
+ if (isEmpty(segments)) {
519
+ return path ?? '';
520
+ }
521
+ return compose(path, segments.join('.'));
522
+ };
297
523
  const isInternationalized = (element) => typeof element === 'object' &&
298
524
  element !== null &&
299
525
  typeof element.i18n === 'string';
@@ -305,277 +531,208 @@ const isLabelable = (obj) => !!obj && typeof obj === 'object';
305
531
  const isLabeled = (obj) => isLabelable(obj) && ['string', 'boolean'].includes(typeof obj.label);
306
532
  const isControlElement = (uiSchema) => uiSchema.type === 'Control';
307
533
 
308
- const move = (array, index, delta) => {
309
- const newIndex = index + delta;
310
- if (newIndex < 0 || newIndex >= array.length) {
311
- return;
312
- }
313
- const indexes = [index, newIndex].sort((a, b) => a - b);
314
- array.splice(indexes[0], 2, array[indexes[1]], array[indexes[0]]);
315
- };
316
- const moveUp = (array, toMove) => {
317
- move(array, toMove, -1);
318
- };
319
- const moveDown = (array, toMove) => {
320
- move(array, toMove, 1);
534
+ const isOrCondition = (condition) => condition.type === 'OR';
535
+ const isAndCondition = (condition) => condition.type === 'AND';
536
+ const isLeafCondition = (condition) => condition.type === 'LEAF';
537
+ const isSchemaCondition = (condition) => has(condition, 'schema');
538
+ const getConditionScope = (condition, path) => {
539
+ return composeWithUi(condition, path);
321
540
  };
322
-
323
- const cellReducer = (state = [], { type, tester, cell }) => {
324
- switch (type) {
325
- case ADD_CELL:
326
- return state.concat([{ tester, cell }]);
327
- case REMOVE_CELL:
328
- return state.filter((t) => t.tester !== tester);
329
- default:
330
- return state;
541
+ const evaluateCondition = (data, condition, path, ajv) => {
542
+ if (isAndCondition(condition)) {
543
+ return condition.conditions.reduce((acc, cur) => acc && evaluateCondition(data, cur, path, ajv), true);
544
+ }
545
+ else if (isOrCondition(condition)) {
546
+ return condition.conditions.reduce((acc, cur) => acc || evaluateCondition(data, cur, path, ajv), false);
547
+ }
548
+ else if (isLeafCondition(condition)) {
549
+ const value = resolveData(data, getConditionScope(condition, path));
550
+ return value === condition.expectedValue;
551
+ }
552
+ else if (isSchemaCondition(condition)) {
553
+ const value = resolveData(data, getConditionScope(condition, path));
554
+ if (condition.failWhenUndefined && value === undefined) {
555
+ return false;
556
+ }
557
+ return ajv.validate(condition.schema, value);
558
+ }
559
+ else {
560
+ return true;
331
561
  }
332
562
  };
333
-
334
- const configDefault = {
335
- restrict: false,
336
- trim: false,
337
- showUnfocusedDescription: false,
338
- hideRequiredAsterisk: false,
563
+ const isRuleFulfilled = (uischema, data, path, ajv) => {
564
+ const condition = uischema.rule.condition;
565
+ return evaluateCondition(data, condition, path, ajv);
339
566
  };
340
-
341
- const applyDefaultConfiguration = (config = {}) => merge({}, configDefault, config);
342
- const configReducer = (state = applyDefaultConfiguration(), action) => {
343
- switch (action.type) {
344
- case SET_CONFIG:
345
- return applyDefaultConfiguration(action.config);
567
+ const evalVisibility = (uischema, data, path = undefined, ajv) => {
568
+ const fulfilled = isRuleFulfilled(uischema, data, path, ajv);
569
+ switch (uischema.rule.effect) {
570
+ case RuleEffect.HIDE:
571
+ return !fulfilled;
572
+ case RuleEffect.SHOW:
573
+ return fulfilled;
346
574
  default:
347
- return state;
575
+ return true;
348
576
  }
349
577
  };
350
-
351
- const validate = (validator, data) => {
352
- if (validator === undefined) {
353
- return [];
354
- }
355
- const valid = validator(data);
356
- if (valid) {
357
- return [];
578
+ const evalEnablement = (uischema, data, path = undefined, ajv) => {
579
+ const fulfilled = isRuleFulfilled(uischema, data, path, ajv);
580
+ switch (uischema.rule.effect) {
581
+ case RuleEffect.DISABLE:
582
+ return !fulfilled;
583
+ case RuleEffect.ENABLE:
584
+ return fulfilled;
585
+ default:
586
+ return true;
358
587
  }
359
- return validator.errors;
360
- };
361
- const initState = {
362
- data: {},
363
- schema: {},
364
- uischema: undefined,
365
- errors: [],
366
- validator: undefined,
367
- ajv: undefined,
368
- validationMode: 'ValidateAndShow',
369
- additionalErrors: [],
370
588
  };
371
- const getOrCreateAjv = (state, action) => {
372
- if (action) {
373
- if (hasAjvOption(action.options)) {
374
- return action.options.ajv;
375
- }
376
- else if (action.options !== undefined) {
377
- if (isFunction(action.options.compile)) {
378
- return action.options;
379
- }
380
- }
589
+ const hasShowRule = (uischema) => {
590
+ if (uischema.rule &&
591
+ (uischema.rule.effect === RuleEffect.SHOW ||
592
+ uischema.rule.effect === RuleEffect.HIDE)) {
593
+ return true;
381
594
  }
382
- return state.ajv ? state.ajv : createAjv();
595
+ return false;
383
596
  };
384
- const hasAjvOption = (option) => {
385
- if (option) {
386
- return option.ajv !== undefined;
597
+ const hasEnableRule = (uischema) => {
598
+ if (uischema.rule &&
599
+ (uischema.rule.effect === RuleEffect.ENABLE ||
600
+ uischema.rule.effect === RuleEffect.DISABLE)) {
601
+ return true;
387
602
  }
388
603
  return false;
389
604
  };
390
- const getValidationMode = (state, action) => {
391
- if (action && hasValidationModeOption(action.options)) {
392
- return action.options.validationMode;
605
+ const isVisible = (uischema, data, path = undefined, ajv) => {
606
+ if (uischema.rule) {
607
+ return evalVisibility(uischema, data, path, ajv);
393
608
  }
394
- return state.validationMode;
609
+ return true;
395
610
  };
396
- const hasValidationModeOption = (option) => {
397
- if (option) {
398
- return option.validationMode !== undefined;
611
+ const isEnabled = (uischema, data, path = undefined, ajv) => {
612
+ if (uischema.rule) {
613
+ return evalEnablement(uischema, data, path, ajv);
399
614
  }
400
- return false;
615
+ return true;
401
616
  };
402
- const hasAdditionalErrorsOption = (option) => {
403
- if (option) {
404
- return option.additionalErrors !== undefined;
617
+
618
+ const getFirstPrimitiveProp = (schema) => {
619
+ if (schema.properties) {
620
+ return find(Object.keys(schema.properties), (propName) => {
621
+ const prop = schema.properties[propName];
622
+ return (prop.type === 'string' ||
623
+ prop.type === 'number' ||
624
+ prop.type === 'integer');
625
+ });
405
626
  }
406
- return false;
627
+ return undefined;
407
628
  };
408
- const getAdditionalErrors = (state, action) => {
409
- if (action && hasAdditionalErrorsOption(action.options)) {
410
- return action.options.additionalErrors;
629
+ const isOneOfEnumSchema = (schema) => !!schema &&
630
+ Object.prototype.hasOwnProperty.call(schema, 'oneOf') &&
631
+ schema.oneOf &&
632
+ schema.oneOf.every((s) => s.const !== undefined);
633
+ const isEnumSchema = (schema) => !!schema &&
634
+ typeof schema === 'object' &&
635
+ (Object.prototype.hasOwnProperty.call(schema, 'enum') ||
636
+ Object.prototype.hasOwnProperty.call(schema, 'const'));
637
+
638
+ const convertDateToString = (date, format) => {
639
+ const dateString = date.toISOString();
640
+ if (format === 'date-time') {
641
+ return dateString;
411
642
  }
412
- return state.additionalErrors;
643
+ else if (format === 'date') {
644
+ return dateString.split('T')[0];
645
+ }
646
+ else if (format === 'time') {
647
+ return dateString.split('T')[1].split('.')[0];
648
+ }
649
+ return dateString;
413
650
  };
414
- const coreReducer = (state = initState, action) => {
415
- switch (action.type) {
416
- case INIT: {
417
- const thisAjv = getOrCreateAjv(state, action);
418
- const validationMode = getValidationMode(state, action);
419
- const v = validationMode === 'NoValidation'
420
- ? undefined
421
- : thisAjv.compile(action.schema);
422
- const e = validate(v, action.data);
423
- const additionalErrors = getAdditionalErrors(state, action);
424
- return {
425
- ...state,
426
- data: action.data,
427
- schema: action.schema,
428
- uischema: action.uischema,
429
- additionalErrors,
430
- errors: e,
431
- validator: v,
432
- ajv: thisAjv,
433
- validationMode,
434
- };
435
- }
436
- case UPDATE_CORE: {
437
- const thisAjv = getOrCreateAjv(state, action);
438
- const validationMode = getValidationMode(state, action);
439
- let validator = state.validator;
440
- let errors = state.errors;
441
- if (state.schema !== action.schema ||
442
- state.validationMode !== validationMode ||
443
- state.ajv !== thisAjv) {
444
- validator =
445
- validationMode === 'NoValidation'
446
- ? undefined
447
- : thisAjv.compile(action.schema);
448
- errors = validate(validator, action.data);
651
+ const convertToValidClassName = (s) => s.replace('#', 'root').replace(new RegExp('/', 'g'), '_');
652
+ const hasType = (jsonSchema, expected) => {
653
+ return includes(deriveTypes(jsonSchema), expected);
654
+ };
655
+ const deriveTypes = (jsonSchema) => {
656
+ if (isEmpty(jsonSchema)) {
657
+ return [];
658
+ }
659
+ if (!isEmpty(jsonSchema.type) && typeof jsonSchema.type === 'string') {
660
+ return [jsonSchema.type];
661
+ }
662
+ if (isArray(jsonSchema.type)) {
663
+ return jsonSchema.type;
664
+ }
665
+ if (!isEmpty(jsonSchema.properties) ||
666
+ !isEmpty(jsonSchema.additionalProperties)) {
667
+ return ['object'];
668
+ }
669
+ if (!isEmpty(jsonSchema.items)) {
670
+ return ['array'];
671
+ }
672
+ if (!isEmpty(jsonSchema.enum)) {
673
+ const types = new Set();
674
+ jsonSchema.enum.forEach((enumElement) => {
675
+ if (typeof enumElement === 'string') {
676
+ types.add('string');
449
677
  }
450
- else if (state.data !== action.data) {
451
- errors = validate(validator, action.data);
678
+ else {
679
+ deriveTypes(enumElement).forEach((type) => types.add(type));
452
680
  }
453
- const additionalErrors = getAdditionalErrors(state, action);
454
- const stateChanged = state.data !== action.data ||
455
- state.schema !== action.schema ||
456
- state.uischema !== action.uischema ||
457
- state.ajv !== thisAjv ||
458
- state.errors !== errors ||
459
- state.validator !== validator ||
460
- state.validationMode !== validationMode ||
461
- state.additionalErrors !== additionalErrors;
462
- return stateChanged
463
- ? {
464
- ...state,
465
- data: action.data,
466
- schema: action.schema,
467
- uischema: action.uischema,
468
- ajv: thisAjv,
469
- errors: isEqual(errors, state.errors) ? state.errors : errors,
470
- validator: validator,
471
- validationMode: validationMode,
472
- additionalErrors,
473
- }
474
- : state;
475
- }
476
- case SET_AJV: {
477
- const currentAjv = action.ajv;
478
- const validator = state.validationMode === 'NoValidation'
479
- ? undefined
480
- : currentAjv.compile(state.schema);
481
- const errors = validate(validator, state.data);
482
- return {
483
- ...state,
484
- validator,
485
- errors,
486
- };
487
- }
488
- case SET_SCHEMA: {
489
- const needsNewValidator = action.schema && state.ajv && state.validationMode !== 'NoValidation';
490
- const v = needsNewValidator
491
- ? state.ajv.compile(action.schema)
492
- : state.validator;
493
- const errors = validate(v, state.data);
494
- return {
495
- ...state,
496
- validator: v,
497
- schema: action.schema,
498
- errors,
499
- };
500
- }
501
- case SET_UISCHEMA: {
502
- return {
503
- ...state,
504
- uischema: action.uischema,
505
- };
506
- }
507
- case UPDATE_DATA: {
508
- if (action.path === undefined || action.path === null) {
509
- return state;
510
- }
511
- else if (action.path === '') {
512
- const result = action.updater(cloneDeep(state.data));
513
- const errors = validate(state.validator, result);
514
- return {
515
- ...state,
516
- data: result,
517
- errors,
518
- };
519
- }
520
- else {
521
- const oldData = get(state.data, action.path);
522
- const newData = action.updater(cloneDeep(oldData));
523
- let newState;
524
- if (newData !== undefined) {
525
- newState = setFp(action.path, newData, state.data === undefined ? {} : state.data);
526
- }
527
- else {
528
- newState = unsetFp(action.path, state.data === undefined ? {} : state.data);
529
- }
530
- const errors = validate(state.validator, newState);
531
- return {
532
- ...state,
533
- data: newState,
534
- errors,
535
- };
536
- }
537
- }
538
- case UPDATE_ERRORS: {
539
- return {
540
- ...state,
541
- errors: action.errors,
542
- };
543
- }
544
- case SET_VALIDATION_MODE: {
545
- if (state.validationMode === action.validationMode) {
546
- return state;
547
- }
548
- if (action.validationMode === 'NoValidation') {
549
- const errors = validate(undefined, state.data);
550
- return {
551
- ...state,
552
- errors,
553
- validationMode: action.validationMode,
554
- };
555
- }
556
- if (state.validationMode === 'NoValidation') {
557
- const validator = state.ajv.compile(state.schema);
558
- const errors = validate(validator, state.data);
559
- return {
560
- ...state,
561
- validator,
562
- errors,
563
- validationMode: action.validationMode,
564
- };
565
- }
566
- return {
567
- ...state,
568
- validationMode: action.validationMode,
569
- };
681
+ });
682
+ return Array.from(types);
683
+ }
684
+ if (!isEmpty(jsonSchema.allOf)) {
685
+ const allOfType = find(jsonSchema.allOf, (schema) => deriveTypes(schema).length !== 0);
686
+ if (allOfType) {
687
+ return deriveTypes(allOfType);
570
688
  }
571
- default:
572
- return state;
573
689
  }
690
+ return [];
574
691
  };
575
- const extractData = (state) => get(state, 'data');
576
- const extractSchema = (state) => get(state, 'schema');
577
- const extractUiSchema = (state) => get(state, 'uischema');
578
- const extractAjv = (state) => get(state, 'ajv');
692
+ const Resolve = {
693
+ schema: resolveSchema,
694
+ data: resolveData,
695
+ };
696
+ const fromScoped = (scopable) => toDataPathSegments(scopable.scope).join('.');
697
+ const Paths = {
698
+ compose: compose,
699
+ fromScoped,
700
+ };
701
+ const Runtime = {
702
+ isEnabled(uischema, data, ajv) {
703
+ return isEnabled(uischema, data, undefined, ajv);
704
+ },
705
+ isVisible(uischema, data, ajv) {
706
+ return isVisible(uischema, data, undefined, ajv);
707
+ },
708
+ };
709
+
710
+ const createAjv = (options) => {
711
+ const ajv = new Ajv({
712
+ allErrors: true,
713
+ verbose: true,
714
+ strict: false,
715
+ addUsedSchema: false,
716
+ ...options,
717
+ });
718
+ addFormats(ajv);
719
+ return ajv;
720
+ };
721
+ const validate = (validator, data) => {
722
+ if (validator === undefined) {
723
+ return [];
724
+ }
725
+ const valid = validator(data);
726
+ if (valid) {
727
+ return [];
728
+ }
729
+ return validator.errors;
730
+ };
731
+
732
+ const defaultDateFormat = 'YYYY-MM-DD';
733
+ const defaultTimeFormat = 'HH:mm:ss';
734
+ const defaultDateTimeFormat = 'YYYY-MM-DDTHH:mm:ss.sssZ';
735
+
579
736
  const getInvalidProperty = (error) => {
580
737
  switch (error.keyword) {
581
738
  case 'required':
@@ -609,7 +766,7 @@ const errorsAt = (instancePath, schema, matchPath) => (errors) => {
609
766
  let result = matchPath(controlPath);
610
767
  const parentSchema = error.parentSchema;
611
768
  if (result &&
612
- !isObjectSchema$1(parentSchema) &&
769
+ !isObjectSchema(parentSchema) &&
613
770
  !isOneOfEnumSchema(parentSchema) &&
614
771
  combinatorPaths.findIndex((p) => instancePath.startsWith(p)) !== -1) {
615
772
  result = result && isEqual(parentSchema, schema);
@@ -617,7 +774,7 @@ const errorsAt = (instancePath, schema, matchPath) => (errors) => {
617
774
  return result;
618
775
  });
619
776
  };
620
- const isObjectSchema$1 = (schema) => {
777
+ const isObjectSchema = (schema) => {
621
778
  return schema?.type === 'object' || !!schema?.properties;
622
779
  };
623
780
  const filteredErrorKeywords = [
@@ -626,1031 +783,1193 @@ const filteredErrorKeywords = [
626
783
  'anyOf',
627
784
  'oneOf',
628
785
  ];
629
- const getErrorsAt = (instancePath, schema, matchPath) => (state) => {
630
- const errors = state.errors ?? [];
631
- const additionalErrors = state.additionalErrors ?? [];
632
- return errorsAt(instancePath, schema, matchPath)(state.validationMode === 'ValidateAndHide'
633
- ? additionalErrors
634
- : [...errors, ...additionalErrors]);
786
+ const formatErrorMessage = (errors) => {
787
+ if (errors === undefined || errors === null) {
788
+ return '';
789
+ }
790
+ return errors.join('\n');
635
791
  };
636
- const errorAt = (instancePath, schema) => getErrorsAt(instancePath, schema, (path) => path === instancePath);
637
- const subErrorsAt = (instancePath, schema) => getErrorsAt(instancePath, schema, (path) => path.startsWith(instancePath + '.'));
638
792
 
639
- const defaultDataReducer = (state = [], action) => {
640
- switch (action.type) {
641
- case ADD_DEFAULT_DATA:
642
- return state.concat([
643
- { schemaPath: action.schemaPath, data: action.data },
644
- ]);
645
- case REMOVE_DEFAULT_DATA:
646
- return state.filter((t) => t.schemaPath !== action.schemaPath);
647
- default:
648
- return state;
649
- }
793
+ const Helpers = {
794
+ createLabelDescriptionFrom,
795
+ convertToValidClassName,
650
796
  };
651
- const extractDefaultData = (state) => state;
652
797
 
653
- const getI18nKeyPrefixBySchema = (schema, uischema) => {
654
- if (isInternationalized(uischema)) {
655
- return uischema.i18n;
798
+ const createLayout = (layoutType) => ({
799
+ type: layoutType,
800
+ elements: [],
801
+ });
802
+ const createControlElement = (ref) => ({
803
+ type: 'Control',
804
+ scope: ref,
805
+ });
806
+ const wrapInLayoutIfNecessary = (uischema, layoutType) => {
807
+ if (!isEmpty(uischema) && !isLayout(uischema)) {
808
+ const verticalLayout = createLayout(layoutType);
809
+ verticalLayout.elements.push(uischema);
810
+ return verticalLayout;
656
811
  }
657
- return schema?.i18n ?? undefined;
658
- };
659
- const transformPathToI18nPrefix = (path) => {
660
- return (path
661
- ?.split('.')
662
- .filter((segment) => !/^\d+$/.test(segment))
663
- .join('.') || 'root');
664
- };
665
- const getI18nKeyPrefix = (schema, uischema, path) => {
666
- return (getI18nKeyPrefixBySchema(schema, uischema) ??
667
- transformPathToI18nPrefix(path));
812
+ return uischema;
668
813
  };
669
- const getI18nKey = (schema, uischema, path, key) => {
670
- return `${getI18nKeyPrefix(schema, uischema, path)}.${key}`;
814
+ const addLabel = (layout, labelName) => {
815
+ if (!isEmpty(labelName)) {
816
+ const fixedLabel = startCase(labelName);
817
+ if (isGroup(layout)) {
818
+ layout.label = fixedLabel;
819
+ }
820
+ else {
821
+ const label = {
822
+ type: 'Label',
823
+ text: fixedLabel,
824
+ };
825
+ layout.elements.push(label);
826
+ }
827
+ }
671
828
  };
672
- const addI18nKeyToPrefix = (i18nKeyPrefix, key) => {
673
- return `${i18nKeyPrefix}.${key}`;
829
+ const isCombinator = (jsonSchema) => {
830
+ return (!isEmpty(jsonSchema) &&
831
+ (!isEmpty(jsonSchema.oneOf) ||
832
+ !isEmpty(jsonSchema.anyOf) ||
833
+ !isEmpty(jsonSchema.allOf)));
674
834
  };
675
- const defaultTranslator = (_id, defaultMessage) => defaultMessage;
676
- const defaultErrorTranslator = (error, t, uischema) => {
677
- const i18nKey = getI18nKey(error.parentSchema, uischema, getControlPath(error), `error.${error.keyword}`);
678
- const specializedKeywordMessage = t(i18nKey, undefined, { error });
679
- if (specializedKeywordMessage !== undefined) {
680
- return specializedKeywordMessage;
681
- }
682
- const genericKeywordMessage = t(`error.${error.keyword}`, undefined, {
683
- error,
684
- });
685
- if (genericKeywordMessage !== undefined) {
686
- return genericKeywordMessage;
835
+ const generateUISchema = (jsonSchema, schemaElements, currentRef, schemaName, layoutType, rootSchema) => {
836
+ if (!isEmpty(jsonSchema) && jsonSchema.$ref !== undefined) {
837
+ return generateUISchema(resolveSchema(rootSchema, jsonSchema.$ref, rootSchema), schemaElements, currentRef, schemaName, layoutType, rootSchema);
687
838
  }
688
- const messageCustomization = t(error.message, undefined, { error });
689
- if (messageCustomization !== undefined) {
690
- return messageCustomization;
839
+ if (isCombinator(jsonSchema)) {
840
+ const controlObject = createControlElement(currentRef);
841
+ schemaElements.push(controlObject);
842
+ return controlObject;
691
843
  }
692
- if (error.keyword === 'required' &&
693
- error.message?.startsWith('must have required property')) {
694
- return t('is a required property', 'is a required property', { error });
695
- }
696
- return error.message;
697
- };
698
- const getCombinedErrorMessage = (errors, et, t, schema, uischema, path) => {
699
- if (errors.length > 0 && t) {
700
- const customErrorKey = getI18nKey(schema, uischema, path, 'error.custom');
701
- const specializedErrorMessage = t(customErrorKey, undefined, {
702
- schema,
703
- uischema,
704
- path,
705
- errors,
706
- });
707
- if (specializedErrorMessage !== undefined) {
708
- return specializedErrorMessage;
709
- }
844
+ const types = deriveTypes(jsonSchema);
845
+ if (types.length === 0) {
846
+ return null;
710
847
  }
711
- return formatErrorMessage(errors.map((error) => et(error, t, uischema)));
712
- };
713
- const deriveLabelForUISchemaElement = (uischema, t) => {
714
- if (uischema.label === false) {
715
- return undefined;
848
+ if (types.length > 1) {
849
+ const controlObject = createControlElement(currentRef);
850
+ schemaElements.push(controlObject);
851
+ return controlObject;
716
852
  }
717
- if ((uischema.label === undefined ||
718
- uischema.label === null ||
719
- uischema.label === true) &&
720
- !isInternationalized(uischema)) {
721
- return undefined;
853
+ if (currentRef === '#' && types[0] === 'object') {
854
+ const layout = createLayout(layoutType);
855
+ schemaElements.push(layout);
856
+ if (jsonSchema.properties && keys(jsonSchema.properties).length > 1) {
857
+ addLabel(layout, schemaName);
858
+ }
859
+ if (!isEmpty(jsonSchema.properties)) {
860
+ const nextRef = currentRef + '/properties';
861
+ Object.keys(jsonSchema.properties).map((propName) => {
862
+ let value = jsonSchema.properties[propName];
863
+ const ref = `${nextRef}/${encode(propName)}`;
864
+ if (value.$ref !== undefined) {
865
+ value = resolveSchema(rootSchema, value.$ref, rootSchema);
866
+ }
867
+ generateUISchema(value, layout.elements, ref, propName, layoutType, rootSchema);
868
+ });
869
+ }
870
+ return layout;
722
871
  }
723
- const stringifiedLabel = typeof uischema.label === 'string'
724
- ? uischema.label
725
- : JSON.stringify(uischema.label);
726
- const i18nKeyPrefix = getI18nKeyPrefixBySchema(undefined, uischema);
727
- const i18nKey = typeof i18nKeyPrefix === 'string'
728
- ? `${i18nKeyPrefix}.label`
729
- : stringifiedLabel;
730
- return t(i18nKey, stringifiedLabel, { uischema: uischema });
731
- };
732
- const getArrayTranslations = (t, defaultTranslations, i18nKeyPrefix, label) => {
733
- const translations = {};
734
- defaultTranslations.forEach((controlElement) => {
735
- const key = addI18nKeyToPrefix(i18nKeyPrefix, controlElement.key);
736
- translations[controlElement.key] = t(key, controlElement.default(label));
737
- });
738
- return translations;
739
- };
740
- const getCombinatorTranslations = (t, defaultTranslations, i18nKeyPrefix, label) => {
741
- const translations = {};
742
- defaultTranslations.forEach((controlElement) => {
743
- const key = addI18nKeyToPrefix(i18nKeyPrefix, controlElement.key);
744
- translations[controlElement.key] = t(key, controlElement.default(label));
745
- });
746
- return translations;
747
- };
748
-
749
- var ArrayTranslationEnum;
750
- (function (ArrayTranslationEnum) {
751
- ArrayTranslationEnum["addTooltip"] = "addTooltip";
752
- ArrayTranslationEnum["addAriaLabel"] = "addAriaLabel";
753
- ArrayTranslationEnum["removeTooltip"] = "removeTooltip";
754
- ArrayTranslationEnum["upAriaLabel"] = "upAriaLabel";
755
- ArrayTranslationEnum["downAriaLabel"] = "downAriaLabel";
756
- ArrayTranslationEnum["noSelection"] = "noSelection";
757
- ArrayTranslationEnum["removeAriaLabel"] = "removeAriaLabel";
758
- ArrayTranslationEnum["noDataMessage"] = "noDataMessage";
759
- ArrayTranslationEnum["deleteDialogTitle"] = "deleteDialogTitle";
760
- ArrayTranslationEnum["deleteDialogMessage"] = "deleteDialogMessage";
761
- ArrayTranslationEnum["deleteDialogAccept"] = "deleteDialogAccept";
762
- ArrayTranslationEnum["deleteDialogDecline"] = "deleteDialogDecline";
763
- ArrayTranslationEnum["up"] = "up";
764
- ArrayTranslationEnum["down"] = "down";
765
- })(ArrayTranslationEnum || (ArrayTranslationEnum = {}));
766
- const arrayDefaultTranslations = [
767
- {
768
- key: ArrayTranslationEnum.addTooltip,
769
- default: (input) => (input ? `Add to ${input}` : 'Add'),
770
- },
771
- {
772
- key: ArrayTranslationEnum.addAriaLabel,
773
- default: (input) => (input ? `Add to ${input} button` : 'Add button'),
774
- },
775
- { key: ArrayTranslationEnum.removeTooltip, default: () => 'Delete' },
776
- { key: ArrayTranslationEnum.removeAriaLabel, default: () => 'Delete button' },
777
- { key: ArrayTranslationEnum.upAriaLabel, default: () => `Move item up` },
778
- { key: ArrayTranslationEnum.up, default: () => 'Up' },
779
- { key: ArrayTranslationEnum.down, default: () => 'Down' },
780
- { key: ArrayTranslationEnum.downAriaLabel, default: () => `Move item down` },
781
- { key: ArrayTranslationEnum.noDataMessage, default: () => 'No data' },
782
- { key: ArrayTranslationEnum.noSelection, default: () => 'No selection' },
783
- {
784
- key: ArrayTranslationEnum.deleteDialogTitle,
785
- default: () => 'Confirm Deletion',
786
- },
787
- {
788
- key: ArrayTranslationEnum.deleteDialogMessage,
789
- default: () => 'Are you sure you want to delete the selected entry?',
790
- },
791
- { key: ArrayTranslationEnum.deleteDialogAccept, default: () => 'Yes' },
792
- { key: ArrayTranslationEnum.deleteDialogDecline, default: () => 'No' },
793
- ];
794
-
795
- var CombinatorTranslationEnum;
796
- (function (CombinatorTranslationEnum) {
797
- CombinatorTranslationEnum["clearDialogTitle"] = "clearDialogTitle";
798
- CombinatorTranslationEnum["clearDialogMessage"] = "clearDialogMessage";
799
- CombinatorTranslationEnum["clearDialogAccept"] = "clearDialogAccept";
800
- CombinatorTranslationEnum["clearDialogDecline"] = "clearDialogDecline";
801
- })(CombinatorTranslationEnum || (CombinatorTranslationEnum = {}));
802
- const combinatorDefaultTranslations = [
803
- {
804
- key: CombinatorTranslationEnum.clearDialogTitle,
805
- default: () => 'Clear form?',
806
- },
807
- {
808
- key: CombinatorTranslationEnum.clearDialogMessage,
809
- default: () => 'Your data will be cleared. Do you want to proceed?',
810
- },
811
- { key: CombinatorTranslationEnum.clearDialogAccept, default: () => 'Yes' },
812
- { key: CombinatorTranslationEnum.clearDialogDecline, default: () => 'No' },
813
- ];
814
-
815
- const defaultJsonFormsI18nState = {
816
- locale: 'en',
817
- translate: defaultTranslator,
818
- translateError: defaultErrorTranslator,
819
- };
820
- const i18nReducer = (state = defaultJsonFormsI18nState, action) => {
821
- switch (action.type) {
822
- case UPDATE_I18N: {
823
- const locale = action.locale ?? defaultJsonFormsI18nState.locale;
824
- const translate = action.translator ?? defaultJsonFormsI18nState.translate;
825
- const translateError = action.errorTranslator ?? defaultJsonFormsI18nState.translateError;
826
- if (locale !== state.locale ||
827
- translate !== state.translate ||
828
- translateError !== state.translateError) {
829
- return {
830
- ...state,
831
- locale,
832
- translate,
833
- translateError,
834
- };
835
- }
836
- return state;
872
+ switch (types[0]) {
873
+ case 'object':
874
+ case 'array':
875
+ case 'string':
876
+ case 'number':
877
+ case 'integer':
878
+ case 'null':
879
+ case 'boolean': {
880
+ const controlObject = createControlElement(currentRef);
881
+ schemaElements.push(controlObject);
882
+ return controlObject;
837
883
  }
838
- case SET_TRANSLATOR:
839
- return {
840
- ...state,
841
- translate: action.translator ?? defaultTranslator,
842
- translateError: action.errorTranslator ?? defaultErrorTranslator,
843
- };
844
- case SET_LOCALE:
845
- return {
846
- ...state,
847
- locale: action.locale ?? navigator.languages[0],
848
- };
849
884
  default:
850
- return state;
851
- }
852
- };
853
- const fetchLocale = (state) => {
854
- if (state === undefined) {
855
- return undefined;
856
- }
857
- return state.locale;
858
- };
859
- const fetchTranslator = (state) => {
860
- if (state === undefined) {
861
- return defaultTranslator;
862
- }
863
- return state.translate;
864
- };
865
- const fetchErrorTranslator = (state) => {
866
- if (state === undefined) {
867
- return defaultErrorTranslator;
885
+ throw new Error('Unknown type: ' + JSON.stringify(jsonSchema));
868
886
  }
869
- return state.translateError;
870
887
  };
888
+ const generateDefaultUISchema = (jsonSchema, layoutType = 'VerticalLayout', prefix = '#', rootSchema = jsonSchema) => wrapInLayoutIfNecessary(generateUISchema(jsonSchema, [], prefix, '', layoutType, rootSchema), layoutType);
871
889
 
872
- const rendererReducer = (state = [], action) => {
873
- switch (action.type) {
874
- case ADD_RENDERER:
875
- return state.concat([
876
- { tester: action.tester, renderer: action.renderer },
877
- ]);
878
- case REMOVE_RENDERER:
879
- return state.filter((t) => t.tester !== action.tester);
880
- default:
881
- return state;
882
- }
890
+ const Generate = {
891
+ jsonSchema: generateJsonSchema,
892
+ uiSchema: generateDefaultUISchema,
893
+ controlElement: createControlElement,
883
894
  };
884
895
 
885
- const NOT_APPLICABLE = -1;
886
- const isControl = (uischema) => !isEmpty(uischema) && uischema.scope !== undefined;
887
- const schemaMatches = (predicate) => (uischema, schema, context) => {
888
- if (isEmpty(uischema) || !isControl(uischema)) {
896
+ const INIT = 'jsonforms/INIT';
897
+ const UPDATE_CORE = 'jsonforms/UPDATE_CORE';
898
+ const SET_AJV = 'jsonforms/SET_AJV';
899
+ const UPDATE_DATA = 'jsonforms/UPDATE';
900
+ const UPDATE_ERRORS = 'jsonforms/UPDATE_ERRORS';
901
+ const VALIDATE = 'jsonforms/VALIDATE';
902
+ const ADD_RENDERER = 'jsonforms/ADD_RENDERER';
903
+ const REMOVE_RENDERER = 'jsonforms/REMOVE_RENDERER';
904
+ const ADD_CELL = 'jsonforms/ADD_CELL';
905
+ const REMOVE_CELL = 'jsonforms/REMOVE_CELL';
906
+ const SET_CONFIG = 'jsonforms/SET_CONFIG';
907
+ const ADD_UI_SCHEMA = 'jsonforms/ADD_UI_SCHEMA';
908
+ const REMOVE_UI_SCHEMA = 'jsonforms/REMOVE_UI_SCHEMA';
909
+ const SET_SCHEMA = 'jsonforms/SET_SCHEMA';
910
+ const SET_UISCHEMA = 'jsonforms/SET_UISCHEMA';
911
+ const SET_VALIDATION_MODE = 'jsonforms/SET_VALIDATION_MODE';
912
+ const SET_LOCALE = 'jsonforms/SET_LOCALE';
913
+ const SET_TRANSLATOR = 'jsonforms/SET_TRANSLATOR';
914
+ const UPDATE_I18N = 'jsonforms/UPDATE_I18N';
915
+ const ADD_DEFAULT_DATA = 'jsonforms/ADD_DEFAULT_DATA';
916
+ const REMOVE_DEFAULT_DATA = 'jsonforms/REMOVE_DEFAULT_DATA';
917
+ const isUpdateArrayContext = (context) => {
918
+ if (!('type' in context)) {
889
919
  return false;
890
920
  }
891
- if (isEmpty(schema)) {
921
+ if (typeof context.type !== 'string') {
892
922
  return false;
893
923
  }
894
- const schemaPath = uischema.scope;
895
- if (isEmpty(schemaPath)) {
896
- return false;
897
- }
898
- let currentDataSchema = schema;
899
- if (hasType(schema, 'object')) {
900
- currentDataSchema = resolveSchema(schema, schemaPath, context?.rootSchema);
901
- }
902
- if (currentDataSchema === undefined) {
903
- return false;
904
- }
905
- return predicate(currentDataSchema, context?.rootSchema);
906
- };
907
- const schemaSubPathMatches = (subPath, predicate) => (uischema, schema, context) => {
908
- if (isEmpty(uischema) || !isControl(uischema)) {
909
- return false;
910
- }
911
- const schemaPath = uischema.scope;
912
- let currentDataSchema = schema;
913
- if (hasType(schema, 'object')) {
914
- currentDataSchema = resolveSchema(schema, schemaPath, context?.rootSchema);
915
- }
916
- currentDataSchema = get(currentDataSchema, subPath);
917
- if (currentDataSchema === undefined) {
918
- return false;
919
- }
920
- return predicate(currentDataSchema, context?.rootSchema);
921
- };
922
- const schemaTypeIs = (expectedType) => schemaMatches((schema) => !isEmpty(schema) && hasType(schema, expectedType));
923
- const formatIs = (expectedFormat) => schemaMatches((schema) => !isEmpty(schema) &&
924
- schema.format === expectedFormat &&
925
- hasType(schema, 'string'));
926
- const uiTypeIs = (expected) => (uischema) => !isEmpty(uischema) && uischema.type === expected;
927
- const optionIs = (optionName, optionValue) => (uischema) => {
928
- if (isEmpty(uischema)) {
929
- return false;
930
- }
931
- const options = uischema.options;
932
- return !isEmpty(options) && options[optionName] === optionValue;
933
- };
934
- const hasOption = (optionName) => (uischema) => {
935
- if (isEmpty(uischema)) {
936
- return false;
937
- }
938
- const options = uischema.options;
939
- return !isEmpty(options) && !isUndefined(options[optionName]);
940
- };
941
- const scopeEndsWith = (expected) => (uischema) => {
942
- if (isEmpty(expected) || !isControl(uischema)) {
943
- return false;
944
- }
945
- return endsWith(uischema.scope, expected);
946
- };
947
- const scopeEndIs = (expected) => (uischema) => {
948
- if (isEmpty(expected) || !isControl(uischema)) {
949
- return false;
950
- }
951
- const schemaPath = uischema.scope;
952
- return !isEmpty(schemaPath) && last(schemaPath.split('/')) === expected;
953
- };
954
- const and = (...testers) => (uischema, schema, context) => testers.reduce((acc, tester) => acc && tester(uischema, schema, context), true);
955
- const or = (...testers) => (uischema, schema, context) => testers.reduce((acc, tester) => acc || tester(uischema, schema, context), false);
956
- const rankWith = (rank, tester) => (uischema, schema, context) => {
957
- if (tester(uischema, schema, context)) {
958
- return rank;
959
- }
960
- return NOT_APPLICABLE;
961
- };
962
- const withIncreasedRank = (by, rankedTester) => (uischema, schema, context) => {
963
- const rank = rankedTester(uischema, schema, context);
964
- if (rank === NOT_APPLICABLE) {
965
- return NOT_APPLICABLE;
966
- }
967
- return rank + by;
968
- };
969
- const isBooleanControl = and(uiTypeIs('Control'), schemaTypeIs('boolean'));
970
- const isObjectControl = and(uiTypeIs('Control'), schemaTypeIs('object'));
971
- const isAllOfControl = and(uiTypeIs('Control'), schemaMatches((schema) => Object.prototype.hasOwnProperty.call(schema, 'allOf')));
972
- const isAnyOfControl = and(uiTypeIs('Control'), schemaMatches((schema) => Object.prototype.hasOwnProperty.call(schema, 'anyOf')));
973
- const isOneOfControl = and(uiTypeIs('Control'), schemaMatches((schema) => Object.prototype.hasOwnProperty.call(schema, 'oneOf')));
974
- const isEnumControl = and(uiTypeIs('Control'), schemaMatches((schema) => isEnumSchema(schema)));
975
- const isOneOfEnumControl = and(uiTypeIs('Control'), schemaMatches((schema) => isOneOfEnumSchema(schema)));
976
- const isIntegerControl = and(uiTypeIs('Control'), schemaTypeIs('integer'));
977
- const isNumberControl = and(uiTypeIs('Control'), schemaTypeIs('number'));
978
- const isStringControl = and(uiTypeIs('Control'), schemaTypeIs('string'));
979
- const isMultiLineControl = and(uiTypeIs('Control'), optionIs('multi', true));
980
- const isDateControl = and(uiTypeIs('Control'), or(formatIs('date'), optionIs('format', 'date')));
981
- const isTimeControl = and(uiTypeIs('Control'), or(formatIs('time'), optionIs('format', 'time')));
982
- const isDateTimeControl = and(uiTypeIs('Control'), or(formatIs('date-time'), optionIs('format', 'date-time')));
983
- const isObjectArray = and(schemaMatches((schema, rootSchema) => hasType(schema, 'array') &&
984
- !Array.isArray(resolveSchema(schema, 'items', rootSchema))
985
- ), schemaSubPathMatches('items', (schema, rootSchema) => {
986
- const resolvedSchema = schema.$ref
987
- ? resolveSchema(rootSchema, schema.$ref, rootSchema)
988
- : schema;
989
- return hasType(resolvedSchema, 'object');
990
- }));
991
- const isObjectArrayControl = and(uiTypeIs('Control'), isObjectArray);
992
- const traverse = (any, pred, rootSchema) => {
993
- if (isArray(any)) {
994
- return reduce(any, (acc, el) => acc || traverse(el, pred, rootSchema), false);
995
- }
996
- if (pred(any)) {
997
- return true;
998
- }
999
- if (any.$ref) {
1000
- const toTraverse = resolveSchema(rootSchema, any.$ref, rootSchema);
1001
- if (toTraverse && !toTraverse.$ref) {
1002
- return traverse(toTraverse, pred, rootSchema);
924
+ switch (context.type) {
925
+ case 'ADD': {
926
+ return ('values' in context &&
927
+ Array.isArray(context.values) &&
928
+ context.values.length > 0);
1003
929
  }
1004
- }
1005
- if (any.items) {
1006
- return traverse(any.items, pred, rootSchema);
1007
- }
1008
- if (any.properties) {
1009
- return reduce(toPairs(any.properties), (acc, [_key, val]) => acc || traverse(val, pred, rootSchema), false);
1010
- }
1011
- return false;
1012
- };
1013
- const isObjectArrayWithNesting = (uischema, schema, context) => {
1014
- if (!uiTypeIs('Control')(uischema, schema, context)) {
1015
- return false;
1016
- }
1017
- const schemaPath = uischema.scope;
1018
- const resolvedSchema = resolveSchema(schema, schemaPath, context?.rootSchema ?? schema);
1019
- let objectDepth = 0;
1020
- if (resolvedSchema !== undefined && resolvedSchema.items !== undefined) {
1021
- if (traverse(resolvedSchema.items, (val) => {
1022
- if (val === schema) {
1023
- return false;
1024
- }
1025
- if (val.$ref !== undefined) {
1026
- return false;
1027
- }
1028
- if (val.anyOf || val.allOf) {
1029
- return true;
1030
- }
1031
- if (val.oneOf && !isOneOfEnumSchema(val)) {
1032
- return true;
1033
- }
1034
- if (hasType(val, 'object')) {
1035
- objectDepth++;
1036
- if (objectDepth === 2) {
1037
- return true;
1038
- }
1039
- }
1040
- if (hasType(val, 'array')) {
1041
- return true;
1042
- }
1043
- return false;
1044
- }, context?.rootSchema)) {
1045
- return true;
930
+ case 'REMOVE': {
931
+ return ('indices' in context &&
932
+ Array.isArray(context.indices) &&
933
+ context.indices.length > 0 &&
934
+ context.indices.every((i) => typeof i === 'number'));
1046
935
  }
1047
- if (uischema.options && uischema.options.detail) {
1048
- if (typeof uischema.options.detail === 'string') {
1049
- return uischema.options.detail.toUpperCase() !== 'DEFAULT';
1050
- }
1051
- else if (typeof uischema.options.detail === 'object' &&
1052
- uischema.options.detail.type) {
1053
- return true;
1054
- }
936
+ case 'MOVE': {
937
+ return ('moves' in context &&
938
+ Array.isArray(context.moves) &&
939
+ context.moves.length > 0 &&
940
+ context.moves.every((m) => typeof m === 'object' &&
941
+ m !== null &&
942
+ 'from' in m &&
943
+ 'to' in m &&
944
+ typeof m.from === 'number' &&
945
+ typeof m.to === 'number'));
1055
946
  }
947
+ default:
948
+ return false;
1056
949
  }
1057
- return false;
1058
950
  };
1059
- const isArrayObjectControl = isObjectArrayControl;
1060
- const isPrimitiveArrayControl = and(uiTypeIs('Control'), schemaMatches((schema, rootSchema) => deriveTypes(schema).length !== 0 &&
1061
- !Array.isArray(resolveSchema(schema, 'items', rootSchema))
1062
- ), schemaSubPathMatches('items', (schema, rootSchema) => {
1063
- const resolvedSchema = schema.$ref
1064
- ? resolveSchema(rootSchema, schema.$ref, rootSchema)
1065
- : schema;
1066
- const types = deriveTypes(resolvedSchema);
1067
- return (types.length === 1 &&
1068
- includes(['integer', 'number', 'boolean', 'string'], types[0]));
1069
- }));
1070
- const isRangeControl = and(uiTypeIs('Control'), or(schemaTypeIs('number'), schemaTypeIs('integer')), schemaMatches((schema) => Object.prototype.hasOwnProperty.call(schema, 'maximum') &&
1071
- Object.prototype.hasOwnProperty.call(schema, 'minimum') &&
1072
- Object.prototype.hasOwnProperty.call(schema, 'default')), optionIs('slider', true));
1073
- const isNumberFormatControl = and(uiTypeIs('Control'), schemaTypeIs('integer'), optionIs('format', true));
1074
- const isCategorization = (category) => category.type === 'Categorization';
1075
- const isCategory = (uischema) => uischema.type === 'Category';
1076
- const hasCategory = (categorization) => {
1077
- if (isEmpty(categorization.elements)) {
1078
- return false;
1079
- }
1080
- return categorization.elements
1081
- .map((elem) => isCategorization(elem) ? hasCategory(elem) : isCategory(elem))
1082
- .reduce((prev, curr) => prev && curr, true);
951
+ const init = (data, schema = generateJsonSchema(data), uischema, options) => ({
952
+ type: INIT,
953
+ data,
954
+ schema,
955
+ uischema: typeof uischema === 'object' ? uischema : generateDefaultUISchema(schema),
956
+ options,
957
+ });
958
+ const updateCore = (data, schema, uischema, options) => ({
959
+ type: UPDATE_CORE,
960
+ data,
961
+ schema,
962
+ uischema,
963
+ options,
964
+ });
965
+ const registerDefaultData = (schemaPath, data) => ({
966
+ type: ADD_DEFAULT_DATA,
967
+ schemaPath,
968
+ data,
969
+ });
970
+ const unregisterDefaultData = (schemaPath) => ({
971
+ type: REMOVE_DEFAULT_DATA,
972
+ schemaPath,
973
+ });
974
+ const setAjv = (ajv) => ({
975
+ type: SET_AJV,
976
+ ajv,
977
+ });
978
+ const update = (path, updater, context) => ({
979
+ type: UPDATE_DATA,
980
+ path,
981
+ updater,
982
+ context,
983
+ });
984
+ const updateErrors = (errors) => ({
985
+ type: UPDATE_ERRORS,
986
+ errors,
987
+ });
988
+ const registerRenderer = (tester, renderer) => ({
989
+ type: ADD_RENDERER,
990
+ tester,
991
+ renderer,
992
+ });
993
+ const registerCell = (tester, cell) => ({
994
+ type: ADD_CELL,
995
+ tester,
996
+ cell,
997
+ });
998
+ const unregisterCell = (tester, cell) => ({
999
+ type: REMOVE_CELL,
1000
+ tester,
1001
+ cell,
1002
+ });
1003
+ const unregisterRenderer = (tester, renderer) => ({
1004
+ type: REMOVE_RENDERER,
1005
+ tester,
1006
+ renderer,
1007
+ });
1008
+ const setConfig = (config) => ({
1009
+ type: SET_CONFIG,
1010
+ config,
1011
+ });
1012
+ const setValidationMode = (validationMode) => ({
1013
+ type: SET_VALIDATION_MODE,
1014
+ validationMode,
1015
+ });
1016
+ const registerUISchema = (tester, uischema) => {
1017
+ return {
1018
+ type: ADD_UI_SCHEMA,
1019
+ tester,
1020
+ uischema,
1021
+ };
1083
1022
  };
1084
- const categorizationHasCategory = (uischema) => hasCategory(uischema);
1085
- const not = (tester) => (uischema, schema, context) => !tester(uischema, schema, context);
1023
+ const unregisterUISchema = (tester) => {
1024
+ return {
1025
+ type: REMOVE_UI_SCHEMA,
1026
+ tester,
1027
+ };
1028
+ };
1029
+ const setLocale = (locale) => ({
1030
+ type: SET_LOCALE,
1031
+ locale,
1032
+ });
1033
+ const setSchema = (schema) => ({
1034
+ type: SET_SCHEMA,
1035
+ schema,
1036
+ });
1037
+ const setTranslator = (translator, errorTranslator) => ({
1038
+ type: SET_TRANSLATOR,
1039
+ translator,
1040
+ errorTranslator,
1041
+ });
1042
+ const updateI18n = (locale, translator, errorTranslator) => ({
1043
+ type: UPDATE_I18N,
1044
+ locale,
1045
+ translator,
1046
+ errorTranslator,
1047
+ });
1048
+ const setUISchema = (uischema) => ({
1049
+ type: SET_UISCHEMA,
1050
+ uischema,
1051
+ });
1086
1052
 
1087
1053
  var index$1 = /*#__PURE__*/Object.freeze({
1088
1054
  __proto__: null,
1089
- NOT_APPLICABLE: NOT_APPLICABLE,
1090
- isControl: isControl,
1091
- schemaMatches: schemaMatches,
1092
- schemaSubPathMatches: schemaSubPathMatches,
1093
- schemaTypeIs: schemaTypeIs,
1094
- formatIs: formatIs,
1095
- uiTypeIs: uiTypeIs,
1096
- optionIs: optionIs,
1097
- hasOption: hasOption,
1098
- scopeEndsWith: scopeEndsWith,
1099
- scopeEndIs: scopeEndIs,
1100
- and: and,
1101
- or: or,
1102
- rankWith: rankWith,
1103
- withIncreasedRank: withIncreasedRank,
1104
- isBooleanControl: isBooleanControl,
1105
- isObjectControl: isObjectControl,
1106
- isAllOfControl: isAllOfControl,
1107
- isAnyOfControl: isAnyOfControl,
1108
- isOneOfControl: isOneOfControl,
1109
- isEnumControl: isEnumControl,
1110
- isOneOfEnumControl: isOneOfEnumControl,
1111
- isIntegerControl: isIntegerControl,
1112
- isNumberControl: isNumberControl,
1113
- isStringControl: isStringControl,
1114
- isMultiLineControl: isMultiLineControl,
1115
- isDateControl: isDateControl,
1116
- isTimeControl: isTimeControl,
1117
- isDateTimeControl: isDateTimeControl,
1118
- isObjectArray: isObjectArray,
1119
- isObjectArrayControl: isObjectArrayControl,
1120
- isObjectArrayWithNesting: isObjectArrayWithNesting,
1121
- isArrayObjectControl: isArrayObjectControl,
1122
- isPrimitiveArrayControl: isPrimitiveArrayControl,
1123
- isRangeControl: isRangeControl,
1124
- isNumberFormatControl: isNumberFormatControl,
1125
- isCategorization: isCategorization,
1126
- isCategory: isCategory,
1127
- hasCategory: hasCategory,
1128
- categorizationHasCategory: categorizationHasCategory,
1129
- not: not
1055
+ INIT: INIT,
1056
+ UPDATE_CORE: UPDATE_CORE,
1057
+ SET_AJV: SET_AJV,
1058
+ UPDATE_DATA: UPDATE_DATA,
1059
+ UPDATE_ERRORS: UPDATE_ERRORS,
1060
+ VALIDATE: VALIDATE,
1061
+ ADD_RENDERER: ADD_RENDERER,
1062
+ REMOVE_RENDERER: REMOVE_RENDERER,
1063
+ ADD_CELL: ADD_CELL,
1064
+ REMOVE_CELL: REMOVE_CELL,
1065
+ SET_CONFIG: SET_CONFIG,
1066
+ ADD_UI_SCHEMA: ADD_UI_SCHEMA,
1067
+ REMOVE_UI_SCHEMA: REMOVE_UI_SCHEMA,
1068
+ SET_SCHEMA: SET_SCHEMA,
1069
+ SET_UISCHEMA: SET_UISCHEMA,
1070
+ SET_VALIDATION_MODE: SET_VALIDATION_MODE,
1071
+ SET_LOCALE: SET_LOCALE,
1072
+ SET_TRANSLATOR: SET_TRANSLATOR,
1073
+ UPDATE_I18N: UPDATE_I18N,
1074
+ ADD_DEFAULT_DATA: ADD_DEFAULT_DATA,
1075
+ REMOVE_DEFAULT_DATA: REMOVE_DEFAULT_DATA,
1076
+ isUpdateArrayContext: isUpdateArrayContext,
1077
+ init: init,
1078
+ updateCore: updateCore,
1079
+ registerDefaultData: registerDefaultData,
1080
+ unregisterDefaultData: unregisterDefaultData,
1081
+ setAjv: setAjv,
1082
+ update: update,
1083
+ updateErrors: updateErrors,
1084
+ registerRenderer: registerRenderer,
1085
+ registerCell: registerCell,
1086
+ unregisterCell: unregisterCell,
1087
+ unregisterRenderer: unregisterRenderer,
1088
+ setConfig: setConfig,
1089
+ setValidationMode: setValidationMode,
1090
+ registerUISchema: registerUISchema,
1091
+ unregisterUISchema: unregisterUISchema,
1092
+ setLocale: setLocale,
1093
+ setSchema: setSchema,
1094
+ setTranslator: setTranslator,
1095
+ updateI18n: updateI18n,
1096
+ setUISchema: setUISchema
1130
1097
  });
1131
1098
 
1132
- const uischemaRegistryReducer = (state = [], action) => {
1133
- switch (action.type) {
1134
- case ADD_UI_SCHEMA:
1135
- return state
1136
- .slice()
1137
- .concat({ tester: action.tester, uischema: action.uischema });
1138
- case REMOVE_UI_SCHEMA: {
1139
- const copy = state.slice();
1140
- remove(copy, (entry) => entry.tester === action.tester);
1141
- return copy;
1142
- }
1099
+ const cellReducer = (state = [], { type, tester, cell }) => {
1100
+ switch (type) {
1101
+ case ADD_CELL:
1102
+ return state.concat([{ tester, cell }]);
1103
+ case REMOVE_CELL:
1104
+ return state.filter((t) => t.tester !== tester);
1143
1105
  default:
1144
1106
  return state;
1145
1107
  }
1146
1108
  };
1147
- const findMatchingUISchema = (state) => (jsonSchema, schemaPath, path) => {
1148
- const match = maxBy(state, (entry) => entry.tester(jsonSchema, schemaPath, path));
1149
- if (match !== undefined &&
1150
- match.tester(jsonSchema, schemaPath, path) !== NOT_APPLICABLE) {
1151
- return match.uischema;
1109
+
1110
+ const configDefault = {
1111
+ restrict: false,
1112
+ trim: false,
1113
+ showUnfocusedDescription: false,
1114
+ hideRequiredAsterisk: false,
1115
+ };
1116
+
1117
+ const applyDefaultConfiguration = (config = {}) => merge({}, configDefault, config);
1118
+ const configReducer = (state = applyDefaultConfiguration(), action) => {
1119
+ switch (action.type) {
1120
+ case SET_CONFIG:
1121
+ return applyDefaultConfiguration(action.config);
1122
+ default:
1123
+ return state;
1152
1124
  }
1153
- return undefined;
1154
1125
  };
1155
1126
 
1156
- const jsonFormsReducerConfig = {
1157
- core: coreReducer,
1158
- renderers: rendererReducer,
1159
- cells: cellReducer,
1160
- config: configReducer,
1161
- uischemas: uischemaRegistryReducer,
1162
- defaultData: defaultDataReducer,
1163
- i18n: i18nReducer,
1127
+ const initState = {
1128
+ data: {},
1129
+ schema: {},
1130
+ uischema: undefined,
1131
+ errors: [],
1132
+ validator: undefined,
1133
+ ajv: undefined,
1134
+ validationMode: 'ValidateAndShow',
1135
+ additionalErrors: [],
1164
1136
  };
1165
- const findUISchema = (uischemas, schema, schemaPath, path, fallback = 'VerticalLayout', control, rootSchema) => {
1166
- if (control && control.options && control.options.detail) {
1167
- if (typeof control.options.detail === 'string') {
1168
- if (control.options.detail.toUpperCase() === 'GENERATE') {
1169
- if (typeof fallback === 'function') {
1170
- return fallback();
1137
+ const getValidationMode = (state, action) => {
1138
+ if (action && hasValidationModeOption(action.options)) {
1139
+ return action.options.validationMode;
1140
+ }
1141
+ return state.validationMode;
1142
+ };
1143
+ const hasValidationModeOption = (option) => {
1144
+ if (option) {
1145
+ return option.validationMode !== undefined;
1146
+ }
1147
+ return false;
1148
+ };
1149
+ const hasAdditionalErrorsOption = (option) => {
1150
+ if (option) {
1151
+ return option.additionalErrors !== undefined;
1152
+ }
1153
+ return false;
1154
+ };
1155
+ const getAdditionalErrors = (state, action) => {
1156
+ if (action && hasAdditionalErrorsOption(action.options)) {
1157
+ return action.options.additionalErrors;
1158
+ }
1159
+ return state.additionalErrors;
1160
+ };
1161
+ const getOrCreateAjv = (state, action) => {
1162
+ if (action) {
1163
+ if (hasAjvOption(action.options)) {
1164
+ return action.options.ajv;
1165
+ }
1166
+ else if (action.options !== undefined) {
1167
+ if (isFunction(action.options.compile)) {
1168
+ return action.options;
1169
+ }
1170
+ }
1171
+ }
1172
+ return state.ajv ? state.ajv : createAjv();
1173
+ };
1174
+ const hasAjvOption = (option) => {
1175
+ if (option) {
1176
+ return option.ajv !== undefined;
1177
+ }
1178
+ return false;
1179
+ };
1180
+ const coreReducer = (state = initState, action) => {
1181
+ switch (action.type) {
1182
+ case INIT: {
1183
+ const thisAjv = getOrCreateAjv(state, action);
1184
+ const validationMode = getValidationMode(state, action);
1185
+ const v = validationMode === 'NoValidation'
1186
+ ? undefined
1187
+ : thisAjv.compile(action.schema);
1188
+ const e = validate(v, action.data);
1189
+ const additionalErrors = getAdditionalErrors(state, action);
1190
+ return {
1191
+ ...state,
1192
+ data: action.data,
1193
+ schema: action.schema,
1194
+ uischema: action.uischema,
1195
+ additionalErrors,
1196
+ errors: e,
1197
+ validator: v,
1198
+ ajv: thisAjv,
1199
+ validationMode,
1200
+ };
1201
+ }
1202
+ case UPDATE_CORE: {
1203
+ const thisAjv = getOrCreateAjv(state, action);
1204
+ const validationMode = getValidationMode(state, action);
1205
+ let validator = state.validator;
1206
+ let errors = state.errors;
1207
+ if (state.schema !== action.schema ||
1208
+ state.validationMode !== validationMode ||
1209
+ state.ajv !== thisAjv) {
1210
+ validator =
1211
+ validationMode === 'NoValidation'
1212
+ ? undefined
1213
+ : thisAjv.compile(action.schema);
1214
+ errors = validate(validator, action.data);
1215
+ }
1216
+ else if (state.data !== action.data) {
1217
+ errors = validate(validator, action.data);
1218
+ }
1219
+ const additionalErrors = getAdditionalErrors(state, action);
1220
+ const stateChanged = state.data !== action.data ||
1221
+ state.schema !== action.schema ||
1222
+ state.uischema !== action.uischema ||
1223
+ state.ajv !== thisAjv ||
1224
+ state.errors !== errors ||
1225
+ state.validator !== validator ||
1226
+ state.validationMode !== validationMode ||
1227
+ state.additionalErrors !== additionalErrors;
1228
+ return stateChanged
1229
+ ? {
1230
+ ...state,
1231
+ data: action.data,
1232
+ schema: action.schema,
1233
+ uischema: action.uischema,
1234
+ ajv: thisAjv,
1235
+ errors: isEqual(errors, state.errors) ? state.errors : errors,
1236
+ validator: validator,
1237
+ validationMode: validationMode,
1238
+ additionalErrors,
1171
1239
  }
1172
- return Generate.uiSchema(schema, fallback, undefined, rootSchema);
1240
+ : state;
1241
+ }
1242
+ case SET_AJV: {
1243
+ const currentAjv = action.ajv;
1244
+ const validator = state.validationMode === 'NoValidation'
1245
+ ? undefined
1246
+ : currentAjv.compile(state.schema);
1247
+ const errors = validate(validator, state.data);
1248
+ return {
1249
+ ...state,
1250
+ validator,
1251
+ errors,
1252
+ };
1253
+ }
1254
+ case SET_SCHEMA: {
1255
+ const needsNewValidator = action.schema && state.ajv && state.validationMode !== 'NoValidation';
1256
+ const v = needsNewValidator
1257
+ ? state.ajv.compile(action.schema)
1258
+ : state.validator;
1259
+ const errors = validate(v, state.data);
1260
+ return {
1261
+ ...state,
1262
+ validator: v,
1263
+ schema: action.schema,
1264
+ errors,
1265
+ };
1266
+ }
1267
+ case SET_UISCHEMA: {
1268
+ return {
1269
+ ...state,
1270
+ uischema: action.uischema,
1271
+ };
1272
+ }
1273
+ case UPDATE_DATA: {
1274
+ if (action.path === undefined || action.path === null) {
1275
+ return state;
1276
+ }
1277
+ else if (action.path === '') {
1278
+ const result = action.updater(cloneDeep(state.data));
1279
+ const errors = validate(state.validator, result);
1280
+ return {
1281
+ ...state,
1282
+ data: result,
1283
+ errors,
1284
+ };
1285
+ }
1286
+ else {
1287
+ const oldData = get(state.data, action.path);
1288
+ const newData = action.updater(cloneDeep(oldData));
1289
+ let newState;
1290
+ if (newData !== undefined) {
1291
+ newState = setFp(action.path, newData, state.data === undefined ? {} : state.data);
1292
+ }
1293
+ else {
1294
+ newState = unsetFp(action.path, state.data === undefined ? {} : state.data);
1295
+ }
1296
+ const errors = validate(state.validator, newState);
1297
+ return {
1298
+ ...state,
1299
+ data: newState,
1300
+ errors,
1301
+ };
1173
1302
  }
1174
1303
  }
1175
- else if (typeof control.options.detail === 'object') {
1176
- if (control.options.detail.type &&
1177
- typeof control.options.detail.type === 'string') {
1178
- return control.options.detail;
1304
+ case UPDATE_ERRORS: {
1305
+ return {
1306
+ ...state,
1307
+ errors: action.errors,
1308
+ };
1309
+ }
1310
+ case SET_VALIDATION_MODE: {
1311
+ if (state.validationMode === action.validationMode) {
1312
+ return state;
1313
+ }
1314
+ if (action.validationMode === 'NoValidation') {
1315
+ const errors = validate(undefined, state.data);
1316
+ return {
1317
+ ...state,
1318
+ errors,
1319
+ validationMode: action.validationMode,
1320
+ };
1321
+ }
1322
+ if (state.validationMode === 'NoValidation') {
1323
+ const validator = state.ajv.compile(state.schema);
1324
+ const errors = validate(validator, state.data);
1325
+ return {
1326
+ ...state,
1327
+ validator,
1328
+ errors,
1329
+ validationMode: action.validationMode,
1330
+ };
1179
1331
  }
1332
+ return {
1333
+ ...state,
1334
+ validationMode: action.validationMode,
1335
+ };
1180
1336
  }
1337
+ default:
1338
+ return state;
1181
1339
  }
1182
- const uiSchema = findMatchingUISchema(uischemas)(schema, schemaPath, path);
1183
- if (uiSchema === undefined) {
1184
- if (typeof fallback === 'function') {
1185
- return fallback();
1186
- }
1187
- return Generate.uiSchema(schema, fallback, '#', rootSchema);
1188
- }
1189
- return uiSchema;
1190
- };
1191
- const getErrorAt = (instancePath, schema) => (state) => {
1192
- return errorAt(instancePath, schema)(state.jsonforms.core);
1193
1340
  };
1194
- const getSubErrorsAt = (instancePath, schema) => (state) => subErrorsAt(instancePath, schema)(state.jsonforms.core);
1195
- const getConfig = (state) => state.jsonforms.config;
1196
- const getLocale = (state) => fetchLocale(get(state, 'jsonforms.i18n'));
1197
- const getTranslator = () => (state) => fetchTranslator(get(state, 'jsonforms.i18n'));
1198
- const getErrorTranslator = () => (state) => fetchErrorTranslator(get(state, 'jsonforms.i18n'));
1199
1341
 
1200
- const getData = (state) => extractData(get(state, 'jsonforms.core'));
1201
- const getSchema = (state) => extractSchema(get(state, 'jsonforms.core'));
1202
- const getUiSchema = (state) => extractUiSchema(get(state, 'jsonforms.core'));
1203
- const getAjv = (state) => extractAjv(get(state, 'jsonforms.core'));
1342
+ const defaultDataReducer = (state = [], action) => {
1343
+ switch (action.type) {
1344
+ case ADD_DEFAULT_DATA:
1345
+ return state.concat([
1346
+ { schemaPath: action.schemaPath, data: action.data },
1347
+ ]);
1348
+ case REMOVE_DEFAULT_DATA:
1349
+ return state.filter((t) => t.schemaPath !== action.schemaPath);
1350
+ default:
1351
+ return state;
1352
+ }
1353
+ };
1204
1354
  const getDefaultData = (state) => extractDefaultData(get(state, 'jsonforms.defaultData'));
1205
- const getRenderers = (state) => get(state, 'jsonforms.renderers');
1206
- const getCells = (state) => get(state, 'jsonforms.cells');
1207
- const getUISchemas = (state) => get(state, 'jsonforms.uischemas');
1355
+ const extractDefaultData = (state) => state;
1208
1356
 
1209
- const defaultMiddleware = (state, action, defaultReducer) => defaultReducer(state, action);
1357
+ var ArrayTranslationEnum;
1358
+ (function (ArrayTranslationEnum) {
1359
+ ArrayTranslationEnum["addTooltip"] = "addTooltip";
1360
+ ArrayTranslationEnum["addAriaLabel"] = "addAriaLabel";
1361
+ ArrayTranslationEnum["removeTooltip"] = "removeTooltip";
1362
+ ArrayTranslationEnum["upAriaLabel"] = "upAriaLabel";
1363
+ ArrayTranslationEnum["downAriaLabel"] = "downAriaLabel";
1364
+ ArrayTranslationEnum["noSelection"] = "noSelection";
1365
+ ArrayTranslationEnum["removeAriaLabel"] = "removeAriaLabel";
1366
+ ArrayTranslationEnum["noDataMessage"] = "noDataMessage";
1367
+ ArrayTranslationEnum["deleteDialogTitle"] = "deleteDialogTitle";
1368
+ ArrayTranslationEnum["deleteDialogMessage"] = "deleteDialogMessage";
1369
+ ArrayTranslationEnum["deleteDialogAccept"] = "deleteDialogAccept";
1370
+ ArrayTranslationEnum["deleteDialogDecline"] = "deleteDialogDecline";
1371
+ ArrayTranslationEnum["up"] = "up";
1372
+ ArrayTranslationEnum["down"] = "down";
1373
+ })(ArrayTranslationEnum || (ArrayTranslationEnum = {}));
1374
+ const arrayDefaultTranslations = [
1375
+ {
1376
+ key: ArrayTranslationEnum.addTooltip,
1377
+ default: (input) => (input ? `Add to ${input}` : 'Add'),
1378
+ },
1379
+ {
1380
+ key: ArrayTranslationEnum.addAriaLabel,
1381
+ default: (input) => (input ? `Add to ${input} button` : 'Add button'),
1382
+ },
1383
+ { key: ArrayTranslationEnum.removeTooltip, default: () => 'Delete' },
1384
+ { key: ArrayTranslationEnum.removeAriaLabel, default: () => 'Delete button' },
1385
+ { key: ArrayTranslationEnum.upAriaLabel, default: () => `Move item up` },
1386
+ { key: ArrayTranslationEnum.up, default: () => 'Up' },
1387
+ { key: ArrayTranslationEnum.down, default: () => 'Down' },
1388
+ { key: ArrayTranslationEnum.downAriaLabel, default: () => `Move item down` },
1389
+ { key: ArrayTranslationEnum.noDataMessage, default: () => 'No data' },
1390
+ { key: ArrayTranslationEnum.noSelection, default: () => 'No selection' },
1391
+ {
1392
+ key: ArrayTranslationEnum.deleteDialogTitle,
1393
+ default: () => 'Confirm Deletion',
1394
+ },
1395
+ {
1396
+ key: ArrayTranslationEnum.deleteDialogMessage,
1397
+ default: () => 'Are you sure you want to delete the selected entry?',
1398
+ },
1399
+ { key: ArrayTranslationEnum.deleteDialogAccept, default: () => 'Yes' },
1400
+ { key: ArrayTranslationEnum.deleteDialogDecline, default: () => 'No' },
1401
+ ];
1210
1402
 
1211
- const compose = (path1, path2) => {
1212
- let p1 = path1;
1213
- if (!isEmpty(path1) && !isEmpty(path2) && !path2.startsWith('[')) {
1214
- p1 = path1 + '.';
1215
- }
1216
- if (isEmpty(p1)) {
1217
- return path2;
1218
- }
1219
- else if (isEmpty(path2)) {
1220
- return p1;
1221
- }
1222
- else {
1223
- return `${p1}${path2}`;
1224
- }
1225
- };
1226
- const toDataPathSegments = (schemaPath) => {
1227
- const s = schemaPath
1228
- .replace(/(anyOf|allOf|oneOf)\/[\d]+\//g, '')
1229
- .replace(/(then|else)\//g, '');
1230
- const segments = s.split('/');
1231
- const decodedSegments = segments.map(decode);
1232
- const startFromRoot = decodedSegments[0] === '#' || decodedSegments[0] === '';
1233
- const startIndex = startFromRoot ? 2 : 1;
1234
- return range(startIndex, decodedSegments.length, 2).map((idx) => decodedSegments[idx]);
1235
- };
1236
- const toDataPath = (schemaPath) => {
1237
- return toDataPathSegments(schemaPath).join('.');
1238
- };
1239
- const composeWithUi = (scopableUi, path) => {
1240
- if (!isScoped(scopableUi)) {
1241
- return path ?? '';
1242
- }
1243
- const segments = toDataPathSegments(scopableUi.scope);
1244
- if (isEmpty(segments)) {
1245
- return path ?? '';
1246
- }
1247
- return compose(path, segments.join('.'));
1248
- };
1249
- const encode = (segment) => segment?.replace(/~/g, '~0').replace(/\//g, '~1');
1250
- const decode = (pointerSegment) => pointerSegment?.replace(/~1/g, '/').replace(/~0/, '~');
1403
+ var CombinatorTranslationEnum;
1404
+ (function (CombinatorTranslationEnum) {
1405
+ CombinatorTranslationEnum["clearDialogTitle"] = "clearDialogTitle";
1406
+ CombinatorTranslationEnum["clearDialogMessage"] = "clearDialogMessage";
1407
+ CombinatorTranslationEnum["clearDialogAccept"] = "clearDialogAccept";
1408
+ CombinatorTranslationEnum["clearDialogDecline"] = "clearDialogDecline";
1409
+ })(CombinatorTranslationEnum || (CombinatorTranslationEnum = {}));
1410
+ const combinatorDefaultTranslations = [
1411
+ {
1412
+ key: CombinatorTranslationEnum.clearDialogTitle,
1413
+ default: () => 'Clear form?',
1414
+ },
1415
+ {
1416
+ key: CombinatorTranslationEnum.clearDialogMessage,
1417
+ default: () => 'Your data will be cleared. Do you want to proceed?',
1418
+ },
1419
+ { key: CombinatorTranslationEnum.clearDialogAccept, default: () => 'Yes' },
1420
+ { key: CombinatorTranslationEnum.clearDialogDecline, default: () => 'No' },
1421
+ ];
1251
1422
 
1252
- const isObjectSchema = (schema) => {
1253
- return schema.properties !== undefined;
1254
- };
1255
- const isArraySchema = (schema) => {
1256
- return schema.type === 'array' && schema.items !== undefined;
1257
- };
1258
- const resolveData = (instance, dataPath) => {
1259
- if (isEmpty(dataPath)) {
1260
- return instance;
1423
+ const getI18nKeyPrefixBySchema = (schema, uischema) => {
1424
+ if (isInternationalized(uischema)) {
1425
+ return uischema.i18n;
1261
1426
  }
1262
- const dataPathSegments = dataPath.split('.');
1263
- return dataPathSegments.reduce((curInstance, decodedSegment) => {
1264
- if (!curInstance ||
1265
- !Object.prototype.hasOwnProperty.call(curInstance, decodedSegment)) {
1266
- return undefined;
1267
- }
1268
- return curInstance[decodedSegment];
1269
- }, instance);
1427
+ return schema?.i18n ?? undefined;
1270
1428
  };
1271
- const findAllRefs = (schema, result = {}, resolveTuples = false) => {
1272
- if (isObjectSchema(schema)) {
1273
- Object.keys(schema.properties).forEach((key) => findAllRefs(schema.properties[key], result));
1274
- }
1275
- if (isArraySchema(schema)) {
1276
- if (Array.isArray(schema.items)) {
1277
- if (resolveTuples) {
1278
- const items = schema.items;
1279
- items.forEach((child) => findAllRefs(child, result));
1280
- }
1281
- }
1282
- else {
1283
- findAllRefs(schema.items, result);
1284
- }
1285
- }
1286
- if (Array.isArray(schema.anyOf)) {
1287
- const anyOf = schema.anyOf;
1288
- anyOf.forEach((child) => findAllRefs(child, result));
1289
- }
1290
- if (schema.$ref !== undefined) {
1291
- result[schema.$ref] = schema;
1292
- }
1293
- return result;
1429
+ const transformPathToI18nPrefix = (path) => {
1430
+ return (path
1431
+ ?.split('.')
1432
+ .filter((segment) => !/^\d+$/.test(segment))
1433
+ .join('.') || 'root');
1294
1434
  };
1295
- const invalidSegment = (pathSegment) => pathSegment === '#' || pathSegment === undefined || pathSegment === '';
1296
- const resolveSchema = (schema, schemaPath, rootSchema) => {
1297
- const segments = schemaPath?.split('/').map(decode);
1298
- return resolveSchemaWithSegments(schema, segments, rootSchema);
1435
+ const getI18nKeyPrefix = (schema, uischema, path) => {
1436
+ return (getI18nKeyPrefixBySchema(schema, uischema) ??
1437
+ transformPathToI18nPrefix(path));
1299
1438
  };
1300
- const resolveSchemaWithSegments = (schema, pathSegments, rootSchema) => {
1301
- if (isEmpty(schema)) {
1302
- return undefined;
1303
- }
1304
- if (schema.$ref) {
1305
- schema = resolveSchema(rootSchema, schema.$ref, rootSchema);
1306
- }
1307
- if (!pathSegments || pathSegments.length === 0) {
1308
- return schema;
1309
- }
1310
- const [segment, ...remainingSegments] = pathSegments;
1311
- if (invalidSegment(segment)) {
1312
- return resolveSchemaWithSegments(schema, remainingSegments, rootSchema);
1313
- }
1314
- const singleSegmentResolveSchema = get(schema, segment);
1315
- const resolvedSchema = resolveSchemaWithSegments(singleSegmentResolveSchema, remainingSegments, rootSchema);
1316
- if (resolvedSchema) {
1317
- return resolvedSchema;
1318
- }
1319
- if (segment === 'properties' || segment === 'items') {
1320
- let alternativeResolveResult = undefined;
1321
- const subSchemas = [].concat(schema.oneOf ?? [], schema.allOf ?? [], schema.anyOf ?? [], schema.then ?? [], schema.else ?? []);
1322
- for (const subSchema of subSchemas) {
1323
- alternativeResolveResult = resolveSchemaWithSegments(subSchema, [segment, ...remainingSegments], rootSchema);
1324
- if (alternativeResolveResult) {
1325
- break;
1326
- }
1327
- }
1328
- return alternativeResolveResult;
1329
- }
1330
- return undefined;
1439
+ const getI18nKey = (schema, uischema, path, key) => {
1440
+ return `${getI18nKeyPrefix(schema, uischema, path)}.${key}`;
1331
1441
  };
1332
-
1333
- const isOrCondition = (condition) => condition.type === 'OR';
1334
- const isAndCondition = (condition) => condition.type === 'AND';
1335
- const isLeafCondition = (condition) => condition.type === 'LEAF';
1336
- const isSchemaCondition = (condition) => has(condition, 'schema');
1337
- const getConditionScope = (condition, path) => {
1338
- return composeWithUi(condition, path);
1442
+ const addI18nKeyToPrefix = (i18nKeyPrefix, key) => {
1443
+ return `${i18nKeyPrefix}.${key}`;
1339
1444
  };
1340
- const evaluateCondition = (data, condition, path, ajv) => {
1341
- if (isAndCondition(condition)) {
1342
- return condition.conditions.reduce((acc, cur) => acc && evaluateCondition(data, cur, path, ajv), true);
1445
+ const defaultTranslator = (_id, defaultMessage) => defaultMessage;
1446
+ const defaultErrorTranslator = (error, t, uischema) => {
1447
+ const i18nKey = getI18nKey(error.parentSchema, uischema, getControlPath(error), `error.${error.keyword}`);
1448
+ const specializedKeywordMessage = t(i18nKey, undefined, { error });
1449
+ if (specializedKeywordMessage !== undefined) {
1450
+ return specializedKeywordMessage;
1343
1451
  }
1344
- else if (isOrCondition(condition)) {
1345
- return condition.conditions.reduce((acc, cur) => acc || evaluateCondition(data, cur, path, ajv), false);
1452
+ const genericKeywordMessage = t(`error.${error.keyword}`, undefined, {
1453
+ error,
1454
+ });
1455
+ if (genericKeywordMessage !== undefined) {
1456
+ return genericKeywordMessage;
1346
1457
  }
1347
- else if (isLeafCondition(condition)) {
1348
- const value = resolveData(data, getConditionScope(condition, path));
1349
- return value === condition.expectedValue;
1458
+ const messageCustomization = t(error.message, undefined, { error });
1459
+ if (messageCustomization !== undefined) {
1460
+ return messageCustomization;
1350
1461
  }
1351
- else if (isSchemaCondition(condition)) {
1352
- const value = resolveData(data, getConditionScope(condition, path));
1353
- if (condition.failWhenUndefined && value === undefined) {
1354
- return false;
1462
+ if (error.keyword === 'required' &&
1463
+ error.message?.startsWith('must have required property')) {
1464
+ return t('is a required property', 'is a required property', { error });
1465
+ }
1466
+ return error.message;
1467
+ };
1468
+ const getCombinedErrorMessage = (errors, et, t, schema, uischema, path) => {
1469
+ if (errors.length > 0 && t) {
1470
+ const customErrorKey = getI18nKey(schema, uischema, path, 'error.custom');
1471
+ const specializedErrorMessage = t(customErrorKey, undefined, {
1472
+ schema,
1473
+ uischema,
1474
+ path,
1475
+ errors,
1476
+ });
1477
+ if (specializedErrorMessage !== undefined) {
1478
+ return specializedErrorMessage;
1355
1479
  }
1356
- return ajv.validate(condition.schema, value);
1357
1480
  }
1358
- else {
1359
- return true;
1481
+ return formatErrorMessage(errors.map((error) => et(error, t, uischema)));
1482
+ };
1483
+ const deriveLabelForUISchemaElement = (uischema, t) => {
1484
+ if (uischema.label === false) {
1485
+ return undefined;
1486
+ }
1487
+ if ((uischema.label === undefined ||
1488
+ uischema.label === null ||
1489
+ uischema.label === true) &&
1490
+ !isInternationalized(uischema)) {
1491
+ return undefined;
1360
1492
  }
1493
+ const stringifiedLabel = typeof uischema.label === 'string'
1494
+ ? uischema.label
1495
+ : JSON.stringify(uischema.label);
1496
+ const i18nKeyPrefix = getI18nKeyPrefixBySchema(undefined, uischema);
1497
+ const i18nKey = typeof i18nKeyPrefix === 'string'
1498
+ ? `${i18nKeyPrefix}.label`
1499
+ : stringifiedLabel;
1500
+ return t(i18nKey, stringifiedLabel, { uischema: uischema });
1361
1501
  };
1362
- const isRuleFulfilled = (uischema, data, path, ajv) => {
1363
- const condition = uischema.rule.condition;
1364
- return evaluateCondition(data, condition, path, ajv);
1502
+ const getArrayTranslations = (t, defaultTranslations, i18nKeyPrefix, label) => {
1503
+ const translations = {};
1504
+ defaultTranslations.forEach((controlElement) => {
1505
+ const key = addI18nKeyToPrefix(i18nKeyPrefix, controlElement.key);
1506
+ translations[controlElement.key] = t(key, controlElement.default(label));
1507
+ });
1508
+ return translations;
1365
1509
  };
1366
- const evalVisibility = (uischema, data, path = undefined, ajv) => {
1367
- const fulfilled = isRuleFulfilled(uischema, data, path, ajv);
1368
- switch (uischema.rule.effect) {
1369
- case RuleEffect.HIDE:
1370
- return !fulfilled;
1371
- case RuleEffect.SHOW:
1372
- return fulfilled;
1373
- default:
1374
- return true;
1375
- }
1510
+ const getCombinatorTranslations = (t, defaultTranslations, i18nKeyPrefix, label) => {
1511
+ const translations = {};
1512
+ defaultTranslations.forEach((controlElement) => {
1513
+ const key = addI18nKeyToPrefix(i18nKeyPrefix, controlElement.key);
1514
+ translations[controlElement.key] = t(key, controlElement.default(label));
1515
+ });
1516
+ return translations;
1376
1517
  };
1377
- const evalEnablement = (uischema, data, path = undefined, ajv) => {
1378
- const fulfilled = isRuleFulfilled(uischema, data, path, ajv);
1379
- switch (uischema.rule.effect) {
1380
- case RuleEffect.DISABLE:
1381
- return !fulfilled;
1382
- case RuleEffect.ENABLE:
1383
- return fulfilled;
1384
- default:
1385
- return true;
1518
+
1519
+ const fetchLocale = (state) => {
1520
+ if (state === undefined) {
1521
+ return undefined;
1386
1522
  }
1523
+ return state.locale;
1387
1524
  };
1388
- const hasShowRule = (uischema) => {
1389
- if (uischema.rule &&
1390
- (uischema.rule.effect === RuleEffect.SHOW ||
1391
- uischema.rule.effect === RuleEffect.HIDE)) {
1392
- return true;
1525
+ const fetchTranslator = (state) => {
1526
+ if (state === undefined) {
1527
+ return defaultTranslator;
1393
1528
  }
1394
- return false;
1529
+ return state.translate;
1395
1530
  };
1396
- const hasEnableRule = (uischema) => {
1397
- if (uischema.rule &&
1398
- (uischema.rule.effect === RuleEffect.ENABLE ||
1399
- uischema.rule.effect === RuleEffect.DISABLE)) {
1400
- return true;
1531
+ const fetchErrorTranslator = (state) => {
1532
+ if (state === undefined) {
1533
+ return defaultErrorTranslator;
1401
1534
  }
1402
- return false;
1535
+ return state.translateError;
1403
1536
  };
1404
- const isVisible = (uischema, data, path = undefined, ajv) => {
1405
- if (uischema.rule) {
1406
- return evalVisibility(uischema, data, path, ajv);
1537
+ const getLocale = (state) => fetchLocale(get(state, 'jsonforms.i18n'));
1538
+ const getTranslator = () => (state) => fetchTranslator(get(state, 'jsonforms.i18n'));
1539
+ const getErrorTranslator = () => (state) => fetchErrorTranslator(get(state, 'jsonforms.i18n'));
1540
+
1541
+ const defaultJsonFormsI18nState = {
1542
+ locale: 'en',
1543
+ translate: defaultTranslator,
1544
+ translateError: defaultErrorTranslator,
1545
+ };
1546
+ const i18nReducer = (state = defaultJsonFormsI18nState, action) => {
1547
+ switch (action.type) {
1548
+ case UPDATE_I18N: {
1549
+ const locale = action.locale ?? defaultJsonFormsI18nState.locale;
1550
+ const translate = action.translator ?? defaultJsonFormsI18nState.translate;
1551
+ const translateError = action.errorTranslator ?? defaultJsonFormsI18nState.translateError;
1552
+ if (locale !== state.locale ||
1553
+ translate !== state.translate ||
1554
+ translateError !== state.translateError) {
1555
+ return {
1556
+ ...state,
1557
+ locale,
1558
+ translate,
1559
+ translateError,
1560
+ };
1561
+ }
1562
+ return state;
1563
+ }
1564
+ case SET_TRANSLATOR:
1565
+ return {
1566
+ ...state,
1567
+ translate: action.translator ?? defaultTranslator,
1568
+ translateError: action.errorTranslator ?? defaultErrorTranslator,
1569
+ };
1570
+ case SET_LOCALE:
1571
+ return {
1572
+ ...state,
1573
+ locale: action.locale ?? navigator.languages[0],
1574
+ };
1575
+ default:
1576
+ return state;
1407
1577
  }
1408
- return true;
1409
1578
  };
1410
- const isEnabled = (uischema, data, path = undefined, ajv) => {
1411
- if (uischema.rule) {
1412
- return evalEnablement(uischema, data, path, ajv);
1579
+
1580
+ const rendererReducer = (state = [], action) => {
1581
+ switch (action.type) {
1582
+ case ADD_RENDERER:
1583
+ return state.concat([
1584
+ { tester: action.tester, renderer: action.renderer },
1585
+ ]);
1586
+ case REMOVE_RENDERER:
1587
+ return state.filter((t) => t.tester !== action.tester);
1588
+ default:
1589
+ return state;
1413
1590
  }
1414
- return true;
1415
1591
  };
1416
- const isInherentlyEnabled = (state, ownProps, uischema, schema, rootData, config) => {
1417
- if (state?.jsonforms?.readonly) {
1592
+
1593
+ const NOT_APPLICABLE = -1;
1594
+ const isControl = (uischema) => !isEmpty(uischema) && uischema.scope !== undefined;
1595
+ const schemaMatches = (predicate) => (uischema, schema, context) => {
1596
+ if (isEmpty(uischema) || !isControl(uischema)) {
1418
1597
  return false;
1419
1598
  }
1420
- if (uischema && hasEnableRule(uischema)) {
1421
- return isEnabled(uischema, rootData, ownProps?.path, getAjv(state));
1599
+ if (isEmpty(schema)) {
1600
+ return false;
1422
1601
  }
1423
- if (typeof uischema?.options?.readonly === 'boolean') {
1424
- return !uischema.options.readonly;
1602
+ const schemaPath = uischema.scope;
1603
+ if (isEmpty(schemaPath)) {
1604
+ return false;
1425
1605
  }
1426
- if (typeof uischema?.options?.readOnly === 'boolean') {
1427
- return !uischema.options.readOnly;
1606
+ let currentDataSchema = schema;
1607
+ if (hasType(schema, 'object')) {
1608
+ currentDataSchema = resolveSchema(schema, schemaPath, context?.rootSchema);
1428
1609
  }
1429
- if (typeof config?.readonly === 'boolean') {
1430
- return !config.readonly;
1610
+ if (currentDataSchema === undefined) {
1611
+ return false;
1431
1612
  }
1432
- if (typeof config?.readOnly === 'boolean') {
1433
- return !config.readOnly;
1613
+ return predicate(currentDataSchema, context?.rootSchema);
1614
+ };
1615
+ const schemaSubPathMatches = (subPath, predicate) => (uischema, schema, context) => {
1616
+ if (isEmpty(uischema) || !isControl(uischema)) {
1617
+ return false;
1434
1618
  }
1435
- if (schema?.readOnly === true) {
1619
+ const schemaPath = uischema.scope;
1620
+ let currentDataSchema = schema;
1621
+ if (hasType(schema, 'object')) {
1622
+ currentDataSchema = resolveSchema(schema, schemaPath, context?.rootSchema);
1623
+ }
1624
+ currentDataSchema = get(currentDataSchema, subPath);
1625
+ if (currentDataSchema === undefined) {
1436
1626
  return false;
1437
1627
  }
1438
- if (typeof ownProps?.enabled === 'boolean') {
1439
- return ownProps.enabled;
1628
+ return predicate(currentDataSchema, context?.rootSchema);
1629
+ };
1630
+ const schemaTypeIs = (expectedType) => schemaMatches((schema) => !isEmpty(schema) && hasType(schema, expectedType));
1631
+ const formatIs = (expectedFormat) => schemaMatches((schema) => !isEmpty(schema) &&
1632
+ schema.format === expectedFormat &&
1633
+ hasType(schema, 'string'));
1634
+ const uiTypeIs = (expected) => (uischema) => !isEmpty(uischema) && uischema.type === expected;
1635
+ const optionIs = (optionName, optionValue) => (uischema) => {
1636
+ if (isEmpty(uischema)) {
1637
+ return false;
1440
1638
  }
1441
- return true;
1639
+ const options = uischema.options;
1640
+ return !isEmpty(options) && options[optionName] === optionValue;
1442
1641
  };
1443
-
1444
- const convertDateToString = (date, format) => {
1445
- const dateString = date.toISOString();
1446
- if (format === 'date-time') {
1447
- return dateString;
1642
+ const hasOption = (optionName) => (uischema) => {
1643
+ if (isEmpty(uischema)) {
1644
+ return false;
1448
1645
  }
1449
- else if (format === 'date') {
1450
- return dateString.split('T')[0];
1646
+ const options = uischema.options;
1647
+ return !isEmpty(options) && !isUndefined(options[optionName]);
1648
+ };
1649
+ const scopeEndsWith = (expected) => (uischema) => {
1650
+ if (isEmpty(expected) || !isControl(uischema)) {
1651
+ return false;
1451
1652
  }
1452
- else if (format === 'time') {
1453
- return dateString.split('T')[1].split('.')[0];
1653
+ return endsWith(uischema.scope, expected);
1654
+ };
1655
+ const scopeEndIs = (expected) => (uischema) => {
1656
+ if (isEmpty(expected) || !isControl(uischema)) {
1657
+ return false;
1454
1658
  }
1455
- return dateString;
1659
+ const schemaPath = uischema.scope;
1660
+ return !isEmpty(schemaPath) && last(schemaPath.split('/')) === expected;
1456
1661
  };
1457
- const convertToValidClassName = (s) => s.replace('#', 'root').replace(new RegExp('/', 'g'), '_');
1458
- const formatErrorMessage = (errors) => {
1459
- if (errors === undefined || errors === null) {
1460
- return '';
1662
+ const and = (...testers) => (uischema, schema, context) => testers.reduce((acc, tester) => acc && tester(uischema, schema, context), true);
1663
+ const or = (...testers) => (uischema, schema, context) => testers.reduce((acc, tester) => acc || tester(uischema, schema, context), false);
1664
+ const rankWith = (rank, tester) => (uischema, schema, context) => {
1665
+ if (tester(uischema, schema, context)) {
1666
+ return rank;
1461
1667
  }
1462
- return errors.join('\n');
1668
+ return NOT_APPLICABLE;
1463
1669
  };
1464
- const hasType = (jsonSchema, expected) => {
1465
- return includes(deriveTypes(jsonSchema), expected);
1670
+ const withIncreasedRank = (by, rankedTester) => (uischema, schema, context) => {
1671
+ const rank = rankedTester(uischema, schema, context);
1672
+ if (rank === NOT_APPLICABLE) {
1673
+ return NOT_APPLICABLE;
1674
+ }
1675
+ return rank + by;
1466
1676
  };
1467
- const deriveTypes = (jsonSchema) => {
1468
- if (isEmpty(jsonSchema)) {
1469
- return [];
1677
+ const isBooleanControl = and(uiTypeIs('Control'), schemaTypeIs('boolean'));
1678
+ const isObjectControl = and(uiTypeIs('Control'), schemaTypeIs('object'));
1679
+ const isAllOfControl = and(uiTypeIs('Control'), schemaMatches((schema) => Object.prototype.hasOwnProperty.call(schema, 'allOf')));
1680
+ const isAnyOfControl = and(uiTypeIs('Control'), schemaMatches((schema) => Object.prototype.hasOwnProperty.call(schema, 'anyOf')));
1681
+ const isOneOfControl = and(uiTypeIs('Control'), schemaMatches((schema) => Object.prototype.hasOwnProperty.call(schema, 'oneOf')));
1682
+ const isEnumControl = and(uiTypeIs('Control'), schemaMatches((schema) => isEnumSchema(schema)));
1683
+ const isOneOfEnumControl = and(uiTypeIs('Control'), schemaMatches((schema) => isOneOfEnumSchema(schema)));
1684
+ const isIntegerControl = and(uiTypeIs('Control'), schemaTypeIs('integer'));
1685
+ const isNumberControl = and(uiTypeIs('Control'), schemaTypeIs('number'));
1686
+ const isStringControl = and(uiTypeIs('Control'), schemaTypeIs('string'));
1687
+ const isMultiLineControl = and(uiTypeIs('Control'), optionIs('multi', true));
1688
+ const isDateControl = and(uiTypeIs('Control'), or(formatIs('date'), optionIs('format', 'date')));
1689
+ const isTimeControl = and(uiTypeIs('Control'), or(formatIs('time'), optionIs('format', 'time')));
1690
+ const isDateTimeControl = and(uiTypeIs('Control'), or(formatIs('date-time'), optionIs('format', 'date-time')));
1691
+ const isObjectArray = and(schemaMatches((schema, rootSchema) => hasType(schema, 'array') &&
1692
+ !Array.isArray(resolveSchema(schema, 'items', rootSchema))
1693
+ ), schemaSubPathMatches('items', (schema, rootSchema) => {
1694
+ const resolvedSchema = schema.$ref
1695
+ ? resolveSchema(rootSchema, schema.$ref, rootSchema)
1696
+ : schema;
1697
+ return hasType(resolvedSchema, 'object');
1698
+ }));
1699
+ const isObjectArrayControl = and(uiTypeIs('Control'), isObjectArray);
1700
+ const traverse = (any, pred, rootSchema) => {
1701
+ if (isArray(any)) {
1702
+ return reduce(any, (acc, el) => acc || traverse(el, pred, rootSchema), false);
1470
1703
  }
1471
- if (!isEmpty(jsonSchema.type) && typeof jsonSchema.type === 'string') {
1472
- return [jsonSchema.type];
1704
+ if (pred(any)) {
1705
+ return true;
1473
1706
  }
1474
- if (isArray(jsonSchema.type)) {
1475
- return jsonSchema.type;
1707
+ if (any.$ref) {
1708
+ const toTraverse = resolveSchema(rootSchema, any.$ref, rootSchema);
1709
+ if (toTraverse && !toTraverse.$ref) {
1710
+ return traverse(toTraverse, pred, rootSchema);
1711
+ }
1476
1712
  }
1477
- if (!isEmpty(jsonSchema.properties) ||
1478
- !isEmpty(jsonSchema.additionalProperties)) {
1479
- return ['object'];
1713
+ if (any.items) {
1714
+ return traverse(any.items, pred, rootSchema);
1480
1715
  }
1481
- if (!isEmpty(jsonSchema.items)) {
1482
- return ['array'];
1716
+ if (any.properties) {
1717
+ return reduce(toPairs(any.properties), (acc, [_key, val]) => acc || traverse(val, pred, rootSchema), false);
1483
1718
  }
1484
- if (!isEmpty(jsonSchema.enum)) {
1485
- const types = new Set();
1486
- jsonSchema.enum.forEach((enumElement) => {
1487
- if (typeof enumElement === 'string') {
1488
- types.add('string');
1719
+ return false;
1720
+ };
1721
+ const isObjectArrayWithNesting = (uischema, schema, context) => {
1722
+ if (!uiTypeIs('Control')(uischema, schema, context)) {
1723
+ return false;
1724
+ }
1725
+ const schemaPath = uischema.scope;
1726
+ const resolvedSchema = resolveSchema(schema, schemaPath, context?.rootSchema ?? schema);
1727
+ let objectDepth = 0;
1728
+ if (resolvedSchema !== undefined && resolvedSchema.items !== undefined) {
1729
+ if (traverse(resolvedSchema.items, (val) => {
1730
+ if (val === schema) {
1731
+ return false;
1489
1732
  }
1490
- else {
1491
- deriveTypes(enumElement).forEach((type) => types.add(type));
1733
+ if (val.$ref !== undefined) {
1734
+ return false;
1735
+ }
1736
+ if (val.anyOf || val.allOf) {
1737
+ return true;
1738
+ }
1739
+ if (val.oneOf && !isOneOfEnumSchema(val)) {
1740
+ return true;
1741
+ }
1742
+ if (hasType(val, 'object')) {
1743
+ objectDepth++;
1744
+ if (objectDepth === 2) {
1745
+ return true;
1746
+ }
1747
+ }
1748
+ if (hasType(val, 'array')) {
1749
+ return true;
1750
+ }
1751
+ return false;
1752
+ }, context?.rootSchema)) {
1753
+ return true;
1754
+ }
1755
+ if (uischema.options && uischema.options.detail) {
1756
+ if (typeof uischema.options.detail === 'string') {
1757
+ return uischema.options.detail.toUpperCase() !== 'DEFAULT';
1758
+ }
1759
+ else if (typeof uischema.options.detail === 'object' &&
1760
+ uischema.options.detail.type) {
1761
+ return true;
1492
1762
  }
1493
- });
1494
- return Array.from(types);
1495
- }
1496
- if (!isEmpty(jsonSchema.allOf)) {
1497
- const allOfType = find(jsonSchema.allOf, (schema) => deriveTypes(schema).length !== 0);
1498
- if (allOfType) {
1499
- return deriveTypes(allOfType);
1500
1763
  }
1501
1764
  }
1502
- return [];
1503
- };
1504
- const Resolve = {
1505
- schema: resolveSchema,
1506
- data: resolveData,
1507
- };
1508
- const fromScoped = (scopable) => toDataPathSegments(scopable.scope).join('.');
1509
- const Paths = {
1510
- compose: compose,
1511
- fromScoped,
1512
- };
1513
- const Runtime = {
1514
- isEnabled(uischema, data, ajv) {
1515
- return isEnabled(uischema, data, undefined, ajv);
1516
- },
1517
- isVisible(uischema, data, ajv) {
1518
- return isVisible(uischema, data, undefined, ajv);
1519
- },
1765
+ return false;
1520
1766
  };
1521
-
1522
- const getFirstPrimitiveProp = (schema) => {
1523
- if (schema.properties) {
1524
- return find(Object.keys(schema.properties), (propName) => {
1525
- const prop = schema.properties[propName];
1526
- return (prop.type === 'string' ||
1527
- prop.type === 'number' ||
1528
- prop.type === 'integer');
1529
- });
1767
+ const isArrayObjectControl = isObjectArrayControl;
1768
+ const isPrimitiveArrayControl = and(uiTypeIs('Control'), schemaMatches((schema, rootSchema) => deriveTypes(schema).length !== 0 &&
1769
+ !Array.isArray(resolveSchema(schema, 'items', rootSchema))
1770
+ ), schemaSubPathMatches('items', (schema, rootSchema) => {
1771
+ const resolvedSchema = schema.$ref
1772
+ ? resolveSchema(rootSchema, schema.$ref, rootSchema)
1773
+ : schema;
1774
+ const types = deriveTypes(resolvedSchema);
1775
+ return (types.length === 1 &&
1776
+ includes(['integer', 'number', 'boolean', 'string'], types[0]));
1777
+ }));
1778
+ const isRangeControl = and(uiTypeIs('Control'), or(schemaTypeIs('number'), schemaTypeIs('integer')), schemaMatches((schema) => Object.prototype.hasOwnProperty.call(schema, 'maximum') &&
1779
+ Object.prototype.hasOwnProperty.call(schema, 'minimum') &&
1780
+ Object.prototype.hasOwnProperty.call(schema, 'default')), optionIs('slider', true));
1781
+ const isNumberFormatControl = and(uiTypeIs('Control'), schemaTypeIs('integer'), optionIs('format', true));
1782
+ const isCategorization = (category) => category.type === 'Categorization';
1783
+ const isCategory = (uischema) => uischema.type === 'Category';
1784
+ const hasCategory = (categorization) => {
1785
+ if (isEmpty(categorization.elements)) {
1786
+ return false;
1530
1787
  }
1531
- return undefined;
1788
+ return categorization.elements
1789
+ .map((elem) => isCategorization(elem) ? hasCategory(elem) : isCategory(elem))
1790
+ .reduce((prev, curr) => prev && curr, true);
1532
1791
  };
1533
- const isOneOfEnumSchema = (schema) => !!schema &&
1534
- Object.prototype.hasOwnProperty.call(schema, 'oneOf') &&
1535
- schema.oneOf &&
1536
- schema.oneOf.every((s) => s.const !== undefined);
1537
- const isEnumSchema = (schema) => !!schema &&
1538
- typeof schema === 'object' &&
1539
- (Object.prototype.hasOwnProperty.call(schema, 'enum') ||
1540
- Object.prototype.hasOwnProperty.call(schema, 'const'));
1792
+ const categorizationHasCategory = (uischema) => hasCategory(uischema);
1793
+ const not = (tester) => (uischema, schema, context) => !tester(uischema, schema, context);
1541
1794
 
1542
- const setReadonlyPropertyValue = (value) => (child) => {
1543
- if (!child.options) {
1544
- child.options = {};
1545
- }
1546
- child.options.readonly = value;
1547
- };
1548
- const setReadonly = (uischema) => {
1549
- iterateSchema(uischema, setReadonlyPropertyValue(true));
1550
- };
1551
- const unsetReadonly = (uischema) => {
1552
- iterateSchema(uischema, setReadonlyPropertyValue(false));
1553
- };
1554
- const iterateSchema = (uischema, toApply) => {
1555
- if (isEmpty(uischema)) {
1556
- return;
1795
+ var index = /*#__PURE__*/Object.freeze({
1796
+ __proto__: null,
1797
+ NOT_APPLICABLE: NOT_APPLICABLE,
1798
+ isControl: isControl,
1799
+ schemaMatches: schemaMatches,
1800
+ schemaSubPathMatches: schemaSubPathMatches,
1801
+ schemaTypeIs: schemaTypeIs,
1802
+ formatIs: formatIs,
1803
+ uiTypeIs: uiTypeIs,
1804
+ optionIs: optionIs,
1805
+ hasOption: hasOption,
1806
+ scopeEndsWith: scopeEndsWith,
1807
+ scopeEndIs: scopeEndIs,
1808
+ and: and,
1809
+ or: or,
1810
+ rankWith: rankWith,
1811
+ withIncreasedRank: withIncreasedRank,
1812
+ isBooleanControl: isBooleanControl,
1813
+ isObjectControl: isObjectControl,
1814
+ isAllOfControl: isAllOfControl,
1815
+ isAnyOfControl: isAnyOfControl,
1816
+ isOneOfControl: isOneOfControl,
1817
+ isEnumControl: isEnumControl,
1818
+ isOneOfEnumControl: isOneOfEnumControl,
1819
+ isIntegerControl: isIntegerControl,
1820
+ isNumberControl: isNumberControl,
1821
+ isStringControl: isStringControl,
1822
+ isMultiLineControl: isMultiLineControl,
1823
+ isDateControl: isDateControl,
1824
+ isTimeControl: isTimeControl,
1825
+ isDateTimeControl: isDateTimeControl,
1826
+ isObjectArray: isObjectArray,
1827
+ isObjectArrayControl: isObjectArrayControl,
1828
+ isObjectArrayWithNesting: isObjectArrayWithNesting,
1829
+ isArrayObjectControl: isArrayObjectControl,
1830
+ isPrimitiveArrayControl: isPrimitiveArrayControl,
1831
+ isRangeControl: isRangeControl,
1832
+ isNumberFormatControl: isNumberFormatControl,
1833
+ isCategorization: isCategorization,
1834
+ isCategory: isCategory,
1835
+ hasCategory: hasCategory,
1836
+ categorizationHasCategory: categorizationHasCategory,
1837
+ not: not
1838
+ });
1839
+
1840
+ const uischemaRegistryReducer = (state = [], action) => {
1841
+ switch (action.type) {
1842
+ case ADD_UI_SCHEMA:
1843
+ return state
1844
+ .slice()
1845
+ .concat({ tester: action.tester, uischema: action.uischema });
1846
+ case REMOVE_UI_SCHEMA: {
1847
+ const copy = state.slice();
1848
+ remove(copy, (entry) => entry.tester === action.tester);
1849
+ return copy;
1850
+ }
1851
+ default:
1852
+ return state;
1557
1853
  }
1558
- if (isLayout(uischema)) {
1559
- uischema.elements.forEach((child) => iterateSchema(child, toApply));
1560
- return;
1854
+ };
1855
+ const findMatchingUISchema = (state) => (jsonSchema, schemaPath, path) => {
1856
+ const match = maxBy(state, (entry) => entry.tester(jsonSchema, schemaPath, path));
1857
+ if (match !== undefined &&
1858
+ match.tester(jsonSchema, schemaPath, path) !== NOT_APPLICABLE) {
1859
+ return match.uischema;
1561
1860
  }
1562
- toApply(uischema);
1861
+ return undefined;
1563
1862
  };
1564
- const getPropPath = (path) => {
1565
- return `/properties/${path
1566
- .split('.')
1567
- .map((p) => encode(p))
1568
- .join('/properties/')}`;
1863
+
1864
+ const jsonFormsReducerConfig = {
1865
+ core: coreReducer,
1866
+ renderers: rendererReducer,
1867
+ cells: cellReducer,
1868
+ config: configReducer,
1869
+ uischemas: uischemaRegistryReducer,
1870
+ defaultData: defaultDataReducer,
1871
+ i18n: i18nReducer,
1569
1872
  };
1570
- const findUiControl = (uiSchema, path) => {
1571
- if (isControlElement(uiSchema)) {
1572
- if (isScoped(uiSchema) && uiSchema.scope.endsWith(getPropPath(path))) {
1573
- return uiSchema;
1873
+ const findUISchema = (uischemas, schema, schemaPath, path, fallback = 'VerticalLayout', control, rootSchema) => {
1874
+ if (control && control.options && control.options.detail) {
1875
+ if (typeof control.options.detail === 'string') {
1876
+ if (control.options.detail.toUpperCase() === 'GENERATE') {
1877
+ if (typeof fallback === 'function') {
1878
+ return fallback();
1879
+ }
1880
+ return Generate.uiSchema(schema, fallback, undefined, rootSchema);
1881
+ }
1574
1882
  }
1575
- else if (uiSchema.options?.detail) {
1576
- return findUiControl(uiSchema.options.detail, path);
1883
+ else if (typeof control.options.detail === 'object') {
1884
+ if (control.options.detail.type &&
1885
+ typeof control.options.detail.type === 'string') {
1886
+ return control.options.detail;
1887
+ }
1577
1888
  }
1578
1889
  }
1579
- if (isLayout(uiSchema)) {
1580
- for (const elem of uiSchema.elements) {
1581
- const result = findUiControl(elem, path);
1582
- if (result !== undefined)
1583
- return result;
1890
+ const uiSchema = findMatchingUISchema(uischemas)(schema, schemaPath, path);
1891
+ if (uiSchema === undefined) {
1892
+ if (typeof fallback === 'function') {
1893
+ return fallback();
1584
1894
  }
1895
+ return Generate.uiSchema(schema, fallback, '#', rootSchema);
1585
1896
  }
1586
- return undefined;
1897
+ return uiSchema;
1587
1898
  };
1588
1899
 
1589
- const deriveLabel = (controlElement, schemaElement) => {
1590
- if (schemaElement && typeof schemaElement.title === 'string') {
1591
- return schemaElement.title;
1592
- }
1593
- if (typeof controlElement.scope === 'string') {
1594
- const ref = controlElement.scope;
1595
- const label = decode(ref.substr(ref.lastIndexOf('/') + 1));
1596
- return startCase(label);
1597
- }
1598
- return '';
1900
+ const defaultMiddleware = (state, action, defaultReducer) => defaultReducer(state, action);
1901
+
1902
+ const getErrorsAt = (instancePath, schema, matchPath) => (state) => {
1903
+ const errors = state.errors ?? [];
1904
+ const additionalErrors = state.additionalErrors ?? [];
1905
+ return errorsAt(instancePath, schema, matchPath)(state.validationMode === 'ValidateAndHide'
1906
+ ? additionalErrors
1907
+ : [...errors, ...additionalErrors]);
1599
1908
  };
1600
- const createCleanLabel = (label) => {
1601
- return startCase(label.replace('_', ' '));
1909
+ const errorAt = (instancePath, schema) => getErrorsAt(instancePath, schema, (path) => path === instancePath);
1910
+ const subErrorsAt = (instancePath, schema) => getErrorsAt(instancePath, schema, (path) => path.startsWith(instancePath + '.'));
1911
+ const getErrorAt = (instancePath, schema) => (state) => {
1912
+ return errorAt(instancePath, schema)(state.jsonforms.core);
1602
1913
  };
1603
- const createLabelDescriptionFrom = (withLabel, schema) => {
1604
- const labelProperty = withLabel.label;
1605
- if (typeof labelProperty === 'boolean') {
1606
- return labelDescription(deriveLabel(withLabel, schema), labelProperty);
1914
+ const getSubErrorsAt = (instancePath, schema) => (state) => subErrorsAt(instancePath, schema)(state.jsonforms.core);
1915
+ const getData = (state) => extractData(get(state, 'jsonforms.core'));
1916
+ const getSchema = (state) => extractSchema(get(state, 'jsonforms.core'));
1917
+ const getUiSchema = (state) => extractUiSchema(get(state, 'jsonforms.core'));
1918
+ const getAjv = (state) => extractAjv(get(state, 'jsonforms.core'));
1919
+ const getRenderers = (state) => get(state, 'jsonforms.renderers');
1920
+ const getCells = (state) => get(state, 'jsonforms.cells');
1921
+ const getUISchemas = (state) => get(state, 'jsonforms.uischemas');
1922
+ const extractData = (state) => get(state, 'data');
1923
+ const extractSchema = (state) => get(state, 'schema');
1924
+ const extractUiSchema = (state) => get(state, 'uischema');
1925
+ const extractAjv = (state) => get(state, 'ajv');
1926
+ const getConfig = (state) => state.jsonforms.config;
1927
+
1928
+ const isInherentlyEnabled = (state, ownProps, uischema, schema, rootData, config) => {
1929
+ if (state?.jsonforms?.readonly) {
1930
+ return false;
1607
1931
  }
1608
- if (typeof labelProperty === 'string') {
1609
- return labelDescription(labelProperty, true);
1932
+ if (uischema && hasEnableRule(uischema)) {
1933
+ return isEnabled(uischema, rootData, ownProps?.path, getAjv(state));
1610
1934
  }
1611
- if (typeof labelProperty === 'object') {
1612
- const label = typeof labelProperty.text === 'string'
1613
- ? labelProperty.text
1614
- : deriveLabel(withLabel, schema);
1615
- const show = typeof labelProperty.show === 'boolean' ? labelProperty.show : true;
1616
- return labelDescription(label, show);
1935
+ if (typeof uischema?.options?.readonly === 'boolean') {
1936
+ return !uischema.options.readonly;
1617
1937
  }
1618
- return labelDescription(deriveLabel(withLabel, schema), true);
1619
- };
1620
- const labelDescription = (text, show) => ({
1621
- text: text,
1622
- show: show,
1623
- });
1624
- const computeChildLabel = (data, childPath, childLabelProp, schema, rootSchema, translateFct, uiSchema) => {
1625
- const childData = Resolve.data(data, childPath);
1626
- if (!childLabelProp) {
1627
- childLabelProp = getFirstPrimitiveProp(schema);
1938
+ if (typeof uischema?.options?.readOnly === 'boolean') {
1939
+ return !uischema.options.readOnly;
1628
1940
  }
1629
- if (!childLabelProp) {
1630
- return '';
1941
+ if (typeof config?.readonly === 'boolean') {
1942
+ return !config.readonly;
1631
1943
  }
1632
- const currentValue = get(childData, childLabelProp);
1633
- if (currentValue === undefined) {
1634
- return '';
1944
+ if (typeof config?.readOnly === 'boolean') {
1945
+ return !config.readOnly;
1635
1946
  }
1636
- const childSchema = Resolve.schema(schema, '#' + getPropPath(childLabelProp), rootSchema);
1637
- let enumOption = undefined;
1638
- if (isEnumSchema(childSchema)) {
1639
- enumOption = enumToEnumOptionMapper(currentValue, translateFct, getI18nKeyPrefix(childSchema, findUiControl(uiSchema, childLabelProp), childPath + '.' + childLabelProp));
1947
+ if (schema?.readOnly === true) {
1948
+ return false;
1640
1949
  }
1641
- else if (isOneOfEnumSchema(childSchema)) {
1642
- const oneOfArray = childSchema.oneOf;
1643
- const oneOfSchema = oneOfArray.find((e) => isEqual(e.const, currentValue));
1644
- if (oneOfSchema) {
1645
- enumOption = oneOfToEnumOptionMapper(oneOfSchema, translateFct, getI18nKeyPrefix(oneOfSchema, undefined, childPath + '.' + childLabelProp));
1646
- }
1950
+ if (typeof ownProps?.enabled === 'boolean') {
1951
+ return ownProps.enabled;
1647
1952
  }
1648
- return enumOption ? enumOption.label : currentValue;
1953
+ return true;
1649
1954
  };
1650
1955
 
1956
+ const move = (array, index, delta) => {
1957
+ const newIndex = index + delta;
1958
+ if (newIndex < 0 || newIndex >= array.length) {
1959
+ return;
1960
+ }
1961
+ const indexes = [index, newIndex].sort((a, b) => a - b);
1962
+ array.splice(indexes[0], 2, array[indexes[1]], array[indexes[0]]);
1963
+ };
1964
+ const moveUp = (array, toMove) => {
1965
+ move(array, toMove, -1);
1966
+ };
1967
+ const moveDown = (array, toMove) => {
1968
+ move(array, toMove, 1);
1969
+ };
1651
1970
  const isRequired = (schema, schemaPath, rootSchema) => {
1652
1971
  const pathSegments = schemaPath.split('/');
1653
- const lastSegment = pathSegments[pathSegments.length - 1];
1972
+ const lastSegment = decode(pathSegments[pathSegments.length - 1]);
1654
1973
  const nextHigherSchemaSegments = pathSegments.slice(0, pathSegments.length - 2);
1655
1974
  const nextHigherSchemaPath = nextHigherSchemaSegments.join('/');
1656
1975
  const nextHigherSchema = Resolve.schema(schema, nextHigherSchemaPath, rootSchema);
@@ -2030,490 +2349,173 @@ const mapStateToCombinatorRendererProps = (state, ownProps, keyword) => {
2030
2349
  schema,
2031
2350
  rootSchema,
2032
2351
  ...props,
2033
- i18nKeyPrefix,
2034
- label,
2035
- indexOfFittingSchema,
2036
- uischemas: getUISchemas(state),
2037
- translations,
2038
- };
2039
- };
2040
- const mapStateToAllOfProps = (state, ownProps) => mapStateToCombinatorRendererProps(state, ownProps, 'allOf');
2041
- const mapStateToAnyOfProps = (state, ownProps) => {
2042
- return mapStateToCombinatorRendererProps(state, ownProps, 'anyOf');
2043
- };
2044
- const mapStateToOneOfProps = (state, ownProps) => {
2045
- return mapStateToCombinatorRendererProps(state, ownProps, 'oneOf');
2046
- };
2047
- const mapStateToArrayLayoutProps = (state, ownProps) => {
2048
- const { path, schema, uischema, errors, i18nKeyPrefix, label, ...props } = mapStateToControlWithDetailProps(state, ownProps);
2049
- const resolvedSchema = Resolve.schema(schema, 'items', props.rootSchema);
2050
- const t = getTranslator()(state);
2051
- const childErrors = getCombinedErrorMessage(getSubErrorsAt(path, resolvedSchema)(state), getErrorTranslator()(state), t, undefined, undefined, undefined);
2052
- const allErrors = errors +
2053
- (errors.length > 0 && childErrors.length > 0 ? '\n' : '') +
2054
- childErrors;
2055
- return {
2056
- ...props,
2057
- label,
2058
- path,
2059
- uischema,
2060
- schema: resolvedSchema,
2061
- data: props.data ? props.data.length : 0,
2062
- errors: allErrors,
2063
- minItems: schema.minItems,
2064
- translations: getArrayTranslations(t, arrayDefaultTranslations, i18nKeyPrefix, label),
2065
- };
2066
- };
2067
- const mapStateToLabelProps = (state, props) => {
2068
- const { uischema } = props;
2069
- const visible = props.visible === undefined || hasShowRule(uischema)
2070
- ? isVisible(props.uischema, getData(state), props.path, getAjv(state))
2071
- : props.visible;
2072
- const text = uischema.text;
2073
- const t = getTranslator()(state);
2074
- const i18nKeyPrefix = getI18nKeyPrefixBySchema(undefined, uischema);
2075
- const i18nKey = i18nKeyPrefix ? `${i18nKeyPrefix}.text` : text ?? '';
2076
- const i18nText = t(i18nKey, text, { uischema });
2077
- return {
2078
- text: i18nText,
2079
- visible,
2080
- config: getConfig(state),
2081
- renderers: props.renderers || getRenderers(state),
2082
- cells: props.cells || getCells(state),
2083
- };
2084
- };
2085
-
2086
- const mapStateToCellProps = (state, ownProps) => {
2087
- const { id, schema, path, uischema, renderers, cells } = ownProps;
2088
- const rootData = getData(state);
2089
- const visible = ownProps.visible !== undefined
2090
- ? ownProps.visible
2091
- : isVisible(uischema, rootData, undefined, getAjv(state));
2092
- const rootSchema = getSchema(state);
2093
- const config = getConfig(state);
2094
- let enabled;
2095
- if (state.jsonforms.readonly === true) {
2096
- enabled = false;
2097
- }
2098
- else if (typeof ownProps.enabled === 'boolean') {
2099
- enabled = ownProps.enabled;
2100
- }
2101
- else {
2102
- enabled = isInherentlyEnabled(state, ownProps, uischema, schema || rootSchema, rootData, config);
2103
- }
2104
- const t = getTranslator()(state);
2105
- const te = getErrorTranslator()(state);
2106
- const errors = getCombinedErrorMessage(getErrorAt(path, schema)(state), te, t, schema, uischema, path);
2107
- const isValid = isEmpty(errors);
2108
- return {
2109
- data: Resolve.data(rootData, path),
2110
- visible,
2111
- enabled,
2112
- id,
2113
- path,
2114
- errors,
2115
- isValid,
2116
- schema,
2117
- uischema,
2118
- config: getConfig(state),
2119
- rootSchema,
2120
- renderers,
2121
- cells,
2122
- };
2123
- };
2124
- const mapStateToDispatchCellProps = (state, ownProps) => {
2125
- const props = mapStateToCellProps(state, ownProps);
2126
- const { renderers: _renderers, cells, ...otherOwnProps } = ownProps;
2127
- return {
2128
- ...props,
2129
- ...otherOwnProps,
2130
- cells: cells || state.jsonforms.cells || [],
2352
+ i18nKeyPrefix,
2353
+ label,
2354
+ indexOfFittingSchema,
2355
+ uischemas: getUISchemas(state),
2356
+ translations,
2131
2357
  };
2132
2358
  };
2133
- const defaultMapStateToEnumCellProps = (state, ownProps) => {
2134
- const props = mapStateToCellProps(state, ownProps);
2135
- const options = ownProps.options ||
2136
- props.schema.enum?.map((e) => enumToEnumOptionMapper(e, getTranslator()(state), getI18nKeyPrefix(props.schema, props.uischema, props.path))) ||
2137
- (props.schema.const && [
2138
- enumToEnumOptionMapper(props.schema.const, getTranslator()(state), getI18nKeyPrefix(props.schema, props.uischema, props.path)),
2139
- ]);
2140
- return {
2141
- ...props,
2142
- options,
2143
- };
2359
+ const mapStateToAllOfProps = (state, ownProps) => mapStateToCombinatorRendererProps(state, ownProps, 'allOf');
2360
+ const mapStateToAnyOfProps = (state, ownProps) => {
2361
+ return mapStateToCombinatorRendererProps(state, ownProps, 'anyOf');
2144
2362
  };
2145
- const mapStateToOneOfEnumCellProps = (state, ownProps) => {
2146
- const props = mapStateToCellProps(state, ownProps);
2147
- const options = ownProps.options ||
2148
- props.schema.oneOf?.map((oneOfSubSchema) => oneOfToEnumOptionMapper(oneOfSubSchema, getTranslator()(state), getI18nKeyPrefix(props.schema, props.uischema, props.path)));
2149
- return {
2150
- ...props,
2151
- options,
2152
- };
2363
+ const mapStateToOneOfProps = (state, ownProps) => {
2364
+ return mapStateToCombinatorRendererProps(state, ownProps, 'oneOf');
2153
2365
  };
2154
- const mapDispatchToCellProps = mapDispatchToControlProps;
2155
- const defaultMapDispatchToControlProps =
2156
- (dispatch, ownProps) => {
2157
- const { handleChange } = mapDispatchToCellProps(dispatch);
2366
+ const mapStateToArrayLayoutProps = (state, ownProps) => {
2367
+ const { path, schema, uischema, errors, i18nKeyPrefix, label, ...props } = mapStateToControlWithDetailProps(state, ownProps);
2368
+ const resolvedSchema = Resolve.schema(schema, 'items', props.rootSchema);
2369
+ const t = getTranslator()(state);
2370
+ const childErrors = getCombinedErrorMessage(getSubErrorsAt(path, resolvedSchema)(state), getErrorTranslator()(state), t, undefined, undefined, undefined);
2371
+ const allErrors = errors +
2372
+ (errors.length > 0 && childErrors.length > 0 ? '\n' : '') +
2373
+ childErrors;
2158
2374
  return {
2159
- handleChange: ownProps.handleChange || handleChange,
2375
+ ...props,
2376
+ label,
2377
+ path,
2378
+ uischema,
2379
+ schema: resolvedSchema,
2380
+ data: props.data ? props.data.length : 0,
2381
+ errors: allErrors,
2382
+ minItems: schema.minItems,
2383
+ translations: getArrayTranslations(t, arrayDefaultTranslations, i18nKeyPrefix, label),
2160
2384
  };
2161
2385
  };
2162
-
2163
- const createCombinatorRenderInfos = (combinatorSubSchemas, rootSchema, keyword, control, path, uischemas) => combinatorSubSchemas.map((subSchema, subSchemaIndex) => {
2164
- const resolvedSubSchema = subSchema.$ref && Resolve.schema(rootSchema, subSchema.$ref, rootSchema);
2165
- const schema = resolvedSubSchema ?? subSchema;
2386
+ const mapStateToLabelProps = (state, props) => {
2387
+ const { uischema } = props;
2388
+ const visible = props.visible === undefined || hasShowRule(uischema)
2389
+ ? isVisible(props.uischema, getData(state), props.path, getAjv(state))
2390
+ : props.visible;
2391
+ const text = uischema.text;
2392
+ const t = getTranslator()(state);
2393
+ const i18nKeyPrefix = getI18nKeyPrefixBySchema(undefined, uischema);
2394
+ const i18nKey = i18nKeyPrefix ? `${i18nKeyPrefix}.text` : text ?? '';
2395
+ const i18nText = t(i18nKey, text, { uischema });
2166
2396
  return {
2167
- schema,
2168
- uischema: findUISchema(uischemas, schema, control.scope, path, undefined, control, rootSchema),
2169
- label: subSchema.title ??
2170
- resolvedSubSchema?.title ??
2171
- `${keyword}-${subSchemaIndex}`,
2397
+ text: i18nText,
2398
+ visible,
2399
+ config: getConfig(state),
2400
+ renderers: props.renderers || getRenderers(state),
2401
+ cells: props.cells || getCells(state),
2172
2402
  };
2173
- });
2174
-
2175
- const usedIds = new Set();
2176
- const makeId = (idBase, iteration) => iteration <= 1 ? idBase : idBase + iteration.toString();
2177
- const isUniqueId = (idBase, iteration) => {
2178
- const newID = makeId(idBase, iteration);
2179
- return !usedIds.has(newID);
2180
- };
2181
- const createId = (proposedId) => {
2182
- if (proposedId === undefined) {
2183
- proposedId = 'undefined';
2184
- }
2185
- let tries = 0;
2186
- while (!isUniqueId(proposedId, tries)) {
2187
- tries++;
2188
- }
2189
- const newID = makeId(proposedId, tries);
2190
- usedIds.add(newID);
2191
- return newID;
2192
- };
2193
- const removeId = (id) => usedIds.delete(id);
2194
- const clearAllIds = () => usedIds.clear();
2195
-
2196
- const createAjv = (options) => {
2197
- const ajv = new Ajv({
2198
- allErrors: true,
2199
- verbose: true,
2200
- strict: false,
2201
- addUsedSchema: false,
2202
- ...options,
2203
- });
2204
- addFormats(ajv);
2205
- return ajv;
2206
- };
2207
-
2208
- const defaultDateFormat = 'YYYY-MM-DD';
2209
- const defaultTimeFormat = 'HH:mm:ss';
2210
- const defaultDateTimeFormat = 'YYYY-MM-DDTHH:mm:ss.sssZ';
2211
-
2212
- const createLayout = (layoutType) => ({
2213
- type: layoutType,
2214
- elements: [],
2215
- });
2216
- const createControlElement = (ref) => ({
2217
- type: 'Control',
2218
- scope: ref,
2219
- });
2220
- const wrapInLayoutIfNecessary = (uischema, layoutType) => {
2221
- if (!isEmpty(uischema) && !isLayout(uischema)) {
2222
- const verticalLayout = createLayout(layoutType);
2223
- verticalLayout.elements.push(uischema);
2224
- return verticalLayout;
2225
- }
2226
- return uischema;
2227
- };
2228
- const addLabel = (layout, labelName) => {
2229
- if (!isEmpty(labelName)) {
2230
- const fixedLabel = startCase(labelName);
2231
- if (isGroup(layout)) {
2232
- layout.label = fixedLabel;
2233
- }
2234
- else {
2235
- const label = {
2236
- type: 'Label',
2237
- text: fixedLabel,
2238
- };
2239
- layout.elements.push(label);
2240
- }
2241
- }
2242
- };
2243
- const isCombinator = (jsonSchema) => {
2244
- return (!isEmpty(jsonSchema) &&
2245
- (!isEmpty(jsonSchema.oneOf) ||
2246
- !isEmpty(jsonSchema.anyOf) ||
2247
- !isEmpty(jsonSchema.allOf)));
2248
2403
  };
2249
- const generateUISchema = (jsonSchema, schemaElements, currentRef, schemaName, layoutType, rootSchema) => {
2250
- if (!isEmpty(jsonSchema) && jsonSchema.$ref !== undefined) {
2251
- return generateUISchema(resolveSchema(rootSchema, jsonSchema.$ref, rootSchema), schemaElements, currentRef, schemaName, layoutType, rootSchema);
2252
- }
2253
- if (isCombinator(jsonSchema)) {
2254
- const controlObject = createControlElement(currentRef);
2255
- schemaElements.push(controlObject);
2256
- return controlObject;
2257
- }
2258
- const types = deriveTypes(jsonSchema);
2259
- if (types.length === 0) {
2260
- return null;
2261
- }
2262
- if (types.length > 1) {
2263
- const controlObject = createControlElement(currentRef);
2264
- schemaElements.push(controlObject);
2265
- return controlObject;
2266
- }
2267
- if (currentRef === '#' && types[0] === 'object') {
2268
- const layout = createLayout(layoutType);
2269
- schemaElements.push(layout);
2270
- if (jsonSchema.properties && keys(jsonSchema.properties).length > 1) {
2271
- addLabel(layout, schemaName);
2272
- }
2273
- if (!isEmpty(jsonSchema.properties)) {
2274
- const nextRef = currentRef + '/properties';
2275
- Object.keys(jsonSchema.properties).map((propName) => {
2276
- let value = jsonSchema.properties[propName];
2277
- const ref = `${nextRef}/${encode(propName)}`;
2278
- if (value.$ref !== undefined) {
2279
- value = resolveSchema(rootSchema, value.$ref, rootSchema);
2280
- }
2281
- generateUISchema(value, layout.elements, ref, propName, layoutType, rootSchema);
2282
- });
2283
- }
2284
- return layout;
2404
+ const computeChildLabel = (data, childPath, childLabelProp, schema, rootSchema, translateFct, uiSchema) => {
2405
+ const childData = Resolve.data(data, childPath);
2406
+ if (!childLabelProp) {
2407
+ childLabelProp = getFirstPrimitiveProp(schema);
2285
2408
  }
2286
- switch (types[0]) {
2287
- case 'object':
2288
- case 'array':
2289
- case 'string':
2290
- case 'number':
2291
- case 'integer':
2292
- case 'null':
2293
- case 'boolean': {
2294
- const controlObject = createControlElement(currentRef);
2295
- schemaElements.push(controlObject);
2296
- return controlObject;
2297
- }
2298
- default:
2299
- throw new Error('Unknown type: ' + JSON.stringify(jsonSchema));
2409
+ if (!childLabelProp) {
2410
+ return '';
2300
2411
  }
2301
- };
2302
- const generateDefaultUISchema = (jsonSchema, layoutType = 'VerticalLayout', prefix = '#', rootSchema = jsonSchema) => wrapInLayoutIfNecessary(generateUISchema(jsonSchema, [], prefix, '', layoutType, rootSchema), layoutType);
2303
-
2304
- const Generate = {
2305
- jsonSchema: generateJsonSchema,
2306
- uiSchema: generateDefaultUISchema,
2307
- controlElement: createControlElement,
2308
- };
2309
-
2310
- const INIT = 'jsonforms/INIT';
2311
- const UPDATE_CORE = 'jsonforms/UPDATE_CORE';
2312
- const SET_AJV = 'jsonforms/SET_AJV';
2313
- const UPDATE_DATA = 'jsonforms/UPDATE';
2314
- const UPDATE_ERRORS = 'jsonforms/UPDATE_ERRORS';
2315
- const VALIDATE = 'jsonforms/VALIDATE';
2316
- const ADD_RENDERER = 'jsonforms/ADD_RENDERER';
2317
- const REMOVE_RENDERER = 'jsonforms/REMOVE_RENDERER';
2318
- const ADD_CELL = 'jsonforms/ADD_CELL';
2319
- const REMOVE_CELL = 'jsonforms/REMOVE_CELL';
2320
- const SET_CONFIG = 'jsonforms/SET_CONFIG';
2321
- const ADD_UI_SCHEMA = 'jsonforms/ADD_UI_SCHEMA';
2322
- const REMOVE_UI_SCHEMA = 'jsonforms/REMOVE_UI_SCHEMA';
2323
- const SET_SCHEMA = 'jsonforms/SET_SCHEMA';
2324
- const SET_UISCHEMA = 'jsonforms/SET_UISCHEMA';
2325
- const SET_VALIDATION_MODE = 'jsonforms/SET_VALIDATION_MODE';
2326
- const SET_LOCALE = 'jsonforms/SET_LOCALE';
2327
- const SET_TRANSLATOR = 'jsonforms/SET_TRANSLATOR';
2328
- const UPDATE_I18N = 'jsonforms/UPDATE_I18N';
2329
- const ADD_DEFAULT_DATA = 'jsonforms/ADD_DEFAULT_DATA';
2330
- const REMOVE_DEFAULT_DATA = 'jsonforms/REMOVE_DEFAULT_DATA';
2331
- const isUpdateArrayContext = (context) => {
2332
- if (!('type' in context)) {
2333
- return false;
2412
+ const currentValue = get(childData, childLabelProp);
2413
+ if (currentValue === undefined) {
2414
+ return '';
2334
2415
  }
2335
- if (typeof context.type !== 'string') {
2336
- return false;
2416
+ const childSchema = Resolve.schema(schema, '#' + getPropPath(childLabelProp), rootSchema);
2417
+ let enumOption = undefined;
2418
+ if (isEnumSchema(childSchema)) {
2419
+ enumOption = enumToEnumOptionMapper(currentValue, translateFct, getI18nKeyPrefix(childSchema, findUiControl(uiSchema, childLabelProp), childPath + '.' + childLabelProp));
2337
2420
  }
2338
- switch (context.type) {
2339
- case 'ADD': {
2340
- return ('values' in context &&
2341
- Array.isArray(context.values) &&
2342
- context.values.length > 0);
2343
- }
2344
- case 'REMOVE': {
2345
- return ('indices' in context &&
2346
- Array.isArray(context.indices) &&
2347
- context.indices.length > 0 &&
2348
- context.indices.every((i) => typeof i === 'number'));
2349
- }
2350
- case 'MOVE': {
2351
- return ('moves' in context &&
2352
- Array.isArray(context.moves) &&
2353
- context.moves.length > 0 &&
2354
- context.moves.every((m) => typeof m === 'object' &&
2355
- m !== null &&
2356
- 'from' in m &&
2357
- 'to' in m &&
2358
- typeof m.from === 'number' &&
2359
- typeof m.to === 'number'));
2421
+ else if (isOneOfEnumSchema(childSchema)) {
2422
+ const oneOfArray = childSchema.oneOf;
2423
+ const oneOfSchema = oneOfArray.find((e) => isEqual$1(e.const, currentValue));
2424
+ if (oneOfSchema) {
2425
+ enumOption = oneOfToEnumOptionMapper(oneOfSchema, translateFct, getI18nKeyPrefix(oneOfSchema, undefined, childPath + '.' + childLabelProp));
2360
2426
  }
2361
- default:
2362
- return false;
2363
2427
  }
2428
+ return enumOption ? enumOption.label : currentValue;
2364
2429
  };
2365
- const init = (data, schema = generateJsonSchema(data), uischema, options) => ({
2366
- type: INIT,
2367
- data,
2368
- schema,
2369
- uischema: typeof uischema === 'object' ? uischema : generateDefaultUISchema(schema),
2370
- options,
2371
- });
2372
- const updateCore = (data, schema, uischema, options) => ({
2373
- type: UPDATE_CORE,
2374
- data,
2375
- schema,
2376
- uischema,
2377
- options,
2378
- });
2379
- const registerDefaultData = (schemaPath, data) => ({
2380
- type: ADD_DEFAULT_DATA,
2381
- schemaPath,
2382
- data,
2383
- });
2384
- const unregisterDefaultData = (schemaPath) => ({
2385
- type: REMOVE_DEFAULT_DATA,
2386
- schemaPath,
2387
- });
2388
- const setAjv = (ajv) => ({
2389
- type: SET_AJV,
2390
- ajv,
2391
- });
2392
- const update = (path, updater, context) => ({
2393
- type: UPDATE_DATA,
2394
- path,
2395
- updater,
2396
- context,
2397
- });
2398
- const updateErrors = (errors) => ({
2399
- type: UPDATE_ERRORS,
2400
- errors,
2401
- });
2402
- const registerRenderer = (tester, renderer) => ({
2403
- type: ADD_RENDERER,
2404
- tester,
2405
- renderer,
2406
- });
2407
- const registerCell = (tester, cell) => ({
2408
- type: ADD_CELL,
2409
- tester,
2410
- cell,
2411
- });
2412
- const unregisterCell = (tester, cell) => ({
2413
- type: REMOVE_CELL,
2414
- tester,
2415
- cell,
2416
- });
2417
- const unregisterRenderer = (tester, renderer) => ({
2418
- type: REMOVE_RENDERER,
2419
- tester,
2420
- renderer,
2421
- });
2422
- const setConfig = (config) => ({
2423
- type: SET_CONFIG,
2424
- config,
2425
- });
2426
- const setValidationMode = (validationMode) => ({
2427
- type: SET_VALIDATION_MODE,
2428
- validationMode,
2429
- });
2430
- const registerUISchema = (tester, uischema) => {
2430
+
2431
+ const mapStateToCellProps = (state, ownProps) => {
2432
+ const { id, schema, path, uischema, renderers, cells } = ownProps;
2433
+ const rootData = getData(state);
2434
+ const visible = ownProps.visible !== undefined
2435
+ ? ownProps.visible
2436
+ : isVisible(uischema, rootData, undefined, getAjv(state));
2437
+ const rootSchema = getSchema(state);
2438
+ const config = getConfig(state);
2439
+ let enabled;
2440
+ if (state.jsonforms.readonly === true) {
2441
+ enabled = false;
2442
+ }
2443
+ else if (typeof ownProps.enabled === 'boolean') {
2444
+ enabled = ownProps.enabled;
2445
+ }
2446
+ else {
2447
+ enabled = isInherentlyEnabled(state, ownProps, uischema, schema || rootSchema, rootData, config);
2448
+ }
2449
+ const t = getTranslator()(state);
2450
+ const te = getErrorTranslator()(state);
2451
+ const errors = getCombinedErrorMessage(getErrorAt(path, schema)(state), te, t, schema, uischema, path);
2452
+ const isValid = isEmpty(errors);
2431
2453
  return {
2432
- type: ADD_UI_SCHEMA,
2433
- tester,
2454
+ data: Resolve.data(rootData, path),
2455
+ visible,
2456
+ enabled,
2457
+ id,
2458
+ path,
2459
+ errors,
2460
+ isValid,
2461
+ schema,
2434
2462
  uischema,
2463
+ config: getConfig(state),
2464
+ rootSchema,
2465
+ renderers,
2466
+ cells,
2435
2467
  };
2436
2468
  };
2437
- const unregisterUISchema = (tester) => {
2469
+ const mapStateToDispatchCellProps = (state, ownProps) => {
2470
+ const props = mapStateToCellProps(state, ownProps);
2471
+ const { renderers: _renderers, cells, ...otherOwnProps } = ownProps;
2438
2472
  return {
2439
- type: REMOVE_UI_SCHEMA,
2440
- tester,
2473
+ ...props,
2474
+ ...otherOwnProps,
2475
+ cells: cells || state.jsonforms.cells || [],
2476
+ };
2477
+ };
2478
+ const defaultMapStateToEnumCellProps = (state, ownProps) => {
2479
+ const props = mapStateToCellProps(state, ownProps);
2480
+ const options = ownProps.options ||
2481
+ props.schema.enum?.map((e) => enumToEnumOptionMapper(e, getTranslator()(state), getI18nKeyPrefix(props.schema, props.uischema, props.path))) ||
2482
+ (props.schema.const && [
2483
+ enumToEnumOptionMapper(props.schema.const, getTranslator()(state), getI18nKeyPrefix(props.schema, props.uischema, props.path)),
2484
+ ]);
2485
+ return {
2486
+ ...props,
2487
+ options,
2488
+ };
2489
+ };
2490
+ const mapStateToOneOfEnumCellProps = (state, ownProps) => {
2491
+ const props = mapStateToCellProps(state, ownProps);
2492
+ const options = ownProps.options ||
2493
+ props.schema.oneOf?.map((oneOfSubSchema) => oneOfToEnumOptionMapper(oneOfSubSchema, getTranslator()(state), getI18nKeyPrefix(props.schema, props.uischema, props.path)));
2494
+ return {
2495
+ ...props,
2496
+ options,
2497
+ };
2498
+ };
2499
+ const mapDispatchToCellProps = mapDispatchToControlProps;
2500
+ const defaultMapDispatchToControlProps =
2501
+ (dispatch, ownProps) => {
2502
+ const { handleChange } = mapDispatchToCellProps(dispatch);
2503
+ return {
2504
+ handleChange: ownProps.handleChange || handleChange,
2441
2505
  };
2442
2506
  };
2443
- const setLocale = (locale) => ({
2444
- type: SET_LOCALE,
2445
- locale,
2446
- });
2447
- const setSchema = (schema) => ({
2448
- type: SET_SCHEMA,
2449
- schema,
2450
- });
2451
- const setTranslator = (translator, errorTranslator) => ({
2452
- type: SET_TRANSLATOR,
2453
- translator,
2454
- errorTranslator,
2455
- });
2456
- const updateI18n = (locale, translator, errorTranslator) => ({
2457
- type: UPDATE_I18N,
2458
- locale,
2459
- translator,
2460
- errorTranslator,
2461
- });
2462
- const setUISchema = (uischema) => ({
2463
- type: SET_UISCHEMA,
2464
- uischema,
2465
- });
2466
2507
 
2467
- var index = /*#__PURE__*/Object.freeze({
2468
- __proto__: null,
2469
- INIT: INIT,
2470
- UPDATE_CORE: UPDATE_CORE,
2471
- SET_AJV: SET_AJV,
2472
- UPDATE_DATA: UPDATE_DATA,
2473
- UPDATE_ERRORS: UPDATE_ERRORS,
2474
- VALIDATE: VALIDATE,
2475
- ADD_RENDERER: ADD_RENDERER,
2476
- REMOVE_RENDERER: REMOVE_RENDERER,
2477
- ADD_CELL: ADD_CELL,
2478
- REMOVE_CELL: REMOVE_CELL,
2479
- SET_CONFIG: SET_CONFIG,
2480
- ADD_UI_SCHEMA: ADD_UI_SCHEMA,
2481
- REMOVE_UI_SCHEMA: REMOVE_UI_SCHEMA,
2482
- SET_SCHEMA: SET_SCHEMA,
2483
- SET_UISCHEMA: SET_UISCHEMA,
2484
- SET_VALIDATION_MODE: SET_VALIDATION_MODE,
2485
- SET_LOCALE: SET_LOCALE,
2486
- SET_TRANSLATOR: SET_TRANSLATOR,
2487
- UPDATE_I18N: UPDATE_I18N,
2488
- ADD_DEFAULT_DATA: ADD_DEFAULT_DATA,
2489
- REMOVE_DEFAULT_DATA: REMOVE_DEFAULT_DATA,
2490
- isUpdateArrayContext: isUpdateArrayContext,
2491
- init: init,
2492
- updateCore: updateCore,
2493
- registerDefaultData: registerDefaultData,
2494
- unregisterDefaultData: unregisterDefaultData,
2495
- setAjv: setAjv,
2496
- update: update,
2497
- updateErrors: updateErrors,
2498
- registerRenderer: registerRenderer,
2499
- registerCell: registerCell,
2500
- unregisterCell: unregisterCell,
2501
- unregisterRenderer: unregisterRenderer,
2502
- setConfig: setConfig,
2503
- setValidationMode: setValidationMode,
2504
- registerUISchema: registerUISchema,
2505
- unregisterUISchema: unregisterUISchema,
2506
- setLocale: setLocale,
2507
- setSchema: setSchema,
2508
- setTranslator: setTranslator,
2509
- updateI18n: updateI18n,
2510
- setUISchema: setUISchema
2508
+ const createCombinatorRenderInfos = (combinatorSubSchemas, rootSchema, keyword, control, path, uischemas) => combinatorSubSchemas.map((subSchema, subSchemaIndex) => {
2509
+ const resolvedSubSchema = subSchema.$ref && Resolve.schema(rootSchema, subSchema.$ref, rootSchema);
2510
+ const schema = resolvedSubSchema ?? subSchema;
2511
+ return {
2512
+ schema,
2513
+ uischema: findUISchema(uischemas, schema, control.scope, path, undefined, control, rootSchema),
2514
+ label: subSchema.title ??
2515
+ resolvedSubSchema?.title ??
2516
+ `${keyword}-${subSchemaIndex}`,
2517
+ };
2511
2518
  });
2512
2519
 
2513
- const Helpers = {
2514
- createLabelDescriptionFrom,
2515
- convertToValidClassName,
2516
- };
2517
-
2518
- export { ADD_CELL, ADD_DEFAULT_DATA, ADD_RENDERER, ADD_UI_SCHEMA, index as Actions, ArrayTranslationEnum, CombinatorTranslationEnum, Draft4, Generate, Helpers, INIT, NOT_APPLICABLE, Paths, REMOVE_CELL, REMOVE_DEFAULT_DATA, REMOVE_RENDERER, REMOVE_UI_SCHEMA, Resolve, RuleEffect, Runtime, SET_AJV, SET_CONFIG, SET_LOCALE, SET_SCHEMA, SET_TRANSLATOR, SET_UISCHEMA, SET_VALIDATION_MODE, index$1 as Test, UPDATE_CORE, UPDATE_DATA, UPDATE_ERRORS, UPDATE_I18N, VALIDATE, addI18nKeyToPrefix, and, arrayDefaultTranslations, categorizationHasCategory, cellReducer, clearAllIds, combinatorDefaultTranslations, compose, compose as composePaths, composeWithUi, computeChildLabel, computeLabel, configReducer, controlDefaultProps, convertDateToString, convertToValidClassName, coreReducer, createAjv, createCleanLabel, createCombinatorRenderInfos, createControlElement, createDefaultValue, createId, createLabelDescriptionFrom, decode, defaultDataReducer, defaultDateFormat, defaultDateTimeFormat, defaultErrorTranslator, defaultJsonFormsI18nState, defaultMapDispatchToControlProps, defaultMapStateToEnumCellProps, defaultMiddleware, defaultTimeFormat, defaultTranslator, deriveLabelForUISchemaElement, deriveTypes, encode, enumToEnumOptionMapper, errorAt, errorsAt, evalEnablement, evalVisibility, extractAjv, extractData, extractDefaultData, extractDefaults, extractSchema, extractUiSchema, fetchErrorTranslator, fetchLocale, fetchTranslator, findAllRefs, findMatchingUISchema, findUISchema, findUiControl, formatErrorMessage, formatIs, generateDefaultUISchema, generateJsonSchema, getAjv, getArrayTranslations, getCells, getCombinatorTranslations, getCombinedErrorMessage, getConfig, getControlPath, getData, getDefaultData, getErrorAt, getErrorTranslator, getFirstPrimitiveProp, getI18nKey, getI18nKeyPrefix, getI18nKeyPrefixBySchema, getLocale, getPropPath, getRenderers, getSchema, getSubErrorsAt, getTranslator, getUISchemas, getUiSchema, hasCategory, hasEnableRule, hasOption, hasShowRule, hasType, i18nReducer, init, isAllOfControl, isAnyOfControl, isArrayObjectControl, isBooleanControl, isCategorization, isCategory, isControl, isControlElement, isDateControl, isDateTimeControl, isDescriptionHidden, isEnabled, isEnumControl, isEnumSchema, isGroup, isInherentlyEnabled, isIntegerControl, isInternationalized, isLabelable, isLabeled, isLayout, isMultiLineControl, isNumberControl, isNumberFormatControl, isObjectArray, isObjectArrayControl, isObjectArrayWithNesting, isObjectControl, isOneOfControl, isOneOfEnumControl, isOneOfEnumSchema, isPrimitiveArrayControl, isRangeControl, isScopable, isScoped, isStringControl, isTimeControl, isUpdateArrayContext, isVisible, iterateSchema, jsonFormsReducerConfig, layoutDefaultProps, mapDispatchToArrayControlProps, mapDispatchToCellProps, mapDispatchToControlProps, mapDispatchToMultiEnumProps, mapStateToAllOfProps, mapStateToAnyOfProps, mapStateToArrayControlProps, mapStateToArrayLayoutProps, mapStateToCellProps, mapStateToCombinatorRendererProps, mapStateToControlProps, mapStateToControlWithDetailProps, mapStateToDispatchCellProps, mapStateToEnumControlProps, mapStateToJsonFormsRendererProps, mapStateToLabelProps, mapStateToLayoutProps, mapStateToMasterListItemProps, mapStateToMultiEnumControlProps, mapStateToOneOfEnumCellProps, mapStateToOneOfEnumControlProps, mapStateToOneOfProps, moveDown, moveUp, not, oneOfToEnumOptionMapper, optionIs, or, rankWith, registerCell, registerDefaultData, registerRenderer, registerUISchema, removeId, rendererReducer, resolveData, resolveSchema, schemaMatches, schemaSubPathMatches, schemaTypeIs, scopeEndIs, scopeEndsWith, setAjv, setConfig, setLocale, setReadonly, setSchema, setTranslator, setUISchema, setValidationMode, showAsRequired, subErrorsAt, toDataPath, toDataPathSegments, transformPathToI18nPrefix, uiTypeIs, uischemaRegistryReducer, unregisterCell, unregisterDefaultData, unregisterRenderer, unregisterUISchema, unsetReadonly, update, updateCore, updateErrors, updateI18n, validate, withIncreasedRank };
2520
+ export { ADD_CELL, ADD_DEFAULT_DATA, ADD_RENDERER, ADD_UI_SCHEMA, index$1 as Actions, ArrayTranslationEnum, CombinatorTranslationEnum, Draft4, Generate, Helpers, INIT, NOT_APPLICABLE, Paths, REMOVE_CELL, REMOVE_DEFAULT_DATA, REMOVE_RENDERER, REMOVE_UI_SCHEMA, Resolve, RuleEffect, Runtime, SET_AJV, SET_CONFIG, SET_LOCALE, SET_SCHEMA, SET_TRANSLATOR, SET_UISCHEMA, SET_VALIDATION_MODE, index as Test, UPDATE_CORE, UPDATE_DATA, UPDATE_ERRORS, UPDATE_I18N, VALIDATE, addI18nKeyToPrefix, and, arrayDefaultTranslations, categorizationHasCategory, cellReducer, clearAllIds, combinatorDefaultTranslations, compose, compose as composePaths, composeWithUi, computeChildLabel, computeLabel, configReducer, controlDefaultProps, convertDateToString, convertToValidClassName, coreReducer, createAjv, createCleanLabel, createCombinatorRenderInfos, createControlElement, createDefaultValue, createId, createLabelDescriptionFrom, decode, defaultDataReducer, defaultDateFormat, defaultDateTimeFormat, defaultErrorTranslator, defaultJsonFormsI18nState, defaultMapDispatchToControlProps, defaultMapStateToEnumCellProps, defaultMiddleware, defaultTimeFormat, defaultTranslator, deriveLabelForUISchemaElement, deriveTypes, encode, enumToEnumOptionMapper, errorAt, errorsAt, evalEnablement, evalVisibility, extractAjv, extractData, extractDefaultData, extractDefaults, extractSchema, extractUiSchema, fetchErrorTranslator, fetchLocale, fetchTranslator, findAllRefs, findMatchingUISchema, findUISchema, findUiControl, formatErrorMessage, formatIs, generateDefaultUISchema, generateJsonSchema, getAdditionalErrors, getAjv, getArrayTranslations, getCells, getCombinatorTranslations, getCombinedErrorMessage, getConfig, getControlPath, getData, getDefaultData, getErrorAt, getErrorTranslator, getFirstPrimitiveProp, getI18nKey, getI18nKeyPrefix, getI18nKeyPrefixBySchema, getLocale, getOrCreateAjv, getPropPath, getRenderers, getSchema, getSubErrorsAt, getTranslator, getUISchemas, getUiSchema, getValidationMode, hasCategory, hasEnableRule, hasOption, hasShowRule, hasType, i18nReducer, init, initState, isAllOfControl, isAnyOfControl, isArrayObjectControl, isBooleanControl, isCategorization, isCategory, isControl, isControlElement, isDateControl, isDateTimeControl, isDescriptionHidden, isEnabled, isEnumControl, isEnumSchema, isGroup, isInherentlyEnabled, isIntegerControl, isInternationalized, isLabelable, isLabeled, isLayout, isMultiLineControl, isNumberControl, isNumberFormatControl, isObjectArray, isObjectArrayControl, isObjectArrayWithNesting, isObjectControl, isOneOfControl, isOneOfEnumControl, isOneOfEnumSchema, isPrimitiveArrayControl, isRangeControl, isScopable, isScoped, isStringControl, isTimeControl, isUpdateArrayContext, isVisible, iterateSchema, jsonFormsReducerConfig, layoutDefaultProps, mapDispatchToArrayControlProps, mapDispatchToCellProps, mapDispatchToControlProps, mapDispatchToMultiEnumProps, mapStateToAllOfProps, mapStateToAnyOfProps, mapStateToArrayControlProps, mapStateToArrayLayoutProps, mapStateToCellProps, mapStateToCombinatorRendererProps, mapStateToControlProps, mapStateToControlWithDetailProps, mapStateToDispatchCellProps, mapStateToEnumControlProps, mapStateToJsonFormsRendererProps, mapStateToLabelProps, mapStateToLayoutProps, mapStateToMasterListItemProps, mapStateToMultiEnumControlProps, mapStateToOneOfEnumCellProps, mapStateToOneOfEnumControlProps, mapStateToOneOfProps, moveDown, moveUp, not, oneOfToEnumOptionMapper, optionIs, or, rankWith, registerCell, registerDefaultData, registerRenderer, registerUISchema, removeId, rendererReducer, resolveData, resolveSchema, schemaMatches, schemaSubPathMatches, schemaTypeIs, scopeEndIs, scopeEndsWith, setAjv, setConfig, setLocale, setReadonly, setSchema, setTranslator, setUISchema, setValidationMode, showAsRequired, subErrorsAt, toDataPath, toDataPathSegments, transformPathToI18nPrefix, uiTypeIs, uischemaRegistryReducer, unregisterCell, unregisterDefaultData, unregisterRenderer, unregisterUISchema, unsetReadonly, update, updateCore, updateErrors, updateI18n, validate, withIncreasedRank };
2519
2521
  //# sourceMappingURL=jsonforms-core.esm.js.map