@flowgram.ai/form-materials 0.2.16 → 0.2.18
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/materials.ts +6 -1
- package/bin/project.ts +5 -0
- package/dist/esm/index.js +462 -14
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +177 -6
- package/dist/index.d.ts +177 -6
- package/dist/index.js +482 -43
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- 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/index.tsx +5 -0
- package/src/components/condition-row/constants.ts +5 -0
- package/src/components/condition-row/hooks/useOp.tsx +5 -0
- package/src/components/condition-row/hooks/useRule.ts +5 -0
- package/src/components/condition-row/index.tsx +5 -0
- package/src/components/condition-row/styles.tsx +5 -0
- package/src/components/condition-row/types.ts +5 -0
- package/src/components/constant-input/index.tsx +5 -0
- package/src/components/constant-input/types.ts +5 -0
- package/src/components/dynamic-value-input/index.tsx +7 -0
- package/src/components/dynamic-value-input/styles.tsx +7 -0
- package/src/components/index.ts +8 -0
- package/src/components/json-schema-editor/components/blur-input.tsx +5 -0
- package/src/components/json-schema-editor/default-value.tsx +5 -0
- package/src/components/json-schema-editor/hooks.tsx +5 -0
- package/src/components/json-schema-editor/index.tsx +5 -0
- package/src/components/json-schema-editor/styles.tsx +5 -0
- package/src/components/json-schema-editor/types.ts +5 -0
- package/src/components/json-schema-editor/utils.ts +5 -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 +43 -0
- package/src/components/prompt-editor/styles.tsx +18 -0
- package/src/components/prompt-editor/types.tsx +16 -0
- package/src/components/prompt-editor-with-variables/config.json +10 -0
- package/src/components/prompt-editor-with-variables/extensions/variable.tsx +85 -0
- package/src/components/prompt-editor-with-variables/index.tsx +17 -0
- package/src/components/type-selector/constants.tsx +5 -0
- package/src/components/type-selector/index.tsx +5 -0
- package/src/components/variable-selector/index.tsx +9 -2
- package/src/components/variable-selector/styles.tsx +17 -1
- package/src/components/variable-selector/use-variable-tree.tsx +8 -3
- package/src/effects/auto-rename-ref/index.ts +5 -0
- package/src/effects/index.ts +5 -0
- package/src/effects/provide-batch-input/index.ts +5 -0
- package/src/effects/provide-batch-outputs/index.ts +5 -1
- package/src/effects/provide-json-schema-outputs/index.ts +5 -0
- package/src/effects/sync-variable-title/index.ts +5 -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 +6 -0
- package/src/typings/flow-value/index.ts +5 -0
- package/src/typings/index.ts +5 -0
- package/src/typings/json-schema/index.ts +5 -0
- package/src/utils/format-legacy-refs/index.ts +5 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/json-schema/index.ts +21 -2
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import styled, { css } from 'styled-components';
|
|
7
|
+
|
|
8
|
+
export const UIContainer = styled.div<{ $hasError?: boolean }>`
|
|
9
|
+
background-color: var(--semi-color-fill-0);
|
|
10
|
+
padding-left: 10px;
|
|
11
|
+
padding-right: 6px;
|
|
12
|
+
|
|
13
|
+
${({ $hasError }) =>
|
|
14
|
+
$hasError &&
|
|
15
|
+
css`
|
|
16
|
+
border: 1px solid var(--semi-color-danger-6);
|
|
17
|
+
`}
|
|
18
|
+
`;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { IFlowTemplateValue } from '../../typings';
|
|
9
|
+
|
|
10
|
+
export type PropsType = React.PropsWithChildren<{
|
|
11
|
+
value?: IFlowTemplateValue;
|
|
12
|
+
onChange: (value?: IFlowTemplateValue) => void;
|
|
13
|
+
readonly?: boolean;
|
|
14
|
+
hasError?: boolean;
|
|
15
|
+
style?: React.CSSProperties;
|
|
16
|
+
}>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React, { useEffect, useState } from 'react';
|
|
7
|
+
|
|
8
|
+
import { Popover, Tree } from '@douyinfe/semi-ui';
|
|
9
|
+
import {
|
|
10
|
+
Mention,
|
|
11
|
+
MentionOpenChangeEvent,
|
|
12
|
+
getCurrentMentionReplaceRange,
|
|
13
|
+
useEditor,
|
|
14
|
+
PositionMirror,
|
|
15
|
+
} from '@coze-editor/editor/react';
|
|
16
|
+
import { EditorAPI } from '@coze-editor/editor/preset-prompt';
|
|
17
|
+
|
|
18
|
+
import { useVariableTree } from '../../variable-selector';
|
|
19
|
+
|
|
20
|
+
function Variable() {
|
|
21
|
+
const [posKey, setPosKey] = useState('');
|
|
22
|
+
const [visible, setVisible] = useState(false);
|
|
23
|
+
const [position, setPosition] = useState(-1);
|
|
24
|
+
const editor = useEditor<EditorAPI>();
|
|
25
|
+
|
|
26
|
+
function insert(variablePath: string) {
|
|
27
|
+
const range = getCurrentMentionReplaceRange(editor.$view.state);
|
|
28
|
+
|
|
29
|
+
if (!range) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
editor.replaceText({
|
|
34
|
+
...range,
|
|
35
|
+
text: '{{' + variablePath + '}}',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
setVisible(false);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function handleOpenChange(e: MentionOpenChangeEvent) {
|
|
42
|
+
setPosition(e.state.selection.main.head);
|
|
43
|
+
setVisible(e.value);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!editor) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}, [editor, visible]);
|
|
51
|
+
|
|
52
|
+
const treeData = useVariableTree({});
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<>
|
|
56
|
+
<Mention triggerCharacters={['{', '{}']} onOpenChange={handleOpenChange} />
|
|
57
|
+
|
|
58
|
+
<Popover
|
|
59
|
+
visible={visible}
|
|
60
|
+
trigger="custom"
|
|
61
|
+
position="topLeft"
|
|
62
|
+
rePosKey={posKey}
|
|
63
|
+
content={
|
|
64
|
+
<div style={{ width: 300 }}>
|
|
65
|
+
<Tree
|
|
66
|
+
treeData={treeData}
|
|
67
|
+
onSelect={(v) => {
|
|
68
|
+
insert(v);
|
|
69
|
+
}}
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
72
|
+
}
|
|
73
|
+
>
|
|
74
|
+
{/* PositionMirror allows the Popover to appear at the specified cursor position */}
|
|
75
|
+
<PositionMirror
|
|
76
|
+
position={position}
|
|
77
|
+
// When Doc scroll, update position
|
|
78
|
+
onChange={() => setPosKey(String(Math.random()))}
|
|
79
|
+
/>
|
|
80
|
+
</Popover>
|
|
81
|
+
</>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export default Variable;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import Variable from './extensions/variable';
|
|
9
|
+
import { PromptEditor, PromptEditorPropsType } from '../prompt-editor';
|
|
10
|
+
|
|
11
|
+
export function PromptEditorWithVariables(props: PromptEditorPropsType) {
|
|
12
|
+
return (
|
|
13
|
+
<PromptEditor {...props}>
|
|
14
|
+
<Variable />
|
|
15
|
+
</PromptEditor>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
import React, { useMemo } from 'react';
|
|
2
7
|
|
|
3
8
|
import { TriggerRenderProps } from '@douyinfe/semi-ui/lib/es/treeSelect';
|
|
@@ -6,7 +11,7 @@ import { IconChevronDownStroked, IconIssueStroked } from '@douyinfe/semi-icons';
|
|
|
6
11
|
|
|
7
12
|
import { IJsonSchema } from '../../typings/json-schema';
|
|
8
13
|
import { useVariableTree } from './use-variable-tree';
|
|
9
|
-
import { UIRootTitle, UITag, UITreeSelect } from './styles';
|
|
14
|
+
import { UIRootTitle, UITag, UITreeSelect, UIVarName } from './styles';
|
|
10
15
|
|
|
11
16
|
interface PropTypes {
|
|
12
17
|
value?: string[];
|
|
@@ -25,6 +30,8 @@ interface PropTypes {
|
|
|
25
30
|
|
|
26
31
|
export type VariableSelectorProps = PropTypes;
|
|
27
32
|
|
|
33
|
+
export { useVariableTree };
|
|
34
|
+
|
|
28
35
|
export const VariableSelector = ({
|
|
29
36
|
value,
|
|
30
37
|
config = {},
|
|
@@ -95,7 +102,7 @@ export const VariableSelector = ({
|
|
|
95
102
|
<UIRootTitle>
|
|
96
103
|
{_option.rootMeta?.title ? `${_option.rootMeta?.title} -` : null}
|
|
97
104
|
</UIRootTitle>
|
|
98
|
-
{_option.label}
|
|
105
|
+
<UIVarName>{_option.label}</UIVarName>
|
|
99
106
|
</UITag>
|
|
100
107
|
);
|
|
101
108
|
}}
|
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
import styled from 'styled-components';
|
|
2
7
|
import { Tag, TreeSelect } from '@douyinfe/semi-ui';
|
|
3
8
|
|
|
4
|
-
export const UIRootTitle = styled.
|
|
9
|
+
export const UIRootTitle = styled.div`
|
|
5
10
|
margin-right: 4px;
|
|
11
|
+
min-width: 20px;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
text-overflow: ellipsis;
|
|
14
|
+
white-space: nowrap;
|
|
6
15
|
color: var(--semi-color-text-2);
|
|
7
16
|
`;
|
|
8
17
|
|
|
18
|
+
export const UIVarName = styled.div`
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
text-overflow: ellipsis;
|
|
21
|
+
white-space: nowrap;
|
|
22
|
+
min-width: 50%;
|
|
23
|
+
`;
|
|
24
|
+
|
|
9
25
|
export const UITag = styled(Tag)`
|
|
10
26
|
width: 100%;
|
|
11
27
|
display: flex;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
import React, { useCallback } from 'react';
|
|
2
7
|
|
|
3
|
-
import {
|
|
8
|
+
import { ASTMatch, BaseVariableField, useAvailableVariables } from '@flowgram.ai/editor';
|
|
4
9
|
import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
|
|
5
10
|
import { Icon } from '@douyinfe/semi-ui';
|
|
6
11
|
|
|
@@ -16,7 +21,7 @@ export function useVariableTree(params: {
|
|
|
16
21
|
}): TreeNodeData[] {
|
|
17
22
|
const { includeSchema, excludeSchema } = params;
|
|
18
23
|
|
|
19
|
-
const
|
|
24
|
+
const variables = useAvailableVariables();
|
|
20
25
|
|
|
21
26
|
const getVariableTypeIcon = useCallback((variable: VariableField) => {
|
|
22
27
|
if (variable.meta?.icon) {
|
|
@@ -92,7 +97,7 @@ export function useVariableTree(params: {
|
|
|
92
97
|
};
|
|
93
98
|
};
|
|
94
99
|
|
|
95
|
-
return [...
|
|
100
|
+
return [...variables.slice(0).reverse()]
|
|
96
101
|
.map((_variable) => renderVariable(_variable as VariableField))
|
|
97
102
|
.filter(Boolean) as TreeNodeData[];
|
|
98
103
|
}
|
package/src/effects/index.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
import {
|
|
2
7
|
ASTFactory,
|
|
3
8
|
EffectOptions,
|
|
@@ -9,7 +14,6 @@ import {
|
|
|
9
14
|
import { IFlowRefValue } from '../../typings';
|
|
10
15
|
|
|
11
16
|
export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariableProvider({
|
|
12
|
-
private: true,
|
|
13
17
|
parse: (value: Record<string, IFlowRefValue>, ctx) => [
|
|
14
18
|
ASTFactory.createVariableDeclaration({
|
|
15
19
|
key: `${ctx.node.id}`,
|
|
@@ -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
CHANGED
package/src/typings/index.ts
CHANGED
package/src/utils/index.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
import { get } from 'lodash';
|
|
2
7
|
import { ASTFactory, ASTKind, ASTMatch, ASTNode, ASTNodeJSON, BaseType } from '@flowgram.ai/editor';
|
|
3
8
|
|
|
@@ -37,7 +42,10 @@ export namespace JsonSchemaUtils {
|
|
|
37
42
|
.map(([key, _property]) => ({
|
|
38
43
|
key,
|
|
39
44
|
type: schemaToAST(_property),
|
|
40
|
-
meta: {
|
|
45
|
+
meta: {
|
|
46
|
+
title: _property.title,
|
|
47
|
+
description: _property.description,
|
|
48
|
+
},
|
|
41
49
|
})),
|
|
42
50
|
});
|
|
43
51
|
case 'array':
|
|
@@ -109,7 +117,18 @@ export namespace JsonSchemaUtils {
|
|
|
109
117
|
type: 'object',
|
|
110
118
|
properties: drilldown
|
|
111
119
|
? Object.fromEntries(
|
|
112
|
-
|
|
120
|
+
typeAST.properties.map((property) => {
|
|
121
|
+
const schema = astToSchema(property.type);
|
|
122
|
+
|
|
123
|
+
if (property.meta?.title && schema) {
|
|
124
|
+
schema.title = property.meta.title;
|
|
125
|
+
}
|
|
126
|
+
if (property.meta?.description && schema) {
|
|
127
|
+
schema.description = property.meta.description;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return [property.key, schema!];
|
|
131
|
+
})
|
|
113
132
|
)
|
|
114
133
|
: {},
|
|
115
134
|
};
|