@remoteoss/json-schema-form 0.10.1-beta.0 → 0.11.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -1
- package/dist/index.cjs +203 -15
- package/dist/index.js +203 -15
- package/dist/standalone.js +373 -23
- package/package.json +1 -1
- package/src/tests/modify.test.js +528 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,27 @@
|
|
|
1
|
+
#### 0.11.0-beta.0 (2024-07-25)
|
|
2
|
+
|
|
3
|
+
##### Breaking changes
|
|
4
|
+
|
|
5
|
+
- **modify:**
|
|
6
|
+
- Change the return result to include warnings ([#83](https://github.com/remoteoss/json-schema-form/pull/83)) ([e07fcec8](https://github.com/remoteoss/json-schema-form/commit/e07fcec8e11cfcba2b477e5e6339cebbcc42038c))
|
|
7
|
+
|
|
8
|
+
##### New Features
|
|
9
|
+
|
|
10
|
+
- **modify:**
|
|
11
|
+
- Allow picking fields ([#79](https://github.com/remoteoss/json-schema-form/pull/79)) ([2e044021](https://github.com/remoteoss/json-schema-form/commit/2e044021f30292be81cede3805eefb4f1ea96dd9))
|
|
12
|
+
- Add x-jsf-presentation shorthand ([#81](https://github.com/remoteoss/json-schema-form/pull/81)) ([7cfaab0b](https://github.com/remoteoss/json-schema-form/commit/7cfaab0bdbb05a1555f6c1d74b26b1e6d7fa8c43))
|
|
13
|
+
- Allow creating fields ([#80](https://github.com/remoteoss/json-schema-form/pull/80)) ([8a82254d](https://github.com/remoteoss/json-schema-form/commit/8a82254d7cf5799471fa0bf2d3d09179f1327187))
|
|
14
|
+
- Allow customize fields order ([#78](https://github.com/remoteoss/json-schema-form/pull/78)) ([adc88179](https://github.com/remoteoss/json-schema-form/commit/adc88179a5d1e5bd85371c0cc581b35964bf6edf))
|
|
15
|
+
|
|
16
|
+
##### Bug Fixes
|
|
17
|
+
|
|
18
|
+
- **modify:** Customize attrs as Array now overrides the value ([#82](https://github.com/remoteoss/json-schema-form/pull/82)) ([7cc0853e](https://github.com/remoteoss/json-schema-form/commit/7cc0853e30f0c06ff160d8a3e4c4b4e402a1e520))
|
|
19
|
+
|
|
1
20
|
#### 0.10.1-beta.0 (2024-07-23)
|
|
2
21
|
|
|
3
22
|
##### Chores
|
|
4
23
|
|
|
5
|
-
|
|
24
|
+
- **Text field docs:** Change naming of ID number property ([#74](https://github.com/remoteoss/json-schema-form/pull/74)) ([338ddd2a](https://github.com/remoteoss/json-schema-form/commit/338ddd2a5f008ec089f38db834f075100b856001))
|
|
6
25
|
|
|
7
26
|
#### 0.10.0-beta.0 (2024-06-20)
|
|
8
27
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2024 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.0-beta.0
|
|
5
|
+
Generated: Thu, 25 Jul 2024 16:43:12 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -1834,37 +1834,78 @@ function createHeadlessForm(jsonSchema, customConfig = {}) {
|
|
|
1834
1834
|
}
|
|
1835
1835
|
|
|
1836
1836
|
// src/modify.js
|
|
1837
|
+
var import_difference = __toESM(require("lodash/difference"));
|
|
1837
1838
|
var import_get4 = __toESM(require("lodash/get"));
|
|
1839
|
+
var import_intersection = __toESM(require("lodash/intersection"));
|
|
1838
1840
|
var import_merge3 = __toESM(require("lodash/merge"));
|
|
1841
|
+
var import_mergeWith = __toESM(require("lodash/mergeWith"));
|
|
1842
|
+
var import_set2 = __toESM(require("lodash/set"));
|
|
1843
|
+
var WARNING_TYPES = {
|
|
1844
|
+
FIELD_TO_CHANGE_NOT_FOUND: "FIELD_TO_CHANGE_NOT_FOUND",
|
|
1845
|
+
ORDER_MISSING_FIELDS: "ORDER_MISSING_FIELDS",
|
|
1846
|
+
FIELD_TO_CREATE_EXISTS: "FIELD_TO_CREATE_EXISTS",
|
|
1847
|
+
PICK_MISSED_FIELD: "PICK_MISSED_FIELD"
|
|
1848
|
+
};
|
|
1839
1849
|
function shortToFullPath(path) {
|
|
1840
1850
|
return path.replace(".", ".properties.");
|
|
1841
1851
|
}
|
|
1852
|
+
function mergeReplaceArray(_, newVal) {
|
|
1853
|
+
return Array.isArray(newVal) ? newVal : void 0;
|
|
1854
|
+
}
|
|
1842
1855
|
function standardizeAttrs(attrs) {
|
|
1843
|
-
const { errorMessage, properties, ...rest } = attrs;
|
|
1856
|
+
const { errorMessage, presentation, properties, ...rest } = attrs;
|
|
1844
1857
|
return {
|
|
1845
1858
|
...rest,
|
|
1859
|
+
...presentation ? { "x-jsf-presentation": presentation } : {},
|
|
1846
1860
|
...errorMessage ? { "x-jsf-errorMessage": errorMessage } : {}
|
|
1847
1861
|
};
|
|
1848
1862
|
}
|
|
1863
|
+
function isConditionalReferencingAnyPickedField(condition, fieldsToPick) {
|
|
1864
|
+
const { if: ifCondition, then: thenCondition, else: elseCondition } = condition;
|
|
1865
|
+
const inIf = (0, import_intersection.default)(ifCondition.required, fieldsToPick);
|
|
1866
|
+
if (inIf.length > 0) {
|
|
1867
|
+
return true;
|
|
1868
|
+
}
|
|
1869
|
+
const inThen = (0, import_intersection.default)(thenCondition.required, fieldsToPick) || (0, import_intersection.default)(Object.keys(thenCondition.properties), fieldsToPick);
|
|
1870
|
+
if (inThen.length > 0) {
|
|
1871
|
+
return true;
|
|
1872
|
+
}
|
|
1873
|
+
const inElse = (0, import_intersection.default)(elseCondition.required, fieldsToPick) || (0, import_intersection.default)(Object.keys(elseCondition.properties), fieldsToPick);
|
|
1874
|
+
if (inElse.length > 0) {
|
|
1875
|
+
return true;
|
|
1876
|
+
}
|
|
1877
|
+
return false;
|
|
1878
|
+
}
|
|
1849
1879
|
function rewriteFields(schema, fieldsConfig) {
|
|
1850
1880
|
if (!fieldsConfig)
|
|
1851
|
-
return null;
|
|
1881
|
+
return { warnings: null };
|
|
1882
|
+
const warnings = [];
|
|
1852
1883
|
const fieldsToModify = Object.entries(fieldsConfig);
|
|
1853
1884
|
fieldsToModify.forEach(([shortPath, mutation]) => {
|
|
1854
1885
|
const fieldPath = shortToFullPath(shortPath);
|
|
1855
1886
|
if (!(0, import_get4.default)(schema.properties, fieldPath)) {
|
|
1887
|
+
warnings.push({
|
|
1888
|
+
type: WARNING_TYPES.FIELD_TO_CHANGE_NOT_FOUND,
|
|
1889
|
+
message: `Changing field "${shortPath}" was ignored because it does not exist.`
|
|
1890
|
+
});
|
|
1856
1891
|
return;
|
|
1857
1892
|
}
|
|
1858
1893
|
const fieldAttrs = (0, import_get4.default)(schema.properties, fieldPath);
|
|
1859
1894
|
const fieldChanges = typeof mutation === "function" ? mutation(fieldAttrs) : mutation;
|
|
1860
|
-
(0,
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1895
|
+
(0, import_mergeWith.default)(
|
|
1896
|
+
(0, import_get4.default)(schema.properties, fieldPath),
|
|
1897
|
+
{
|
|
1898
|
+
...fieldAttrs,
|
|
1899
|
+
...standardizeAttrs(fieldChanges)
|
|
1900
|
+
},
|
|
1901
|
+
mergeReplaceArray
|
|
1902
|
+
);
|
|
1864
1903
|
if (fieldChanges.properties) {
|
|
1865
|
-
rewriteFields((0, import_get4.default)(schema.properties, fieldPath), fieldChanges.properties);
|
|
1904
|
+
const result = rewriteFields((0, import_get4.default)(schema.properties, fieldPath), fieldChanges.properties);
|
|
1905
|
+
warnings.push(result.warnings);
|
|
1866
1906
|
}
|
|
1867
1907
|
});
|
|
1908
|
+
return { warnings: warnings.flat() };
|
|
1868
1909
|
}
|
|
1869
1910
|
function rewriteAllFields(schema, configCallback, context) {
|
|
1870
1911
|
if (!configCallback)
|
|
@@ -1872,10 +1913,14 @@ function rewriteAllFields(schema, configCallback, context) {
|
|
|
1872
1913
|
const parentName = context?.parent;
|
|
1873
1914
|
Object.entries(schema.properties).forEach(([fieldName, fieldAttrs]) => {
|
|
1874
1915
|
const fullName = parentName ? `${parentName}.${fieldName}` : fieldName;
|
|
1875
|
-
(0,
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1916
|
+
(0, import_mergeWith.default)(
|
|
1917
|
+
(0, import_get4.default)(schema.properties, fieldName),
|
|
1918
|
+
{
|
|
1919
|
+
...fieldAttrs,
|
|
1920
|
+
...configCallback(fullName, fieldAttrs)
|
|
1921
|
+
},
|
|
1922
|
+
mergeReplaceArray
|
|
1923
|
+
);
|
|
1879
1924
|
if (fieldAttrs.properties) {
|
|
1880
1925
|
rewriteAllFields(fieldAttrs, configCallback, {
|
|
1881
1926
|
parent: fieldName
|
|
@@ -1883,9 +1928,152 @@ function rewriteAllFields(schema, configCallback, context) {
|
|
|
1883
1928
|
}
|
|
1884
1929
|
});
|
|
1885
1930
|
}
|
|
1931
|
+
function reorderFields(schema, configOrder) {
|
|
1932
|
+
if (!configOrder)
|
|
1933
|
+
return { warnings: null };
|
|
1934
|
+
const warnings = [];
|
|
1935
|
+
const originalOrder = schema["x-jsf-order"] || [];
|
|
1936
|
+
const orderConfig = typeof configOrder === "function" ? configOrder(originalOrder) : configOrder;
|
|
1937
|
+
const remaining = (0, import_difference.default)(originalOrder, orderConfig);
|
|
1938
|
+
if (remaining.length > 0) {
|
|
1939
|
+
warnings.push({
|
|
1940
|
+
type: WARNING_TYPES.ORDER_MISSING_FIELDS,
|
|
1941
|
+
message: `Some fields got forgotten in the new order. They were automatically appended: ${remaining.join(
|
|
1942
|
+
", "
|
|
1943
|
+
)}`
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1946
|
+
schema["x-jsf-order"] = [...orderConfig, ...remaining];
|
|
1947
|
+
return { warnings };
|
|
1948
|
+
}
|
|
1949
|
+
function createFields(schema, fieldsConfig) {
|
|
1950
|
+
if (!fieldsConfig)
|
|
1951
|
+
return { warnings: null };
|
|
1952
|
+
const warnings = [];
|
|
1953
|
+
const fieldsToCreate = Object.entries(fieldsConfig);
|
|
1954
|
+
fieldsToCreate.forEach(([shortPath, fieldAttrs]) => {
|
|
1955
|
+
const fieldPath = shortToFullPath(shortPath);
|
|
1956
|
+
if (fieldAttrs.properties) {
|
|
1957
|
+
const result = createFields((0, import_get4.default)(schema.properties, fieldPath), fieldAttrs.properties);
|
|
1958
|
+
warnings.push(result.warnings);
|
|
1959
|
+
}
|
|
1960
|
+
const fieldInSchema = (0, import_get4.default)(schema.properties, fieldPath);
|
|
1961
|
+
if (fieldInSchema) {
|
|
1962
|
+
warnings.push({
|
|
1963
|
+
type: WARNING_TYPES.FIELD_TO_CREATE_EXISTS,
|
|
1964
|
+
message: `Creating field "${shortPath}" was ignored because it already exists.`
|
|
1965
|
+
});
|
|
1966
|
+
return;
|
|
1967
|
+
}
|
|
1968
|
+
const fieldInObjectPath = (0, import_set2.default)({}, fieldPath, standardizeAttrs(fieldAttrs));
|
|
1969
|
+
(0, import_merge3.default)(schema.properties, fieldInObjectPath);
|
|
1970
|
+
});
|
|
1971
|
+
return { warnings: warnings.flat() };
|
|
1972
|
+
}
|
|
1973
|
+
function pickFields(originalSchema, fieldsToPick) {
|
|
1974
|
+
if (!fieldsToPick) {
|
|
1975
|
+
return { schema: originalSchema, warnings: null };
|
|
1976
|
+
}
|
|
1977
|
+
const newSchema = {
|
|
1978
|
+
properties: {}
|
|
1979
|
+
};
|
|
1980
|
+
Object.entries(originalSchema).forEach(([attrKey, attrValue]) => {
|
|
1981
|
+
switch (attrKey) {
|
|
1982
|
+
case "properties":
|
|
1983
|
+
fieldsToPick.forEach((fieldPath) => {
|
|
1984
|
+
(0, import_set2.default)(newSchema.properties, fieldPath, attrValue[fieldPath]);
|
|
1985
|
+
});
|
|
1986
|
+
break;
|
|
1987
|
+
case "x-jsf-order":
|
|
1988
|
+
case "required":
|
|
1989
|
+
newSchema[attrKey] = attrValue.filter((fieldName) => fieldsToPick.includes(fieldName));
|
|
1990
|
+
break;
|
|
1991
|
+
case "allOf": {
|
|
1992
|
+
const newAllOf = originalSchema.allOf.filter(
|
|
1993
|
+
(condition) => isConditionalReferencingAnyPickedField(condition, fieldsToPick)
|
|
1994
|
+
);
|
|
1995
|
+
newSchema[attrKey] = newAllOf;
|
|
1996
|
+
break;
|
|
1997
|
+
}
|
|
1998
|
+
default:
|
|
1999
|
+
newSchema[attrKey] = attrValue;
|
|
2000
|
+
}
|
|
2001
|
+
});
|
|
2002
|
+
let missingFields = {};
|
|
2003
|
+
newSchema.allOf.forEach((condition) => {
|
|
2004
|
+
const { if: ifCondition, then: thenCondition, else: elseCondition } = condition;
|
|
2005
|
+
const index = originalSchema.allOf.indexOf(condition);
|
|
2006
|
+
missingFields = {
|
|
2007
|
+
...missingFields,
|
|
2008
|
+
...findMissingFields(ifCondition, {
|
|
2009
|
+
fields: fieldsToPick,
|
|
2010
|
+
path: `allOf[${index}].if`
|
|
2011
|
+
}),
|
|
2012
|
+
...findMissingFields(thenCondition, {
|
|
2013
|
+
fields: fieldsToPick,
|
|
2014
|
+
path: `allOf[${index}].then`
|
|
2015
|
+
}),
|
|
2016
|
+
...findMissingFields(elseCondition, {
|
|
2017
|
+
fields: fieldsToPick,
|
|
2018
|
+
path: `allOf[${index}].else`
|
|
2019
|
+
})
|
|
2020
|
+
};
|
|
2021
|
+
});
|
|
2022
|
+
const warnings = [];
|
|
2023
|
+
if (Object.keys(missingFields).length > 0) {
|
|
2024
|
+
Object.entries(missingFields).forEach(([fieldName]) => {
|
|
2025
|
+
(0, import_set2.default)(newSchema.properties, fieldName, originalSchema.properties[fieldName]);
|
|
2026
|
+
});
|
|
2027
|
+
warnings.push({
|
|
2028
|
+
type: WARNING_TYPES.PICK_MISSED_FIELD,
|
|
2029
|
+
message: `The picked fields are in conditionals that refeer other fields. They added automatically: ${Object.keys(
|
|
2030
|
+
missingFields
|
|
2031
|
+
).map((name) => `"${name}"`).join(", ")}. Check "meta" for more details.`,
|
|
2032
|
+
meta: missingFields
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
return { schema: newSchema, warnings };
|
|
2036
|
+
}
|
|
2037
|
+
function findMissingFields(conditional, { fields, path }) {
|
|
2038
|
+
if (!conditional) {
|
|
2039
|
+
return null;
|
|
2040
|
+
}
|
|
2041
|
+
let missingFields = {};
|
|
2042
|
+
conditional.required?.forEach((fieldName) => {
|
|
2043
|
+
if (!fields.includes(fieldName)) {
|
|
2044
|
+
missingFields[fieldName] = {
|
|
2045
|
+
path
|
|
2046
|
+
};
|
|
2047
|
+
}
|
|
2048
|
+
});
|
|
2049
|
+
Object.entries(conditional.properties || []).forEach(([fieldName]) => {
|
|
2050
|
+
if (!fields.includes(fieldName)) {
|
|
2051
|
+
missingFields[fieldName] = { path };
|
|
2052
|
+
}
|
|
2053
|
+
});
|
|
2054
|
+
return missingFields;
|
|
2055
|
+
}
|
|
1886
2056
|
function modify(originalSchema, config) {
|
|
1887
2057
|
const schema = JSON.parse(JSON.stringify(originalSchema));
|
|
1888
|
-
rewriteFields(schema, config.fields);
|
|
2058
|
+
const resultRewrite = rewriteFields(schema, config.fields);
|
|
1889
2059
|
rewriteAllFields(schema, config.allFields);
|
|
1890
|
-
|
|
2060
|
+
const resultCreate = createFields(schema, config.create);
|
|
2061
|
+
const resultPick = pickFields(schema, config.pick);
|
|
2062
|
+
const finalSchema = resultPick.schema;
|
|
2063
|
+
const resultReorder = reorderFields(finalSchema, config.orderRoot);
|
|
2064
|
+
if (!config.muteLogging) {
|
|
2065
|
+
console.warn(
|
|
2066
|
+
"json-schema-form modify(): We highly recommend you to handle/report the returned `warnings` as they highlight possible bugs in your modifications. To mute this log, pass `muteLogging: true` to the config."
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
const warnings = [
|
|
2070
|
+
resultRewrite.warnings,
|
|
2071
|
+
resultCreate.warnings,
|
|
2072
|
+
resultPick.warnings,
|
|
2073
|
+
resultReorder.warnings
|
|
2074
|
+
].flat().filter(Boolean);
|
|
2075
|
+
return {
|
|
2076
|
+
schema: finalSchema,
|
|
2077
|
+
warnings
|
|
2078
|
+
};
|
|
1891
2079
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2024 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.0-beta.0
|
|
5
|
+
Generated: Thu, 25 Jul 2024 16:43:12 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -1797,37 +1797,78 @@ function createHeadlessForm(jsonSchema, customConfig = {}) {
|
|
|
1797
1797
|
}
|
|
1798
1798
|
|
|
1799
1799
|
// src/modify.js
|
|
1800
|
+
import difference from "lodash/difference";
|
|
1800
1801
|
import get4 from "lodash/get";
|
|
1802
|
+
import intersection from "lodash/intersection";
|
|
1801
1803
|
import merge3 from "lodash/merge";
|
|
1804
|
+
import mergeWith from "lodash/mergeWith";
|
|
1805
|
+
import set2 from "lodash/set";
|
|
1806
|
+
var WARNING_TYPES = {
|
|
1807
|
+
FIELD_TO_CHANGE_NOT_FOUND: "FIELD_TO_CHANGE_NOT_FOUND",
|
|
1808
|
+
ORDER_MISSING_FIELDS: "ORDER_MISSING_FIELDS",
|
|
1809
|
+
FIELD_TO_CREATE_EXISTS: "FIELD_TO_CREATE_EXISTS",
|
|
1810
|
+
PICK_MISSED_FIELD: "PICK_MISSED_FIELD"
|
|
1811
|
+
};
|
|
1802
1812
|
function shortToFullPath(path) {
|
|
1803
1813
|
return path.replace(".", ".properties.");
|
|
1804
1814
|
}
|
|
1815
|
+
function mergeReplaceArray(_, newVal) {
|
|
1816
|
+
return Array.isArray(newVal) ? newVal : void 0;
|
|
1817
|
+
}
|
|
1805
1818
|
function standardizeAttrs(attrs) {
|
|
1806
|
-
const { errorMessage, properties, ...rest } = attrs;
|
|
1819
|
+
const { errorMessage, presentation, properties, ...rest } = attrs;
|
|
1807
1820
|
return {
|
|
1808
1821
|
...rest,
|
|
1822
|
+
...presentation ? { "x-jsf-presentation": presentation } : {},
|
|
1809
1823
|
...errorMessage ? { "x-jsf-errorMessage": errorMessage } : {}
|
|
1810
1824
|
};
|
|
1811
1825
|
}
|
|
1826
|
+
function isConditionalReferencingAnyPickedField(condition, fieldsToPick) {
|
|
1827
|
+
const { if: ifCondition, then: thenCondition, else: elseCondition } = condition;
|
|
1828
|
+
const inIf = intersection(ifCondition.required, fieldsToPick);
|
|
1829
|
+
if (inIf.length > 0) {
|
|
1830
|
+
return true;
|
|
1831
|
+
}
|
|
1832
|
+
const inThen = intersection(thenCondition.required, fieldsToPick) || intersection(Object.keys(thenCondition.properties), fieldsToPick);
|
|
1833
|
+
if (inThen.length > 0) {
|
|
1834
|
+
return true;
|
|
1835
|
+
}
|
|
1836
|
+
const inElse = intersection(elseCondition.required, fieldsToPick) || intersection(Object.keys(elseCondition.properties), fieldsToPick);
|
|
1837
|
+
if (inElse.length > 0) {
|
|
1838
|
+
return true;
|
|
1839
|
+
}
|
|
1840
|
+
return false;
|
|
1841
|
+
}
|
|
1812
1842
|
function rewriteFields(schema, fieldsConfig) {
|
|
1813
1843
|
if (!fieldsConfig)
|
|
1814
|
-
return null;
|
|
1844
|
+
return { warnings: null };
|
|
1845
|
+
const warnings = [];
|
|
1815
1846
|
const fieldsToModify = Object.entries(fieldsConfig);
|
|
1816
1847
|
fieldsToModify.forEach(([shortPath, mutation]) => {
|
|
1817
1848
|
const fieldPath = shortToFullPath(shortPath);
|
|
1818
1849
|
if (!get4(schema.properties, fieldPath)) {
|
|
1850
|
+
warnings.push({
|
|
1851
|
+
type: WARNING_TYPES.FIELD_TO_CHANGE_NOT_FOUND,
|
|
1852
|
+
message: `Changing field "${shortPath}" was ignored because it does not exist.`
|
|
1853
|
+
});
|
|
1819
1854
|
return;
|
|
1820
1855
|
}
|
|
1821
1856
|
const fieldAttrs = get4(schema.properties, fieldPath);
|
|
1822
1857
|
const fieldChanges = typeof mutation === "function" ? mutation(fieldAttrs) : mutation;
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1858
|
+
mergeWith(
|
|
1859
|
+
get4(schema.properties, fieldPath),
|
|
1860
|
+
{
|
|
1861
|
+
...fieldAttrs,
|
|
1862
|
+
...standardizeAttrs(fieldChanges)
|
|
1863
|
+
},
|
|
1864
|
+
mergeReplaceArray
|
|
1865
|
+
);
|
|
1827
1866
|
if (fieldChanges.properties) {
|
|
1828
|
-
rewriteFields(get4(schema.properties, fieldPath), fieldChanges.properties);
|
|
1867
|
+
const result = rewriteFields(get4(schema.properties, fieldPath), fieldChanges.properties);
|
|
1868
|
+
warnings.push(result.warnings);
|
|
1829
1869
|
}
|
|
1830
1870
|
});
|
|
1871
|
+
return { warnings: warnings.flat() };
|
|
1831
1872
|
}
|
|
1832
1873
|
function rewriteAllFields(schema, configCallback, context) {
|
|
1833
1874
|
if (!configCallback)
|
|
@@ -1835,10 +1876,14 @@ function rewriteAllFields(schema, configCallback, context) {
|
|
|
1835
1876
|
const parentName = context?.parent;
|
|
1836
1877
|
Object.entries(schema.properties).forEach(([fieldName, fieldAttrs]) => {
|
|
1837
1878
|
const fullName = parentName ? `${parentName}.${fieldName}` : fieldName;
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1879
|
+
mergeWith(
|
|
1880
|
+
get4(schema.properties, fieldName),
|
|
1881
|
+
{
|
|
1882
|
+
...fieldAttrs,
|
|
1883
|
+
...configCallback(fullName, fieldAttrs)
|
|
1884
|
+
},
|
|
1885
|
+
mergeReplaceArray
|
|
1886
|
+
);
|
|
1842
1887
|
if (fieldAttrs.properties) {
|
|
1843
1888
|
rewriteAllFields(fieldAttrs, configCallback, {
|
|
1844
1889
|
parent: fieldName
|
|
@@ -1846,11 +1891,154 @@ function rewriteAllFields(schema, configCallback, context) {
|
|
|
1846
1891
|
}
|
|
1847
1892
|
});
|
|
1848
1893
|
}
|
|
1894
|
+
function reorderFields(schema, configOrder) {
|
|
1895
|
+
if (!configOrder)
|
|
1896
|
+
return { warnings: null };
|
|
1897
|
+
const warnings = [];
|
|
1898
|
+
const originalOrder = schema["x-jsf-order"] || [];
|
|
1899
|
+
const orderConfig = typeof configOrder === "function" ? configOrder(originalOrder) : configOrder;
|
|
1900
|
+
const remaining = difference(originalOrder, orderConfig);
|
|
1901
|
+
if (remaining.length > 0) {
|
|
1902
|
+
warnings.push({
|
|
1903
|
+
type: WARNING_TYPES.ORDER_MISSING_FIELDS,
|
|
1904
|
+
message: `Some fields got forgotten in the new order. They were automatically appended: ${remaining.join(
|
|
1905
|
+
", "
|
|
1906
|
+
)}`
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
schema["x-jsf-order"] = [...orderConfig, ...remaining];
|
|
1910
|
+
return { warnings };
|
|
1911
|
+
}
|
|
1912
|
+
function createFields(schema, fieldsConfig) {
|
|
1913
|
+
if (!fieldsConfig)
|
|
1914
|
+
return { warnings: null };
|
|
1915
|
+
const warnings = [];
|
|
1916
|
+
const fieldsToCreate = Object.entries(fieldsConfig);
|
|
1917
|
+
fieldsToCreate.forEach(([shortPath, fieldAttrs]) => {
|
|
1918
|
+
const fieldPath = shortToFullPath(shortPath);
|
|
1919
|
+
if (fieldAttrs.properties) {
|
|
1920
|
+
const result = createFields(get4(schema.properties, fieldPath), fieldAttrs.properties);
|
|
1921
|
+
warnings.push(result.warnings);
|
|
1922
|
+
}
|
|
1923
|
+
const fieldInSchema = get4(schema.properties, fieldPath);
|
|
1924
|
+
if (fieldInSchema) {
|
|
1925
|
+
warnings.push({
|
|
1926
|
+
type: WARNING_TYPES.FIELD_TO_CREATE_EXISTS,
|
|
1927
|
+
message: `Creating field "${shortPath}" was ignored because it already exists.`
|
|
1928
|
+
});
|
|
1929
|
+
return;
|
|
1930
|
+
}
|
|
1931
|
+
const fieldInObjectPath = set2({}, fieldPath, standardizeAttrs(fieldAttrs));
|
|
1932
|
+
merge3(schema.properties, fieldInObjectPath);
|
|
1933
|
+
});
|
|
1934
|
+
return { warnings: warnings.flat() };
|
|
1935
|
+
}
|
|
1936
|
+
function pickFields(originalSchema, fieldsToPick) {
|
|
1937
|
+
if (!fieldsToPick) {
|
|
1938
|
+
return { schema: originalSchema, warnings: null };
|
|
1939
|
+
}
|
|
1940
|
+
const newSchema = {
|
|
1941
|
+
properties: {}
|
|
1942
|
+
};
|
|
1943
|
+
Object.entries(originalSchema).forEach(([attrKey, attrValue]) => {
|
|
1944
|
+
switch (attrKey) {
|
|
1945
|
+
case "properties":
|
|
1946
|
+
fieldsToPick.forEach((fieldPath) => {
|
|
1947
|
+
set2(newSchema.properties, fieldPath, attrValue[fieldPath]);
|
|
1948
|
+
});
|
|
1949
|
+
break;
|
|
1950
|
+
case "x-jsf-order":
|
|
1951
|
+
case "required":
|
|
1952
|
+
newSchema[attrKey] = attrValue.filter((fieldName) => fieldsToPick.includes(fieldName));
|
|
1953
|
+
break;
|
|
1954
|
+
case "allOf": {
|
|
1955
|
+
const newAllOf = originalSchema.allOf.filter(
|
|
1956
|
+
(condition) => isConditionalReferencingAnyPickedField(condition, fieldsToPick)
|
|
1957
|
+
);
|
|
1958
|
+
newSchema[attrKey] = newAllOf;
|
|
1959
|
+
break;
|
|
1960
|
+
}
|
|
1961
|
+
default:
|
|
1962
|
+
newSchema[attrKey] = attrValue;
|
|
1963
|
+
}
|
|
1964
|
+
});
|
|
1965
|
+
let missingFields = {};
|
|
1966
|
+
newSchema.allOf.forEach((condition) => {
|
|
1967
|
+
const { if: ifCondition, then: thenCondition, else: elseCondition } = condition;
|
|
1968
|
+
const index = originalSchema.allOf.indexOf(condition);
|
|
1969
|
+
missingFields = {
|
|
1970
|
+
...missingFields,
|
|
1971
|
+
...findMissingFields(ifCondition, {
|
|
1972
|
+
fields: fieldsToPick,
|
|
1973
|
+
path: `allOf[${index}].if`
|
|
1974
|
+
}),
|
|
1975
|
+
...findMissingFields(thenCondition, {
|
|
1976
|
+
fields: fieldsToPick,
|
|
1977
|
+
path: `allOf[${index}].then`
|
|
1978
|
+
}),
|
|
1979
|
+
...findMissingFields(elseCondition, {
|
|
1980
|
+
fields: fieldsToPick,
|
|
1981
|
+
path: `allOf[${index}].else`
|
|
1982
|
+
})
|
|
1983
|
+
};
|
|
1984
|
+
});
|
|
1985
|
+
const warnings = [];
|
|
1986
|
+
if (Object.keys(missingFields).length > 0) {
|
|
1987
|
+
Object.entries(missingFields).forEach(([fieldName]) => {
|
|
1988
|
+
set2(newSchema.properties, fieldName, originalSchema.properties[fieldName]);
|
|
1989
|
+
});
|
|
1990
|
+
warnings.push({
|
|
1991
|
+
type: WARNING_TYPES.PICK_MISSED_FIELD,
|
|
1992
|
+
message: `The picked fields are in conditionals that refeer other fields. They added automatically: ${Object.keys(
|
|
1993
|
+
missingFields
|
|
1994
|
+
).map((name) => `"${name}"`).join(", ")}. Check "meta" for more details.`,
|
|
1995
|
+
meta: missingFields
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
return { schema: newSchema, warnings };
|
|
1999
|
+
}
|
|
2000
|
+
function findMissingFields(conditional, { fields, path }) {
|
|
2001
|
+
if (!conditional) {
|
|
2002
|
+
return null;
|
|
2003
|
+
}
|
|
2004
|
+
let missingFields = {};
|
|
2005
|
+
conditional.required?.forEach((fieldName) => {
|
|
2006
|
+
if (!fields.includes(fieldName)) {
|
|
2007
|
+
missingFields[fieldName] = {
|
|
2008
|
+
path
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
});
|
|
2012
|
+
Object.entries(conditional.properties || []).forEach(([fieldName]) => {
|
|
2013
|
+
if (!fields.includes(fieldName)) {
|
|
2014
|
+
missingFields[fieldName] = { path };
|
|
2015
|
+
}
|
|
2016
|
+
});
|
|
2017
|
+
return missingFields;
|
|
2018
|
+
}
|
|
1849
2019
|
function modify(originalSchema, config) {
|
|
1850
2020
|
const schema = JSON.parse(JSON.stringify(originalSchema));
|
|
1851
|
-
rewriteFields(schema, config.fields);
|
|
2021
|
+
const resultRewrite = rewriteFields(schema, config.fields);
|
|
1852
2022
|
rewriteAllFields(schema, config.allFields);
|
|
1853
|
-
|
|
2023
|
+
const resultCreate = createFields(schema, config.create);
|
|
2024
|
+
const resultPick = pickFields(schema, config.pick);
|
|
2025
|
+
const finalSchema = resultPick.schema;
|
|
2026
|
+
const resultReorder = reorderFields(finalSchema, config.orderRoot);
|
|
2027
|
+
if (!config.muteLogging) {
|
|
2028
|
+
console.warn(
|
|
2029
|
+
"json-schema-form modify(): We highly recommend you to handle/report the returned `warnings` as they highlight possible bugs in your modifications. To mute this log, pass `muteLogging: true` to the config."
|
|
2030
|
+
);
|
|
2031
|
+
}
|
|
2032
|
+
const warnings = [
|
|
2033
|
+
resultRewrite.warnings,
|
|
2034
|
+
resultCreate.warnings,
|
|
2035
|
+
resultPick.warnings,
|
|
2036
|
+
resultReorder.warnings
|
|
2037
|
+
].flat().filter(Boolean);
|
|
2038
|
+
return {
|
|
2039
|
+
schema: finalSchema,
|
|
2040
|
+
warnings
|
|
2041
|
+
};
|
|
1854
2042
|
}
|
|
1855
2043
|
export {
|
|
1856
2044
|
buildCompleteYupSchema,
|