Compare commits

...

35 Commits

Author SHA1 Message Date
Gregory Schier
673f2920a1 Fix gRPC request creation 2024-08-09 14:37:43 -07:00
Gregory Schier
e4ba408534 Correctly wrap small dialog text 2024-08-09 14:28:20 -07:00
Gregory Schier
96ae1d467b GraphQL variables now reset if entire thing deleted 2024-08-09 14:05:38 -07:00
Gregory Schier
48c239b7dc Fix Windows paths for new plugin runtime 2024-08-09 12:43:56 -07:00
Gregory Schier
331f1eb9b9 Better Windows pathing 2024-08-09 11:52:18 -07:00
Gregory Schier
1e9f10a99f UNC paths for plugins 2024-08-09 11:33:54 -07:00
Gregory Schier
6eb2cbd582 Fix up DB creation and migration 2024-08-09 11:20:04 -07:00
Gregory Schier
d9a7dba2e2 Vendor in build script 2024-08-09 08:51:21 -07:00
Gregory Schier
d885e6cb0a Fix body change setting headers/method 2024-08-09 08:33:49 -07:00
Gregory Schier
4cafc30f21 Remove problematic tests from release.yml 2024-08-09 08:33:01 -07:00
Gregory Schier
598a051bf8 Fix release script 2024-08-09 07:53:33 -07:00
Gregory Schier
965b579eb7 Switch to proper log plugin 2024-08-09 07:49:48 -07:00
Gregory Schier
d3a6125488 Fix release script 2024-08-09 07:42:39 -07:00
Gregory Schier
7f3492a1f0 Fix variable regex 2024-08-09 07:41:52 -07:00
Gregory Schier
c3970ba756 Run build before test as well 2024-08-09 07:29:48 -07:00
Gregory Schier
6f0a0a55a4 Fix 2024-08-09 07:12:32 -07:00
Gregory Schier
30fe3ee5cb Fix lint errors 2024-08-09 06:58:36 -07:00
Gregory Schier
1f637c583a Run vendor as separate script 2024-08-09 06:49:18 -07:00
Gregory Schier
3050995fed Fix xpath filtering 2024-08-08 22:54:15 -07:00
Gregory Schier
8081c86ec6 Better TS type generation 2024-08-08 22:07:05 -07:00
Gregory Schier
ed300dd320 Plugin runtime v2 (#62) 2024-08-08 21:30:59 -07:00
Gregory Schier
989b5a8058 Model and DB refactor (#61)
- [x] Move from `sqlx` to `rusqlite`
- [x] Generate TS types from Rust models
2024-08-05 07:58:20 -07:00
Gregory Schier
71013fd701 Use @yaakapp/api in models 2024-08-01 15:14:33 -07:00
Gregory Schier
76dd4380ce Updated plugin APIs 2024-08-01 07:01:57 -07:00
Gregory Schier
a643713139 Start of plugin types refactor 2024-07-31 14:56:55 -07:00
Gregory Schier
1cb86bc1b7 More flexible placeholder match 2024-07-31 07:42:18 -07:00
Gregory Schier
cc9bd2bc70 Template function return Result 2024-07-31 07:32:37 -07:00
Gregory Schier
90bf96c7c1 Apply forceUpdateKey to bulk pair editor 2024-07-30 15:50:29 -07:00
Gregory Schier
4e4c93c34e Always enable pairs from bulk editor 2024-07-30 15:35:06 -07:00
Gregory Schier
c2ce446692 Add rename/delete/send to cmd+k 2024-07-30 15:10:24 -07:00
Gregory Schier
d1a2c9622d Fix hotkey state messing up on Enter->submit 2024-07-30 15:10:08 -07:00
Gregory Schier
ecd8b93bd1 Add timestamp() to template fns 2024-07-30 14:04:33 -07:00
Gregory Schier
dd032a9e4d Fix fold gutter icon direction 2024-07-30 13:58:30 -07:00
Gregory Schier
f350f3b5f4 Named arguments in templating 2024-07-30 08:02:10 -07:00
Gregory Schier
45cb1ef0fe Tweak release things 2024-07-29 14:38:57 -07:00
264 changed files with 11194 additions and 11082 deletions

View File

@@ -12,7 +12,13 @@ module.exports = {
parserOptions: {
project: ["./tsconfig.json"]
},
ignorePatterns: ["scripts/**/*", "plugin-runtime/**/*", "src-tauri/**/*", "plugins/**/*"],
ignorePatterns: [
"scripts/**/*",
"plugin-runtime/**/*",
"plugin-runtime-types/**/*",
"src-tauri/**/*",
"plugins/**/*",
],
settings: {
react: {
version: "detect"

View File

@@ -114,7 +114,7 @@ jobs:
with:
tagName: 'v__VERSION__'
releaseName: 'Release __VERSION__'
releaseBody: 'https://yaak.app/changelog/__VERSION__'
releaseBody: 'https://yaak.app/blog/__VERSION__'
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Yaak App</title>
<script src="http://localhost:8097"></script>
<!-- <script src="http://localhost:8097"></script>-->
<!-- Certain elements like webview (and maybe <select>?) will use background
color depending on document background color-->

201
package-lock.json generated
View File

@@ -20,12 +20,14 @@
"@react-hook/resize-observer": "^1.2.6",
"@tailwindcss/container-queries": "^0.1.0",
"@tanstack/react-query": "^5.45.1",
"@tauri-apps/api": "^2.0.0-beta.15",
"@tauri-apps/plugin-clipboard-manager": "^2.1.0-beta.5",
"@tauri-apps/plugin-dialog": "^2.0.0-beta.7",
"@tauri-apps/plugin-fs": "^2.0.0-beta.7",
"@tauri-apps/plugin-os": "^2.0.0-beta.7",
"@tauri-apps/plugin-shell": "^2.0.0-beta.8",
"@tauri-apps/api": "^2.0.0-rc.0",
"@tauri-apps/plugin-clipboard-manager": "^2.0.0-rc.0",
"@tauri-apps/plugin-dialog": "^2.0.0-rc.0",
"@tauri-apps/plugin-fs": "^2.0.0-rc.0",
"@tauri-apps/plugin-log": "^2.0.0-rc.0",
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
"@yaakapp/api": "^0.1.4",
"buffer": "^6.0.3",
"classnames": "^2.3.2",
"cm6-graphql": "^0.0.9",
@@ -49,14 +51,13 @@
"react-router-dom": "^6.8.1",
"react-use": "^17.4.0",
"slugify": "^1.6.6",
"tauri-plugin-log-api": "github:tauri-apps/tauri-plugin-log#v2",
"uuid": "^9.0.0",
"xml-formatter": "^3.6.2"
},
"devDependencies": {
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tanstack/react-query-devtools": "^5.45.1",
"@tauri-apps/cli": "^2.0.0-beta.22",
"@tauri-apps/cli": "^2.0.0-rc.2",
"@types/node": "^18.7.10",
"@types/papaparse": "^5.3.7",
"@types/parse-color": "^1.0.1",
@@ -2342,9 +2343,9 @@
}
},
"node_modules/@tauri-apps/api": {
"version": "2.0.0-beta.15",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-beta.15.tgz",
"integrity": "sha512-H9w6iISmR+NvH4XuyCZB4zDN10tf9RFt6i/9JHEjaRhAowdAaJ+oiXq/3kedizNClHMtbTQ5j0oqDVPkZDAI8g==",
"version": "2.0.0-rc.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-rc.0.tgz",
"integrity": "sha512-v454Qs3REHc3Za59U+/eSmBsdmF+3NE5+76+lFDaitVqN4ZglDHENDaMARYKGJVZuxiSkzyqG0SeG7lLQjVkPA==",
"engines": {
"node": ">= 18.18",
"npm": ">= 6.6.0",
@@ -2356,9 +2357,9 @@
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-beta.22.tgz",
"integrity": "sha512-OAuiDdSRKxNmr/dseQKKMoZZxIhQ6aAxmXJctGYJxCnkd62tQ8xeq87roVXGNS5Qkuv7WpySAyR0ntiMjvNLUA==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.0.0-rc.3.tgz",
"integrity": "sha512-iNF95pieBmverl1EmQyqh+fhcIClS544fN5Ex5lAbYLTiHZ/gm3lOfVBhF6NPaKd/sfLuy7K1tfDXlHztBfANw==",
"dev": true,
"bin": {
"tauri": "tauri.js"
@@ -2371,22 +2372,22 @@
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.0.0-beta.22",
"@tauri-apps/cli-darwin-x64": "2.0.0-beta.22",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-beta.22",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-beta.22",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-beta.22",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-beta.22",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-beta.22",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-beta.22",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-beta.22",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-beta.22"
"@tauri-apps/cli-darwin-arm64": "2.0.0-rc.3",
"@tauri-apps/cli-darwin-x64": "2.0.0-rc.3",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.0.0-rc.3",
"@tauri-apps/cli-linux-arm64-gnu": "2.0.0-rc.3",
"@tauri-apps/cli-linux-arm64-musl": "2.0.0-rc.3",
"@tauri-apps/cli-linux-x64-gnu": "2.0.0-rc.3",
"@tauri-apps/cli-linux-x64-musl": "2.0.0-rc.3",
"@tauri-apps/cli-win32-arm64-msvc": "2.0.0-rc.3",
"@tauri-apps/cli-win32-ia32-msvc": "2.0.0-rc.3",
"@tauri-apps/cli-win32-x64-msvc": "2.0.0-rc.3"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-beta.22.tgz",
"integrity": "sha512-Ofhythvg1Ks2IM87WUYNtgFzm21aU1Zn+8QP81lJy9Y7ZGMxP8FYfqeHz6GIWKI+CYf6I77HA8LHkT9pyE5PYg==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.0.0-rc.3.tgz",
"integrity": "sha512-szYCSr/ChbCF+S6Wnr15TYpI2cZR07d+AQOiFGuScP0preM8Pbsk/sb0hfLwqzepjVFFNVWQba9sG7FEW2Y2XA==",
"cpu": [
"arm64"
],
@@ -2400,9 +2401,9 @@
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-beta.22.tgz",
"integrity": "sha512-/lWIixo7WgmMUqcxlPT7Ojlkl6qbVlNDwUZ+9DtTpoWnaaBxv/YpSe1k62vDWEC7l0apFY+Fz7cRONN2wglFyQ==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.0.0-rc.3.tgz",
"integrity": "sha512-BJv6EJOY1DJbRzVtfg8CcBAlnS5OjhBAc5YKjh4BT7EyOcop8HStBSxhL6yjWrUP7eLR1iIsW/uSehVJwzYIdQ==",
"cpu": [
"x64"
],
@@ -2416,9 +2417,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-beta.22.tgz",
"integrity": "sha512-9nJCSStoxu4BKaKVJhu/uBJ8IsIofwAdsX0TWFxqo0obaZbeQSEpPhVsCy+uk3u/28dF+qyUtMCYawO2Uljnag==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.0.0-rc.3.tgz",
"integrity": "sha512-fwx805/xL4sF/EdMYqcUHQHzMYwo+OVTBTz5x/JWK8D57rnmLHAP+ZhnfFsZQLRo2QRT2l1Ye3bDyU+QRA1JFA==",
"cpu": [
"arm"
],
@@ -2432,9 +2433,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-beta.22.tgz",
"integrity": "sha512-TF9q9zHFBx9LaG2fJJC+BcpIokOmX1UIniBapndvx3dJmdDiK4F6w2QYKDkrBQVzDzcIducmdo2zNBv17O9tFQ==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.0.0-rc.3.tgz",
"integrity": "sha512-3KauzO1Ls4kuY0nr82S4X8XFxlQAMN+Mqp8LLqvQ+PPMp92XQAkPH7osQdoHIEoW5gsE69U2JaiQ5tHSqNM9og==",
"cpu": [
"arm64"
],
@@ -2448,9 +2449,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-beta.22.tgz",
"integrity": "sha512-ak/RdmaV7sATQmNOxlpHVlbKlrdquH7WH8nOv82X+iK+1HgAOGGqLqBUMzzhkGqo9SHQ9zJ6A2yOo7Z6TJXMmQ==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.0-rc.3.tgz",
"integrity": "sha512-ngHS0foffm1xO5gqnDKGeYMKj8ceGmrFP5dDldoaaMQubw1SyFa0pRUjb7fZSYiO7F4SOSa8NYeMqlF9peZmnQ==",
"cpu": [
"arm64"
],
@@ -2464,9 +2465,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-beta.22.tgz",
"integrity": "sha512-9t+jQeMqBdXz51ikTh1PQFG/gs9PBzXmtMcIzUxE0juvH/ynjw0Vf+yZbNmwqVS9g7cj8XiBXoc6/N41SZE2cA==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.0.0-rc.3.tgz",
"integrity": "sha512-0/am9pVvuUHGmz32M8ffz1fpLnc08j3nzcRe5wUdL2AxfT+wKMII+Dn99GtCVgcdDW4jSXDMRUwrBkGocGC2OA==",
"cpu": [
"x64"
],
@@ -2480,9 +2481,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-beta.22.tgz",
"integrity": "sha512-PemcztfHG3HAuuo7HcnhfDrtN9NT7kueyNg8ipxJNPMa+s4K7kfieViyEiMW5pTr2F5WG/UuBSNcuwY+DVCcPA==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.0-rc.3.tgz",
"integrity": "sha512-r7mRi8q8TqTFVjb9kAsU7IgwUgno2s8Ip4xwq9psQhlRE3JGEZQmSEcy1jqTjfl6KFh6lJcDR7l+9/EMhL/D3Q==",
"cpu": [
"x64"
],
@@ -2496,9 +2497,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-beta.22.tgz",
"integrity": "sha512-EgKoG/jGEtTzhOp7ISjMdQsfd8IOG/5yZhO9Z4L/u7oB9mprKAJohYs24+ZxJtq2bOz4f/ZIysZ19nbkpxUzrg==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.0.0-rc.3.tgz",
"integrity": "sha512-2J6KjmDIQCw6HF1X6/yPcd+JLl7pxrH2zVMGmNllaoWhHeByvRobqFWnT7gcdHaA3dGTo432CwWvOgTgrINQpQ==",
"cpu": [
"arm64"
],
@@ -2512,9 +2513,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-beta.22.tgz",
"integrity": "sha512-67OrM2m4FB3KujPbjd/i+9lqcLDO3/ixqL1GMc3BoHhcjF+7QY08OxqWeitdsP/8ihnMIIdir2xEjNUKc6Zelw==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.0.0-rc.3.tgz",
"integrity": "sha512-8q75CsHDSEDdgi6xPwim+BaQZFCswK2Dn/qL38V3Mh9kmVvC8oGJMPC66bC20dF+v3KWeFm2FNNGQqOSXCveHg==",
"cpu": [
"ia32"
],
@@ -2528,9 +2529,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.0.0-beta.22",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-beta.22.tgz",
"integrity": "sha512-BsO5xMUxliTZTImXnOC73sKT2U9VUeqR8AtklSObBcAg5LaZKpYOdF2pZzU6rIMAZwzROTAT1hYsr4r/nx2UZg==",
"version": "2.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.0.0-rc.3.tgz",
"integrity": "sha512-qeBRJYalahxEXolekcpZJ/HBrIJacG2NWJBGhhi797mIwnbmlpbHMc8blIJtNNNwVUb2BjXuxKQVfojQ5YYrcg==",
"cpu": [
"x64"
],
@@ -2544,43 +2545,51 @@
}
},
"node_modules/@tauri-apps/plugin-clipboard-manager": {
"version": "2.1.0-beta.5",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.1.0-beta.5.tgz",
"integrity": "sha512-7YQEXRHXn5dIr/YcE7RtkoAhc6XwpqI7Qz0I3FcHn5vMbVvQ5OxKnGqEa8ZGRud6R3G9pNdnEKglLXLgUXK8tA==",
"version": "2.0.0-rc.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.0.0-rc.0.tgz",
"integrity": "sha512-2fS3wbRQEtorkk3Np2msJUeKCXRqLQ9sSo2FzlFdUPYNzThsu43uWCF55McGLAfltNOvXQIcQLUBf05jbBL/5w==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.0"
}
},
"node_modules/@tauri-apps/plugin-dialog": {
"version": "2.0.0-beta.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-beta.7.tgz",
"integrity": "sha512-myywwpsKbquDDzl5zaOmmLLv5O8EJ/GgHDAoVSPwO97R4iWzkDvj3HFF91tNh7i25Tu/bP6jYPAdZA1NCRxxtg==",
"version": "2.0.0-rc.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.0.0-rc.0.tgz",
"integrity": "sha512-DPOXYe8SQ6Radk/67EOdaomlxL7oF99JO/ZUaPp1IBEs3Wro7lhlz63CfdKIBfKIZTLJLzP1R7/EiPL/GTA3Bg==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.0"
}
},
"node_modules/@tauri-apps/plugin-fs": {
"version": "2.0.0-beta.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.0.0-beta.7.tgz",
"integrity": "sha512-hsZyhzvy+xtRfbrKI2rmU1ZfmgbSs7Zu/6a12MFlJKVzqXmUwJvggcjYdm1cEFdLbnOOsszENXbwMnkzmxtirA==",
"version": "2.0.0-rc.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.0.0-rc.0.tgz",
"integrity": "sha512-74VCXEZlzTJ+Jv1V3KrV0qIHhSePpE/ljsF78rcEuvSfyTxLtt/Sb5CIUmVhFlKTRFOH9dX50T4dTZ3qFLyRnA==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.0"
}
},
"node_modules/@tauri-apps/plugin-log": {
"version": "2.0.0-rc.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-log/-/plugin-log-2.0.0-rc.0.tgz",
"integrity": "sha512-ztKfzUcq03dtr08vBu+xcwIEPusP6mCpuLAt6kpXEwG+HvYsC8e1/KFFokn3xvfwD+oBJ3UTL1h4kdM30GAqGw==",
"dependencies": {
"@tauri-apps/api": "^2.0.0-rc.0"
}
},
"node_modules/@tauri-apps/plugin-os": {
"version": "2.0.0-beta.7",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-beta.7.tgz",
"integrity": "sha512-CHo09ecxUU0NFkAqctXeQzdaXw02EXulqcaZnbjrBfRJ2ulmGq7zaUCsHihfcqWcdnmNwmP9Wh/gyznMc1JF9Q==",
"version": "2.0.0-rc.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-os/-/plugin-os-2.0.0-rc.0.tgz",
"integrity": "sha512-OWAl8mooKnGykSD4iog8WRqcnOSx0gGmTJBlEExHdFeIuOHg0Ezvd+WiVLhT9LBg7go3ibNWRWpe/ZG7YEp4Vw==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.0"
}
},
"node_modules/@tauri-apps/plugin-shell": {
"version": "2.0.0-beta.8",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-beta.8.tgz",
"integrity": "sha512-rFXI6MvsCdSGbuKbDu/NaOePREb9YTVTdeugHdvvljnKWW3dvmThBb2h/8Hxj+Z7Cd8MUoRxPeJWUZbPbJ2Imw==",
"version": "2.0.0-rc.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-shell/-/plugin-shell-2.0.0-rc.0.tgz",
"integrity": "sha512-bhUcQcrqZoK8H1DFXapr5r1Z75oh6Kd5Tltz97XpZFLREEqp+KhN2Fvyh8r/fKAyenYsTYUIsDsyGdjdueuF9g==",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.15"
"@tauri-apps/api": "^2.0.0-rc.0"
}
},
"node_modules/@types/babel__core": {
@@ -2979,6 +2988,27 @@
"resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz",
"integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ=="
},
"node_modules/@yaakapp/api": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@yaakapp/api/-/api-0.1.4.tgz",
"integrity": "sha512-dI5b2WPjTWXkaYBE/ltfxrJDIjIf/ETjMOzrfWDDcgT2GSBNlYmywZRTsk7j5cEbSQbSrDNgXYGJwG0I89aqSg==",
"dependencies": {
"@types/node": "^22.0.0"
}
},
"node_modules/@yaakapp/api/node_modules/@types/node": {
"version": "22.0.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.2.tgz",
"integrity": "sha512-yPL6DyFwY5PiMVEwymNeqUTKsDczQBJ/5T7W/46RwLU/VH+AA8aT5TZkvBviLKLbbm0hlfftEkGrNzfRk/fofQ==",
"dependencies": {
"undici-types": "~6.11.1"
}
},
"node_modules/@yaakapp/api/node_modules/undici-types": {
"version": "6.11.1",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz",
"integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ=="
},
"node_modules/abbrev": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -11081,29 +11111,6 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"optional": true
},
"node_modules/tauri-plugin-log-api": {
"name": "@tauri-apps/plugin-log",
"version": "2.0.0-beta.4",
"resolved": "git+ssh://git@github.com/tauri-apps/tauri-plugin-log.git#1dc096891b697dc9af1241450c4608cbc33695da",
"license": "MIT or APACHE-2.0",
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.11"
}
},
"node_modules/tauri-plugin-log-api/node_modules/@tauri-apps/api": {
"version": "2.0.0-beta.11",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.0.0-beta.11.tgz",
"integrity": "sha512-wJRY+fBUm3KpqZDHMIz5HRv+1vlnvRJ/dFxiyY3NlINTx2qXqDou5qWYcP1CuZXsd39InWVPV3FAZvno/kGCkA==",
"engines": {
"node": ">= 18",
"npm": ">= 6.6.0",
"yarn": ">= 1.19.1"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
}
},
"node_modules/term-size": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",

