mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-01-16 05:56:47 +01:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b84545b67 | ||
|
|
0e28079965 | ||
|
|
5d5f9cc943 | ||
|
|
b71bc2cc92 | ||
|
|
23191dcfc3 | ||
|
|
372b15689d | ||
|
|
5c6d6fb7e4 | ||
|
|
835a2e93e9 | ||
|
|
93c6f6d611 | ||
|
|
b445261b32 | ||
|
|
685b59cee9 | ||
|
|
38529cc89e | ||
|
|
0d98b95b61 | ||
|
|
e044dcae3e |
272
package-lock.json
generated
272
package-lock.json
generated
@@ -3619,6 +3619,16 @@
|
||||
"@types/react": "^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-syntax-highlighter": {
|
||||
"version": "15.5.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz",
|
||||
"integrity": "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/shell-quote": {
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/shell-quote/-/shell-quote-1.7.5.tgz",
|
||||
@@ -9018,6 +9028,16 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/hast-util-parse-selector": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
|
||||
"integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/hast-util-to-html": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
|
||||
@@ -9081,6 +9101,71 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/hastscript": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
|
||||
"integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/hast": "^2.0.0",
|
||||
"comma-separated-tokens": "^1.0.0",
|
||||
"hast-util-parse-selector": "^2.0.0",
|
||||
"property-information": "^5.0.0",
|
||||
"space-separated-tokens": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/hastscript/node_modules/@types/hast": {
|
||||
"version": "2.3.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
|
||||
"integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/unist": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/hastscript/node_modules/@types/unist": {
|
||||
"version": "2.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
|
||||
"integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/hastscript/node_modules/comma-separated-tokens": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
|
||||
"integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/hastscript/node_modules/property-information": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
|
||||
"integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"xtend": "^4.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/hastscript/node_modules/space-separated-tokens": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
|
||||
"integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/hexy": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/hexy/-/hexy-0.3.5.tgz",
|
||||
@@ -9093,6 +9178,21 @@
|
||||
"node": ">=10.4"
|
||||
}
|
||||
},
|
||||
"node_modules/highlight.js": {
|
||||
"version": "10.7.3",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
|
||||
"integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/highlightjs-vue": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz",
|
||||
"integrity": "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==",
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/history": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz",
|
||||
@@ -10782,6 +10882,33 @@
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/lowlight": {
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
|
||||
"integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fault": "^1.0.0",
|
||||
"highlight.js": "~10.7.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/lowlight/node_modules/fault": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
|
||||
"integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"format": "^0.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
@@ -14103,6 +14230,15 @@
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prismjs": {
|
||||
"version": "1.30.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
|
||||
"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
@@ -14339,6 +14475,23 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-syntax-highlighter": {
|
||||
"version": "15.6.1",
|
||||
"resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.6.1.tgz",
|
||||
"integrity": "sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.1",
|
||||
"highlight.js": "^10.4.1",
|
||||
"highlightjs-vue": "^1.0.0",
|
||||
"lowlight": "^1.17.0",
|
||||
"prismjs": "^1.27.0",
|
||||
"refractor": "^3.6.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">= 0.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-universal-interface": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz",
|
||||
@@ -14654,6 +14807,122 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
|
||||
"integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hastscript": "^6.0.0",
|
||||
"parse-entities": "^2.0.0",
|
||||
"prismjs": "~1.27.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/character-entities": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
|
||||
"integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/character-entities-legacy": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
|
||||
"integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/character-reference-invalid": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
|
||||
"integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/is-alphabetical": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
|
||||
"integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/is-alphanumerical": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
|
||||
"integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-alphabetical": "^1.0.0",
|
||||
"is-decimal": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/is-decimal": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
|
||||
"integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/is-hexadecimal": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
|
||||
"integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/parse-entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
|
||||
"integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"character-entities": "^1.0.0",
|
||||
"character-entities-legacy": "^1.0.0",
|
||||
"character-reference-invalid": "^1.0.0",
|
||||
"is-alphanumerical": "^1.0.0",
|
||||
"is-decimal": "^1.0.0",
|
||||
"is-hexadecimal": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/refractor/node_modules/prismjs": {
|
||||
"version": "1.27.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
|
||||
"integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/reftools": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz",
|
||||
@@ -18263,7 +18532,6 @@
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
@@ -18784,6 +19052,7 @@
|
||||
"react-dom": "^19.1.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-pdf": "^10.0.1",
|
||||
"react-syntax-highlighter": "^15.6.1",
|
||||
"react-use": "^17.6.0",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
@@ -18803,6 +19072,7 @@
|
||||
"@types/parse-color": "^1.0.3",
|
||||
"@types/react": "^19.1.8",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@types/whatwg-mimetype": "^3.0.2",
|
||||
"@vitejs/plugin-react": "^4.6.0",
|
||||
|
||||
@@ -4,8 +4,6 @@ import type { JsonValue } from "./serde_json/JsonValue.js";
|
||||
|
||||
export type BootRequest = { dir: string, watch: boolean, };
|
||||
|
||||
export type BootResponse = { name: string, version: string, };
|
||||
|
||||
export type CallGrpcRequestActionArgs = { grpcRequest: GrpcRequest, protoFiles: Array<string>, };
|
||||
|
||||
export type CallGrpcRequestActionRequest = { index: number, pluginRefId: string, args: CallGrpcRequestActionArgs, };
|
||||
@@ -387,7 +385,7 @@ export type ImportResponse = { resources: ImportResources, };
|
||||
|
||||
export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: PluginWindowContext, payload: InternalEventPayload, };
|
||||
|
||||
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & BootResponse | { "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": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_grpc_request_actions_request" } & EmptyPayload | { "type": "get_grpc_request_actions_response" } & GetGrpcRequestActionsResponse | { "type": "call_grpc_request_action_request" } & CallGrpcRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "render_grpc_request_request" } & RenderGrpcRequestRequest | { "type": "render_grpc_request_response" } & RenderGrpcRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "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": "get_themes_request" } & GetThemesRequest | { "type": "get_themes_response" } & GetThemesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse;
|
||||
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } | { "type": "reload_response" } & ReloadResponse | { "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": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_grpc_request_actions_request" } & EmptyPayload | { "type": "get_grpc_request_actions_response" } & GetGrpcRequestActionsResponse | { "type": "call_grpc_request_action_request" } & CallGrpcRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "render_grpc_request_request" } & RenderGrpcRequestRequest | { "type": "render_grpc_request_response" } & RenderGrpcRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "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": "get_themes_request" } & GetThemesRequest | { "type": "get_themes_response" } & GetThemesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse;
|
||||
|
||||
export type JsonPrimitive = string | number | boolean | null;
|
||||
|
||||
@@ -419,6 +417,8 @@ required?: boolean, };
|
||||
|
||||
export type PromptTextResponse = { value: string | null, };
|
||||
|
||||
export type ReloadResponse = { silent: boolean, };
|
||||
|
||||
export type RenderGrpcRequestRequest = { grpcRequest: GrpcRequest, purpose: RenderPurpose, };
|
||||
|
||||
export type RenderGrpcRequestResponse = { grpcRequest: GrpcRequest, };
|
||||
|
||||
@@ -61,4 +61,7 @@ export interface Context {
|
||||
templates: {
|
||||
render<T extends JsonValue>(args: TemplateRenderRequest & { data: T }): Promise<T>;
|
||||
};
|
||||
plugin: {
|
||||
reload(): void;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,12 +6,16 @@ import type { ImporterPlugin } from './ImporterPlugin';
|
||||
import type { TemplateFunctionPlugin } from './TemplateFunctionPlugin';
|
||||
import type { ThemePlugin } from './ThemePlugin';
|
||||
|
||||
export type { Context } from './Context';
|
||||
import type { Context } from './Context';
|
||||
|
||||
export type { Context };
|
||||
|
||||
/**
|
||||
* The global structure of a Yaak plugin
|
||||
*/
|
||||
export type PluginDefinition = {
|
||||
init?: (ctx: Context) => void | Promise<void>;
|
||||
dispose?: () => void | Promise<void>;
|
||||
importer?: ImporterPlugin;
|
||||
themes?: ThemePlugin[];
|
||||
filter?: FilterPlugin;
|
||||
|
||||
@@ -21,7 +21,7 @@ export class PluginHandle {
|
||||
this.#instance.postMessage(event);
|
||||
}
|
||||
|
||||
terminate() {
|
||||
this.#instance.terminate();
|
||||
async terminate() {
|
||||
await this.#instance.terminate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
BootRequest,
|
||||
BootResponse,
|
||||
DeleteKeyValueResponse,
|
||||
FindHttpResponsesResponse,
|
||||
FormInput,
|
||||
@@ -56,19 +55,19 @@ export class PluginInstance {
|
||||
// Reload plugin if the JS or package.json changes
|
||||
const windowContextNone: PluginWindowContext = { type: 'none' };
|
||||
|
||||
this.#mod = {};
|
||||
this.#mod = {} as any;
|
||||
this.#pkg = JSON.parse(readFileSync(this.#pathPkg(), 'utf8'));
|
||||
|
||||
const bootResponse: BootResponse = {
|
||||
name: this.#pkg.name ?? 'unknown',
|
||||
version: this.#pkg.version ?? '0.0.1',
|
||||
};
|
||||
|
||||
const fileChangeCallback = async () => {
|
||||
await this.#mod?.dispose?.();
|
||||
this.#importModule();
|
||||
await this.#mod?.init?.(this.#newCtx({ type: 'none' }));
|
||||
return this.#sendPayload(
|
||||
windowContextNone,
|
||||
{ type: 'reload_response', ...bootResponse },
|
||||
{
|
||||
type: 'reload_response',
|
||||
silent: false,
|
||||
},
|
||||
null,
|
||||
);
|
||||
};
|
||||
@@ -85,23 +84,20 @@ export class PluginInstance {
|
||||
this.#appToPluginEvents.emit(event);
|
||||
}
|
||||
|
||||
terminate() {
|
||||
async terminate() {
|
||||
await this.#mod?.dispose?.();
|
||||
this.#unimportModule();
|
||||
}
|
||||
|
||||
async #onMessage(event: InternalEvent) {
|
||||
const ctx = this.#newCtx(event);
|
||||
const ctx = this.#newCtx(event.windowContext);
|
||||
|
||||
const { windowContext, payload, id: replyId } = event;
|
||||
|
||||
try {
|
||||
if (payload.type === 'boot_request') {
|
||||
// console.log('Plugin initialized', pkg.name, { capabilities, enableWatch });
|
||||
const payload: InternalEventPayload = {
|
||||
type: 'boot_response',
|
||||
name: this.#pkg.name ?? 'unknown',
|
||||
version: this.#pkg.version ?? '0.0.1',
|
||||
};
|
||||
this.#sendPayload(windowContext, payload, replyId);
|
||||
await this.#mod?.init?.(ctx);
|
||||
this.#sendPayload(windowContext, { type: 'boot_response' }, replyId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -109,6 +105,7 @@ export class PluginInstance {
|
||||
const payload: InternalEventPayload = {
|
||||
type: 'terminate_response',
|
||||
};
|
||||
await this.terminate();
|
||||
this.#sendPayload(windowContext, payload, replyId);
|
||||
return;
|
||||
}
|
||||
@@ -332,10 +329,6 @@ export class PluginInstance {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (payload.type === 'reload_request') {
|
||||
this.#importModule();
|
||||
}
|
||||
} catch (err) {
|
||||
const error = `${err}`.replace(/^Error:\s*/g, '');
|
||||
console.log('Plugin call threw exception', payload.type, '→', error);
|
||||
@@ -447,11 +440,11 @@ export class PluginInstance {
|
||||
this.#sendEvent(eventToSend);
|
||||
}
|
||||
|
||||
#newCtx(event: InternalEvent): Context {
|
||||
#newCtx(windowContext: PluginWindowContext): Context {
|
||||
return {
|
||||
clipboard: {
|
||||
copyText: async (text) => {
|
||||
await this.#sendAndWaitForReply(event.windowContext, {
|
||||
await this.#sendAndWaitForReply(windowContext, {
|
||||
type: 'copy_text_request',
|
||||
text,
|
||||
});
|
||||
@@ -459,7 +452,7 @@ export class PluginInstance {
|
||||
},
|
||||
toast: {
|
||||
show: async (args) => {
|
||||
await this.#sendAndWaitForReply(event.windowContext, {
|
||||
await this.#sendAndWaitForReply(windowContext, {
|
||||
type: 'show_toast_request',
|
||||
...args,
|
||||
});
|
||||
@@ -476,21 +469,21 @@ export class PluginInstance {
|
||||
onClose?.();
|
||||
}
|
||||
};
|
||||
this.#sendAndListenForEvents(event.windowContext, payload, onEvent);
|
||||
this.#sendAndListenForEvents(windowContext, payload, onEvent);
|
||||
return {
|
||||
close: () => {
|
||||
const closePayload: InternalEventPayload = {
|
||||
type: 'close_window_request',
|
||||
label: args.label,
|
||||
};
|
||||
this.#sendPayload(event.windowContext, closePayload, null);
|
||||
this.#sendPayload(windowContext, closePayload, null);
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
prompt: {
|
||||
text: async (args) => {
|
||||
const reply: PromptTextResponse = await this.#sendAndWaitForReply(event.windowContext, {
|
||||
const reply: PromptTextResponse = await this.#sendAndWaitForReply(windowContext, {
|
||||
type: 'prompt_text_request',
|
||||
...args,
|
||||
});
|
||||
@@ -504,7 +497,7 @@ export class PluginInstance {
|
||||
...args,
|
||||
} as const;
|
||||
const { httpResponses } = await this.#sendAndWaitForReply<FindHttpResponsesResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return httpResponses;
|
||||
@@ -517,7 +510,7 @@ export class PluginInstance {
|
||||
...args,
|
||||
} as const;
|
||||
const { grpcRequest } = await this.#sendAndWaitForReply<RenderGrpcRequestResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return grpcRequest;
|
||||
@@ -530,7 +523,7 @@ export class PluginInstance {
|
||||
...args,
|
||||
} as const;
|
||||
const { httpRequest } = await this.#sendAndWaitForReply<GetHttpRequestByIdResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return httpRequest;
|
||||
@@ -541,7 +534,7 @@ export class PluginInstance {
|
||||
...args,
|
||||
} as const;
|
||||
const { httpResponse } = await this.#sendAndWaitForReply<SendHttpRequestResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return httpResponse;
|
||||
@@ -552,7 +545,7 @@ export class PluginInstance {
|
||||
...args,
|
||||
} as const;
|
||||
const { httpRequest } = await this.#sendAndWaitForReply<RenderHttpRequestResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return httpRequest;
|
||||
@@ -565,7 +558,7 @@ export class PluginInstance {
|
||||
...args,
|
||||
} as const;
|
||||
const { value } = await this.#sendAndWaitForReply<GetCookieValueResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return value;
|
||||
@@ -573,7 +566,7 @@ export class PluginInstance {
|
||||
listNames: async () => {
|
||||
const payload = { type: 'list_cookie_names_request' } as const;
|
||||
const { names } = await this.#sendAndWaitForReply<ListCookieNamesResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return names;
|
||||
@@ -587,7 +580,7 @@ export class PluginInstance {
|
||||
render: async (args) => {
|
||||
const payload = { type: 'template_render_request', ...args } as const;
|
||||
const result = await this.#sendAndWaitForReply<TemplateRenderResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return result.data as any;
|
||||
@@ -597,7 +590,7 @@ export class PluginInstance {
|
||||
get: async <T>(key: string) => {
|
||||
const payload = { type: 'get_key_value_request', key } as const;
|
||||
const result = await this.#sendAndWaitForReply<GetKeyValueResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return result.value ? (JSON.parse(result.value) as T) : undefined;
|
||||
@@ -609,17 +602,22 @@ export class PluginInstance {
|
||||
key,
|
||||
value: valueStr,
|
||||
};
|
||||
await this.#sendAndWaitForReply<GetKeyValueResponse>(event.windowContext, payload);
|
||||
await this.#sendAndWaitForReply<GetKeyValueResponse>(windowContext, payload);
|
||||
},
|
||||
delete: async (key: string) => {
|
||||
const payload = { type: 'delete_key_value_request', key } as const;
|
||||
const result = await this.#sendAndWaitForReply<DeleteKeyValueResponse>(
|
||||
event.windowContext,
|
||||
windowContext,
|
||||
payload,
|
||||
);
|
||||
return result.deleted;
|
||||
},
|
||||
},
|
||||
plugin: {
|
||||
reload: () => {
|
||||
this.#sendPayload({ type: 'none' }, { type: 'reload_response', silent: true }, null);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ async function handleIncoming(msg: string) {
|
||||
}
|
||||
|
||||
if (pluginEvent.payload.type === 'terminate_request') {
|
||||
plugin.terminate();
|
||||
await plugin.terminate();
|
||||
console.log('Terminated plugin worker', pluginEvent.pluginRefId);
|
||||
delete plugins[pluginEvent.pluginRefId];
|
||||
}
|
||||
|
||||
@@ -34,18 +34,18 @@ export async function convertToCurl(request: Partial<HttpRequest>) {
|
||||
let finalUrl = request.url || '';
|
||||
const urlParams = (request.urlParameters ?? []).filter(onlyEnabled);
|
||||
if (urlParams.length > 0) {
|
||||
// Build url
|
||||
// Build url
|
||||
const [base, hash] = finalUrl.split('#');
|
||||
const separator = base!.includes('?') ? '&' : '?';
|
||||
const queryString = urlParams
|
||||
.map(p => `${encodeURIComponent(p.name)}=${encodeURIComponent(p.value)}`)
|
||||
.map((p) => `${encodeURIComponent(p.name)}=${encodeURIComponent(p.value)}`)
|
||||
.join('&');
|
||||
finalUrl = base + separator + queryString + (hash ? `#${hash}` : '');
|
||||
}
|
||||
|
||||
|
||||
xs.push(quote(finalUrl));
|
||||
xs.push(NEWLINE);
|
||||
|
||||
|
||||
// Add headers
|
||||
for (const h of (request.headers ?? []).filter(onlyEnabled)) {
|
||||
xs.push('--header', quote(`${h.name}: ${h.value}`));
|
||||
@@ -53,7 +53,11 @@ export async function convertToCurl(request: Partial<HttpRequest>) {
|
||||
}
|
||||
|
||||
// Add form params
|
||||
if (Array.isArray(request.body?.form)) {
|
||||
const type = request.bodyType ?? 'none';
|
||||
if (
|
||||
(type === 'multipart/form-data' || type === 'application/x-www-form-urlencoded') &&
|
||||
Array.isArray(request.body?.form)
|
||||
) {
|
||||
const flag = request.bodyType === 'multipart/form-data' ? '--form' : '--data';
|
||||
for (const p of (request.body?.form ?? []).filter(onlyEnabled)) {
|
||||
if (p.file) {
|
||||
@@ -65,14 +69,14 @@ export async function convertToCurl(request: Partial<HttpRequest>) {
|
||||
}
|
||||
xs.push(NEWLINE);
|
||||
}
|
||||
} else if (typeof request.body?.query === 'string') {
|
||||
} else if (type === 'graphql' && typeof request.body?.query === 'string') {
|
||||
const body = {
|
||||
query: request.body.query || '',
|
||||
variables: maybeParseJSON(request.body.variables, undefined),
|
||||
};
|
||||
xs.push('--data', quote(JSON.stringify(body)));
|
||||
xs.push(NEWLINE);
|
||||
} else if (typeof request.body?.text === 'string') {
|
||||
} else if (type !== 'none' && typeof request.body?.text === 'string') {
|
||||
xs.push('--data', quote(request.body.text));
|
||||
xs.push(NEWLINE);
|
||||
}
|
||||
@@ -116,4 +120,4 @@ function maybeParseJSON<T>(v: string, fallback: T) {
|
||||
} catch {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('exporter-curl', () => {
|
||||
],
|
||||
}),
|
||||
).toEqual(
|
||||
[`curl 'https://yaak.app/?a=aaa&b=bbb'`].join(` \\n `),
|
||||
[`curl 'https://yaak.app?a=aaa&b=bbb'`].join(` \\n `),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -218,4 +218,16 @@ describe('exporter-curl', () => {
|
||||
}),
|
||||
).toEqual([`curl 'https://yaak.app'`, `--header 'Authorization: Bearer '`].join(` \\\n `));
|
||||
});
|
||||
});
|
||||
|
||||
test('Stale body data', async () => {
|
||||
expect(
|
||||
await convertToCurl({
|
||||
url: 'https://yaak.app',
|
||||
bodyType: 'none',
|
||||
body: {
|
||||
text: 'ignore me',
|
||||
}
|
||||
}),
|
||||
).toEqual([`curl 'https://yaak.app'`].join(` \\\n `));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -595,5 +595,112 @@ export const plugin: PluginDefinition = {
|
||||
danger: 'hsl(343,81%,75%)',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'rose-pine',
|
||||
label: 'Rosé Pine',
|
||||
dark: true,
|
||||
base: {
|
||||
surface: 'hsl(249,22%,12%)',
|
||||
text: 'hsl(245,50%,91%)',
|
||||
textSubtle: 'hsl(248,15%,61%)',
|
||||
textSubtlest: 'hsl(249,12%,47%)',
|
||||
primary: 'hsl(267,57%,78%)',
|
||||
secondary: 'hsl(249,12%,47%)',
|
||||
info: 'hsl(199,49%,60%)',
|
||||
success: 'hsl(180,43%,73%)',
|
||||
notice: 'hsl(35,88%,72%)',
|
||||
warning: 'hsl(1,74%,79%)',
|
||||
danger: 'hsl(343,76%,68%)',
|
||||
},
|
||||
components: {
|
||||
responsePane: {
|
||||
surface: 'hsl(247,23%,15%)',
|
||||
},
|
||||
sidebar: {
|
||||
surface: 'hsl(247,23%,15%)',
|
||||
},
|
||||
menu: {
|
||||
surface: 'hsl(248,21%,26%)',
|
||||
textSubtle: 'hsl(248,15%,66%)',
|
||||
textSubtlest: 'hsl(249,12%,52%)',
|
||||
border: 'hsl(248,21%,35%)',
|
||||
borderSubtle: 'hsl(248,21%,33%)',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'rose-pine-moon',
|
||||
label: 'Rosé Pine Moon',
|
||||
dark: true,
|
||||
base: {
|
||||
surface: 'hsl(246,24%,17%)',
|
||||
text: 'hsl(245,50%,91%)',
|
||||
textSubtle: 'hsl(248,15%,61%)',
|
||||
textSubtlest: 'hsl(249,12%,47%)',
|
||||
primary: 'hsl(267,57%,78%)',
|
||||
secondary: 'hsl(248,15%,61%)',
|
||||
info: 'hsl(197,48%,60%)',
|
||||
success: 'hsl(197,48%,60%)',
|
||||
notice: 'hsl(35,88%,72%)',
|
||||
warning: 'hsl(2,66%,75%)',
|
||||
danger: 'hsl(343,76%,68%)',
|
||||
},
|
||||
components: {
|
||||
responsePane: {
|
||||
surface: 'hsl(247,24%,20%)',
|
||||
},
|
||||
sidebar: {
|
||||
surface: 'hsl(247,24%,20%)',
|
||||
},
|
||||
menu: {
|
||||
surface: 'hsl(248,21%,26%)',
|
||||
textSubtle: 'hsl(248,15%,61%)',
|
||||
textSubtlest: 'hsl(249,12%,55%)',
|
||||
border: 'hsl(248,21%,35%)',
|
||||
borderSubtle: 'hsl(248,21%,31%)',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'rose-pine-dawn',
|
||||
label: 'Rosé Pine Dawn',
|
||||
dark: false,
|
||||
base: {
|
||||
surface: 'hsl(32,57%,95%)',
|
||||
border: 'hsl(10,9%,86%)',
|
||||
surfaceHighlight: 'hsl(25,35%,93%)',
|
||||
text: 'hsl(248,19%,40%)',
|
||||
textSubtle: 'hsl(248,12%,52%)',
|
||||
textSubtlest: 'hsl(257,9%,61%)',
|
||||
primary: 'hsl(271,27%,56%)',
|
||||
secondary: 'hsl(249,12%,47%)',
|
||||
info: 'hsl(197,52%,36%)',
|
||||
success: 'hsl(188,31%,45%)',
|
||||
notice: 'hsl(34,64%,49%)',
|
||||
warning: 'hsl(2,47%,64%)',
|
||||
danger: 'hsl(343,35%,55%)',
|
||||
},
|
||||
components: {
|
||||
responsePane: {
|
||||
border: 'hsl(20,12%,90%)',
|
||||
},
|
||||
sidebar: {
|
||||
border: 'hsl(20,12%,90%)',
|
||||
},
|
||||
appHeader: {
|
||||
border: 'hsl(20,12%,90%)',
|
||||
},
|
||||
input: {
|
||||
border: 'hsl(10,9%,86%)',
|
||||
},
|
||||
dialog: {
|
||||
border: 'hsl(20,12%,90%)',
|
||||
},
|
||||
menu: {
|
||||
surface: 'hsl(28,40%,92%)',
|
||||
border: 'hsl(10,9%,86%)',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ log = "0.4.27"
|
||||
md5 = "0.8.0"
|
||||
mime_guess = "2.0.5"
|
||||
rand = "0.9.0"
|
||||
reqwest = { workspace = true, features = ["multipart", "cookies", "gzip", "brotli", "deflate", "json", "rustls-tls-manual-roots-no-provider", "socks"] }
|
||||
reqwest = { workspace = true, features = ["multipart", "cookies", "gzip", "brotli", "deflate", "json", "rustls-tls-manual-roots-no-provider", "socks", "http2"] }
|
||||
reqwest_cookie_store = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true, features = ["raw_value"] }
|
||||
|
||||
@@ -111,7 +111,7 @@ pub async fn send_http_request<R: Runtime>(
|
||||
.referer(false)
|
||||
.tls_info(true);
|
||||
|
||||
let tls_config = yaak_http::tls::get_config(workspace.setting_validate_certificates);
|
||||
let tls_config = yaak_http::tls::get_config(workspace.setting_validate_certificates, true);
|
||||
client_builder = client_builder.use_preconfigured_tls(tls_config);
|
||||
|
||||
match settings.proxy {
|
||||
|
||||
@@ -150,7 +150,7 @@ pub(crate) async fn handle_plugin_event<R: Runtime>(
|
||||
Box::pin(handle_plugin_event(app_handle, &toast_event, plugin_handle)).await;
|
||||
None
|
||||
}
|
||||
InternalEventPayload::ReloadResponse(r) => {
|
||||
InternalEventPayload::ReloadResponse(req) => {
|
||||
let plugins = app_handle.db().list_plugins().unwrap();
|
||||
for plugin in plugins {
|
||||
if plugin.directory != plugin_handle.dir {
|
||||
@@ -163,16 +163,20 @@ pub(crate) async fn handle_plugin_event<R: Runtime>(
|
||||
};
|
||||
app_handle.db().upsert_plugin(&new_plugin, &UpdateSource::Plugin).unwrap();
|
||||
}
|
||||
let toast_event = plugin_handle.build_event_to_send(
|
||||
&window_context,
|
||||
&InternalEventPayload::ShowToastRequest(ShowToastRequest {
|
||||
message: format!("Reloaded plugin {}@{}", r.name, r.version),
|
||||
icon: Some(Icon::Info),
|
||||
..Default::default()
|
||||
}),
|
||||
None,
|
||||
);
|
||||
Box::pin(handle_plugin_event(app_handle, &toast_event, plugin_handle)).await;
|
||||
|
||||
if !req.silent {
|
||||
let info = plugin_handle.info();
|
||||
let toast_event = plugin_handle.build_event_to_send(
|
||||
&window_context,
|
||||
&InternalEventPayload::ShowToastRequest(ShowToastRequest {
|
||||
message: format!("Reloaded plugin {}@{}", info.name, info.version),
|
||||
icon: Some(Icon::Info),
|
||||
..Default::default()
|
||||
}),
|
||||
None,
|
||||
);
|
||||
Box::pin(handle_plugin_event(app_handle, &toast_event, plugin_handle)).await;
|
||||
}
|
||||
None
|
||||
}
|
||||
InternalEventPayload::SendHttpRequestRequest(req) => {
|
||||
|
||||
@@ -66,6 +66,14 @@ impl YaakUpdater {
|
||||
mode: UpdateMode,
|
||||
update_trigger: UpdateTrigger,
|
||||
) -> Result<bool> {
|
||||
// Only AppImage supports updates on Linux, so skip if it's not
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if std::env::var("APPIMAGE").is_err() {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
let settings = window.db().get_settings();
|
||||
let update_key = format!("{:x}", md5::compute(settings.id));
|
||||
self.last_update_check = SystemTime::now();
|
||||
|
||||
@@ -4,8 +4,11 @@ use hyper_util::client::legacy::Client;
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
use tonic::body::BoxBody;
|
||||
|
||||
// I think ALPN breaks this because we're specifying http2_only
|
||||
const WITH_ALPN: bool = false;
|
||||
|
||||
pub(crate) fn get_transport(validate_certificates: bool) -> Client<HttpsConnector<HttpConnector>, BoxBody> {
|
||||
let tls_config = yaak_http::tls::get_config(validate_certificates);
|
||||
let tls_config = yaak_http::tls::get_config(validate_certificates, WITH_ALPN);
|
||||
|
||||
let mut http = HttpConnector::new();
|
||||
http.enforce_http(false);
|
||||
|
||||
@@ -5,12 +5,12 @@ use rustls::{ClientConfig, DigitallySignedStruct, SignatureScheme};
|
||||
use rustls_platform_verifier::BuilderVerifierExt;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn get_config(validate_certificates: bool) -> ClientConfig {
|
||||
pub fn get_config(validate_certificates: bool, with_alpn: bool) -> ClientConfig {
|
||||
let arc_crypto_provider = Arc::new(ring::default_provider());
|
||||
let config_builder = ClientConfig::builder_with_provider(arc_crypto_provider)
|
||||
.with_safe_default_protocol_versions()
|
||||
.unwrap();
|
||||
if validate_certificates {
|
||||
let mut client = if validate_certificates {
|
||||
// Use platform-native verifier to validate certificates
|
||||
config_builder.with_platform_verifier().unwrap().with_no_client_auth()
|
||||
} else {
|
||||
@@ -18,7 +18,13 @@ pub fn get_config(validate_certificates: bool) -> ClientConfig {
|
||||
.dangerous()
|
||||
.with_custom_certificate_verifier(Arc::new(NoVerifier))
|
||||
.with_no_client_auth()
|
||||
};
|
||||
|
||||
if with_alpn {
|
||||
client.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
||||
}
|
||||
|
||||
client
|
||||
}
|
||||
|
||||
// Copied from reqwest: https://github.com/seanmonstar/reqwest/blob/595c80b1fbcdab73ac2ae93e4edc3406f453df25/src/tls.rs#L608
|
||||
|
||||
@@ -4,8 +4,6 @@ import type { JsonValue } from "./serde_json/JsonValue.js";
|
||||
|
||||
export type BootRequest = { dir: string, watch: boolean, };
|
||||
|
||||
export type BootResponse = { name: string, version: string, };
|
||||
|
||||
export type CallGrpcRequestActionArgs = { grpcRequest: GrpcRequest, protoFiles: Array<string>, };
|
||||
|
||||
export type CallGrpcRequestActionRequest = { index: number, pluginRefId: string, args: CallGrpcRequestActionArgs, };
|
||||
@@ -387,7 +385,7 @@ export type ImportResponse = { resources: ImportResources, };
|
||||
|
||||
export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: PluginWindowContext, payload: InternalEventPayload, };
|
||||
|
||||
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & BootResponse | { "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": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_grpc_request_actions_request" } & EmptyPayload | { "type": "get_grpc_request_actions_response" } & GetGrpcRequestActionsResponse | { "type": "call_grpc_request_action_request" } & CallGrpcRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "render_grpc_request_request" } & RenderGrpcRequestRequest | { "type": "render_grpc_request_response" } & RenderGrpcRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "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": "get_themes_request" } & GetThemesRequest | { "type": "get_themes_response" } & GetThemesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse;
|
||||
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } | { "type": "reload_response" } & ReloadResponse | { "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": "list_cookie_names_request" } & ListCookieNamesRequest | { "type": "list_cookie_names_response" } & ListCookieNamesResponse | { "type": "get_cookie_value_request" } & GetCookieValueRequest | { "type": "get_cookie_value_response" } & GetCookieValueResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_grpc_request_actions_request" } & EmptyPayload | { "type": "get_grpc_request_actions_response" } & GetGrpcRequestActionsResponse | { "type": "call_grpc_request_action_request" } & CallGrpcRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "render_grpc_request_request" } & RenderGrpcRequestRequest | { "type": "render_grpc_request_response" } & RenderGrpcRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "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": "get_themes_request" } & GetThemesRequest | { "type": "get_themes_response" } & GetThemesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse;
|
||||
|
||||
export type JsonPrimitive = string | number | boolean | null;
|
||||
|
||||
@@ -419,6 +417,8 @@ required?: boolean, };
|
||||
|
||||
export type PromptTextResponse = { value: string | null, };
|
||||
|
||||
export type ReloadResponse = { silent: boolean, };
|
||||
|
||||
export type RenderGrpcRequestRequest = { grpcRequest: GrpcRequest, purpose: RenderPurpose, };
|
||||
|
||||
export type RenderGrpcRequestResponse = { grpcRequest: GrpcRequest, };
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
use tauri::{Runtime, WebviewWindow};
|
||||
use ts_rs::TS;
|
||||
@@ -64,10 +65,9 @@ impl PluginWindowContext {
|
||||
#[ts(export, export_to = "gen_events.ts")]
|
||||
pub enum InternalEventPayload {
|
||||
BootRequest(BootRequest),
|
||||
BootResponse(BootResponse),
|
||||
BootResponse,
|
||||
|
||||
ReloadRequest(EmptyPayload),
|
||||
ReloadResponse(BootResponse),
|
||||
ReloadResponse(ReloadResponse),
|
||||
|
||||
TerminateRequest,
|
||||
TerminateResponse,
|
||||
@@ -161,6 +161,17 @@ pub enum InternalEventPayload {
|
||||
ErrorResponse(ErrorResponse),
|
||||
}
|
||||
|
||||
impl InternalEventPayload {
|
||||
pub fn type_name(&self) -> String {
|
||||
if let Ok(Value::Object(map)) = serde_json::to_value(self) {
|
||||
map.get("type").map(|s| s.as_str().unwrap_or("unknown").to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.unwrap_or("invalid_event".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default)]
|
||||
#[ts(export, type = "{}", export_to = "gen_events.ts")]
|
||||
@@ -184,9 +195,8 @@ pub struct BootRequest {
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
#[serde(default, rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "gen_events.ts")]
|
||||
pub struct BootResponse {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub struct ReloadResponse {
|
||||
pub silent: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
|
||||
@@ -30,6 +30,7 @@ use tauri::path::BaseDirectory;
|
||||
use tauri::{AppHandle, Manager, Runtime, WebviewWindow, is_dev};
|
||||
use tokio::fs::read_dir;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::sync::mpsc::error::TrySendError;
|
||||
use tokio::sync::{Mutex, mpsc};
|
||||
use tokio::time::{Instant, timeout};
|
||||
use yaak_models::models::Environment;
|
||||
@@ -91,7 +92,14 @@ impl PluginManager {
|
||||
while let Some(event) = events_rx.recv().await {
|
||||
for (tx_id, tx) in subscribers.lock().await.iter_mut() {
|
||||
if let Err(e) = tx.try_send(event.clone()) {
|
||||
warn!("Failed to send event to subscriber {tx_id} {e:?}");
|
||||
match e {
|
||||
TrySendError::Full(e) => {
|
||||
error!("Failed to send event to full subscriber {tx_id} {e:?}");
|
||||
}
|
||||
TrySendError::Closed(_) => {
|
||||
// Subscriber already unsubscribed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -197,7 +205,12 @@ impl PluginManager {
|
||||
plugin: &PluginHandle,
|
||||
) -> Result<()> {
|
||||
// Terminate the plugin
|
||||
plugin.terminate(window_context).await?;
|
||||
self.send_to_plugin_and_wait(
|
||||
window_context,
|
||||
plugin,
|
||||
&InternalEventPayload::TerminateRequest,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Remove the plugin from the list
|
||||
let mut plugins = self.plugins.lock().await;
|
||||
@@ -240,17 +253,14 @@ impl PluginManager {
|
||||
)
|
||||
.await??;
|
||||
|
||||
let mut plugins = self.plugins.lock().await;
|
||||
if !matches!(event.payload, InternalEventPayload::BootResponse) {
|
||||
return Err(UnknownEventErr);
|
||||
}
|
||||
|
||||
// Remove the existing plugin (if exists) before adding this one
|
||||
let mut plugins = self.plugins.lock().await;
|
||||
plugins.retain(|p| p.dir != dir);
|
||||
plugins.push(plugin_handle.clone());
|
||||
|
||||
let _ = match event.payload {
|
||||
InternalEventPayload::BootResponse(resp) => resp,
|
||||
_ => return Err(UnknownEventErr),
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -363,7 +373,7 @@ impl PluginManager {
|
||||
payload: &InternalEventPayload,
|
||||
plugins: Vec<PluginHandle>,
|
||||
) -> Result<Vec<InternalEvent>> {
|
||||
let label = format!("wait[{}]", plugins.len());
|
||||
let label = format!("wait[{}.{}]", plugins.len(), payload.type_name());
|
||||
let (rx_id, mut rx) = self.subscribe(label.as_str()).await;
|
||||
|
||||
// 1. Build the events with IDs and everything
|
||||
@@ -411,7 +421,7 @@ impl PluginManager {
|
||||
let events = sub_events_fut.await.expect("Thread didn't succeed");
|
||||
|
||||
// 5. Unsubscribe
|
||||
self.unsubscribe(rx_id.as_str()).await;
|
||||
self.unsubscribe(&rx_id).await;
|
||||
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ use crate::error::Result;
|
||||
use crate::events::{InternalEvent, InternalEventPayload, PluginWindowContext};
|
||||
use crate::plugin_meta::{PluginMetadata, get_plugin_meta};
|
||||
use crate::util::gen_id;
|
||||
use log::info;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{Mutex, mpsc};
|
||||
@@ -58,13 +57,6 @@ impl PluginHandle {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn terminate(&self, window_context: &PluginWindowContext) -> Result<()> {
|
||||
info!("Terminating plugin {}", self.dir);
|
||||
let event =
|
||||
self.build_event_to_send(window_context, &InternalEventPayload::TerminateRequest, None);
|
||||
self.send(&event).await
|
||||
}
|
||||
|
||||
pub async fn send(&self, event: &InternalEvent) -> Result<()> {
|
||||
self.to_plugin_tx.lock().await.send(event.to_owned()).await?;
|
||||
Ok(())
|
||||
|
||||
@@ -7,16 +7,19 @@ use tokio_tungstenite::tungstenite::handshake::client::Response;
|
||||
use tokio_tungstenite::tungstenite::http::HeaderValue;
|
||||
use tokio_tungstenite::tungstenite::protocol::WebSocketConfig;
|
||||
use tokio_tungstenite::{
|
||||
connect_async_tls_with_config, Connector, MaybeTlsStream, WebSocketStream,
|
||||
Connector, MaybeTlsStream, WebSocketStream, connect_async_tls_with_config,
|
||||
};
|
||||
|
||||
// Enabling ALPN breaks websocket requests
|
||||
const WITH_ALPN: bool = false;
|
||||
|
||||
pub(crate) async fn ws_connect(
|
||||
url: &str,
|
||||
headers: HeaderMap<HeaderValue>,
|
||||
validate_certificates: bool,
|
||||
) -> crate::error::Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response)> {
|
||||
info!("Connecting to WS {url}");
|
||||
let tls_config = yaak_http::tls::get_config(validate_certificates);
|
||||
let tls_config = yaak_http::tls::get_config(validate_certificates, WITH_ALPN);
|
||||
|
||||
let mut req = url.into_client_request()?;
|
||||
let req_headers = req.headers_mut();
|
||||
@@ -34,4 +37,4 @@ pub(crate) async fn ws_connect(
|
||||
)
|
||||
.await?;
|
||||
Ok((stream, response))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
||||
return (
|
||||
<VStack className="flex-col-reverse mb-3" space={3}>
|
||||
{/* Buttons on top so they get focus first */}
|
||||
<HStack space={2} justifyContent="start" className="flex-row-reverse">
|
||||
<HStack space={2} justifyContent="start" className="flex-row-reverse mt-3">
|
||||
<Button
|
||||
color="primary"
|
||||
variant="border"
|
||||
@@ -135,9 +135,7 @@ function GrpcProtoSelectionDialogWithRequest({ request }: Props & { request: Grp
|
||||
<table className="w-full divide-y divide-surface-highlight">
|
||||
<thead>
|
||||
<tr>
|
||||
<th />
|
||||
<th className="text-text-subtlest">Added File Paths</th>
|
||||
<th />
|
||||
<th className="text-text-subtlest" colSpan={3}>Added File Paths</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-surface-highlight">
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import type { CSSProperties } from 'react';
|
||||
import ReactMarkdown, { type Components } from 'react-markdown';
|
||||
import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import { ErrorBoundary } from './ErrorBoundary';
|
||||
import { Prose } from './Prose';
|
||||
@@ -22,6 +24,57 @@ export function Markdown({ children, className }: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
const prismTheme = {
|
||||
'pre[class*="language-"]': {
|
||||
// Needs to be here, so the lib doesn't add its own
|
||||
},
|
||||
|
||||
// Syntax tokens
|
||||
comment: { color: 'var(--textSubtle)' },
|
||||
prolog: { color: 'var(--textSubtle)' },
|
||||
doctype: { color: 'var(--textSubtle)' },
|
||||
cdata: { color: 'var(--textSubtle)' },
|
||||
|
||||
punctuation: { color: 'var(--textSubtle)' },
|
||||
|
||||
property: { color: 'var(--primary)' },
|
||||
'attr-name': { color: 'var(--primary)' },
|
||||
|
||||
string: { color: 'var(--notice)' },
|
||||
char: { color: 'var(--notice)' },
|
||||
|
||||
number: { color: 'var(--info)' },
|
||||
constant: { color: 'var(--info)' },
|
||||
symbol: { color: 'var(--info)' },
|
||||
|
||||
boolean: { color: 'var(--warning)' },
|
||||
'attr-value': { color: 'var(--warning)' },
|
||||
|
||||
variable: { color: 'var(--success)' },
|
||||
|
||||
tag: { color: 'var(--info)' },
|
||||
operator: { color: 'var(--danger)' },
|
||||
keyword: { color: 'var(--danger)' },
|
||||
function: { color: 'var(--success)' },
|
||||
'class-name': { color: 'var(--primary)' },
|
||||
builtin: { color: 'var(--danger)' },
|
||||
selector: { color: 'var(--danger)' },
|
||||
inserted: { color: 'var(--success)' },
|
||||
deleted: { color: 'var(--danger)' },
|
||||
regex: { color: 'var(--warning)' },
|
||||
|
||||
important: { color: 'var(--danger)', fontWeight: 'bold' },
|
||||
italic: { fontStyle: 'italic' },
|
||||
bold: { fontWeight: 'bold' },
|
||||
entity: { cursor: 'help' },
|
||||
};
|
||||
|
||||
const lineStyle: CSSProperties = {
|
||||
paddingRight: '1.5em',
|
||||
paddingLeft: '0',
|
||||
opacity: 0.5,
|
||||
};
|
||||
|
||||
const markdownComponents: Partial<Components> = {
|
||||
// Ensure links open in external browser by adding target="_blank"
|
||||
a: ({ href, children, ...rest }) => {
|
||||
@@ -34,4 +87,27 @@ const markdownComponents: Partial<Components> = {
|
||||
</a>
|
||||
);
|
||||
},
|
||||
code(props) {
|
||||
const { children, className, ref, ...extraProps } = props;
|
||||
delete extraProps.node;
|
||||
|
||||
const match = /language-(\w+)/.exec(className || '');
|
||||
return match ? (
|
||||
<SyntaxHighlighter
|
||||
{...extraProps}
|
||||
CodeTag="code"
|
||||
showLineNumbers
|
||||
PreTag="div"
|
||||
lineNumberStyle={lineStyle}
|
||||
language={match[1]}
|
||||
style={prismTheme}
|
||||
>
|
||||
{String(children).replace(/\n$/, '')}
|
||||
</SyntaxHighlighter>
|
||||
) : (
|
||||
<code {...extraProps} ref={ref} className={className}>
|
||||
{children}
|
||||
</code>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -46,8 +46,8 @@ export function MarkdownEditor({
|
||||
defaultValue.length === 0 ? (
|
||||
<p className="text-text-subtlest">No description</p>
|
||||
) : (
|
||||
<div className="overflow-y-auto max-h-full [&_*]:cursor-auto [&_*]:select-auto">
|
||||
<Markdown className="max-w-lg">{defaultValue}</Markdown>
|
||||
<div className="pr-1.5 overflow-y-auto max-h-full [&_*]:cursor-auto [&_*]:select-auto">
|
||||
<Markdown className="max-w-lg select-auto cursor-auto">{defaultValue}</Markdown>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -59,6 +59,7 @@ export function MarkdownEditor({
|
||||
className={classNames(
|
||||
'group/markdown',
|
||||
'relative w-full h-full pt-1.5 rounded-md gap-x-1.5',
|
||||
'min-w-0', // Not sure why this is needed
|
||||
className,
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -118,9 +118,10 @@
|
||||
@apply bg-surface-highlight text-text !important;
|
||||
@apply px-4 py-3 rounded-md;
|
||||
@apply overflow-auto whitespace-pre;
|
||||
@apply text-editor font-mono;
|
||||
|
||||
code {
|
||||
@apply text-xs font-normal;
|
||||
@apply font-normal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,14 +34,14 @@ export const RecentHttpResponsesDropdown = function ResponsePane({
|
||||
label: 'Save to File',
|
||||
onSelect: saveResponse.mutate,
|
||||
leftSlot: <Icon icon="save" />,
|
||||
hidden: responses.length === 0,
|
||||
hidden: responses.length === 0 || !!activeResponse.error,
|
||||
disabled: activeResponse.state !== 'closed' && activeResponse.status >= 100,
|
||||
},
|
||||
{
|
||||
label: 'Copy Body',
|
||||
onSelect: copyResponse.mutate,
|
||||
leftSlot: <Icon icon="copy" />,
|
||||
hidden: responses.length === 0,
|
||||
hidden: responses.length === 0 || !!activeResponse.error,
|
||||
disabled: activeResponse.state !== 'closed' && activeResponse.status >= 100,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -436,7 +436,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle' | 'items'
|
||||
const heightBelow = docRect.height - triggerShape.bottom;
|
||||
const horizontalSpaceRemaining = docRect.width - triggerShape.left;
|
||||
const top = triggerShape.bottom;
|
||||
const onRight = horizontalSpaceRemaining < 200;
|
||||
const onRight = horizontalSpaceRemaining < 300;
|
||||
const upsideDown = heightBelow < heightAbove && heightBelow < items.length * 25 + 20 + 200;
|
||||
const triggerWidth = triggerShape.right - triggerShape.left;
|
||||
return {
|
||||
|
||||
@@ -21,9 +21,10 @@ export function WebPageViewer({ response }: Props) {
|
||||
<div className="h-full pb-3">
|
||||
<iframe
|
||||
key={body ? 'has-body' : 'no-body'}
|
||||
title="Response preview"
|
||||
title="Yaak response preview"
|
||||
srcDoc={contentForIframe}
|
||||
sandbox="allow-scripts allow-same-origin"
|
||||
sandbox="allow-scripts allow-forms"
|
||||
referrerPolicy="no-referrer"
|
||||
className="h-full w-full rounded border border-border-subtle"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -344,7 +344,7 @@ export function Sidebar({ className }: Props) {
|
||||
'h-full grid grid-rows-[minmax(0,1fr)_auto]',
|
||||
)}
|
||||
>
|
||||
<div className="pb-3 overflow-x-visible overflow-y-scroll pt-2">
|
||||
<div className="pb-3 overflow-x-visible overflow-y-scroll pt-2 pr-0.5">
|
||||
<ContextMenu
|
||||
triggerPosition={showMainContextMenu}
|
||||
items={mainContextMenuItems}
|
||||
|
||||
@@ -108,12 +108,11 @@ export function useIntrospectGraphQL(
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const schema = buildClientSchema(JSON.parse(introspection.data.content).data);
|
||||
setSchema(schema);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
setError('message' in e ? e.message : String(e));
|
||||
const parseResult = tryParseIntrospectionToSchema(introspection.data.content);
|
||||
if ('error' in parseResult) {
|
||||
setError(parseResult.error);
|
||||
} else {
|
||||
setSchema(parseResult.schema);
|
||||
}
|
||||
}, [introspection.data?.content]);
|
||||
|
||||
@@ -135,7 +134,26 @@ export function useCurrentGraphQLSchema(request: HttpRequest) {
|
||||
return useMemo(() => {
|
||||
if (result.data == null) return null;
|
||||
if (result.data.content == null || result.data.content === '') return null;
|
||||
const schema = buildClientSchema(JSON.parse(result.data.content).data);
|
||||
return schema;
|
||||
const r = tryParseIntrospectionToSchema(result.data.content);
|
||||
return 'error' in r ? null : r.schema;
|
||||
}, [result.data]);
|
||||
}
|
||||
|
||||
function tryParseIntrospectionToSchema(
|
||||
content: string,
|
||||
): { schema: GraphQLSchema } | { error: string } {
|
||||
let parsedResponse;
|
||||
try {
|
||||
parsedResponse = JSON.parse(content).data;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
return { error: String('message' in e ? e.message : e) };
|
||||
}
|
||||
|
||||
try {
|
||||
return { schema: buildClientSchema(parsedResponse, {}) };
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
return { error: String('message' in e ? e.message : e) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export function useResolvedTheme() {
|
||||
settings.themeLight,
|
||||
settings.themeDark,
|
||||
);
|
||||
return { ...data, ...await getThemes() };
|
||||
return { ...data, ...(await getThemes()) };
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"react-dom": "^19.1.0",
|
||||
"react-markdown": "^10.1.0",
|
||||
"react-pdf": "^10.0.1",
|
||||
"react-syntax-highlighter": "^15.6.1",
|
||||
"react-use": "^17.6.0",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
@@ -75,6 +76,7 @@
|
||||
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
|
||||
"@tanstack/router-plugin": "^1.127.5",
|
||||
"@types/node": "^24.0.13",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/papaparse": "^5.3.16",
|
||||
"@types/parse-color": "^1.0.3",
|
||||
"@types/react": "^19.1.8",
|
||||
|
||||
Reference in New Issue
Block a user