@flowgram.ai/form-materials 0.1.0-alpha.10
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/bin/index.ts +99 -0
- package/bin/materials.ts +156 -0
- package/bin/project.ts +91 -0
- package/dist/esm/index.js +3303 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/index.d.mts +495 -0
- package/dist/index.d.ts +495 -0
- package/dist/index.js +3299 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
- package/src/components/batch-outputs/config.json +12 -0
- package/src/components/batch-outputs/index.tsx +61 -0
- package/src/components/batch-outputs/styles.tsx +19 -0
- package/src/components/batch-outputs/types.ts +22 -0
- package/src/components/batch-outputs/use-list.ts +86 -0
- package/src/components/batch-variable-selector/config.json +5 -0
- package/src/components/batch-variable-selector/index.tsx +24 -0
- package/src/components/code-editor/config.json +9 -0
- package/src/components/code-editor/index.tsx +74 -0
- package/src/components/code-editor/language-features.ts +24 -0
- package/src/components/code-editor/theme/dark.ts +119 -0
- package/src/components/code-editor/theme/index.ts +12 -0
- package/src/components/code-editor/theme/light.ts +119 -0
- package/src/components/code-editor/utils.ts +20 -0
- package/src/components/condition-row/config.json +5 -0
- package/src/components/condition-row/constants.ts +128 -0
- package/src/components/condition-row/hooks/useOp.tsx +50 -0
- package/src/components/condition-row/hooks/useRule.ts +31 -0
- package/src/components/condition-row/index.tsx +81 -0
- package/src/components/condition-row/styles.tsx +30 -0
- package/src/components/condition-row/types.ts +42 -0
- package/src/components/constant-input/config.json +6 -0
- package/src/components/constant-input/index.tsx +86 -0
- package/src/components/constant-input/types.ts +23 -0
- package/src/components/dynamic-value-input/config.json +5 -0
- package/src/components/dynamic-value-input/index.tsx +92 -0
- package/src/components/dynamic-value-input/styles.tsx +26 -0
- package/src/components/index.ts +18 -0
- package/src/components/json-editor-with-variables/config.json +13 -0
- package/src/components/json-editor-with-variables/extensions/variable-tag.tsx +173 -0
- package/src/components/json-editor-with-variables/extensions/variable-tree.tsx +83 -0
- package/src/components/json-editor-with-variables/index.tsx +19 -0
- package/src/components/json-editor-with-variables/styles.tsx +44 -0
- package/src/components/json-schema-editor/components/blur-input.tsx +27 -0
- package/src/components/json-schema-editor/config.json +13 -0
- package/src/components/json-schema-editor/default-value.tsx +135 -0
- package/src/components/json-schema-editor/hooks.tsx +166 -0
- package/src/components/json-schema-editor/index.tsx +267 -0
- package/src/components/json-schema-editor/styles.tsx +240 -0
- package/src/components/json-schema-editor/types.ts +26 -0
- package/src/components/json-schema-editor/utils.ts +29 -0
- package/src/components/prompt-editor/config.json +9 -0
- package/src/components/prompt-editor/extensions/jinja.tsx +58 -0
- package/src/components/prompt-editor/extensions/language-support.tsx +19 -0
- package/src/components/prompt-editor/extensions/markdown.tsx +75 -0
- package/src/components/prompt-editor/index.tsx +68 -0
- package/src/components/prompt-editor/styles.tsx +18 -0
- package/src/components/prompt-editor/types.tsx +18 -0
- package/src/components/prompt-editor-with-inputs/config.json +13 -0
- package/src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx +82 -0
- package/src/components/prompt-editor-with-inputs/index.tsx +22 -0
- package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +100 -0
- package/src/components/prompt-editor-with-variables/config.json +13 -0
- package/src/components/prompt-editor-with-variables/extensions/variable-tag.tsx +179 -0
- package/src/components/prompt-editor-with-variables/extensions/variable-tree.tsx +83 -0
- package/src/components/prompt-editor-with-variables/index.tsx +19 -0
- package/src/components/prompt-editor-with-variables/styles.tsx +44 -0
- package/src/components/type-selector/config.json +5 -0
- package/src/components/type-selector/constants.tsx +364 -0
- package/src/components/type-selector/index.tsx +62 -0
- package/src/components/variable-selector/config.json +5 -0
- package/src/components/variable-selector/index.tsx +116 -0
- package/src/components/variable-selector/styles.tsx +59 -0
- package/src/components/variable-selector/use-variable-tree.tsx +103 -0
- package/src/effects/auto-rename-ref/config.json +5 -0
- package/src/effects/auto-rename-ref/index.ts +109 -0
- package/src/effects/index.ts +10 -0
- package/src/effects/provide-batch-input/config.json +5 -0
- package/src/effects/provide-batch-input/index.ts +43 -0
- package/src/effects/provide-batch-outputs/config.json +5 -0
- package/src/effects/provide-batch-outputs/index.ts +38 -0
- package/src/effects/provide-json-schema-outputs/config.json +8 -0
- package/src/effects/provide-json-schema-outputs/index.ts +28 -0
- package/src/effects/sync-variable-title/config.json +5 -0
- package/src/effects/sync-variable-title/index.ts +28 -0
- package/src/form-plugins/batch-outputs-plugin/config.json +7 -0
- package/src/form-plugins/batch-outputs-plugin/index.ts +104 -0
- package/src/form-plugins/index.ts +6 -0
- package/src/index.ts +10 -0
- package/src/typings/flow-value/config.json +5 -0
- package/src/typings/flow-value/index.ts +32 -0
- package/src/typings/index.ts +7 -0
- package/src/typings/json-schema/config.json +5 -0
- package/src/typings/json-schema/index.ts +36 -0
- package/src/utils/format-legacy-refs/config.json +5 -0
- package/src/utils/format-legacy-refs/index.ts +158 -0
- package/src/utils/format-legacy-refs/readme.md +38 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/json-schema/config.json +5 -0
- package/src/utils/json-schema/index.ts +180 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React, { useCallback } from 'react';
|
|
7
|
+
|
|
8
|
+
import { ASTMatch, BaseVariableField, useAvailableVariables } from '@flowgram.ai/editor';
|
|
9
|
+
import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
|
|
10
|
+
import { Icon } from '@douyinfe/semi-ui';
|
|
11
|
+
|
|
12
|
+
import { ArrayIcons, VariableTypeIcons } from '../type-selector/constants';
|
|
13
|
+
import { JsonSchemaUtils } from '../../utils/json-schema';
|
|
14
|
+
import { IJsonSchema } from '../../typings/json-schema';
|
|
15
|
+
|
|
16
|
+
type VariableField = BaseVariableField<{ icon?: string | JSX.Element; title?: string }>;
|
|
17
|
+
|
|
18
|
+
export function useVariableTree(params: {
|
|
19
|
+
includeSchema?: IJsonSchema | IJsonSchema[];
|
|
20
|
+
excludeSchema?: IJsonSchema | IJsonSchema[];
|
|
21
|
+
}): TreeNodeData[] {
|
|
22
|
+
const { includeSchema, excludeSchema } = params;
|
|
23
|
+
|
|
24
|
+
const variables = useAvailableVariables();
|
|
25
|
+
|
|
26
|
+
const getVariableTypeIcon = useCallback((variable: VariableField) => {
|
|
27
|
+
if (variable.meta?.icon) {
|
|
28
|
+
if (typeof variable.meta.icon === 'string') {
|
|
29
|
+
return <img style={{ marginRight: 8 }} width={12} height={12} src={variable.meta.icon} />;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return variable.meta.icon;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const _type = variable.type;
|
|
36
|
+
|
|
37
|
+
if (ASTMatch.isArray(_type)) {
|
|
38
|
+
return (
|
|
39
|
+
<Icon
|
|
40
|
+
size="small"
|
|
41
|
+
svg={ArrayIcons[_type.items?.kind.toLowerCase()] || VariableTypeIcons.array}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (ASTMatch.isCustomType(_type)) {
|
|
47
|
+
return <Icon size="small" svg={VariableTypeIcons[_type.typeName.toLowerCase()]} />;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return <Icon size="small" svg={VariableTypeIcons[variable.type?.kind.toLowerCase()]} />;
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
const renderVariable = (
|
|
54
|
+
variable: VariableField,
|
|
55
|
+
parentFields: VariableField[] = []
|
|
56
|
+
): TreeNodeData | null => {
|
|
57
|
+
let type = variable?.type;
|
|
58
|
+
|
|
59
|
+
if (!type) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let children: TreeNodeData[] | undefined;
|
|
64
|
+
|
|
65
|
+
if (ASTMatch.isObject(type)) {
|
|
66
|
+
children = (type.properties || [])
|
|
67
|
+
.map((_property) => renderVariable(_property as VariableField, [...parentFields, variable]))
|
|
68
|
+
.filter(Boolean) as TreeNodeData[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const keyPath = [...parentFields.map((_field) => _field.key), variable.key];
|
|
72
|
+
const key = keyPath.join('.');
|
|
73
|
+
|
|
74
|
+
const isSchemaInclude = includeSchema
|
|
75
|
+
? JsonSchemaUtils.isASTMatchSchema(type, includeSchema)
|
|
76
|
+
: true;
|
|
77
|
+
const isSchemaExclude = excludeSchema
|
|
78
|
+
? JsonSchemaUtils.isASTMatchSchema(type, excludeSchema)
|
|
79
|
+
: false;
|
|
80
|
+
|
|
81
|
+
const isSchemaMatch = isSchemaInclude && !isSchemaExclude;
|
|
82
|
+
|
|
83
|
+
// If not match, and no children, return null
|
|
84
|
+
if (!isSchemaMatch && !children?.length) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
key: key,
|
|
90
|
+
label: variable.meta?.title || variable.key,
|
|
91
|
+
value: key,
|
|
92
|
+
keyPath,
|
|
93
|
+
icon: getVariableTypeIcon(variable),
|
|
94
|
+
children,
|
|
95
|
+
disabled: !isSchemaMatch,
|
|
96
|
+
rootMeta: parentFields[0]?.meta,
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return [...variables.slice(0).reverse()]
|
|
101
|
+
.map((_variable) => renderVariable(_variable as VariableField))
|
|
102
|
+
.filter(Boolean) as TreeNodeData[];
|
|
103
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { isArray, isObject } from 'lodash';
|
|
7
|
+
import {
|
|
8
|
+
DataEvent,
|
|
9
|
+
Effect,
|
|
10
|
+
EffectOptions,
|
|
11
|
+
VariableFieldKeyRenameService,
|
|
12
|
+
} from '@flowgram.ai/editor';
|
|
13
|
+
|
|
14
|
+
import { IFlowRefValue } from '../../typings';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Auto rename ref when form item's key is renamed
|
|
18
|
+
*
|
|
19
|
+
* Example:
|
|
20
|
+
*
|
|
21
|
+
* formMeta: {
|
|
22
|
+
* effects: {
|
|
23
|
+
* "inputsValues": autoRenameRefEffect,
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
*/
|
|
27
|
+
export const autoRenameRefEffect: EffectOptions[] = [
|
|
28
|
+
{
|
|
29
|
+
event: DataEvent.onValueInit,
|
|
30
|
+
effect: ((params) => {
|
|
31
|
+
const { context, form, name } = params;
|
|
32
|
+
|
|
33
|
+
const renameService = context.node.getService(VariableFieldKeyRenameService);
|
|
34
|
+
|
|
35
|
+
const disposable = renameService.onRename(({ before, after }) => {
|
|
36
|
+
const beforeKeyPath = [
|
|
37
|
+
...before.parentFields.map((_field) => _field.key).reverse(),
|
|
38
|
+
before.key,
|
|
39
|
+
];
|
|
40
|
+
const afterKeyPath = [
|
|
41
|
+
...after.parentFields.map((_field) => _field.key).reverse(),
|
|
42
|
+
after.key,
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
// traverse rename refs inside form item 'name'
|
|
46
|
+
traverseRef(name, form.getValueIn(name), (_drilldownName, _v) => {
|
|
47
|
+
if (isRefMatch(_v, beforeKeyPath)) {
|
|
48
|
+
_v.content = [...afterKeyPath, ...(_v.content || [])?.slice(beforeKeyPath.length)];
|
|
49
|
+
form.setValueIn(_drilldownName, _v);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return () => {
|
|
55
|
+
disposable.dispose();
|
|
56
|
+
};
|
|
57
|
+
}) as Effect,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* If ref value's keyPath is the under as targetKeyPath
|
|
63
|
+
* @param value
|
|
64
|
+
* @param targetKeyPath
|
|
65
|
+
* @returns
|
|
66
|
+
*/
|
|
67
|
+
function isRefMatch(value: IFlowRefValue, targetKeyPath: string[]) {
|
|
68
|
+
return targetKeyPath.every((_key, index) => _key === value.content?.[index]);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* If value is ref
|
|
73
|
+
* @param value
|
|
74
|
+
* @returns
|
|
75
|
+
*/
|
|
76
|
+
function isRef(value: any): value is IFlowRefValue {
|
|
77
|
+
return (
|
|
78
|
+
value?.type === 'ref' && Array.isArray(value?.content) && typeof value?.content[0] === 'string'
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Traverse value to find ref
|
|
84
|
+
* @param value
|
|
85
|
+
* @param options
|
|
86
|
+
* @returns
|
|
87
|
+
*/
|
|
88
|
+
function traverseRef(name: string, value: any, cb: (name: string, _v: IFlowRefValue) => void) {
|
|
89
|
+
if (isObject(value)) {
|
|
90
|
+
if (isRef(value)) {
|
|
91
|
+
cb(name, value);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
Object.entries(value).forEach(([_key, _value]) => {
|
|
96
|
+
traverseRef(`${name}.${_key}`, _value, cb);
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (isArray(value)) {
|
|
102
|
+
value.forEach((_value, idx) => {
|
|
103
|
+
traverseRef(`${name}[${idx}]`, _value, cb);
|
|
104
|
+
});
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export * from './provide-batch-input';
|
|
7
|
+
export * from './provide-batch-outputs';
|
|
8
|
+
export * from './auto-rename-ref';
|
|
9
|
+
export * from './provide-json-schema-outputs';
|
|
10
|
+
export * from './sync-variable-title';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ASTFactory,
|
|
8
|
+
EffectOptions,
|
|
9
|
+
FlowNodeRegistry,
|
|
10
|
+
createEffectFromVariableProvider,
|
|
11
|
+
getNodeForm,
|
|
12
|
+
} from '@flowgram.ai/editor';
|
|
13
|
+
|
|
14
|
+
import { IFlowRefValue } from '../../typings';
|
|
15
|
+
|
|
16
|
+
export const provideBatchInputEffect: EffectOptions[] = createEffectFromVariableProvider({
|
|
17
|
+
private: true,
|
|
18
|
+
parse: (value: IFlowRefValue, ctx) => [
|
|
19
|
+
ASTFactory.createVariableDeclaration({
|
|
20
|
+
key: `${ctx.node.id}_locals`,
|
|
21
|
+
meta: {
|
|
22
|
+
title: getNodeForm(ctx.node)?.getValueIn('title'),
|
|
23
|
+
icon: ctx.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
|
|
24
|
+
},
|
|
25
|
+
type: ASTFactory.createObject({
|
|
26
|
+
properties: [
|
|
27
|
+
ASTFactory.createProperty({
|
|
28
|
+
key: 'item',
|
|
29
|
+
initializer: ASTFactory.createEnumerateExpression({
|
|
30
|
+
enumerateFor: ASTFactory.createKeyPathExpression({
|
|
31
|
+
keyPath: value.content || [],
|
|
32
|
+
}),
|
|
33
|
+
}),
|
|
34
|
+
}),
|
|
35
|
+
ASTFactory.createProperty({
|
|
36
|
+
key: 'index',
|
|
37
|
+
type: ASTFactory.createNumber(),
|
|
38
|
+
}),
|
|
39
|
+
],
|
|
40
|
+
}),
|
|
41
|
+
}),
|
|
42
|
+
],
|
|
43
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ASTFactory,
|
|
8
|
+
EffectOptions,
|
|
9
|
+
FlowNodeRegistry,
|
|
10
|
+
createEffectFromVariableProvider,
|
|
11
|
+
getNodeForm,
|
|
12
|
+
} from '@flowgram.ai/editor';
|
|
13
|
+
|
|
14
|
+
import { IFlowRefValue } from '../../typings';
|
|
15
|
+
|
|
16
|
+
export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariableProvider({
|
|
17
|
+
parse: (value: Record<string, IFlowRefValue>, ctx) => [
|
|
18
|
+
ASTFactory.createVariableDeclaration({
|
|
19
|
+
key: `${ctx.node.id}`,
|
|
20
|
+
meta: {
|
|
21
|
+
title: getNodeForm(ctx.node)?.getValueIn('title'),
|
|
22
|
+
icon: ctx.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
|
|
23
|
+
},
|
|
24
|
+
type: ASTFactory.createObject({
|
|
25
|
+
properties: Object.entries(value).map(([_key, value]) =>
|
|
26
|
+
ASTFactory.createProperty({
|
|
27
|
+
key: _key,
|
|
28
|
+
initializer: ASTFactory.createWrapArrayExpression({
|
|
29
|
+
wrapFor: ASTFactory.createKeyPathExpression({
|
|
30
|
+
keyPath: value.content || [],
|
|
31
|
+
}),
|
|
32
|
+
}),
|
|
33
|
+
})
|
|
34
|
+
),
|
|
35
|
+
}),
|
|
36
|
+
}),
|
|
37
|
+
],
|
|
38
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ASTFactory,
|
|
8
|
+
EffectOptions,
|
|
9
|
+
FlowNodeRegistry,
|
|
10
|
+
createEffectFromVariableProvider,
|
|
11
|
+
getNodeForm,
|
|
12
|
+
} from '@flowgram.ai/editor';
|
|
13
|
+
|
|
14
|
+
import { JsonSchemaUtils } from '../../utils';
|
|
15
|
+
import { IJsonSchema } from '../../typings';
|
|
16
|
+
|
|
17
|
+
export const provideJsonSchemaOutputs: EffectOptions[] = createEffectFromVariableProvider({
|
|
18
|
+
parse: (value: IJsonSchema, ctx) => [
|
|
19
|
+
ASTFactory.createVariableDeclaration({
|
|
20
|
+
key: `${ctx.node.id}`,
|
|
21
|
+
meta: {
|
|
22
|
+
title: getNodeForm(ctx.node)?.getValueIn('title') || ctx.node.id,
|
|
23
|
+
icon: ctx.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
|
|
24
|
+
},
|
|
25
|
+
type: JsonSchemaUtils.schemaToAST(value),
|
|
26
|
+
}),
|
|
27
|
+
],
|
|
28
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
DataEvent,
|
|
8
|
+
Effect,
|
|
9
|
+
EffectOptions,
|
|
10
|
+
FlowNodeRegistry,
|
|
11
|
+
FlowNodeVariableData,
|
|
12
|
+
} from '@flowgram.ai/editor';
|
|
13
|
+
|
|
14
|
+
export const syncVariableTitle: EffectOptions[] = [
|
|
15
|
+
{
|
|
16
|
+
event: DataEvent.onValueChange,
|
|
17
|
+
effect: (({ value, context }) => {
|
|
18
|
+
context.node.getData(FlowNodeVariableData).allScopes.forEach((_scope) => {
|
|
19
|
+
_scope.output.variables.forEach((_var) => {
|
|
20
|
+
_var.updateMeta({
|
|
21
|
+
title: value || context.node.id,
|
|
22
|
+
icon: context.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}) as Effect,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ASTFactory,
|
|
8
|
+
createEffectFromVariableProvider,
|
|
9
|
+
defineFormPluginCreator,
|
|
10
|
+
FlowNodeRegistry,
|
|
11
|
+
getNodeForm,
|
|
12
|
+
getNodePrivateScope,
|
|
13
|
+
getNodeScope,
|
|
14
|
+
ScopeChainTransformService,
|
|
15
|
+
type EffectOptions,
|
|
16
|
+
type FormPluginCreator,
|
|
17
|
+
FlowNodeScopeType,
|
|
18
|
+
} from '@flowgram.ai/editor';
|
|
19
|
+
|
|
20
|
+
import { IFlowRefValue } from '../../typings';
|
|
21
|
+
|
|
22
|
+
export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariableProvider({
|
|
23
|
+
parse: (value: Record<string, IFlowRefValue>, ctx) => [
|
|
24
|
+
ASTFactory.createVariableDeclaration({
|
|
25
|
+
key: `${ctx.node.id}`,
|
|
26
|
+
meta: {
|
|
27
|
+
title: getNodeForm(ctx.node)?.getValueIn('title'),
|
|
28
|
+
icon: ctx.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
|
|
29
|
+
},
|
|
30
|
+
type: ASTFactory.createObject({
|
|
31
|
+
properties: Object.entries(value).map(([_key, value]) =>
|
|
32
|
+
ASTFactory.createProperty({
|
|
33
|
+
key: _key,
|
|
34
|
+
initializer: ASTFactory.createWrapArrayExpression({
|
|
35
|
+
wrapFor: ASTFactory.createKeyPathExpression({
|
|
36
|
+
keyPath: value?.content || [],
|
|
37
|
+
}),
|
|
38
|
+
}),
|
|
39
|
+
})
|
|
40
|
+
),
|
|
41
|
+
}),
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Free Layout only right now
|
|
48
|
+
*/
|
|
49
|
+
export const createBatchOutputsFormPlugin: FormPluginCreator<{ outputKey: string }> =
|
|
50
|
+
defineFormPluginCreator({
|
|
51
|
+
name: 'batch-outputs-plugin',
|
|
52
|
+
onSetupFormMeta({ mergeEffect }, { outputKey }) {
|
|
53
|
+
mergeEffect({
|
|
54
|
+
[outputKey]: provideBatchOutputsEffect,
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
onInit(ctx, { outputKey }) {
|
|
58
|
+
const chainTransformService = ctx.node.getService(ScopeChainTransformService);
|
|
59
|
+
|
|
60
|
+
const batchNodeType = ctx.node.flowNodeType;
|
|
61
|
+
|
|
62
|
+
const transformerId = `${batchNodeType}-outputs`;
|
|
63
|
+
|
|
64
|
+
if (chainTransformService.hasTransformer(transformerId)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
chainTransformService.registerTransformer(transformerId, {
|
|
69
|
+
transformCovers: (covers, ctx) => {
|
|
70
|
+
const node = ctx.scope.meta?.node;
|
|
71
|
+
|
|
72
|
+
// Child Node's variable can cover parent
|
|
73
|
+
if (node?.parent?.flowNodeType === batchNodeType) {
|
|
74
|
+
return [...covers, getNodeScope(node.parent)];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return covers;
|
|
78
|
+
},
|
|
79
|
+
transformDeps(scopes, ctx) {
|
|
80
|
+
const scopeMeta = ctx.scope.meta;
|
|
81
|
+
|
|
82
|
+
if (scopeMeta?.type === FlowNodeScopeType.private) {
|
|
83
|
+
return scopes;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const node = scopeMeta?.node;
|
|
87
|
+
|
|
88
|
+
// Public of Loop Node depends on child Node
|
|
89
|
+
if (node?.flowNodeType === batchNodeType) {
|
|
90
|
+
// Get all child blocks
|
|
91
|
+
const childBlocks = node.blocks;
|
|
92
|
+
|
|
93
|
+
// public scope of all child blocks
|
|
94
|
+
return [
|
|
95
|
+
getNodePrivateScope(node),
|
|
96
|
+
...childBlocks.map((_childBlock) => getNodeScope(_childBlock)),
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return scopes;
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface IFlowConstantValue {
|
|
7
|
+
type: 'constant';
|
|
8
|
+
content?: string | number | boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IFlowRefValue {
|
|
12
|
+
type: 'ref';
|
|
13
|
+
content?: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface IFlowExpressionValue {
|
|
17
|
+
type: 'expression';
|
|
18
|
+
content?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IFlowTemplateValue {
|
|
22
|
+
type: 'template';
|
|
23
|
+
content?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type IFlowValue =
|
|
27
|
+
| IFlowConstantValue
|
|
28
|
+
| IFlowRefValue
|
|
29
|
+
| IFlowExpressionValue
|
|
30
|
+
| IFlowTemplateValue;
|
|
31
|
+
|
|
32
|
+
export type IFlowConstantRefValue = IFlowConstantValue | IFlowRefValue;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type JsonSchemaBasicType =
|
|
7
|
+
| 'boolean'
|
|
8
|
+
| 'string'
|
|
9
|
+
| 'integer'
|
|
10
|
+
| 'number'
|
|
11
|
+
| 'object'
|
|
12
|
+
| 'array'
|
|
13
|
+
| 'map';
|
|
14
|
+
|
|
15
|
+
export interface IJsonSchema<T = string> {
|
|
16
|
+
type?: T;
|
|
17
|
+
default?: any;
|
|
18
|
+
title?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
enum?: (string | number)[];
|
|
21
|
+
properties?: Record<string, IJsonSchema<T>>;
|
|
22
|
+
additionalProperties?: IJsonSchema<T>;
|
|
23
|
+
items?: IJsonSchema<T>;
|
|
24
|
+
required?: string[];
|
|
25
|
+
$ref?: string;
|
|
26
|
+
extra?: {
|
|
27
|
+
index?: number;
|
|
28
|
+
// Used in BaseType.isEqualWithJSONSchema, the type comparison will be weak
|
|
29
|
+
weak?: boolean;
|
|
30
|
+
// Set the render component
|
|
31
|
+
formComponent?: string;
|
|
32
|
+
[key: string]: any;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type IBasicJsonSchema = IJsonSchema<JsonSchemaBasicType>;
|