View File

@@ -11,14 +11,14 @@
"tauri": "tauri",
"dev:js": "vite dev",
"lint": "tsc && eslint . --ext .ts,.tsx",
"build": "run-p build:*",
"build:icon:release": "tauri icon design/icon.png --output ./src-tauri/icons/release",
"build:icon:dev": "tauri icon design/icon-dev.png --output ./src-tauri/icons/dev",
"build": "run-p build:*",
"build:js": "vite build",
"build:plugin-runtime": "npm run --prefix plugin-runtime build",
"build:vendor-protoc": "node scripts/vendor-protoc.cjs",
"build:vendor-plugins": "node scripts/vendor-plugins.cjs",
"build:vendor-node": "node scripts/vendor-node.cjs",
"build:plugin-runtime": "npm run --prefix plugin-runtime build",
"prepare": "husky install",
"replace-version": "node scripts/replace-version.cjs"
},
@@ -35,12 +35,14 @@
"@react-hook/resize-observer": "^1.2.6",
"@tailwindcss/container-queries": "^0.1.0",
"@tanstack/react-query": "^5.45.1",
"@tauri-apps/api": "^2.0.0-beta.15",
"@tauri-apps/plugin-clipboard-manager": "^2.1.0-beta.5",
"@tauri-apps/plugin-dialog": "^2.0.0-beta.7",
"@tauri-apps/plugin-fs": "^2.0.0-beta.7",
"@tauri-apps/plugin-os": "^2.0.0-beta.7",
"@tauri-apps/plugin-shell": "^2.0.0-beta.8",
"@tauri-apps/api": "^2.0.0-rc.0",
"@tauri-apps/plugin-clipboard-manager": "^2.0.0-rc.0",
"@tauri-apps/plugin-dialog": "^2.0.0-rc.0",
"@tauri-apps/plugin-fs": "^2.0.0-rc.0",
"@tauri-apps/plugin-os": "^2.0.0-rc.0",
"@tauri-apps/plugin-shell": "^2.0.0-rc.0",
"@tauri-apps/plugin-log": "^2.0.0-rc.0",
"@yaakapp/api": "^0.1.4",
"buffer": "^6.0.3",
"classnames": "^2.3.2",
"cm6-graphql": "^0.0.9",
@@ -64,14 +66,13 @@
"react-router-dom": "^6.8.1",
"react-use": "^17.4.0",
"slugify": "^1.6.6",
"tauri-plugin-log-api": "github:tauri-apps/tauri-plugin-log#v2",
"uuid": "^9.0.0",
"xml-formatter": "^3.6.2"
},
"devDependencies": {
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@tanstack/react-query-devtools": "^5.45.1",
"@tauri-apps/cli": "^2.0.0-beta.22",
"@tauri-apps/cli": "^2.0.0-rc.2",
"@types/node": "^18.7.10",
"@types/papaparse": "^5.3.7",
"@types/parse-color": "^1.0.1",

2
plugin-runtime-types/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
lib
node_modules

44
plugin-runtime-types/package-lock.json generated Normal file
View File

@@ -0,0 +1,44 @@
{
"name": "@yaakapp/api",
"version": "0.1.0-beta.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@yaakapp/api",
"version": "0.1.0-beta.4",
"dependencies": {
"@types/node": "^22.0.0"
},
"devDependencies": {
"typescript": "^5.5.4"
}
},
"node_modules/@types/node": {
"version": "22.0.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz",
"integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==",
"dependencies": {
"undici-types": "~6.11.1"
}
},
"node_modules/typescript": {
"version": "5.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "6.11.1",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz",
"integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ=="
}
}
}

