fix: where HTTP node URL, JSON text, and raw text template rendering could not find the corresponding rendering variables (#745)
This commit is contained in:
parent
ff00dcb31b
commit
4ff734f15f
|
|
@ -4655,7 +4655,7 @@ func TestJsonSerializationDeserializationWithWarning(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetAppVariablesFOrSubProcesses(t *testing.T) {
|
func TestSetAppVariablesForSubProcesses(t *testing.T) {
|
||||||
mockey.PatchConvey("app variables for sub_process", t, func() {
|
mockey.PatchConvey("app variables for sub_process", t, func() {
|
||||||
r := newWfTestRunner(t)
|
r := newWfTestRunner(t)
|
||||||
defer r.closeFn()
|
defer r.closeFn()
|
||||||
|
|
@ -4672,3 +4672,79 @@ func TestSetAppVariablesFOrSubProcesses(t *testing.T) {
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHttpImplicitDependencies(t *testing.T) {
|
||||||
|
mockey.PatchConvey("test http implicit dependencies", t, func() {
|
||||||
|
r := newWfTestRunner(t)
|
||||||
|
defer r.closeFn()
|
||||||
|
|
||||||
|
r.appVarS.EXPECT().Get(gomock.Any(), gomock.Any(), gomock.Any()).Return("1.0", nil).AnyTimes()
|
||||||
|
|
||||||
|
idStr := r.load("httprequester/http_implicit_dependencies.json")
|
||||||
|
|
||||||
|
r.publish(idStr, "v0.0.1", true)
|
||||||
|
|
||||||
|
runner := mockcode.NewMockRunner(r.ctrl)
|
||||||
|
runner.EXPECT().Run(gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, request *coderunner.RunRequest) (*coderunner.RunResponse, error) {
|
||||||
|
in := request.Params["input"]
|
||||||
|
_ = in
|
||||||
|
result := make(map[string]any)
|
||||||
|
err := sonic.UnmarshalString(in.(string), &result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &coderunner.RunResponse{
|
||||||
|
Result: result,
|
||||||
|
}, nil
|
||||||
|
}).AnyTimes()
|
||||||
|
|
||||||
|
code.SetCodeRunner(runner)
|
||||||
|
|
||||||
|
mockey.PatchConvey("test http node implicit dependencies", func() {
|
||||||
|
input := map[string]string{
|
||||||
|
"input": "a",
|
||||||
|
}
|
||||||
|
result, _ := r.openapiSyncRun(idStr, input)
|
||||||
|
|
||||||
|
batchRets := result["batch"].([]any)
|
||||||
|
loopRets := result["loop"].([]any)
|
||||||
|
|
||||||
|
for _, r := range batchRets {
|
||||||
|
assert.Contains(t, []any{
|
||||||
|
"http://echo.apifox.com/anything?aa=1.0&cc=1",
|
||||||
|
"http://echo.apifox.com/anything?aa=1.0&cc=2",
|
||||||
|
}, r)
|
||||||
|
}
|
||||||
|
for _, r := range loopRets {
|
||||||
|
assert.Contains(t, []any{
|
||||||
|
"http://echo.apifox.com/anything?a=1&m=123",
|
||||||
|
"http://echo.apifox.com/anything?a=2&m=123",
|
||||||
|
}, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mockey.PatchConvey("node debug http node implicit dependencies", func() {
|
||||||
|
exeID := r.nodeDebug(idStr, "109387",
|
||||||
|
withNDInput(map[string]string{
|
||||||
|
"__apiInfo_url_87fc7c69536cae843fa7f5113cf0067b": "m",
|
||||||
|
"__apiInfo_url_ac86361e3cd503952e71986dc091fa6f": "a",
|
||||||
|
"__body_bodyData_json_ac86361e3cd503952e71986dc091fa6f": "b",
|
||||||
|
"__body_bodyData_json_f77817a7cf8441279e1cfd8af4eeb1da": "1",
|
||||||
|
}))
|
||||||
|
|
||||||
|
e := r.getProcess(idStr, exeID, withSpecificNodeID("109387"))
|
||||||
|
e.assertSuccess()
|
||||||
|
|
||||||
|
ret := make(map[string]any)
|
||||||
|
err := sonic.UnmarshalString(e.output, &ret)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
err = sonic.UnmarshalString(ret["body"].(string), &ret)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, ret["url"].(string), "http://echo.apifox.com/anything?a=a&m=m")
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ func CanvasBlockInputToTypeInfo(b *vo.BlockInput) (tInfo *vo.TypeInfo, err error
|
||||||
}
|
}
|
||||||
tInfo.Properties[subV.Name] = subTInfo
|
tInfo.Properties[subV.Name] = subTInfo
|
||||||
} else if b.Value.Type == vo.BlockInputValueTypeObjectRef {
|
} else if b.Value.Type == vo.BlockInputValueTypeObjectRef {
|
||||||
subV, err := parseParam(subVAny)
|
subV, err := ParseParam(subVAny)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +195,7 @@ func CanvasBlockInputToFieldInfo(b *vo.BlockInput, path einoCompose.FieldPath, p
|
||||||
|
|
||||||
for i := range paramList {
|
for i := range paramList {
|
||||||
paramAny := paramList[i]
|
paramAny := paramList[i]
|
||||||
param, err := parseParam(paramAny)
|
param, err := ParseParam(paramAny)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -343,7 +343,7 @@ func parseBlockInputRef(content any) (*vo.BlockInputReference, error) {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseParam(v any) (*vo.Param, error) {
|
func ParseParam(v any) (*vo.Param, error) {
|
||||||
if pa, ok := v.(*vo.Param); ok {
|
if pa, ok := v.(*vo.Param); ok {
|
||||||
return pa, nil
|
return pa, nil
|
||||||
}
|
}
|
||||||
|
|
@ -497,7 +497,7 @@ func SetOutputTypesForNodeSchema(n *vo.Node, ns *schema.NodeSchema) error {
|
||||||
|
|
||||||
func SetOutputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema) error {
|
func SetOutputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema) error {
|
||||||
for _, vAny := range n.Data.Outputs {
|
for _, vAny := range n.Data.Outputs {
|
||||||
param, err := parseParam(vAny)
|
param, err := ParseParam(vAny)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -565,7 +565,7 @@ func BlockInputToNamedTypeInfo(name string, b *vo.BlockInput) (*vo.NamedTypeInfo
|
||||||
}
|
}
|
||||||
tInfo.Properties = append(tInfo.Properties, subNInfo)
|
tInfo.Properties = append(tInfo.Properties, subNInfo)
|
||||||
} else if b.Value.Type == vo.BlockInputValueTypeObjectRef {
|
} else if b.Value.Type == vo.BlockInputValueTypeObjectRef {
|
||||||
subV, err := parseParam(subVAny)
|
subV, err := ParseParam(subVAny)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,578 @@
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "100001",
|
||||||
|
"type": "1",
|
||||||
|
"meta": {
|
||||||
|
"position": {
|
||||||
|
"x": 180,
|
||||||
|
"y": 26.950000000000003
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nodeMeta": {
|
||||||
|
"description": "工作流的起始节点,用于设定启动工作流需要的信息",
|
||||||
|
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start-v2.jpg",
|
||||||
|
"subTitle": "",
|
||||||
|
"title": "开始"
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "input",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"trigger_parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "900001",
|
||||||
|
"type": "2",
|
||||||
|
"meta": {
|
||||||
|
"position": {
|
||||||
|
"x": 2880,
|
||||||
|
"y": 13.950000000000003
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nodeMeta": {
|
||||||
|
"description": "工作流的最终节点,用于返回工作流运行后的结果信息",
|
||||||
|
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End-v2.jpg",
|
||||||
|
"subTitle": "",
|
||||||
|
"title": "结束"
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"terminatePlan": "returnVariables",
|
||||||
|
"inputParameters": [
|
||||||
|
{
|
||||||
|
"name": "batch",
|
||||||
|
"input": {
|
||||||
|
"type": "list",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "ref",
|
||||||
|
"content": {
|
||||||
|
"source": "block-output",
|
||||||
|
"blockID": "125743",
|
||||||
|
"name": "output"
|
||||||
|
},
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 99
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "loop",
|
||||||
|
"input": {
|
||||||
|
"type": "list",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "ref",
|
||||||
|
"content": {
|
||||||
|
"source": "block-output",
|
||||||
|
"blockID": "122230",
|
||||||
|
"name": "output"
|
||||||
|
},
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 99
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "122230",
|
||||||
|
"type": "21",
|
||||||
|
"meta": {
|
||||||
|
"position": {
|
||||||
|
"x": 941.8355065195586,
|
||||||
|
"y": -65.71715145436308
|
||||||
|
},
|
||||||
|
"canvasPosition": {
|
||||||
|
"x": 560,
|
||||||
|
"y": 319.9
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nodeMeta": {
|
||||||
|
"title": "循环",
|
||||||
|
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Loop-v2.jpg",
|
||||||
|
"description": "用于通过设定循环次数和逻辑,重复执行一系列任务",
|
||||||
|
"mainColor": "#00B2B2",
|
||||||
|
"subTitle": "循环"
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"loopType": "array",
|
||||||
|
"loopCount": {
|
||||||
|
"type": "integer",
|
||||||
|
"value": {
|
||||||
|
"type": "literal",
|
||||||
|
"content": "10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"variableParameters": [
|
||||||
|
{
|
||||||
|
"name": "m",
|
||||||
|
"input": {
|
||||||
|
"type": "string",
|
||||||
|
"value": {
|
||||||
|
"type": "literal",
|
||||||
|
"content": "123",
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputParameters": [
|
||||||
|
{
|
||||||
|
"name": "input",
|
||||||
|
"input": {
|
||||||
|
"type": "list",
|
||||||
|
"value": {
|
||||||
|
"type": "literal",
|
||||||
|
"content": "[\"1\",\"2\"]",
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 99
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "output",
|
||||||
|
"input": {
|
||||||
|
"type": "list",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "ref",
|
||||||
|
"content": {
|
||||||
|
"source": "block-output",
|
||||||
|
"blockID": "164858",
|
||||||
|
"name": "url"
|
||||||
|
},
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blocks": [
|
||||||
|
{
|
||||||
|
"id": "109387",
|
||||||
|
"type": "45",
|
||||||
|
"meta": {
|
||||||
|
"position": {
|
||||||
|
"x": 180,
|
||||||
|
"y": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nodeMeta": {
|
||||||
|
"title": "HTTP 请求",
|
||||||
|
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-HTTP.png",
|
||||||
|
"description": "用于发送API请求,从接口返回数据",
|
||||||
|
"mainColor": "#3071F2",
|
||||||
|
"subTitle": "HTTP 请求"
|
||||||
|
},
|
||||||
|
"inputParameters": [],
|
||||||
|
"inputs": {
|
||||||
|
"apiInfo": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "http://echo.apifox.com/anything?a={{block_output_122230.input}}&m={{block_output_122230.m}}"
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"bodyType": "JSON",
|
||||||
|
"bodyData": {
|
||||||
|
"binary": {
|
||||||
|
"fileURL": {
|
||||||
|
"type": "string",
|
||||||
|
"value": {
|
||||||
|
"type": "ref",
|
||||||
|
"content": {
|
||||||
|
"source": "block-output",
|
||||||
|
"blockID": "",
|
||||||
|
"name": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"json": "{\n \"index\": {{block_output_122230.index}},\n \"value\": \"{{block_output_122230.input}}\"\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"headers": [],
|
||||||
|
"params": [],
|
||||||
|
"auth": {
|
||||||
|
"authType": "BEARER_AUTH",
|
||||||
|
"authData": {
|
||||||
|
"customData": {
|
||||||
|
"addTo": "header"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authOpen": false
|
||||||
|
},
|
||||||
|
"setting": {
|
||||||
|
"timeout": 120,
|
||||||
|
"retryTimes": 3
|
||||||
|
},
|
||||||
|
"settingOnError": {}
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "body"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"name": "statusCode"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "headers"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settingOnError": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "164858",
|
||||||
|
"type": "5",
|
||||||
|
"meta": {
|
||||||
|
"position": {
|
||||||
|
"x": 640,
|
||||||
|
"y": 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nodeMeta": {
|
||||||
|
"title": "代码_1",
|
||||||
|
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Code-v2.jpg",
|
||||||
|
"description": "编写代码,处理输入变量来生成返回值",
|
||||||
|
"mainColor": "#00B2B2",
|
||||||
|
"subTitle": "代码"
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"inputParameters": [
|
||||||
|
{
|
||||||
|
"name": "input",
|
||||||
|
"input": {
|
||||||
|
"type": "string",
|
||||||
|
"value": {
|
||||||
|
"type": "ref",
|
||||||
|
"content": {
|
||||||
|
"source": "block-output",
|
||||||
|
"blockID": "109387",
|
||||||
|
"name": "body"
|
||||||
|
},
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"code": "import json\nasync def main(args: Args) -> Output:\n params = args.params\n input_string = params['input']\n return json.loads(input_string)",
|
||||||
|
"language": 3,
|
||||||
|
"settingOnError": {
|
||||||
|
"processType": 1,
|
||||||
|
"timeoutMs": 60000,
|
||||||
|
"retryTimes": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"name": "args",
|
||||||
|
"schema": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "url"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edges": [
|
||||||
|
{
|
||||||
|
"sourceNodeID": "122230",
|
||||||
|
"targetNodeID": "109387",
|
||||||
|
"sourcePortID": "loop-function-inline-output"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sourceNodeID": "109387",
|
||||||
|
"targetNodeID": "164858"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sourceNodeID": "164858",
|
||||||
|
"targetNodeID": "122230",
|
||||||
|
"targetPortID": "loop-function-inline-input"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "125743",
|
||||||
|
"type": "28",
|
||||||
|
"meta": {
|
||||||
|
"position": {
|
||||||
|
"x": 2090,
|
||||||
|
"y": 13
|
||||||
|
},
|
||||||
|
"canvasPosition": {
|
||||||
|
"x": 1680,
|
||||||
|
"y": 306.9
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nodeMeta": {
|
||||||
|
"title": "批处理",
|
||||||
|
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Batch-v2.jpg",
|
||||||
|
"description": "通过设定批量运行次数和逻辑,运行批处理体内的任务",
|
||||||
|
"mainColor": "#00B2B2",
|
||||||
|
"subTitle": "批处理"
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"concurrentSize": {
|
||||||
|
"type": "integer",
|
||||||
|
"value": {
|
||||||
|
"type": "literal",
|
||||||
|
"content": "10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"batchSize": {
|
||||||
|
"type": "integer",
|
||||||
|
"value": {
|
||||||
|
"type": "literal",
|
||||||
|
"content": "100"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inputParameters": [
|
||||||
|
{
|
||||||
|
"name": "input",
|
||||||
|
"input": {
|
||||||
|
"type": "list",
|
||||||
|
"value": {
|
||||||
|
"type": "literal",
|
||||||
|
"content": "[\"1\",\"2\"]",
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 99
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "output",
|
||||||
|
"input": {
|
||||||
|
"type": "list",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"type": "ref",
|
||||||
|
"content": {
|
||||||
|
"source": "block-output",
|
||||||
|
"blockID": "182572",
|
||||||
|
"name": "url"
|
||||||
|
},
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"blocks": [
|
||||||
|
{
|
||||||
|
"id": "191311",
|
||||||
|
"type": "45",
|
||||||
|
"meta": {
|
||||||
|
"position": {
|
||||||
|
"x": 180,
|
||||||
|
"y": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nodeMeta": {
|
||||||
|
"title": "HTTP 请求_1",
|
||||||
|
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-HTTP.png",
|
||||||
|
"description": "用于发送API请求,从接口返回数据",
|
||||||
|
"mainColor": "#3071F2",
|
||||||
|
"subTitle": "HTTP 请求"
|
||||||
|
},
|
||||||
|
"inputParameters": [],
|
||||||
|
"inputs": {
|
||||||
|
"apiInfo": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "http://echo.apifox.com/anything?cc={{block_output_125743.input}}&aa={{global_variable_app[\"app\"]}}"
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"bodyType": "JSON",
|
||||||
|
"bodyData": {
|
||||||
|
"binary": {
|
||||||
|
"fileURL": {
|
||||||
|
"type": "string",
|
||||||
|
"value": {
|
||||||
|
"type": "ref",
|
||||||
|
"content": {
|
||||||
|
"source": "block-output",
|
||||||
|
"blockID": "",
|
||||||
|
"name": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"json": "{\n \"value\": {{block_output_125743.index}}\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"headers": [],
|
||||||
|
"params": [],
|
||||||
|
"auth": {
|
||||||
|
"authType": "BEARER_AUTH",
|
||||||
|
"authData": {
|
||||||
|
"customData": {
|
||||||
|
"addTo": "header"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authOpen": false
|
||||||
|
},
|
||||||
|
"setting": {
|
||||||
|
"timeout": 120,
|
||||||
|
"retryTimes": 3
|
||||||
|
},
|
||||||
|
"settingOnError": {}
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "body"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"name": "statusCode"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "headers"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settingOnError": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "182572",
|
||||||
|
"type": "5",
|
||||||
|
"meta": {
|
||||||
|
"position": {
|
||||||
|
"x": 640,
|
||||||
|
"y": 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"nodeMeta": {
|
||||||
|
"title": "代码_3",
|
||||||
|
"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Code-v2.jpg",
|
||||||
|
"description": "编写代码,处理输入变量来生成返回值",
|
||||||
|
"mainColor": "#00B2B2",
|
||||||
|
"subTitle": "代码"
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"inputParameters": [
|
||||||
|
{
|
||||||
|
"name": "input",
|
||||||
|
"input": {
|
||||||
|
"type": "string",
|
||||||
|
"value": {
|
||||||
|
"type": "ref",
|
||||||
|
"content": {
|
||||||
|
"source": "block-output",
|
||||||
|
"blockID": "191311",
|
||||||
|
"name": "body"
|
||||||
|
},
|
||||||
|
"rawMeta": {
|
||||||
|
"type": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"code": "import json\nasync def main(args: Args) -> Output:\n params = args.params\n input_string = params['input']\n return json.loads(input_string)",
|
||||||
|
"language": 3,
|
||||||
|
"settingOnError": {
|
||||||
|
"processType": 1,
|
||||||
|
"timeoutMs": 60000,
|
||||||
|
"retryTimes": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"name": "url"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edges": [
|
||||||
|
{
|
||||||
|
"sourceNodeID": "125743",
|
||||||
|
"targetNodeID": "191311",
|
||||||
|
"sourcePortID": "batch-function-inline-output"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sourceNodeID": "191311",
|
||||||
|
"targetNodeID": "182572"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sourceNodeID": "182572",
|
||||||
|
"targetNodeID": "125743",
|
||||||
|
"targetPortID": "batch-function-inline-input"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edges": [
|
||||||
|
{
|
||||||
|
"sourceNodeID": "100001",
|
||||||
|
"targetNodeID": "122230"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sourceNodeID": "125743",
|
||||||
|
"targetNodeID": "900001",
|
||||||
|
"sourcePortID": "batch-output"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sourceNodeID": "122230",
|
||||||
|
"targetNodeID": "125743",
|
||||||
|
"sourcePortID": "loop-output"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"versions": {
|
||||||
|
"loop": "v2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,10 +23,12 @@ import (
|
||||||
|
|
||||||
"github.com/cloudwego/eino/compose"
|
"github.com/cloudwego/eino/compose"
|
||||||
|
|
||||||
|
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
|
||||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/crypto"
|
"github.com/coze-dev/coze-studio/backend/pkg/lang/crypto"
|
||||||
|
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var extractBracesRegexp = regexp.MustCompile(`\{\{(.*?)}}`)
|
var extractBracesRegexp = regexp.MustCompile(`\{\{(.*?)}}`)
|
||||||
|
|
@ -46,6 +48,7 @@ type ImplicitNodeDependency struct {
|
||||||
NodeID string
|
NodeID string
|
||||||
FieldPath compose.FieldPath
|
FieldPath compose.FieldPath
|
||||||
TypeInfo *vo.TypeInfo
|
TypeInfo *vo.TypeInfo
|
||||||
|
IsIntermediateVar bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractImplicitDependency(node *vo.Node, canvas *vo.Canvas) ([]*ImplicitNodeDependency, error) {
|
func extractImplicitDependency(node *vo.Node, canvas *vo.Canvas) ([]*ImplicitNodeDependency, error) {
|
||||||
|
|
@ -84,14 +87,24 @@ func extractImplicitDependency(node *vo.Node, canvas *vo.Canvas) ([]*ImplicitNod
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Data.Inputs.Body.BodyType == string(BodyTypeRawText) {
|
if node.Data.Inputs.Body.BodyType == string(BodyTypeRawText) {
|
||||||
rawTextVars := extractBracesContent(node.Data.Inputs.Body.BodyData.Json)
|
rawTextVars := extractBracesContent(node.Data.Inputs.Body.BodyData.RawText)
|
||||||
err = extractDependenciesFromVars(rawTextVars)
|
err = extractDependenciesFromVars(rawTextVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeID2ParentID := make(map[string]string)
|
||||||
|
for _, n := range canvas.Nodes {
|
||||||
|
if len(n.Blocks) > 0 {
|
||||||
|
for _, block := range n.Blocks {
|
||||||
|
nodeID2ParentID[block.ID] = n.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var nodeFinder func(nodes []*vo.Node, nodeID string) *vo.Node
|
var nodeFinder func(nodes []*vo.Node, nodeID string) *vo.Node
|
||||||
nodeFinder = func(nodes []*vo.Node, nodeID string) *vo.Node {
|
nodeFinder = func(nodes []*vo.Node, nodeID string) *vo.Node {
|
||||||
for i := range nodes {
|
for i := range nodes {
|
||||||
|
|
@ -111,7 +124,55 @@ func extractImplicitDependency(node *vo.Node, canvas *vo.Canvas) ([]*ImplicitNod
|
||||||
if fNode == nil {
|
if fNode == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
tInfoMap := make(map[string]*vo.TypeInfo, len(node.Data.Outputs))
|
intermediateVars := map[string]bool{}
|
||||||
|
tInfoMap := make(map[string]*vo.TypeInfo)
|
||||||
|
parentID, ok := nodeID2ParentID[node.ID]
|
||||||
|
if ok && parentID == fNode.ID {
|
||||||
|
// when referencing a composite node, the index field type is available by default
|
||||||
|
tInfoMap["index"] = &vo.TypeInfo{
|
||||||
|
Type: vo.DataTypeInteger,
|
||||||
|
}
|
||||||
|
for _, p := range fNode.Data.Inputs.InputParameters {
|
||||||
|
tInfo, err := convert.CanvasBlockInputToTypeInfo(p.Input)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if tInfo.Type != vo.DataTypeArray {
|
||||||
|
return nil, fmt.Errorf("when referencing a composite node, the input parameter must be an array type")
|
||||||
|
}
|
||||||
|
tInfoMap[p.Name] = tInfo.ElemTypeInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
if fNode.Data.Inputs.Loop != nil {
|
||||||
|
for _, vAny := range fNode.Data.Inputs.Loop.VariableParameters {
|
||||||
|
v, err := convert.ParseParam(vAny)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tInfo, err := convert.CanvasBlockInputToTypeInfo(v.Input)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tInfoMap[v.Name] = tInfo
|
||||||
|
|
||||||
|
intermediateVars[v.Name] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if entity.NodeTypeMetas[entity.IDStrToNodeType(fNode.Type)].IsComposite {
|
||||||
|
for _, vAny := range fNode.Data.Outputs {
|
||||||
|
v, err := convert.ParseParam(vAny)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tInfo, err := convert.CanvasBlockInputToTypeInfo(v.Input)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tInfoMap[v.Name] = tInfo
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for _, vAny := range fNode.Data.Outputs {
|
for _, vAny := range fNode.Data.Outputs {
|
||||||
v, err := vo.ParseVariable(vAny)
|
v, err := vo.ParseVariable(vAny)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -123,11 +184,18 @@ func extractImplicitDependency(node *vo.Node, canvas *vo.Canvas) ([]*ImplicitNod
|
||||||
}
|
}
|
||||||
tInfoMap[v.Name] = tInfo
|
tInfoMap[v.Name] = tInfo
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tInfo, ok := getTypeInfoByPath(ds.FieldPath[0], ds.FieldPath[1:], tInfoMap)
|
tInfo, ok := getTypeInfoByPath(ds.FieldPath[0], ds.FieldPath[1:], tInfoMap)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("cannot find type info for dependency: %s", ds.FieldPath)
|
return nil, fmt.Errorf("cannot find type info for dependency: %s", ds.FieldPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
ds.TypeInfo = tInfo
|
ds.TypeInfo = tInfo
|
||||||
|
if len(intermediateVars) > 0 {
|
||||||
|
ds.IsIntermediateVar = intermediateVars[strings.Join(ds.FieldPath, ".")]
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dependencies, nil
|
return dependencies, nil
|
||||||
|
|
@ -152,7 +220,7 @@ var globalVariableRegex = regexp.MustCompile(`global_variable_\w+\s*\["(.*?)"]`)
|
||||||
func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, implicitNodeDependencies []*ImplicitNodeDependency) (err error) {
|
func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, implicitNodeDependencies []*ImplicitNodeDependency) (err error) {
|
||||||
inputs := n.Data.Inputs
|
inputs := n.Data.Inputs
|
||||||
implicitPathVars := make(map[string]bool)
|
implicitPathVars := make(map[string]bool)
|
||||||
addImplicitVarsSources := func(prefix string, vars []string) error {
|
addImplicitVarsSources := func(prefix string, vars []string, parent *vo.Node) error {
|
||||||
for _, v := range vars {
|
for _, v := range vars {
|
||||||
if strings.HasPrefix(v, "block_output_") {
|
if strings.HasPrefix(v, "block_output_") {
|
||||||
paths := strings.Split(strings.TrimPrefix(v, "block_output_"), ".")
|
paths := strings.Split(strings.TrimPrefix(v, "block_output_"), ".")
|
||||||
|
|
@ -167,7 +235,8 @@ func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, impl
|
||||||
}
|
}
|
||||||
implicitPathVars[pathValue] = true
|
implicitPathVars[pathValue] = true
|
||||||
ns.SetInputType(pathValue, dep.TypeInfo)
|
ns.SetInputType(pathValue, dep.TypeInfo)
|
||||||
ns.AddInputSource(&vo.FieldInfo{
|
|
||||||
|
filedInfo := &vo.FieldInfo{
|
||||||
Path: []string{pathValue},
|
Path: []string{pathValue},
|
||||||
Source: vo.FieldSource{
|
Source: vo.FieldSource{
|
||||||
Ref: &vo.Reference{
|
Ref: &vo.Reference{
|
||||||
|
|
@ -175,7 +244,12 @@ func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, impl
|
||||||
FromPath: dep.FieldPath,
|
FromPath: dep.FieldPath,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
}
|
||||||
|
|
||||||
|
if dep.IsIntermediateVar && parent != nil {
|
||||||
|
filedInfo.Source.Ref.VariableType = ptr.Of(vo.ParentIntermediate)
|
||||||
|
}
|
||||||
|
ns.AddInputSource(filedInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -215,7 +289,7 @@ func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, impl
|
||||||
}
|
}
|
||||||
|
|
||||||
urlVars := extractBracesContent(inputs.APIInfo.URL)
|
urlVars := extractBracesContent(inputs.APIInfo.URL)
|
||||||
err = addImplicitVarsSources("__apiInfo_url_", urlVars)
|
err = addImplicitVarsSources("__apiInfo_url_", urlVars, n.Parent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -304,13 +378,13 @@ func setHttpRequesterInputsForNodeSchema(n *vo.Node, ns *schema.NodeSchema, impl
|
||||||
ns.AddInputSource(sources...)
|
ns.AddInputSource(sources...)
|
||||||
case BodyTypeJSON:
|
case BodyTypeJSON:
|
||||||
jsonVars := extractBracesContent(inputs.Body.BodyData.Json)
|
jsonVars := extractBracesContent(inputs.Body.BodyData.Json)
|
||||||
err = addImplicitVarsSources("__body_bodyData_json_", jsonVars)
|
err = addImplicitVarsSources("__body_bodyData_json_", jsonVars, n.Parent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case BodyTypeRawText:
|
case BodyTypeRawText:
|
||||||
rawTextVars := extractBracesContent(inputs.Body.BodyData.RawText)
|
rawTextVars := extractBracesContent(inputs.Body.BodyData.RawText)
|
||||||
err = addImplicitVarsSources("__body_bodyData_rawText_", rawTextVars)
|
err = addImplicitVarsSources("__body_bodyData_rawText_", rawTextVars, n.Parent())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -360,6 +360,11 @@ type HTTPRequester struct {
|
||||||
md5FieldMapping MD5FieldMapping
|
md5FieldMapping MD5FieldMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func adaptTemplate(template string) string {
|
||||||
|
return globalVariableReplaceRegexp.ReplaceAllString(template, "global_variable_$1.$2")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (hg *HTTPRequester) Invoke(ctx context.Context, input map[string]any) (output map[string]any, err error) {
|
func (hg *HTTPRequester) Invoke(ctx context.Context, input map[string]any) (output map[string]any, err error) {
|
||||||
var (
|
var (
|
||||||
req = &Request{}
|
req = &Request{}
|
||||||
|
|
@ -380,7 +385,7 @@ func (hg *HTTPRequester) Invoke(ctx context.Context, input map[string]any) (outp
|
||||||
Header: http.Header{},
|
Header: http.Header{},
|
||||||
}
|
}
|
||||||
|
|
||||||
httpURL, err := nodes.TemplateRender(hg.urlConfig.Tpl, req.URLVars)
|
httpURL, err := nodes.TemplateRender(adaptTemplate(hg.urlConfig.Tpl), req.URLVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -524,7 +529,7 @@ func (b *BodyConfig) getBodyAndContentType(ctx context.Context, req *Request) (i
|
||||||
|
|
||||||
switch b.BodyType {
|
switch b.BodyType {
|
||||||
case BodyTypeJSON:
|
case BodyTypeJSON:
|
||||||
jsonString, err := nodes.TemplateRender(b.TextJsonConfig.Tpl, req.JsonVars)
|
jsonString, err := nodes.TemplateRender(adaptTemplate(b.TextJsonConfig.Tpl), req.JsonVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, contentType, err
|
return nil, contentType, err
|
||||||
}
|
}
|
||||||
|
|
@ -539,7 +544,7 @@ func (b *BodyConfig) getBodyAndContentType(ctx context.Context, req *Request) (i
|
||||||
body = strings.NewReader(form.Encode())
|
body = strings.NewReader(form.Encode())
|
||||||
contentType = ContentTypeFormURLEncoded
|
contentType = ContentTypeFormURLEncoded
|
||||||
case BodyTypeRawText:
|
case BodyTypeRawText:
|
||||||
textString, err := nodes.TemplateRender(b.TextPlainConfig.Tpl, req.TextPlainVars)
|
textString, err := nodes.TemplateRender(adaptTemplate(b.TextPlainConfig.Tpl), req.TextPlainVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, contentType, err
|
return nil, contentType, err
|
||||||
}
|
}
|
||||||
|
|
@ -632,7 +637,7 @@ func (hg *HTTPRequester) ToCallbackInput(_ context.Context, input map[string]any
|
||||||
result := make(map[string]any)
|
result := make(map[string]any)
|
||||||
result["method"] = hg.method
|
result["method"] = hg.method
|
||||||
|
|
||||||
u, err := nodes.TemplateRender(hg.urlConfig.Tpl, request.URLVars)
|
u, err := nodes.TemplateRender(adaptTemplate(hg.urlConfig.Tpl), request.URLVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -666,7 +671,7 @@ func (hg *HTTPRequester) ToCallbackInput(_ context.Context, input map[string]any
|
||||||
result["body"] = nil
|
result["body"] = nil
|
||||||
switch hg.bodyConfig.BodyType {
|
switch hg.bodyConfig.BodyType {
|
||||||
case BodyTypeJSON:
|
case BodyTypeJSON:
|
||||||
js, err := nodes.TemplateRender(hg.bodyConfig.TextJsonConfig.Tpl, request.JsonVars)
|
js, err := nodes.TemplateRender(adaptTemplate(hg.bodyConfig.TextJsonConfig.Tpl), request.JsonVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -677,7 +682,7 @@ func (hg *HTTPRequester) ToCallbackInput(_ context.Context, input map[string]any
|
||||||
}
|
}
|
||||||
result["body"] = ret
|
result["body"] = ret
|
||||||
case BodyTypeRawText:
|
case BodyTypeRawText:
|
||||||
tx, err := nodes.TemplateRender(hg.bodyConfig.TextPlainConfig.Tpl, request.TextPlainVars)
|
tx, err := nodes.TemplateRender(adaptTemplate(hg.bodyConfig.TextPlainConfig.Tpl), request.TextPlainVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -729,7 +734,7 @@ func (hg *HTTPRequester) parserToRequest(input map[string]any) (*Request, error)
|
||||||
if strings.HasPrefix(urlKey, "global_variable_") {
|
if strings.HasPrefix(urlKey, "global_variable_") {
|
||||||
urlKey = globalVariableReplaceRegexp.ReplaceAllString(urlKey, "global_variable_$1.$2")
|
urlKey = globalVariableReplaceRegexp.ReplaceAllString(urlKey, "global_variable_$1.$2")
|
||||||
}
|
}
|
||||||
nodes.SetMapValue(request.URLVars, strings.Split(urlKey, "."), value.(string))
|
nodes.SetMapValue(request.URLVars, strings.Split(urlKey, "."), value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(key, headersPrefix) {
|
if strings.HasPrefix(key, headersPrefix) {
|
||||||
|
|
@ -777,7 +782,6 @@ func (hg *HTTPRequester) parserToRequest(input map[string]any) (*Request, error)
|
||||||
if formDataKey, ok := hg.md5FieldMapping.BodyMD5Mapping[formDataMd5Key]; ok {
|
if formDataKey, ok := hg.md5FieldMapping.BodyMD5Mapping[formDataMd5Key]; ok {
|
||||||
request.FormDataVars[formDataKey] = value.(string)
|
request.FormDataVars[formDataKey] = value.(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(bodyKey, bodyFormURLEncodedPrefix) {
|
if strings.HasPrefix(bodyKey, bodyFormURLEncodedPrefix) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue