|
@@ -1,4 +1,4 @@
|
|
|
-import { invoke } from "@tauri-apps/api/core";
|
|
|
|
|
|
|
+import { Channel, invoke } from "@tauri-apps/api/core";
|
|
|
import type {
|
|
import type {
|
|
|
Workspace,
|
|
Workspace,
|
|
|
WorkspaceEntryBase,
|
|
WorkspaceEntryBase,
|
|
@@ -11,6 +11,8 @@ import type {
|
|
|
RequestPathParam,
|
|
RequestPathParam,
|
|
|
Authentication,
|
|
Authentication,
|
|
|
AuthType,
|
|
AuthType,
|
|
|
|
|
+ HttpResponse,
|
|
|
|
|
+ ResponseResult,
|
|
|
} from "./types";
|
|
} from "./types";
|
|
|
import { getSetting, setSetting } from "./settings.svelte";
|
|
import { getSetting, setSetting } from "./settings.svelte";
|
|
|
|
|
|
|
@@ -31,14 +33,14 @@ export type WorkspaceState = {
|
|
|
roots: number[];
|
|
roots: number[];
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * Workspace entry parent => children mappings.
|
|
|
|
|
|
|
+ * Workspace entry root => children mappings.
|
|
|
*/
|
|
*/
|
|
|
children: Record<number, number[]>;
|
|
children: Record<number, number[]>;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* All workspace entries.
|
|
* All workspace entries.
|
|
|
*/
|
|
*/
|
|
|
- indexes: Record<number, WorkspaceEntry>;
|
|
|
|
|
|
|
+ indexes: Record<number, WorkspaceEntryBase>;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* Currently selected workspace environments.
|
|
* Currently selected workspace environments.
|
|
@@ -54,6 +56,16 @@ export type WorkspaceState = {
|
|
|
* All workspace authentication schemes.
|
|
* All workspace authentication schemes.
|
|
|
*/
|
|
*/
|
|
|
auth: Authentication[];
|
|
auth: Authentication[];
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Set of pending sent requests.
|
|
|
|
|
+ */
|
|
|
|
|
+ pendingRequests: number[];
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Maps request IDs to their latest response.
|
|
|
|
|
+ */
|
|
|
|
|
+ responses: Record<number, HttpResponse>;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
export const state: WorkspaceState = $state({
|
|
export const state: WorkspaceState = $state({
|
|
@@ -65,6 +77,8 @@ export const state: WorkspaceState = $state({
|
|
|
environments: [],
|
|
environments: [],
|
|
|
environment: null,
|
|
environment: null,
|
|
|
auth: [],
|
|
auth: [],
|
|
|
|
|
+ pendingRequests: [],
|
|
|
|
|
+ responses: {},
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
const index = (entry: WorkspaceEntry) => {
|
|
const index = (entry: WorkspaceEntry) => {
|
|
@@ -90,6 +104,8 @@ function reset() {
|
|
|
state.environment = null;
|
|
state.environment = null;
|
|
|
state.environments = [];
|
|
state.environments = [];
|
|
|
state.auth = [];
|
|
state.auth = [];
|
|
|
|
|
+ state.pendingRequests = [];
|
|
|
|
|
+ state.responses = {};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export async function selectEnvironment(
|
|
export async function selectEnvironment(
|
|
@@ -132,7 +148,27 @@ export function selectWorkspace(ws: Workspace) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export async function selectEntry(id: number) {
|
|
export async function selectEntry(id: number) {
|
|
|
- state.entry = state.indexes[id];
|
|
|
|
|
|
|
+ const entry = await invoke<WorkspaceEntryResponse>("get_workspace_entry", {
|
|
|
|
|
+ entryId: id,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ switch (entry.type) {
|
|
|
|
|
+ case "Collection": {
|
|
|
|
|
+ state.entry = entry.data;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case "Request": {
|
|
|
|
|
+ state.entry = {
|
|
|
|
|
+ ...entry.data.entry,
|
|
|
|
|
+ method: entry.data.method,
|
|
|
|
|
+ url: entry.data.url,
|
|
|
|
|
+ headers: entry.data.headers,
|
|
|
|
|
+ body: entry.data.body,
|
|
|
|
|
+ path: entry.data.path_params,
|
|
|
|
|
+ };
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
console.log("selected entry:", $state.snapshot(state.entry));
|
|
console.log("selected entry:", $state.snapshot(state.entry));
|
|
|
|
|
|
|
@@ -183,26 +219,15 @@ export async function loadWorkspace(ws: Workspace) {
|
|
|
|
|
|
|
|
state.workspace = ws;
|
|
state.workspace = ws;
|
|
|
|
|
|
|
|
- const entries = await invoke<WorkspaceEntryResponse[]>(
|
|
|
|
|
- "list_workspace_entries",
|
|
|
|
|
- {
|
|
|
|
|
- id: state.workspace.id,
|
|
|
|
|
- },
|
|
|
|
|
- );
|
|
|
|
|
|
|
+ const entries = await invoke<WorkspaceEntryBase[]>("list_workspace_entries", {
|
|
|
|
|
+ id: state.workspace.id,
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
for (const entry of entries) {
|
|
for (const entry of entries) {
|
|
|
- if (entry.type === "Request") {
|
|
|
|
|
- index({
|
|
|
|
|
- ...entry.data.entry,
|
|
|
|
|
- method: entry.data.method,
|
|
|
|
|
- url: entry.data.url,
|
|
|
|
|
- headers: entry.data.headers,
|
|
|
|
|
- body: entry.data.body,
|
|
|
|
|
- path: entry.data.path_params,
|
|
|
|
|
- });
|
|
|
|
|
- } else {
|
|
|
|
|
- index(entry.data);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // if (entry.type === "Request") {
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ index(entry);
|
|
|
|
|
+ // }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
await loadEnvironments(state.workspace.id);
|
|
await loadEnvironments(state.workspace.id);
|
|
@@ -211,7 +236,7 @@ export async function loadWorkspace(ws: Workspace) {
|
|
|
|
|
|
|
|
export function createRequest(parentId?: number) {
|
|
export function createRequest(parentId?: number) {
|
|
|
if (state.workspace == null) {
|
|
if (state.workspace == null) {
|
|
|
- console.warn("create workspace request called with no active workspace");
|
|
|
|
|
|
|
+ console.warn("create request called with no active workspace");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -222,27 +247,22 @@ export function createRequest(parentId?: number) {
|
|
|
parent_id: parentId,
|
|
parent_id: parentId,
|
|
|
method: "GET",
|
|
method: "GET",
|
|
|
url: "",
|
|
url: "",
|
|
|
|
|
+ auth_inherit: parentId !== undefined,
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
invoke<WorkspaceEntryBase>("create_workspace_entry", {
|
|
invoke<WorkspaceEntryBase>("create_workspace_entry", {
|
|
|
data,
|
|
data,
|
|
|
}).then((entry) => {
|
|
}).then((entry) => {
|
|
|
- index({
|
|
|
|
|
- ...entry,
|
|
|
|
|
- method: data.Request.method,
|
|
|
|
|
- url: data.Request.url,
|
|
|
|
|
- body: null,
|
|
|
|
|
- headers: [],
|
|
|
|
|
- path: [],
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ index(entry);
|
|
|
|
|
+ selectEntry(entry.id);
|
|
|
console.log("request created:", entry);
|
|
console.log("request created:", entry);
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export function createCollection(parentId?: number) {
|
|
export function createCollection(parentId?: number) {
|
|
|
if (state.workspace == null) {
|
|
if (state.workspace == null) {
|
|
|
- console.warn("create workspace request called with no active workspace");
|
|
|
|
|
|
|
+ console.warn("create collection called with no active workspace");
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -251,12 +271,14 @@ export function createCollection(parentId?: number) {
|
|
|
name: "",
|
|
name: "",
|
|
|
workspace_id: state.workspace.id,
|
|
workspace_id: state.workspace.id,
|
|
|
parent_id: parentId,
|
|
parent_id: parentId,
|
|
|
|
|
+ auth_inherit: parentId !== undefined,
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
invoke<WorkspaceEntryBase>("create_workspace_entry", {
|
|
invoke<WorkspaceEntryBase>("create_workspace_entry", {
|
|
|
data,
|
|
data,
|
|
|
}).then((entry) => {
|
|
}).then((entry) => {
|
|
|
index(entry);
|
|
index(entry);
|
|
|
|
|
+ selectEntry(entry.id);
|
|
|
console.log("collection created:", entry);
|
|
console.log("collection created:", entry);
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
@@ -300,15 +322,67 @@ export async function updateEnvironment() {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-export async function sendRequest(): Promise<any> {
|
|
|
|
|
- const res = await invoke("send_request", {
|
|
|
|
|
- reqId: state.entry!!.id,
|
|
|
|
|
|
|
+export async function sendRequest(): Promise<void> {
|
|
|
|
|
+ const reqId = state.entry!!.id;
|
|
|
|
|
+
|
|
|
|
|
+ if (state.pendingRequests.includes(reqId)) {
|
|
|
|
|
+ console.warn("request is already pending", reqId);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ console.log("sending request", reqId);
|
|
|
|
|
+
|
|
|
|
|
+ const onComplete = new Channel<ResponseResult>();
|
|
|
|
|
+
|
|
|
|
|
+ console.time("request-" + reqId);
|
|
|
|
|
+
|
|
|
|
|
+ onComplete.onmessage = (response) => {
|
|
|
|
|
+ console.log("received response", response);
|
|
|
|
|
+
|
|
|
|
|
+ switch (response.type) {
|
|
|
|
|
+ case "Ok": {
|
|
|
|
|
+ state.responses[state.entry!!.id] = response.data;
|
|
|
|
|
+ console.log(state.responses);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ case "Err": {
|
|
|
|
|
+ console.error("received response error", response.data);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ default: {
|
|
|
|
|
+ console.error("unrecognized response type", response.type);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ console.timeEnd("request-" + reqId);
|
|
|
|
|
+
|
|
|
|
|
+ state.pendingRequests = state.pendingRequests.filter((id) => id !== reqId);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ await invoke<HttpResponse>("send_request", {
|
|
|
|
|
+ reqId,
|
|
|
envId: state.environment?.id,
|
|
envId: state.environment?.id,
|
|
|
|
|
+ onComplete,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- console.debug(res);
|
|
|
|
|
|
|
+ state.pendingRequests.push(reqId);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export async function cancelRequest(): Promise<void> {
|
|
|
|
|
+ if (!state.pendingRequests.includes(state.entry!!.id)) {
|
|
|
|
|
+ console.warn("nothing to cancel!");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- return res;
|
|
|
|
|
|
|
+ console.log("cancelling request");
|
|
|
|
|
+
|
|
|
|
|
+ await invoke("cancel_request", { reqId: state.entry!!.id });
|
|
|
|
|
+
|
|
|
|
|
+ console.timeEnd("request-" + state.entry!!.id);
|
|
|
|
|
+
|
|
|
|
|
+ state.pendingRequests = state.pendingRequests.filter(
|
|
|
|
|
+ (id) => id !== state.entry!!.id,
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export async function updateEntryName(name: string) {
|
|
export async function updateEntryName(name: string) {
|
|
@@ -334,6 +408,8 @@ export async function updateEntryName(name: string) {
|
|
|
entryId: state.entry.id,
|
|
entryId: state.entry.id,
|
|
|
data,
|
|
data,
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
|
|
+ state.indexes[state.entry.id].name = name;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export async function parseUrl(url: string) {
|
|
export async function parseUrl(url: string) {
|
|
@@ -494,7 +570,9 @@ export async function createAuth(type: AuthType) {
|
|
|
workspaceId: state.workspace!!.id,
|
|
workspaceId: state.workspace!!.id,
|
|
|
type,
|
|
type,
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
console.debug("created auth", auth);
|
|
console.debug("created auth", auth);
|
|
|
|
|
+
|
|
|
state.auth.unshift(auth);
|
|
state.auth.unshift(auth);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -543,9 +621,11 @@ export async function setEntryAuth(id: number | null, inherit: boolean | null) {
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
state.entry!!.auth = id;
|
|
state.entry!!.auth = id;
|
|
|
|
|
+ state.indexes[state.entry!!.id].auth = id;
|
|
|
|
|
|
|
|
if (inherit != null) {
|
|
if (inherit != null) {
|
|
|
state.entry!!.auth_inherit = inherit;
|
|
state.entry!!.auth_inherit = inherit;
|
|
|
|
|
+ state.indexes[state.entry!!.id].auth_inherit = inherit;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|