View File

@@ -0,0 +1,19 @@
{
"name": "@yaakapp/api",
"version": "0.1.4",
"main": "lib/index.js",
"typings": "./lib/index.d.ts",
"files": [
"lib"
],
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build"
},
"dependencies": {
"@types/node": "^22.0.0"
},
"devDependencies": {
"typescript": "^5.5.4"
}
}

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type BootRequest = { dir: string, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type BootResponse = { name: string, version: string, capabilities: Array<string>, };

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { CookieDomain } from "./CookieDomain";
import type { CookieExpires } from "./CookieExpires";
export type Cookie = { raw_cookie: string, domain: CookieDomain, expires: CookieExpires, path: [string, boolean], };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type CookieDomain = { "HostOnly": string } | { "Suffix": string } | "NotPresent" | "Empty";

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type CookieExpires = { "AtUtc": string } | "SessionEnd";

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Cookie } from "./Cookie";
export type CookieJar = { id: string, model: "cookie_jar", createdAt: string, updatedAt: string, workspaceId: string, name: string, cookies: Array<Cookie>, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type EmptyResponse = {};

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { EnvironmentVariable } from "./EnvironmentVariable";
export type Environment = { id: string, workspaceId: string, model: "environment", createdAt: string, updatedAt: string, name: string, variables: Array<EnvironmentVariable>, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, };

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { HttpRequest } from "./HttpRequest";
export type ExportHttpRequestRequest = { httpRequest: HttpRequest, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type ExportHttpRequestResponse = { content: string, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type FilterRequest = { content: string, filter: string, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type FilterResponse = { content: string, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Folder = { createdAt: string, updatedAt: string, id: string, workspaceId: string, folderId: string | null, model: "folder", name: string, sortPriority: number, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type GrpcConnection = { id: string, model: "grpc_connection", workspaceId: string, requestId: string, createdAt: string, updatedAt: string, service: string, method: string, elapsed: number, status: number, url: string, error: string | null, trailers: { [key: string]: string }, };

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { GrpcEventType } from "./GrpcEventType";
export type GrpcEvent = { id: string, model: "grpc_event", workspaceId: string, requestId: string, connectionId: string, createdAt: string, content: string, eventType: GrpcEventType, metadata: { [key: string]: string }, status: number | null, error: string | null, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type GrpcEventType = "info" | "error" | "client_message" | "server_message" | "connection_start" | "connection_end";

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, };

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { GrpcMetadataEntry } from "./GrpcMetadataEntry";
export type GrpcRequest = { id: string, model: "grpc_request", workspaceId: string, createdAt: string, updatedAt: string, folderId: string | null, name: string, sortPriority: number, url: string, service: string | null, method: string | null, message: string, authenticationType: string | null, authentication: Record<string, any>, metadata: Array<GrpcMetadataEntry>, };

View File

@@ -0,0 +1,5 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { HttpRequestHeader } from "./HttpRequestHeader";
import type { HttpUrlParameter } from "./HttpUrlParameter";
export type HttpRequest = { createdAt: string, updatedAt: string, id: string, workspaceId: string, folderId: string | null, model: "http_request", sortPriority: number, name: string, url: string, urlParameters: Array<HttpUrlParameter>, method: string, body: Record<string, any>, bodyType: string | null, authentication: Record<string, any>, authenticationType: string | null, headers: Array<HttpRequestHeader>, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, };

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { HttpResponseHeader } from "./HttpResponseHeader";
export type HttpResponse = { id: string, model: "http_response", workspaceId: string, requestId: string, createdAt: string, updatedAt: string, error: string | null, url: string, contentLength: number | null, version: string | null, elapsed: number, elapsedHeaders: number, remoteAddr: string | null, status: number, statusReason: string | null, bodyPath: string | null, headers: Array<HttpResponseHeader>, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type HttpResponseHeader = { name: string, value: string, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type HttpUrlParameter = { enabled?: boolean, name: string, value: string, };

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type ImportRequest = { content: string, };

View File

@@ -0,0 +1,8 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { Environment } from "./Environment";
import type { Folder } from "./Folder";
import type { GrpcRequest } from "./GrpcRequest";
import type { HttpRequest } from "./HttpRequest";
import type { Workspace } from "./Workspace";
export type ImportResources = { workspaces: Array<Workspace>, environments: Array<Environment>, folders: Array<Folder>, httpRequests: Array<HttpRequest>, grpcRequests: Array<GrpcRequest>, };

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { ImportResources } from "./ImportResources";
export type ImportResponse = { resources: ImportResources, };

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { InternalEventPayload } from "./InternalEventPayload";
export type InternalEvent = { id: string, pluginRefId: string, replyId: string | null, payload: InternalEventPayload, };

View File

@@ -0,0 +1,12 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { BootRequest } from "./BootRequest";
import type { BootResponse } from "./BootResponse";
import type { EmptyResponse } from "./EmptyResponse";
import type { ExportHttpRequestRequest } from "./ExportHttpRequestRequest";
import type { ExportHttpRequestResponse } from "./ExportHttpRequestResponse";
import type { FilterRequest } from "./FilterRequest";
import type { FilterResponse } from "./FilterResponse";
import type { ImportRequest } from "./ImportRequest";
import type { ImportResponse } from "./ImportResponse";
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "empty_response" } & EmptyResponse;

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type KeyValue = { model: "key_value", createdAt: string, updatedAt: string, namespace: string, key: string, value: string, };

View File

@@ -0,0 +1,14 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { CookieJar } from "./CookieJar";
import type { Environment } from "./Environment";
import type { Folder } from "./Folder";
import type { GrpcConnection } from "./GrpcConnection";
import type { GrpcEvent } from "./GrpcEvent";
import type { GrpcRequest } from "./GrpcRequest";
import type { HttpRequest } from "./HttpRequest";
import type { HttpResponse } from "./HttpResponse";
import type { KeyValue } from "./KeyValue";
import type { Settings } from "./Settings";
import type { Workspace } from "./Workspace";
export type Model = Environment | Folder | GrpcConnection | GrpcEvent | GrpcRequest | HttpRequest | HttpResponse | KeyValue | Workspace | CookieJar | Settings;

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Settings = { id: string, model: "settings", createdAt: string, updatedAt: string, theme: string, appearance: string, themeDark: string, themeLight: string, updateChannel: string, interfaceFontSize: number, interfaceScale: number, editorFontSize: number, editorSoftWrap: boolean, openWorkspaceNewWindow: boolean | null, };

View File

@@ -0,0 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { EnvironmentVariable } from "./EnvironmentVariable";
export type Workspace = { id: string, model: "workspace", createdAt: string, updatedAt: string, name: string, description: string, variables: Array<EnvironmentVariable>, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };

View File

@@ -0,0 +1,2 @@
export type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
export type OneOrMany<T> = T[] | T;

View File

@@ -0,0 +1,35 @@
export type * from './plugins';
export type * from './themes';
export * from './gen/BootRequest';
export * from './gen/BootResponse';
export * from './gen/Cookie';
export * from './gen/CookieDomain';
export * from './gen/CookieExpires';
export * from './gen/CookieJar';
export * from './gen/EmptyResponse';
export * from './gen/Environment';
export * from './gen/EnvironmentVariable';
export * from './gen/ExportHttpRequestRequest';
export * from './gen/ExportHttpRequestResponse';
export * from './gen/FilterRequest';
export * from './gen/FilterResponse';
export * from './gen/Folder';
export * from './gen/GrpcConnection';
export * from './gen/GrpcEvent';
export * from './gen/GrpcMetadataEntry';
export * from './gen/GrpcRequest';
export * from './gen/HttpRequest';
export * from './gen/HttpRequestHeader';
export * from './gen/HttpResponse';
export * from './gen/HttpResponseHeader';
export * from './gen/HttpUrlParameter';
export * from './gen/ImportRequest';
export * from './gen/ImportResources';
export * from './gen/ImportResponse';
export * from './gen/InternalEvent';
export * from './gen/InternalEventPayload';
export * from './gen/KeyValue';
export * from './gen/Model';
export * from './gen/Settings';
export * from './gen/Workspace';

View File

@@ -0,0 +1,12 @@
import { HttpRequest } from '../gen/HttpRequest';
import { HttpResponse } from '../gen/HttpResponse';
export type YaakContext = {
metadata: {
getVersion(): Promise<string>;
};
httpRequest: {
send(id: string): Promise<HttpResponse>;
getById(id: string): Promise<HttpRequest | null>;
};
};

View File

@@ -0,0 +1,13 @@
import { YaakContext } from './context';
export type FilterPluginResponse = string[];
export type FilterPlugin = {
name: string;
description?: string;
canFilter(ctx: YaakContext, args: { mimeType: string }): Promise<boolean>;
onFilter(
ctx: YaakContext,
args: { payload: string; mimeType: string },
): Promise<FilterPluginResponse>;
};

View File

@@ -0,0 +1,8 @@
import { HttpRequest } from '../gen/HttpRequest';
import { YaakContext } from './context';
export type HttpRequestActionPlugin = {
key: string;
label: string;
onSelect(ctx: YaakContext, args: { httpRequest: HttpRequest }): void;
};

View File

@@ -0,0 +1,19 @@
import { Environment } from '../gen/Environment';
import { Folder } from '../gen/Folder';
import { HttpRequest } from '../gen/HttpRequest';
import { Workspace } from '../gen/Workspace';
import { AtLeast } from '../helpers';
import { YaakContext } from './context';
export type ImportPluginResponse = null | {
workspaces: AtLeast<Workspace, 'name' | 'id' | 'model'>[];
environments: AtLeast<Environment, 'name' | 'id' | 'model' | 'workspaceId'>[];
httpRequests: AtLeast<HttpRequest, 'name' | 'id' | 'model' | 'workspaceId'>[];
folders: AtLeast<Folder, 'name' | 'id' | 'model' | 'workspaceId'>[];
};
export type ImporterPlugin = {
name: string;
description?: string;
onImport(ctx: YaakContext, args: { text: string }): Promise<ImportPluginResponse>;
};

View File

@@ -0,0 +1,15 @@
import { OneOrMany } from '../helpers';
import { FilterPlugin } from './filter';
import { HttpRequestActionPlugin } from './httpRequestAction';
import { ImporterPlugin } from './import';
import { ThemePlugin } from './theme';
/**
* The global structure of a Yaak plugin
*/
export type YaakPlugin = {
importer?: OneOrMany<ImporterPlugin>;
theme?: OneOrMany<ThemePlugin>;
filter?: OneOrMany<FilterPlugin>;
httpRequestAction?: OneOrMany<HttpRequestActionPlugin>;
};

View File

@@ -0,0 +1,8 @@
import { Theme } from '../themes';
import { YaakContext } from './context';
export type ThemePlugin = {
name: string;
description?: string;
getTheme(ctx: YaakContext, fileContents: string): Promise<Theme>;
};

View File

@@ -0,0 +1,44 @@
export type Colors = {
surface: string;
surfaceHighlight?: string;
surfaceActive?: string;
text: string;
textSubtle?: string;
textSubtlest?: string;
border?: string;
borderSubtle?: string;
borderFocus?: string;
shadow?: string;
backdrop?: string;
selection?: string;
primary?: string;
secondary?: string;
info?: string;
success?: string;
notice?: string;
warning?: string;
danger?: string;
};
export type Theme = Colors & {
id: string;
name: string;
components?: Partial<{
dialog: Partial<Colors>;
menu: Partial<Colors>;
toast: Partial<Colors>;
sidebar: Partial<Colors>;
responsePane: Partial<Colors>;
appHeader: Partial<Colors>;
button: Partial<Colors>;
banner: Partial<Colors>;
placeholder: Partial<Colors>;
urlBar: Partial<Colors>;
editor: Partial<Colors>;
input: Partial<Colors>;
}>;
};

View File

@@ -0,0 +1,15 @@
{
"compilerOptions": {
"module": "node16",
"target": "es6",
"lib": ["es2021"],
"declaration": true,
"declarationDir": "./lib",
"outDir": "./lib",
"strict": true,
"types": ["node"]
},
"files": [
"src/index.ts"
]
}

View File

@@ -6,11 +6,13 @@
"": {
"name": "@yaak/plugin-runtime",
"dependencies": {
"intercept-stdout": "^0.1.2",
"long": "^5.2.3",
"nice-grpc": "^2.1.9",
"protobufjs": "^7.3.2"
},
"devDependencies": {
"@types/intercept-stdout": "^0.1.3",
"grpc-tools": "^1.12.4",
"nodemon": "^3.1.4",
"npm-run-all": "^4.1.5",
@@ -192,6 +194,12 @@
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"dev": true
},
"node_modules/@types/intercept-stdout": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@types/intercept-stdout/-/intercept-stdout-0.1.3.tgz",
"integrity": "sha512-5qWSvqohM5rRKsF58LBWJeyu+lUlZwYKSnTcnXGfvFyMYIjvhpfniQRJNiyE/Gcru3jwVr2pHedsKTGLtzZqNA==",
"dev": true
},
"node_modules/@types/node": {
"version": "20.14.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.7.tgz",
@@ -1304,6 +1312,14 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"node_modules/intercept-stdout": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/intercept-stdout/-/intercept-stdout-0.1.2.tgz",
"integrity": "sha512-Umb41Ryp5FzLurfCRAWx+jjNAk8jsw2RTk2XPIwus+86h/Y2Eb4DfOWof/mZ6FBww8SoO45rJSlg25054/Di9w==",
"dependencies": {
"lodash.toarray": "^3.0.0"
}
},
"node_modules/internal-slot": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
@@ -1644,11 +1660,56 @@
"node": ">=4"
}
},
"node_modules/lodash._arraycopy": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz",
"integrity": "sha512-RHShTDnPKP7aWxlvXKiDT6IX2jCs6YZLCtNhOru/OX2Q/tzX295vVBK5oX1ECtN+2r86S0Ogy8ykP1sgCZAN0A=="
},
"node_modules/lodash._basevalues": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz",
"integrity": "sha512-H94wl5P13uEqlCg7OcNNhMQ8KvWSIyqXzOPusRgHC9DK3o54P6P3xtbXlVbRABG4q5gSmp7EDdJ0MSuW9HX6Mg=="
},
"node_modules/lodash._getnative": {
"version": "3.9.1",
"resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
"integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA=="
},
"node_modules/lodash.camelcase": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
"integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
},
"node_modules/lodash.isarguments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
"integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg=="
},
"node_modules/lodash.isarray": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
"integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ=="
},
"node_modules/lodash.keys": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
"integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==",
"dependencies": {
"lodash._getnative": "^3.0.0",
"lodash.isarguments": "^3.0.0",
"lodash.isarray": "^3.0.0"
}
},
"node_modules/lodash.toarray": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-3.0.2.tgz",
"integrity": "sha512-ptkjUqvuHjTuMJJxiktJpZhxM5l60bEkfntJx+NFzdQd1bZVxfpTF1bhFYFqBrT4F0wZ1qx9KbVmHJV3Rfc7Tw==",
"dependencies": {
"lodash._arraycopy": "^3.0.0",
"lodash._basevalues": "^3.0.0",
"lodash.keys": "^3.0.0"
}
},
"node_modules/long": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",

