@rjsf/utils 6.0.0-beta.1 → 6.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +75 -30
- package/dist/index.js.map +3 -3
- package/dist/utils.esm.js +75 -30
- package/dist/utils.esm.js.map +3 -3
- package/dist/utils.umd.js +70 -28
- package/lib/constants.d.ts +4 -0
- package/lib/constants.js +4 -0
- package/lib/constants.js.map +1 -1
- package/lib/findSchemaDefinition.d.ts +4 -2
- package/lib/findSchemaDefinition.js +52 -10
- package/lib/findSchemaDefinition.js.map +1 -1
- package/lib/schema/getDefaultFormState.js +6 -1
- package/lib/schema/getDefaultFormState.js.map +1 -1
- package/lib/schema/retrieveSchema.d.ts +2 -1
- package/lib/schema/retrieveSchema.js +12 -5
- package/lib/schema/retrieveSchema.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.d.ts +6 -9
- package/package.json +2 -1
- package/src/constants.ts +5 -0
- package/src/findSchemaDefinition.ts +52 -8
- package/src/schema/getDefaultFormState.ts +7 -1
- package/src/schema/retrieveSchema.ts +12 -3
- package/src/types.ts +6 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rjsf/utils",
|
|
3
|
-
"version": "6.0.0-beta.
|
|
3
|
+
"version": "6.0.0-beta.3",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"react": ">=18"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
+
"fast-uri": "^3.0.6",
|
|
68
69
|
"json-schema-merge-allof": "^0.8.1",
|
|
69
70
|
"jsonpointer": "^5.0.1",
|
|
70
71
|
"lodash": "^4.17.21",
|
package/src/constants.ts
CHANGED
|
@@ -25,6 +25,7 @@ export const READONLY_KEY = 'readonly';
|
|
|
25
25
|
export const REQUIRED_KEY = 'required';
|
|
26
26
|
export const SUBMIT_BTN_OPTIONS_KEY = 'submitButtonOptions';
|
|
27
27
|
export const REF_KEY = '$ref';
|
|
28
|
+
export const SCHEMA_KEY = '$schema';
|
|
28
29
|
/** The path of the discriminator value returned by the schema endpoint.
|
|
29
30
|
* The discriminator is the value in a `oneOf` that determines which option is selected.
|
|
30
31
|
*/
|
|
@@ -42,3 +43,7 @@ export const UI_FIELD_KEY = 'ui:field';
|
|
|
42
43
|
export const UI_WIDGET_KEY = 'ui:widget';
|
|
43
44
|
export const UI_OPTIONS_KEY = 'ui:options';
|
|
44
45
|
export const UI_GLOBAL_OPTIONS_KEY = 'ui:globalOptions';
|
|
46
|
+
|
|
47
|
+
/** The JSON Schema version strings
|
|
48
|
+
*/
|
|
49
|
+
export const JSON_SCHEMA_DRAFT_2020_12 = 'https://json-schema.org/draft/2020-12/schema';
|
|
@@ -1,8 +1,33 @@
|
|
|
1
1
|
import jsonpointer from 'jsonpointer';
|
|
2
2
|
import omit from 'lodash/omit';
|
|
3
3
|
|
|
4
|
-
import { REF_KEY } from './constants';
|
|
4
|
+
import { ID_KEY, JSON_SCHEMA_DRAFT_2020_12, REF_KEY, SCHEMA_KEY } from './constants';
|
|
5
5
|
import { GenericObjectType, RJSFSchema, StrictRJSFSchema } from './types';
|
|
6
|
+
import isObject from 'lodash/isObject';
|
|
7
|
+
import isEmpty from 'lodash/isEmpty';
|
|
8
|
+
import UriResolver from 'fast-uri';
|
|
9
|
+
|
|
10
|
+
/** Looks for the `$id` pointed by `ref` in the schema definitions embedded in
|
|
11
|
+
* a JSON Schema bundle
|
|
12
|
+
*
|
|
13
|
+
* @param schema - The schema wherein `ref` should be searched
|
|
14
|
+
* @param ref - The `$id` of the reference to search for
|
|
15
|
+
* @returns - The schema matching the reference, or `undefined` if no match is found
|
|
16
|
+
*/
|
|
17
|
+
function findEmbeddedSchemaRecursive<S extends StrictRJSFSchema = RJSFSchema>(schema: S, ref: string): S | undefined {
|
|
18
|
+
if (ID_KEY in schema && UriResolver.equal(schema[ID_KEY] as string, ref)) {
|
|
19
|
+
return schema;
|
|
20
|
+
}
|
|
21
|
+
for (const subSchema of Object.values(schema)) {
|
|
22
|
+
if (isObject(subSchema)) {
|
|
23
|
+
const result = findEmbeddedSchemaRecursive<S>(subSchema as S, ref);
|
|
24
|
+
if (result !== undefined) {
|
|
25
|
+
return result as S;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
6
31
|
|
|
7
32
|
/** Splits out the value at the `key` in `object` from the `object`, returning an array that contains in the first
|
|
8
33
|
* location, the `object` minus the `key: value` and in the second location the `value`.
|
|
@@ -26,6 +51,7 @@ export function splitKeyElementFromObject(key: string, object: GenericObjectType
|
|
|
26
51
|
* @param $ref - The ref string for which the schema definition is desired
|
|
27
52
|
* @param [rootSchema={}] - The root schema in which to search for the definition
|
|
28
53
|
* @param recurseList - List of $refs already resolved to prevent recursion
|
|
54
|
+
* @param baseURI - The base URI to be used for resolving relative references
|
|
29
55
|
* @returns - The sub-schema within the `rootSchema` which matches the `$ref` if it exists
|
|
30
56
|
* @throws - Error indicating that no schema for that reference could be resolved
|
|
31
57
|
*/
|
|
@@ -33,16 +59,32 @@ export function findSchemaDefinitionRecursive<S extends StrictRJSFSchema = RJSFS
|
|
|
33
59
|
$ref?: string,
|
|
34
60
|
rootSchema: S = {} as S,
|
|
35
61
|
recurseList: string[] = [],
|
|
62
|
+
baseURI: string | undefined = ID_KEY in rootSchema ? rootSchema[ID_KEY] : undefined,
|
|
36
63
|
): S {
|
|
37
64
|
const ref = $ref || '';
|
|
38
|
-
let
|
|
65
|
+
let current: S | undefined = undefined;
|
|
39
66
|
if (ref.startsWith('#')) {
|
|
40
67
|
// Decode URI fragment representation.
|
|
41
|
-
decodedRef = decodeURIComponent(ref.substring(1));
|
|
42
|
-
|
|
43
|
-
|
|
68
|
+
const decodedRef = decodeURIComponent(ref.substring(1));
|
|
69
|
+
if (baseURI === undefined || (ID_KEY in rootSchema && rootSchema[ID_KEY] === baseURI)) {
|
|
70
|
+
current = jsonpointer.get(rootSchema, decodedRef);
|
|
71
|
+
} else if (rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2020_12) {
|
|
72
|
+
current = findEmbeddedSchemaRecursive<S>(rootSchema, baseURI.replace(/\/$/, ''));
|
|
73
|
+
if (current !== undefined) {
|
|
74
|
+
current = jsonpointer.get(current, decodedRef);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
} else if (rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2020_12) {
|
|
78
|
+
const resolvedRef = baseURI ? UriResolver.resolve(baseURI, ref) : ref;
|
|
79
|
+
const [refId, ...refAnchor] = resolvedRef.replace(/#\/?$/, '').split('#');
|
|
80
|
+
current = findEmbeddedSchemaRecursive<S>(rootSchema, refId.replace(/\/$/, ''));
|
|
81
|
+
if (current !== undefined) {
|
|
82
|
+
baseURI = current[ID_KEY];
|
|
83
|
+
if (!isEmpty(refAnchor)) {
|
|
84
|
+
current = jsonpointer.get(current, decodeURIComponent(refAnchor.join('#')));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
44
87
|
}
|
|
45
|
-
const current: S = jsonpointer.get(rootSchema, decodedRef);
|
|
46
88
|
if (current === undefined) {
|
|
47
89
|
throw new Error(`Could not find a definition for ${$ref}.`);
|
|
48
90
|
}
|
|
@@ -58,7 +100,7 @@ export function findSchemaDefinitionRecursive<S extends StrictRJSFSchema = RJSFS
|
|
|
58
100
|
throw new Error(`Definition for ${firstRef} contains a circular reference through ${circularPath}`);
|
|
59
101
|
}
|
|
60
102
|
const [remaining, theRef] = splitKeyElementFromObject(REF_KEY, current);
|
|
61
|
-
const subSchema = findSchemaDefinitionRecursive<S>(theRef, rootSchema, [...recurseList, ref]);
|
|
103
|
+
const subSchema = findSchemaDefinitionRecursive<S>(theRef, rootSchema, [...recurseList, ref], baseURI);
|
|
62
104
|
if (Object.keys(remaining).length > 0) {
|
|
63
105
|
return { ...remaining, ...subSchema };
|
|
64
106
|
}
|
|
@@ -74,13 +116,15 @@ export function findSchemaDefinitionRecursive<S extends StrictRJSFSchema = RJSFS
|
|
|
74
116
|
*
|
|
75
117
|
* @param $ref - The ref string for which the schema definition is desired
|
|
76
118
|
* @param [rootSchema={}] - The root schema in which to search for the definition
|
|
119
|
+
* @param [baseURI=rootSchema['$id']] - The base URI to be used for resolving relative references
|
|
77
120
|
* @returns - The sub-schema within the `rootSchema` which matches the `$ref` if it exists
|
|
78
121
|
* @throws - Error indicating that no schema for that reference could be resolved
|
|
79
122
|
*/
|
|
80
123
|
export default function findSchemaDefinition<S extends StrictRJSFSchema = RJSFSchema>(
|
|
81
124
|
$ref?: string,
|
|
82
125
|
rootSchema: S = {} as S,
|
|
126
|
+
baseURI: string | undefined = ID_KEY in rootSchema ? rootSchema[ID_KEY] : undefined,
|
|
83
127
|
): S {
|
|
84
128
|
const recurseList: string[] = [];
|
|
85
|
-
return findSchemaDefinitionRecursive($ref, rootSchema, recurseList);
|
|
129
|
+
return findSchemaDefinitionRecursive($ref, rootSchema, recurseList, baseURI);
|
|
86
130
|
}
|
|
@@ -223,7 +223,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
223
223
|
// For object defaults, only override parent defaults that are defined in
|
|
224
224
|
// schema.default.
|
|
225
225
|
defaults = mergeObjects(defaults!, schema.default as GenericObjectType) as T;
|
|
226
|
-
} else if (DEFAULT_KEY in schema && !schema[ANY_OF_KEY] && !schema[ONE_OF_KEY]) {
|
|
226
|
+
} else if (DEFAULT_KEY in schema && !schema[ANY_OF_KEY] && !schema[ONE_OF_KEY] && !schema[REF_KEY]) {
|
|
227
227
|
// If the schema has a default value, then we should use it as the default.
|
|
228
228
|
// And if the schema does not have anyOf or oneOf, this is done because we need to merge the defaults with the formData.
|
|
229
229
|
defaults = schema.default as unknown as T;
|
|
@@ -234,6 +234,12 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
234
234
|
updatedRecurseList = _recurseList.concat(refName!);
|
|
235
235
|
schemaToCompute = findSchemaDefinition<S>(refName, rootSchema);
|
|
236
236
|
}
|
|
237
|
+
|
|
238
|
+
// If the referenced schema exists and parentDefaults is not set
|
|
239
|
+
// Then set the defaults from the current schema for the referenced schema
|
|
240
|
+
if (schemaToCompute && !defaults) {
|
|
241
|
+
defaults = schema.default as T | undefined;
|
|
242
|
+
}
|
|
237
243
|
} else if (DEPENDENCIES_KEY in schema) {
|
|
238
244
|
// Get the default if set from properties to ensure the dependencies conditions are resolved based on it
|
|
239
245
|
const defaultFormData: T = {
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
ALL_OF_KEY,
|
|
14
14
|
ANY_OF_KEY,
|
|
15
15
|
DEPENDENCIES_KEY,
|
|
16
|
+
ID_KEY,
|
|
16
17
|
IF_KEY,
|
|
17
18
|
ITEMS_KEY,
|
|
18
19
|
ONE_OF_KEY,
|
|
@@ -333,12 +334,14 @@ export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchem
|
|
|
333
334
|
* @param schema - The schema for which resolving all references is desired
|
|
334
335
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
335
336
|
* @param recurseList - List of $refs already resolved to prevent recursion
|
|
337
|
+
* @param baseURI - The base URI to be used for resolving relative references
|
|
336
338
|
* @returns - given schema will all references resolved or the original schema if no internal `$refs` were resolved
|
|
337
339
|
*/
|
|
338
340
|
export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
|
|
339
341
|
schema: S,
|
|
340
342
|
rootSchema: S,
|
|
341
343
|
recurseList: string[],
|
|
344
|
+
baseURI?: string,
|
|
342
345
|
): S {
|
|
343
346
|
if (!isObject(schema)) {
|
|
344
347
|
return schema;
|
|
@@ -353,8 +356,11 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
|
|
|
353
356
|
}
|
|
354
357
|
recurseList.push($ref!);
|
|
355
358
|
// Retrieve the referenced schema definition.
|
|
356
|
-
const refSchema = findSchemaDefinition<S>($ref, rootSchema);
|
|
359
|
+
const refSchema = findSchemaDefinition<S>($ref, rootSchema, baseURI);
|
|
357
360
|
resolvedSchema = { ...refSchema, ...localSchema };
|
|
361
|
+
if (ID_KEY in resolvedSchema) {
|
|
362
|
+
baseURI = resolvedSchema[ID_KEY];
|
|
363
|
+
}
|
|
358
364
|
}
|
|
359
365
|
|
|
360
366
|
if (PROPERTIES_KEY in resolvedSchema) {
|
|
@@ -363,7 +369,7 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
|
|
|
363
369
|
resolvedSchema[PROPERTIES_KEY]!,
|
|
364
370
|
(result, value, key: string) => {
|
|
365
371
|
const childList: string[] = [...recurseList];
|
|
366
|
-
result[key] = resolveAllReferences(value as S, rootSchema, childList);
|
|
372
|
+
result[key] = resolveAllReferences(value as S, rootSchema, childList, baseURI);
|
|
367
373
|
childrenLists.push(childList);
|
|
368
374
|
},
|
|
369
375
|
{} as RJSFSchema,
|
|
@@ -379,7 +385,7 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
|
|
|
379
385
|
) {
|
|
380
386
|
resolvedSchema = {
|
|
381
387
|
...resolvedSchema,
|
|
382
|
-
items: resolveAllReferences(resolvedSchema.items as S, rootSchema, recurseList),
|
|
388
|
+
items: resolveAllReferences(resolvedSchema.items as S, rootSchema, recurseList, baseURI),
|
|
383
389
|
};
|
|
384
390
|
}
|
|
385
391
|
|
|
@@ -550,6 +556,9 @@ export function retrieveSchemaInternal<
|
|
|
550
556
|
? experimental_customMergeAllOf(resolvedSchema)
|
|
551
557
|
: (mergeAllOf(resolvedSchema, {
|
|
552
558
|
deep: false,
|
|
559
|
+
resolvers: {
|
|
560
|
+
$defs: mergeAllOf.options.resolvers.definitions,
|
|
561
|
+
},
|
|
553
562
|
} as Options) as S);
|
|
554
563
|
if (withContainsSchemas.length) {
|
|
555
564
|
resolvedSchema.allOf = withContainsSchemas;
|
package/src/types.ts
CHANGED
|
@@ -245,7 +245,7 @@ export type FormValidation<T = any> = FieldValidation & {
|
|
|
245
245
|
export type RJSFBaseProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = {
|
|
246
246
|
/** The schema object for the field being described */
|
|
247
247
|
schema: S;
|
|
248
|
-
/** The uiSchema object for this
|
|
248
|
+
/** The uiSchema object for this base component */
|
|
249
249
|
uiSchema?: UiSchema<T, S, F>;
|
|
250
250
|
/** The `registry` object */
|
|
251
251
|
registry: Registry<T, S, F>;
|
|
@@ -387,6 +387,9 @@ export type GlobalUISchemaOptions = {
|
|
|
387
387
|
* This option allows you to change the separator between the original key name and the integer. Default is "-"
|
|
388
388
|
*/
|
|
389
389
|
duplicateKeySuffixSeparator?: string;
|
|
390
|
+
/** Enables the displaying of description text that contains markdown
|
|
391
|
+
*/
|
|
392
|
+
enableMarkdownInDescription?: boolean;
|
|
390
393
|
};
|
|
391
394
|
|
|
392
395
|
/** The object containing the registered core, theme and custom fields and widgets as well as the root schema, form
|
|
@@ -422,11 +425,8 @@ export interface Registry<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
422
425
|
/** The properties that are passed to a Field implementation */
|
|
423
426
|
export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>
|
|
424
427
|
extends GenericObjectType,
|
|
428
|
+
RJSFBaseProps<T, S, F>,
|
|
425
429
|
Pick<HTMLAttributes<HTMLElement>, Exclude<keyof HTMLAttributes<HTMLElement>, 'onBlur' | 'onFocus' | 'onChange'>> {
|
|
426
|
-
/** The JSON subschema object for this field */
|
|
427
|
-
schema: S;
|
|
428
|
-
/** The uiSchema for this field */
|
|
429
|
-
uiSchema?: UiSchema<T, S, F>;
|
|
430
430
|
/** The tree of unique ids for every child field */
|
|
431
431
|
idSchema: IdSchema<T>;
|
|
432
432
|
/** The data for this field */
|
|
@@ -463,8 +463,6 @@ export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F
|
|
|
463
463
|
idSeparator?: string;
|
|
464
464
|
/** An array of strings listing all generated error messages from encountered errors for this field */
|
|
465
465
|
rawErrors?: string[];
|
|
466
|
-
/** The `registry` object */
|
|
467
|
-
registry: Registry<T, S, F>;
|
|
468
466
|
}
|
|
469
467
|
|
|
470
468
|
/** The definition of a React-based Field component */
|
|
@@ -726,7 +724,7 @@ export type ObjectFieldTemplateProps<
|
|
|
726
724
|
/** A string value containing the title for the object */
|
|
727
725
|
title: string;
|
|
728
726
|
/** A string value containing the description for the object */
|
|
729
|
-
description?: string;
|
|
727
|
+
description?: string | ReactElement;
|
|
730
728
|
/** A boolean value stating if the object is disabled */
|
|
731
729
|
disabled?: boolean;
|
|
732
730
|
/** An array of objects representing the properties in the object */
|