mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-07-05 12:31:47 +02:00
Request actions (#65)
This commit is contained in:
@@ -14,3 +14,8 @@ cargo sqlx migrate add ${MIGRATION_NAME}
|
|||||||
cargo sqlx migrate run --database-url 'sqlite://db.sqlite?mode=rw'
|
cargo sqlx migrate run --database-url 'sqlite://db.sqlite?mode=rw'
|
||||||
cargo sqlx prepare --database-url 'sqlite://db.sqlite'
|
cargo sqlx prepare --database-url 'sqlite://db.sqlite'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Add App->Plugin API
|
||||||
|
|
||||||
|
- Add event in `events.rs`
|
||||||
|
- Add handler to `index.worker.ts`
|
||||||
|
|||||||
Generated
+4
-4
@@ -27,7 +27,7 @@
|
|||||||
"@tauri-apps/plugin-log": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-log": "^2.0.0-rc.0",
|
||||||
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
|
||||||
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
|
||||||
"@yaakapp/api": "^0.1.4",
|
"@yaakapp/api": "^0.1.6",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"cm6-graphql": "^0.0.9",
|
"cm6-graphql": "^0.0.9",
|
||||||
@@ -2989,9 +2989,9 @@
|
|||||||
"integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ=="
|
"integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@yaakapp/api": {
|
"node_modules/@yaakapp/api": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.6.tgz",
|
||||||
"integrity": "sha512-dI5b2WPjTWXkaYBE/ltfxrJDIjIf/ETjMOzrfWDDcgT2GSBNlYmywZRTsk7j5cEbSQbSrDNgXYGJwG0I89aqSg==",
|
"integrity": "sha512-5lYXKcOVmLzVUrkfU4JOCbz+CBV5Dm/cALoZvfbelvZWOVu3sTrBxS9cbNVQQq2B6WwLInSevk7pMq58GqIj5Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "^22.0.0"
|
"@types/node": "^22.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@
|
|||||||
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
|
||||||
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
|
||||||
"@tauri-apps/plugin-log": "^2.0.0-rc.0",
|
"@tauri-apps/plugin-log": "^2.0.0-rc.0",
|
||||||
"@yaakapp/api": "^0.1.4",
|
"@yaakapp/api": "^0.1.6",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
"cm6-graphql": "^0.0.9",
|
"cm6-graphql": "^0.0.9",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@yaakapp/api",
|
"name": "@yaakapp/api",
|
||||||
"version": "0.1.4",
|
"version": "0.1.6",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"typings": "./lib/index.d.ts",
|
"typings": "./lib/index.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
import type { HttpRequest } from "./HttpRequest";
|
||||||
|
|
||||||
|
export type CallHttpRequestActionArgs = { httpRequest: HttpRequest, };
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
import type { CallHttpRequestActionArgs } from "./CallHttpRequestActionArgs";
|
||||||
|
|
||||||
|
export type CallHttpRequestActionRequest = { key: string, pluginRefId: string, args: CallHttpRequestActionArgs, };
|
||||||
@@ -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 CopyTextRequest = { text: string, };
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
import type { HttpRequestAction } from "./HttpRequestAction";
|
||||||
|
|
||||||
|
export type GetHttpRequestActionsResponse = { actions: Array<HttpRequestAction>, pluginRefId: 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 HttpRequestAction = { key: string, label: string, icon: string | null, };
|
||||||
@@ -1,16 +1,22 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
import type { BootRequest } from "./BootRequest";
|
import type { BootRequest } from "./BootRequest";
|
||||||
import type { BootResponse } from "./BootResponse";
|
import type { BootResponse } from "./BootResponse";
|
||||||
|
import type { CallHttpRequestActionRequest } from "./CallHttpRequestActionRequest";
|
||||||
|
import type { CopyTextRequest } from "./CopyTextRequest";
|
||||||
import type { EmptyResponse } from "./EmptyResponse";
|
import type { EmptyResponse } from "./EmptyResponse";
|
||||||
import type { ExportHttpRequestRequest } from "./ExportHttpRequestRequest";
|
import type { ExportHttpRequestRequest } from "./ExportHttpRequestRequest";
|
||||||
import type { ExportHttpRequestResponse } from "./ExportHttpRequestResponse";
|
import type { ExportHttpRequestResponse } from "./ExportHttpRequestResponse";
|
||||||
import type { FilterRequest } from "./FilterRequest";
|
import type { FilterRequest } from "./FilterRequest";
|
||||||
import type { FilterResponse } from "./FilterResponse";
|
import type { FilterResponse } from "./FilterResponse";
|
||||||
|
import type { GetHttpRequestActionsResponse } from "./GetHttpRequestActionsResponse";
|
||||||
import type { GetHttpRequestByIdRequest } from "./GetHttpRequestByIdRequest";
|
import type { GetHttpRequestByIdRequest } from "./GetHttpRequestByIdRequest";
|
||||||
import type { GetHttpRequestByIdResponse } from "./GetHttpRequestByIdResponse";
|
import type { GetHttpRequestByIdResponse } from "./GetHttpRequestByIdResponse";
|
||||||
import type { ImportRequest } from "./ImportRequest";
|
import type { ImportRequest } from "./ImportRequest";
|
||||||
import type { ImportResponse } from "./ImportResponse";
|
import type { ImportResponse } from "./ImportResponse";
|
||||||
|
import type { RenderHttpRequestRequest } from "./RenderHttpRequestRequest";
|
||||||
|
import type { RenderHttpRequestResponse } from "./RenderHttpRequestResponse";
|
||||||
import type { SendHttpRequestRequest } from "./SendHttpRequestRequest";
|
import type { SendHttpRequestRequest } from "./SendHttpRequestRequest";
|
||||||
import type { SendHttpRequestResponse } from "./SendHttpRequestResponse";
|
import type { SendHttpRequestResponse } from "./SendHttpRequestResponse";
|
||||||
|
import type { ShowToastRequest } from "./ShowToastRequest";
|
||||||
|
|
||||||
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "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_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "empty_response" } & EmptyResponse;
|
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "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" } | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "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": "empty_response" } & EmptyResponse;
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
import type { HttpRequest } from "./HttpRequest";
|
||||||
|
|
||||||
|
export type RenderHttpRequestRequest = { httpRequest: HttpRequest, };
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
import type { HttpRequest } from "./HttpRequest";
|
||||||
|
|
||||||
|
export type RenderHttpRequestResponse = { httpRequest: HttpRequest, };
|
||||||
@@ -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 RenderRequest = { template: 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 RenderResponse = { rendered: string, };
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||||
|
import type { ToastVariant } from "./ToastVariant";
|
||||||
|
|
||||||
|
export type ShowToastRequest = { message: string, variant: ToastVariant, };
|
||||||
@@ -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 ToastVariant = "custom" | "copied" | "success" | "info" | "warning" | "error";
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
export type * from './plugins';
|
export type * from './plugins';
|
||||||
export type * from './themes';
|
export type * from './themes';
|
||||||
|
|
||||||
|
// TODO: The next ts-rs release includes the ability to put everything in 1 file!
|
||||||
export * from './gen/BootRequest';
|
export * from './gen/BootRequest';
|
||||||
export * from './gen/BootResponse';
|
export * from './gen/BootResponse';
|
||||||
|
export * from './gen/CallHttpRequestActionRequest';
|
||||||
|
export * from './gen/CallHttpRequestActionArgs';
|
||||||
export * from './gen/Cookie';
|
export * from './gen/Cookie';
|
||||||
export * from './gen/CookieDomain';
|
export * from './gen/CookieDomain';
|
||||||
export * from './gen/CookieExpires';
|
export * from './gen/CookieExpires';
|
||||||
@@ -15,11 +18,16 @@ export * from './gen/ExportHttpRequestResponse';
|
|||||||
export * from './gen/FilterRequest';
|
export * from './gen/FilterRequest';
|
||||||
export * from './gen/FilterResponse';
|
export * from './gen/FilterResponse';
|
||||||
export * from './gen/Folder';
|
export * from './gen/Folder';
|
||||||
|
export * from './gen/GetHttpRequestActionsResponse';
|
||||||
|
export * from './gen/GetHttpRequestByIdRequest';
|
||||||
|
export * from './gen/CopyTextRequest';
|
||||||
|
export * from './gen/GetHttpRequestByIdResponse';
|
||||||
export * from './gen/GrpcConnection';
|
export * from './gen/GrpcConnection';
|
||||||
export * from './gen/GrpcEvent';
|
export * from './gen/GrpcEvent';
|
||||||
export * from './gen/GrpcMetadataEntry';
|
export * from './gen/GrpcMetadataEntry';
|
||||||
export * from './gen/GrpcRequest';
|
export * from './gen/GrpcRequest';
|
||||||
export * from './gen/HttpRequest';
|
export * from './gen/HttpRequest';
|
||||||
|
export * from './gen/HttpRequestAction';
|
||||||
export * from './gen/HttpRequestHeader';
|
export * from './gen/HttpRequestHeader';
|
||||||
export * from './gen/HttpResponse';
|
export * from './gen/HttpResponse';
|
||||||
export * from './gen/HttpResponseHeader';
|
export * from './gen/HttpResponseHeader';
|
||||||
@@ -32,9 +40,11 @@ export * from './gen/InternalEventPayload';
|
|||||||
export * from './gen/KeyValue';
|
export * from './gen/KeyValue';
|
||||||
export * from './gen/Model';
|
export * from './gen/Model';
|
||||||
export * from './gen/SendHttpRequestRequest';
|
export * from './gen/SendHttpRequestRequest';
|
||||||
|
export * from './gen/ToastVariant';
|
||||||
|
export * from './gen/ShowToastRequest';
|
||||||
|
export * from './gen/RenderHttpRequestRequest';
|
||||||
|
export * from './gen/RenderHttpRequestResponse';
|
||||||
export * from './gen/SendHttpRequestResponse';
|
export * from './gen/SendHttpRequestResponse';
|
||||||
export * from './gen/GetHttpRequestByIdRequest';
|
|
||||||
export * from './gen/GetHttpRequestByIdResponse';
|
|
||||||
export * from './gen/SendHttpRequestResponse';
|
export * from './gen/SendHttpRequestResponse';
|
||||||
export * from './gen/Settings';
|
export * from './gen/Settings';
|
||||||
export * from './gen/Workspace';
|
export * from './gen/Workspace';
|
||||||
|
|||||||
@@ -1,11 +1,21 @@
|
|||||||
import { GetHttpRequestByIdRequest } from '../gen/GetHttpRequestByIdRequest';
|
import { GetHttpRequestByIdRequest } from '../gen/GetHttpRequestByIdRequest';
|
||||||
import { GetHttpRequestByIdResponse } from '../gen/GetHttpRequestByIdResponse';
|
import { GetHttpRequestByIdResponse } from '../gen/GetHttpRequestByIdResponse';
|
||||||
|
import { RenderHttpRequestRequest } from '../gen/RenderHttpRequestRequest';
|
||||||
|
import { RenderHttpRequestResponse } from '../gen/RenderHttpRequestResponse';
|
||||||
import { SendHttpRequestRequest } from '../gen/SendHttpRequestRequest';
|
import { SendHttpRequestRequest } from '../gen/SendHttpRequestRequest';
|
||||||
import { SendHttpRequestResponse } from '../gen/SendHttpRequestResponse';
|
import { SendHttpRequestResponse } from '../gen/SendHttpRequestResponse';
|
||||||
|
import { ShowToastRequest } from '../gen/ShowToastRequest';
|
||||||
|
|
||||||
export type YaakContext = {
|
export type YaakContext = {
|
||||||
|
clipboard: {
|
||||||
|
copyText(text: string): void;
|
||||||
|
};
|
||||||
|
toast: {
|
||||||
|
show(args: ShowToastRequest): void;
|
||||||
|
};
|
||||||
httpRequest: {
|
httpRequest: {
|
||||||
send(args: SendHttpRequestRequest): Promise<SendHttpRequestResponse['httpResponse']>;
|
send(args: SendHttpRequestRequest): Promise<SendHttpRequestResponse['httpResponse']>;
|
||||||
getById(args: GetHttpRequestByIdRequest): Promise<GetHttpRequestByIdResponse['httpRequest']>;
|
getById(args: GetHttpRequestByIdRequest): Promise<GetHttpRequestByIdResponse['httpRequest']>;
|
||||||
|
render(args: RenderHttpRequestRequest): Promise<RenderHttpRequestResponse['httpRequest']>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { HttpRequest } from '../gen/HttpRequest';
|
import { CallHttpRequestActionArgs } from '../gen/CallHttpRequestActionArgs';
|
||||||
|
import { HttpRequestAction } from '../gen/HttpRequestAction';
|
||||||
import { YaakContext } from './context';
|
import { YaakContext } from './context';
|
||||||
|
|
||||||
export type HttpRequestActionPlugin = {
|
export type HttpRequestActionPlugin = HttpRequestAction & {
|
||||||
key: string;
|
onSelect(ctx: YaakContext, args: CallHttpRequestActionArgs): Promise<void> | void;
|
||||||
label: string;
|
|
||||||
onSelect(ctx: YaakContext, args: { httpRequest: HttpRequest }): void;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import { OneOrMany } from '../helpers';
|
|
||||||
import { FilterPlugin } from './filter';
|
import { FilterPlugin } from './filter';
|
||||||
import { HttpRequestActionPlugin } from './httpRequestAction';
|
import { HttpRequestActionPlugin } from './httpRequestAction';
|
||||||
import { ImporterPlugin } from './import';
|
import { ImporterPlugin } from './import';
|
||||||
import { ThemePlugin } from './theme';
|
import { ThemePlugin } from './theme';
|
||||||
|
|
||||||
export { YaakContext } from './context';
|
export { YaakContext } from './context';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The global structure of a Yaak plugin
|
* The global structure of a Yaak plugin
|
||||||
*/
|
*/
|
||||||
export type YaakPlugin = {
|
export type YaakPlugin = {
|
||||||
importer?: OneOrMany<ImporterPlugin>;
|
importer?: ImporterPlugin;
|
||||||
theme?: OneOrMany<ThemePlugin>;
|
theme?: ThemePlugin;
|
||||||
filter?: OneOrMany<FilterPlugin>;
|
filter?: FilterPlugin;
|
||||||
httpRequestAction?: OneOrMany<HttpRequestActionPlugin>;
|
httpRequestActions?: HttpRequestActionPlugin[];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import {
|
import {
|
||||||
GetHttpRequestByIdResponse,
|
GetHttpRequestByIdResponse,
|
||||||
|
HttpRequestAction,
|
||||||
ImportResponse,
|
ImportResponse,
|
||||||
InternalEvent,
|
InternalEvent,
|
||||||
InternalEventPayload,
|
InternalEventPayload,
|
||||||
|
RenderHttpRequestResponse,
|
||||||
SendHttpRequestResponse,
|
SendHttpRequestResponse,
|
||||||
} from '@yaakapp/api';
|
} from '@yaakapp/api';
|
||||||
import { YaakContext } from '@yaakapp/api/lib/plugins/context';
|
import { YaakContext } from '@yaakapp/api/lib/plugins/context';
|
||||||
|
import { HttpRequestActionPlugin } from '@yaakapp/api/lib/plugins/httpRequestAction';
|
||||||
import interceptStdout from 'intercept-stdout';
|
import interceptStdout from 'intercept-stdout';
|
||||||
import * as console from 'node:console';
|
import * as console from 'node:console';
|
||||||
import { readFileSync } from 'node:fs';
|
import { readFileSync } from 'node:fs';
|
||||||
@@ -47,6 +50,10 @@ new Promise<void>(async (resolve, reject) => {
|
|||||||
return { pluginRefId, id: genId(), replyId, payload };
|
return { pluginRefId, id: genId(), replyId, payload };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendEmpty(replyId: string | null = null): string {
|
||||||
|
return sendPayload({ type: 'empty_response' }, replyId);
|
||||||
|
}
|
||||||
|
|
||||||
function sendPayload(payload: InternalEventPayload, replyId: string | null = null): string {
|
function sendPayload(payload: InternalEventPayload, replyId: string | null = null): string {
|
||||||
const event = buildEventToSend(payload, replyId);
|
const event = buildEventToSend(payload, replyId);
|
||||||
sendEvent(event);
|
sendEvent(event);
|
||||||
@@ -82,6 +89,16 @@ new Promise<void>(async (resolve, reject) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ctx: YaakContext = {
|
const ctx: YaakContext = {
|
||||||
|
clipboard: {
|
||||||
|
async copyText(text) {
|
||||||
|
await sendAndWaitForReply({ type: 'copy_text_request', text });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
toast: {
|
||||||
|
async show(args) {
|
||||||
|
await sendAndWaitForReply({ type: 'show_toast_request', ...args });
|
||||||
|
},
|
||||||
|
},
|
||||||
httpRequest: {
|
httpRequest: {
|
||||||
async getById({ id }) {
|
async getById({ id }) {
|
||||||
const payload = { type: 'get_http_request_by_id_request', id } as const;
|
const payload = { type: 'get_http_request_by_id_request', id } as const;
|
||||||
@@ -93,6 +110,11 @@ new Promise<void>(async (resolve, reject) => {
|
|||||||
const { httpResponse } = await sendAndWaitForReply<SendHttpRequestResponse>(payload);
|
const { httpResponse } = await sendAndWaitForReply<SendHttpRequestResponse>(payload);
|
||||||
return httpResponse;
|
return httpResponse;
|
||||||
},
|
},
|
||||||
|
async render({ httpRequest }) {
|
||||||
|
const payload = { type: 'render_http_request_request', httpRequest } as const;
|
||||||
|
const result = await sendAndWaitForReply<RenderHttpRequestResponse>(payload);
|
||||||
|
return result.httpRequest;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,13 +173,45 @@ new Promise<void>(async (resolve, reject) => {
|
|||||||
sendPayload(replyPayload, replyId);
|
sendPayload(replyPayload, replyId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
payload.type === 'get_http_request_actions_request' &&
|
||||||
|
Array.isArray(mod.plugin?.httpRequestActions)
|
||||||
|
) {
|
||||||
|
const reply: HttpRequestAction[] = mod.plugin.httpRequestActions.map(
|
||||||
|
(a: HttpRequestActionPlugin) => ({
|
||||||
|
...a,
|
||||||
|
onSelect: undefined,
|
||||||
|
// Add everything except onSelect
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const replyPayload: InternalEventPayload = {
|
||||||
|
type: 'get_http_request_actions_response',
|
||||||
|
pluginRefId,
|
||||||
|
actions: reply,
|
||||||
|
};
|
||||||
|
sendPayload(replyPayload, replyId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
payload.type === 'call_http_request_action_request' &&
|
||||||
|
Array.isArray(mod.plugin?.httpRequestActions)
|
||||||
|
) {
|
||||||
|
const action = mod.plugin.httpRequestActions.find((a) => a.key === payload.key);
|
||||||
|
if (typeof action?.onSelect === 'function') {
|
||||||
|
await action.onSelect(ctx, payload.args);
|
||||||
|
sendEmpty(replyId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Plugin call threw exception', payload.type, err);
|
console.log('Plugin call threw exception', payload.type, err);
|
||||||
// TODO: Return errors to server
|
// TODO: Return errors to server
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
sendPayload({ type: 'empty_response' }, replyId);
|
sendEmpty(replyId);
|
||||||
});
|
});
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
|
|||||||
+68
-28
@@ -21,6 +21,7 @@ use tauri::TitleBarStyle;
|
|||||||
use tauri::{AppHandle, Emitter, LogicalSize, RunEvent, State, WebviewUrl, WebviewWindow};
|
use tauri::{AppHandle, Emitter, LogicalSize, RunEvent, State, WebviewUrl, WebviewWindow};
|
||||||
use tauri::{Listener, Runtime};
|
use tauri::{Listener, Runtime};
|
||||||
use tauri::{Manager, WindowEvent};
|
use tauri::{Manager, WindowEvent};
|
||||||
|
use tauri_plugin_clipboard_manager::ClipboardExt;
|
||||||
use tauri_plugin_log::{fern, Target, TargetKind};
|
use tauri_plugin_log::{fern, Target, TargetKind};
|
||||||
use tauri_plugin_shell::ShellExt;
|
use tauri_plugin_shell::ShellExt;
|
||||||
use tokio::sync::{watch, Mutex};
|
use tokio::sync::{watch, Mutex};
|
||||||
@@ -55,7 +56,8 @@ use yaak_models::queries::{
|
|||||||
upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_workspace,
|
upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_workspace,
|
||||||
};
|
};
|
||||||
use yaak_plugin_runtime::events::{
|
use yaak_plugin_runtime::events::{
|
||||||
FilterResponse, GetHttpRequestByIdResponse, InternalEvent, InternalEventPayload,
|
CallHttpRequestActionRequest, FilterResponse, GetHttpRequestActionsResponse,
|
||||||
|
GetHttpRequestByIdResponse, InternalEvent, InternalEventPayload, RenderHttpRequestResponse,
|
||||||
SendHttpRequestResponse,
|
SendHttpRequestResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -870,29 +872,24 @@ async fn cmd_import_data(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_request_to_curl(
|
async fn cmd_http_request_actions(
|
||||||
app: AppHandle,
|
|
||||||
request_id: &str,
|
|
||||||
plugin_manager: State<'_, PluginManager>,
|
plugin_manager: State<'_, PluginManager>,
|
||||||
environment_id: Option<&str>,
|
) -> Result<Vec<GetHttpRequestActionsResponse>, String> {
|
||||||
) -> Result<String, String> {
|
plugin_manager
|
||||||
let request = get_http_request(&app, request_id)
|
.run_http_request_actions()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())
|
||||||
let environment = match environment_id {
|
}
|
||||||
Some(id) => Some(get_environment(&app, id).await.map_err(|e| e.to_string())?),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
let workspace = get_workspace(&app, &request.workspace_id)
|
|
||||||
.await
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
let rendered = render_request(&request, &workspace, environment.as_ref());
|
|
||||||
|
|
||||||
let import_response = plugin_manager
|
#[tauri::command]
|
||||||
.run_export_curl(&rendered)
|
async fn cmd_call_http_request_action(
|
||||||
|
req: CallHttpRequestActionRequest,
|
||||||
|
plugin_manager: State<'_, PluginManager>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
plugin_manager
|
||||||
|
.call_http_request_action(req)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())
|
||||||
Ok(import_response.content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -1624,6 +1621,7 @@ pub fn run() {
|
|||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
cmd_call_http_request_action,
|
||||||
cmd_check_for_updates,
|
cmd_check_for_updates,
|
||||||
cmd_create_cookie_jar,
|
cmd_create_cookie_jar,
|
||||||
cmd_create_environment,
|
cmd_create_environment,
|
||||||
@@ -1642,6 +1640,7 @@ pub fn run() {
|
|||||||
cmd_delete_http_request,
|
cmd_delete_http_request,
|
||||||
cmd_delete_http_response,
|
cmd_delete_http_response,
|
||||||
cmd_delete_workspace,
|
cmd_delete_workspace,
|
||||||
|
cmd_dismiss_notification,
|
||||||
cmd_duplicate_grpc_request,
|
cmd_duplicate_grpc_request,
|
||||||
cmd_duplicate_http_request,
|
cmd_duplicate_http_request,
|
||||||
cmd_export_data,
|
cmd_export_data,
|
||||||
@@ -1656,6 +1655,7 @@ pub fn run() {
|
|||||||
cmd_get_workspace,
|
cmd_get_workspace,
|
||||||
cmd_grpc_go,
|
cmd_grpc_go,
|
||||||
cmd_grpc_reflect,
|
cmd_grpc_reflect,
|
||||||
|
cmd_http_request_actions,
|
||||||
cmd_import_data,
|
cmd_import_data,
|
||||||
cmd_list_cookie_jars,
|
cmd_list_cookie_jars,
|
||||||
cmd_list_environments,
|
cmd_list_environments,
|
||||||
@@ -1669,8 +1669,6 @@ pub fn run() {
|
|||||||
cmd_metadata,
|
cmd_metadata,
|
||||||
cmd_new_nested_window,
|
cmd_new_nested_window,
|
||||||
cmd_new_window,
|
cmd_new_window,
|
||||||
cmd_request_to_curl,
|
|
||||||
cmd_dismiss_notification,
|
|
||||||
cmd_save_response,
|
cmd_save_response,
|
||||||
cmd_send_ephemeral_request,
|
cmd_send_ephemeral_request,
|
||||||
cmd_send_http_request,
|
cmd_send_http_request,
|
||||||
@@ -1915,9 +1913,49 @@ async fn handle_plugin_event<R: Runtime>(
|
|||||||
let event = match event.clone().payload {
|
let event = match event.clone().payload {
|
||||||
InternalEventPayload::GetHttpRequestByIdRequest(req) => {
|
InternalEventPayload::GetHttpRequestByIdRequest(req) => {
|
||||||
let http_request = get_http_request(app_handle, req.id.as_str()).await.ok();
|
let http_request = get_http_request(app_handle, req.id.as_str()).await.ok();
|
||||||
InternalEventPayload::GetHttpRequestByIdResponse(GetHttpRequestByIdResponse {
|
Some(InternalEventPayload::GetHttpRequestByIdResponse(
|
||||||
http_request,
|
GetHttpRequestByIdResponse { http_request },
|
||||||
})
|
))
|
||||||
|
}
|
||||||
|
InternalEventPayload::CopyTextRequest(req) => {
|
||||||
|
app_handle
|
||||||
|
.clipboard()
|
||||||
|
.write_text(req.text.as_str())
|
||||||
|
.expect("Failed to write text to clipboard");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
InternalEventPayload::ShowToastRequest(req) => {
|
||||||
|
app_handle
|
||||||
|
.emit("show_toast", req)
|
||||||
|
.expect("Failed to emit show_toast");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
InternalEventPayload::RenderHttpRequestRequest(req) => {
|
||||||
|
let webview_windows = app_handle.get_focused_window()?.webview_windows();
|
||||||
|
let w = match webview_windows.iter().next() {
|
||||||
|
None => return None,
|
||||||
|
Some((_, w)) => w,
|
||||||
|
};
|
||||||
|
let workspace = get_workspace(app_handle, req.http_request.workspace_id.as_str())
|
||||||
|
.await
|
||||||
|
.expect("Failed to get workspace for request");
|
||||||
|
|
||||||
|
let url = w.url().unwrap();
|
||||||
|
let mut query_pairs = url.query_pairs();
|
||||||
|
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(w, id.as_str()).await.ok(),
|
||||||
|
};
|
||||||
|
let rendered_http_request =
|
||||||
|
render_request(&req.http_request, &workspace, environment.as_ref());
|
||||||
|
Some(InternalEventPayload::RenderHttpRequestResponse(
|
||||||
|
RenderHttpRequestResponse {
|
||||||
|
http_request: rendered_http_request,
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
InternalEventPayload::SendHttpRequestRequest(req) => {
|
InternalEventPayload::SendHttpRequestRequest(req) => {
|
||||||
let webview_windows = app_handle.get_focused_window()?.webview_windows();
|
let webview_windows = app_handle.get_focused_window()?.webview_windows();
|
||||||
@@ -1964,10 +2002,12 @@ async fn handle_plugin_event<R: Runtime>(
|
|||||||
Err(_e) => return None,
|
Err(_e) => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
InternalEventPayload::SendHttpRequestResponse(SendHttpRequestResponse { http_response })
|
Some(InternalEventPayload::SendHttpRequestResponse(
|
||||||
|
SendHttpRequestResponse { http_response },
|
||||||
|
))
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(event)
|
event
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,13 +32,24 @@ pub enum InternalEventPayload {
|
|||||||
|
|
||||||
ExportHttpRequestRequest(ExportHttpRequestRequest),
|
ExportHttpRequestRequest(ExportHttpRequestRequest),
|
||||||
ExportHttpRequestResponse(ExportHttpRequestResponse),
|
ExportHttpRequestResponse(ExportHttpRequestResponse),
|
||||||
|
|
||||||
SendHttpRequestRequest(SendHttpRequestRequest),
|
SendHttpRequestRequest(SendHttpRequestRequest),
|
||||||
SendHttpRequestResponse(SendHttpRequestResponse),
|
SendHttpRequestResponse(SendHttpRequestResponse),
|
||||||
|
|
||||||
|
GetHttpRequestActionsRequest,
|
||||||
|
GetHttpRequestActionsResponse(GetHttpRequestActionsResponse),
|
||||||
|
CallHttpRequestActionRequest(CallHttpRequestActionRequest),
|
||||||
|
|
||||||
|
CopyTextRequest(CopyTextRequest),
|
||||||
|
|
||||||
|
RenderHttpRequestRequest(RenderHttpRequestRequest),
|
||||||
|
RenderHttpRequestResponse(RenderHttpRequestResponse),
|
||||||
|
|
||||||
|
ShowToastRequest(ShowToastRequest),
|
||||||
|
|
||||||
GetHttpRequestByIdRequest(GetHttpRequestByIdRequest),
|
GetHttpRequestByIdRequest(GetHttpRequestByIdRequest),
|
||||||
GetHttpRequestByIdResponse(GetHttpRequestByIdResponse),
|
GetHttpRequestByIdResponse(GetHttpRequestByIdResponse),
|
||||||
|
|
||||||
/// Returned when a plugin doesn't get run, just so the server
|
/// Returned when a plugin doesn't get run, just so the server
|
||||||
/// has something to listen for
|
/// has something to listen for
|
||||||
EmptyResponse(EmptyResponse),
|
EmptyResponse(EmptyResponse),
|
||||||
@@ -122,6 +133,86 @@ pub struct SendHttpRequestResponse {
|
|||||||
pub http_response: HttpResponse,
|
pub http_response: HttpResponse,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub struct CopyTextRequest {
|
||||||
|
pub text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub struct RenderHttpRequestRequest {
|
||||||
|
pub http_request: HttpRequest,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub struct RenderHttpRequestResponse {
|
||||||
|
pub http_request: HttpRequest,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub struct ShowToastRequest {
|
||||||
|
pub message: String,
|
||||||
|
pub variant: ToastVariant,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub enum ToastVariant {
|
||||||
|
Custom,
|
||||||
|
Copied,
|
||||||
|
Success,
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ToastVariant {
|
||||||
|
fn default() -> Self {
|
||||||
|
ToastVariant::Info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub struct GetHttpRequestActionsResponse {
|
||||||
|
pub actions: Vec<HttpRequestAction>,
|
||||||
|
pub plugin_ref_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub struct HttpRequestAction {
|
||||||
|
pub key: String,
|
||||||
|
pub label: String,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub struct CallHttpRequestActionRequest {
|
||||||
|
pub key: String,
|
||||||
|
pub plugin_ref_id: String,
|
||||||
|
pub args: CallHttpRequestActionArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||||
|
#[serde(default, rename_all = "camelCase")]
|
||||||
|
#[ts(export)]
|
||||||
|
pub struct CallHttpRequestActionArgs {
|
||||||
|
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)]
|
#[ts(export)]
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::events::{
|
use crate::events::{CallHttpRequestActionRequest, FilterRequest, FilterResponse, GetHttpRequestActionsResponse, ImportRequest, ImportResponse, InternalEvent, InternalEventPayload};
|
||||||
ExportHttpRequestRequest, ExportHttpRequestResponse, FilterRequest, FilterResponse
|
|
||||||
, ImportRequest, ImportResponse, InternalEvent, InternalEventPayload,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::error::Error::PluginErr;
|
use crate::error::Error::PluginErr;
|
||||||
use crate::nodejs::start_nodejs_plugin_runtime;
|
use crate::nodejs::start_nodejs_plugin_runtime;
|
||||||
@@ -12,7 +9,6 @@ use std::time::Duration;
|
|||||||
use tauri::{AppHandle, Runtime};
|
use tauri::{AppHandle, Runtime};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::sync::watch::Sender;
|
use tokio::sync::watch::Sender;
|
||||||
use yaak_models::models::HttpRequest;
|
|
||||||
|
|
||||||
pub struct PluginManager {
|
pub struct PluginManager {
|
||||||
kill_tx: Sender<bool>,
|
kill_tx: Sender<bool>,
|
||||||
@@ -61,6 +57,29 @@ impl PluginManager {
|
|||||||
.send(&payload, source_event.plugin_ref_id.as_str(), reply_id)
|
.send(&payload, source_event.plugin_ref_id.as_str(), reply_id)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn run_http_request_actions(&self) -> Result<Vec<GetHttpRequestActionsResponse>> {
|
||||||
|
let reply_events = self
|
||||||
|
.server
|
||||||
|
.send_and_wait(&InternalEventPayload::GetHttpRequestActionsRequest)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut all_actions = Vec::new();
|
||||||
|
for event in reply_events {
|
||||||
|
if let InternalEventPayload::GetHttpRequestActionsResponse(resp) = event.payload {
|
||||||
|
all_actions.push(resp.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(all_actions)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn call_http_request_action(&self, req: CallHttpRequestActionRequest) -> Result<()> {
|
||||||
|
let plugin = self.server.plugin_by_ref_id(req.plugin_ref_id.as_str()).await?;
|
||||||
|
let event = plugin.build_event_to_send(&InternalEventPayload::CallHttpRequestActionRequest(req), None);
|
||||||
|
plugin.send(&event).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn run_import(&self, content: &str) -> Result<(ImportResponse, String)> {
|
pub async fn run_import(&self, content: &str) -> Result<(ImportResponse, String)> {
|
||||||
let reply_events = self
|
let reply_events = self
|
||||||
@@ -72,43 +91,17 @@ impl PluginManager {
|
|||||||
|
|
||||||
// TODO: Don't just return the first valid response
|
// TODO: Don't just return the first valid response
|
||||||
for event in reply_events {
|
for event in reply_events {
|
||||||
match event.payload {
|
if let InternalEventPayload::ImportResponse(resp) = event.payload {
|
||||||
InternalEventPayload::ImportResponse(resp) => {
|
let ref_id = event.plugin_ref_id.as_str();
|
||||||
let ref_id = event.plugin_ref_id.as_str();
|
let plugin = self.server.plugin_by_ref_id(ref_id).await?;
|
||||||
let plugin = self.server.plugin_by_ref_id(ref_id).await?;
|
let plugin_name = plugin.name().await;
|
||||||
let plugin_name = plugin.name().await;
|
return Ok((resp, plugin_name));
|
||||||
return Ok((resp, plugin_name));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(PluginErr("No import responses found".to_string()))
|
Err(PluginErr("No import responses found".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_export_curl(
|
|
||||||
&self,
|
|
||||||
request: &HttpRequest,
|
|
||||||
) -> Result<ExportHttpRequestResponse> {
|
|
||||||
let event = self
|
|
||||||
.server
|
|
||||||
.send_to_plugin_and_wait(
|
|
||||||
"exporter-curl",
|
|
||||||
&InternalEventPayload::ExportHttpRequestRequest(ExportHttpRequestRequest {
|
|
||||||
http_request: request.to_owned(),
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
match event.payload {
|
|
||||||
InternalEventPayload::ExportHttpRequestResponse(resp) => Ok(resp),
|
|
||||||
InternalEventPayload::EmptyResponse(_) => {
|
|
||||||
Err(PluginErr("Export returned empty".to_string()))
|
|
||||||
}
|
|
||||||
e => Err(PluginErr(format!("Export returned invalid event {:?}", e))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn run_filter(
|
pub async fn run_filter(
|
||||||
&self,
|
&self,
|
||||||
filter: &str,
|
filter: &str,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { useActiveEnvironment } from '../hooks/useActiveEnvironment';
|
|||||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||||
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
||||||
import { useAppRoutes } from '../hooks/useAppRoutes';
|
import { useAppRoutes } from '../hooks/useAppRoutes';
|
||||||
import { useCopyAsCurl } from '../hooks/useCopyAsCurl';
|
|
||||||
import { useCreateDropdownItems } from '../hooks/useCreateDropdownItems';
|
import { useCreateDropdownItems } from '../hooks/useCreateDropdownItems';
|
||||||
import { useDeleteFolder } from '../hooks/useDeleteFolder';
|
import { useDeleteFolder } from '../hooks/useDeleteFolder';
|
||||||
import { useDeleteRequest } from '../hooks/useDeleteRequest';
|
import { useDeleteRequest } from '../hooks/useDeleteRequest';
|
||||||
@@ -18,6 +17,7 @@ import { useDuplicateGrpcRequest } from '../hooks/useDuplicateGrpcRequest';
|
|||||||
import { useDuplicateHttpRequest } from '../hooks/useDuplicateHttpRequest';
|
import { useDuplicateHttpRequest } from '../hooks/useDuplicateHttpRequest';
|
||||||
import { useFolders } from '../hooks/useFolders';
|
import { useFolders } from '../hooks/useFolders';
|
||||||
import { useHotKey } from '../hooks/useHotKey';
|
import { useHotKey } from '../hooks/useHotKey';
|
||||||
|
import { useHttpRequestActions } from '../hooks/useHttpRequestActions';
|
||||||
import { useKeyValue } from '../hooks/useKeyValue';
|
import { useKeyValue } from '../hooks/useKeyValue';
|
||||||
import { useLatestGrpcConnection } from '../hooks/useLatestGrpcConnection';
|
import { useLatestGrpcConnection } from '../hooks/useLatestGrpcConnection';
|
||||||
import { useLatestHttpResponse } from '../hooks/useLatestHttpResponse';
|
import { useLatestHttpResponse } from '../hooks/useLatestHttpResponse';
|
||||||
@@ -34,6 +34,7 @@ import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest';
|
|||||||
import { useWorkspaces } from '../hooks/useWorkspaces';
|
import { useWorkspaces } from '../hooks/useWorkspaces';
|
||||||
import { fallbackRequestName } from '../lib/fallbackRequestName';
|
import { fallbackRequestName } from '../lib/fallbackRequestName';
|
||||||
import { isResponseLoading } from '../lib/models';
|
import { isResponseLoading } from '../lib/models';
|
||||||
|
import { getHttpRequest } from '../lib/store';
|
||||||
import type { DropdownItem } from './core/Dropdown';
|
import type { DropdownItem } from './core/Dropdown';
|
||||||
import { ContextMenu } from './core/Dropdown';
|
import { ContextMenu } from './core/Dropdown';
|
||||||
import { HttpMethodTag } from './core/HttpMethodTag';
|
import { HttpMethodTag } from './core/HttpMethodTag';
|
||||||
@@ -653,7 +654,7 @@ function SidebarItem({
|
|||||||
const renameRequest = useRenameRequest(itemId);
|
const renameRequest = useRenameRequest(itemId);
|
||||||
const duplicateHttpRequest = useDuplicateHttpRequest({ id: itemId, navigateAfter: true });
|
const duplicateHttpRequest = useDuplicateHttpRequest({ id: itemId, navigateAfter: true });
|
||||||
const duplicateGrpcRequest = useDuplicateGrpcRequest({ id: itemId, navigateAfter: true });
|
const duplicateGrpcRequest = useDuplicateGrpcRequest({ id: itemId, navigateAfter: true });
|
||||||
const copyAsCurl = useCopyAsCurl(itemId);
|
const httpRequestActions = useHttpRequestActions();
|
||||||
const sendRequest = useSendAnyHttpRequest();
|
const sendRequest = useSendAnyHttpRequest();
|
||||||
const moveToWorkspace = useMoveToWorkspace(itemId);
|
const moveToWorkspace = useMoveToWorkspace(itemId);
|
||||||
const sendManyRequests = useSendManyRequests();
|
const sendManyRequests = useSendManyRequests();
|
||||||
@@ -782,12 +783,16 @@ function SidebarItem({
|
|||||||
leftSlot: <Icon icon="sendHorizontal" />,
|
leftSlot: <Icon icon="sendHorizontal" />,
|
||||||
onSelect: () => sendRequest.mutate(itemId),
|
onSelect: () => sendRequest.mutate(itemId),
|
||||||
},
|
},
|
||||||
{
|
...httpRequestActions.map((a) => ({
|
||||||
key: 'copyCurl',
|
key: a.key,
|
||||||
label: 'Copy as Curl',
|
label: a.label,
|
||||||
leftSlot: <Icon icon="copy" />,
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
onSelect: copyAsCurl.mutate,
|
leftSlot: <Icon icon={(a.icon as any) ?? 'empty'} />,
|
||||||
},
|
onSelect: async () => {
|
||||||
|
const request = await getHttpRequest(itemId);
|
||||||
|
if (request != null) await a.call(request);
|
||||||
|
},
|
||||||
|
})),
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
]
|
]
|
||||||
: [];
|
: [];
|
||||||
@@ -829,12 +834,12 @@ function SidebarItem({
|
|||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
child.children,
|
child.children,
|
||||||
copyAsCurl.mutate,
|
|
||||||
createDropdownItems,
|
createDropdownItems,
|
||||||
deleteFolder,
|
deleteFolder,
|
||||||
deleteRequest,
|
deleteRequest,
|
||||||
duplicateGrpcRequest,
|
duplicateGrpcRequest,
|
||||||
duplicateHttpRequest,
|
duplicateHttpRequest,
|
||||||
|
httpRequestActions,
|
||||||
itemId,
|
itemId,
|
||||||
itemModel,
|
itemModel,
|
||||||
itemName,
|
itemName,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import React, { createContext, useContext, useMemo, useRef, useState } from 'react';
|
import React, { createContext, useContext, useMemo, useRef, useState } from 'react';
|
||||||
|
import type { ShowToastRequest } from '../../plugin-runtime-types/src';
|
||||||
|
import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent';
|
||||||
import type { ToastProps } from './core/Toast';
|
import type { ToastProps } from './core/Toast';
|
||||||
import { Toast } from './core/Toast';
|
import { Toast } from './core/Toast';
|
||||||
import { generateId } from '../lib/generateId';
|
import { generateId } from '../lib/generateId';
|
||||||
@@ -61,6 +63,10 @@ export const ToastProvider = ({ children }: { children: React.ReactNode }) => {
|
|||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useListenToTauriEvent<ShowToastRequest>('show_toast', (event) => {
|
||||||
|
actions.show({ ...event.payload });
|
||||||
|
});
|
||||||
|
|
||||||
const state: State = { toasts, actions };
|
const state: State = { toasts, actions };
|
||||||
return <ToastContext.Provider value={state}>{children}</ToastContext.Provider>;
|
return <ToastContext.Provider value={state}>{children}</ToastContext.Provider>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import { useMutation } from '@tanstack/react-query';
|
|
||||||
import { invokeCmd } from '../lib/tauri';
|
|
||||||
import { useActiveEnvironment } from './useActiveEnvironment';
|
|
||||||
import { useCopy } from './useCopy';
|
|
||||||
|
|
||||||
export function useCopyAsCurl(requestId: string) {
|
|
||||||
const copy = useCopy();
|
|
||||||
const [environment] = useActiveEnvironment();
|
|
||||||
return useMutation({
|
|
||||||
mutationKey: ['copy_as_curl', requestId],
|
|
||||||
mutationFn: async () => {
|
|
||||||
const cmd: string = await invokeCmd('cmd_request_to_curl', {
|
|
||||||
requestId,
|
|
||||||
environmentId: environment?.id,
|
|
||||||
});
|
|
||||||
copy(cmd);
|
|
||||||
return cmd;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import type {
|
||||||
|
CallHttpRequestActionRequest,
|
||||||
|
GetHttpRequestActionsResponse,
|
||||||
|
HttpRequest,
|
||||||
|
} from '@yaakapp/api';
|
||||||
|
import { invokeCmd } from '../lib/tauri';
|
||||||
|
|
||||||
|
export function useHttpRequestActions() {
|
||||||
|
const httpRequestActions = useQuery({
|
||||||
|
queryKey: ['http_request_actions'],
|
||||||
|
queryFn: async () => {
|
||||||
|
const responses = (await invokeCmd(
|
||||||
|
'cmd_http_request_actions',
|
||||||
|
)) as GetHttpRequestActionsResponse[];
|
||||||
|
return responses;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
httpRequestActions.data?.flatMap((r) =>
|
||||||
|
r.actions.map((a) => ({
|
||||||
|
key: a.key,
|
||||||
|
label: a.label,
|
||||||
|
icon: a.icon,
|
||||||
|
call: async (httpRequest: HttpRequest) => {
|
||||||
|
const payload: CallHttpRequestActionRequest = {
|
||||||
|
key: a.key,
|
||||||
|
pluginRefId: r.pluginRefId,
|
||||||
|
args: { httpRequest },
|
||||||
|
};
|
||||||
|
await invokeCmd('cmd_call_http_request_action', { req: payload });
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
) ?? []
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import type { InvokeArgs } from '@tauri-apps/api/core';
|
|||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
|
|
||||||
type TauriCmd =
|
type TauriCmd =
|
||||||
|
| 'cmd_call_http_request_action'
|
||||||
| 'cmd_check_for_updates'
|
| 'cmd_check_for_updates'
|
||||||
| 'cmd_create_cookie_jar'
|
| 'cmd_create_cookie_jar'
|
||||||
| 'cmd_create_environment'
|
| 'cmd_create_environment'
|
||||||
@@ -47,7 +48,6 @@ type TauriCmd =
|
|||||||
| 'cmd_metadata'
|
| 'cmd_metadata'
|
||||||
| 'cmd_new_nested_window'
|
| 'cmd_new_nested_window'
|
||||||
| 'cmd_new_window'
|
| 'cmd_new_window'
|
||||||
| 'cmd_request_to_curl'
|
|
||||||
| 'cmd_dismiss_notification'
|
| 'cmd_dismiss_notification'
|
||||||
| 'cmd_save_response'
|
| 'cmd_save_response'
|
||||||
| 'cmd_send_ephemeral_request'
|
| 'cmd_send_ephemeral_request'
|
||||||
@@ -62,6 +62,7 @@ type TauriCmd =
|
|||||||
| 'cmd_update_http_request'
|
| 'cmd_update_http_request'
|
||||||
| 'cmd_update_settings'
|
| 'cmd_update_settings'
|
||||||
| 'cmd_update_workspace'
|
| 'cmd_update_workspace'
|
||||||
|
| 'cmd_http_request_actions'
|
||||||
| 'cmd_write_file_dev';
|
| 'cmd_write_file_dev';
|
||||||
|
|
||||||
export async function invokeCmd<T>(cmd: TauriCmd, args?: InvokeArgs): Promise<T> {
|
export async function invokeCmd<T>(cmd: TauriCmd, args?: InvokeArgs): Promise<T> {
|
||||||
|
|||||||
Reference in New Issue
Block a user