@flowgram-vue/json-schema 0.2.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/LICENSE +22 -0
- package/dist/index.cjs +750 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +295 -0
- package/dist/index.js +744 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
- package/src/base/base-type-manager.ts +94 -0
- package/src/base/index.ts +7 -0
- package/src/base/types.ts +30 -0
- package/src/composables/use-type-manager.ts +76 -0
- package/src/container-module.ts +19 -0
- package/src/index.ts +10 -0
- package/src/json-schema/index.ts +19 -0
- package/src/json-schema/json-schema-type-manager.ts +152 -0
- package/src/json-schema/type-definition/array-icons.ts +62 -0
- package/src/json-schema/type-definition/array.ts +120 -0
- package/src/json-schema/type-definition/boolean.ts +30 -0
- package/src/json-schema/type-definition/date-time.ts +36 -0
- package/src/json-schema/type-definition/default.ts +66 -0
- package/src/json-schema/type-definition/index.ts +13 -0
- package/src/json-schema/type-definition/integer.ts +29 -0
- package/src/json-schema/type-definition/map.ts +118 -0
- package/src/json-schema/type-definition/number.ts +30 -0
- package/src/json-schema/type-definition/object.ts +44 -0
- package/src/json-schema/type-definition/string.ts +32 -0
- package/src/json-schema/type-definition/svg-vnode.ts +17 -0
- package/src/json-schema/type-definition/unknown.ts +27 -0
- package/src/json-schema/types.ts +175 -0
- package/src/json-schema/utils.ts +212 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IJsonSchema, JsonSchemaTypeRegistryCreator } from '../types';
|
|
7
|
+
import { createSvgVNode } from './svg-vnode';
|
|
8
|
+
import { arrayNumberIcon } from './array-icons';
|
|
9
|
+
|
|
10
|
+
export const numberRegistryCreator: JsonSchemaTypeRegistryCreator = () => ({
|
|
11
|
+
type: 'number',
|
|
12
|
+
|
|
13
|
+
label: 'Number',
|
|
14
|
+
|
|
15
|
+
extend: 'integer',
|
|
16
|
+
|
|
17
|
+
icon: createSvgVNode({
|
|
18
|
+
width: "16",
|
|
19
|
+
height: "16",
|
|
20
|
+
viewBox: "0 0 16 16",
|
|
21
|
+
fill: "none",
|
|
22
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
23
|
+
}, `<path d="M3.44151 5.3068C3.44151 3.83404 4.71542 2.64014 6.18818 2.64014C7.66094 2.64014 8.93484 3.83404 8.93484 5.3068V10.6135C8.93484 12.0862 7.66094 13.2801 6.18818 13.2801C4.71542 13.2801 3.44151 12.0862 3.44151 10.6135V5.3068ZM7.60151 5.3068C7.60151 4.57042 6.92456 3.97347 6.18818 3.97347C5.4518 3.97347 4.77484 4.57042 4.77484 5.3068V10.6135C4.77484 11.3498 5.4518 11.9468 6.18818 11.9468C6.92456 11.9468 7.60151 11.3498 7.60151 10.6135V5.3068Z" fill="currentColor" /> <path d="M12.9882 2.64014C11.5154 2.64014 10.2415 3.83404 10.2415 5.3068V10.6135C10.2415 12.0862 11.5154 13.2801 12.9882 13.2801C14.4609 13.2801 15.7348 12.0862 15.7348 10.6135V5.3068C15.7348 3.83404 14.4609 2.64014 12.9882 2.64014ZM14.4015 10.6135C14.4015 11.3498 13.7246 11.9468 12.9882 11.9468C12.2518 11.9468 11.5748 11.3498 11.5748 10.6135V5.3068C11.5748 4.57042 12.2518 3.97347 12.9882 3.97347C13.7246 3.97347 14.4015 4.57042 14.4015 5.3068V10.6135Z" fill="currentColor" /> <path d="M1.21484 13.2001C1.76713 13.2001 2.21484 12.7524 2.21484 12.2001C2.21484 11.6479 1.76713 11.2001 1.21484 11.2001C0.662559 11.2001 0.214844 11.6479 0.214844 12.2001C0.214844 12.7524 0.662559 13.2001 1.21484 13.2001Z" fill="currentColor" />`),
|
|
24
|
+
|
|
25
|
+
arrayIcon: arrayNumberIcon,
|
|
26
|
+
|
|
27
|
+
getValueText: (value?: unknown) => (value ? `${value}` : ''),
|
|
28
|
+
|
|
29
|
+
getDefaultSchema: (): IJsonSchema => ({ type: 'number' }),
|
|
30
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IJsonSchema, JsonSchemaTypeRegistryCreator } from '../types';
|
|
7
|
+
import { createSvgVNode } from './svg-vnode';
|
|
8
|
+
import { arrayObjectIcon } from './array-icons';
|
|
9
|
+
|
|
10
|
+
export const objectRegistryCreator: JsonSchemaTypeRegistryCreator = () => ({
|
|
11
|
+
type: 'object',
|
|
12
|
+
label: 'Object',
|
|
13
|
+
|
|
14
|
+
icon: createSvgVNode({
|
|
15
|
+
width: "16",
|
|
16
|
+
height: "16",
|
|
17
|
+
viewBox: "0 0 16 16",
|
|
18
|
+
fill: "none",
|
|
19
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
20
|
+
}, `<path d="M5.33893 1.5835C5.66613 1.5835 5.93137 1.88142 5.93137 2.20862C5.93137 2.53582 5.66613 2.76838 5.33893 2.76838H4.9099C4.34717 2.76838 4.08062 3.07557 4.08062 3.71921V6.58633C4.08062 7.30996 3.80723 7.84734 3.26798 8.19105C3.11426 8.28902 3.10884 8.55273 3.26068 8.65359C3.80476 9.01503 4.08062 9.53994 4.08062 10.2434V13.1251C4.08062 13.7395 4.34717 14.0613 4.9099 14.0613H5.33893C5.66613 14.0613 5.93137 14.3435 5.93137 14.6707C5.93137 14.9979 5.66613 15.2462 5.33893 15.2462H4.64335C3.99177 15.2462 3.48828 15.0268 3.13287 14.6172C2.80708 14.2369 2.64419 13.7103 2.64419 13.0666V10.3165C2.64419 9.8923 2.55534 9.58511 2.37764 9.39494C2.26816 9.27135 1.80618 9.17938 1.38154 9.11602C1.02726 9.06315 0.759057 8.76744 0.765747 8.4093C0.772379 8.0543 1.03439 7.7566 1.38545 7.70346C1.80778 7.63952 2.26906 7.54968 2.37764 7.43477C2.55534 7.22997 2.64419 6.92278 2.64419 6.51319V3.77772C2.64419 3.11945 2.80708 2.59284 3.13287 2.21251C3.48828 1.78829 3.99177 1.5835 4.64335 1.5835H5.33893Z" fill="currentColor" /> <path d="M10.962 15.2463C10.6348 15.2463 10.3696 14.9483 10.3696 14.6211C10.3696 14.2939 10.6348 14.0614 10.962 14.0614H11.391C11.9538 14.0614 12.2203 13.7542 12.2203 13.1105V10.2434C12.2203 9.51979 12.4937 8.98241 13.033 8.6387C13.1867 8.54073 13.1921 8.27703 13.0403 8.17616C12.4962 7.81472 12.2203 7.28982 12.2203 6.58638V3.70463C12.2203 3.09024 11.9538 2.76842 11.391 2.76842L10.962 2.76842C10.6348 2.76842 10.3696 2.48627 10.3696 2.15907C10.3696 1.83188 10.6348 1.58354 10.962 1.58354L11.6576 1.58354C12.3092 1.58354 12.8127 1.80296 13.1681 2.21255C13.4939 2.59289 13.6568 3.1195 13.6568 3.76314V6.51324C13.6568 6.93745 13.7456 7.24464 13.9233 7.43481C14.03 7.5553 14.4328 7.64858 14.8186 7.71393C15.1718 7.77376 15.4401 8.06977 15.4334 8.42791C15.4268 8.78291 15.1646 9.08018 14.814 9.13633C14.4306 9.19774 14.0291 9.28303 13.9233 9.39499C13.7456 9.59978 13.6568 9.90697 13.6568 10.3166V13.052C13.6568 13.7103 13.4939 14.2369 13.1681 14.6172C12.8127 15.0415 12.3092 15.2463 11.6576 15.2463H10.962Z" fill="currentColor" />`),
|
|
21
|
+
|
|
22
|
+
arrayIcon: arrayObjectIcon,
|
|
23
|
+
|
|
24
|
+
getTypeSchemaProperties: (type: IJsonSchema): Record<string, IJsonSchema> =>
|
|
25
|
+
type.properties || {},
|
|
26
|
+
|
|
27
|
+
getPropertiesParent: (type) => type,
|
|
28
|
+
|
|
29
|
+
canAddField: () => true,
|
|
30
|
+
|
|
31
|
+
getDefaultSchema: (): IJsonSchema => ({
|
|
32
|
+
type: 'object',
|
|
33
|
+
required: [],
|
|
34
|
+
properties: {},
|
|
35
|
+
}),
|
|
36
|
+
|
|
37
|
+
getIJsonSchemaPropertiesParent: (type: IJsonSchema) => type,
|
|
38
|
+
|
|
39
|
+
getValueText: () => '',
|
|
40
|
+
|
|
41
|
+
getJsonPaths: () => ['properties'],
|
|
42
|
+
|
|
43
|
+
getDefaultValue: () => ({}),
|
|
44
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { JsonSchemaTypeRegistryCreator } from '../types';
|
|
7
|
+
import { createSvgVNode } from './svg-vnode';
|
|
8
|
+
import { arrayStringIcon } from './array-icons';
|
|
9
|
+
|
|
10
|
+
export const stringRegistryCreator: JsonSchemaTypeRegistryCreator = () => ({
|
|
11
|
+
type: 'string',
|
|
12
|
+
|
|
13
|
+
label: 'String',
|
|
14
|
+
|
|
15
|
+
icon: createSvgVNode({
|
|
16
|
+
width: "1em",
|
|
17
|
+
height: "1em",
|
|
18
|
+
viewBox: "0 0 16 16",
|
|
19
|
+
fill: "none",
|
|
20
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
21
|
+
}, `<path d="M9.3342 3.33321C8.96601 3.33321 8.66753 3.63169 8.66753 3.99988C8.66753 4.36807 8.96601 4.66655 9.3342 4.66655H14.6675C15.0357 4.66655 15.3342 4.36807 15.3342 3.99988C15.3342 3.63169 15.0357 3.33321 14.6675 3.33321H9.3342Z" fill="currentColor" /> <path d="M10.0009 7.99988C10.0009 7.63169 10.2993 7.33321 10.6675 7.33321H14.6675C15.0357 7.33321 15.3342 7.63169 15.3342 7.99988C15.3342 8.36807 15.0357 8.66655 14.6675 8.66655H10.6675C10.2993 8.66655 10.0009 8.36807 10.0009 7.99988Z" fill="currentColor" /> <path d="M12.0009 11.3332C11.6327 11.3332 11.3342 11.6317 11.3342 11.9999C11.3342 12.3681 11.6327 12.6665 12.0009 12.6665H14.6675C15.0357 12.6665 15.3342 12.3681 15.3342 11.9999C15.3342 11.6317 15.0357 11.3332 14.6675 11.3332H12.0009Z" fill="currentColor" /> <path d="M9.86659 14.1482L8.23444 10.1844H3.18136C3.13868 10.1844 3.09685 10.1808 3.05616 10.1738L1.66589 14.1129C1.53049 14.4965 1.10971 14.6978 0.726058 14.5624C0.342408 14.427 0.141166 14.0062 0.276572 13.6225L4.37566 2.00848C4.71323 1.05202 6.05321 1.01763 6.4394 1.95552L11.2289 13.5872C11.3838 13.9634 11.2044 14.394 10.8282 14.5489C10.452 14.7038 10.0215 14.5244 9.86659 14.1482ZM5.44412 3.40791L3.57241 8.71109H7.62778L5.44412 3.40791Z" fill="currentColor" />`),
|
|
22
|
+
|
|
23
|
+
arrayIcon: arrayStringIcon,
|
|
24
|
+
|
|
25
|
+
getDefaultSchema: () => ({
|
|
26
|
+
type: 'string',
|
|
27
|
+
}),
|
|
28
|
+
|
|
29
|
+
getValueText: (value?: unknown) => (value ? `${value}` : ''),
|
|
30
|
+
|
|
31
|
+
getDefaultValue: () => '',
|
|
32
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Comment, h, type VNode } from 'vue';
|
|
7
|
+
|
|
8
|
+
export function createSvgVNode(
|
|
9
|
+
attrs: Record<string, string | number | boolean | undefined>,
|
|
10
|
+
innerHTML: string
|
|
11
|
+
): VNode {
|
|
12
|
+
return h('svg', { ...attrs, innerHTML });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function emptyVNode(): VNode {
|
|
16
|
+
return h(Comment);
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IJsonSchema, JsonSchemaTypeRegistryCreator } from '../types';
|
|
7
|
+
import { createSvgVNode } from './svg-vnode';
|
|
8
|
+
|
|
9
|
+
export const unknownRegistryCreator: JsonSchemaTypeRegistryCreator = () => ({
|
|
10
|
+
type: 'unknown',
|
|
11
|
+
label: 'Unknown',
|
|
12
|
+
parentType: [],
|
|
13
|
+
|
|
14
|
+
icon: createSvgVNode({
|
|
15
|
+
viewBox: "0 0 24 24",
|
|
16
|
+
fill: "none",
|
|
17
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
18
|
+
width: "1em",
|
|
19
|
+
height: "1em",
|
|
20
|
+
focusable: "false",
|
|
21
|
+
'aria-hidden': "true"
|
|
22
|
+
}, `<path fill-rule="evenodd" clip-rule="evenodd" d="M4.22183 4.22182C6.21136 2.23232 8.96273 1 12 1C15.0373 1 17.7886 2.23231 19.7782 4.22182L19.0711 4.92893L19.7782 4.22183C21.7677 6.21136 23 8.96273 23 12C23 15.0373 21.7677 17.7886 19.7782 19.7782C17.7886 21.7677 15.0373 23 12 23C8.96273 23 6.21136 21.7677 4.22183 19.7782L4.92893 19.0711L4.22182 19.7782C2.23231 17.7886 1 15.0373 1 12C1 8.96273 2.23232 6.21136 4.22182 4.22183L4.22183 4.22182ZM12 3C9.51447 3 7.26584 4.00626 5.63603 5.63604C4.00625 7.26585 3 9.51447 3 12C3 14.4855 4.00627 16.7342 5.63604 18.3639C7.26584 19.9937 9.51447 21 12 21C14.4855 21 16.7342 19.9937 18.3639 18.3639C19.9937 16.7342 21 14.4855 21 12C21 9.51447 19.9937 7.26584 18.3639 5.63604C16.7342 4.00627 14.4855 3 12 3Z" fill="currentColor" ></path> <path fill-rule="evenodd" clip-rule="evenodd" d="M8 9.31245C8 7.10331 9.79086 5.31245 12 5.31245C14.2091 5.31245 16 7.10331 16 9.31245C16 11.1763 14.7252 12.7424 13 13.1864V14.3124C13 14.8647 12.5523 15.3124 12 15.3124C11.4477 15.3124 11 14.8647 11 14.3124V12.3124C11 11.7602 11.4477 11.3124 12 11.3124C13.1046 11.3124 14 10.417 14 9.31245C14 8.20788 13.1046 7.31245 12 7.31245C10.8954 7.31245 10 8.20788 10 9.31245C10 9.86473 9.55228 10.3124 9 10.3124C8.44772 10.3124 8 9.86473 8 9.31245Z" fill="currentColor" ></path> <path fill-rule="evenodd" clip-rule="evenodd" d="M12 18.8125C12.6904 18.8125 13.25 18.2528 13.25 17.5625C13.25 16.8721 12.6904 16.3125 12 16.3125C11.3097 16.3125 10.75 16.8721 10.75 17.5625C10.75 18.2528 11.3097 18.8125 12 18.8125Z" fill="currentColor" ></path>`),
|
|
23
|
+
|
|
24
|
+
getDefaultSchema: (): IJsonSchema => ({ type: 'unknown' } as unknown as IJsonSchema),
|
|
25
|
+
|
|
26
|
+
getDefaultValue: () => undefined,
|
|
27
|
+
});
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { type VNode } from 'vue';
|
|
7
|
+
|
|
8
|
+
import { BaseTypeRegistry, TypeRegistryCreator } from '../base';
|
|
9
|
+
import { type JsonSchemaTypeManager } from './json-schema-type-manager';
|
|
10
|
+
|
|
11
|
+
export type JsonSchemaBasicType =
|
|
12
|
+
| 'boolean'
|
|
13
|
+
| 'string'
|
|
14
|
+
| 'integer'
|
|
15
|
+
| 'number'
|
|
16
|
+
| 'object'
|
|
17
|
+
| 'array'
|
|
18
|
+
| 'map';
|
|
19
|
+
|
|
20
|
+
export interface IJsonSchema<T = string> {
|
|
21
|
+
type?: T;
|
|
22
|
+
/**
|
|
23
|
+
* The format of string
|
|
24
|
+
* https://json-schema.org/understanding-json-schema/reference/type#format
|
|
25
|
+
*/
|
|
26
|
+
format?: string;
|
|
27
|
+
default?: any;
|
|
28
|
+
title?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
enum?: (string | number)[];
|
|
31
|
+
properties?: Record<string, IJsonSchema<T>>;
|
|
32
|
+
additionalProperties?: IJsonSchema<T>;
|
|
33
|
+
items?: IJsonSchema<T>;
|
|
34
|
+
required?: string[];
|
|
35
|
+
$ref?: string;
|
|
36
|
+
extra?: {
|
|
37
|
+
index?: number;
|
|
38
|
+
// Used in BaseType.isEqualWithJSONSchema, the type comparison will be weak
|
|
39
|
+
weak?: boolean;
|
|
40
|
+
// Set the render component
|
|
41
|
+
formComponent?: string;
|
|
42
|
+
[key: string]: any;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type IBasicJsonSchema = IJsonSchema<JsonSchemaBasicType>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* TypeRegistry based on IJsonSchema
|
|
50
|
+
*/
|
|
51
|
+
export interface JsonSchemaTypeRegistry<Schema extends Partial<IJsonSchema> = IJsonSchema>
|
|
52
|
+
extends BaseTypeRegistry {
|
|
53
|
+
/**
|
|
54
|
+
* The icon of this type
|
|
55
|
+
*/
|
|
56
|
+
icon: VNode;
|
|
57
|
+
/**
|
|
58
|
+
* The icon displayed when this type is used as an array item
|
|
59
|
+
*/
|
|
60
|
+
arrayIcon?: VNode;
|
|
61
|
+
/**
|
|
62
|
+
* The display text of this type, not including the icon
|
|
63
|
+
*/
|
|
64
|
+
label: string;
|
|
65
|
+
/**
|
|
66
|
+
* Whether it is a container type
|
|
67
|
+
*/
|
|
68
|
+
container: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Supported parent types. Some types can only appear as subtypes in type selection, but not as basic types.
|
|
71
|
+
*/
|
|
72
|
+
parentType?: string[];
|
|
73
|
+
|
|
74
|
+
/*
|
|
75
|
+
* Get supported sub-types
|
|
76
|
+
*/
|
|
77
|
+
getSupportedItemTypes?: (ctx: {
|
|
78
|
+
level: number;
|
|
79
|
+
parentTypes?: string[];
|
|
80
|
+
}) => Array<{ type: string; disabled?: string }>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get the display label
|
|
84
|
+
*/
|
|
85
|
+
getDisplayLabel: (typeSchema: Schema) => VNode;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get the display text
|
|
89
|
+
*/
|
|
90
|
+
getDisplayText: (typeSchema: Schema) => string | undefined;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get the sub-type
|
|
94
|
+
*/
|
|
95
|
+
getItemType?: (typeSchema: Schema) => Schema | undefined;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Generate default Schema
|
|
99
|
+
*/
|
|
100
|
+
getDefaultSchema: () => Schema;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* onInit initialization logic, which is called at the appropriate time externally to register data into the type system
|
|
104
|
+
*/
|
|
105
|
+
onInit?: () => void;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Whether to allow adding fields, such as object
|
|
109
|
+
*/
|
|
110
|
+
canAddField: (typeSchema: Schema) => boolean;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Get the string value, for example
|
|
114
|
+
* { type: "array", items: { type: "string" } }
|
|
115
|
+
* The value is "array-string"
|
|
116
|
+
*
|
|
117
|
+
* The use case is that in some UI components, a string value needs to be generated
|
|
118
|
+
*/
|
|
119
|
+
getStringValueByTypeSchema?: (optionValue: Schema) => string | undefined;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Restore the string value to typeSchema
|
|
123
|
+
* "array-string" is restored to
|
|
124
|
+
* { type: "array", items: { type: "string" } }
|
|
125
|
+
*/
|
|
126
|
+
getTypeSchemaByStringValue?: (type: string) => Schema;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Get the display icon, and the composite icon of the array is also processed
|
|
130
|
+
*/
|
|
131
|
+
getDisplayIcon: (typeSchema: Schema) => VNode;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Get sub-properties
|
|
135
|
+
*/
|
|
136
|
+
getTypeSchemaProperties: (typeSchema: Schema) => Record<string, Schema> | undefined;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get the default value
|
|
140
|
+
*/
|
|
141
|
+
getDefaultValue: () => unknown;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get the display text based on the value
|
|
145
|
+
*/
|
|
146
|
+
getValueText: (value?: unknown) => string;
|
|
147
|
+
/**
|
|
148
|
+
* Get the json path of a certain type in the flow schema
|
|
149
|
+
* For example
|
|
150
|
+
* { type: "object", properties: { name: { type: "string" } } }
|
|
151
|
+
* -> ['properties', 'name']
|
|
152
|
+
* { type: "array", items: { type: "string" } }
|
|
153
|
+
* ->['items']
|
|
154
|
+
*/
|
|
155
|
+
getJsonPaths: (typeSchema: Schema) => string[];
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get the parent node of the sub-field
|
|
159
|
+
* object is itself
|
|
160
|
+
* array<object> is items
|
|
161
|
+
* map<object> is additionalProperties
|
|
162
|
+
*/
|
|
163
|
+
getPropertiesParent: (typeSchema: Schema) => Schema | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* The complexText of a custom type
|
|
166
|
+
* For example, Array<string>, can be modified
|
|
167
|
+
*/
|
|
168
|
+
customComplexText?: (typeSchema: Schema) => string;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export type JsonSchemaTypeRegistryCreator<
|
|
172
|
+
Schema extends Partial<IJsonSchema> = IJsonSchema,
|
|
173
|
+
Registry extends JsonSchemaTypeRegistry<Schema> = JsonSchemaTypeRegistry<Schema>,
|
|
174
|
+
Manager extends JsonSchemaTypeManager<Schema, Registry> = JsonSchemaTypeManager<Schema, Registry>
|
|
175
|
+
> = TypeRegistryCreator<Schema, Registry, Manager>;
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { get } from 'lodash-es';
|
|
7
|
+
import {
|
|
8
|
+
ASTFactory,
|
|
9
|
+
ASTKind,
|
|
10
|
+
ASTMatch,
|
|
11
|
+
ASTNode,
|
|
12
|
+
ASTNodeJSON,
|
|
13
|
+
BaseType,
|
|
14
|
+
} from '@flowgram-vue/variable-core';
|
|
15
|
+
|
|
16
|
+
import { IJsonSchema } from './types';
|
|
17
|
+
|
|
18
|
+
export namespace JsonSchemaUtils {
|
|
19
|
+
/**
|
|
20
|
+
* Converts a JSON schema to an Abstract Syntax Tree (AST) representation.
|
|
21
|
+
* This function recursively processes the JSON schema and creates corresponding AST nodes.
|
|
22
|
+
*
|
|
23
|
+
* For more information on JSON Schema, refer to the official documentation:
|
|
24
|
+
* https://json-schema.org/
|
|
25
|
+
*
|
|
26
|
+
* @param jsonSchema - The JSON schema to convert.
|
|
27
|
+
* @returns An AST node representing the JSON schema, or undefined if the schema type is not recognized.
|
|
28
|
+
*/
|
|
29
|
+
export function schemaToAST(jsonSchema: IJsonSchema): ASTNodeJSON | undefined {
|
|
30
|
+
const { type, extra, required } = jsonSchema || {};
|
|
31
|
+
const { weak = false } = extra || {};
|
|
32
|
+
|
|
33
|
+
if (!type) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
switch (type) {
|
|
38
|
+
case 'object':
|
|
39
|
+
if (weak) {
|
|
40
|
+
return { kind: ASTKind.Object, weak: true };
|
|
41
|
+
}
|
|
42
|
+
return ASTFactory.createObject({
|
|
43
|
+
properties: Object.entries(jsonSchema.properties || {})
|
|
44
|
+
/**
|
|
45
|
+
* Sorts the properties of a JSON schema based on the 'extra.index' field.
|
|
46
|
+
* If the 'extra.index' field is not present, the property will be treated as having an index of 0.
|
|
47
|
+
*/
|
|
48
|
+
.sort((a, b) => (get(a?.[1], 'extra.index') || 0) - (get(b?.[1], 'extra.index') || 0))
|
|
49
|
+
.map(([key, _property]) => ({
|
|
50
|
+
key,
|
|
51
|
+
type: schemaToAST(_property),
|
|
52
|
+
meta: {
|
|
53
|
+
title: _property.title,
|
|
54
|
+
description: _property.description,
|
|
55
|
+
required: !!required?.includes(key),
|
|
56
|
+
default: _property.default,
|
|
57
|
+
},
|
|
58
|
+
})),
|
|
59
|
+
});
|
|
60
|
+
case 'array':
|
|
61
|
+
if (weak) {
|
|
62
|
+
return { kind: ASTKind.Array, weak: true };
|
|
63
|
+
}
|
|
64
|
+
return ASTFactory.createArray({
|
|
65
|
+
items: schemaToAST(jsonSchema.items!),
|
|
66
|
+
});
|
|
67
|
+
case 'map':
|
|
68
|
+
if (weak) {
|
|
69
|
+
return { kind: ASTKind.Map, weak: true };
|
|
70
|
+
}
|
|
71
|
+
return ASTFactory.createMap({
|
|
72
|
+
valueType: schemaToAST(jsonSchema.additionalProperties!),
|
|
73
|
+
});
|
|
74
|
+
case 'string':
|
|
75
|
+
return ASTFactory.createString({ format: jsonSchema.format });
|
|
76
|
+
case 'number':
|
|
77
|
+
return ASTFactory.createNumber();
|
|
78
|
+
case 'boolean':
|
|
79
|
+
return ASTFactory.createBoolean();
|
|
80
|
+
case 'integer':
|
|
81
|
+
return ASTFactory.createInteger();
|
|
82
|
+
|
|
83
|
+
default:
|
|
84
|
+
// If the type is not recognized, return CustomType
|
|
85
|
+
return ASTFactory.createCustomType({ typeName: type });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Convert AST To JSON Schema
|
|
91
|
+
* @param typeAST
|
|
92
|
+
* @returns
|
|
93
|
+
*/
|
|
94
|
+
export function astToSchema(
|
|
95
|
+
typeAST?: ASTNode,
|
|
96
|
+
options?: {
|
|
97
|
+
drilldown?: boolean;
|
|
98
|
+
drilldownObject?: boolean;
|
|
99
|
+
drilldownMap?: boolean;
|
|
100
|
+
drilldownArray?: boolean;
|
|
101
|
+
}
|
|
102
|
+
): IJsonSchema | undefined {
|
|
103
|
+
const {
|
|
104
|
+
drilldown = true,
|
|
105
|
+
drilldownMap = drilldown,
|
|
106
|
+
drilldownObject = drilldown,
|
|
107
|
+
drilldownArray = drilldown,
|
|
108
|
+
} = options || {};
|
|
109
|
+
|
|
110
|
+
if (!typeAST) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (ASTMatch.isString(typeAST)) {
|
|
115
|
+
return {
|
|
116
|
+
type: 'string',
|
|
117
|
+
format: typeAST.format,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (ASTMatch.isBoolean(typeAST)) {
|
|
122
|
+
return {
|
|
123
|
+
type: 'boolean',
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (ASTMatch.isNumber(typeAST)) {
|
|
128
|
+
return {
|
|
129
|
+
type: 'number',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (ASTMatch.isInteger(typeAST)) {
|
|
134
|
+
return {
|
|
135
|
+
type: 'integer',
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (ASTMatch.isObject(typeAST)) {
|
|
140
|
+
return {
|
|
141
|
+
type: 'object',
|
|
142
|
+
required: typeAST.properties
|
|
143
|
+
.filter((property) => property.meta?.required)
|
|
144
|
+
.map((property) => property.key),
|
|
145
|
+
properties: drilldownObject
|
|
146
|
+
? Object.fromEntries(
|
|
147
|
+
typeAST.properties.map((property) => {
|
|
148
|
+
const schema = astToSchema(property.type);
|
|
149
|
+
|
|
150
|
+
if (property.meta?.title && schema) {
|
|
151
|
+
schema.title = property.meta.title;
|
|
152
|
+
}
|
|
153
|
+
if (property.meta?.description && schema) {
|
|
154
|
+
schema.description = property.meta.description;
|
|
155
|
+
}
|
|
156
|
+
if (property.meta?.default && schema) {
|
|
157
|
+
schema.default = property.meta.default;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return [property.key, schema!];
|
|
161
|
+
})
|
|
162
|
+
)
|
|
163
|
+
: {},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (ASTMatch.isArray(typeAST)) {
|
|
168
|
+
return {
|
|
169
|
+
type: 'array',
|
|
170
|
+
items: drilldownArray ? astToSchema(typeAST.items) : undefined,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (ASTMatch.isMap(typeAST)) {
|
|
175
|
+
return {
|
|
176
|
+
type: 'map',
|
|
177
|
+
items: drilldownMap ? astToSchema(typeAST.valueType) : undefined,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (ASTMatch.isCustomType(typeAST)) {
|
|
182
|
+
return {
|
|
183
|
+
type: typeAST.typeName,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
console.warn('JsonSchemaUtils.astToSchema: AST must extends BaseType', typeAST);
|
|
188
|
+
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Check if the AST type is match the JSON Schema
|
|
194
|
+
* @param typeAST
|
|
195
|
+
* @param schema
|
|
196
|
+
* @returns
|
|
197
|
+
*/
|
|
198
|
+
export function isASTMatchSchema(
|
|
199
|
+
typeAST: BaseType,
|
|
200
|
+
schema: IJsonSchema | IJsonSchema[]
|
|
201
|
+
): boolean {
|
|
202
|
+
if (Array.isArray(schema)) {
|
|
203
|
+
return typeAST.isTypeEqual(
|
|
204
|
+
ASTFactory.createUnion({
|
|
205
|
+
types: schema.map((_schema) => schemaToAST(_schema)!).filter(Boolean),
|
|
206
|
+
})
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return typeAST.isTypeEqual(schemaToAST(schema));
|
|
211
|
+
}
|
|
212
|
+
}
|