@nolwenture/formik-jsonschema-form 0.7.1 → 0.9.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/README.md +176 -1
- package/dist/Form.js +2 -1
- package/dist/Form.stories.d.ts +2 -0
- package/dist/Form.stories.js +15 -0
- package/dist/Form.test.d.ts +1 -1
- package/dist/Form.test.js +3 -1
- package/dist/fields/ArrayField.js +2 -1
- package/dist/fields/MultipleChoiceField.d.ts +3 -0
- package/dist/fields/MultipleChoiceField.js +13 -0
- package/dist/fields/ObjectField.js +3 -1
- package/dist/fields/SchemaField.js +7 -5
- package/dist/fields/StringField.js +1 -1
- package/dist/fields/index.d.ts +1 -0
- package/dist/fields/index.js +1 -0
- package/dist/fields/stories/AnyField.stories.d.ts +5 -0
- package/dist/fields/stories/AnyField.stories.js +79 -0
- package/dist/fields/stories/ArrayField.stories.d.ts +7 -0
- package/dist/fields/stories/ArrayField.stories.js +191 -0
- package/dist/fields/stories/BooleanField.stories.d.ts +5 -0
- package/dist/fields/stories/BooleanField.stories.js +36 -0
- package/dist/fields/stories/DateField.stories.d.ts +5 -0
- package/dist/fields/stories/DateField.stories.js +34 -0
- package/dist/fields/stories/NullField.stories.d.ts +5 -0
- package/dist/fields/stories/NullField.stories.js +38 -0
- package/dist/fields/stories/NumberField.stories.d.ts +5 -0
- package/dist/fields/stories/NumberField.stories.js +33 -0
- package/dist/fields/stories/ObjectField.stories.d.ts +5 -0
- package/dist/fields/stories/ObjectField.stories.js +76 -0
- package/dist/fields/stories/RadioField.stories.d.ts +5 -0
- package/dist/fields/stories/RadioField.stories.js +42 -0
- package/dist/fields/stories/SchemaField.stories.d.ts +1716 -0
- package/dist/fields/stories/SchemaField.stories.js +85 -0
- package/dist/fields/stories/SearchMultiTagSelectField.stories.d.ts +5 -0
- package/dist/fields/stories/SearchMultiTagSelectField.stories.js +58 -0
- package/dist/fields/stories/StringField.stories.d.ts +7 -0
- package/dist/fields/stories/StringField.stories.js +75 -0
- package/dist/fields/stories/ToggleField.stories.d.ts +5 -0
- package/dist/fields/stories/ToggleField.stories.js +34 -0
- package/dist/formEditorSchemas.js +177 -21
- package/dist/hooks/__tests__/useExtractUiSchema.test.d.ts +1 -0
- package/dist/hooks/__tests__/useExtractUiSchema.test.js +45 -0
- package/dist/hooks/__tests__/useSetDefault.test.d.ts +1 -0
- package/dist/hooks/__tests__/useSetDefault.test.js +65 -0
- package/dist/hooks/useExtractUiSchema.js +7 -3
- package/dist/sampleData/ageFieldDefinition.d.ts +2 -0
- package/dist/sampleData/ageFieldDefinition.js +5 -0
- package/dist/sampleData/multipleChoiceSchema.d.ts +3 -0
- package/dist/sampleData/multipleChoiceSchema.js +112 -0
- package/dist/sampleData/refDefSchema.d.ts +3 -0
- package/dist/sampleData/refDefSchema.js +219 -0
- package/dist/sampleData/requiredInputSchema.js +0 -5
- package/dist/styledComponents.d.ts +2 -1
- package/dist/styledComponents.js +8 -0
- package/dist/types.d.ts +19 -2
- package/dist/utils/__tests/createInitialValues.test.d.ts +1 -0
- package/dist/utils/__tests/createInitialValues.test.js +72 -0
- package/dist/utils/__tests/deepOverlap.test.d.ts +1 -0
- package/dist/utils/__tests/deepOverlap.test.js +41 -0
- package/dist/utils/__tests/getEnums.test.js +11 -16
- package/dist/utils/__tests/getTitleAndDescription.test.d.ts +1 -0
- package/dist/utils/__tests/getTitleAndDescription.test.js +53 -0
- package/dist/utils/__tests/getTypes.test.d.ts +1 -0
- package/dist/utils/__tests/getTypes.test.js +62 -0
- package/dist/utils/__tests/mergeSchemas.test.d.ts +1 -0
- package/dist/utils/__tests/mergeSchemas.test.js +40 -0
- package/dist/utils/__tests/resolveSchema.test.js +43 -33
- package/dist/utils/__tests/solveReferences.test.d.ts +1 -0
- package/dist/utils/__tests/solveReferences.test.js +12 -0
- package/dist/utils/__tests/testSchemas.d.ts +4 -0
- package/dist/utils/__tests/testSchemas.js +67 -0
- package/dist/utils/createInitialValues.d.ts +4 -0
- package/dist/utils/createInitialValues.js +27 -0
- package/dist/utils/getStyle.d.ts +5 -0
- package/dist/utils/getStyle.js +18 -0
- package/dist/utils/getTypes.js +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/resolveSchema.d.ts +1 -1
- package/dist/utils/resolveSchema.js +88 -39
- package/dist/utils/solveReferences.d.ts +2 -0
- package/dist/utils/solveReferences.js +8 -0
- package/package.json +5 -2
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getTitle, getDescription } from "../getTitleAndDescription";
|
|
2
|
+
describe("getTitleAndDescription", () => {
|
|
3
|
+
describe("getTitle", () => {
|
|
4
|
+
test("returns title when provided", () => {
|
|
5
|
+
const title = "Test Title";
|
|
6
|
+
expect(getTitle({ title })).toBe(title);
|
|
7
|
+
});
|
|
8
|
+
test("returns title from uiSchema options when provided", () => {
|
|
9
|
+
const uiSchema = {
|
|
10
|
+
"ui:options": { title: "UI Schema Title" },
|
|
11
|
+
};
|
|
12
|
+
expect(getTitle({ uiSchema })).toBe("UI Schema Title");
|
|
13
|
+
});
|
|
14
|
+
test("returns title from uiSchema title when provided", () => {
|
|
15
|
+
const uiSchema = { "ui:title": "UI Schema Title" };
|
|
16
|
+
expect(getTitle({ uiSchema })).toBe("UI Schema Title");
|
|
17
|
+
});
|
|
18
|
+
test("returns title from schema when provided", () => {
|
|
19
|
+
const schema = { title: "Schema Title" };
|
|
20
|
+
expect(getTitle({ schema })).toBe("Schema Title");
|
|
21
|
+
});
|
|
22
|
+
test("returns last part of name when provided", () => {
|
|
23
|
+
const name = "nested.property";
|
|
24
|
+
expect(getTitle({ name })).toBe("property");
|
|
25
|
+
});
|
|
26
|
+
test("returns undefined when no title is provided", () => {
|
|
27
|
+
expect(getTitle({})).toBeUndefined();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("getDescription", () => {
|
|
31
|
+
test("returns description when provided", () => {
|
|
32
|
+
const description = "Test Description";
|
|
33
|
+
expect(getDescription({ description })).toBe(description);
|
|
34
|
+
});
|
|
35
|
+
test("returns description from uiSchema options when provided", () => {
|
|
36
|
+
const uiSchema = {
|
|
37
|
+
"ui:options": { description: "UI Schema Description" },
|
|
38
|
+
};
|
|
39
|
+
expect(getDescription({ uiSchema })).toBe("UI Schema Description");
|
|
40
|
+
});
|
|
41
|
+
test("returns description from uiSchema description when provided", () => {
|
|
42
|
+
const uiSchema = { "ui:description": "UI Schema Description" };
|
|
43
|
+
expect(getDescription({ uiSchema })).toBe("UI Schema Description");
|
|
44
|
+
});
|
|
45
|
+
test("returns description from schema when provided", () => {
|
|
46
|
+
const schema = { description: "Schema Description" };
|
|
47
|
+
expect(getDescription({ schema })).toBe("Schema Description");
|
|
48
|
+
});
|
|
49
|
+
test("returns undefined when no description is provided", () => {
|
|
50
|
+
expect(getDescription({})).toBeUndefined();
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { isObject, getDefaultValueForType, guessType, getSchemaType, } from "../getTypes";
|
|
2
|
+
describe("getTypes", () => {
|
|
3
|
+
describe("isObject", () => {
|
|
4
|
+
test("returns true for non-null objects", () => {
|
|
5
|
+
expect(isObject({})).toBe(true);
|
|
6
|
+
expect(isObject([])).toBe(true);
|
|
7
|
+
});
|
|
8
|
+
test("returns false for null", () => {
|
|
9
|
+
expect(isObject(null)).toBe(false);
|
|
10
|
+
});
|
|
11
|
+
test("returns false for non-object types", () => {
|
|
12
|
+
expect(isObject(42)).toBe(false);
|
|
13
|
+
expect(isObject("string")).toBe(false);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe("getDefaultValueForType", () => {
|
|
17
|
+
test("returns empty array for 'array' type", () => {
|
|
18
|
+
expect(getDefaultValueForType("array")).toEqual([]);
|
|
19
|
+
});
|
|
20
|
+
test("returns empty object for 'object' type", () => {
|
|
21
|
+
expect(getDefaultValueForType("object")).toEqual({});
|
|
22
|
+
});
|
|
23
|
+
test("returns null for unspecified or complex types", () => {
|
|
24
|
+
expect(getDefaultValueForType("string")).toBeNull();
|
|
25
|
+
expect(getDefaultValueForType(["string", "null"])).toBeNull();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe("guessType", () => {
|
|
29
|
+
test("correctly guesses basic types", () => {
|
|
30
|
+
expect(guessType([])).toBe("array");
|
|
31
|
+
expect(guessType("test")).toBe("string");
|
|
32
|
+
expect(guessType(42)).toBe("number");
|
|
33
|
+
expect(guessType(true)).toBe("boolean");
|
|
34
|
+
expect(guessType(null)).toBe("null");
|
|
35
|
+
expect(guessType({})).toBe("object");
|
|
36
|
+
});
|
|
37
|
+
test("defaults to 'string' for unrecognized values", () => {
|
|
38
|
+
expect(guessType(() => { })).toBe("string");
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("getSchemaType", () => {
|
|
42
|
+
test("returns the explicit type if provided", () => {
|
|
43
|
+
expect(getSchemaType({ type: "number" })).toBe("number");
|
|
44
|
+
});
|
|
45
|
+
test("guesses the type based on const values", () => {
|
|
46
|
+
expect(getSchemaType({ const: 42 })).toBe("number");
|
|
47
|
+
});
|
|
48
|
+
test("returns 'string' for enums", () => {
|
|
49
|
+
expect(getSchemaType({ enum: ["one", "two"] })).toBe("string");
|
|
50
|
+
});
|
|
51
|
+
test("returns 'object' for schemas with properties or additionalProperties", () => {
|
|
52
|
+
expect(getSchemaType({ properties: { a: { type: "number" } } })).toBe("object");
|
|
53
|
+
expect(getSchemaType({ additionalProperties: { type: "number" } })).toBe("object");
|
|
54
|
+
});
|
|
55
|
+
test('handles array types, excluding "null" when paired with another type', () => {
|
|
56
|
+
expect(getSchemaType({ type: ["number", "null"] })).toBe("number");
|
|
57
|
+
});
|
|
58
|
+
test("returns undefined for empty or invalid schemas", () => {
|
|
59
|
+
expect(getSchemaType({})).toBeUndefined();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { mergeSchemas } from "../mergeSchemas";
|
|
2
|
+
describe("mergeSchemas", () => {
|
|
3
|
+
test("merges simple objects without overlap", () => {
|
|
4
|
+
const obj1 = { a: 1 };
|
|
5
|
+
const obj2 = { b: 2 };
|
|
6
|
+
expect(mergeSchemas(obj1, obj2)).toEqual({ a: 1, b: 2 });
|
|
7
|
+
});
|
|
8
|
+
test("merges objects with nested objects", () => {
|
|
9
|
+
const obj1 = { a: { b: 1 } };
|
|
10
|
+
const obj2 = { a: { c: 2 }, d: 3 };
|
|
11
|
+
expect(mergeSchemas(obj1, obj2)).toEqual({ a: { b: 1, c: 2 }, d: 3 });
|
|
12
|
+
});
|
|
13
|
+
test("handles merging with overlapping keys", () => {
|
|
14
|
+
const obj1 = { a: 1, b: 2 };
|
|
15
|
+
const obj2 = { a: 3, c: 4 };
|
|
16
|
+
expect(mergeSchemas(obj1, obj2)).toEqual({ a: 3, b: 2, c: 4 });
|
|
17
|
+
});
|
|
18
|
+
test("merges schemas with arrays (ensuring arrays are replaced, not merged)", () => {
|
|
19
|
+
const obj1 = { a: [1, 2], b: "string" };
|
|
20
|
+
const obj2 = { a: [3, 4] };
|
|
21
|
+
expect(mergeSchemas(obj1, obj2)).toEqual({ a: [3, 4], b: "string" });
|
|
22
|
+
});
|
|
23
|
+
test("deep merges nested objects", () => {
|
|
24
|
+
const obj1 = { a: { b: { c: 1 } } };
|
|
25
|
+
const obj2 = { a: { b: { d: 2 }, e: 3 } };
|
|
26
|
+
expect(mergeSchemas(obj1, obj2)).toEqual({
|
|
27
|
+
a: { b: { c: 1, d: 2 }, e: 3 },
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
test("retains the more specific type when merging schemas with different types", () => {
|
|
31
|
+
const obj1 = { type: ["null", "number"] };
|
|
32
|
+
const obj2 = { type: "number" };
|
|
33
|
+
expect(mergeSchemas(obj1, obj2)).toEqual({ type: "number" });
|
|
34
|
+
});
|
|
35
|
+
test("returns the second object if the first one is null or undefined", () => {
|
|
36
|
+
const obj1 = null;
|
|
37
|
+
const obj2 = { a: 1 };
|
|
38
|
+
expect(mergeSchemas(obj1, obj2)).toEqual({ a: 1 });
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -1,36 +1,7 @@
|
|
|
1
1
|
import { resolveSchema } from "../resolveSchema";
|
|
2
|
-
|
|
3
|
-
type: "object",
|
|
4
|
-
title: "Title",
|
|
5
|
-
properties: {
|
|
6
|
-
animal: {
|
|
7
|
-
type: "string",
|
|
8
|
-
enum: ["cat", "bird"],
|
|
9
|
-
},
|
|
10
|
-
},
|
|
11
|
-
allOf: [
|
|
12
|
-
{
|
|
13
|
-
if: {
|
|
14
|
-
properties: {
|
|
15
|
-
animal: {
|
|
16
|
-
const: "cat",
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
then: {
|
|
21
|
-
properties: {
|
|
22
|
-
food: {
|
|
23
|
-
type: "string",
|
|
24
|
-
enum: ["meat", "grass", "fish"],
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
required: ["food"],
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
],
|
|
31
|
-
};
|
|
2
|
+
import { schemaWithDependenciesAndOneOf, simpleConditionalSchema, } from "./testSchemas";
|
|
32
3
|
describe("resolveSchema", () => {
|
|
33
|
-
test("
|
|
4
|
+
test("adds conditional properties when condition is met", () => {
|
|
34
5
|
const value = { animal: "cat" };
|
|
35
6
|
const resolvedSchema = resolveSchema(simpleConditionalSchema, value);
|
|
36
7
|
expect(resolvedSchema).toEqual([
|
|
@@ -52,7 +23,7 @@ describe("resolveSchema", () => {
|
|
|
52
23
|
[],
|
|
53
24
|
]);
|
|
54
25
|
});
|
|
55
|
-
test("
|
|
26
|
+
test("does not add conditional properties when condition is not met", () => {
|
|
56
27
|
const value = { animal: "bird" };
|
|
57
28
|
const resolvedSchema = resolveSchema(simpleConditionalSchema, value);
|
|
58
29
|
expect(resolvedSchema).toEqual([
|
|
@@ -69,7 +40,7 @@ describe("resolveSchema", () => {
|
|
|
69
40
|
[],
|
|
70
41
|
]);
|
|
71
42
|
});
|
|
72
|
-
test("
|
|
43
|
+
test("does not add conditional properties when no value is provided", () => {
|
|
73
44
|
const value = {};
|
|
74
45
|
const resolvedSchema = resolveSchema(simpleConditionalSchema, value);
|
|
75
46
|
expect(resolvedSchema).toEqual([
|
|
@@ -103,4 +74,43 @@ describe("resolveSchema", () => {
|
|
|
103
74
|
["food"],
|
|
104
75
|
]);
|
|
105
76
|
});
|
|
77
|
+
test("selects the correct oneOf schema based on the type dependency", () => {
|
|
78
|
+
const valueCar = { type: "car" };
|
|
79
|
+
const resolvedCarSchema = resolveSchema(schemaWithDependenciesAndOneOf, valueCar);
|
|
80
|
+
expect(resolvedCarSchema).toEqual([
|
|
81
|
+
{
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
type: { type: "string", enum: ["car", "bike"] },
|
|
85
|
+
wheels: { type: "number", enum: [4] },
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
[],
|
|
89
|
+
]);
|
|
90
|
+
const valueBike = { type: "bike" };
|
|
91
|
+
const resolvedBikeSchema = resolveSchema(schemaWithDependenciesAndOneOf, valueBike);
|
|
92
|
+
expect(resolvedBikeSchema).toEqual([
|
|
93
|
+
{
|
|
94
|
+
type: "object",
|
|
95
|
+
properties: {
|
|
96
|
+
type: { type: "string", enum: ["car", "bike"] },
|
|
97
|
+
wheels: { type: "number", enum: [2] },
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
[],
|
|
101
|
+
]);
|
|
102
|
+
});
|
|
103
|
+
test("handles missing dependencies", () => {
|
|
104
|
+
const valueEmpty = {};
|
|
105
|
+
const resolvedEmptySchema = resolveSchema(schemaWithDependenciesAndOneOf, valueEmpty);
|
|
106
|
+
expect(resolvedEmptySchema).toEqual([
|
|
107
|
+
{
|
|
108
|
+
type: "object",
|
|
109
|
+
properties: {
|
|
110
|
+
type: { type: "string", enum: ["car", "bike"] },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
[],
|
|
114
|
+
]);
|
|
115
|
+
});
|
|
106
116
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { solveReferences } from "../solveReferences";
|
|
2
|
+
import { refDefSchema } from "./testSchemas";
|
|
3
|
+
describe("solveReferences", () => {
|
|
4
|
+
it("should resolve simple references correctly", () => {
|
|
5
|
+
var _a;
|
|
6
|
+
const schemaSolvedForReferences = solveReferences((_a = refDefSchema === null || refDefSchema === void 0 ? void 0 : refDefSchema.properties) === null || _a === void 0 ? void 0 : _a.name, refDefSchema.definitions);
|
|
7
|
+
expect(schemaSolvedForReferences).toEqual({
|
|
8
|
+
type: "string",
|
|
9
|
+
title: "Name",
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export const refDefSchema = {
|
|
2
|
+
title: "References and Definitions",
|
|
3
|
+
type: "object",
|
|
4
|
+
required: ["string"],
|
|
5
|
+
properties: {
|
|
6
|
+
name: {
|
|
7
|
+
$ref: "#/definitions/name",
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
definitions: {
|
|
11
|
+
name: { type: "string", title: "Name" },
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export const simpleConditionalSchema = {
|
|
15
|
+
type: "object",
|
|
16
|
+
title: "Title",
|
|
17
|
+
properties: {
|
|
18
|
+
animal: {
|
|
19
|
+
type: "string",
|
|
20
|
+
enum: ["cat", "bird"],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
allOf: [
|
|
24
|
+
{
|
|
25
|
+
if: {
|
|
26
|
+
properties: {
|
|
27
|
+
animal: {
|
|
28
|
+
const: "cat",
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
then: {
|
|
33
|
+
properties: {
|
|
34
|
+
food: {
|
|
35
|
+
type: "string",
|
|
36
|
+
enum: ["meat", "grass", "fish"],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["food"],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
export const schemaWithDependenciesAndOneOf = {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
type: { type: "string", enum: ["car", "bike"] },
|
|
48
|
+
},
|
|
49
|
+
dependencies: {
|
|
50
|
+
type: {
|
|
51
|
+
oneOf: [
|
|
52
|
+
{
|
|
53
|
+
properties: {
|
|
54
|
+
type: { enum: ["car"] },
|
|
55
|
+
wheels: { type: "number", enum: [4] },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
properties: {
|
|
60
|
+
type: { enum: ["bike"] },
|
|
61
|
+
wheels: { type: "number", enum: [2] },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function createInitialValues(schema) {
|
|
2
|
+
if (!schema) {
|
|
3
|
+
return {};
|
|
4
|
+
}
|
|
5
|
+
if (schema.properties) {
|
|
6
|
+
return Object.keys(schema === null || schema === void 0 ? void 0 : schema.properties).reduce((acc, key) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const value = (_a = schema === null || schema === void 0 ? void 0 : schema.properties) === null || _a === void 0 ? void 0 : _a[key];
|
|
9
|
+
return Object.assign(Object.assign({}, acc), { [key]: createInitialValues(value) });
|
|
10
|
+
}, {});
|
|
11
|
+
}
|
|
12
|
+
const type = schema.type;
|
|
13
|
+
switch (type) {
|
|
14
|
+
case "array":
|
|
15
|
+
return [];
|
|
16
|
+
case "boolean":
|
|
17
|
+
return false;
|
|
18
|
+
case "null":
|
|
19
|
+
return "";
|
|
20
|
+
case "number":
|
|
21
|
+
return 0;
|
|
22
|
+
case "string":
|
|
23
|
+
return "";
|
|
24
|
+
default:
|
|
25
|
+
throw new Error("Unsupported schema type");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function getStyle(key) {
|
|
2
|
+
const style = {};
|
|
3
|
+
if (key === "inline") {
|
|
4
|
+
style.display = "inline-grid";
|
|
5
|
+
}
|
|
6
|
+
if (key === "oneColumn") {
|
|
7
|
+
style.display = "grid";
|
|
8
|
+
}
|
|
9
|
+
if (key === "twoColumns") {
|
|
10
|
+
style.display = "grid";
|
|
11
|
+
style["grid-template-columns"] = "1fr 1fr";
|
|
12
|
+
}
|
|
13
|
+
if (key === "threeColumns") {
|
|
14
|
+
style.display = "grid";
|
|
15
|
+
style["grid-template-columns"] = "1fr 1fr 1fr";
|
|
16
|
+
}
|
|
17
|
+
return style;
|
|
18
|
+
}
|
package/dist/utils/getTypes.js
CHANGED
package/dist/utils/index.d.ts
CHANGED
|
@@ -4,4 +4,6 @@ export * from "./getTitleAndDescription";
|
|
|
4
4
|
export * from "./getTypes";
|
|
5
5
|
export * from "./mergeSchemas";
|
|
6
6
|
export * from "./resolveSchema";
|
|
7
|
+
export * from "./solveReferences";
|
|
8
|
+
export * from "./createInitialValues";
|
|
7
9
|
export declare const warnFromUnsupportedKeys: (componentName: string, data: Record<string, any>, supportedKeys: string[]) => void;
|
package/dist/utils/index.js
CHANGED
|
@@ -4,6 +4,8 @@ export * from "./getTitleAndDescription";
|
|
|
4
4
|
export * from "./getTypes";
|
|
5
5
|
export * from "./mergeSchemas";
|
|
6
6
|
export * from "./resolveSchema";
|
|
7
|
+
export * from "./solveReferences";
|
|
8
|
+
export * from "./createInitialValues";
|
|
7
9
|
//TODO: REMOVE WHEN ALL SUPPORTED
|
|
8
10
|
export const warnFromUnsupportedKeys = (componentName, data, supportedKeys) => {
|
|
9
11
|
Object.keys(data).forEach((key) => {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Schema } from "../types";
|
|
2
|
-
export declare const resolveSchema: ({ allOf, ...schema }: Schema, value: Record<string, any>) => [Schema, string[]];
|
|
2
|
+
export declare const resolveSchema: ({ allOf, dependencies, ...schema }: Schema, value: Record<string, any>) => [Schema, string[]];
|
|
@@ -19,50 +19,99 @@ const resolveEquality = (value, expression) => {
|
|
|
19
19
|
};
|
|
20
20
|
return deepOverlap(expression, newObject);
|
|
21
21
|
};
|
|
22
|
+
function resolveOneOfValue(value) {
|
|
23
|
+
var _a;
|
|
24
|
+
if (typeof value !== "boolean" && ((_a = value.enum) === null || _a === void 0 ? void 0 : _a[0]) !== undefined) {
|
|
25
|
+
return value.enum[0];
|
|
26
|
+
}
|
|
27
|
+
else if (value === true || value === false) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
else
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const resolveSelectedOneOfValue = (key, value, oneOf) => {
|
|
34
|
+
const update = oneOf.findIndex((one) => resolveOneOfValue(one.properties[key]) === value[key]);
|
|
35
|
+
const manipulatedUpdateValue = Object.keys(oneOf[update].properties)
|
|
36
|
+
.filter((objKey) => objKey !== key)
|
|
37
|
+
.reduce((newObj, innerKey) => {
|
|
38
|
+
newObj[innerKey] = oneOf[update].properties[innerKey];
|
|
39
|
+
return newObj;
|
|
40
|
+
}, {});
|
|
41
|
+
return { properties: manipulatedUpdateValue };
|
|
42
|
+
};
|
|
22
43
|
export const resolveSchema = (_a, value) => {
|
|
23
|
-
var _b;
|
|
24
|
-
var { allOf } = _a, schema = __rest(_a, ["allOf"]);
|
|
25
|
-
|
|
26
|
-
|
|
44
|
+
var _b, _c;
|
|
45
|
+
var { allOf, dependencies } = _a, schema = __rest(_a, ["allOf", "dependencies"]);
|
|
46
|
+
let schemaCopy = schema;
|
|
47
|
+
let valuesToRemoveDeps = [];
|
|
48
|
+
let valuesToRemoveAllOf = [];
|
|
49
|
+
if (dependencies) {
|
|
50
|
+
schemaCopy = Object.entries(dependencies).reduce((schema, [key, dependency]) => {
|
|
51
|
+
if (value[key] !== undefined && value[key] !== "") {
|
|
52
|
+
const oneOf = dependency.oneOf;
|
|
53
|
+
if (Array.isArray(oneOf) && oneOf !== undefined) {
|
|
54
|
+
const selectedOneOf = resolveSelectedOneOfValue(key, value, oneOf);
|
|
55
|
+
return mergeSchemas(schema, selectedOneOf);
|
|
56
|
+
}
|
|
57
|
+
return mergeSchemas(schema, dependency);
|
|
58
|
+
}
|
|
59
|
+
return schema;
|
|
60
|
+
}, schemaCopy);
|
|
27
61
|
}
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
if (!
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
const { if: expression, then, else: otherwise } = current, resolvedSchemaLessConditional = __rest(current, ["if", "then", "else"]);
|
|
34
|
-
if (!expression || typeof expression === "boolean") {
|
|
35
|
-
return {
|
|
36
|
-
resolvedSchema: mergeSchemas(resolvedSchema, resolvedSchemaLessConditional),
|
|
37
|
-
notAddedProperties,
|
|
38
|
-
};
|
|
62
|
+
const usedProperties = Object.keys((_b = schemaCopy.properties) !== null && _b !== void 0 ? _b : {});
|
|
63
|
+
Object.keys(value).map((key) => {
|
|
64
|
+
if (!usedProperties.includes(key)) {
|
|
65
|
+
valuesToRemoveDeps.push(key);
|
|
39
66
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
67
|
+
});
|
|
68
|
+
if (!allOf && dependencies) {
|
|
69
|
+
return [schemaCopy, valuesToRemoveDeps];
|
|
70
|
+
}
|
|
71
|
+
if (allOf) {
|
|
72
|
+
const { resolvedSchema, notAddedProperties } = allOf.reduce(({ resolvedSchema, notAddedProperties }, current) => {
|
|
73
|
+
var _a, _b;
|
|
74
|
+
if (!current || typeof current === "boolean") {
|
|
75
|
+
return { resolvedSchema, notAddedProperties };
|
|
43
76
|
}
|
|
44
|
-
if
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
77
|
+
const { if: expression, then, else: otherwise } = current, resolvedSchemaLessConditional = __rest(current, ["if", "then", "else"]);
|
|
78
|
+
if (!expression || typeof expression === "boolean") {
|
|
79
|
+
return {
|
|
80
|
+
resolvedSchema: mergeSchemas(resolvedSchema, resolvedSchemaLessConditional),
|
|
81
|
+
notAddedProperties,
|
|
82
|
+
};
|
|
49
83
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
84
|
+
if (resolveEquality(value, expression)) {
|
|
85
|
+
if (then && typeof then !== "boolean") {
|
|
86
|
+
resolvedSchema = mergeSchemas(resolvedSchema, then);
|
|
87
|
+
}
|
|
88
|
+
if (otherwise && typeof otherwise !== "boolean") {
|
|
89
|
+
notAddedProperties = [
|
|
90
|
+
...notAddedProperties,
|
|
91
|
+
...Object.keys((_a = otherwise.properties) !== null && _a !== void 0 ? _a : {}),
|
|
92
|
+
];
|
|
93
|
+
}
|
|
57
94
|
}
|
|
58
|
-
|
|
59
|
-
|
|
95
|
+
else {
|
|
96
|
+
if (then && typeof then !== "boolean") {
|
|
97
|
+
notAddedProperties = [
|
|
98
|
+
...notAddedProperties,
|
|
99
|
+
...Object.keys((_b = then.properties) !== null && _b !== void 0 ? _b : {}),
|
|
100
|
+
];
|
|
101
|
+
}
|
|
102
|
+
if (otherwise && typeof otherwise !== "boolean") {
|
|
103
|
+
resolvedSchema = mergeSchemas(resolvedSchema, otherwise);
|
|
104
|
+
}
|
|
60
105
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
106
|
+
return { resolvedSchema, notAddedProperties };
|
|
107
|
+
}, { resolvedSchema: schemaCopy, notAddedProperties: [] });
|
|
108
|
+
//Values that do not exists due to conditions
|
|
109
|
+
const usedPropertiesAllOf = Object.keys((_c = resolvedSchema.properties) !== null && _c !== void 0 ? _c : {});
|
|
110
|
+
valuesToRemoveAllOf = [...new Set([...notAddedProperties])].filter((key) => !usedPropertiesAllOf.includes(key) && typeof value[key] !== "undefined");
|
|
111
|
+
const valuesToRemove = [
|
|
112
|
+
...new Set([...valuesToRemoveDeps, ...valuesToRemoveAllOf]),
|
|
113
|
+
];
|
|
114
|
+
return [resolvedSchema, valuesToRemove];
|
|
115
|
+
}
|
|
116
|
+
return [schemaCopy, []];
|
|
68
117
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function solveReferences(schema, definitions) {
|
|
2
|
+
var _a, _b;
|
|
3
|
+
if (typeof schema === "object" && schema["$ref"]) {
|
|
4
|
+
const schemaKey = (_b = (_a = schema["$ref"]) === null || _a === void 0 ? void 0 : _a.substring(14)) !== null && _b !== void 0 ? _b : "";
|
|
5
|
+
return definitions[schemaKey];
|
|
6
|
+
}
|
|
7
|
+
return schema;
|
|
8
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nolwenture/formik-jsonschema-form",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Formik form generation from json schema",
|
|
5
5
|
"author": "Antti Vikman <antti.vikman@nolwenture.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"build": "tsc --build",
|
|
32
32
|
"clean": "tsc --build --clean",
|
|
33
33
|
"test": "jest",
|
|
34
|
-
"storybook": "storybook dev -p 6006"
|
|
34
|
+
"storybook": "storybook dev -p 6006",
|
|
35
|
+
"test-storybook": "test-storybook"
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
38
|
"formik": "^2.4.5",
|
|
@@ -50,6 +51,7 @@
|
|
|
50
51
|
"@storybook/react": "^8.0.5",
|
|
51
52
|
"@storybook/react-webpack5": "^8.0.5",
|
|
52
53
|
"@storybook/test": "^8.0.5",
|
|
54
|
+
"@storybook/test-runner": "^0.17.0",
|
|
53
55
|
"@testing-library/jest-dom": "^6.4.2",
|
|
54
56
|
"@testing-library/react": "^14.2.2",
|
|
55
57
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -59,6 +61,7 @@
|
|
|
59
61
|
"@types/styled-components": "^5.1.34",
|
|
60
62
|
"babel-plugin-named-exports-order": "^0.0.2",
|
|
61
63
|
"jest": "^29.7.0",
|
|
64
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
62
65
|
"storybook": "^8.0.5",
|
|
63
66
|
"ts-jest": "^29.1.2",
|
|
64
67
|
"webpack": "^5.91.0"
|