View File

@@ -8,11 +8,13 @@
"build:proto": "grpc_tools_node_protoc --ts_proto_out=src/gen --ts_proto_opt=outputServices=nice-grpc,outputServices=generic-definitions,useExactTypes=false --proto_path=../proto ../proto/plugins/*.proto"
},
"dependencies": {
"intercept-stdout": "^0.1.2",
"long": "^5.2.3",
"nice-grpc": "^2.1.9",
"protobufjs": "^7.3.2"
},
"devDependencies": {
"@types/intercept-stdout": "^0.1.3",
"grpc-tools": "^1.12.4",
"nodemon": "^3.1.4",
"npm-run-all": "^4.1.5",

View File

@@ -0,0 +1,21 @@
import { InternalEvent } from '@yaakapp/api';
import EventEmitter from 'node:events';
import { EventStreamEvent } from './gen/plugins/runtime';
export class EventChannel {
emitter: EventEmitter = new EventEmitter();
emit(e: InternalEvent) {
this.emitter.emit('__plugin_event__', { event: JSON.stringify(e) });
}
async *listen(): AsyncGenerator<EventStreamEvent> {
while (true) {
yield new Promise<EventStreamEvent>((resolve) => {
this.emitter.once('__plugin_event__', (event: EventStreamEvent) => {
resolve(event);
});
});
}
}
}

View File

@@ -1,81 +1,31 @@
import { randomUUID } from 'node:crypto';
import { InternalEvent } from '@yaakapp/api';
import path from 'node:path';
import { Worker } from 'node:worker_threads';
import { PluginInfo } from './plugins';
export interface ParentToWorkerEvent<T = any> {
callbackId: string;
name: string;
payload: T;
}
export type WorkerToParentSuccessEvent<T> = {
callbackId: string;
payload: T;
};
export type WorkerToParentErrorEvent = {
callbackId: string;
error: string;
};
export type WorkerToParentEvent<T = any> = WorkerToParentErrorEvent | WorkerToParentSuccessEvent<T>;
import { EventChannel } from './EventChannel';
export class PluginHandle {
readonly pluginDir: string;
readonly #worker: Worker;
constructor(pluginDir: string) {
this.pluginDir = pluginDir;
const workerPath = path.join(__dirname, 'index.worker.cjs');
constructor(
readonly pluginDir: string,
readonly pluginRefId: string,
readonly events: EventChannel,
) {
const workerPath = process.env.YAAK_WORKER_PATH ?? path.join(__dirname, 'index.worker.cjs');
this.#worker = new Worker(workerPath, {
workerData: {
pluginDir: this.pluginDir,
pluginDir,
pluginRefId,
},
});
this.#worker.on('message', (e) => this.events.emit(e));
this.#worker.on('error', this.#handleError.bind(this));
this.#worker.on('exit', this.#handleExit.bind(this));
}
async getInfo(): Promise<PluginInfo> {
return this.#callPlugin('info', null);
}
async runResponseFilter({ filter, body }: { filter: string; body: string }): Promise<string> {
return this.#callPlugin('run-filter', { filter, body });
}
async runExport(request: any): Promise<string> {
return this.#callPlugin('run-export', request);
}
async runImport(data: string): Promise<string> {
const result = await this.#callPlugin('run-import', data);
// Plugin returns object, but we convert to string
return JSON.stringify(result, null, 2);
}
#callPlugin<P, R>(name: string, payload: P): Promise<R> {
const callbackId = `cb_${randomUUID().replaceAll('-', '')}`;
return new Promise((resolve, reject) => {
const cb = (e: WorkerToParentEvent<R>) => {
if (e.callbackId !== callbackId) return;
if ('error' in e) {
reject(e.error);
} else {
resolve(e.payload as R);
}
this.#worker.removeListener('message', cb);
};
this.#worker.addListener('message', cb);
this.#worker.postMessage({ callbackId, name, payload });
});
sendToWorker(event: InternalEvent) {
this.#worker.postMessage(event);
}
async #handleError(err: Error) {

View File

@@ -1,44 +0,0 @@
import { PluginHandle } from './PluginHandle';
import { loadPlugins, PluginInfo } from './plugins';
export class PluginManager {
#handles: PluginHandle[] | null = null;
static #instance: PluginManager | null = null;
public static instance(): PluginManager {
if (PluginManager.#instance == null) {
PluginManager.#instance = new PluginManager();
PluginManager.#instance.plugins(); // Trigger workers to boot, as it takes a few seconds
}
return PluginManager.#instance;
}
async plugins(): Promise<PluginHandle[]> {
this.#handles = this.#handles ?? loadPlugins();
return this.#handles;
}
async #pluginsWithInfo(): Promise<{ plugin: PluginHandle; info: PluginInfo }[]> {
const plugins = await this.plugins();
return Promise.all(plugins.map(async (plugin) => ({ plugin, info: await plugin.getInfo() })));
}
async pluginsWith(capability: PluginInfo['capabilities'][0]): Promise<PluginHandle[]> {
return (await this.#pluginsWithInfo())
.filter((v) => v.info.capabilities.includes(capability))
.map((v) => v.plugin);
}
async plugin(name: string): Promise<PluginHandle | null> {
return (await this.#pluginsWithInfo()).find((v) => v.info.name === name)?.plugin ?? null;
}
async pluginOrThrow(name: string): Promise<PluginHandle> {
const plugin = await this.plugin(name);
if (plugin == null) {
throw new Error(`Failed to find plugin by ${name}`);
}
return plugin;
}
}

View File

@@ -33,6 +33,10 @@ export interface HookExportRequest {
request: string;
}
export interface EventStreamEvent {
event: string;
}
function createBasePluginInfo(): PluginInfo {
return { plugin: "" };
}
@@ -369,54 +373,91 @@ export const HookExportRequest = {
},
};
function createBaseEventStreamEvent(): EventStreamEvent {
return { event: "" };
}
export const EventStreamEvent = {
encode(message: EventStreamEvent, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.event !== "") {
writer.uint32(10).string(message.event);
}
return writer;
},
decode(input: _m0.Reader | Uint8Array, length?: number): EventStreamEvent {
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseEventStreamEvent();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (tag !== 10) {
break;
}
message.event = reader.string();
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skipType(tag & 7);
}
return message;
},
fromJSON(object: any): EventStreamEvent {
return { event: isSet(object.event) ? globalThis.String(object.event) : "" };
},
toJSON(message: EventStreamEvent): unknown {
const obj: any = {};
if (message.event !== "") {
obj.event = message.event;
}
return obj;
},
create(base?: DeepPartial<EventStreamEvent>): EventStreamEvent {
return EventStreamEvent.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<EventStreamEvent>): EventStreamEvent {
const message = createBaseEventStreamEvent();
message.event = object.event ?? "";
return message;
},
};
export type PluginRuntimeDefinition = typeof PluginRuntimeDefinition;
export const PluginRuntimeDefinition = {
name: "PluginRuntime",
fullName: "yaak.plugins.runtime.PluginRuntime",
methods: {
hookImport: {
name: "hookImport",
requestType: HookImportRequest,
requestStream: false,
responseType: HookResponse,
responseStream: false,
options: {},
},
hookExport: {
name: "hookExport",
requestType: HookExportRequest,
requestStream: false,
responseType: HookResponse,
responseStream: false,
options: {},
},
hookResponseFilter: {
name: "hookResponseFilter",
requestType: HookResponseFilterRequest,
requestStream: false,
responseType: HookResponse,
responseStream: false,
eventStream: {
name: "EventStream",
requestType: EventStreamEvent,
requestStream: true,
responseType: EventStreamEvent,
responseStream: true,
options: {},
},
},
} as const;
export interface PluginRuntimeServiceImplementation<CallContextExt = {}> {
hookImport(request: HookImportRequest, context: CallContext & CallContextExt): Promise<DeepPartial<HookResponse>>;
hookExport(request: HookExportRequest, context: CallContext & CallContextExt): Promise<DeepPartial<HookResponse>>;
hookResponseFilter(
request: HookResponseFilterRequest,
eventStream(
request: AsyncIterable<EventStreamEvent>,
context: CallContext & CallContextExt,
): Promise<DeepPartial<HookResponse>>;
): ServerStreamingMethodResult<DeepPartial<EventStreamEvent>>;
}
export interface PluginRuntimeClient<CallOptionsExt = {}> {
hookImport(request: DeepPartial<HookImportRequest>, options?: CallOptions & CallOptionsExt): Promise<HookResponse>;
hookExport(request: DeepPartial<HookExportRequest>, options?: CallOptions & CallOptionsExt): Promise<HookResponse>;
hookResponseFilter(
request: DeepPartial<HookResponseFilterRequest>,
eventStream(
request: AsyncIterable<DeepPartial<EventStreamEvent>>,
options?: CallOptions & CallOptionsExt,
): Promise<HookResponse>;
): AsyncIterable<EventStreamEvent>;
}
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
@@ -430,3 +471,5 @@ export type DeepPartial<T> = T extends Builtin ? T
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}
export type ServerStreamingMethodResult<Response> = { [Symbol.asyncIterator](): AsyncIterator<Response, void> };

