mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-02-19 00:57:48 +01:00
Compare commits
6 Commits
v2024.11.0
...
v2024.11.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e775b2b49 | ||
|
|
e77a9e5d44 | ||
|
|
a381e44d8c | ||
|
|
4acf0969e8 | ||
|
|
30c4178269 | ||
|
|
dffe6e0a16 |
@@ -288,7 +288,8 @@ var SUPPORTED_ARGS = [
|
||||
// Request method
|
||||
DATA_FLAGS
|
||||
].flatMap((v) => v);
|
||||
function pluginHookImport(ctx, rawData) {
|
||||
var BOOL_FLAGS = ["G", "get", "digest"];
|
||||
function pluginHookImport(_ctx, rawData) {
|
||||
if (!rawData.match(/^\s*curl /)) {
|
||||
return null;
|
||||
}
|
||||
@@ -359,10 +360,11 @@ function importCommand(parseEntries, workspaceId) {
|
||||
}
|
||||
let value;
|
||||
const nextEntry = parseEntries[i + 1];
|
||||
const hasValue = !BOOL_FLAGS.includes(name);
|
||||
if (isSingleDash && name.length > 1) {
|
||||
value = name.slice(1);
|
||||
name = name.slice(0, 1);
|
||||
} else if (typeof nextEntry === "string" && !nextEntry.startsWith("-")) {
|
||||
} else if (typeof nextEntry === "string" && hasValue && !nextEntry.startsWith("-")) {
|
||||
value = nextEntry;
|
||||
i++;
|
||||
} else {
|
||||
|
||||
55
src-tauri/vendored/plugins/template-function-fs/build/index.js
generated
Normal file
55
src-tauri/vendored/plugins/template-function-fs/build/index.js
generated
Normal file
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
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 import_node_fs = __toESM(require("node:fs"));
|
||||
var plugin = {
|
||||
templateFunctions: [{
|
||||
name: "fs.readFile",
|
||||
description: "Read the contents of a file as utf-8",
|
||||
args: [{ title: "Select File", type: "file", name: "path", label: "File" }],
|
||||
async onRender(_ctx, args) {
|
||||
if (!args.values.path) return null;
|
||||
try {
|
||||
return import_node_fs.default.promises.readFile(args.values.path, "utf-8");
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
plugin
|
||||
});
|
||||
9
src-tauri/vendored/plugins/template-function-fs/package.json
generated
Normal file
9
src-tauri/vendored/plugins/template-function-fs/package.json
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "@yaakapp/template-function-fs",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"build": "yaakcli build ./src/index.ts",
|
||||
"dev": "yaakcli dev ./src/index.js"
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ var algorithms = ["md5", "sha1", "sha256", "sha512"];
|
||||
var plugin = {
|
||||
templateFunctions: algorithms.map((algorithm) => ({
|
||||
name: `hash.${algorithm}`,
|
||||
description: "Hash a value to its hexidecimal representation",
|
||||
args: [
|
||||
{
|
||||
name: "input",
|
||||
|
||||
@@ -26,24 +26,21 @@ module.exports = __toCommonJS(src_exports);
|
||||
var plugin = {
|
||||
templateFunctions: [{
|
||||
name: "prompt.text",
|
||||
description: "Prompt the user for input when sending a request",
|
||||
args: [
|
||||
{ type: "text", name: "title", label: "Title" },
|
||||
{ type: "text", name: "label", label: "Label", optional: true },
|
||||
{ type: "text", name: "defaultValue", label: "Default Value", optional: true },
|
||||
{ type: "text", name: "placeholder", label: "Placeholder", optional: true }
|
||||
],
|
||||
async onRender(ctx, args) {
|
||||
console.log("PROMPT", args);
|
||||
if (args.purpose !== "send") return null;
|
||||
const value = await ctx.prompt.text({
|
||||
return await ctx.prompt.text({
|
||||
id: `prompt-${args.values.label}`,
|
||||
label: args.values.label ?? "",
|
||||
label: args.values.title ?? "",
|
||||
title: args.values.title ?? "",
|
||||
defaultValue: args.values.defaultValue,
|
||||
placeholder: args.values.placeholder
|
||||
});
|
||||
console.log("VALUE", value);
|
||||
return value;
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
@@ -8837,6 +8837,7 @@ var plugin = {
|
||||
templateFunctions: [
|
||||
{
|
||||
name: "response.header",
|
||||
description: "Read the value of a response header, by name",
|
||||
args: [
|
||||
requestArg,
|
||||
{
|
||||
@@ -8863,6 +8864,7 @@ var plugin = {
|
||||
},
|
||||
{
|
||||
name: "response.body.path",
|
||||
description: "Access a field of the response body using JsonPath or XPath",
|
||||
aliases: ["response"],
|
||||
args: [
|
||||
requestArg,
|
||||
@@ -8901,6 +8903,34 @@ var plugin = {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "response.body.raw",
|
||||
description: "Access the entire response body, as text",
|
||||
aliases: ["response"],
|
||||
args: [
|
||||
requestArg,
|
||||
behaviorArg
|
||||
],
|
||||
async onRender(ctx, args) {
|
||||
if (!args.values.request) return null;
|
||||
const response = await getResponse(ctx, {
|
||||
requestId: args.values.request,
|
||||
purpose: args.purpose,
|
||||
behavior: args.values.behavior ?? null
|
||||
});
|
||||
if (response == null) return null;
|
||||
if (response.bodyPath == null) {
|
||||
return null;
|
||||
}
|
||||
let body;
|
||||
try {
|
||||
body = (0, import_node_fs.readFileSync)(response.bodyPath, "utf-8");
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
return body;
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import { lazy } from 'react';
|
||||
import { createBrowserRouter, Navigate, RouterProvider, useParams } from 'react-router-dom';
|
||||
import { routePaths, useAppRoutes } from '../hooks/useAppRoutes';
|
||||
import { useGenerateThemeCss } from '../hooks/useGenerateThemeCss';
|
||||
import { useSyncFontSizeSetting } from '../hooks/useSyncFontSizeSetting';
|
||||
import { useSyncModelStores } from '../hooks/useSyncModelStores';
|
||||
import { useSyncZoomSetting } from '../hooks/useSyncZoomSetting';
|
||||
import { DefaultLayout } from './DefaultLayout';
|
||||
import { RedirectToLatestWorkspace } from './RedirectToLatestWorkspace';
|
||||
import RouteError from './RouteError';
|
||||
@@ -54,12 +50,6 @@ const router = createBrowserRouter([
|
||||
]);
|
||||
|
||||
export function AppRouter() {
|
||||
// Add some global hooks that should remain persistent
|
||||
useSyncModelStores();
|
||||
useSyncZoomSetting();
|
||||
useSyncFontSizeSetting();
|
||||
useGenerateThemeCss();
|
||||
|
||||
return <RouterProvider router={router} />;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { emit } from '@tauri-apps/api/event';
|
||||
import type { PromptTextRequest, PromptTextResponse } from '@yaakapp-internal/plugin';
|
||||
import { useEnsureActiveCookieJar } from '../hooks/useActiveCookieJar';
|
||||
import { useActiveWorkspaceChangedToast } from '../hooks/useActiveWorkspaceChangedToast';
|
||||
import {useGenerateThemeCss} from "../hooks/useGenerateThemeCss";
|
||||
import { useHotKey } from '../hooks/useHotKey';
|
||||
import { useListenToTauriEvent } from '../hooks/useListenToTauriEvent';
|
||||
import { useNotificationToast } from '../hooks/useNotificationToast';
|
||||
@@ -10,10 +11,18 @@ import { useRecentCookieJars } from '../hooks/useRecentCookieJars';
|
||||
import { useRecentEnvironments } from '../hooks/useRecentEnvironments';
|
||||
import { useRecentRequests } from '../hooks/useRecentRequests';
|
||||
import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces';
|
||||
import {useSyncFontSizeSetting} from "../hooks/useSyncFontSizeSetting";
|
||||
import {useSyncModelStores} from "../hooks/useSyncModelStores";
|
||||
import { useSyncWorkspaceChildModels } from '../hooks/useSyncWorkspaceChildModels';
|
||||
import {useSyncZoomSetting} from "../hooks/useSyncZoomSetting";
|
||||
import { useToggleCommandPalette } from '../hooks/useToggleCommandPalette';
|
||||
|
||||
export function GlobalHooks() {
|
||||
useSyncModelStores();
|
||||
useSyncZoomSetting();
|
||||
useSyncFontSizeSetting();
|
||||
useGenerateThemeCss();
|
||||
|
||||
// Include here so they always update, even if no component references them
|
||||
useRecentWorkspaces();
|
||||
useRecentEnvironments();
|
||||
|
||||
@@ -702,11 +702,11 @@ function SidebarItem({
|
||||
useScrollIntoView(ref.current, isActive);
|
||||
|
||||
const handleSubmitNameEdit = useCallback(
|
||||
(el: HTMLInputElement) => {
|
||||
async (el: HTMLInputElement) => {
|
||||
if (itemModel === 'http_request') {
|
||||
updateHttpRequest.mutate({ id: itemId, update: (r) => ({ ...r, name: el.value }) });
|
||||
await updateHttpRequest.mutateAsync({ id: itemId, update: (r) => ({ ...r, name: el.value }) });
|
||||
} else if (itemModel === 'grpc_request') {
|
||||
updateGrpcRequest.mutate({ id: itemId, update: (r) => ({ ...r, name: el.value }) });
|
||||
await updateGrpcRequest.mutateAsync({ id: itemId, update: (r) => ({ ...r, name: el.value }) });
|
||||
}
|
||||
setEditing(false);
|
||||
},
|
||||
|
||||
@@ -8,12 +8,12 @@ import classNames from 'classnames';
|
||||
import { EditorView } from 'codemirror';
|
||||
import type { MutableRefObject, ReactNode } from 'react';
|
||||
import {
|
||||
useEffect,
|
||||
Children,
|
||||
cloneElement,
|
||||
forwardRef,
|
||||
isValidElement,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
useRef,
|
||||
@@ -343,6 +343,33 @@ export const Editor = forwardRef<EditorView | undefined, EditorProps>(function E
|
||||
[forceUpdateKey],
|
||||
);
|
||||
|
||||
// For read-only mode, update content when `defaultValue` changes
|
||||
useEffect(() => {
|
||||
if (!readOnly || cm.current?.view == null || defaultValue == null) return;
|
||||
|
||||
// Replace codemirror contents
|
||||
const currentDoc = cm.current.view.state.doc.toString();
|
||||
if (defaultValue.startsWith(currentDoc)) {
|
||||
// If we're just appending, append only the changes. This preserves
|
||||
// things like scroll position.
|
||||
cm.current.view.dispatch({
|
||||
changes: cm.current.view.state.changes({
|
||||
from: currentDoc.length,
|
||||
insert: defaultValue.slice(currentDoc.length),
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
// If we're replacing everything, reset the entire content
|
||||
cm.current.view.dispatch({
|
||||
changes: cm.current.view.state.changes({
|
||||
from: 0,
|
||||
to: currentDoc.length,
|
||||
insert: currentDoc,
|
||||
}),
|
||||
});
|
||||
}
|
||||
}, [defaultValue, readOnly]);
|
||||
|
||||
// Add bg classes to actions, so they appear over the text
|
||||
const decoratedActions = useMemo(() => {
|
||||
const results = [];
|
||||
|
||||
@@ -128,6 +128,9 @@ export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function
|
||||
type={type === 'password' && !obscured ? 'text' : type}
|
||||
defaultValue={defaultValue}
|
||||
placeholder={placeholder}
|
||||
autoComplete="off"
|
||||
autoCapitalize="off"
|
||||
autoCorrect="off"
|
||||
onChange={(e) => handleChange(e.target.value)}
|
||||
onPaste={(e) => onPaste?.(e.clipboardData.getData('Text'))}
|
||||
className={inputClassName}
|
||||
|
||||
@@ -90,7 +90,6 @@ function ActualEventStreamViewer({ response }: Props) {
|
||||
) : (
|
||||
<Editor
|
||||
readOnly
|
||||
forceUpdateKey={activeEvent.id ?? activeEvent.data}
|
||||
defaultValue={tryFormatJson(activeEvent.data)}
|
||||
language={language}
|
||||
/>
|
||||
|
||||
@@ -160,7 +160,6 @@ export function TextViewer({
|
||||
<Editor
|
||||
readOnly
|
||||
className={className}
|
||||
forceUpdateKey={body}
|
||||
defaultValue={body}
|
||||
language={language}
|
||||
actions={actions}
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { AnyModel } from '@yaakapp-internal/models';
|
||||
import { useSetAtom } from 'jotai/index';
|
||||
import { extractKeyValue } from '../lib/keyValueStore';
|
||||
import { modelsEq } from '../lib/model_util';
|
||||
import {useActiveWorkspace} from "./useActiveWorkspace";
|
||||
import { cookieJarsAtom } from './useCookieJars';
|
||||
import { environmentsAtom } from './useEnvironments';
|
||||
import { foldersAtom } from './useFolders';
|
||||
@@ -25,6 +26,7 @@ export interface ModelPayload {
|
||||
}
|
||||
|
||||
export function useSyncModelStores() {
|
||||
const activeWorkspace = useActiveWorkspace();
|
||||
const queryClient = useQueryClient();
|
||||
const { wasUpdatedExternally } = useRequestUpdateKey(null);
|
||||
|
||||
@@ -48,10 +50,17 @@ export function useSyncModelStores() {
|
||||
? keyValueQueryKey(model)
|
||||
: null;
|
||||
|
||||
// TODO: Move this logic to useRequestEditor() hook
|
||||
if (model.model === 'http_request' && windowLabel !== getCurrentWebviewWindow().label) {
|
||||
wasUpdatedExternally(model.id);
|
||||
}
|
||||
|
||||
// Only sync models that belong to this workspace, if a workspace ID is present
|
||||
if ('workspaceId' in model && model.workspaceId !== activeWorkspace?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark these models as DESC instead of ASC
|
||||
const pushToFront = (['http_response', 'grpc_connection'] as AnyModel['model'][]).includes(
|
||||
model.model,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user