Skip to content

Commit f928b84

Browse files
committed
update plugin and workflow
1 parent af5d1ed commit f928b84

9 files changed

Lines changed: 336 additions & 35 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,5 @@ Cargo.lock
2929
*.key.pub
3030
.env
3131
*.css.map
32-
docs/.vitepress/cache
32+
docs/.vitepress/cache
33+
deno

deno.lock

Lines changed: 175 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/src/plugins/deno/plugin.rs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use crate::plugins::deno::error::{PluginError, Result};
2+
use crate::utils::gen::generate_id;
13
use serde::{Deserialize, Serialize};
24
use serde_json::Value;
3-
use crate::plugins::deno::error::{PluginError, Result};
4-
use base64::engine::{general_purpose::STANDARD, Engine};
5+
use std::fs::{create_dir_all, write};
56

67
/// 插件信息结构
78
#[derive(Debug, Serialize, Deserialize, Clone)]
@@ -47,48 +48,55 @@ impl PluginManager {
4748
/// 执行插件工具
4849
pub async fn execute(&self, content: &str, tool: &str, args: Value) -> Result<Value> {
4950
let runtime = crate::plugins::deno::DENO_RUNTIME.lock().await;
50-
let runtime = runtime.as_ref().ok_or_else(|| PluginError::Plugin("Deno运行时未初始化".to_string()))?;
51+
let runtime = runtime
52+
.as_ref()
53+
.ok_or_else(|| PluginError::Plugin("Deno运行时未初始化".to_string()))?;
5154

5255
if !runtime.check_installed() {
5356
return Err(PluginError::DenoNotInstalled);
5457
}
5558

56-
// 使用 data URL 直接执行内容
59+
// 获取插件目录
60+
let config_dir = crate::utils::file::get_config_dir()
61+
.ok_or_else(|| PluginError::Plugin("无法获取配置目录".to_string()))?;
62+
let plugins_dir = config_dir.join("plugins");
63+
create_dir_all(&plugins_dir)?;
64+
65+
// 创建唯一的插件文件
66+
let plugin_path = plugins_dir.join(format!("plugin_{}.ts", generate_id()));
67+
let plugin_path_str = plugin_path.to_str().unwrap();
68+
69+
// 写入插件内容
70+
write(&plugin_path, content)?;
71+
72+
// 使用文件路径方式执行
5773
let script = format!(
5874
r#"
5975
(async () => {{
60-
const plugin = await import('data:text/typescript;base64,{content}');
76+
const plugin = await import('file://{plugin_path}');
6177
const targetFunction = plugin['{tool}'];
6278
if (typeof targetFunction !== 'function') {{
6379
throw new Error(`插件中未找到函数 '{tool}' 或导出不是一个函数。`);
6480
}}
65-
// 从 Rust 传递过来的 JSON 字符串,需要解析
6681
const parsedArgs = JSON.parse('{args_json}');
67-
// 直接调用目标函数并传递解析后的参数对象
68-
// TypeScript 函数内部负责处理参数结构
6982
const result = await targetFunction(parsedArgs);
70-
// 将结果序列化为 JSON 字符串并打印到 stdout, 以便 Rust 捕获
7183
console.log(JSON.stringify(result !== undefined ? result : null));
7284
}})();
7385
"#,
74-
content = STANDARD.encode(content),
86+
plugin_path = plugin_path_str.replace("\\", "/"), // 确保路径使用正斜杠
7587
tool = tool,
76-
// 确保 args 被正确序列化为 JSON 字符串, 并进行 JS 字符串所需的基本转义
7788
args_json = serde_json::to_string(&args)?
78-
.replace("\\", "\\\\") // 必须先转义反斜杠本身
79-
.replace("'", "\\'") // 转义单引号
80-
.replace("\"", "\\\"") // 转义双引号
81-
.replace("\n", "\\n") // 转义换行符
82-
.replace("\r", "\\r") // 转义回车符
89+
.replace("\\", "\\\\")
90+
.replace("'", "\\'")
91+
.replace("\"", "\\\"")
92+
.replace("\n", "\\n")
93+
.replace("\r", "\\r")
8394
);
8495

85-
println!("{}", script);
86-
8796
let env_vars = self.env_manager.load().await?;
8897
let output = runtime.execute(&script, &env_vars).await?;
89-
98+
// 清理插件文件
99+
let _ = std::fs::remove_file(&plugin_path);
90100
serde_json::from_str(&output).map_err(|e| PluginError::Json(e.to_string()))
91101
}
92-
93-
94-
}
102+
}

src/components/ui/textarea.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export const Textarea = forwardRef<CustomTextAreaRef, TextAreaProps>(
8686
);
8787

8888
return (
89-
<div className="relative h-full">
89+
<div className="relative h-full p">
9090
<textarea
9191
ref={internalRef}
9292
value={value}

src/page/plugins/components/TestDrawer.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,21 @@ export function TestDrawer({
4646
<div className="flex items-center justify-between w-full">
4747
<h3 className="text-lg font-semibold">{selectedPlugin?.name}</h3>{" "}
4848
<Button
49-
disabled={!testTool}
49+
disabled={!testTool || isSubmitting}
5050
onClick={() => onTest(testTool)}
5151
variant="default"
5252
size="sm"
5353
>
54-
<TbPlayerPlay className="w-3.5 h-3.5" />
5554
{isSubmitting ? (
5655
<span className="flex items-center gap-1.5">
5756
<TbLoader2 className="w-3.5 h-3.5 animate-spin" />
5857
Testing...
5958
</span>
6059
) : (
61-
"Run Test"
60+
<span className="flex items-center gap-1.5">
61+
<TbPlayerPlay className="w-3.5 h-3.5" />
62+
Run Test
63+
</span>
6264
)}
6365
</Button>
6466
</div>

src/page/workflow/WorkflowsMarket.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const WorkflowsMarket = () => {
5050
// 安装工作流
5151
const handleInstall = async (workflow: WorkflowMarketProps) => {
5252
try {
53+
console.log(workflow);
5354
setInstalling(workflow.id);
5455

5556
// 添加到工作流管理器
@@ -61,9 +62,11 @@ export const WorkflowsMarket = () => {
6162
description: workflow.description,
6263
});
6364

65+
console.log(workflow.data);
66+
6467
// 更新工作流主体数据
65-
if (workflow.data && workflow.data.body) {
66-
new Echo(workflow.data.body)
68+
if (workflow.data && workflow.data) {
69+
new Echo(JSON.parse(workflow.data))
6770
.indexed({
6871
database: WORKFLOW_BODY_DATABASE,
6972
name: newWorkflow.meta.id,

0 commit comments

Comments
 (0)