View File

@@ -1,87 +1,42 @@
import { isAbortError } from 'abort-controller-x';
import { createServer, ServerError, ServerMiddlewareCall, Status } from 'nice-grpc';
import { CallContext } from 'nice-grpc-common';
import * as fs from 'node:fs';
import {
DeepPartial,
HookExportRequest,
HookImportRequest,
HookResponse,
HookResponseFilterRequest,
PluginRuntimeDefinition,
PluginRuntimeServiceImplementation,
} from './gen/plugins/runtime';
import { PluginManager } from './PluginManager';
import { InternalEvent } from '@yaakapp/api';
import { createChannel, createClient, Status } from 'nice-grpc';
import { EventChannel } from './EventChannel';
import { PluginRuntimeClient, PluginRuntimeDefinition } from './gen/plugins/runtime';
import { PluginHandle } from './PluginHandle';
class PluginRuntimeService implements PluginRuntimeServiceImplementation {
#manager: PluginManager;
const port = process.env.PORT || '50051';
constructor() {
this.#manager = PluginManager.instance();
}
const channel = createChannel(`localhost:${port}`);
const client: PluginRuntimeClient = createClient(PluginRuntimeDefinition, channel);
async hookExport(request: HookExportRequest): Promise<DeepPartial<HookResponse>> {
const plugin = await this.#manager.pluginOrThrow('exporter-curl');
const data = await plugin.runExport(JSON.parse(request.request));
const info = { plugin: (await plugin.getInfo()).name };
return { info, data };
}
const events = new EventChannel();
const plugins: Record<string, PluginHandle> = {};
async hookImport(request: HookImportRequest): Promise<DeepPartial<HookResponse>> {
const plugins = await this.#manager.pluginsWith('import');
for (const p of plugins) {
const data = await p.runImport(request.data);
if (data != null && data !== 'null') {
const info = { plugin: (await p.getInfo()).name };
return { info, data };
}
}
throw new ServerError(Status.UNKNOWN, 'No importers found for data');
}
async hookResponseFilter(request: HookResponseFilterRequest): Promise<DeepPartial<HookResponse>> {
const pluginName = request.contentType.includes('json') ? 'filter-jsonpath' : 'filter-xpath';
const plugin = await this.#manager.pluginOrThrow(pluginName);
const data = await plugin.runResponseFilter(request);
const info = { plugin: (await plugin.getInfo()).name };
return { info, data };
}
}
let server = createServer();
async function* errorHandlingMiddleware<Request, Response>(
call: ServerMiddlewareCall<Request, Response>,
context: CallContext,
) {
(async () => {
try {
return yield* call.next(call.request, context);
} catch (error: unknown) {
if (error instanceof ServerError || isAbortError(error)) {
throw error;
for await (const e of client.eventStream(events.listen())) {
const pluginEvent: InternalEvent = JSON.parse(e.event);
// Handle special event to bootstrap plugin
if (pluginEvent.payload.type === 'boot_request') {
const plugin = new PluginHandle(pluginEvent.payload.dir, pluginEvent.pluginRefId, events);
plugins[pluginEvent.pluginRefId] = plugin;
}
// Once booted, forward all events to plugin's worker
const plugin = plugins[pluginEvent.pluginRefId];
if (!plugin) {
console.warn('Failed to get plugin for event by', pluginEvent.pluginRefId);
continue;
}
plugin.sendToWorker(pluginEvent);
}
let details = String(error);
if (process.env.NODE_ENV === 'development') {
// @ts-ignore
details += `: ${error.stack}`;
console.log('Stream ended');
} catch (err: any) {
if (err.code === Status.CANCELLED) {
console.log('Stream was cancelled by server');
} else {
console.log('Client stream errored', err);
}
throw new ServerError(Status.UNKNOWN, details);
}
}
server = server.use(errorHandlingMiddleware);
server.add(PluginRuntimeDefinition, new PluginRuntimeService());
// Start on random port if YAAK_GRPC_PORT_FILE_PATH is set, or :4000
const addr = process.env.YAAK_GRPC_PORT_FILE_PATH ? 'localhost:0' : 'localhost:4000';
server.listen(addr).then((port) => {
console.log('gRPC server listening on', `http://localhost:${port}`);
if (process.env.YAAK_GRPC_PORT_FILE_PATH) {
console.log('Wrote port file to', process.env.YAAK_GRPC_PORT_FILE_PATH);
fs.writeFileSync(process.env.YAAK_GRPC_PORT_FILE_PATH, JSON.stringify({ port }, null, 2));
}
});
})();

View File

@@ -1,14 +1,18 @@
import { ImportResponse, InternalEvent, InternalEventPayload } from '@yaakapp/api';
import interceptStdout from 'intercept-stdout';
import * as console from 'node:console';
import { readFileSync } from 'node:fs';
import path from 'node:path';
import * as util from 'node:util';
import { parentPort, workerData } from 'node:worker_threads';
import { ParentToWorkerEvent } from './PluginHandle';
import { PluginInfo } from './plugins';
new Promise<void>(async (resolve, reject) => {
const { pluginDir } = workerData;
const pathMod = path.join(pluginDir, 'build/index.js');
const { pluginDir /*, pluginRefId*/ } = workerData;
const pathPkg = path.join(pluginDir, 'package.json');
// NOTE: Use POSIX join because require() needs forward slash
const pathMod = path.posix.join(pluginDir, 'build', 'index.js');
let pkg: { [x: string]: any };
try {
pkg = JSON.parse(readFileSync(pathPkg, 'utf8'));
@@ -18,59 +22,112 @@ new Promise<void>(async (resolve, reject) => {
return;
}
const mod = (await import(`file://${pathMod}`)).default ?? {};
prefixStdout(`[plugin][${pkg.name}] %s`);
const info: PluginInfo = {
capabilities: [],
name: pkg['name'] ?? 'n/a',
dir: pluginDir,
};
const mod = (await import(pathMod)).default ?? {};
if (typeof mod['pluginHookImport'] === 'function') {
info.capabilities.push('import');
}
const capabilities: string[] = [];
if (typeof mod.pluginHookExport === 'function') capabilities.push('export');
if (typeof mod.pluginHookImport === 'function') capabilities.push('import');
if (typeof mod.pluginHookResponseFilter === 'function') capabilities.push('filter');
if (typeof mod['pluginHookExport'] === 'function') {
info.capabilities.push('export');
}
console.log('Plugin initialized', pkg.name, capabilities, Object.keys(mod));
if (typeof mod['pluginHookResponseFilter'] === 'function') {
info.capabilities.push('filter');
}
// Message comes into the plugin to be processed
parentPort!.on('message', async ({ payload, pluginRefId, id: replyId }: InternalEvent) => {
console.log(`Received ${payload.type}`);
console.log('Loaded plugin', info.name, info.capabilities, info.dir);
function reply<T>(originalMsg: ParentToWorkerEvent, payload: T) {
parentPort!.postMessage({ payload, callbackId: originalMsg.callbackId });
}
function replyErr(originalMsg: ParentToWorkerEvent, error: unknown) {
parentPort!.postMessage({
error: String(error),
callbackId: originalMsg.callbackId,
});
}
parentPort!.on('message', async (msg: ParentToWorkerEvent) => {
try {
const ctx = { todo: 'implement me' };
if (msg.name === 'run-import') {
reply(msg, await mod.pluginHookImport(ctx, msg.payload));
} else if (msg.name === 'run-filter') {
reply(msg, await mod.pluginHookResponseFilter(ctx, msg.payload));
} else if (msg.name === 'run-export') {
reply(msg, await mod.pluginHookExport(ctx, msg.payload));
} else if (msg.name === 'info') {
reply(msg, info);
} else {
console.log('Unknown message', msg);
if (payload.type === 'boot_request') {
const payload: InternalEventPayload = {
type: 'boot_response',
name: pkg.name,
version: pkg.version,
capabilities,
};
sendToServer({ id: genId(), pluginRefId, replyId, payload });
return;
}
} catch (err: unknown) {
replyErr(msg, err);
if (payload.type === 'import_request' && typeof mod.pluginHookImport === 'function') {
const reply: ImportResponse | null = await mod.pluginHookImport({}, payload.content);
if (reply != null) {
const replyPayload: InternalEventPayload = {
type: 'import_response',
resources: reply?.resources,
};
sendToServer({ id: genId(), pluginRefId, replyId, payload: replyPayload });
return;
} else {
// Continue, to send back an empty reply
}
}
if (
payload.type === 'export_http_request_request' &&
typeof mod.pluginHookExport === 'function'
) {
const reply: string = await mod.pluginHookExport({}, payload.httpRequest);
const replyPayload: InternalEventPayload = {
type: 'export_http_request_response',
content: reply,
};
sendToServer({ id: genId(), pluginRefId, replyId, payload: replyPayload });
return;
}
if (payload.type === 'filter_request' && typeof mod.pluginHookResponseFilter === 'function') {
const reply: string = await mod.pluginHookResponseFilter(
{},
{ filter: payload.filter, body: payload.content },
);
const replyPayload: InternalEventPayload = {
type: 'filter_response',
content: reply,
};
sendToServer({ id: genId(), pluginRefId, replyId, payload: replyPayload });
return;
}
} catch (err) {
console.log('Plugin call threw exception', payload.type, err);
// TODO: Return errors to server
}
// No matches, so send back an empty response so the caller doesn't block forever
const id = genId();
console.log('Sending nothing back to', id, { replyId });
sendToServer({ id, pluginRefId, replyId, payload: { type: 'empty_response' } });
});
resolve();
}).catch((err) => {
console.log('failed to boot plugin', err);
});
function sendToServer(e: InternalEvent) {
parentPort!.postMessage(e);
}
function genId(len = 5): string {
const alphabet = '01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
let id = '';
for (let i = 0; i < len; i++) {
id += alphabet[Math.floor(Math.random() * alphabet.length)];
}
return id;
}
function prefixStdout(s: string) {
if (!s.includes('%s')) {
throw new Error('Console prefix must contain a "%s" replacer');
}
interceptStdout((text) => {
const lines = text.split(/\n/);
let newText = '';
for (let i = 0; i < lines.length; i++) {
if (lines[i] == '') continue;
newText += util.format(s, lines[i]) + '\n';
}
return newText.trimEnd();
});
}

View File

@@ -1,18 +0,0 @@
import * as fs from 'node:fs';
import path from 'node:path';
import { PluginHandle } from './PluginHandle';
export interface PluginInfo {
name: string;
dir: string;
capabilities: ('import' | 'export' | 'filter')[];
}
export function loadPlugins(): PluginHandle[] {
const pluginsDir = process.env.YAAK_PLUGINS_DIR;
if (!pluginsDir) throw new Error('YAAK_PLUGINS_DIR is not set');
console.log('Loading plugins from', pluginsDir);
const pluginDirs = fs.readdirSync(pluginsDir).map((p) => path.join(pluginsDir, p));
return pluginDirs.map((pluginDir) => new PluginHandle(pluginDir));
}

View File

@@ -11,7 +11,6 @@
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"skipLibCheck": true,
"paths": {
"*": [
"node_modules/*",

View File

@@ -3,30 +3,9 @@ syntax = "proto3";
package yaak.plugins.runtime;
service PluginRuntime {
rpc hookImport (HookImportRequest) returns (HookResponse);
rpc hookExport (HookExportRequest) returns (HookResponse);
rpc hookResponseFilter (HookResponseFilterRequest) returns (HookResponse);
rpc EventStream (stream EventStreamEvent) returns (stream EventStreamEvent);
}
message PluginInfo {
string plugin = 1;
}
message HookResponse {
PluginInfo info = 1;
string data = 2;
}
message HookImportRequest {
string data = 1;
}
message HookResponseFilterRequest {
string filter = 1;
string body = 2;
string contentType = 3;
}
message HookExportRequest {
string request = 1;
message EventStreamEvent {
string event = 1;
}

View File

@@ -52,7 +52,7 @@ mkdirSync(destDir, {recursive: true});
const tmpDir = path.join(__dirname, 'tmp', Date.now().toString());
// Download GitHub release artifact
const {filePath} = await new Downloader({url, directory: tmpDir,}).download();
const {filePath} = await new Downloader({url, directory: tmpDir}).download();
// Decompress to the same directory
await decompress(filePath, tmpDir, {});

View File

@@ -3,6 +3,8 @@ const Downloader = require("nodejs-file-downloader");
const path = require("node:path");
const {rmSync, mkdirSync, cpSync} = require("node:fs");
const VERSION = '27.2';
// `${process.platform}_${process.arch}`
const MAC_ARM = 'darwin_arm64';
const MAC_X64 = 'darwin_x64';
@@ -10,10 +12,10 @@ const LNX_X64 = 'linux_x64';
const WIN_X64 = 'win32_x64';
const URL_MAP = {
[MAC_ARM]: 'https://github.com/protocolbuffers/protobuf/releases/download/v27.2/protoc-27.2-osx-aarch_64.zip',
[MAC_X64]: 'https://github.com/protocolbuffers/protobuf/releases/download/v27.2/protoc-27.2-osx-x86_64.zip',
[LNX_X64]: 'https://github.com/protocolbuffers/protobuf/releases/download/v27.2/protoc-27.2-linux-x86_64.zip',
[WIN_X64]: 'https://github.com/protocolbuffers/protobuf/releases/download/v27.2/protoc-27.2-win64.zip',
[MAC_ARM]: `https://github.com/protocolbuffers/protobuf/releases/download/v${VERSION}/protoc-${VERSION}-osx-aarch_64.zip`,
[MAC_X64]: `https://github.com/protocolbuffers/protobuf/releases/download/v${VERSION}/protoc-${VERSION}-osx-x86_64.zip`,
[LNX_X64]: `https://github.com/protocolbuffers/protobuf/releases/download/v${VERSION}/protoc-${VERSION}-linux-x86_64.zip`,
[WIN_X64]: `https://github.com/protocolbuffers/protobuf/releases/download/v${VERSION}/protoc-${VERSION}-win64.zip`,
};
const SRC_BIN_MAP = {
@@ -36,7 +38,7 @@ mkdirSync(dstDir, {recursive: true});
(async function () {
const key = `${process.platform}_${process.env.YAAK_TARGET_ARCH ?? process.arch}`;
console.log("Vendoring protoc binary for", key);
console.log(`Vendoring protoc ${VERSION} for ${key}`);
const url = URL_MAP[key];
const tmpDir = path.join(__dirname, 'tmp', Date.now().toString());

View File

@@ -1,50 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT model, created_at, updated_at, namespace, key, value\n FROM key_values\n WHERE namespace = ? AND key = ?\n ",
"describe": {
"columns": [
{
"name": "model",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 1,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "namespace",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "key",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "value",
"ordinal": 5,
"type_info": "Text"
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false,
false,
false,
false,
false
]
},
"hash": "06aaf8f4a17566f1d25da2a60f0baf4b5fc28c3cf0c001a84e25edf9eab3c7e3"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM http_responses\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "07d1a1c7b4f3d9625a766e60fd57bb779b71dae30e5bbce34885a911a5a42428"
}

View File

@@ -1,116 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, request_id, updated_at, created_at, url, status,\n status_reason, content_length, body_path, elapsed, elapsed_headers, error,\n version, remote_addr,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpResponseHeader>>\"\n FROM http_responses\n WHERE id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "request_id",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "updated_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "created_at",
"ordinal": 5,
"type_info": "Datetime"
},
{
"name": "url",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "status",
"ordinal": 7,
"type_info": "Int64"
},
{
"name": "status_reason",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "content_length",
"ordinal": 9,
"type_info": "Int64"
},
{
"name": "body_path",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "elapsed",
"ordinal": 11,
"type_info": "Int64"
},
{
"name": "elapsed_headers",
"ordinal": 12,
"type_info": "Int64"
},
{
"name": "error",
"ordinal": 13,
"type_info": "Text"
},
{
"name": "version",
"ordinal": 14,
"type_info": "Text"
},
{
"name": "remote_addr",
"ordinal": 15,
"type_info": "Text"
},
{
"name": "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>",
"ordinal": 16,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
true,
true,
true,
false
]
},
"hash": "0fa6b56f8c996d14908a56928674b4b35af5fa36f63dc48b9b66ee6dfde78976"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO workspaces (\n id, name, description, variables, setting_request_timeout,\n setting_follow_redirects, setting_validate_certificates\n )\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n description = excluded.description,\n variables = excluded.variables,\n setting_request_timeout = excluded.setting_request_timeout,\n setting_follow_redirects = excluded.setting_follow_redirects,\n setting_validate_certificates = excluded.setting_validate_certificates\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 7
},
"nullable": []
},
"hash": "12b265491d1ebba19e1ce8a660e458ffbcd8c0850aef16ba1f70e358623ac66a"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO environments (\n id, workspace_id, name, variables\n )\n VALUES (?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n variables = excluded.variables\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 4
},
"nullable": []
},
"hash": "13cb883199e81966174e6fda9c252bf7213fe01b5346266c0a89dc0ac89eda64"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO grpc_events (\n id, workspace_id, request_id, connection_id, content, event_type, metadata,\n status, error\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n content = excluded.content,\n event_type = excluded.event_type,\n metadata = excluded.metadata,\n status = excluded.status,\n error = excluded.error\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 9
},
"nullable": []
},
"hash": "14930955e8a914e292dfbebfce2ea43cc41c1d517386ed816c16d436bf626bf3"
}

View File

@@ -1,104 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, sort_priority,\n url, service, method, message, authentication_type,\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n metadata AS \"metadata!: sqlx::types::Json<Vec<GrpcMetadataEntry>>\"\n FROM grpc_requests\n WHERE workspace_id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "folder_id",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 5,
"type_info": "Datetime"
},
{
"name": "name",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "sort_priority",
"ordinal": 7,
"type_info": "Float"
},
{
"name": "url",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "service",
"ordinal": 9,
"type_info": "Text"
},
{
"name": "method",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "message",
"ordinal": 11,
"type_info": "Text"
},
{
"name": "authentication_type",
"ordinal": 12,
"type_info": "Text"
},
{
"name": "authentication!: Json<HashMap<String, JsonValue>>",
"ordinal": 13,
"type_info": "Text"
},
{
"name": "metadata!: sqlx::types::Json<Vec<GrpcMetadataEntry>>",
"ordinal": 14,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true,
false,
false,
false,
false,
false,
true,
true,
false,
true,
false,
false
]
},
"hash": "1821c2f60b9fa4514d58eb73b23e25ad683b80b9bd0c2944063190a0d0a19ee5"
}

View File

@@ -1,80 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, request_id, connection_id, created_at, content, status, error,\n event_type AS \"event_type!: GrpcEventType\",\n metadata AS \"metadata!: sqlx::types::Json<HashMap<String, String>>\"\n FROM grpc_events\n WHERE connection_id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "request_id",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "connection_id",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 5,
"type_info": "Datetime"
},
{
"name": "content",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "status",
"ordinal": 7,
"type_info": "Int64"
},
{
"name": "error",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "event_type!: GrpcEventType",
"ordinal": 9,
"type_info": "Text"
},
{
"name": "metadata!: sqlx::types::Json<HashMap<String, String>>",
"ordinal": 10,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
true,
true,
false,
false
]
},
"hash": "18ada3bb42c29f1940ab2e61961d79cdd69210f3dc2076aedcadeba8e34dcb6e"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO settings (id)\n VALUES ('default')\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 0
},
"nullable": []
},
"hash": "2c181a4dc13efc52fe6a5a68291c5678a9624020df4ea744e78396f6926d5c88"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO http_responses (\n id, request_id, workspace_id, elapsed, elapsed_headers, url, status, status_reason,\n content_length, body_path, headers, version, remote_addr\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 13
},
"nullable": []
},
"hash": "2c9658a639c5e4994ae9c8ec30bd4e40a1945d640962991f879928619950ef62"
}

