@@ -35,6 +35,7 @@
type="textarea"
dense
borderless
+ style="font-family: monospace, monoca, consola"
autogrow
@update:model-value="updateFunction"
>
@@ -198,7 +199,39 @@ export default defineComponent({
diff --git a/src/js/composer/composerConfig.js b/src/js/composer/composerConfig.js
index 2233280..3e75487 100644
--- a/src/js/composer/composerConfig.js
+++ b/src/js/composer/composerConfig.js
@@ -42,28 +42,20 @@ export const commandCategories = [
},
{
value: "ubrowser",
- label: "UBrowser浏览器操作",
- desc: "配置UBrowser浏览器操作",
+ label: "ubrowser浏览器操作",
+ desc: "配置ubrowser浏览器操作",
hasUBrowserEditor: true,
isAsync: true,
icon: "public",
},
{
value: "axios",
- label: "发送HTTP请求(Axios)",
+ label: "HTTP请求(Axios)",
desc: "使用Axios发送HTTP请求",
hasAxiosEditor: true,
isAsync: true,
icon: "http",
},
- {
- value: "fetch",
- label: "发送HTTP请求(Fetch)",
- desc: "使用Fetch API发送HTTP请求",
- hasFetchEditor: true,
- isAsync: true,
- icon: "http",
- },
],
},
{
@@ -82,24 +74,31 @@ export const commandCategories = [
desc: "要写入剪切板的内容",
icon: "content_copy",
},
+ {
+ value: "electron.clipboard.readText",
+ label: "获取剪贴板内容",
+ desc: "获取剪贴板内容",
+ icon: "content_copy",
+ hasNoArgs: true,
+ },
],
},
{
label: "消息通知",
icon: "notifications",
commands: [
+ {
+ value: "console.log",
+ label: "打印消息",
+ desc: "要打印的消息文本",
+ icon: "info",
+ },
{
value: "message",
label: "发送系统消息",
desc: "要发送的系统消息文本",
icon: "message",
},
- {
- value: "quickcommand.showMessageBox",
- label: "弹窗显示消息",
- desc: "要弹窗显示的消息文本",
- icon: "warning",
- },
{
value: "send",
label: "发送文本到活动窗口",
diff --git a/src/js/composer/formatString.js b/src/js/composer/formatString.js
index 3b8acbc..b6ffa97 100644
--- a/src/js/composer/formatString.js
+++ b/src/js/composer/formatString.js
@@ -12,14 +12,46 @@ const processVariableValue = (value) => {
return value.slice(1, -1);
};
+/**
+ * 检查路径是否匹配或是目标路径的父路径
+ * @param {string} currentPath 当前路径
+ * @param {string[]} targetPaths 目标路径列表
+ * @returns {boolean} 是否匹配
+ */
+const isPathMatched = (currentPath, targetPaths) => {
+ if (!targetPaths) return false;
+ return targetPaths.some(
+ (path) =>
+ path === currentPath || // 精确匹配
+ path.startsWith(currentPath + ".") // 是父路径
+ );
+};
+
+/**
+ * 递归移除对象中的空值
+ * @param {Object} obj 要处理的对象
+ * @returns {Object} 处理后的对象
+ */
+const removeEmptyValues = (obj) => {
+ return _.omitBy(obj, (value) => {
+ if (_.isNil(value) || value === "") return true;
+ if (typeof value === "object")
+ return _.isEmpty(removeEmptyValues(value));
+ return false;
+ });
+};
+
/**
* 递归处理对象的值
* @param {Object} obj 要处理的对象
* @param {string} parentPath 父路径
* @param {string[]|null} variableFields 需要处理的字段列表,null表示处理所有字段
+ * @param {string[]|null} excludeFields 需要排除的字段列表,即使匹配了处理条件也不处理
* @returns {string} 处理后的字符串
*/
-const processObject = (obj, parentPath = "", variableFields) => {
+const processObject = (obj, parentPath = "", variableFields, excludeFields) => {
+ // 移除空值
+ obj = removeEmptyValues(obj);
let result = "{\n";
const entries = Object.entries(obj);
@@ -28,16 +60,20 @@ const processObject = (obj, parentPath = "", variableFields) => {
let valueStr = "";
// 检查是否需要处理当前字段
- const shouldProcess =
- !variableFields || // 不传递variableFields则处理所有字段
- variableFields.includes(parentPath) || // 父字段是完整处理字段
- variableFields.includes(key) || // 当前字段是完整处理字段
- variableFields.includes(currentPath) || // 当前路径精确匹配
- variableFields.some((field) => field.startsWith(currentPath + ".")); // 当前路径是指定路径的父路径
+ const isIncluded =
+ !variableFields || isPathMatched(currentPath, variableFields);
+ const isExcluded =
+ excludeFields && isPathMatched(currentPath, excludeFields);
+ const shouldProcess = isIncluded && !isExcluded;
// 处理对象类型
if (typeof value === "object" && value !== null) {
- valueStr = processObject(value, currentPath, variableFields);
+ valueStr = processObject(
+ value,
+ currentPath,
+ variableFields,
+ excludeFields
+ );
}
// 处理字符串类型
else if (typeof value === "string") {
@@ -71,13 +107,19 @@ const processObject = (obj, parentPath = "", variableFields) => {
* 1. 完整字段处理:如 headers - 处理整个对象及其所有子字段
* 2. 指定路径处理:如 data.headers.Referer - 只处理特定路径
* 3. 不传递 variableFields 则处理所有字段
+ * 4. 可以通过 excludeFields 排除特定字段,即使匹配了处理条件也不处理
* @param {string} jsonStr JSON字符串
* @param {string[]|null} [variableFields] 需要处理的字段列表,包括完整字段和指定路径。不传则处理所有字段
+ * @param {string[]|null} [excludeFields] 需要排除的字段列表,即使匹配了处理条件也不处理
* @returns {string} 处理后的字符串
*/
-export const formatJsonVariables = (jsonObj, variableFields = null) => {
+export const formatJsonVariables = (
+ jsonObj,
+ variableFields = null,
+ excludeFields = null
+) => {
try {
- return processObject(jsonObj, "", variableFields);
+ return processObject(jsonObj, "", variableFields, excludeFields);
} catch (e) {
console.warn("Failed to process JSON variables:", e);
return JSON.stringify(jsonObj, null, 2);
diff --git a/src/js/options/httpHeaders.js b/src/js/options/httpHeaders.js
index 7801433..09e424c 100644
--- a/src/js/options/httpHeaders.js
+++ b/src/js/options/httpHeaders.js
@@ -55,12 +55,15 @@ export const commonHeaders = [
{ label: "Content-Type", value: "Content-Type" },
{ label: "Authorization", value: "Authorization" },
{ label: "User-Agent", value: "User-Agent" },
+ { label: "Cookie", value: "Cookie" },
{ label: "Accept", value: "Accept" },
{ label: "Accept-Language", value: "Accept-Language" },
{ label: "Accept-Encoding", value: "Accept-Encoding" },
- { label: "Cookie", value: "Cookie" },
{ label: "Origin", value: "Origin" },
{ label: "Referer", value: "Referer" },
+ { label: "X-Requested-With", value: "X-Requested-With" },
+ { label: "X-Forwarded-For", value: "X-Forwarded-For" },
+ { label: "X-Real-IP", value: "X-Real-IP" },
];
export const deviceName = [
@@ -75,3 +78,38 @@ export const deviceName = [
{ label: "HUAWEI Mate30", value: "HUAWEI Mate30" },
{ label: "HUAWEI Mate30 Pro", value: "HUAWEI Mate30 Pro" },
];
+
+export const contentTypes = [
+ {
+ label: "application/json",
+ value: "application/json",
+ },
+ {
+ label: "application/x-www-form-urlencoded",
+ value: "application/x-www-form-urlencoded",
+ },
+ {
+ label: "multipart/form-data",
+ value: "multipart/form-data",
+ },
+ {
+ label: "text/plain",
+ value: "text/plain",
+ },
+ {
+ label: "text/html",
+ value: "text/html",
+ },
+ {
+ label: "text/xml",
+ value: "text/xml",
+ },
+ {
+ label: "application/xml",
+ value: "application/xml",
+ },
+ {
+ label: "application/octet-stream",
+ value: "application/octet-stream",
+ },
+];