mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-25 10:18:31 +02:00
Plugin execution context (#119)
This commit is contained in:
@@ -9,7 +9,9 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "run-s build:copy-types build:tsc",
|
"build": "run-s build:copy-types build:tsc",
|
||||||
"build:tsc": "tsc",
|
"build:tsc": "tsc",
|
||||||
"build:copy-types": "cpy --flat ../src-tauri/yaak_plugin_runtime/bindings/*.ts ./src/bindings/",
|
"build:copy-types": "run-p build:copy-types:*",
|
||||||
|
"build:copy-types:root": "cpy --flat ../src-tauri/yaak_plugin_runtime/bindings/*.ts ./src/bindings",
|
||||||
|
"build:copy-types:next": "cpy --flat ../src-tauri/yaak_plugin_runtime/bindings/serde_json/*.ts ./src/bindings/serde_json",
|
||||||
"prepublishOnly": "npm run build"
|
"prepublishOnly": "npm run build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { Folder } from "./models";
|
|||||||
import type { GrpcRequest } from "./models";
|
import type { GrpcRequest } from "./models";
|
||||||
import type { HttpRequest } from "./models";
|
import type { HttpRequest } from "./models";
|
||||||
import type { HttpResponse } from "./models";
|
import type { HttpResponse } from "./models";
|
||||||
|
import type { JsonValue } from "./serde_json/JsonValue";
|
||||||
import type { Workspace } from "./models";
|
import type { Workspace } from "./models";
|
||||||
|
|
||||||
export type BootRequest = { dir: string, watch: boolean, };
|
export type BootRequest = { dir: string, watch: boolean, };
|
||||||
@@ -56,9 +57,9 @@ export type ImportResources = { workspaces: Array<Workspace>, environments: Arra
|
|||||||
|
|
||||||
export type ImportResponse = { resources: ImportResources, };
|
export type ImportResponse = { resources: ImportResources, };
|
||||||
|
|
||||||
export type InternalEvent = { id: string, pluginRefId: string, replyId: string | null, payload: InternalEventPayload, };
|
export type InternalEvent = { id: string, pluginRefId: string, replyId: string | null, payload: InternalEventPayload, windowContext: WindowContext, };
|
||||||
|
|
||||||
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } | { "type": "reload_response" } | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & GetHttpRequestActionsRequest | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "copy_text_request" } & CopyTextRequest | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" };
|
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } | { "type": "reload_response" } | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & GetHttpRequestActionsRequest | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "copy_text_request" } & CopyTextRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" };
|
||||||
|
|
||||||
export type RenderHttpRequestRequest = { httpRequest: HttpRequest, purpose: RenderPurpose, };
|
export type RenderHttpRequestRequest = { httpRequest: HttpRequest, purpose: RenderPurpose, };
|
||||||
|
|
||||||
@@ -87,3 +88,9 @@ export type TemplateFunctionSelectArg = { options: Array<TemplateFunctionSelectO
|
|||||||
export type TemplateFunctionSelectOption = { name: string, value: string, };
|
export type TemplateFunctionSelectOption = { name: string, value: string, };
|
||||||
|
|
||||||
export type TemplateFunctionTextArg = { placeholder?: string | null, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
export type TemplateFunctionTextArg = { placeholder?: string | null, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
||||||
|
|
||||||
|
export type TemplateRenderRequest = { data: JsonValue, purpose: RenderPurpose, };
|
||||||
|
|
||||||
|
export type TemplateRenderResponse = { data: JsonValue, };
|
||||||
|
|
||||||
|
export type WindowContext = { "type": "none" } | { "type": "label" } & string;
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
|
||||||
|
export type JsonValue = number | string | Array<JsonValue> | { [key in string]?: JsonValue };
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { TemplateRenderRequest, TemplateRenderResponse } from '@yaakapp-internal/plugin';
|
||||||
import {
|
import {
|
||||||
FindHttpResponsesRequest,
|
FindHttpResponsesRequest,
|
||||||
FindHttpResponsesResponse,
|
FindHttpResponsesResponse,
|
||||||
@@ -25,4 +26,7 @@ export type Context = {
|
|||||||
httpResponse: {
|
httpResponse: {
|
||||||
find(args: FindHttpResponsesRequest): Promise<FindHttpResponsesResponse['httpResponses']>;
|
find(args: FindHttpResponsesRequest): Promise<FindHttpResponsesResponse['httpResponses']>;
|
||||||
};
|
};
|
||||||
|
templates: {
|
||||||
|
render(args: TemplateRenderRequest): Promise<TemplateRenderResponse['data']>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
|
import { TemplateRenderResponse, WindowContext } from '@yaakapp-internal/plugin';
|
||||||
import {
|
import {
|
||||||
BootRequest,
|
BootRequest,
|
||||||
Context,
|
Context,
|
||||||
FindHttpResponsesResponse,
|
FindHttpResponsesResponse,
|
||||||
GetHttpRequestByIdResponse,
|
GetHttpRequestByIdResponse,
|
||||||
|
HttpRequest,
|
||||||
HttpRequestAction,
|
HttpRequestAction,
|
||||||
ImportResponse,
|
ImportResponse,
|
||||||
InternalEvent,
|
InternalEvent,
|
||||||
InternalEventPayload,
|
InternalEventPayload,
|
||||||
RenderHttpRequestResponse,
|
|
||||||
SendHttpRequestResponse,
|
SendHttpRequestResponse,
|
||||||
TemplateFunction,
|
TemplateFunction,
|
||||||
} from '@yaakapp/api';
|
} from '@yaakapp/api';
|
||||||
@@ -51,21 +52,26 @@ async function initialize() {
|
|||||||
if (typeof mod.pluginHookImport === 'function') capabilities.push('import');
|
if (typeof mod.pluginHookImport === 'function') capabilities.push('import');
|
||||||
if (typeof mod.pluginHookResponseFilter === 'function') capabilities.push('filter');
|
if (typeof mod.pluginHookResponseFilter === 'function') capabilities.push('filter');
|
||||||
|
|
||||||
console.log('Plugin initialized', pkg.name, capabilities, Object.keys(mod));
|
console.log('Plugin initialized', pkg.name, { capabilities, enableWatch });
|
||||||
|
|
||||||
function buildEventToSend(
|
function buildEventToSend(
|
||||||
|
windowContext: WindowContext,
|
||||||
payload: InternalEventPayload,
|
payload: InternalEventPayload,
|
||||||
replyId: string | null = null,
|
replyId: string | null = null,
|
||||||
): InternalEvent {
|
): InternalEvent {
|
||||||
return { pluginRefId, id: genId(), replyId, payload };
|
return { pluginRefId, id: genId(), replyId, payload, windowContext };
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendEmpty(replyId: string | null = null): string {
|
function sendEmpty(windowContext: WindowContext, replyId: string | null = null): string {
|
||||||
return sendPayload({ type: 'empty_response' }, replyId);
|
return sendPayload(windowContext, { type: 'empty_response' }, replyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendPayload(payload: InternalEventPayload, replyId: string | null): string {
|
function sendPayload(
|
||||||
const event = buildEventToSend(payload, replyId);
|
windowContext: WindowContext,
|
||||||
|
payload: InternalEventPayload,
|
||||||
|
replyId: string | null,
|
||||||
|
): string {
|
||||||
|
const event = buildEventToSend(windowContext, payload, replyId);
|
||||||
sendEvent(event);
|
sendEvent(event);
|
||||||
return event.id;
|
return event.id;
|
||||||
}
|
}
|
||||||
@@ -78,10 +84,11 @@ async function initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function sendAndWaitForReply<T extends Omit<InternalEventPayload, 'type'>>(
|
async function sendAndWaitForReply<T extends Omit<InternalEventPayload, 'type'>>(
|
||||||
|
windowContext: WindowContext,
|
||||||
payload: InternalEventPayload,
|
payload: InternalEventPayload,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
// 1. Build event to send
|
// 1. Build event to send
|
||||||
const eventToSend = buildEventToSend(payload, null);
|
const eventToSend = buildEventToSend(windowContext, payload, null);
|
||||||
|
|
||||||
// 2. Spawn listener in background
|
// 2. Spawn listener in background
|
||||||
const promise = new Promise<InternalEventPayload>(async (resolve) => {
|
const promise = new Promise<InternalEventPayload>(async (resolve) => {
|
||||||
@@ -106,9 +113,10 @@ async function initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reload plugin if JS or package.json changes
|
// Reload plugin if JS or package.json changes
|
||||||
|
const windowContextNone: WindowContext = { type: 'none' };
|
||||||
const cb = async () => {
|
const cb = async () => {
|
||||||
await reloadModule();
|
await reloadModule();
|
||||||
return sendPayload({ type: 'reload_response' }, null);
|
return sendPayload(windowContextNone, { type: 'reload_response' }, null);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (enableWatch) {
|
if (enableWatch) {
|
||||||
@@ -116,45 +124,78 @@ async function initialize() {
|
|||||||
watchFile(pathPkg, cb);
|
watchFile(pathPkg, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ctx: Context = {
|
const newCtx = (event: InternalEvent): Context => ({
|
||||||
clipboard: {
|
clipboard: {
|
||||||
async copyText(text) {
|
async copyText(text) {
|
||||||
await sendAndWaitForReply({ type: 'copy_text_request', text });
|
await sendAndWaitForReply(event.windowContext, { type: 'copy_text_request', text });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
toast: {
|
toast: {
|
||||||
async show(args) {
|
async show(args) {
|
||||||
await sendAndWaitForReply({ type: 'show_toast_request', ...args });
|
await sendAndWaitForReply(event.windowContext, { type: 'show_toast_request', ...args });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
httpResponse: {
|
httpResponse: {
|
||||||
async find(args) {
|
async find(args) {
|
||||||
const payload = { type: 'find_http_responses_request', ...args } as const;
|
const payload = { type: 'find_http_responses_request', ...args } as const;
|
||||||
const { httpResponses } = await sendAndWaitForReply<FindHttpResponsesResponse>(payload);
|
const { httpResponses } = await sendAndWaitForReply<FindHttpResponsesResponse>(
|
||||||
|
event.windowContext,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
return httpResponses;
|
return httpResponses;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
httpRequest: {
|
httpRequest: {
|
||||||
async getById(args) {
|
async getById(args) {
|
||||||
const payload = { type: 'get_http_request_by_id_request', ...args } as const;
|
const payload = { type: 'get_http_request_by_id_request', ...args } as const;
|
||||||
const { httpRequest } = await sendAndWaitForReply<GetHttpRequestByIdResponse>(payload);
|
const { httpRequest } = await sendAndWaitForReply<GetHttpRequestByIdResponse>(
|
||||||
|
event.windowContext,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
return httpRequest;
|
return httpRequest;
|
||||||
},
|
},
|
||||||
async send(args) {
|
async send(args) {
|
||||||
const payload = { type: 'send_http_request_request', ...args } as const;
|
const payload = { type: 'send_http_request_request', ...args } as const;
|
||||||
const { httpResponse } = await sendAndWaitForReply<SendHttpRequestResponse>(payload);
|
const { httpResponse } = await sendAndWaitForReply<SendHttpRequestResponse>(
|
||||||
|
event.windowContext,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
return httpResponse;
|
return httpResponse;
|
||||||
},
|
},
|
||||||
|
/** @deprecated: please use ctx.templates.render */
|
||||||
async render(args) {
|
async render(args) {
|
||||||
const payload = { type: 'render_http_request_request', ...args } as const;
|
const payload = {
|
||||||
const result = await sendAndWaitForReply<RenderHttpRequestResponse>(payload);
|
type: 'template_render_request',
|
||||||
return result.httpRequest;
|
data: args.httpRequest,
|
||||||
|
purpose: args.purpose,
|
||||||
|
} as const;
|
||||||
|
const result = await sendAndWaitForReply<TemplateRenderResponse>(
|
||||||
|
event.windowContext,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
return result.data as HttpRequest;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
templates: {
|
||||||
|
/**
|
||||||
|
* Invoke Yaak's template engine to render a value. If the value is a nested type
|
||||||
|
* (eg. object), it will be recursively rendered.
|
||||||
|
* */
|
||||||
|
async render(args) {
|
||||||
|
const payload = { type: 'template_render_request', ...args } as const;
|
||||||
|
const result = await sendAndWaitForReply<TemplateRenderResponse>(
|
||||||
|
event.windowContext,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
return result.data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Message comes into the plugin to be processed
|
// Message comes into the plugin to be processed
|
||||||
parentPort!.on('message', async ({ payload, id: replyId }: InternalEvent) => {
|
parentPort!.on('message', async (event: InternalEvent) => {
|
||||||
|
let { windowContext, payload, id: replyId } = event;
|
||||||
|
const ctx = newCtx(event);
|
||||||
try {
|
try {
|
||||||
if (payload.type === 'boot_request') {
|
if (payload.type === 'boot_request') {
|
||||||
const payload: InternalEventPayload = {
|
const payload: InternalEventPayload = {
|
||||||
@@ -163,7 +204,7 @@ async function initialize() {
|
|||||||
version: pkg.version,
|
version: pkg.version,
|
||||||
capabilities,
|
capabilities,
|
||||||
};
|
};
|
||||||
sendPayload(payload, replyId);
|
sendPayload(windowContext, payload, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +212,7 @@ async function initialize() {
|
|||||||
const payload: InternalEventPayload = {
|
const payload: InternalEventPayload = {
|
||||||
type: 'terminate_response',
|
type: 'terminate_response',
|
||||||
};
|
};
|
||||||
sendPayload(payload, replyId);
|
sendPayload(windowContext, payload, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +223,7 @@ async function initialize() {
|
|||||||
type: 'import_response',
|
type: 'import_response',
|
||||||
resources: reply?.resources,
|
resources: reply?.resources,
|
||||||
};
|
};
|
||||||
sendPayload(replyPayload, replyId);
|
sendPayload(windowContext, replyPayload, replyId);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Continue, to send back an empty reply
|
// Continue, to send back an empty reply
|
||||||
@@ -198,7 +239,7 @@ async function initialize() {
|
|||||||
type: 'export_http_request_response',
|
type: 'export_http_request_response',
|
||||||
content: reply,
|
content: reply,
|
||||||
};
|
};
|
||||||
sendPayload(replyPayload, replyId);
|
sendPayload(windowContext, replyPayload, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +252,7 @@ async function initialize() {
|
|||||||
type: 'filter_response',
|
type: 'filter_response',
|
||||||
content: reply,
|
content: reply,
|
||||||
};
|
};
|
||||||
sendPayload(replyPayload, replyId);
|
sendPayload(windowContext, replyPayload, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +272,7 @@ async function initialize() {
|
|||||||
pluginRefId,
|
pluginRefId,
|
||||||
actions: reply,
|
actions: reply,
|
||||||
};
|
};
|
||||||
sendPayload(replyPayload, replyId);
|
sendPayload(windowContext, replyPayload, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +292,7 @@ async function initialize() {
|
|||||||
pluginRefId,
|
pluginRefId,
|
||||||
functions: reply,
|
functions: reply,
|
||||||
};
|
};
|
||||||
sendPayload(replyPayload, replyId);
|
sendPayload(windowContext, replyPayload, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +305,7 @@ async function initialize() {
|
|||||||
);
|
);
|
||||||
if (typeof action?.onSelect === 'function') {
|
if (typeof action?.onSelect === 'function') {
|
||||||
await action.onSelect(ctx, payload.args);
|
await action.onSelect(ctx, payload.args);
|
||||||
sendEmpty(replyId);
|
sendEmpty(windowContext, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,7 +319,14 @@ async function initialize() {
|
|||||||
);
|
);
|
||||||
if (typeof action?.onRender === 'function') {
|
if (typeof action?.onRender === 'function') {
|
||||||
const result = await action.onRender(ctx, payload.args);
|
const result = await action.onRender(ctx, payload.args);
|
||||||
sendPayload({ type: 'call_template_function_response', value: result ?? null }, replyId);
|
sendPayload(
|
||||||
|
windowContext,
|
||||||
|
{
|
||||||
|
type: 'call_template_function_response',
|
||||||
|
value: result ?? null,
|
||||||
|
},
|
||||||
|
replyId,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,7 +340,7 @@ async function initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No matches, so send back an empty response so the caller doesn't block forever
|
// No matches, so send back an empty response so the caller doesn't block forever
|
||||||
sendEmpty(replyId);
|
sendEmpty(windowContext, replyId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ use yaak_models::models::{
|
|||||||
Cookie, CookieJar, Environment, HttpRequest, HttpResponse, HttpResponseHeader, HttpUrlParameter,
|
Cookie, CookieJar, Environment, HttpRequest, HttpResponse, HttpResponseHeader, HttpUrlParameter,
|
||||||
};
|
};
|
||||||
use yaak_models::queries::{get_workspace, update_response_if_id, upsert_cookie_jar};
|
use yaak_models::queries::{get_workspace, update_response_if_id, upsert_cookie_jar};
|
||||||
|
use yaak_plugin_runtime::events::{RenderPurpose, WindowContext};
|
||||||
|
|
||||||
pub async fn send_http_request<R: Runtime>(
|
pub async fn send_http_request<R: Runtime>(
|
||||||
window: &WebviewWindow<R>,
|
window: &WebviewWindow<R>,
|
||||||
@@ -39,8 +40,11 @@ pub async fn send_http_request<R: Runtime>(
|
|||||||
let workspace = get_workspace(window, &request.workspace_id)
|
let workspace = get_workspace(window, &request.workspace_id)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to get Workspace");
|
.expect("Failed to get Workspace");
|
||||||
let cb = &*window.app_handle().state::<PluginTemplateCallback>();
|
let cb = PluginTemplateCallback::new(
|
||||||
let cb = cb.for_send();
|
window.app_handle(),
|
||||||
|
&WindowContext::from_window(window),
|
||||||
|
RenderPurpose::Send,
|
||||||
|
);
|
||||||
let rendered_request =
|
let rendered_request =
|
||||||
render_http_request(&request, &workspace, environment.as_ref(), &cb).await;
|
render_http_request(&request, &workspace, environment.as_ref(), &cb).await;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use chrono::Utc;
|
|||||||
use fern::colors::ColoredLevelConfig;
|
use fern::colors::ColoredLevelConfig;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rand::random;
|
use rand::random;
|
||||||
|
use regex::Regex;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
use tauri::TitleBarStyle;
|
use tauri::TitleBarStyle;
|
||||||
@@ -36,7 +37,7 @@ use crate::export_resources::{get_workspace_export_resources, WorkspaceExportRes
|
|||||||
use crate::grpc::metadata_to_map;
|
use crate::grpc::metadata_to_map;
|
||||||
use crate::http_request::send_http_request;
|
use crate::http_request::send_http_request;
|
||||||
use crate::notifications::YaakNotifier;
|
use crate::notifications::YaakNotifier;
|
||||||
use crate::render::{render_grpc_request, render_http_request, render_template};
|
use crate::render::{render_grpc_request, render_json_value, render_template};
|
||||||
use crate::template_callback::PluginTemplateCallback;
|
use crate::template_callback::PluginTemplateCallback;
|
||||||
use crate::updates::{UpdateMode, YaakUpdater};
|
use crate::updates::{UpdateMode, YaakUpdater};
|
||||||
use crate::window_menu::app_menu;
|
use crate::window_menu::app_menu;
|
||||||
@@ -60,8 +61,8 @@ use yaak_models::queries::{
|
|||||||
use yaak_plugin_runtime::events::{
|
use yaak_plugin_runtime::events::{
|
||||||
BootResponse, CallHttpRequestActionRequest, FilterResponse, FindHttpResponsesResponse,
|
BootResponse, CallHttpRequestActionRequest, FilterResponse, FindHttpResponsesResponse,
|
||||||
GetHttpRequestActionsResponse, GetHttpRequestByIdResponse, GetTemplateFunctionsResponse, Icon,
|
GetHttpRequestActionsResponse, GetHttpRequestByIdResponse, GetTemplateFunctionsResponse, Icon,
|
||||||
InternalEvent, InternalEventPayload, RenderHttpRequestResponse, SendHttpRequestResponse,
|
InternalEvent, InternalEventPayload, RenderPurpose, SendHttpRequestResponse, ShowToastRequest,
|
||||||
ShowToastRequest,
|
TemplateRenderResponse, WindowContext,
|
||||||
};
|
};
|
||||||
use yaak_plugin_runtime::plugin_handle::PluginHandle;
|
use yaak_plugin_runtime::plugin_handle::PluginHandle;
|
||||||
use yaak_templates::{Parser, Tokens};
|
use yaak_templates::{Parser, Tokens};
|
||||||
@@ -121,8 +122,9 @@ async fn cmd_template_tokens_to_string(tokens: Tokens) -> Result<String, String>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_render_template(
|
async fn cmd_render_template<R: Runtime>(
|
||||||
window: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
|
app_handle: AppHandle<R>,
|
||||||
template: &str,
|
template: &str,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
environment_id: Option<&str>,
|
environment_id: Option<&str>,
|
||||||
@@ -139,18 +141,22 @@ async fn cmd_render_template(
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
let rendered = render_template(
|
let rendered = render_template(
|
||||||
window.app_handle(),
|
|
||||||
template,
|
template,
|
||||||
&workspace,
|
&workspace,
|
||||||
environment.as_ref(),
|
environment.as_ref(),
|
||||||
|
&PluginTemplateCallback::new(
|
||||||
|
&app_handle,
|
||||||
|
&WindowContext::from_window(&window),
|
||||||
|
RenderPurpose::Preview,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
Ok(rendered)
|
Ok(rendered)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_dismiss_notification(
|
async fn cmd_dismiss_notification<R: Runtime>(
|
||||||
window: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
notification_id: &str,
|
notification_id: &str,
|
||||||
yaak_notifier: State<'_, Mutex<YaakNotifier>>,
|
yaak_notifier: State<'_, Mutex<YaakNotifier>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
@@ -162,10 +168,10 @@ async fn cmd_dismiss_notification(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_grpc_reflect(
|
async fn cmd_grpc_reflect<R: Runtime>(
|
||||||
request_id: &str,
|
request_id: &str,
|
||||||
proto_files: Vec<String>,
|
proto_files: Vec<String>,
|
||||||
window: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
grpc_handle: State<'_, Mutex<GrpcHandle>>,
|
grpc_handle: State<'_, Mutex<GrpcHandle>>,
|
||||||
) -> Result<Vec<ServiceDefinition>, String> {
|
) -> Result<Vec<ServiceDefinition>, String> {
|
||||||
let req = get_grpc_request(&window, request_id)
|
let req = get_grpc_request(&window, request_id)
|
||||||
@@ -189,11 +195,11 @@ async fn cmd_grpc_reflect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_grpc_go(
|
async fn cmd_grpc_go<R: Runtime>(
|
||||||
request_id: &str,
|
request_id: &str,
|
||||||
environment_id: Option<&str>,
|
environment_id: Option<&str>,
|
||||||
proto_files: Vec<String>,
|
proto_files: Vec<String>,
|
||||||
window: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
grpc_handle: State<'_, Mutex<GrpcHandle>>,
|
grpc_handle: State<'_, Mutex<GrpcHandle>>,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let environment = match environment_id {
|
let environment = match environment_id {
|
||||||
@@ -210,8 +216,17 @@ async fn cmd_grpc_go(
|
|||||||
let workspace = get_workspace(&window, &req.workspace_id)
|
let workspace = get_workspace(&window, &req.workspace_id)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
let req =
|
let req = render_grpc_request(
|
||||||
render_grpc_request(window.app_handle(), &req, &workspace, environment.as_ref()).await;
|
&req,
|
||||||
|
&workspace,
|
||||||
|
environment.as_ref(),
|
||||||
|
&PluginTemplateCallback::new(
|
||||||
|
window.app_handle(),
|
||||||
|
&WindowContext::from_window(&window),
|
||||||
|
RenderPurpose::Send,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
let mut metadata = BTreeMap::new();
|
let mut metadata = BTreeMap::new();
|
||||||
|
|
||||||
// Add the rest of metadata
|
// Add the rest of metadata
|
||||||
@@ -345,7 +360,7 @@ async fn cmd_grpc_go(
|
|||||||
|
|
||||||
move |ev: tauri::Event| {
|
move |ev: tauri::Event| {
|
||||||
if *cancelled_rx.borrow() {
|
if *cancelled_rx.borrow() {
|
||||||
// Stream is cancelled
|
// Stream is canceled
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,13 +765,13 @@ async fn cmd_send_ephemeral_request(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_filter_response(
|
async fn cmd_filter_response<R: Runtime>(
|
||||||
w: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
response_id: &str,
|
response_id: &str,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
filter: &str,
|
filter: &str,
|
||||||
) -> Result<FilterResponse, String> {
|
) -> Result<FilterResponse, String> {
|
||||||
let response = get_http_response(&w, response_id)
|
let response = get_http_response(&window, response_id)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to get http response");
|
.expect("Failed to get http response");
|
||||||
|
|
||||||
@@ -776,14 +791,14 @@ async fn cmd_filter_response(
|
|||||||
|
|
||||||
// TODO: Have plugins register their own content type (regex?)
|
// TODO: Have plugins register their own content type (regex?)
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.filter_data(filter, &body, &content_type)
|
.filter_data(&window, filter, &body, &content_type)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_import_data(
|
async fn cmd_import_data<R: Runtime>(
|
||||||
w: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
file_path: &str,
|
file_path: &str,
|
||||||
) -> Result<WorkspaceExportResources, String> {
|
) -> Result<WorkspaceExportResources, String> {
|
||||||
@@ -791,7 +806,7 @@ async fn cmd_import_data(
|
|||||||
read_to_string(file_path).unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
|
read_to_string(file_path).unwrap_or_else(|_| panic!("Unable to read file {}", file_path));
|
||||||
let file_contents = file.as_str();
|
let file_contents = file.as_str();
|
||||||
let (import_result, plugin_name) = plugin_manager
|
let (import_result, plugin_name) = plugin_manager
|
||||||
.import_data(file_contents)
|
.import_data(&window, file_contents)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
@@ -828,7 +843,9 @@ async fn cmd_import_data(
|
|||||||
|
|
||||||
for mut v in resources.workspaces {
|
for mut v in resources.workspaces {
|
||||||
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeWorkspace, &mut id_map);
|
v.id = maybe_gen_id(v.id.as_str(), ModelType::TypeWorkspace, &mut id_map);
|
||||||
let x = upsert_workspace(&w, v).await.map_err(|e| e.to_string())?;
|
let x = upsert_workspace(&window, v)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
imported_resources.workspaces.push(x.clone());
|
imported_resources.workspaces.push(x.clone());
|
||||||
}
|
}
|
||||||
info!(
|
info!(
|
||||||
@@ -843,7 +860,9 @@ async fn cmd_import_data(
|
|||||||
ModelType::TypeWorkspace,
|
ModelType::TypeWorkspace,
|
||||||
&mut id_map,
|
&mut id_map,
|
||||||
);
|
);
|
||||||
let x = upsert_environment(&w, v).await.map_err(|e| e.to_string())?;
|
let x = upsert_environment(&window, v)
|
||||||
|
.await
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
imported_resources.environments.push(x.clone());
|
imported_resources.environments.push(x.clone());
|
||||||
}
|
}
|
||||||
info!(
|
info!(
|
||||||
@@ -875,7 +894,7 @@ async fn cmd_import_data(
|
|||||||
if let Some(_) = imported_resources.folders.iter().find(|f| f.id == v.id) {
|
if let Some(_) = imported_resources.folders.iter().find(|f| f.id == v.id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let x = upsert_folder(&w, v).await.map_err(|e| e.to_string())?;
|
let x = upsert_folder(&window, v).await.map_err(|e| e.to_string())?;
|
||||||
imported_resources.folders.push(x.clone());
|
imported_resources.folders.push(x.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -889,7 +908,7 @@ async fn cmd_import_data(
|
|||||||
&mut id_map,
|
&mut id_map,
|
||||||
);
|
);
|
||||||
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
|
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
|
||||||
let x = upsert_http_request(&w, v)
|
let x = upsert_http_request(&window, v)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
imported_resources.http_requests.push(x.clone());
|
imported_resources.http_requests.push(x.clone());
|
||||||
@@ -907,7 +926,7 @@ async fn cmd_import_data(
|
|||||||
&mut id_map,
|
&mut id_map,
|
||||||
);
|
);
|
||||||
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
|
v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map);
|
||||||
let x = upsert_grpc_request(&w, &v)
|
let x = upsert_grpc_request(&window, &v)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
imported_resources.grpc_requests.push(x.clone());
|
imported_resources.grpc_requests.push(x.clone());
|
||||||
@@ -918,7 +937,7 @@ async fn cmd_import_data(
|
|||||||
);
|
);
|
||||||
|
|
||||||
analytics::track_event(
|
analytics::track_event(
|
||||||
&w,
|
&window,
|
||||||
AnalyticsResource::App,
|
AnalyticsResource::App,
|
||||||
AnalyticsAction::Import,
|
AnalyticsAction::Import,
|
||||||
Some(json!({ "plugin": plugin_name })),
|
Some(json!({ "plugin": plugin_name })),
|
||||||
@@ -929,52 +948,55 @@ async fn cmd_import_data(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_http_request_actions(
|
async fn cmd_http_request_actions<R: Runtime>(
|
||||||
|
window: WebviewWindow<R>,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
) -> Result<Vec<GetHttpRequestActionsResponse>, String> {
|
) -> Result<Vec<GetHttpRequestActionsResponse>, String> {
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.get_http_request_actions()
|
.get_http_request_actions(&window)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_template_functions(
|
async fn cmd_template_functions<R: Runtime>(
|
||||||
|
window: WebviewWindow<R>,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
) -> Result<Vec<GetTemplateFunctionsResponse>, String> {
|
) -> Result<Vec<GetTemplateFunctionsResponse>, String> {
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.get_template_functions()
|
.get_template_functions(&window)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_call_http_request_action(
|
async fn cmd_call_http_request_action<R: Runtime>(
|
||||||
|
window: WebviewWindow<R>,
|
||||||
req: CallHttpRequestActionRequest,
|
req: CallHttpRequestActionRequest,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.call_http_request_action(req)
|
.call_http_request_action(&window, req)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_curl_to_request(
|
async fn cmd_curl_to_request<R: Runtime>(
|
||||||
|
window: WebviewWindow<R>,
|
||||||
command: &str,
|
command: &str,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
w: WebviewWindow,
|
|
||||||
) -> Result<HttpRequest, String> {
|
) -> Result<HttpRequest, String> {
|
||||||
let (import_result, plugin_name) = {
|
let (import_result, plugin_name) = {
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.import_data(command)
|
.import_data(&window, command)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?
|
.map_err(|e| e.to_string())?
|
||||||
};
|
};
|
||||||
|
|
||||||
analytics::track_event(
|
analytics::track_event(
|
||||||
&w,
|
&window,
|
||||||
AnalyticsResource::App,
|
AnalyticsResource::App,
|
||||||
AnalyticsAction::Import,
|
AnalyticsAction::Import,
|
||||||
Some(json!({ "plugin": plugin_name })),
|
Some(json!({ "plugin": plugin_name })),
|
||||||
@@ -1176,19 +1198,19 @@ async fn cmd_create_workspace(name: &str, w: WebviewWindow) -> Result<Workspace,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_install_plugin(
|
async fn cmd_install_plugin<R: Runtime>(
|
||||||
directory: &str,
|
directory: &str,
|
||||||
url: Option<String>,
|
url: Option<String>,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
w: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
) -> Result<Plugin, String> {
|
) -> Result<Plugin, String> {
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.add_plugin_by_dir(&directory, true)
|
.add_plugin_by_dir(WindowContext::from_window(&window), &directory, true)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let plugin = upsert_plugin(
|
let plugin = upsert_plugin(
|
||||||
&w,
|
&window,
|
||||||
Plugin {
|
Plugin {
|
||||||
directory: directory.into(),
|
directory: directory.into(),
|
||||||
url,
|
url,
|
||||||
@@ -1202,17 +1224,20 @@ async fn cmd_install_plugin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_uninstall_plugin(
|
async fn cmd_uninstall_plugin<R: Runtime>(
|
||||||
plugin_id: &str,
|
plugin_id: &str,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
w: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
) -> Result<Plugin, String> {
|
) -> Result<Plugin, String> {
|
||||||
let plugin = delete_plugin(&w, plugin_id)
|
let plugin = delete_plugin(&window, plugin_id)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.uninstall(plugin.directory.as_str())
|
.uninstall(
|
||||||
|
WindowContext::from_window(&window),
|
||||||
|
plugin.directory.as_str(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
@@ -1493,12 +1518,12 @@ async fn cmd_list_plugins(w: WebviewWindow) -> Result<Vec<Plugin>, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_reload_plugins(
|
async fn cmd_reload_plugins<R: Runtime>(
|
||||||
app_handle: AppHandle,
|
window: WebviewWindow<R>,
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.initialize_all_plugins(&app_handle)
|
.initialize_all_plugins(window.app_handle(), WindowContext::from_window(&window))
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1828,10 +1853,6 @@ pub fn run() {
|
|||||||
let grpc_handle = GrpcHandle::new(&app.app_handle());
|
let grpc_handle = GrpcHandle::new(&app.app_handle());
|
||||||
app.manage(Mutex::new(grpc_handle));
|
app.manage(Mutex::new(grpc_handle));
|
||||||
|
|
||||||
// Plugin template callback
|
|
||||||
let plugin_cb = PluginTemplateCallback::new(app.app_handle().clone());
|
|
||||||
app.manage(plugin_cb);
|
|
||||||
|
|
||||||
monitor_plugin_events(&app.app_handle().clone());
|
monitor_plugin_events(&app.app_handle().clone());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -2143,6 +2164,7 @@ async fn handle_plugin_event<R: Runtime>(
|
|||||||
plugin_handle: &PluginHandle,
|
plugin_handle: &PluginHandle,
|
||||||
) {
|
) {
|
||||||
// info!("Got event to app {}", event.id);
|
// info!("Got event to app {}", event.id);
|
||||||
|
let window_context = event.window_context.to_owned();
|
||||||
let response_event: Option<InternalEventPayload> = match event.clone().payload {
|
let response_event: Option<InternalEventPayload> = match event.clone().payload {
|
||||||
InternalEventPayload::CopyTextRequest(req) => {
|
InternalEventPayload::CopyTextRequest(req) => {
|
||||||
app_handle
|
app_handle
|
||||||
@@ -2152,9 +2174,14 @@ async fn handle_plugin_event<R: Runtime>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
InternalEventPayload::ShowToastRequest(req) => {
|
InternalEventPayload::ShowToastRequest(req) => {
|
||||||
app_handle
|
match window_context {
|
||||||
.emit("show_toast", req)
|
WindowContext::Label { label } => app_handle
|
||||||
.expect("Failed to emit show_toast");
|
.emit_to(label, "show_toast", req)
|
||||||
|
.expect("Failed to emit show_toast to window"),
|
||||||
|
_ => app_handle
|
||||||
|
.emit("show_toast", req)
|
||||||
|
.expect("Failed to emit show_toast"),
|
||||||
|
};
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
InternalEventPayload::FindHttpResponsesRequest(req) => {
|
InternalEventPayload::FindHttpResponsesRequest(req) => {
|
||||||
@@ -2175,33 +2202,24 @@ async fn handle_plugin_event<R: Runtime>(
|
|||||||
GetHttpRequestByIdResponse { http_request },
|
GetHttpRequestByIdResponse { http_request },
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
InternalEventPayload::RenderHttpRequestRequest(req) => {
|
InternalEventPayload::TemplateRenderRequest(req) => {
|
||||||
let window = get_focused_window_no_lock(app_handle).expect("No focused window");
|
let window = get_window_from_window_context(app_handle, &window_context)
|
||||||
let workspace = get_workspace(app_handle, req.http_request.workspace_id.as_str())
|
.expect("Failed to find window");
|
||||||
.await
|
|
||||||
.expect("Failed to get workspace for request");
|
|
||||||
|
|
||||||
let url = window.url().unwrap();
|
let workspace = workspace_from_window(&window)
|
||||||
let mut query_pairs = url.query_pairs();
|
.await
|
||||||
let environment_id = query_pairs
|
.expect("Failed to get workspace_id from window URL");
|
||||||
.find(|(k, _v)| k == "environment_id")
|
let environment = environment_from_window(&window).await;
|
||||||
.map(|(_k, v)| v.to_string());
|
let cb = PluginTemplateCallback::new(app_handle, &window_context, req.purpose);
|
||||||
let environment = match environment_id {
|
let data = render_json_value(req.data, &workspace, environment.as_ref(), &cb).await;
|
||||||
None => None,
|
Some(InternalEventPayload::TemplateRenderResponse(
|
||||||
Some(id) => get_environment(&window, id.as_str()).await.ok(),
|
TemplateRenderResponse { data },
|
||||||
};
|
|
||||||
let cb = &*app_handle.state::<PluginTemplateCallback>();
|
|
||||||
let rendered_http_request =
|
|
||||||
render_http_request(&req.http_request, &workspace, environment.as_ref(), cb).await;
|
|
||||||
Some(InternalEventPayload::RenderHttpRequestResponse(
|
|
||||||
RenderHttpRequestResponse {
|
|
||||||
http_request: rendered_http_request,
|
|
||||||
},
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
InternalEventPayload::ReloadResponse => {
|
InternalEventPayload::ReloadResponse => {
|
||||||
let window = get_focused_window_no_lock(app_handle).expect("No focused window");
|
let window = get_window_from_window_context(app_handle, &window_context)
|
||||||
let plugins = list_plugins(&window).await.unwrap();
|
.expect("Failed to find window");
|
||||||
|
let plugins = list_plugins(app_handle).await.unwrap();
|
||||||
for plugin in plugins {
|
for plugin in plugins {
|
||||||
if plugin.directory != plugin_handle.dir {
|
if plugin.directory != plugin_handle.dir {
|
||||||
continue;
|
continue;
|
||||||
@@ -2214,6 +2232,7 @@ async fn handle_plugin_event<R: Runtime>(
|
|||||||
upsert_plugin(&window, new_plugin).await.unwrap();
|
upsert_plugin(&window, new_plugin).await.unwrap();
|
||||||
}
|
}
|
||||||
let toast_event = plugin_handle.build_event_to_send(
|
let toast_event = plugin_handle.build_event_to_send(
|
||||||
|
WindowContext::from_window(&window),
|
||||||
&InternalEventPayload::ShowToastRequest(ShowToastRequest {
|
&InternalEventPayload::ShowToastRequest(ShowToastRequest {
|
||||||
message: format!("Reloaded plugin {}", plugin_handle.dir),
|
message: format!("Reloaded plugin {}", plugin_handle.dir),
|
||||||
icon: Some(Icon::Info),
|
icon: Some(Icon::Info),
|
||||||
@@ -2225,32 +2244,17 @@ async fn handle_plugin_event<R: Runtime>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
InternalEventPayload::SendHttpRequestRequest(req) => {
|
InternalEventPayload::SendHttpRequestRequest(req) => {
|
||||||
let w = get_focused_window_no_lock(app_handle).expect("No focused window");
|
let window = get_window_from_window_context(app_handle, &window_context)
|
||||||
let url = w.url().unwrap();
|
.expect("Failed to find window");
|
||||||
let mut query_pairs = url.query_pairs();
|
let cookie_jar = cookie_jar_from_window(&window).await;
|
||||||
|
let environment = environment_from_window(&window).await;
|
||||||
|
|
||||||
let cookie_jar_id = query_pairs
|
let resp = create_default_http_response(&window, req.http_request.id.as_str())
|
||||||
.find(|(k, _v)| k == "cookie_jar_id")
|
|
||||||
.map(|(_k, v)| v.to_string());
|
|
||||||
let cookie_jar = match cookie_jar_id {
|
|
||||||
None => None,
|
|
||||||
Some(id) => get_cookie_jar(app_handle, id.as_str()).await.ok(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let environment_id = query_pairs
|
|
||||||
.find(|(k, _v)| k == "environment_id")
|
|
||||||
.map(|(_k, v)| v.to_string());
|
|
||||||
let environment = match environment_id {
|
|
||||||
None => None,
|
|
||||||
Some(id) => get_environment(app_handle, id.as_str()).await.ok(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let resp = create_default_http_response(&w, req.http_request.id.as_str())
|
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let result = send_http_request(
|
let result = send_http_request(
|
||||||
&w,
|
&window,
|
||||||
&req.http_request,
|
&req.http_request,
|
||||||
&resp,
|
&resp,
|
||||||
environment,
|
environment,
|
||||||
@@ -2279,29 +2283,66 @@ async fn handle_plugin_event<R: Runtime>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// app_handle.get_focused_window locks, so this one is a non-locking version, safe for use in async context
|
fn get_window_from_window_context<R: Runtime>(
|
||||||
fn get_focused_window_no_lock<R: Runtime>(app_handle: &AppHandle<R>) -> Option<WebviewWindow<R>> {
|
app_handle: &AppHandle<R>,
|
||||||
// TODO: Getting the focused window doesn't seem to work on Windows, so
|
window_context: &WindowContext,
|
||||||
// we'll need to pass the window label into plugin events instead.
|
) -> Option<WebviewWindow<R>> {
|
||||||
let main_windows = app_handle
|
let label = match window_context {
|
||||||
.webview_windows()
|
WindowContext::None => return None,
|
||||||
.iter()
|
WindowContext::Label { label } => label,
|
||||||
.filter_map(|(_, w)| {
|
};
|
||||||
if w.label().starts_with(MAIN_WINDOW_PREFIX) {
|
|
||||||
Some(w.to_owned())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<WebviewWindow<R>>>();
|
|
||||||
|
|
||||||
if main_windows.len() == 1 {
|
app_handle.webview_windows().iter().find_map(|(_, w)| {
|
||||||
return main_windows.iter().next().map(|w| w.clone());
|
if w.label() == label {
|
||||||
}
|
Some(w.to_owned())
|
||||||
|
} else {
|
||||||
main_windows
|
None
|
||||||
.iter()
|
}
|
||||||
.cloned()
|
})
|
||||||
.find(|w| w.is_focused().unwrap_or(false))
|
}
|
||||||
.map(|w| w.clone())
|
|
||||||
|
fn workspace_id_from_window<R: Runtime>(window: &WebviewWindow<R>) -> Option<String> {
|
||||||
|
let url = window.url().unwrap();
|
||||||
|
let re = Regex::new(r"/workspaces/(?<wid>\w+)").unwrap();
|
||||||
|
match re.captures(url.as_str()) {
|
||||||
|
None => None,
|
||||||
|
Some(captures) => captures.name("wid").map(|c| c.as_str().to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn workspace_from_window<R: Runtime>(window: &WebviewWindow<R>) -> Option<Workspace> {
|
||||||
|
match workspace_id_from_window(&window) {
|
||||||
|
None => None,
|
||||||
|
Some(id) => get_workspace(window, id.as_str()).await.ok(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn environment_id_from_window<R: Runtime>(window: &WebviewWindow<R>) -> Option<String> {
|
||||||
|
let url = window.url().unwrap();
|
||||||
|
let mut query_pairs = url.query_pairs();
|
||||||
|
query_pairs
|
||||||
|
.find(|(k, _v)| k == "environment_id")
|
||||||
|
.map(|(_k, v)| v.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn environment_from_window<R: Runtime>(window: &WebviewWindow<R>) -> Option<Environment> {
|
||||||
|
match environment_id_from_window(&window) {
|
||||||
|
None => None,
|
||||||
|
Some(id) => get_environment(window, id.as_str()).await.ok(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cookie_jar_id_from_window<R: Runtime>(window: &WebviewWindow<R>) -> Option<String> {
|
||||||
|
let url = window.url().unwrap();
|
||||||
|
let mut query_pairs = url.query_pairs();
|
||||||
|
query_pairs
|
||||||
|
.find(|(k, _v)| k == "cookie_jar_id")
|
||||||
|
.map(|(_k, v)| v.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn cookie_jar_from_window<R: Runtime>(window: &WebviewWindow<R>) -> Option<CookieJar> {
|
||||||
|
match cookie_jar_id_from_window(&window) {
|
||||||
|
None => None,
|
||||||
|
Some(id) => get_cookie_jar(window, id.as_str()).await.ok(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ impl YaakNotifier {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check<R: Runtime>(&mut self, w: &WebviewWindow<R>) -> Result<(), String> {
|
pub async fn check<R: Runtime>(&mut self, window: &WebviewWindow<R>) -> Result<(), String> {
|
||||||
let ignore_check = self.last_check.elapsed().unwrap().as_secs() < MAX_UPDATE_CHECK_SECONDS;
|
let ignore_check = self.last_check.elapsed().unwrap().as_secs() < MAX_UPDATE_CHECK_SECONDS;
|
||||||
|
|
||||||
if ignore_check {
|
if ignore_check {
|
||||||
@@ -60,8 +60,8 @@ impl YaakNotifier {
|
|||||||
|
|
||||||
self.last_check = SystemTime::now();
|
self.last_check = SystemTime::now();
|
||||||
|
|
||||||
let num_launches = get_num_launches(w).await;
|
let num_launches = get_num_launches(window).await;
|
||||||
let info = w.app_handle().package_info().clone();
|
let info = window.app_handle().package_info().clone();
|
||||||
let req = reqwest::Client::default()
|
let req = reqwest::Client::default()
|
||||||
.request(Method::GET, "https://notify.yaak.app/notifications")
|
.request(Method::GET, "https://notify.yaak.app/notifications")
|
||||||
.query(&[
|
.query(&[
|
||||||
@@ -80,14 +80,14 @@ impl YaakNotifier {
|
|||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
let age = notification.timestamp.signed_duration_since(Utc::now());
|
let age = notification.timestamp.signed_duration_since(Utc::now());
|
||||||
let seen = get_kv(w).await?;
|
let seen = get_kv(window).await?;
|
||||||
if seen.contains(¬ification.id) || (age > Duration::days(2)) {
|
if seen.contains(¬ification.id) || (age > Duration::days(2)) {
|
||||||
debug!("Already seen notification {}", notification.id);
|
debug!("Already seen notification {}", notification.id);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
debug!("Got notification {:?}", notification);
|
debug!("Got notification {:?}", notification);
|
||||||
|
|
||||||
let _ = w.emit("notification", notification.clone());
|
let _ = window.emit_to(window.label(), "notification", notification.clone());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,38 @@
|
|||||||
use crate::template_callback::PluginTemplateCallback;
|
use crate::template_callback::PluginTemplateCallback;
|
||||||
use serde_json::{json, Map, Value};
|
use serde_json::{json, Map, Value};
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use tauri::{AppHandle, Manager, Runtime};
|
|
||||||
use yaak_models::models::{
|
use yaak_models::models::{
|
||||||
Environment, EnvironmentVariable, GrpcMetadataEntry, GrpcRequest, HttpRequest,
|
Environment, EnvironmentVariable, GrpcMetadataEntry, GrpcRequest, HttpRequest,
|
||||||
HttpRequestHeader, HttpUrlParameter, Workspace,
|
HttpRequestHeader, HttpUrlParameter, Workspace,
|
||||||
};
|
};
|
||||||
use yaak_templates::{parse_and_render, TemplateCallback};
|
use yaak_templates::{parse_and_render, TemplateCallback};
|
||||||
|
|
||||||
pub async fn render_template<R: Runtime>(
|
pub async fn render_template<T: TemplateCallback>(
|
||||||
app_handle: &AppHandle<R>,
|
|
||||||
template: &str,
|
template: &str,
|
||||||
w: &Workspace,
|
w: &Workspace,
|
||||||
e: Option<&Environment>,
|
e: Option<&Environment>,
|
||||||
|
cb: &T,
|
||||||
) -> String {
|
) -> String {
|
||||||
let cb = &*app_handle.state::<PluginTemplateCallback>();
|
|
||||||
let vars = &make_vars_hashmap(w, e);
|
let vars = &make_vars_hashmap(w, e);
|
||||||
render(template, vars, cb).await
|
render(template, vars, cb).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn render_grpc_request<R: Runtime>(
|
pub async fn render_json_value<T: TemplateCallback>(
|
||||||
app_handle: &AppHandle<R>,
|
value: Value,
|
||||||
|
w: &Workspace,
|
||||||
|
e: Option<&Environment>,
|
||||||
|
cb: &T,
|
||||||
|
) -> Value {
|
||||||
|
let vars = &make_vars_hashmap(w, e);
|
||||||
|
render_json_value_raw(value, vars, cb).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn render_grpc_request<T: TemplateCallback>(
|
||||||
r: &GrpcRequest,
|
r: &GrpcRequest,
|
||||||
w: &Workspace,
|
w: &Workspace,
|
||||||
e: Option<&Environment>,
|
e: Option<&Environment>,
|
||||||
|
cb: &T,
|
||||||
) -> GrpcRequest {
|
) -> GrpcRequest {
|
||||||
let cb = &*app_handle.state::<PluginTemplateCallback>();
|
|
||||||
let vars = &make_vars_hashmap(w, e);
|
let vars = &make_vars_hashmap(w, e);
|
||||||
|
|
||||||
let mut metadata = Vec::new();
|
let mut metadata = Vec::new();
|
||||||
@@ -39,7 +46,7 @@ pub async fn render_grpc_request<R: Runtime>(
|
|||||||
|
|
||||||
let mut authentication = BTreeMap::new();
|
let mut authentication = BTreeMap::new();
|
||||||
for (k, v) in r.authentication.clone() {
|
for (k, v) in r.authentication.clone() {
|
||||||
authentication.insert(k, render_json_value(v, vars, cb).await);
|
authentication.insert(k, render_json_value_raw(v, vars, cb).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = render(r.url.as_str(), vars, cb).await;
|
let url = render(r.url.as_str(), vars, cb).await;
|
||||||
@@ -80,12 +87,12 @@ pub async fn render_http_request(
|
|||||||
|
|
||||||
let mut body = BTreeMap::new();
|
let mut body = BTreeMap::new();
|
||||||
for (k, v) in r.body.clone() {
|
for (k, v) in r.body.clone() {
|
||||||
body.insert(k, render_json_value(v, vars, cb).await);
|
body.insert(k, render_json_value_raw(v, vars, cb).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut authentication = BTreeMap::new();
|
let mut authentication = BTreeMap::new();
|
||||||
for (k, v) in r.authentication.clone() {
|
for (k, v) in r.authentication.clone() {
|
||||||
authentication.insert(k, render_json_value(v, vars, cb).await);
|
authentication.insert(k, render_json_value_raw(v, vars, cb).await);
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = render(r.url.clone().as_str(), vars, cb).await;
|
let url = render(r.url.clone().as_str(), vars, cb).await;
|
||||||
@@ -138,7 +145,7 @@ fn add_variable_to_map(
|
|||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn render_json_value<T: TemplateCallback>(
|
async fn render_json_value_raw<T: TemplateCallback>(
|
||||||
v: Value,
|
v: Value,
|
||||||
vars: &HashMap<String, String>,
|
vars: &HashMap<String, String>,
|
||||||
cb: &T,
|
cb: &T,
|
||||||
@@ -148,7 +155,7 @@ pub async fn render_json_value<T: TemplateCallback>(
|
|||||||
Value::Array(a) => {
|
Value::Array(a) => {
|
||||||
let mut new_a = Vec::new();
|
let mut new_a = Vec::new();
|
||||||
for v in a {
|
for v in a {
|
||||||
new_a.push(Box::pin(render_json_value(v, vars, cb)).await)
|
new_a.push(Box::pin(render_json_value_raw(v, vars, cb)).await)
|
||||||
}
|
}
|
||||||
json!(new_a)
|
json!(new_a)
|
||||||
}
|
}
|
||||||
@@ -156,7 +163,7 @@ pub async fn render_json_value<T: TemplateCallback>(
|
|||||||
let mut new_o = Map::new();
|
let mut new_o = Map::new();
|
||||||
for (k, v) in o {
|
for (k, v) in o {
|
||||||
let key = Box::pin(render(k.as_str(), vars, cb)).await;
|
let key = Box::pin(render(k.as_str(), vars, cb)).await;
|
||||||
let value = Box::pin(render_json_value(v, vars, cb)).await;
|
let value = Box::pin(render_json_value_raw(v, vars, cb)).await;
|
||||||
new_o.insert(key, value);
|
new_o.insert(key, value);
|
||||||
}
|
}
|
||||||
json!(new_o)
|
json!(new_o)
|
||||||
@@ -189,7 +196,7 @@ mod tests {
|
|||||||
let mut vars = HashMap::new();
|
let mut vars = HashMap::new();
|
||||||
vars.insert("a".to_string(), "aaa".to_string());
|
vars.insert("a".to_string(), "aaa".to_string());
|
||||||
|
|
||||||
let result = super::render_json_value(v, &vars, &EmptyCB {}).await;
|
let result = super::render_json_value_raw(v, &vars, &EmptyCB {}).await;
|
||||||
assert_eq!(result, json!("aaa"))
|
assert_eq!(result, json!("aaa"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +206,7 @@ mod tests {
|
|||||||
let mut vars = HashMap::new();
|
let mut vars = HashMap::new();
|
||||||
vars.insert("a".to_string(), "aaa".to_string());
|
vars.insert("a".to_string(), "aaa".to_string());
|
||||||
|
|
||||||
let result = super::render_json_value(v, &vars, &EmptyCB {}).await;
|
let result = super::render_json_value_raw(v, &vars, &EmptyCB {}).await;
|
||||||
assert_eq!(result, json!(["aaa", "aaa"]))
|
assert_eq!(result, json!(["aaa", "aaa"]))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +216,7 @@ mod tests {
|
|||||||
let mut vars = HashMap::new();
|
let mut vars = HashMap::new();
|
||||||
vars.insert("a".to_string(), "aaa".to_string());
|
vars.insert("a".to_string(), "aaa".to_string());
|
||||||
|
|
||||||
let result = super::render_json_value(v, &vars, &EmptyCB {}).await;
|
let result = super::render_json_value_raw(v, &vars, &EmptyCB {}).await;
|
||||||
assert_eq!(result, json!({"aaa": "aaa"}))
|
assert_eq!(result, json!({"aaa": "aaa"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +233,7 @@ mod tests {
|
|||||||
let mut vars = HashMap::new();
|
let mut vars = HashMap::new();
|
||||||
vars.insert("a".to_string(), "aaa".to_string());
|
vars.insert("a".to_string(), "aaa".to_string());
|
||||||
|
|
||||||
let result = super::render_json_value(v, &vars, &EmptyCB {}).await;
|
let result = super::render_json_value_raw(v, &vars, &EmptyCB {}).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result,
|
result,
|
||||||
json!([
|
json!([
|
||||||
|
|||||||
@@ -1,32 +1,34 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tauri::{AppHandle, Manager};
|
use tauri::{AppHandle, Manager, Runtime};
|
||||||
use yaak_plugin_runtime::events::{RenderPurpose, TemplateFunctionArg};
|
use yaak_plugin_runtime::events::{RenderPurpose, TemplateFunctionArg, WindowContext};
|
||||||
use yaak_plugin_runtime::manager::PluginManager;
|
use yaak_plugin_runtime::manager::PluginManager;
|
||||||
use yaak_templates::TemplateCallback;
|
use yaak_templates::TemplateCallback;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PluginTemplateCallback {
|
pub struct PluginTemplateCallback {
|
||||||
app_handle: AppHandle,
|
plugin_manager: PluginManager,
|
||||||
purpose: RenderPurpose,
|
window_context: WindowContext,
|
||||||
|
render_purpose: RenderPurpose,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PluginTemplateCallback {
|
impl PluginTemplateCallback {
|
||||||
pub fn new(app_handle: AppHandle) -> PluginTemplateCallback {
|
pub fn new<R: Runtime>(
|
||||||
|
app_handle: &AppHandle<R>,
|
||||||
|
window_context: &WindowContext,
|
||||||
|
render_purpose: RenderPurpose,
|
||||||
|
) -> PluginTemplateCallback {
|
||||||
|
let plugin_manager = &*app_handle.state::<PluginManager>();
|
||||||
PluginTemplateCallback {
|
PluginTemplateCallback {
|
||||||
app_handle,
|
plugin_manager: plugin_manager.to_owned(),
|
||||||
purpose: RenderPurpose::Preview,
|
window_context: window_context.to_owned(),
|
||||||
|
render_purpose,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_send(&self) -> PluginTemplateCallback {
|
|
||||||
let mut v = self.clone();
|
|
||||||
v.purpose = RenderPurpose::Send;
|
|
||||||
v
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TemplateCallback for PluginTemplateCallback {
|
impl TemplateCallback for PluginTemplateCallback {
|
||||||
async fn run(&self, fn_name: &str, args: HashMap<String, String>) -> Result<String, String> {
|
async fn run(&self, fn_name: &str, args: HashMap<String, String>) -> Result<String, String> {
|
||||||
|
let window_context = self.window_context.to_owned();
|
||||||
// The beta named the function `Response` but was changed in stable.
|
// The beta named the function `Response` but was changed in stable.
|
||||||
// Keep this here for a while because there's no easy way to migrate
|
// Keep this here for a while because there's no easy way to migrate
|
||||||
let fn_name = if fn_name == "Response" {
|
let fn_name = if fn_name == "Response" {
|
||||||
@@ -35,9 +37,9 @@ impl TemplateCallback for PluginTemplateCallback {
|
|||||||
fn_name
|
fn_name
|
||||||
};
|
};
|
||||||
|
|
||||||
let plugin_manager = self.app_handle.state::<PluginManager>();
|
let function = self
|
||||||
let function = plugin_manager
|
.plugin_manager
|
||||||
.get_template_functions()
|
.get_template_functions_with_context(window_context.to_owned())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?
|
.map_err(|e| e.to_string())?
|
||||||
.iter()
|
.iter()
|
||||||
@@ -60,8 +62,14 @@ impl TemplateCallback for PluginTemplateCallback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let resp = plugin_manager
|
let resp = self
|
||||||
.call_template_function(fn_name, args_with_defaults, self.purpose.clone())
|
.plugin_manager
|
||||||
|
.call_template_function(
|
||||||
|
window_context,
|
||||||
|
fn_name,
|
||||||
|
args_with_defaults,
|
||||||
|
self.render_purpose.to_owned(),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
Ok(resp.unwrap_or_default())
|
Ok(resp.unwrap_or_default())
|
||||||
|
|||||||
@@ -3,15 +3,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.js"
|
"build": "yaakcli build ./src/index.js",
|
||||||
},
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
"dependencies": {
|
|
||||||
"@yaakapp/api": "^0.2.9"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"typescript": "^5.5.2",
|
|
||||||
"vitest": "^1.4.0",
|
|
||||||
"@yaakapp/cli": "^0.0.42"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,13 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.ts"
|
"build": "yaakcli build ./src/index.ts",
|
||||||
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jsonpath-plus": "^9.0.0",
|
"jsonpath-plus": "^9.0.0"
|
||||||
"@yaakapp/api": "^0.2.9"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@yaakapp/cli": "^0.0.42",
|
"@types/jsonpath": "^0.2.4"
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"typescript": "^5.5.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,11 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.js"
|
"build": "yaakcli build ./src/index.js",
|
||||||
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@yaakapp/api": "^0.2.9",
|
|
||||||
"@xmldom/xmldom": "^0.8.10",
|
"@xmldom/xmldom": "^0.8.10",
|
||||||
"xpath": "^0.0.34"
|
"xpath": "^0.0.34"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@yaakapp/cli": "^0.0.42",
|
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"typescript": "^5.5.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,10 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.js"
|
"build": "yaakcli build ./src/index.js",
|
||||||
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@yaakapp/api": "^0.2.9",
|
|
||||||
"shell-quote": "^1.8.1"
|
"shell-quote": "^1.8.1"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@yaakapp/cli": "^0.0.42",
|
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"@types/shell-quote": "^1.7.5",
|
|
||||||
"typescript": "^5.5.2",
|
|
||||||
"vitest": "^1.4.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,10 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.js"
|
"build": "yaakcli build ./src/index.js",
|
||||||
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@yaakapp/api": "^0.2.9",
|
|
||||||
"yaml": "^2.4.2"
|
"yaml": "^2.4.2"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@yaakapp/cli": "^0.0.42",
|
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"typescript": "^5.5.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,11 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.js"
|
"build": "yaakcli build ./src/index.js",
|
||||||
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@yaakapp/api": "^0.2.9",
|
|
||||||
"openapi-to-postmanv2": "^4.23.1",
|
"openapi-to-postmanv2": "^4.23.1",
|
||||||
"yaml": "^2.4.2"
|
"yaml": "^2.4.2"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@yaakapp/cli": "^0.0.42",
|
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"@types/openapi-to-postmanv2": "^3.2.4",
|
|
||||||
"typescript": "^5.5.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,16 +4,7 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"main": "./build/index.js",
|
"main": "./build/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.js"
|
"build": "yaakcli build ./src/index.js",
|
||||||
},
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
"dependencies": {
|
|
||||||
"@yaakapp/api": "^0.2.9"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@yaakapp/cli": "^0.0.42",
|
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"esbuild": "^0.21.5",
|
|
||||||
"typescript": "^5.5.2",
|
|
||||||
"vitest": "^1.4.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.js"
|
"build": "yaakcli build ./src/index.js",
|
||||||
},
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
"dependencies": {
|
|
||||||
"@yaakapp/api": "^0.2.9"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@yaakapp/cli": "^0.0.42",
|
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"esbuild": "^0.21.5",
|
|
||||||
"typescript": "^5.5.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
src-tauri/vendored/plugins/template-function-request/build/index.js
generated
Normal file
64
src-tauri/vendored/plugins/template-function-request/build/index.js
generated
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
"use strict";
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __export = (target, all) => {
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __copyProps = (to, from, except, desc) => {
|
||||||
|
if (from && typeof from === "object" || typeof from === "function") {
|
||||||
|
for (let key of __getOwnPropNames(from))
|
||||||
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||||
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||||
|
|
||||||
|
// src/index.ts
|
||||||
|
var src_exports = {};
|
||||||
|
__export(src_exports, {
|
||||||
|
plugin: () => plugin
|
||||||
|
});
|
||||||
|
module.exports = __toCommonJS(src_exports);
|
||||||
|
var plugin = {
|
||||||
|
templateFunctions: [
|
||||||
|
{
|
||||||
|
name: "request.body",
|
||||||
|
args: [],
|
||||||
|
async onRender(ctx, args) {
|
||||||
|
const httpRequest = await ctx.httpRequest.getById({ id: args.values.request ?? "n/a" });
|
||||||
|
if (httpRequest == null) return null;
|
||||||
|
const rendered = await ctx.httpRequest.render({ httpRequest, purpose: args.purpose });
|
||||||
|
return rendered.body.text ?? "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "request.header",
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
name: "requestId",
|
||||||
|
label: "Http Request",
|
||||||
|
type: "http_request"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "header",
|
||||||
|
label: "Header Name",
|
||||||
|
type: "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
async onRender(ctx, args) {
|
||||||
|
const httpRequest = await ctx.httpRequest.getById({ id: args.values.requestId ?? "n/a" });
|
||||||
|
if (httpRequest == null) return null;
|
||||||
|
const rendered = await ctx.httpRequest.render({ httpRequest, purpose: args.purpose });
|
||||||
|
return rendered.headers.find((h) => h.name.toLowerCase() === args.values.header?.toLowerCase())?.value ?? "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
// Annotate the CommonJS export names for ESM import in node:
|
||||||
|
0 && (module.exports = {
|
||||||
|
plugin
|
||||||
|
});
|
||||||
17
src-tauri/vendored/plugins/template-function-request/package.json
generated
Executable file
17
src-tauri/vendored/plugins/template-function-request/package.json
generated
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "template-function-request",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.1",
|
||||||
|
"scripts": {
|
||||||
|
"build": "yaakcli build ./src/index.ts",
|
||||||
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"jsonpath-plus": "^9.0.0",
|
||||||
|
"xpath": "^0.0.34",
|
||||||
|
"@xmldom/xmldom": "^0.8.10"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/jsonpath": "^0.2.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,19 +3,15 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build ./src/index.ts"
|
"build": "yaakcli build ./src/index.ts",
|
||||||
|
"dev": "yaakcli dev ./src/index.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@yaakapp/api": "^0.2.9",
|
|
||||||
"jsonpath-plus": "^9.0.0",
|
"jsonpath-plus": "^9.0.0",
|
||||||
"xpath": "^0.0.34",
|
"xpath": "^0.0.34",
|
||||||
"@xmldom/xmldom": "^0.8.10"
|
"@xmldom/xmldom": "^0.8.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@yaakapp/cli": "^0.0.42",
|
"@types/jsonpath": "^0.2.4"
|
||||||
"@types/jsonpath": "^0.2.4",
|
|
||||||
"@types/node": "^20.14.9",
|
|
||||||
"typescript": "^5.5.2",
|
|
||||||
"vitest": "^1.4.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { Folder } from "./models";
|
|||||||
import type { GrpcRequest } from "./models";
|
import type { GrpcRequest } from "./models";
|
||||||
import type { HttpRequest } from "./models";
|
import type { HttpRequest } from "./models";
|
||||||
import type { HttpResponse } from "./models";
|
import type { HttpResponse } from "./models";
|
||||||
|
import type { JsonValue } from "./serde_json/JsonValue";
|
||||||
import type { Workspace } from "./models";
|
import type { Workspace } from "./models";
|
||||||
|
|
||||||
export type BootRequest = { dir: string, watch: boolean, };
|
export type BootRequest = { dir: string, watch: boolean, };
|
||||||
@@ -56,9 +57,9 @@ export type ImportResources = { workspaces: Array<Workspace>, environments: Arra
|
|||||||
|
|
||||||
export type ImportResponse = { resources: ImportResources, };
|
export type ImportResponse = { resources: ImportResources, };
|
||||||
|
|
||||||
export type InternalEvent = { id: string, pluginRefId: string, replyId: string | null, payload: InternalEventPayload, };
|
export type InternalEvent = { id: string, pluginRefId: string, replyId: string | null, payload: InternalEventPayload, windowContext: WindowContext, };
|
||||||
|
|
||||||
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } | { "type": "reload_response" } | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & GetHttpRequestActionsRequest | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "copy_text_request" } & CopyTextRequest | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" };
|
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } | { "type": "reload_response" } | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & GetHttpRequestActionsRequest | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "copy_text_request" } & CopyTextRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" };
|
||||||
|
|
||||||
export type RenderHttpRequestRequest = { httpRequest: HttpRequest, purpose: RenderPurpose, };
|
export type RenderHttpRequestRequest = { httpRequest: HttpRequest, purpose: RenderPurpose, };
|
||||||
|
|
||||||
@@ -87,3 +88,9 @@ export type TemplateFunctionSelectArg = { options: Array<TemplateFunctionSelectO
|
|||||||
export type TemplateFunctionSelectOption = { name: string, value: string, };
|
export type TemplateFunctionSelectOption = { name: string, value: string, };
|
||||||
|
|
||||||
export type TemplateFunctionTextArg = { placeholder?: string | null, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
export type TemplateFunctionTextArg = { placeholder?: string | null, name: string, optional?: boolean | null, label?: string | null, defaultValue?: string | null, };
|
||||||
|
|
||||||
|
export type TemplateRenderRequest = { data: JsonValue, purpose: RenderPurpose, };
|
||||||
|
|
||||||
|
export type TemplateRenderResponse = { data: JsonValue, };
|
||||||
|
|
||||||
|
export type WindowContext = { "type": "none" } | { "type": "label", label: string, };
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
|
||||||
|
export type JsonValue = number | string | Array<JsonValue> | { [key in string]?: JsonValue };
|
||||||
@@ -1,25 +1,40 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use tauri::{Runtime, WebviewWindow};
|
||||||
use ts_rs::TS;
|
use ts_rs::TS;
|
||||||
|
|
||||||
use yaak_models::models::{
|
use yaak_models::models::{Environment, Folder, GrpcRequest, HttpRequest, HttpResponse, Workspace};
|
||||||
Environment, Folder, GrpcRequest, HttpRequest,
|
|
||||||
HttpResponse, Workspace,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct InternalEvent {
|
pub struct InternalEvent {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub plugin_ref_id: String,
|
pub plugin_ref_id: String,
|
||||||
pub reply_id: Option<String>,
|
pub reply_id: Option<String>,
|
||||||
pub payload: InternalEventPayload,
|
pub payload: InternalEventPayload,
|
||||||
|
pub window_context: WindowContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
#[serde(rename_all = "snake_case", tag = "type")]
|
#[serde(rename_all = "snake_case", tag = "type")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
|
pub enum WindowContext {
|
||||||
|
None,
|
||||||
|
Label { label: String },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WindowContext {
|
||||||
|
pub fn from_window<R: Runtime>(window: &WebviewWindow<R>) -> Self {
|
||||||
|
Self::Label {
|
||||||
|
label: window.label().to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(rename_all = "snake_case", tag = "type")]
|
||||||
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub enum InternalEventPayload {
|
pub enum InternalEventPayload {
|
||||||
BootRequest(BootRequest),
|
BootRequest(BootRequest),
|
||||||
BootResponse(BootResponse),
|
BootResponse(BootResponse),
|
||||||
@@ -53,8 +68,8 @@ pub enum InternalEventPayload {
|
|||||||
|
|
||||||
CopyTextRequest(CopyTextRequest),
|
CopyTextRequest(CopyTextRequest),
|
||||||
|
|
||||||
RenderHttpRequestRequest(RenderHttpRequestRequest),
|
TemplateRenderRequest(TemplateRenderRequest),
|
||||||
RenderHttpRequestResponse(RenderHttpRequestResponse),
|
TemplateRenderResponse(TemplateRenderResponse),
|
||||||
|
|
||||||
ShowToastRequest(ShowToastRequest),
|
ShowToastRequest(ShowToastRequest),
|
||||||
|
|
||||||
@@ -71,7 +86,7 @@ pub enum InternalEventPayload {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct BootRequest {
|
pub struct BootRequest {
|
||||||
pub dir: String,
|
pub dir: String,
|
||||||
pub watch: bool,
|
pub watch: bool,
|
||||||
@@ -79,7 +94,7 @@ pub struct BootRequest {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct BootResponse {
|
pub struct BootResponse {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub version: String,
|
pub version: String,
|
||||||
@@ -88,21 +103,21 @@ pub struct BootResponse {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct ImportRequest {
|
pub struct ImportRequest {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct ImportResponse {
|
pub struct ImportResponse {
|
||||||
pub resources: ImportResources,
|
pub resources: ImportResources,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct FilterRequest {
|
pub struct FilterRequest {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
pub filter: String,
|
pub filter: String,
|
||||||
@@ -110,49 +125,49 @@ pub struct FilterRequest {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct FilterResponse {
|
pub struct FilterResponse {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct ExportHttpRequestRequest {
|
pub struct ExportHttpRequestRequest {
|
||||||
pub http_request: HttpRequest,
|
pub http_request: HttpRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct ExportHttpRequestResponse {
|
pub struct ExportHttpRequestResponse {
|
||||||
pub content: String,
|
pub content: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct SendHttpRequestRequest {
|
pub struct SendHttpRequestRequest {
|
||||||
pub http_request: HttpRequest,
|
pub http_request: HttpRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct SendHttpRequestResponse {
|
pub struct SendHttpRequestResponse {
|
||||||
pub http_response: HttpResponse,
|
pub http_response: HttpResponse,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct CopyTextRequest {
|
pub struct CopyTextRequest {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct RenderHttpRequestRequest {
|
pub struct RenderHttpRequestRequest {
|
||||||
pub http_request: HttpRequest,
|
pub http_request: HttpRequest,
|
||||||
pub purpose: RenderPurpose,
|
pub purpose: RenderPurpose,
|
||||||
@@ -160,14 +175,29 @@ pub struct RenderHttpRequestRequest {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct RenderHttpRequestResponse {
|
pub struct RenderHttpRequestResponse {
|
||||||
pub http_request: HttpRequest,
|
pub http_request: HttpRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
|
pub struct TemplateRenderRequest {
|
||||||
|
pub data: serde_json::Value,
|
||||||
|
pub purpose: RenderPurpose,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export, export_to = "events.ts")]
|
||||||
|
pub struct TemplateRenderResponse {
|
||||||
|
pub data: serde_json::Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct ShowToastRequest {
|
pub struct ShowToastRequest {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
#[ts(optional = nullable)]
|
#[ts(optional = nullable)]
|
||||||
@@ -178,7 +208,7 @@ pub struct ShowToastRequest {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub enum Color {
|
pub enum Color {
|
||||||
Custom,
|
Custom,
|
||||||
Default,
|
Default,
|
||||||
@@ -199,7 +229,7 @@ impl Default for Color {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub enum Icon {
|
pub enum Icon {
|
||||||
Copy,
|
Copy,
|
||||||
Info,
|
Info,
|
||||||
@@ -209,7 +239,7 @@ pub enum Icon {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct GetTemplateFunctionsResponse {
|
pub struct GetTemplateFunctionsResponse {
|
||||||
pub functions: Vec<TemplateFunction>,
|
pub functions: Vec<TemplateFunction>,
|
||||||
pub plugin_ref_id: String,
|
pub plugin_ref_id: String,
|
||||||
@@ -217,7 +247,7 @@ pub struct GetTemplateFunctionsResponse {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct TemplateFunction {
|
pub struct TemplateFunction {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub args: Vec<TemplateFunctionArg>,
|
pub args: Vec<TemplateFunctionArg>,
|
||||||
@@ -225,7 +255,7 @@ pub struct TemplateFunction {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
#[serde(rename_all = "snake_case", tag = "type")]
|
#[serde(rename_all = "snake_case", tag = "type")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub enum TemplateFunctionArg {
|
pub enum TemplateFunctionArg {
|
||||||
Text(TemplateFunctionTextArg),
|
Text(TemplateFunctionTextArg),
|
||||||
Select(TemplateFunctionSelectArg),
|
Select(TemplateFunctionSelectArg),
|
||||||
@@ -235,7 +265,7 @@ pub enum TemplateFunctionArg {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct TemplateFunctionBaseArg {
|
pub struct TemplateFunctionBaseArg {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
#[ts(optional = nullable)]
|
#[ts(optional = nullable)]
|
||||||
@@ -248,7 +278,7 @@ pub struct TemplateFunctionBaseArg {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct TemplateFunctionTextArg {
|
pub struct TemplateFunctionTextArg {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: TemplateFunctionBaseArg,
|
pub base: TemplateFunctionBaseArg,
|
||||||
@@ -258,7 +288,7 @@ pub struct TemplateFunctionTextArg {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct TemplateFunctionHttpRequestArg {
|
pub struct TemplateFunctionHttpRequestArg {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: TemplateFunctionBaseArg,
|
pub base: TemplateFunctionBaseArg,
|
||||||
@@ -266,7 +296,7 @@ pub struct TemplateFunctionHttpRequestArg {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct TemplateFunctionSelectArg {
|
pub struct TemplateFunctionSelectArg {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: TemplateFunctionBaseArg,
|
pub base: TemplateFunctionBaseArg,
|
||||||
@@ -275,7 +305,7 @@ pub struct TemplateFunctionSelectArg {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct TemplateFunctionCheckboxArg {
|
pub struct TemplateFunctionCheckboxArg {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: TemplateFunctionBaseArg,
|
pub base: TemplateFunctionBaseArg,
|
||||||
@@ -283,7 +313,7 @@ pub struct TemplateFunctionCheckboxArg {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct TemplateFunctionSelectOption {
|
pub struct TemplateFunctionSelectOption {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub value: String,
|
pub value: String,
|
||||||
@@ -291,7 +321,7 @@ pub struct TemplateFunctionSelectOption {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct CallTemplateFunctionRequest {
|
pub struct CallTemplateFunctionRequest {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub args: CallTemplateFunctionArgs,
|
pub args: CallTemplateFunctionArgs,
|
||||||
@@ -299,14 +329,14 @@ pub struct CallTemplateFunctionRequest {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct CallTemplateFunctionResponse {
|
pub struct CallTemplateFunctionResponse {
|
||||||
pub value: Option<String>,
|
pub value: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct CallTemplateFunctionArgs {
|
pub struct CallTemplateFunctionArgs {
|
||||||
pub purpose: RenderPurpose,
|
pub purpose: RenderPurpose,
|
||||||
pub values: HashMap<String, String>,
|
pub values: HashMap<String, String>,
|
||||||
@@ -314,7 +344,7 @@ pub struct CallTemplateFunctionArgs {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub enum RenderPurpose {
|
pub enum RenderPurpose {
|
||||||
Send,
|
Send,
|
||||||
Preview,
|
Preview,
|
||||||
@@ -328,12 +358,12 @@ impl Default for RenderPurpose {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct GetHttpRequestActionsRequest {}
|
pub struct GetHttpRequestActionsRequest {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct GetHttpRequestActionsResponse {
|
pub struct GetHttpRequestActionsResponse {
|
||||||
pub actions: Vec<HttpRequestAction>,
|
pub actions: Vec<HttpRequestAction>,
|
||||||
pub plugin_ref_id: String,
|
pub plugin_ref_id: String,
|
||||||
@@ -341,7 +371,7 @@ pub struct GetHttpRequestActionsResponse {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct HttpRequestAction {
|
pub struct HttpRequestAction {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
pub label: String,
|
pub label: String,
|
||||||
@@ -350,7 +380,7 @@ pub struct HttpRequestAction {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct CallHttpRequestActionRequest {
|
pub struct CallHttpRequestActionRequest {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
pub plugin_ref_id: String,
|
pub plugin_ref_id: String,
|
||||||
@@ -359,28 +389,28 @@ pub struct CallHttpRequestActionRequest {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct CallHttpRequestActionArgs {
|
pub struct CallHttpRequestActionArgs {
|
||||||
pub http_request: HttpRequest,
|
pub http_request: HttpRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct GetHttpRequestByIdRequest {
|
pub struct GetHttpRequestByIdRequest {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct GetHttpRequestByIdResponse {
|
pub struct GetHttpRequestByIdResponse {
|
||||||
pub http_request: Option<HttpRequest>,
|
pub http_request: Option<HttpRequest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct FindHttpResponsesRequest {
|
pub struct FindHttpResponsesRequest {
|
||||||
pub request_id: String,
|
pub request_id: String,
|
||||||
pub limit: Option<i32>,
|
pub limit: Option<i32>,
|
||||||
@@ -388,14 +418,14 @@ pub struct FindHttpResponsesRequest {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct FindHttpResponsesResponse {
|
pub struct FindHttpResponsesResponse {
|
||||||
pub http_responses: Vec<HttpResponse>,
|
pub http_responses: Vec<HttpResponse>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
#[serde(default, rename_all = "camelCase")]
|
#[serde(default, rename_all = "camelCase")]
|
||||||
#[ts(export, export_to="events.ts")]
|
#[ts(export, export_to = "events.ts")]
|
||||||
pub struct ImportResources {
|
pub struct ImportResources {
|
||||||
pub workspaces: Vec<Workspace>,
|
pub workspaces: Vec<Workspace>,
|
||||||
pub environments: Vec<Environment>,
|
pub environments: Vec<Environment>,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::events::{
|
|||||||
CallTemplateFunctionRequest, CallTemplateFunctionResponse, FilterRequest, FilterResponse,
|
CallTemplateFunctionRequest, CallTemplateFunctionResponse, FilterRequest, FilterResponse,
|
||||||
GetHttpRequestActionsRequest, GetHttpRequestActionsResponse, GetTemplateFunctionsResponse,
|
GetHttpRequestActionsRequest, GetHttpRequestActionsResponse, GetTemplateFunctionsResponse,
|
||||||
ImportRequest, ImportResponse, InternalEvent, InternalEventPayload, RenderPurpose,
|
ImportRequest, ImportResponse, InternalEvent, InternalEventPayload, RenderPurpose,
|
||||||
|
WindowContext,
|
||||||
};
|
};
|
||||||
use crate::nodejs::start_nodejs_plugin_runtime;
|
use crate::nodejs::start_nodejs_plugin_runtime;
|
||||||
use crate::plugin_handle::PluginHandle;
|
use crate::plugin_handle::PluginHandle;
|
||||||
@@ -17,7 +18,7 @@ use std::path::PathBuf;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tauri::path::BaseDirectory;
|
use tauri::path::BaseDirectory;
|
||||||
use tauri::{AppHandle, Manager, Runtime};
|
use tauri::{AppHandle, Manager, Runtime, WebviewWindow};
|
||||||
use tokio::fs::read_dir;
|
use tokio::fs::read_dir;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
use tokio::sync::{mpsc, Mutex};
|
use tokio::sync::{mpsc, Mutex};
|
||||||
@@ -98,7 +99,7 @@ impl PluginManager {
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
info!("Plugin runtime client connected!");
|
info!("Plugin runtime client connected!");
|
||||||
plugin_manager
|
plugin_manager
|
||||||
.initialize_all_plugins(&app_handle)
|
.initialize_all_plugins(&app_handle, WindowContext::None)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to reload plugins");
|
.expect("Failed to reload plugins");
|
||||||
}
|
}
|
||||||
@@ -171,17 +172,21 @@ impl PluginManager {
|
|||||||
[bundled_plugin_dirs, installed_plugin_dirs].concat()
|
[bundled_plugin_dirs, installed_plugin_dirs].concat()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn uninstall(&self, dir: &str) -> Result<()> {
|
pub async fn uninstall(&self, window_context: WindowContext, dir: &str) -> Result<()> {
|
||||||
let plugin = self
|
let plugin = self
|
||||||
.get_plugin_by_dir(dir)
|
.get_plugin_by_dir(dir)
|
||||||
.await
|
.await
|
||||||
.ok_or(PluginNotFoundErr(dir.to_string()))?;
|
.ok_or(PluginNotFoundErr(dir.to_string()))?;
|
||||||
self.remove_plugin(&plugin).await
|
self.remove_plugin(window_context, &plugin).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_plugin(&self, plugin: &PluginHandle) -> Result<()> {
|
async fn remove_plugin(
|
||||||
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
|
plugin: &PluginHandle,
|
||||||
|
) -> Result<()> {
|
||||||
// Terminate the plugin
|
// Terminate the plugin
|
||||||
plugin.terminate().await?;
|
plugin.terminate(window_context).await?;
|
||||||
|
|
||||||
// Remove the plugin from the list
|
// Remove the plugin from the list
|
||||||
let mut plugins = self.plugins.lock().await;
|
let mut plugins = self.plugins.lock().await;
|
||||||
@@ -193,7 +198,12 @@ impl PluginManager {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_plugin_by_dir(&self, dir: &str, watch: bool) -> Result<()> {
|
pub async fn add_plugin_by_dir(
|
||||||
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
|
dir: &str,
|
||||||
|
watch: bool,
|
||||||
|
) -> Result<()> {
|
||||||
info!("Adding plugin by dir {dir}");
|
info!("Adding plugin by dir {dir}");
|
||||||
let maybe_tx = self.server.app_to_plugin_events_tx.lock().await;
|
let maybe_tx = self.server.app_to_plugin_events_tx.lock().await;
|
||||||
let tx = match &*maybe_tx {
|
let tx = match &*maybe_tx {
|
||||||
@@ -202,9 +212,13 @@ impl PluginManager {
|
|||||||
};
|
};
|
||||||
let plugin_handle = PluginHandle::new(dir, tx.clone());
|
let plugin_handle = PluginHandle::new(dir, tx.clone());
|
||||||
|
|
||||||
|
// Add the new plugin
|
||||||
|
self.plugins.lock().await.push(plugin_handle.clone());
|
||||||
|
|
||||||
// Boot the plugin
|
// Boot the plugin
|
||||||
let event = self
|
let event = self
|
||||||
.send_to_plugin_and_wait(
|
.send_to_plugin_and_wait(
|
||||||
|
window_context,
|
||||||
&plugin_handle,
|
&plugin_handle,
|
||||||
&InternalEventPayload::BootRequest(BootRequest {
|
&InternalEventPayload::BootRequest(BootRequest {
|
||||||
dir: dir.to_string(),
|
dir: dir.to_string(),
|
||||||
@@ -218,27 +232,29 @@ impl PluginManager {
|
|||||||
_ => return Err(UnknownEventErr),
|
_ => return Err(UnknownEventErr),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Set the boot response
|
||||||
plugin_handle.set_boot_response(&resp).await;
|
plugin_handle.set_boot_response(&resp).await;
|
||||||
|
|
||||||
// Add the new plugin after it boots
|
|
||||||
self.plugins.lock().await.push(plugin_handle.clone());
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn initialize_all_plugins<R: Runtime>(
|
pub async fn initialize_all_plugins<R: Runtime>(
|
||||||
&self,
|
&self,
|
||||||
app_handle: &AppHandle<R>,
|
app_handle: &AppHandle<R>,
|
||||||
|
window_context: WindowContext,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let dirs = self.list_plugin_dirs(app_handle).await;
|
let dirs = self.list_plugin_dirs(app_handle).await;
|
||||||
for d in dirs.clone() {
|
for d in dirs.clone() {
|
||||||
// First remove the plugin if it exists
|
// First remove the plugin if it exists
|
||||||
if let Some(plugin) = self.get_plugin_by_dir(d.dir.as_str()).await {
|
if let Some(plugin) = self.get_plugin_by_dir(d.dir.as_str()).await {
|
||||||
if let Err(e) = self.remove_plugin(&plugin).await {
|
if let Err(e) = self.remove_plugin(window_context.to_owned(), &plugin).await {
|
||||||
warn!("Failed to remove plugin {} {e:?}", d.dir);
|
warn!("Failed to remove plugin {} {e:?}", d.dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Err(e) = self.add_plugin_by_dir(d.dir.as_str(), d.watch).await {
|
if let Err(e) = self
|
||||||
|
.add_plugin_by_dir(window_context.to_owned(), d.dir.as_str(), d.watch)
|
||||||
|
.await
|
||||||
|
{
|
||||||
warn!("Failed to add plugin {} {e:?}", d.dir);
|
warn!("Failed to add plugin {} {e:?}", d.dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,12 +296,13 @@ impl PluginManager {
|
|||||||
source_event: &InternalEvent,
|
source_event: &InternalEvent,
|
||||||
payload: &InternalEventPayload,
|
payload: &InternalEventPayload,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let reply_id = Some(source_event.clone().id);
|
let window_label = source_event.to_owned().window_context;
|
||||||
|
let reply_id = Some(source_event.to_owned().id);
|
||||||
let plugin = self
|
let plugin = self
|
||||||
.get_plugin_by_ref_id(source_event.plugin_ref_id.as_str())
|
.get_plugin_by_ref_id(source_event.plugin_ref_id.as_str())
|
||||||
.await
|
.await
|
||||||
.ok_or(PluginNotFoundErr(source_event.plugin_ref_id.to_string()))?;
|
.ok_or(PluginNotFoundErr(source_event.plugin_ref_id.to_string()))?;
|
||||||
let event = plugin.build_event_to_send(&payload, reply_id);
|
let event = plugin.build_event_to_send_raw(window_label, &payload, reply_id);
|
||||||
plugin.send(&event).await
|
plugin.send(&event).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,22 +336,29 @@ impl PluginManager {
|
|||||||
|
|
||||||
async fn send_to_plugin_and_wait(
|
async fn send_to_plugin_and_wait(
|
||||||
&self,
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
plugin: &PluginHandle,
|
plugin: &PluginHandle,
|
||||||
payload: &InternalEventPayload,
|
payload: &InternalEventPayload,
|
||||||
) -> Result<InternalEvent> {
|
) -> Result<InternalEvent> {
|
||||||
let events = self
|
let events = self
|
||||||
.send_to_plugins_and_wait(payload, vec![plugin.to_owned()])
|
.send_to_plugins_and_wait(window_context, payload, vec![plugin.to_owned()])
|
||||||
.await?;
|
.await?;
|
||||||
Ok(events.first().unwrap().to_owned())
|
Ok(events.first().unwrap().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_and_wait(&self, payload: &InternalEventPayload) -> Result<Vec<InternalEvent>> {
|
async fn send_and_wait(
|
||||||
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
|
payload: &InternalEventPayload,
|
||||||
|
) -> Result<Vec<InternalEvent>> {
|
||||||
let plugins = { self.plugins.lock().await.clone() };
|
let plugins = { self.plugins.lock().await.clone() };
|
||||||
self.send_to_plugins_and_wait(payload, plugins).await
|
self.send_to_plugins_and_wait(window_context, payload, plugins)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_to_plugins_and_wait(
|
async fn send_to_plugins_and_wait(
|
||||||
&self,
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
payload: &InternalEventPayload,
|
payload: &InternalEventPayload,
|
||||||
plugins: Vec<PluginHandle>,
|
plugins: Vec<PluginHandle>,
|
||||||
) -> Result<Vec<InternalEvent>> {
|
) -> Result<Vec<InternalEvent>> {
|
||||||
@@ -343,7 +367,7 @@ impl PluginManager {
|
|||||||
// 1. Build the events with IDs and everything
|
// 1. Build the events with IDs and everything
|
||||||
let events_to_send = plugins
|
let events_to_send = plugins
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| p.build_event_to_send(payload, None))
|
.map(|p| p.build_event_to_send(window_context.to_owned(), payload, None))
|
||||||
.collect::<Vec<InternalEvent>>();
|
.collect::<Vec<InternalEvent>>();
|
||||||
|
|
||||||
// 2. Spawn thread to subscribe to incoming events and check reply ids
|
// 2. Spawn thread to subscribe to incoming events and check reply ids
|
||||||
@@ -388,11 +412,17 @@ impl PluginManager {
|
|||||||
Ok(events)
|
Ok(events)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_http_request_actions(&self) -> Result<Vec<GetHttpRequestActionsResponse>> {
|
pub async fn get_http_request_actions<R: Runtime>(
|
||||||
|
&self,
|
||||||
|
window: &WebviewWindow<R>,
|
||||||
|
) -> Result<Vec<GetHttpRequestActionsResponse>> {
|
||||||
let reply_events = self
|
let reply_events = self
|
||||||
.send_and_wait(&InternalEventPayload::GetHttpRequestActionsRequest(
|
.send_and_wait(
|
||||||
GetHttpRequestActionsRequest {},
|
WindowContext::from_window(window),
|
||||||
))
|
&InternalEventPayload::GetHttpRequestActionsRequest(
|
||||||
|
GetHttpRequestActionsRequest {},
|
||||||
|
),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut all_actions = Vec::new();
|
let mut all_actions = Vec::new();
|
||||||
@@ -405,9 +435,23 @@ impl PluginManager {
|
|||||||
Ok(all_actions)
|
Ok(all_actions)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_template_functions(&self) -> Result<Vec<GetTemplateFunctionsResponse>> {
|
pub async fn get_template_functions<R: Runtime>(
|
||||||
|
&self,
|
||||||
|
window: &WebviewWindow<R>,
|
||||||
|
) -> Result<Vec<GetTemplateFunctionsResponse>> {
|
||||||
|
self.get_template_functions_with_context(WindowContext::from_window(window))
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_template_functions_with_context(
|
||||||
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
|
) -> Result<Vec<GetTemplateFunctionsResponse>> {
|
||||||
let reply_events = self
|
let reply_events = self
|
||||||
.send_and_wait(&InternalEventPayload::GetTemplateFunctionsRequest)
|
.send_and_wait(
|
||||||
|
window_context,
|
||||||
|
&InternalEventPayload::GetTemplateFunctionsRequest,
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let mut all_actions = Vec::new();
|
let mut all_actions = Vec::new();
|
||||||
@@ -420,13 +464,18 @@ impl PluginManager {
|
|||||||
Ok(all_actions)
|
Ok(all_actions)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn call_http_request_action(&self, req: CallHttpRequestActionRequest) -> Result<()> {
|
pub async fn call_http_request_action<R: Runtime>(
|
||||||
|
&self,
|
||||||
|
window: &WebviewWindow<R>,
|
||||||
|
req: CallHttpRequestActionRequest,
|
||||||
|
) -> Result<()> {
|
||||||
let ref_id = req.plugin_ref_id.clone();
|
let ref_id = req.plugin_ref_id.clone();
|
||||||
let plugin = self
|
let plugin = self
|
||||||
.get_plugin_by_ref_id(ref_id.as_str())
|
.get_plugin_by_ref_id(ref_id.as_str())
|
||||||
.await
|
.await
|
||||||
.ok_or(PluginNotFoundErr(ref_id))?;
|
.ok_or(PluginNotFoundErr(ref_id))?;
|
||||||
let event = plugin.build_event_to_send(
|
let event = plugin.build_event_to_send(
|
||||||
|
WindowContext::from_window(window),
|
||||||
&InternalEventPayload::CallHttpRequestActionRequest(req),
|
&InternalEventPayload::CallHttpRequestActionRequest(req),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
@@ -436,6 +485,7 @@ impl PluginManager {
|
|||||||
|
|
||||||
pub async fn call_template_function(
|
pub async fn call_template_function(
|
||||||
&self,
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
fn_name: &str,
|
fn_name: &str,
|
||||||
args: HashMap<String, String>,
|
args: HashMap<String, String>,
|
||||||
purpose: RenderPurpose,
|
purpose: RenderPurpose,
|
||||||
@@ -449,7 +499,10 @@ impl PluginManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let events = self
|
let events = self
|
||||||
.send_and_wait(&InternalEventPayload::CallTemplateFunctionRequest(req))
|
.send_and_wait(
|
||||||
|
window_context,
|
||||||
|
&InternalEventPayload::CallTemplateFunctionRequest(req),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let value = events.into_iter().find_map(|e| match e.payload {
|
let value = events.into_iter().find_map(|e| match e.payload {
|
||||||
@@ -462,11 +515,18 @@ impl PluginManager {
|
|||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn import_data(&self, content: &str) -> Result<(ImportResponse, String)> {
|
pub async fn import_data<R: Runtime>(
|
||||||
|
&self,
|
||||||
|
window: &WebviewWindow<R>,
|
||||||
|
content: &str,
|
||||||
|
) -> Result<(ImportResponse, String)> {
|
||||||
let reply_events = self
|
let reply_events = self
|
||||||
.send_and_wait(&InternalEventPayload::ImportRequest(ImportRequest {
|
.send_and_wait(
|
||||||
content: content.to_string(),
|
WindowContext::from_window(window),
|
||||||
}))
|
&InternalEventPayload::ImportRequest(ImportRequest {
|
||||||
|
content: content.to_string(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// TODO: Don't just return the first valid response
|
// TODO: Don't just return the first valid response
|
||||||
@@ -489,8 +549,9 @@ impl PluginManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn filter_data(
|
pub async fn filter_data<R: Runtime>(
|
||||||
&self,
|
&self,
|
||||||
|
window: &WebviewWindow<R>,
|
||||||
filter: &str,
|
filter: &str,
|
||||||
content: &str,
|
content: &str,
|
||||||
content_type: &str,
|
content_type: &str,
|
||||||
@@ -508,6 +569,7 @@ impl PluginManager {
|
|||||||
|
|
||||||
let event = self
|
let event = self
|
||||||
.send_to_plugin_and_wait(
|
.send_to_plugin_and_wait(
|
||||||
|
WindowContext::from_window(window),
|
||||||
&plugin,
|
&plugin,
|
||||||
&InternalEventPayload::FilterRequest(FilterRequest {
|
&InternalEventPayload::FilterRequest(FilterRequest {
|
||||||
filter: filter.to_string(),
|
filter: filter.to_string(),
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
|||||||
_ => {}
|
_ => {}
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::events::{BootResponse, InternalEvent, InternalEventPayload};
|
use crate::events::{BootResponse, InternalEvent, InternalEventPayload, WindowContext};
|
||||||
use crate::server::plugin_runtime::EventStreamEvent;
|
use crate::server::plugin_runtime::EventStreamEvent;
|
||||||
use crate::util::gen_id;
|
use crate::util::gen_id;
|
||||||
use std::sync::Arc;
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use std::sync::Arc;
|
||||||
use tokio::sync::{mpsc, Mutex};
|
use tokio::sync::{mpsc, Mutex};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -33,6 +33,16 @@ impl PluginHandle {
|
|||||||
|
|
||||||
pub fn build_event_to_send(
|
pub fn build_event_to_send(
|
||||||
&self,
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
|
payload: &InternalEventPayload,
|
||||||
|
reply_id: Option<String>,
|
||||||
|
) -> InternalEvent {
|
||||||
|
self.build_event_to_send_raw(window_context, payload, reply_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn build_event_to_send_raw(
|
||||||
|
&self,
|
||||||
|
window_context: WindowContext,
|
||||||
payload: &InternalEventPayload,
|
payload: &InternalEventPayload,
|
||||||
reply_id: Option<String>,
|
reply_id: Option<String>,
|
||||||
) -> InternalEvent {
|
) -> InternalEvent {
|
||||||
@@ -41,16 +51,21 @@ impl PluginHandle {
|
|||||||
plugin_ref_id: self.ref_id.clone(),
|
plugin_ref_id: self.ref_id.clone(),
|
||||||
reply_id,
|
reply_id,
|
||||||
payload: payload.clone(),
|
payload: payload.clone(),
|
||||||
|
window_context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn terminate(&self) -> Result<()> {
|
pub async fn terminate(&self, window_context: WindowContext) -> Result<()> {
|
||||||
info!("Terminating plugin {}", self.dir);
|
info!("Terminating plugin {}", self.dir);
|
||||||
let event = self.build_event_to_send(&InternalEventPayload::TerminateRequest, None);
|
let event = self.build_event_to_send(
|
||||||
|
window_context,
|
||||||
|
&InternalEventPayload::TerminateRequest,
|
||||||
|
None,
|
||||||
|
);
|
||||||
self.send(&event).await
|
self.send(&event).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send(&self, event: &InternalEvent) -> Result<()> {
|
pub(crate) async fn send(&self, event: &InternalEvent) -> Result<()> {
|
||||||
self.to_plugin_tx
|
self.to_plugin_tx
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
@@ -61,15 +76,6 @@ impl PluginHandle {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_payload(
|
|
||||||
&self,
|
|
||||||
payload: &InternalEventPayload,
|
|
||||||
reply_id: Option<String>,
|
|
||||||
) -> Result<()> {
|
|
||||||
let event = self.build_event_to_send(payload, reply_id);
|
|
||||||
self.send(&event).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn set_boot_response(&self, resp: &BootResponse) {
|
pub async fn set_boot_response(&self, resp: &BootResponse) {
|
||||||
let mut boot_resp = self.boot_resp.lock().await;
|
let mut boot_resp = self.boot_resp.lock().await;
|
||||||
*boot_resp = resp.clone();
|
*boot_resp = resp.clone();
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ async fn render_tag<T: TemplateCallback>(
|
|||||||
Some(v) => {
|
Some(v) => {
|
||||||
let r = Box::pin(parse_and_render(v, vars, cb)).await;
|
let r = Box::pin(parse_and_render(v, vars, cb)).await;
|
||||||
r.to_string()
|
r.to_string()
|
||||||
},
|
}
|
||||||
None => "".into(),
|
None => "".into(),
|
||||||
},
|
},
|
||||||
Val::Bool { value } => value.to_string(),
|
Val::Bool { value } => value.to_string(),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { EventCallback, EventName, Options } from '@tauri-apps/api/event';
|
import type { EventCallback, EventName } from '@tauri-apps/api/event';
|
||||||
import { listen } from '@tauri-apps/api/event';
|
import { listen } from '@tauri-apps/api/event';
|
||||||
|
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
|
||||||
import type { DependencyList } from 'react';
|
import type { DependencyList } from 'react';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
@@ -9,14 +10,18 @@ import { useEffect } from 'react';
|
|||||||
export function useListenToTauriEvent<T>(
|
export function useListenToTauriEvent<T>(
|
||||||
event: EventName,
|
event: EventName,
|
||||||
fn: EventCallback<T>,
|
fn: EventCallback<T>,
|
||||||
options: Options | undefined = undefined,
|
|
||||||
deps: DependencyList = [],
|
deps: DependencyList = [],
|
||||||
) {
|
) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let unMounted = false;
|
let unMounted = false;
|
||||||
let unsubFn: (() => void) | undefined = undefined;
|
let unsubFn: (() => void) | undefined = undefined;
|
||||||
|
|
||||||
listen(event, fn, options).then((unsub) => {
|
listen(
|
||||||
|
event,
|
||||||
|
fn,
|
||||||
|
// Listen to `emit_all()` events or events specific to the current window
|
||||||
|
{ target: { label: getCurrentWebviewWindow().label, kind: 'Window' } },
|
||||||
|
).then((unsub) => {
|
||||||
if (unMounted) unsub();
|
if (unMounted) unsub();
|
||||||
else unsubFn = unsub;
|
else unsubFn = unsub;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user