View File

@@ -1,92 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, request_id, created_at, updated_at, service,\n method, elapsed, status, error, url,\n trailers AS \"trailers!: sqlx::types::Json<HashMap<String, String>>\"\n FROM grpc_connections\n WHERE request_id = ?\n ORDER BY created_at DESC\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "request_id",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 5,
"type_info": "Datetime"
},
{
"name": "service",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "method",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "elapsed",
"ordinal": 8,
"type_info": "Int64"
},
{
"name": "status",
"ordinal": 9,
"type_info": "Int64"
},
{
"name": "error",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "url",
"ordinal": 11,
"type_info": "Text"
},
{
"name": "trailers!: sqlx::types::Json<HashMap<String, String>>",
"ordinal": 12,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
false
]
},
"hash": "3e8651cca7feecc208a676dfd24c7d8775040d5287c16890056dcb474674edfb"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM grpc_connections\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "42bc0ded60b44dab19daf6d8fc7df83d83af5d88ea0b84514fdc877a668c27cd"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM http_requests\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "448a1d1f1866ab42c0f81fcf8eb2930bf21dfdd43ca4831bc1a198cf45ac3732"
}

View File

@@ -1,62 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, created_at, updated_at, folder_id, name, sort_priority\n FROM folders\n WHERE workspace_id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "folder_id",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "name",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "sort_priority",
"ordinal": 7,
"type_info": "Float"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
true,
false,
false
]
},
"hash": "558e72df3c6f2635c6b3d52a199f9a5f7a3d82b379ff9af36645dcfb92548fdd"
}

View File

@@ -1,110 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, url, method,\n body_type, authentication_type, sort_priority,\n url_parameters AS \"url_parameters!: sqlx::types::Json<Vec<HttpUrlParameter>>\",\n body AS \"body!: Json<HashMap<String, JsonValue>>\",\n authentication AS \"authentication!: Json<HashMap<String, JsonValue>>\",\n headers AS \"headers!: sqlx::types::Json<Vec<HttpRequestHeader>>\"\n FROM http_requests\n WHERE id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "folder_id",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 5,
"type_info": "Datetime"
},
{
"name": "name",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "url",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "method",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "body_type",
"ordinal": 9,
"type_info": "Text"
},
{
"name": "authentication_type",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "sort_priority",
"ordinal": 11,
"type_info": "Float"
},
{
"name": "url_parameters!: sqlx::types::Json<Vec<HttpUrlParameter>>",
"ordinal": 12,
"type_info": "Text"
},
{
"name": "body!: Json<HashMap<String, JsonValue>>",
"ordinal": 13,
"type_info": "Text"
},
{
"name": "authentication!: Json<HashMap<String, JsonValue>>",
"ordinal": 14,
"type_info": "Text"
},
{
"name": "headers!: sqlx::types::Json<Vec<HttpRequestHeader>>",
"ordinal": 15,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
true,
false,
false,
false,
false,
false,
true,
true,
false,
false,
false,
false,
false
]
},
"hash": "573db23160de025e5c72efb90be7fff5e3ec4619b962d149fdd4d618fe02c680"
}

View File

@@ -1,56 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, created_at, updated_at, name,\n variables AS \"variables!: sqlx::types::Json<Vec<EnvironmentVariable>>\"\n FROM environments\n WHERE id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "name",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>",
"ordinal": 6,
"type_info": "Null"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "5765e9565a8b89c5bc2d72197e0e4a1093739e9abba69f6fe5527d453fab4db8"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO grpc_requests (\n id, name, workspace_id, folder_id, sort_priority, url, service, method, message,\n authentication_type, authentication, metadata\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n workspace_id = excluded.workspace_id,\n name = excluded.name,\n folder_id = excluded.folder_id,\n sort_priority = excluded.sort_priority,\n url = excluded.url,\n service = excluded.service,\n method = excluded.method,\n message = excluded.message,\n authentication_type = excluded.authentication_type,\n authentication = excluded.authentication,\n metadata = excluded.metadata\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 12
},
"nullable": []
},
"hash": "5af82cd333895d3d7d67a92f37b0feb338f615b88aea2bd09cb5809008c645a3"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO http_requests (\n id, workspace_id, folder_id, name, url, url_parameters, method, body, body_type,\n authentication, authentication_type, headers, sort_priority\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n workspace_id = excluded.workspace_id,\n name = excluded.name,\n folder_id = excluded.folder_id,\n method = excluded.method,\n headers = excluded.headers,\n body = excluded.body,\n body_type = excluded.body_type,\n authentication = excluded.authentication,\n authentication_type = excluded.authentication_type,\n url = excluded.url,\n url_parameters = excluded.url_parameters,\n sort_priority = excluded.sort_priority\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 13
},
"nullable": []
},
"hash": "5f2f40062abbe93e23b38876319cf16d4d2b3f8d0be32ffe7848528c725e1429"
}

View File

@@ -1,56 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, created_at, updated_at, workspace_id, name,\n cookies AS \"cookies!: sqlx::types::Json<Vec<JsonValue>>\"\n FROM cookie_jars WHERE workspace_id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "workspace_id",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "name",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "cookies!: sqlx::types::Json<Vec<JsonValue>>",
"ordinal": 6,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "612efa9ac45723dc604a88f5e7e288b4055fec4ba7d9102131bd255c037fa021"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO grpc_connections (\n id, workspace_id, request_id, service, method, elapsed,\n status, error, trailers, url\n )\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n service = excluded.service,\n method = excluded.method,\n elapsed = excluded.elapsed,\n status = excluded.status,\n error = excluded.error,\n trailers = excluded.trailers,\n url = excluded.url\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 10
},
"nullable": []
},
"hash": "66deed028199c78ed15ea2f837907887c2a2cb564d1d076dd4ebf0ecbc82e098"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n UPDATE settings SET (\n theme, appearance, theme_dark, theme_light, update_channel,\n interface_font_size, interface_scale, editor_font_size, editor_soft_wrap,\n open_workspace_new_window\n ) = (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) WHERE id = 'default';\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 10
},
"nullable": []
},
"hash": "6b5edf45a6799cd7f87c23a3c7f818ad110d58c601f694a619d9345ae9e8e11d"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM workspaces\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "84be2b954870ab181738656ecd4d03fca2ff21012947014c79626abfce8e999b"
}

View File

@@ -1,74 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, created_at, updated_at, name, description, setting_request_timeout,\n setting_follow_redirects, setting_validate_certificates,\n variables AS \"variables!: sqlx::types::Json<Vec<EnvironmentVariable>>\"\n FROM workspaces\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "name",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "description",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "setting_request_timeout",
"ordinal": 6,
"type_info": "Int64"
},
{
"name": "setting_follow_redirects",
"ordinal": 7,
"type_info": "Bool"
},
{
"name": "setting_validate_certificates",
"ordinal": 8,
"type_info": "Bool"
},
{
"name": "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>",
"ordinal": 9,
"type_info": "Text"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "8dfbae65ddec905ea3734448cc9f7029b6c78de227c6fa3a85d75d0a7f21e0e9"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO folders (\n id, workspace_id, folder_id, name, sort_priority\n )\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n folder_id = excluded.folder_id,\n sort_priority = excluded.sort_priority\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 5
},
"nullable": []
},
"hash": "9238f94c688d91f42627e5b73c627c514bab4039ab5edadc79b77dfdfd63b208"
}

View File

@@ -1,80 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, request_id, connection_id, created_at, content, status, error,\n event_type AS \"event_type!: GrpcEventType\",\n metadata AS \"metadata!: sqlx::types::Json<HashMap<String, String>>\"\n FROM grpc_events\n WHERE id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "request_id",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "connection_id",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 5,
"type_info": "Datetime"
},
{
"name": "content",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "status",
"ordinal": 7,
"type_info": "Int64"
},
{
"name": "error",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "event_type!: GrpcEventType",
"ordinal": 9,
"type_info": "Text"
},
{
"name": "metadata!: sqlx::types::Json<HashMap<String, String>>",
"ordinal": 10,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
true,
true,
false,
false
]
},
"hash": "92d8f003a8f7df692345f2d2fd2504c9222645976e3433e32e190f4ee4bf100d"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM folders\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "93aea3881dffb70a82325263740a0bb6477e78f27991ce7456b394e84383acb6"
}

View File

@@ -1,74 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, created_at, updated_at, name, description, setting_request_timeout,\n setting_follow_redirects, setting_validate_certificates,\n variables AS \"variables!: sqlx::types::Json<Vec<EnvironmentVariable>>\"\n FROM workspaces WHERE id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 2,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "name",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "description",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "setting_request_timeout",
"ordinal": 6,
"type_info": "Int64"
},
{
"name": "setting_follow_redirects",
"ordinal": 7,
"type_info": "Bool"
},
{
"name": "setting_validate_certificates",
"ordinal": 8,
"type_info": "Bool"
},
{
"name": "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>",
"ordinal": 9,
"type_info": "Null"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "9ba3f783238b77637ffded4171b2fbb5e5ad0be952a0d832448d65cc5f0effc1"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n UPDATE grpc_connections\n SET (elapsed) = (-1)\n WHERE elapsed = 0;\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 0
},
"nullable": []
},
"hash": "a690a04cd1ebe8c3dbfd0cd98ae4ef093a1696d7b7ecaf694d12e5fafd62b685"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n UPDATE http_responses\n SET (elapsed, status_reason) = (-1, 'Cancelled')\n WHERE elapsed = 0;\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 0
},
"nullable": []
},
"hash": "ac1b4ffbd98b67f0a1a74e3525387d679dd6f44c561d55c7bbea747053e53671"
}

View File

@@ -1,116 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, request_id, updated_at, created_at, url, status,\n status_reason, content_length, body_path, elapsed, elapsed_headers, error,\n version, remote_addr,\n headers AS \"headers!: sqlx::types::Json<Vec<HttpResponseHeader>>\"\n FROM http_responses\n WHERE request_id = ?\n ORDER BY created_at DESC\n LIMIT ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "request_id",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "updated_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "created_at",
"ordinal": 5,
"type_info": "Datetime"
},
{
"name": "url",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "status",
"ordinal": 7,
"type_info": "Int64"
},
{
"name": "status_reason",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "content_length",
"ordinal": 9,
"type_info": "Int64"
},
{
"name": "body_path",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "elapsed",
"ordinal": 11,
"type_info": "Int64"
},
{
"name": "elapsed_headers",
"ordinal": 12,
"type_info": "Int64"
},
{
"name": "error",
"ordinal": 13,
"type_info": "Text"
},
{
"name": "version",
"ordinal": 14,
"type_info": "Text"
},
{
"name": "remote_addr",
"ordinal": 15,
"type_info": "Text"
},
{
"name": "headers!: sqlx::types::Json<Vec<HttpResponseHeader>>",
"ordinal": 16,
"type_info": "Text"
}
],
"parameters": {
"Right": 2
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
true,
true,
true,
false,
false,
true,
true,
true,
false
]
},
"hash": "ac38621cd947c3be9ca0d8ea73325fe35c3866d16f6482fc32c23762f112dc83"
}

View File

@@ -1,62 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, created_at, updated_at, folder_id, name, sort_priority\n FROM folders\n WHERE id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "folder_id",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "name",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "sort_priority",
"ordinal": 7,
"type_info": "Float"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
true,
false,
false
]
},
"hash": "ae98a7b35a5cb80a4bcd04faa22545deac2a5e9bfb814b60191f16b98ed49796"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM environments\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "aeb0712785a9964d516dc8939bc54aa8206ad852e608b362d014b67a0f21b0ed"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO cookie_jars (\n id, workspace_id, name, cookies\n )\n VALUES (?, ?, ?, ?)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n cookies = excluded.cookies\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 4
},
"nullable": []
},
"hash": "b3fae40a793a6724dd2286a9ca4bc0a9c000a631ee0d751a9dc4f3e76de3d57c"
}

View File

@@ -1,12 +0,0 @@
{
"db_name": "SQLite",
"query": "\n DELETE FROM cookie_jars\n WHERE id = ?\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 1
},
"nullable": []
},
"hash": "b98609f65dd3a6bbd1ea8dc8bed2840a6d5d13fec1bbc0aa61ca4f60de98a09c"
}

View File

@@ -1,56 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT id, workspace_id, model, created_at, updated_at, name,\n variables AS \"variables!: sqlx::types::Json<Vec<EnvironmentVariable>>\"\n FROM environments\n WHERE workspace_id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 3,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "name",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "variables!: sqlx::types::Json<Vec<EnvironmentVariable>>",
"ordinal": 6,
"type_info": "Null"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false
]
},
"hash": "ba2b34a77723f24f86e4c3c45274dbfec6ca130e16e592f948844c037bdc0593"
}

View File

@@ -1,92 +0,0 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, request_id, created_at, updated_at, service,\n method, elapsed, status, error, url,\n trailers AS \"trailers!: sqlx::types::Json<HashMap<String, String>>\"\n FROM grpc_connections\n WHERE id = ?\n ",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "model",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "workspace_id",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "request_id",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 4,
"type_info": "Datetime"
},
{
"name": "updated_at",
"ordinal": 5,
"type_info": "Datetime"
},
{
"name": "service",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "method",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "elapsed",
"ordinal": 8,
"type_info": "Int64"
},
{
"name": "status",
"ordinal": 9,
"type_info": "Int64"
},
{
"name": "error",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "url",
"ordinal": 11,
"type_info": "Text"
},
{
"name": "trailers!: sqlx::types::Json<HashMap<String, String>>",
"ordinal": 12,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true,
false,
false
]
},
"hash": "d4b64c466624eb75e0f5bd201ebfb6a73d25eb7c9e09cb9690afdb7fef5fca8b"
}

Some files were not shown because too many files have changed in this diff Show More