Compare commits

...

985 Commits

Author SHA1 Message Date
Gregory Schier
d586ec5fb4 Remove canny-specific links 2024-07-29 11:50:00 -07:00
Gregory Schier
ad8a4933da Generate v1 updater artifacts 2024-07-28 18:32:50 -07:00
Gregory Schier
499d0b09ba Update vendor scripts again 2024-07-28 16:04:05 -07:00
Gregory Schier
ac1181c1b4 Refine vendor scripts 2024-07-28 15:56:48 -07:00
Gregory Schier
b9671781d3 Merge remote-tracking branch 'origin/master' 2024-07-28 15:40:37 -07:00
Gregory Schier
42fd7cb21e Fix killing command on Windows 2024-07-28 15:40:19 -07:00
Gregory Schier
fe9f765c1d Send full request to cmd_send_http_request to prevent
update->send race
2024-07-28 15:33:12 -07:00
Gregory Schier
087a1e5ea1 Remove command group 2024-07-28 14:13:01 -07:00
Gregory Schier
6e156497da Upgrade Tauri dependencies 2024-07-28 13:44:50 -07:00
Gregory Schier
ad3c2ed113 Better wait for kill signal 2024-07-27 09:13:34 -07:00
Gregory Schier
166bae6104 Fix spin lock 2024-07-27 09:05:43 -07:00
Gregory Schier
b3e6a2b34f Add sleep to child polling 2024-07-27 08:26:14 -07:00
Gregory Schier
547f1c9139 Better NodeJS vendoring 2024-07-26 00:01:21 -07:00
Gregory Schier
4d7ded61f8 Put updater back into targets 2024-07-25 20:56:47 -07:00
Gregory Schier
c92472dbac Fix targets 2024-07-25 13:33:00 -07:00
Gregory Schier
d347f2db77 Log when plugin runtime exits 2024-07-25 09:28:08 -07:00
Gregory Schier
80c1675331 Remove unused import 2024-07-25 07:58:04 -07:00
Gregory Schier
23fba45fcb Fix dunce usage 2024-07-25 07:52:53 -07:00
Gregory Schier
80777f712c Convert UNC paths in more places 2024-07-25 07:47:00 -07:00
Gregory Schier
6ffb0015c6 Use process group for node runtime 2024-07-24 10:14:40 -07:00
Gregory Schier
9d9b855c04 Remove UNC prefix for protoc exec 2024-07-24 08:07:06 -07:00
Gregory Schier
e7cbcc7b20 Protoc stderr into error 2024-07-24 07:41:51 -07:00
Gregory Schier
20a5ab3666 Fix external bin names 2024-07-24 07:05:05 -07:00
Gregory Schier
311fda887f Unique sidecar names 2024-07-24 07:04:14 -07:00
Gregory Schier
55e33df8d6 Fix NodeJS vendoring on Linux 2024-07-23 20:41:50 -07:00
Gregory Schier
71c9c8ba8c Fix nodejs vendoring 2024-07-23 15:37:27 -07:00
Gregory Schier
11c2b9bb2c Fix Windows vendor tmp path 2024-07-23 15:28:31 -07:00
Gregory Schier
5cfd208c23 NODE_ARCH -> YAAK_TARGET_ARCH 2024-07-23 14:52:25 -07:00
Gregory Schier
3a0b647ce4 Fix protoc vendoring 2024-07-23 14:35:39 -07:00
Gregory Schier
8367835061 Fix NodeJS vendoring 2024-07-23 14:31:53 -07:00
Gregory Schier
55276b968e Response info in new tab 2024-07-23 12:13:09 -07:00
Gregory Schier
9e04226097 Use SelectFile component in more places 2024-07-23 11:54:35 -07:00
Gregory Schier
51487d5412 Guess mime type on multi-part when not set 2024-07-23 11:39:21 -07:00
Gregory Schier
0dccba4ab2 Set minimum windows size 2024-07-23 11:35:16 -07:00
Gregory Schier
13183ae837 Better handling of large responses 2024-07-23 08:59:15 -07:00
Gregory Schier
f24fd13c45 Better import flow 2024-07-23 08:29:09 -07:00
Gregory Schier
972dffe959 Revert version 2024-07-23 07:31:00 -07:00
Gregory Schier
9f7033ab06 Fix notification status code handling 2024-07-23 07:30:47 -07:00
Gregory Schier
cd07123157 Back to @latest 2024-07-22 18:28:27 -07:00
Gregory Schier
b62901e295 Force bump Yaak CLI 2024-07-22 18:27:24 -07:00
Gregory Schier
96996f73d5 Remove test runs 2024-07-22 18:12:12 -07:00
Gregory Schier
4782fd376b Checkout plugins later in the release workflow 2024-07-22 18:08:49 -07:00
Gregory Schier
41dfa15feb Various tweaks 2024-07-22 17:55:28 -07:00
Gregory Schier
47d4fffc20 Plugin tweaks 2024-07-22 12:17:46 -07:00
Gregory Schier
994f314cff Better wording for moving workspace 2024-07-22 09:46:46 -07:00
Gregory Schier
0f8f086e01 Lowercase product name for Linux 2024-07-22 09:03:31 -07:00
Gregory Schier
19280c3bbc Some small refactoring 2024-07-21 22:18:45 -07:00
Gregory Schier
3cd7c1ef2e From SEA to regular NodeJS 2024-07-21 22:14:17 -07:00
Gregory Schier
6a5f61e84b Fixed plugins on Windows 2024-07-21 16:01:13 -07:00
Gregory Schier
a444984aed Fix import plugin hook 2024-07-21 15:46:47 -07:00
Gregory Schier
c0e253ef84 Change app name 2024-07-20 11:33:02 -07:00
Gregory Schier
7910d1b0fc Fix Windows key map 2024-07-20 10:49:08 -07:00
Gregory Schier
d26d20180e Don't resign SEA binary 2024-07-20 10:28:50 -07:00
Gregory Schier
54d9a78474 Fix tool location 2024-07-19 17:38:57 -07:00
Gregory Schier
216c41d8cf Fix deps 2024-07-19 17:31:37 -07:00
Gregory Schier
bf2c392380 Dynamic signtool.exe location 2024-07-19 17:30:20 -07:00
Gregory Schier
1835fa3ba4 Fix signtool path 2024-07-19 17:28:13 -07:00
Gregory Schier
d701381041 Add ampersand 2024-07-19 17:21:23 -07:00
Gregory Schier
89c19858df Fix signtool path? 2024-07-19 17:18:52 -07:00
Gregory Schier
01136921df Absolute signtool path 2024-07-19 17:11:53 -07:00
Gregory Schier
17ab201b96 Remove tmp dirs 2024-07-19 16:58:55 -07:00
Gregory Schier
5d3182da4c Again 2024-07-19 16:53:37 -07:00
Gregory Schier
293a91012f Better tmp dir creation 2024-07-19 16:51:05 -07:00
Gregory Schier
a43f601b6a Fix tmpdir on Windows 2024-07-19 16:43:22 -07:00
Gregory Schier
447932697d Fix script for Windows? 2024-07-19 16:30:20 -07:00
Gregory Schier
0c75c2289e Add protoc back 2024-07-19 16:23:16 -07:00
Gregory Schier
c97c9b599d Install Yaak CLI 2024-07-19 16:13:39 -07:00
Gregory Schier
fc972b04f7 Oops, fix arch 2024-07-19 16:10:40 -07:00
Gregory Schier
e8410f70a1 Fix Node arch 2024-07-19 16:08:37 -07:00
Gregory Schier
70c63fc63c Debug log 2024-07-19 16:01:05 -07:00
Gregory Schier
c4e1353b51 Add repo token 2024-07-19 15:45:54 -07:00
Gregory Schier
fd6959e868 Add protoc installation 2024-07-19 15:38:44 -07:00
Gregory Schier
854c19c1a1 Add download-protoc to build 2024-07-19 15:25:20 -07:00
Gregory Schier
9370b4879b Deps for plugin-runtime 2024-07-19 15:16:35 -07:00
Gregory Schier
0b2da8e7ae Ignore plugins checkout for eslint 2024-07-19 15:13:19 -07:00
Gregory Schier
2e0982b999 Fix is valid 2024-07-19 15:09:45 -07:00
Gregory Schier
2ec3be4374 Update yaak cli path 2024-07-19 14:39:48 -07:00
Gregory Schier
b1e6f52396 Fix Go install 2024-07-19 14:28:59 -07:00
Gregory Schier
5ce928068c Fix again 2024-07-19 14:28:05 -07:00
Gregory Schier
76b1e5b103 Fix setup go 2024-07-19 14:26:47 -07:00
Gregory Schier
4a95128416 Install Yaak CLI with Go 2024-07-19 14:25:21 -07:00
Gregory Schier
cae6eb2b24 Specify version 2024-07-19 14:06:33 -07:00
Gregory Schier
cdcfb585cf Fix directory 2024-07-19 14:01:21 -07:00
Gregory Schier
d4d56dfe1b Install Yaak CLI in workflow 2024-07-19 13:57:04 -07:00
Gregory Schier
f6c491498b Fix checkout 2024-07-19 11:16:15 -07:00
Gregory Schier
e01cdd1dad Fix working directory 2024-07-19 11:13:58 -07:00
Gregory Schier
9e41d366c1 Remove failing step 2024-07-19 11:10:45 -07:00
Gregory Schier
fee46de974 Move ci/build to workflow 2024-07-19 11:09:07 -07:00
Gregory Schier
fa14b7aaf8 Debug where npm is 2024-07-19 11:06:39 -07:00
Gregory Schier
bb44bfca49 Inherit env for exec 2024-07-19 11:04:03 -07:00
Gregory Schier
6fcb3948ce TRy again 2024-07-19 11:02:15 -07:00
Gregory Schier
f716291328 Add debug 2024-07-19 10:58:48 -07:00
Gregory Schier
9f8eabe22b Fix copy plugins script 2024-07-19 10:53:39 -07:00
Gregory Schier
6d9e14784f Fix workflow 2024-07-19 10:49:29 -07:00
Gregory Schier
1d5f3260e2 NodeJS Plugin Runtime (#53) 2024-07-19 10:41:47 -07:00
Gregory Schier
883fcdb6b8 Update useSaveResponse.tsx 2024-06-27 22:05:41 -07:00
Gregory Schier
c9040a6e5f Fix RadioDropdown key 2024-06-24 11:18:38 -07:00
Gregory Schier
151450f55b Better performance on large workspaces 2024-06-21 10:53:11 -07:00
Gregory Schier
5722880890 Better active workspace change notification 2024-06-21 10:11:00 -07:00
Gregory Schier
d361a40903 Consolidate any* hooks 2024-06-21 10:01:45 -07:00
Gregory Schier
cd9e720835 Add mutationKey everywhere 2024-06-21 09:25:25 -07:00
Gregory Schier
50e2ab3a03 Move request to another workspace (#52) 2024-06-21 09:01:18 -07:00
Gregory Schier
dc5dfeb022 Bump CI node version 2024-06-20 16:45:59 -07:00
Gregory Schier
0b8a18edae Safe URI for reflection 2024-06-20 13:11:40 -07:00
Gregory Schier
0bb3f14b4c Fix button styles 2024-06-20 12:55:13 -07:00
Gregory Schier
c18d30b89f Refactor gRPC reflection! 2024-06-20 12:49:58 -07:00
Gregory Schier
8f06a834c8 Update script 2024-06-20 09:23:50 -07:00
Gregory Schier
bd948f9cd6 Actually write the file 2024-06-20 09:20:04 -07:00
Gregory Schier
d70254bcdc Generic build version 2024-06-20 09:17:28 -07:00
Gregory Schier
fac5385d5d Bump version 2024-06-20 09:07:38 -07:00
Gregory Schier
e8bcc695bb Better fallback request name generation 2024-06-20 09:03:24 -07:00
Gregory Schier
88aeb0e530 Fix GRPC with files not refreshing, and tight render loop 2024-06-20 08:40:10 -07:00
Gregory Schier
92b1582232 Better gRPC reflection errors 2024-06-18 10:54:39 -07:00
Gregory Schier
196990c077 Bump version 2024-06-18 10:41:22 -07:00
Gregory Schier
c42b8cf538 Editor autocomplete same font size as editor 2024-06-18 09:43:51 -07:00
Gregory Schier
085274c960 Move GraphQL introspection out of LocalStorage 2024-06-18 09:43:28 -07:00
Gregory Schier
7ef187abf6 REvert other thing 2024-06-17 17:05:51 -07:00
Gregory Schier
12eac34d95 Fix editor tags wrapping behavior 2024-06-17 17:05:29 -07:00
Gregory Schier
c29b3c6509 Change version 2024-06-17 15:09:44 -07:00
Gregory Schier
7faa423aba Recursive environments 2024-06-17 12:24:06 -07:00
Gregory Schier
5b2162e48d Fix flash loading response viewer 2024-06-17 11:43:45 -07:00
Gregory Schier
ee776143b2 Fix parsing notification timestamp 2024-06-17 11:43:20 -07:00
Gregory Schier
7a18fb29e4 More dynamic plugin access 2024-06-15 22:13:01 -07:00
Gregory Schier
4485cad9e8 Workspace dropdown to RadioDropdown 2024-06-14 17:07:35 -07:00
Gregory Schier
33763b6d2f Fix plugins 2024-06-13 07:03:50 -07:00
Gregory Schier
641fe86cf7 Support nested functions 2024-06-12 23:13:36 -07:00
Gregory Schier
65e7c804d7 Parse window title and theme better 2024-06-12 10:15:14 -07:00
Gregory Schier
23ec8bee8f Move binary detection to TextViewer 2024-06-12 09:47:34 -07:00
Gregory Schier
8aeeaa2e09 Bump version 2024-06-12 00:23:50 -07:00
Gregory Schier
57f01d249e Entitlement for v8/Deno 2024-06-12 00:23:32 -07:00
Gregory Schier
6c5a914db6 Variables in pair editor 2024-06-11 12:33:43 -07:00
Gregory Schier
155e51aa74 Put toast on top 2024-06-11 12:04:46 -07:00
Gregory Schier
012a984456 Fix bulk edit label 2024-06-11 09:02:11 -07:00
Gregory Schier
25800202f2 Bump version 2024-06-11 08:35:29 -07:00
Gregory Schier
a058064f1f Adjust fuzzy threshold 2024-06-10 23:25:57 -07:00
Gregory Schier
9f40804532 Fix window drag above cmd+k 2024-06-10 23:24:03 -07:00
Gregory Schier
26cc467858 Fix delete request in sidebar 2024-06-10 23:17:12 -07:00
Gregory Schier
be1cf7bf65 Don't arrow-nav to hidden dropdown items 2024-06-10 23:16:37 -07:00
Gregory Schier
ea4f104ca7 Bulk edit environments 2024-06-10 23:16:21 -07:00
Gregory Schier
32a28a3170 Fix hotkey react keys 2024-06-10 22:29:06 -07:00
Gregory Schier
6215914212 Cmd Palette Improvements (#50)
- Fuzzy matching
- Show hotkeys
- Add actions
2024-06-10 21:37:41 -07:00
Gregory Schier
a2dbd7f849 Download Active Response (#49)
This PR prompts you to save un-previewable file types and adds an option
to save to the response history.
2024-06-10 16:36:09 -07:00
Gregory Schier
5bb9815f4b Remove jump to request hotkey 2024-06-10 09:00:26 -07:00
Gregory Schier
7cd8ac3b21 Response viewer for PDF (#48)
This PR adds a response viewer for PDF files using `react-pdf`
2024-06-10 08:57:08 -07:00
Gregory Schier
456d3aaf52 Don't focus sidebar on cmd+0 2024-06-09 08:36:12 -07:00
Gregory Schier
113743f7cf Try fix CI 2024-06-09 08:09:47 -07:00
Gregory Schier
01a4d6f4ac Bump version 2024-06-09 07:56:44 -07:00
Gregory Schier
ff5cfe744e Remove CI again 2024-06-09 07:56:09 -07:00
Gregory Schier
29c4b51f54 Add it back 2024-06-09 07:23:28 -07:00
Gregory Schier
2f74bf8db8 Remove CI in release stage 2024-06-09 07:22:49 -07:00
Gregory Schier
b30d784d06 Remove GH Action step names 2024-06-09 07:16:53 -07:00
Gregory Schier
ac0adaf3d8 Back to other 2024-06-09 07:14:07 -07:00
Gregory Schier
c246d3a748 Fix action step 2024-06-09 07:10:44 -07:00
Gregory Schier
ae40728c1e Rust cache release 2024-06-09 07:09:46 -07:00
Gregory Schier
0430ec883b Cmd jump to request 2024-06-09 07:03:16 -07:00
Gregory Schier
eba6f33536 Only CI on PR 2024-06-09 06:47:47 -07:00
Gregory Schier
dae2873376 Fix Rust lint 2024-06-09 06:43:53 -07:00
Gregory Schier
cb2f56d9a1 Remove slow udeps from CI 2024-06-08 21:03:17 -07:00
Gregory Schier
7d82aa70a4 Rust CI to release 2024-06-08 20:51:03 -07:00
Gregory Schier
adea234987 Try again 2024-06-08 20:47:48 -07:00
Gregory Schier
37d0b487b8 Remove cache 2024-06-08 20:47:18 -07:00
Gregory Schier
d507f8c99f Try removing git db 2024-06-08 20:44:58 -07:00
Gregory Schier
60406ac83f Cargo check 2024-06-08 20:36:56 -07:00
Gregory Schier
8fe6f3a335 Remove Cargo fmt 2024-06-08 20:34:24 -07:00
Gregory Schier
69e027c302 Fix tests 2024-06-08 20:30:52 -07:00
Gregory Schier
4232bdd298 Cargo format 2024-06-08 20:28:45 -07:00
Gregory Schier
ef1c5da027 Set max dropdown width 2024-06-08 19:55:25 -07:00
Gregory Schier
e250326868 Bump version 2024-06-08 19:46:32 -07:00
Gregory Schier
125f503cfa Upgrade reqwest and add ALPN for http/2 2024-06-08 19:40:35 -07:00
Gregory Schier
8f086425fe Fix curl exporter 2024-06-08 19:40:11 -07:00
Gregory Schier
ae2da73873 Fix cmd+k filtering 2024-06-07 22:52:23 -07:00
Gregory Schier
3cd6688ffb Remove delete hotkey for request 2024-06-07 22:52:10 -07:00
Gregory Schier
8538da8879 Short method tags and hide active in cmd+k 2024-06-07 22:39:11 -07:00
Gregory Schier
b0e4ece278 Add command palette (#46)
This PR finished the initial PoC command palette. It currently only
supports switching between requests and workspaces, but can easily be
extended for more.
2024-06-07 21:59:57 -07:00
Gregory Schier
5e058af03e Bulk editor (#45)
Bulk editor for all pair editors except multipart/form-data
2024-06-07 13:42:08 -07:00
Gregory Schier
5108bc92f3 Fix rose pine and method tags 2024-06-07 12:01:31 -07:00
Gregory Schier
3c5fdcb18d Generate things 2024-06-07 11:58:08 -07:00
Gregory Schier
4672de4a47 Remove tauri-plugin-deep-link 2024-06-07 11:57:44 -07:00
Gregory Schier
239f6da141 Update CI script 2024-06-07 11:01:21 -07:00
Gregory Schier
ec148d1736 Fix workflow 2024-06-07 10:54:50 -07:00
Gregory Schier
392b549646 Deno plugins (#42)
Switch from BoaJS to Deno core
2024-06-07 10:47:41 -07:00
Gregory Schier
993d4dc65d Open workspace pref (#44)
Ability to remember workspace window opening selection.
2024-06-07 09:04:53 -07:00
Gregory Schier
e326405f4f Templating (#43)
Add new `templating` crate with custom parser/renderer for dealing with
variables
2024-06-07 08:39:12 -07:00
Gregory Schier
a83e094f00 Fix copy-as-curl variables 2024-06-05 06:53:38 -07:00
Gregory Schier
e683a2cb2a Bump version 2024-06-04 23:53:45 -07:00
Gregory Schier
1f231c2722 Only release on tag again 2024-06-04 23:53:31 -07:00
Gregory Schier
0fc2575ef6 Fix default workspace settings on initial Workspace 2024-06-04 17:06:40 -07:00
Gregory Schier
44c718e6bc Better analytics error log 2024-06-04 16:27:22 -07:00
Gregory Schier
495df847ab Merge branch 'beta' into master 2024-06-04 15:01:55 -07:00
Gregory Schier
5dbb9852f3 Bump version 2024-06-04 15:00:34 -07:00
Gregory Schier
82d3304c38 Hopefully fix AppImage build not finding migrations. I think it was because the productName had a capital Yaak in it. 2024-06-04 14:59:40 -07:00
Gregory Schier
5e2218fd64 Remove Windows plugin 2024-06-04 02:56:52 -07:00
Gregory Schier
5b12fad173 2024.5.0-beta.2 (#38) 2024-06-03 14:03:25 -07:00
Gregory Schier
8d6f23eacb Bump version 2024-06-03 14:00:49 -07:00
Gregory Schier
75a09859bc Move Postman to first plugin 2024-06-03 14:00:40 -07:00
Gregory Schier
dc47c4ceba Preserve JSON/XPath filter (Closes #22) 2024-06-03 13:49:51 -07:00
Gregory Schier
8ae0290aed Don't send request on completion (Fixes #27) 2024-06-03 07:49:13 -07:00
Gregory Schier
f01d1e704b Don't always change request method. Closes #29 2024-06-03 07:26:40 -07:00
Gregory Schier
3f72996e64 Tweak settings labels 2024-06-02 23:54:00 -07:00
Gregory Schier
fe862517fb Fix dropdown icon color 2024-06-02 23:50:26 -07:00
Gregory Schier
b39335dc4f Don't call is_fullscreen so much 2024-06-02 23:38:56 -07:00
Gregory Schier
8f3bdb5039 Fix autocomplete for environment editor names 2024-06-02 17:52:51 -07:00
Gregory Schier
b47ec01f9c <Select> uses custom component on Windows 2024-06-02 16:57:23 -07:00
Gregory Schier
36728d1d1f Tweak Moonlight theme 2024-06-02 15:48:27 -07:00
Gregory Schier
c3f0351445 Fix font size 2024-06-02 11:53:41 -07:00
Gregory Schier
9a5364187c Better invalid URL errors 2024-06-02 11:53:35 -07:00
Gregory Schier
a9db14994f Import content-type from Postman multi-part form 2024-06-02 11:53:25 -07:00
Gregory Schier
2383e8468f Also release on beta branch 2024-05-31 10:37:21 -07:00
Gregory Schier
a79d485b6a Bump version 2024-05-31 09:46:57 -07:00
Gregory Schier
7eb931d689 Fix multipart files 2024-05-31 09:32:16 -07:00
Gregory Schier
995cd2aa7b Fade in window contents (Layout) 2024-05-31 09:16:52 -07:00
Gregory Schier
1ce50e0c1b Window border on Linux 2024-05-31 08:43:35 -07:00
Gregory Schier
bce3d26a1a Try tweaking settings/theme for Windows. Setting the theme didn't work. 2024-05-30 23:38:49 -07:00
Gregory Schier
d9680ad0fa Ignore stoplights when centering settings title 2024-05-30 12:33:59 -07:00
Gregory Schier
e2e026e1ff Tweak appearance settings 2024-05-30 12:32:12 -07:00
Gregory Schier
16739d9a37 Dracula theme 2024-05-30 11:56:57 -07:00
Gregory Schier
524a4f2275 Tweak 2024-05-30 11:45:40 -07:00
Gregory Schier
ba66883dc2 Theme analytics and Moonlight 2024-05-30 11:00:50 -07:00
Gregory Schier
2caa735a2e Tweak settings for release 2024-05-30 10:28:59 -07:00
Gregory Schier
90637fda6b Unlisten to window event and fix hotkeys 2024-05-30 00:29:01 -07:00
Gregory Schier
2cef46b46a Window title working again 2024-05-30 00:11:55 -07:00
Gregory Schier
14b3abf76c Fix window stoplights 2024-05-29 22:59:34 -07:00
Gregory Schier
8cd3961f87 Custom font sizes and better zoom 2024-05-29 12:10:01 -07:00
Gregory Schier
5eb2e2b5a2 Merge branch 'refs/heads/release'
# Conflicts:
#	src-tauri/src/updates.rs
2024-05-26 09:11:29 -07:00
Gregory Schier
5dd897e042 Initial handler for yaak:// protocol 2024-05-26 08:45:15 -07:00
Gregory Schier
9c77ec296d Better theme export 2024-05-24 18:54:30 -07:00
Gregory Schier
696e72323b More theme stuff 2024-05-24 17:36:48 -07:00
Gregory Schier
3e8c01f436 Tweak themes 2024-05-23 10:16:29 -07:00
Gregory Schier
80fc4dec09 Hotdog stand 2024-05-23 10:14:07 -07:00
Gregory Schier
671885fc8c More themes! 2024-05-23 09:40:11 -07:00
Gregory Schier
002b61f0d7 Set window title on Mac 2024-05-23 09:40:00 -07:00
Gregory Schier
d32b462bd9 More tweaks 2024-05-22 23:44:47 -07:00
Gregory Schier
5c8b47288a Tweak Yaak default themes 2024-05-22 23:28:53 -07:00
Gregory Schier
8e662e6feb A bunch more theme stuff 2024-05-22 23:14:53 -07:00
Gregory Schier
83aaeb94f6 Theme system refactor (#31) 2024-05-21 17:56:06 -07:00
Gregory Schier
8606940dee Move is_dev check for updates 2024-05-16 10:28:25 -07:00
Gregory Schier
60e469a1c9 Fix release (#30) 2024-05-14 15:35:53 -07:00
Gregory Schier
57d548743f Merge remote-tracking branch 'refs/remotes/origin/release'
# Conflicts:
#	src-tauri/tauri.conf.json
2024-05-14 15:35:33 -07:00
Gregory Schier
dab7ee2492 Bump version 2024-05-14 15:34:34 -07:00
Gregory Schier
9360fd7e43 Oops 2024-05-14 15:33:27 -07:00
Gregory Schier
7b4bc53c0f Release 2024.4.1 (#28) 2024-05-14 15:01:55 -07:00
Gregory Schier
0f7969d10a Fix maximize permission 2024-05-14 14:54:09 -07:00
Gregory Schier
6b373b5985 Fix autocomplete 2024-05-14 14:47:33 -07:00
Gregory Schier
c0068a1561 Add num launches to notification call 2024-05-14 14:25:10 -07:00
Gregory Schier
fad5e03f8b Fix window clicking on Linux 2024-05-14 12:19:19 -07:00
Gregory Schier
a22fc68764 Slight refactor 2024-05-14 08:44:15 -07:00
Gregory Schier
59a442e8c0 Build plugin 2024-05-14 08:28:20 -07:00
Gregory Schier
35e8155ecf Improve Curl imports 2024-05-14 08:28:01 -07:00
Gregory Schier
8b9a5cb5fb Bump version for release 2024-05-14 07:50:01 -07:00
Gregory Schier
29f9825f04 Fix upgrade cancel 2024-05-14 07:08:57 -07:00
Gregory Schier
ad8a6beacf Toast after data export 2024-05-14 00:36:15 -07:00
Gregory Schier
194ac78814 Fix selection of HTTP Request on create dropdown hotkey 2024-05-14 00:17:33 -07:00
Gregory Schier
0542f1ebea Fix curl export with multi-line body 2024-05-14 00:05:54 -07:00
Gregory Schier
8de917ea5e Autocomplete URLs of other requests 2024-05-13 23:54:52 -07:00
Gregory Schier
0b494bbfbf Fixed asset:// loading and tweak curl stuff 2024-05-13 23:20:30 -07:00
Gregory Schier
7e74f71c79 Bump version 2024-05-13 16:52:32 -07:00
Gregory Schier
bd7fd676a5 Better notifications 2024-05-13 16:52:20 -07:00
Gregory Schier
cb1c6a4d8c Improve copy-as-curl 2024-05-13 11:30:10 -07:00
Gregory Schier
b640f0c357 Refactor UpdateMode 2024-05-13 07:28:45 -07:00
Gregory Schier
967590c7ff Hide large GRPC messages by default 2024-05-13 07:19:26 -07:00
Gregory Schier
321d6ec9d7 Bump version 2024-05-12 12:11:14 -07:00
Gregory Schier
79b4fd7829 Add curl banner to import dialog 2024-05-10 13:36:30 -07:00
Gregory Schier
52eb4d338f Change curl import to post-toast 2024-05-10 13:06:40 -07:00
Gregory Schier
4b8b48e92f Toast component and use for copy-as-curl 2024-05-10 12:37:04 -07:00
Gregory Schier
e3f45b58e5 Insomnia YAML and loading state on import 2024-05-10 09:46:20 -07:00
Gregory Schier
a5f1922446 Some fixes after upgrading react-query 2024-05-10 09:19:29 -07:00
Gregory Schier
22e7b15a63 Update deps 2024-05-10 08:52:06 -07:00
Gregory Schier
c6bb2a73f8 Fix paste handler in Editor.tsx 2024-05-09 23:17:43 -07:00
Gregory Schier
bde961f95d Fix release targets 2024-05-09 15:38:27 -07:00
Gregory Schier
c4867b3f68 Don't commit .cargo 2024-05-09 10:17:35 -07:00
Gregory Schier
1c36e9a2f0 Fix args 2024-05-09 09:35:39 -07:00
Gregory Schier
1c82d8a738 Update GH action 2024-05-09 09:33:47 -07:00
Gregory Schier
a2df591102 Try fix linux 2024-05-09 08:37:18 -07:00
Gregory Schier
c950ee0fb8 Fix env var in GH Action 2024-05-09 08:29:45 -07:00
Gregory Schier
0ce5a9fcce Fix curl export tests 2024-05-09 08:18:06 -07:00
Gregory Schier
bd1970a805 Default .app/.dev/etc domains to https protos 2024-05-09 08:16:06 -07:00
Gregory Schier
3aaa4b1050 Bump version for beta 2024-05-09 07:52:36 -07:00
Gregory Schier
31d2426846 Fix GRPC event.emit permissions 2024-05-09 07:45:00 -07:00
Gregory Schier
25c4e4edaf Import from Curl 2024-05-09 07:31:52 -07:00
Gregory Schier
1a5bf53b02 Package lock 2024-05-08 15:37:53 -07:00
Gregory Schier
e2d1b62044 Slight refactor to copy-as-curl 2024-05-08 00:28:40 -07:00
Gregory Schier
6186104d11 Add rename request to context menu
Closes #21
2024-05-08 00:08:18 -07:00
Gregory Schier
f1e97eaea4 Copy as curl 2024-05-08 00:00:50 -07:00
Gregory Schier
bb0e58bf8b Curl import (#24) 2024-05-07 21:57:03 -07:00
Gregory Schier
dc802fa055 Upgrade to Tauri 2.0 (#23) 2024-05-04 14:14:19 -07:00
Gregory Schier
3c8e19367f Fix horizontal scroll on GraphQL variables editor 2024-04-18 10:53:36 -07:00
Gregory Schier
a89887eab8 Oops 2024-04-02 10:11:37 +02:00
Gregory Schier
7d3f0ad549 Postman text body import 2024-04-02 10:10:16 +02:00
Gregory Schier
5608db1334 Bump version 2024-04-01 08:48:26 +02:00
Gregory Schier
10443b3c02 Separate floating sidebar hidden state 2024-03-22 10:43:10 -07:00
Gregory Schier
7d272f3cd6 Filtering for cmd palette 2024-03-22 10:42:45 -07:00
Gregory Schier
d60a62ab24 Space between var placeholders and code fold cursor 2024-03-22 10:42:35 -07:00
Gregory Schier
2b0f73b7c5 Fix Postman variable import 2024-03-22 10:40:51 -07:00
Gregory Schier
0915ea8585 Adjust highlight color 2024-03-22 10:37:45 -07:00
Gregory Schier
ed9a0b8ac7 Some scrolling tweaks 2024-03-20 17:27:47 -07:00
Gregory Schier
7437f39ed3 Fix URL bar buttons in expanded state 2024-03-20 16:17:05 -07:00
Gregory Schier
27f80cd97b Bump version 2024-03-20 16:05:14 -07:00
Gregory Schier
04cf688a9b Fix dialog height 2024-03-20 16:05:01 -07:00
Gregory Schier
178af308ce Remove openOnHotKeyAction in favor of putting hotkey on the trigger button= 2024-03-20 15:56:39 -07:00
Gregory Schier
d40732a910 Use SQLite connect options 2024-03-20 13:33:11 -07:00
Gregory Schier
d8a579b7b3 Pass workspace id to import 2024-03-20 07:30:59 -07:00
Gregory Schier
bf8ef40708 Handle import errors 2024-03-20 07:27:12 -07:00
Gregory Schier
41060d5d43 Postman bearer, global auth, global vars 2024-03-20 07:26:46 -07:00
Gregory Schier
ab6cef064c Implement select for command palette 2024-03-19 17:24:57 -07:00
Gregory Schier
829d10d7b9 Tweak checkbox and autocomplete styles 2024-03-19 17:08:06 -07:00
Gregory Schier
57e1f641a7 Fix sidebar border 2024-03-19 16:44:37 -07:00
Gregory Schier
7df965e74b Export multiple workspaces 2024-03-19 13:43:33 -07:00
Gregory Schier
0e1153fdfd Fix settings query store and analytics 2024-03-19 10:23:21 -07:00
Gregory Schier
9797bc1830 Start of command palette 2024-03-18 17:09:01 -07:00
Gregory Schier
9d00eb98d2 useRequests hook 2024-03-18 13:49:36 -07:00
Gregory Schier
88f6e882c6 Fix editor key events 2024-03-18 13:40:15 -07:00
Gregory Schier
230a773909 Simple tests for Postman and Yaak importers 2024-03-18 13:40:00 -07:00
Gregory Schier
e6da1afa82 Set filename on Multipart part 2024-03-18 13:24:27 -07:00
Gregory Schier
a70d9e57be Fix GraphQL editor large variables quirk 2024-03-18 13:10:55 -07:00
Gregory Schier
8afe0c0755 Fix postman import and import Insomnia gRPC 2024-03-18 08:18:04 -07:00
Gregory Schier
e47c2513a8 Better padding 2024-03-16 13:59:06 -07:00
Gregory Schier
276bcfceeb Remove debug log 2024-03-16 12:50:27 -07:00
Gregory Schier
6fd1b35a50 Custom content-type for multipart items 2024-03-16 12:49:17 -07:00
Gregory Schier
bc33244549 Content menu on entire sidebar 2024-03-16 10:47:10 -07:00
Gregory Schier
33c982b288 Obfuscate environment variables 2024-03-16 10:42:46 -07:00
Gregory Schier
98493a1167 Fix light mode text selection 2024-03-16 09:48:55 -07:00
Gregory Schier
a8c10f9601 Stubbed out global commands helper 2024-03-16 09:46:11 -07:00
Gregory Schier
1051f84bbf Fix deleting workspace staying on deleted workspace path 2024-03-15 13:07:02 -07:00
Gregory Schier
eea137e677 Bump version 2024-03-10 18:15:00 -07:00
Gregory Schier
27cf4e925f Fix recent workspaces 2024-03-10 17:42:25 -07:00
Gregory Schier
6b239c4e3f Fix adding header if not exist 2024-03-10 17:10:16 -07:00
Gregory Schier
4c7ee5ef80 Remove completion debug blur thing 2024-03-10 16:46:18 -07:00
Gregory Schier
3ddb79899e Adjust detected content-type header 2024-03-10 16:26:06 -07:00
Gregory Schier
b14595a3e2 Clickable links in response viewer 2024-03-10 13:41:44 -07:00
Gregory Schier
82c94369ae Better error handling for file not found 2024-03-10 11:02:32 -07:00
Gregory Schier
7e77d2e9a8 Cancel file selection sets to undefined 2024-03-10 10:57:49 -07:00
Gregory Schier
ce5ce76b21 Binary file uploads and missing workspace empty state 2024-03-10 10:56:38 -07:00
Gregory Schier
27d6b30cf9 Fix GraphQL Header backend 2024-02-28 13:38:22 -08:00
Gregory Schier
9285dd5d70 Fix GraphQL content type on creation, and placeholder 2024-02-28 13:04:17 -08:00
Gregory Schier
977234808e Include default protoc includes 2024-02-28 09:45:11 -08:00
Gregory Schier
e1ccd327f5 Bump version 2024-02-28 08:51:34 -08:00
Gregory Schier
a0e3e71a4b Fix dropdown arrow keys 2024-02-28 08:51:08 -08:00
Gregory Schier
2d4037da37 Track GRPC 2024-02-28 07:32:05 -08:00
Gregory Schier
d21608bb82 Analytics ID 2024-02-28 07:27:19 -08:00
Gregory Schier
f16239de73 Analytics ID 2024-02-28 07:26:02 -08:00
Gregory Schier
d00f34c240 Remove Escape from hotkeys 2024-02-27 18:58:41 -08:00
Gregory Schier
fd77437f59 Fix sidebar focus 2024-02-27 10:33:20 -08:00
Gregory Schier
f9cd8d24a1 Fix gap in dropdown menu items 2024-02-27 10:27:04 -08:00
Gregory Schier
c0a9f79834 Methods in recent dropdown 2024-02-27 10:20:35 -08:00
Gregory Schier
ca63c101a1 Many hotkey improvements 2024-02-27 10:10:38 -08:00
Gregory Schier
dbd0b46ef2 Info logs in build 2024-02-26 17:27:08 -08:00
Gregory Schier
89793ebe2f Introspection tweak 2024-02-26 17:24:44 -08:00
Gregory Schier
e1ffc387ea Tweak editor find/replace 2024-02-26 17:17:37 -08:00
Gregory Schier
1efd0852ef Fix find/replace CM styling 2024-02-26 17:07:09 -08:00
Gregory Schier
59d532ed4d Fix lint errors 2024-02-26 07:43:08 -08:00
Gregory Schier
f034cda7cd Autocomplete icons and transfer proto files on duplicate 2024-02-26 07:39:53 -08:00
Gregory Schier
5c1cf1e57d Prompt folder name on create 2024-02-26 07:14:27 -08:00
Gregory Schier
780960f5de Better creation from folder menu 2024-02-26 07:09:59 -08:00
Gregory Schier
aada95e9da Auto-fill link to changelog in release script 2024-02-25 18:42:04 -08:00
Gregory Schier
89b5003cce Protoc sidecar 2024-02-25 17:43:29 -08:00
Gregory Schier
3559333461 Fix deletion in sidebar 2024-02-25 12:56:57 -08:00
Gregory Schier
fbb6cab567 Fix create dropdown hotkey 2024-02-24 22:02:04 -08:00
Gregory Schier
30fca29c6d Try changing macOS version 2024-02-24 21:25:58 -08:00
Gregory Schier
ec1e521b39 Bump some things 2024-02-24 21:23:02 -08:00
Gregory Schier
a8998cd696 Fix response pane height 2024-02-24 19:31:59 -08:00
Gregory Schier
df178baed6 Don't build plugins 2024-02-24 18:58:51 -08:00
Gregory Schier
e2f75371e6 Remove npm ci plugins 2024-02-24 18:28:07 -08:00
Gregory Schier
9f25ab39c6 Check in built plugins again 2024-02-24 18:27:36 -08:00
Gregory Schier
937df6a024 Add pkg locks 2024-02-24 18:19:16 -08:00
Gregory Schier
7deb7182a8 Install plugins in CI 2024-02-24 16:29:22 -08:00
Gregory Schier
82b14c56be Bump version 2024-02-24 16:22:55 -08:00
Gregory Schier
58b98734c9 Got json-schema autocomplete working again 2024-02-24 16:22:22 -08:00
Gregory Schier
c2f58f328c Proto files off model 2024-02-24 14:16:58 -08:00
Gregory Schier
36eabe7528 Better gRPC status on error 2024-02-24 12:41:43 -08:00
Gregory Schier
8347093e8b More analytics, and cancel requests 2024-02-24 11:30:07 -08:00
Gregory Schier
75282cb43a Hook up empty state buttons for first-launch experience 2024-02-23 16:34:19 -08:00
Gregory Schier
3a253a758d gRPC in import/export 2024-02-23 16:16:13 -08:00
Gregory Schier
f2955c26c1 Everything in messages now 2024-02-22 19:51:30 -08:00
Gregory Schier
e6c0317b37 Format XML responses 2024-02-22 01:00:02 -08:00
Gregory Schier
0cfb218b07 Refactor into grpc events 2024-02-22 00:49:22 -08:00
Gregory Schier
8ef103fbde Fix split layout placeholder 2024-02-18 09:12:44 -08:00
Gregory Schier
ec5cdfb025 Add other body type 2024-02-18 08:59:14 -08:00
Gregory Schier
7f4d082c17 Add metadata and squash migrations 2024-02-18 08:35:31 -08:00
Gregory Schier
e10011ef34 Better environment edit dialog 2024-02-18 07:44:53 -08:00
Gregory Schier
1eb6999c37 Allow editing base environment 2024-02-18 00:14:47 -08:00
Gregory Schier
35596916bf Render gRPC message body 2024-02-18 00:14:26 -08:00
Gregory Schier
d61b22dd87 gRPC authentication 2024-02-17 23:47:28 -08:00
Gregory Schier
5565a9db9a Even better dropdown filtering 2024-02-17 22:27:01 -08:00
Gregory Schier
b803655306 Started gRPC tabs 2024-02-17 22:15:44 -08:00
Gregory Schier
20df2bf13a Better dropdown filtering 2024-02-17 22:03:42 -08:00
Gregory Schier
e8fab85ce5 Prevent dragging folders into itself 2024-02-17 15:32:15 -08:00
Gregory Schier
ce730f3dbe Fix deps 2024-02-17 15:20:13 -08:00
Gregory Schier
2328973de5 Upgrade Vite deps and fix windows DnD 2024-02-17 14:57:12 -08:00
Gregory Schier
37dea50c91 Fix postman importer TS ref 2024-02-17 11:05:57 -08:00
Gregory Schier
40dfc8b30a Add more info to settings 2024-02-17 11:04:19 -08:00
Gregory Schier
72971bb9ec Adjust placeholder error colors 2024-02-15 21:15:18 -08:00
Gregory Schier
f835599502 Tweak tab padding 2024-02-15 16:38:14 -08:00
Gregory Schier
0caa4f8099 Responsive (scroll) workspace header 2024-02-15 16:30:08 -08:00
Gregory Schier
71d3c9acd1 Better button highlight border 2024-02-15 15:55:32 -08:00
Gregory Schier
239ffa174a Refactor recentRequest/Env/Workspace 2024-02-15 15:14:18 -08:00
Gregory Schier
eae79ab14b Better sidebar collapse, debuonce container uqeries, fix recent requests 2024-02-15 15:07:15 -08:00
Gregory Schier
ef7912615a Better recent work/env/req logic 2024-02-13 17:21:54 -08:00
Gregory Schier
7f20b67380 Fix active environment on workspace change 2024-02-13 16:42:07 -08:00
Gregory Schier
504337c178 Active environment in query param 2024-02-13 16:32:31 -08:00
Gregory Schier
d6b4f06ac8 Better variable placeholder styles 2024-02-13 16:32:17 -08:00
Gregory Schier
28cbf5474d Show GQL for graphql requests in sidebar 2024-02-13 16:32:00 -08:00
Gregory Schier
d797b84d4e Better highlight on JSON tree 2024-02-13 16:31:38 -08:00
Gregory Schier
720745857d Cmd+n to open dropdown 2024-02-11 14:17:09 -08:00
Gregory Schier
a74ea1aeda Tab-to-indent in editor 2024-02-11 14:16:36 -08:00
Gregory Schier
643f5e7f26 Make editor variables more prominent 2024-02-11 14:16:25 -08:00
Gregory Schier
a208b934e4 Fix dropdown open index 2024-02-11 14:16:11 -08:00
Gregory Schier
5892774082 Catch URL error when URL = "{{HOST}}" 2024-02-11 09:04:27 -08:00
Gregory Schier
13bfc1c3bd Grap gRPC status codes 2024-02-11 08:52:12 -08:00
Gregory Schier
00289734c7 Use basemsg 2024-02-11 08:29:57 -08:00
Gregory Schier
09c7c2cb91 Combine grpc handlers, fix duplicate 2024-02-10 10:41:45 -08:00
Gregory Schier
bbe62abd20 Fix response emit and sidebar flex 2024-02-09 16:16:02 -08:00
Gregory Schier
cae9a4fd36 Sidebar methods and fix model hooks 2024-02-09 16:09:24 -08:00
Gregory Schier
e7ee4a8867 Fix editor selection/cursor and lint errors 2024-02-09 14:32:58 -08:00
Gregory Schier
b020574c88 Remove built plugins from source control 2024-02-09 05:09:37 -08:00
Gregory Schier
192e1da5b6 Merge branch 'grpc' 2024-02-09 05:07:45 -08:00
Gregory Schier
0640079e59 Move plugins to build folder 2024-02-09 05:07:34 -08:00
Gregory Schier
a9d99aa17f gRPC Support (#20) 2024-02-09 05:01:00 -08:00
Gregory Schier
b4667e1f88 Better message serialization 2024-02-09 05:00:48 -08:00
Gregory Schier
7bc26fd448 Working sidebar actions for grpc 2024-02-07 00:02:02 -08:00
Gregory Schier
94a9a5d5d5 Change hotkey handling to capture phase 2024-02-06 23:44:10 -08:00
Gregory Schier
bcfa2c411f Fix pool management 2024-02-06 23:26:24 -08:00
Gregory Schier
1e3d43dbae Minor tweaks 2024-02-06 19:32:03 -08:00
Gregory Schier
c6b5e4d5df gRPC schema from files! 2024-02-06 19:20:32 -08:00
Gregory Schier
1293870e11 Proto selection UI/models 2024-02-06 12:29:23 -08:00
Gregory Schier
8309c19167 Better reflect failure UI 2024-02-05 14:50:47 -08:00
Gregory Schier
63a381c55a Async connection management 2024-02-05 11:29:27 -08:00
Gregory Schier
d891f891b7 Refactor model emit, and recent conn dropdown 2024-02-05 10:39:47 -08:00
Gregory Schier
0b12a6b318 db to app_handle! 2024-02-04 22:52:04 -08:00
Gregory Schier
0144ab05a0 Single upserted_model event 2024-02-04 21:19:15 -08:00
Gregory Schier
1f71d4372f Fix DB mutex deadlock 2024-02-04 21:17:05 -08:00
Gregory Schier
5ed1ea07ef More messages 2024-02-04 19:08:31 -08:00
Gregory Schier
4d2b101278 Client streaming working 2024-02-04 17:53:15 -08:00
Gregory Schier
1dfdadde98 Bidirectional working 2024-02-04 14:10:38 -08:00
Gregory Schier
d19729869e Messages are flowing! 2024-02-04 12:09:10 -08:00
Gregory Schier
5f782ad109 Use req/conn/msg models in unary/server 2024-02-04 11:57:12 -08:00
Gregory Schier
27dbdc9b5a Remove console log 2024-02-03 13:39:45 -08:00
Gregory Schier
4892863dd7 Grpc layout use new models 2024-02-03 13:28:31 -08:00
Gregory Schier
dc077209cc Show gRPC requests in sidebar 2024-02-03 13:08:24 -08:00
Gregory Schier
d8d5344d21 gRPC models and tables 2024-02-03 11:14:42 -08:00
Gregory Schier
d148a8384d Tiny fixes 2024-02-02 18:41:00 -08:00
Gregory Schier
6884e9428b Better formatting 2024-02-02 13:37:44 -08:00
Gregory Schier
25ebccfcd7 A bit better handling of responses 2024-02-02 13:32:06 -08:00
Gregory Schier
7adb0cbb50 Split layouts and things 2024-02-02 12:41:37 -08:00
Gregory Schier
50866abda4 bidi hacked! 2024-02-02 01:10:54 -08:00
Gregory Schier
c83d904cf0 Implement cancel 2024-02-02 00:18:37 -08:00
Gregory Schier
160447f8f6 Better connection management 2024-02-01 20:29:32 -08:00
Gregory Schier
184b13cc2a gRPC manager mostly working 2024-02-01 15:36:50 -08:00
Gregory Schier
8fa965e055 Small refactor 2024-02-01 02:42:59 -08:00
Gregory Schier
1dd0b69079 Refactor commands and DB 2024-02-01 02:29:24 -08:00
Gregory Schier
be8dd107e3 Some minor tweaks 2024-02-01 00:48:03 -08:00
Gregory Schier
8f139f10ef Revert response JSON tree 2024-02-01 00:38:57 -08:00
Gregory Schier
8b0823984b Even better styles 2024-02-01 00:36:49 -08:00
Gregory Schier
d82d2229d4 Styled it up a bit 2024-02-01 00:16:09 -08:00
Gregory Schier
4be1bc17f3 Merge remote-tracking branch 'origin/grpc' into grpc 2024-01-31 22:14:15 -08:00
Gregory Schier
e6af0c6009 Hacky server streaming done 2024-01-31 22:14:08 -08:00
Gregory Schier
e5d10bd72b Hacky client streaming done 2024-01-31 22:13:46 -08:00
Gregory Schier
9426885bb8 Initial frontend for gRPC UI 2024-01-30 16:43:54 -08:00
Gregory Schier
89e5d4f235 Hooked up test call from frontend! 2024-01-29 20:50:43 -08:00
Gregory Schier
eecb3fbc7f Fix cookie jar 2024-01-28 17:49:04 -08:00
Gregory Schier
244f1319b4 Track dialogs 2024-01-28 16:33:36 -08:00
Gregory Schier
6a2b76e760 Fix dropdown separator 2024-01-28 16:21:41 -08:00
Gregory Schier
bc0278fce9 Better format 2024-01-28 16:19:46 -08:00
Gregory Schier
959841fb22 More response info 2024-01-28 16:02:49 -08:00
Gregory Schier
fbc878dbe5 Better BG color 2024-01-28 14:43:04 -08:00
Gregory Schier
7d183c6580 Cookie Support (#19) 2024-01-28 14:39:51 -08:00
Gregory Schier
0555420ad9 Add shift to hotkey dialog hotkey 2024-01-19 22:11:20 -08:00
Gregory Schier
ae25561c7e Show alert after force checking updates 2024-01-19 22:11:02 -08:00
Gregory Schier
92e2b2b8f9 Better dialog padding 2024-01-19 22:08:32 -08:00
Gregory Schier
2a4a830fb7 Change env hotkey to use shift 2024-01-19 21:53:48 -08:00
Gregory Schier
0ad4c7cd7e Fix URL 2px grow on focus 2024-01-19 21:49:51 -08:00
Gregory Schier
41413d52ad Bump version 2024-01-19 13:42:02 -08:00
Gregory Schier
eabc1bd305 Fix analytics again 2024-01-18 22:28:25 -08:00
Gregory Schier
9c312e12c1 Fix dialog close button 2024-01-18 20:57:42 -08:00
Gregory Schier
18ea9dda3d Fix URLBar expanded state inner buttons 2024-01-18 20:40:56 -08:00
Gregory Schier
56d4212f68 Some analytics fixes 2024-01-18 20:23:02 -08:00
Gregory Schier
d932c19513 Launch analytics events, changelog, better filter styles 2024-01-18 14:42:02 -08:00
Gregory Schier
b800f00b7e Bump version 2024-01-17 14:56:47 -08:00
Gregory Schier
e43af5234f Custom HTTP method names 2024-01-17 14:52:19 -08:00
Gregory Schier
aa59d96e55 Workspace header tweak Windows 2024-01-17 18:48:43 -08:00
Gregory Schier
5be04ceea6 Fix header in fullscreen mode on Mac 2024-01-17 09:34:47 -08:00
Gregory Schier
da3392ac53 Download response, and some fixes 2024-01-16 17:02:55 -08:00
Gregory Schier
a2c9c98b21 Fix editor toolbar blocking things 2024-01-15 21:44:53 -08:00
Gregory Schier
8298d6e031 Better request creation (Closes #14) 2024-01-15 21:39:27 -08:00
Gregory Schier
d6331022ad XPath plugin 2024-01-15 21:27:47 -08:00
Gregory Schier
5e75d8c9a7 Fix send icon 2024-01-15 15:43:55 -08:00
Gregory Schier
51944a212a Switch to Lucide icons 2024-01-15 15:42:28 -08:00
Gregory Schier
49ed756479 Improve response filter UX 2024-01-15 15:19:29 -08:00
Gregory Schier
1d207d5fbd JSONPath filter plugins working 2024-01-15 15:06:49 -08:00
Gregory Schier
6b1d15415d Move plugin stuff around 2024-01-15 14:33:51 -08:00
Gregory Schier
df3bfaaab7 Fix request duplication 2024-01-15 13:47:44 -08:00
Gregory Schier
ad0b8a8e7d Fix workspace defaults 2024-01-15 12:25:13 -08:00
Gregory Schier
d5459229b9 Better settings dialog 2024-01-15 12:16:44 -08:00
Gregory Schier
adbf596f0b Fix resize observer 2024-01-15 12:02:08 -08:00
Gregory Schier
c740966394 Move request-related settings to workspace 2024-01-15 11:52:36 -08:00
Gregory Schier
7adab73af3 Bump beta version 2024-01-14 20:30:25 -08:00
Gregory Schier
c964f255d8 fix mac decorations 2024-01-14 17:22:31 -08:00
Gregory Schier
a7ffed9716 Integrated titlebar windows 2024-01-14 16:44:04 -08:00
Gregory Schier
488d66d248 Further titlebar tweaks 2024-01-14 12:02:44 -08:00
Gregory Schier
93cb469cb8 Better titlebar control icons 2024-01-14 11:56:21 -08:00
Gregory Schier
03a2fc8ee5 Basic Linux/Windows integrated titlebar 2024-01-13 23:40:32 -08:00
Gregory Schier
2d72e5792e Fix hotkey formatting 2024-01-12 22:12:01 -08:00
Gregory Schier
9bf9a87f12 beta tag 2024-01-12 22:00:55 -08:00
Gregory Schier
e2fca399e0 fix appearance init 2024-01-12 21:59:46 -08:00
Gregory Schier
e13fdddf98 Vendor Openssl 2024-01-12 21:03:28 -08:00
Gregory Schier
890eea299d Hotkeys for request switcher 2024-01-12 21:03:20 -08:00
Gregory Schier
9beac00981 Appearance setting and gzip/etc support 2024-01-12 13:39:08 -08:00
Gregory Schier
1a64d7d9e6 Initial settings implementation 2024-01-11 21:13:17 -08:00
Gregory Schier
bd5ae12f2e Dropdown manages hotkeys now 2024-01-11 10:18:05 -08:00
Gregory Schier
dbaf1da3ce Hotkey for keyboard shortcut help 2024-01-10 22:05:16 -08:00
Gregory Schier
a03c5df440 Bump version number 2024-01-10 16:25:55 -08:00
Gregory Schier
0776f6a2be Add hotkey dialog and rust-only analytics 2024-01-10 16:18:08 -08:00
Gregory Schier
ac9d050d9e Fix beta icon 2024-01-08 17:07:42 -08:00
Gregory Schier
b885c358a3 Bump version to 2024.0.0 2024-01-08 15:57:59 -08:00
Gregory Schier
84d447973e Hotkey labels 2024-01-08 15:57:21 -08:00
Gregory Schier
019ec4de20 Show hotkeys on empty views 2024-01-08 15:13:44 -08:00
Gregory Schier
26189067cd Remove base env, fix hotkeys, and QoL improvements 2024-01-07 22:24:19 -08:00
Gregory Schier
caf39071af Fix hotkeys getting stuck on cmd+tab 2024-01-07 21:32:25 -08:00
Gregory Schier
08a1223482 Always show settings dropdown 2023-11-22 09:39:30 -08:00
Gregory Schier
24bd90745e Tweak margin 2023-11-22 09:37:50 -08:00
Gregory Schier
7a72920e66 Fix bottom-up dropdown positioning 2023-11-22 09:35:56 -08:00
Gregory Schier
81a8276e2b Bump version 2023-11-22 09:06:47 -08:00
Gregory Schier
8fb6f51555 Better linux/Windows support for hotkeys 2023-11-22 09:06:22 -08:00
Gregory Schier
b0026aff66 Good hotkey support 2023-11-22 09:01:48 -08:00
Gregory Schier
3ced7f7c18 Reset URL bar when request changes 2023-11-21 23:26:29 -08:00
Gregory Schier
33f6995193 Env dialog hotkey 2023-11-21 22:35:28 -08:00
Gregory Schier
8af526682a Remove response body and basic hotkeys 2023-11-21 22:15:01 -08:00
Gregory Schier
d0d4324957 Remove app-specific menu items 2023-11-21 19:18:40 -08:00
Gregory Schier
2bcd0e0bbe Fix macOS menu and fallback URL 2023-11-21 09:24:13 -08:00
Gregory Schier
1b99c7e10f Hide menu on windows/linux 2023-11-21 08:17:37 -08:00
Gregory Schier
2831bb61b8 Disable sandboxing (again) 2023-11-19 21:59:55 -08:00
Gregory Schier
320670de2a Fix drag-drop reorder 2023-11-19 21:43:01 -08:00
Gregory Schier
1f39a36f26 Postman ID generation 2023-11-19 20:54:02 -08:00
Gregory Schier
1f84ba716e Bump beta.3 2023-11-19 20:46:55 -08:00
Gregory Schier
d034965d9c Postman variables + urlencoded forms 2023-11-19 20:29:24 -08:00
Gregory Schier
5eb30489e5 Add back Windows/Linux builds 2023-11-19 18:22:13 -08:00
Gregory Schier
05458a0753 Remove Tauri context menu plugin 2023-11-19 18:21:10 -08:00
Gregory Schier
7975ef0699 Fix header padding windows/linux 2023-11-19 18:14:49 -08:00
Gregory Schier
5f810a1b4c Some tweaks 2023-11-19 18:13:32 -08:00
Gregory Schier
c4093e79cf Beta 2 2023-11-19 17:41:58 -08:00
Gregory Schier
956f8ed2ea Network entitlement 2023-11-19 17:41:46 -08:00
Gregory Schier
7b32f76a1e Try sandboxing again 2023-11-19 17:06:31 -08:00
Gregory Schier
0dd11bc051 Remove sandboxing 2023-11-17 09:33:16 -08:00
Gregory Schier
aa38df28af Out of beta 2023-11-17 07:53:26 -08:00
Gregory Schier
32962a6336 Tweak 2023-11-17 07:52:03 -08:00
Gregory Schier
b268b72a4a Format GraphQL variables 2023-11-17 07:51:03 -08:00
Gregory Schier
eb0c90311b Drag into folder (Closes #8) 2023-11-17 07:36:01 -08:00
Gregory Schier
1070bf8e8f Mostly move some stuff around 2023-11-16 18:53:34 -08:00
Gregory Schier
9bdb01987c Better update logic 2023-11-14 14:28:06 -08:00
Gregory Schier
3130fb948a Better dropdown menu 2023-11-14 10:56:56 -08:00
Gregory Schier
e46de9eebd Version to beta 2023-11-14 10:07:39 -08:00
Gregory Schier
4360355c8c Beta channel updates 2023-11-14 08:57:46 -08:00
Gregory Schier
3baaddba0b Multipart form UI and fixes 2023-11-14 00:32:02 -08:00
Gregory Schier
e77c1c2a46 Got multipart working (text-only) 2023-11-13 23:26:11 -08:00
Gregory Schier
38422d59fd Fix window title moving stoplights (for now) 2023-11-13 23:25:47 -08:00
Gregory Schier
c884cedfc2 Postman import form data 2023-11-13 11:48:28 -08:00
Gregory Schier
91074a35d8 Some small improvements 2023-11-13 11:44:29 -08:00
Gregory Schier
9a02b63a6b Form urlencoded bodies! 2023-11-13 11:28:37 -08:00
Gregory Schier
4470409a24 Url parameters done 2023-11-13 10:52:11 -08:00
Gregory Schier
8a978420be Minor tweaks 2023-11-12 21:16:42 -08:00
Gregory Schier
dfc01d51ca Custom updater code 2023-11-12 21:16:33 -08:00
Gregory Schier
758154fa14 Request body is now an object 2023-11-12 11:16:12 -08:00
Gregory Schier
ef23a85577 Some postman import improvements 2023-11-11 10:43:11 -08:00
Gregory Schier
e4533088ed Sync window title (Closes #13) 2023-11-10 15:55:50 -08:00
Gregory Schier
4ffce4a534 Dev app icon 2023-11-10 13:06:12 -08:00
Gregory Schier
6b77a62934 Upgrade sqlx 2023-11-10 12:28:33 -08:00
Gregory Schier
f603867040 Clean up importers 2023-11-10 11:39:17 -08:00
Gregory Schier
b6eb7418aa Fix is_empty check 2023-11-10 09:12:20 -08:00
Gregory Schier
39c97681cf Postman importer semi-complete 2023-11-10 09:08:20 -08:00
Gregory Schier
2d0f0d8f6b Tidy up logs and general cleanup 2023-11-09 20:33:09 -08:00
Gregory Schier
209a767c91 Move error alert to hook 2023-11-09 20:02:42 -08:00
Gregory Schier
71f2a724cb Show import errors 2023-11-09 20:00:19 -08:00
Gregory Schier
4b89b95738 Hacky Yaak import complete! 2023-11-09 19:40:31 -08:00
Gregory Schier
b535722acd More fallback request handing 2023-11-09 17:42:10 -08:00
Gregory Schier
a9806a06a2 Request fallback name in header 2023-11-09 17:34:57 -08:00
Gregory Schier
948e19b82f Better default request names 2023-11-09 17:26:04 -08:00
Gregory Schier
cd841fa13a Better non-named requests 2023-11-09 17:17:03 -08:00
Gregory Schier
3ffcf91abd Better Yaak export 2023-11-09 17:03:29 -08:00
Gregory Schier
9fd84a3bfc Refactor previous commit 2023-11-09 16:50:57 -08:00
Gregory Schier
627c451cd1 Default request name to URL(ish) 2023-11-09 16:47:00 -08:00
Gregory Schier
e6ee89464a Rename initial workspace to "Yaak" 2023-11-09 13:17:21 -08:00
Gregory Schier
136e9f2738 No analytics in dev 2023-11-09 11:46:52 -08:00
Gregory Schier
d97986e526 Analytics event properties 2023-11-09 11:44:59 -08:00
Gregory Schier
7661aa9819 Context menu, logs in DevTools, export, tweaks 2023-11-09 09:28:01 -08:00
Gregory Schier
b7596f3f78 Fix plugin (again) 2023-11-08 13:33:15 -08:00
Gregory Schier
4e2231674c Bundle plugin in Git 2023-11-08 13:06:49 -08:00
Gregory Schier
d36d023a5c Move plugins back 2023-11-08 12:34:14 -08:00
Gregory Schier
3d5a7ebe3d Fix permissions 2023-11-08 12:02:17 -08:00
Gregory Schier
819384e952 Bump version 2023-11-08 10:12:01 -08:00
Gregory Schier
2f34c5e821 Tweak theme 2023-11-08 10:11:29 -08:00
Gregory Schier
0c89c154ee Tweak theme 2023-11-08 09:56:13 -08:00
Gregory Schier
060dce7440 Track screen size, os, and version 2023-11-08 09:49:29 -08:00
Gregory Schier
91707529bd Rust analytics and a few tweaks 2023-11-08 09:13:32 -08:00
Gregory Schier
22f182a8eb Add basic analytics 2023-11-07 09:53:59 -08:00
Gregory Schier
6ccc42dc3f Cancel responses on startup 2023-11-06 13:06:15 -08:00
Gregory Schier
655f5a8eed Send all in a folder 2023-11-06 10:53:39 -08:00
Gregory Schier
cd06a72d6f Rework workspace header 2023-11-06 10:42:59 -08:00
Gregory Schier
0a5d71ecc2 Fix sidebar focus max recursion 2023-11-06 10:40:02 -08:00
Gregory Schier
9c214b619c Save after formatting GraphQL (Closes #9) 2023-11-06 07:20:47 -08:00
Gregory Schier
6fddb727be Move plugins back to root dir 2023-11-06 07:18:53 -08:00
Gregory Schier
b5d3b9a803 Persist sidebar collapsed state (Closes #10) 2023-11-06 07:18:42 -08:00
Gregory Schier
a74c8a94db Vite to bundle insomnia plugin 2023-11-05 22:13:22 -08:00
Gregory Schier
abc6d0ff1e Better import conversion 2023-11-05 14:46:08 -08:00
Gregory Schier
afdbcd0a38 Basic import of request body and bearer auth 2023-11-05 14:35:25 -08:00
Gregory Schier
c31ae805a6 Recursive Insomnia import! 2023-11-05 13:33:23 -08:00
Gregory Schier
7c1afd7fe5 Remove numbers from recent requests 2023-11-04 16:19:21 -07:00
Gregory Schier
ad470a3fd2 Fix drop marker indent 2023-11-04 11:16:41 -07:00
Gregory Schier
7755d06bba Folder actions 2023-11-04 10:48:18 -07:00
Gregory Schier
5aed4b79be Folder chevron icon 2023-11-03 23:10:44 -07:00
Gregory Schier
f0e3f29606 Fix arrow navigation for nested sidebar 2023-11-03 17:29:33 -07:00
Gregory Schier
abbcc525bf Folder-based drag-n-drop complete! 2023-11-03 16:29:21 -07:00
Gregory Schier
ef8ade45b1 Sidebar ordering 95% done! 2023-11-03 15:02:17 -07:00
Gregory Schier
8919d598c2 Nested sidebar ordering almost working 2023-11-03 14:08:46 -07:00
Gregory Schier
e21e42f5fe Add folder model 2023-11-03 07:49:44 -07:00
Gregory Schier
658aed8a29 Even better focus state 2023-11-02 22:23:21 -07:00
Gregory Schier
a666f7d216 Remove focus on env sidebar buttons 2023-11-02 22:18:13 -07:00
Gregory Schier
62429df469 Rearrange menus 2023-11-02 21:41:35 -07:00
Gregory Schier
7aed699c3f Refactor environment edit dialog 2023-11-02 20:38:33 -07:00
Gregory Schier
a14db0ab74 Base environments fully working 2023-11-02 18:43:39 -07:00
Gregory Schier
7b67770dc7 Initial "plugin" system with importer (#7) 2023-11-02 18:08:43 -07:00
Gregory Schier
7766d8439b Fix cursor color in single-line mode 2023-10-31 15:10:33 -07:00
Gregory Schier
fac0683a71 Fix sending of ephemeral requests 2023-10-30 08:24:49 -07:00
Gregory Schier
79e04967f5 Fix GQL introspection and bearer auth templating 2023-10-30 08:07:34 -07:00
Gregory Schier
47eb8947f5 Fix button styles 2023-10-30 07:27:27 -07:00
Gregory Schier
959c55315c Fix editor stale callbacks and recent item deletion 2023-10-30 07:07:14 -07:00
Gregory Schier
b392f0c00f Refactored some core UI 2023-10-30 06:35:52 -07:00
Gregory Schier
c8e674d015 Plugin module loading 2023-10-29 20:50:23 -07:00
Gregory Schier
90fbb81e1d Bump version 2023-10-29 17:22:27 -07:00
Gregory Schier
21e58ca644 Fix sidebar scroll 2023-10-29 17:19:03 -07:00
Gregory Schier
cfb0aa55ea A bit more playing with JS runtime 2023-10-29 17:05:48 -07:00
Gregory Schier
9e0c021481 Initial "Hello World" for plugins 2023-10-29 16:43:28 -07:00
Gregory Schier
4acca8dd06 Fix request creation 2023-10-29 12:05:05 -07:00
Gregory Schier
88eea09428 Restore recent environment on workspace change
Fixes #6
2023-10-29 11:32:55 -07:00
Gregory Schier
90d2743267 Fix var complete and env dialog actions 2023-10-29 11:18:55 -07:00
Gregory Schier
89945532a0 Remove broken key/value enter/backspace logic 2023-10-29 10:45:05 -07:00
Gregory Schier
671860e053 Delete key/value on backspace 2023-10-29 10:26:38 -07:00
Gregory Schier
a87ca6af47 Move workspace menu, better env mgmt, QoL 2023-10-29 09:45:16 -07:00
Gregory Schier
b59ea4991c Bump version 2023-10-28 23:41:58 -07:00
Gregory Schier
b6fd59219f Better listening for path changes 2023-10-28 23:41:24 -07:00
Gregory Schier
38ce7650c1 Bump version 2023-10-28 22:14:51 -07:00
Gregory Schier
2b21e28096 Fixed auto-focus in prompt and env dropdown 2023-10-28 22:14:12 -07:00
Gregory Schier
3206651248 Clear selected sidebar index on drag-drop end 2023-10-28 21:47:00 -07:00
Gregory Schier
ba8aa0e218 Revert debug name 2023-10-28 21:43:09 -07:00
Gregory Schier
975a001635 Fix drag-n-drop things 2023-10-28 21:42:35 -07:00
Gregory Schier
30e7f7ccfe Persist window paths 2023-10-28 21:23:46 -07:00
Gregory Schier
cca8d97d63 Bump version to 2023.1.0 2023-10-28 19:15:33 -07:00
Gregory Schier
455e6c3520 Update placeholders when env changes 2023-10-28 19:14:51 -07:00
Gregory Schier
d05ee3ec16 Placeholder error and fix env nav 2023-10-28 19:08:31 -07:00
Gregory Schier
b1b5d08e89 Recent requests/workspaces. Closes #1 2023-10-28 18:46:54 -07:00
Gregory Schier
6202e59daa Fix recent requests loading on startup 2023-10-28 18:27:18 -07:00
Gregory Schier
c4a8603b81 Add tauri window save state plugin 2023-10-28 13:14:27 -07:00
Gregory Schier
5d15d1565c Fix rustfmt 2023-10-28 12:45:25 -07:00
Gregory Schier
045ff558f8 Handle enabled/disabled variables and render multi 2023-10-28 11:36:40 -07:00
Gregory Schier
504ed583cc Remove unused Variable type 2023-10-28 11:31:45 -07:00
Gregory Schier
15087f2d5a Variables under Environment, and render all props 2023-10-28 11:29:29 -07:00
Gregory Schier
eb1cd1c14b Native Codemirror cursor 2023-10-27 13:14:41 -07:00
Gregory Schier
0918d86654 Only wrap URLBar on focus and hotkey to open recent requests 2023-10-27 12:40:43 -07:00
Gregory Schier
d0e2220df7 Resizing window no longer changes sidebar visibility
Fixes #4
2023-10-27 11:21:59 -07:00
Gregory Schier
ccb04f0b45 Auto-expand URL bar height 2023-10-27 10:57:07 -07:00
Gregory Schier
54b6e1c7c3 Environment deletion and better actions menu 2023-10-26 16:18:47 -07:00
Gregory Schier
7c8acdc956 Stop autocomplete from jumping around 2023-10-26 15:27:48 -07:00
Gregory Schier
3973ae15be Fix request creation from menu 2023-10-26 10:41:14 -07:00
Gregory Schier
86dadf4f5e Send requests with active environment 2023-10-26 10:32:06 -07:00
Gregory Schier
dc4cb4be74 Move create request and fix slow HTML highlighting 2023-10-26 09:42:19 -07:00
Gregory Schier
2a29c4b551 Better project selector, Fixes #2, and a bunch more 2023-10-26 09:11:44 -07:00
Gregory Schier
2f64f45aba Fixed some routing and introspection requests 2023-10-25 21:53:18 -07:00
Gregory Schier
2f998ddfb6 Environments in URL and better rendering 2023-10-25 11:13:00 -07:00
Gregory Schier
93369a779d Move responses dropdown to separate component 2023-10-25 07:59:10 -07:00
Gregory Schier
74e28123a8 Fix dialog height 2023-10-25 00:02:51 -07:00
Gregory Schier
fef7db8710 Better style when no active environment 2023-10-24 23:58:12 -07:00
Gregory Schier
cb5d7626ac Environment dropdown and actions 2023-10-24 09:17:29 -07:00
Gregory Schier
e74f9f33c0 Started on environment edit dialog 2023-10-23 21:00:36 -07:00
Gregory Schier
0d27c17e28 Hacky implementation of variable autocomplete 2023-10-23 10:31:21 -07:00
Gregory Schier
f0b6d32639 Rendered first variable! 2023-10-22 22:30:29 -07:00
Gregory Schier
9ebd506056 Updating environments! 2023-10-22 22:06:51 -07:00
Gregory Schier
a5a91d2444 Update .gitignore 2023-10-22 20:40:00 -07:00
Gregory Schier
4435a66ece Prettier and start of env editor 2023-10-22 20:38:57 -07:00
Gregory Schier
874a1079c3 Environments data model 2023-10-22 18:28:56 -07:00
Gregory Schier
1dc239d243 Environment data model backend 2023-10-22 16:05:09 -07:00
Gregory Schier
73a04276c0 Fix some eslint warnings 2023-10-22 11:02:39 -07:00
Gregory Schier
9955064484 Add APPLE_TEAM_ID 2023-10-18 14:12:08 -07:00
Gregory Schier
7975b528ec Revert artifacts things 2023-10-18 13:25:35 -07:00
Gregory Schier
7d9fbda975 Bump cargo deps 2023-10-18 13:25:20 -07:00
Gregory Schier
fce06747e3 Bump version 2023-10-18 12:14:38 -07:00
Gregory Schier
db0cca54a7 Fix sidebar drag-n-drop 2023-10-18 11:58:58 -07:00
Gregory Schier
4424caecc5 Retry button on introspection errors 2023-06-12 13:20:42 -07:00
Gregory Schier
b866dcd566 Fix autocomplete doc font size 2023-05-31 21:32:48 -07:00
Gregory Schier
9e4e6435ab Persist introspection queries and also improve 2023-05-31 21:29:41 -07:00
Gregory Schier
41b10ff442 Update tauri NPM 2023-05-29 12:49:50 -07:00
Gregory Schier
79f3307104 Fix graphql instrospection 2023-05-29 12:31:34 -07:00
Gregory Schier
026629cd6d Change version 2023-04-27 16:53:39 -07:00
Gregory Schier
cf570a8f88 Version 1.0.0 2023-04-27 16:47:49 -07:00
Gregory Schier
4a64384468 Fix window methods on Linux/Windows 2023-04-27 16:27:02 -07:00
Gregory Schier
a9065c3380 Cross platform window controls 2023-04-27 10:19:49 -07:00
Gregory Schier
e5e5548562 Fix ubuntu build 2023-04-26 17:00:30 -07:00
Gregory Schier
44cf2f670f Windows and Linux 2023-04-26 16:54:51 -07:00
Gregory Schier
d04d91d6dd Bump version 2023-04-26 16:47:50 -07:00
Gregory Schier
3eb25b1507 Very basic CSV viewer 2023-04-22 21:53:04 +08:00
Gregory Schier
a95cae5610 Truncate response files 2023-04-14 14:15:33 -07:00
Gregory Schier
9cc6e62f28 Randomly offset new windows 2023-04-14 14:05:23 -07:00
Gregory Schier
24117f7c8d Fix text encoding and delete responses 2023-04-14 13:50:41 -07:00
Gregory Schier
7245e6e593 Delete response files 2023-04-14 12:17:11 -07:00
Gregory Schier
4a5b1f4da3 Readonly editor disable tabindex 2023-04-13 22:36:11 -07:00
Gregory Schier
c1ac67cc31 Fix imageview padding 2023-04-13 22:33:47 -07:00
Gregory Schier
4085361b7e Duration and size tags 2023-04-13 20:50:17 -07:00
Gregory Schier
8b4227dbff Comment 2023-04-13 18:55:32 -07:00
Gregory Schier
3f7ed9e177 Always store response on filesystem 2023-04-13 18:52:56 -07:00
Gregory Schier
f9f1ba9e24 Support binary responses! 2023-04-13 18:48:40 -07:00
Gregory Schier
29309500a6 Blur backdrop 2023-04-11 16:12:26 -07:00
Gregory Schier
6b07fe105f Autofocus buttons 2023-04-11 14:04:23 -07:00
Gregory Schier
90b03a0b97 Better opening workspaces and redirect workspace to recent request 2023-04-11 11:11:36 -07:00
Gregory Schier
d54a468006 Button disabled style opacity 2023-04-10 16:03:45 -07:00
Gregory Schier
7e98b6d853 Dropdown keys and pointer events 2023-04-10 16:02:29 -07:00
Gregory Schier
8069094201 Upgrade deno core 2023-04-10 11:16:25 -07:00
Gregory Schier
b28dc01e6b Tweak response history 2023-04-09 23:15:51 -07:00
Gregory Schier
6bc1f9f494 Fixed multi-window model sync 2023-04-09 22:32:47 -07:00
Gregory Schier
e85dd32005 Tweak recent requests 2023-04-09 22:25:00 -07:00
Gregory Schier
efc4e3bf6c Toggle settings 2023-04-09 22:12:16 -07:00
Gregory Schier
768a13ff4d Fix sidebar request focus 2023-04-09 22:03:41 -07:00
Gregory Schier
a8d73f74f4 More stuff on sidebar 2023-04-09 21:52:04 -07:00
Gregory Schier
4dddfc0cc5 Small tweaks 2023-04-09 15:32:13 -07:00
Gregory Schier
4163bebe3b Request history navigator 2023-04-09 15:26:54 -07:00
Gregory Schier
ad13744d14 Enter name on create workspace 2023-04-09 12:27:02 -07:00
Gregory Schier
9f9b3a5b21 Rename workspace 2023-04-09 12:23:41 -07:00
Gregory Schier
63e68baeb1 Sidebar hover transitions 2023-04-06 16:30:46 -07:00
Gregory Schier
4382ca6582 Remove some more key value usage 2023-04-06 16:26:56 -07:00
Gregory Schier
99f2f4c211 A bunch of tweaks 2023-04-06 16:05:25 -07:00
Gregory Schier
6b23379e5a macOS 12 2023-04-06 08:39:30 -07:00
Gregory Schier
4deda36e8f Remove system tray icon 2023-04-06 08:15:40 -07:00
Gregory Schier
0ce7831cfb Minor tweaks 2023-04-04 17:21:02 -07:00
Gregory Schier
4e9005e240 Fix some things 2023-04-04 16:56:45 -07:00
Gregory Schier
9147252e5b Editor line wrapping support (not used yet) 2023-04-04 16:40:37 -07:00
Gregory Schier
b6b549ca18 remove janky last location tracking 2023-04-04 16:23:08 -07:00
Gregory Schier
85c25fb71e Fix resize cursor 2023-04-04 16:12:45 -07:00
Gregory Schier
50637ba9fd Better button styles 2023-04-04 15:40:25 -07:00
Gregory Schier
bfe55dd55a Bump version 2023-04-04 13:56:24 -07:00
Gregory Schier
1a2bb3d12e Some small fixes 2023-04-04 13:56:14 -07:00
Gregory Schier
452a0c3ed5 A few fixes 2023-04-04 13:31:48 -07:00
Gregory Schier
b594a4690f Better status tags and delete request on key 2023-04-04 12:36:30 -07:00
Gregory Schier
7d2ba43463 Remove expects from request sending 2023-04-04 08:14:32 -07:00
Gregory Schier
107db42c33 Fix web view height 2023-04-04 07:51:41 -07:00
Gregory Schier
dbacb9fc8d Fix autocomplete spacing 2023-04-04 07:51:19 -07:00
Gregory Schier
1fa3499ca6 Fix input focus border 2023-04-03 12:19:37 -07:00
Gregory Schier
62f3198d27 Hot keys and cleanup 2023-04-03 07:59:49 -07:00
Gregory Schier
529550934b Add entitlemet for v8 2023-04-02 20:23:21 -07:00
Gregory Schier
ca3b22a881 Debug codesigned build 2023-04-02 19:09:14 -07:00
Gregory Schier
0ecf2d9123 Disable code signing 2023-04-02 18:27:14 -07:00
Gregory Schier
af9bb7138b Fix tauri script command 2023-04-02 17:25:24 -07:00
Gregory Schier
6cbfa74f97 Fix universal binary 2023-04-02 17:12:20 -07:00
Gregory Schier
2845fb8d35 Bump version 2023-04-02 15:44:41 -07:00
Gregory Schier
fbe2660a57 Fix toolchain 2023-04-02 15:44:21 -07:00
Gregory Schier
1519282ac6 Add proper target 2023-04-02 15:42:19 -07:00
Gregory Schier
5d8d8dca70 Try universal binary 2023-04-02 15:33:13 -07:00
Gregory Schier
0254e2c31d Fix version 2023-04-02 15:25:24 -07:00
Gregory Schier
368b494d62 Bump version 2023-04-02 14:54:41 -07:00
Gregory Schier
00d2213d05 Notorization (hopefully) 2023-04-02 14:53:49 -07:00
Gregory Schier
b04602bcb9 Change tabs again 2023-04-02 11:11:53 -07:00
Gregory Schier
80bfbd503a Better response headers 2023-04-02 10:45:41 -07:00
Gregory Schier
bfa186aebb Show response headers 2023-04-01 23:43:22 -07:00
Gregory Schier
818595e961 Some more refactoring 2023-04-01 21:48:30 -07:00
Gregory Schier
b5e9852f8d Refactor debounce and tauri event listeners 2023-04-01 21:39:46 -07:00
Gregory Schier
ff3734d65a Fix dropdown and dialog key handling 2023-04-01 21:04:39 -07:00
Gregory Schier
4aa771ba29 Refactor sidebar display 2023-04-01 20:58:53 -07:00
Gregory Schier
5848c381fa Better GraphQL schema fetching 2023-04-01 17:53:36 -07:00
Gregory Schier
03b35beae4 More eslint fixes 2023-04-01 15:48:37 -07:00
Gregory Schier
49856bb6f7 Add React hooks eslint 2023-04-01 15:26:57 -07:00
Gregory Schier
0cb56f1a85 Fix Tauri listeners 2023-04-01 00:02:17 -07:00
Gregory Schier
4a0d698776 Memo editor 2023-03-31 23:19:15 -07:00
Gregory Schier
a4ebdb5736 Fix request duplication 2023-03-31 22:54:32 -07:00
Gregory Schier
6a5ecc2880 Fix tauri listeners causing too many updates 2023-03-31 22:48:34 -07:00
Gregory Schier
7a5bd92442 Remove import 2023-03-31 22:42:41 -07:00
Gregory Schier
63c1111608 Fix 2023-03-31 22:42:26 -07:00
Gregory Schier
5704fb560a Upgrade Deno 2023-03-31 22:42:08 -07:00
Gregory Schier
33dc3b719d Tweak 2023-03-31 16:14:25 -07:00
Gregory Schier
d3329b4628 Fix send hotkey 2023-03-31 16:13:34 -07:00
Gregory Schier
42e2c9f96f Better schema fetching 2023-03-31 16:02:09 -07:00
Gregory Schier
3e8a10757f Finally fix the editor! 2023-03-31 15:56:35 -07:00
Gregory Schier
8028d82fd0 Fix editor blurring bug! 2023-03-31 13:53:28 -07:00
Gregory Schier
4ad9feba68 Better model updates 2023-03-31 13:21:02 -07:00
Gregory Schier
ef469be7a9 Fix text obscuring 2023-03-30 17:22:52 -07:00
Gregory Schier
14cd73d75a Button ring colors 2023-03-30 17:17:07 -07:00
Gregory Schier
fbe6039845 Remove dummy button 2023-03-30 17:12:38 -07:00
Gregory Schier
f3fbd070dd Confirm deletions 2023-03-30 17:09:11 -07:00
Gregory Schier
7c2611a5a7 Dedicated event for model creation 2023-03-30 16:49:49 -07:00
Gregory Schier
ae949f4616 Unify text selection color 2023-03-30 16:36:24 -07:00
Gregory Schier
89da434c0e Some icon tweaks 2023-03-30 16:29:14 -07:00
Gregory Schier
4a98d1d655 Fix strict mode editor blur bug 2023-03-30 10:38:33 -07:00
Gregory Schier
bb41f0e4fe Better tauri listeners and stuff 2023-03-30 09:05:54 -07:00
Gregory Schier
d2e0717d91 Remove updated_by, remember last location 2023-03-30 08:11:51 -07:00
Gregory Schier
7912204fcb Remove hardcoded window config 2023-03-29 22:16:21 -07:00
Gregory Schier
83e41ad618 Fix build 2023-03-29 22:15:55 -07:00
Gregory Schier
dd7e46c2cc Remove unused import 2023-03-29 21:53:49 -07:00
Gregory Schier
fb7424714a Better multi-window updates 2023-03-29 21:53:20 -07:00
Gregory Schier
47481b711e Fixed key/value stuff 2023-03-29 14:46:36 -07:00
Gregory Schier
0f86c3a731 Fix bundle parts 2023-03-29 14:00:34 -07:00
Gregory Schier
b91d1b8b3c Fix(ish) multiwindow updates 2023-03-29 11:15:37 -07:00
Gregory Schier
cd5ae6691c Obscure text 2023-03-29 10:16:51 -07:00
Gregory Schier
0f58986b4c Simple auth schemes 2023-03-29 09:03:38 -07:00
Gregory Schier
af9755c513 Good start to multi-window 2023-03-28 18:29:40 -07:00
Gregory Schier
56ce25f953 Focus traps for dialog and dropdown 2023-03-26 23:07:09 -07:00
Gregory Schier
ed70c15ee9 Confirmation Dialogs 2023-03-26 12:02:20 -07:00
Gregory Schier
d88ae99425 Floating sidebar 2023-03-26 10:09:28 -07:00
Gregory Schier
cf7ef55b7d Panel icons 2023-03-25 23:29:04 -07:00
Gregory Schier
2f12424f8d Update dialog 2023-03-25 21:59:18 -07:00
Gregory Schier
96aacec4fc Optimistically-update key values 2023-03-25 21:54:00 -07:00
Gregory Schier
7e57bb98a8 More tweaks 2023-03-25 21:40:14 -07:00
Gregory Schier
298f5c5a99 Animate dropdown 2023-03-25 21:36:17 -07:00
Gregory Schier
bf44ea7864 Animate sidebar transition 2023-03-25 21:31:52 -07:00
Gregory Schier
9abdc45e93 Refactor and improve layout resizing 2023-03-25 21:16:10 -07:00
Gregory Schier
0d82cc7574 Even better layouts 2023-03-25 18:33:01 -07:00
Gregory Schier
402b2a551f Better grid layouts 2023-03-25 18:12:09 -07:00
Gregory Schier
700c589ae2 Global layout component 2023-03-25 13:26:31 -07:00
Gregory Schier
8929d736d9 Better dropdown separator 2023-03-25 11:06:05 -07:00
Gregory Schier
8c65fce357 Fix sidebar drag 2023-03-24 08:37:52 -07:00
Gregory Schier
b81f1e9e6b Upgrade TYpescript 2023-03-23 15:37:36 -07:00
Gregory Schier
44d083d773 Fix resize 2023-03-23 07:47:58 -07:00
Gregory Schier
2b308282d4 Style tweak 2023-03-21 23:59:09 -07:00
Gregory Schier
c7738743c5 GraphQL autocomplete and duplicate request 2023-03-21 23:54:45 -07:00
Gregory Schier
abc60667c6 Tweak sidebar drag resizer 2023-03-21 19:36:32 -07:00
Gregory Schier
53162e8bca Minor style tweaks 2023-03-21 18:31:05 -07:00
Gregory Schier
6b95574e3d Pull out resize bar 2023-03-21 16:53:49 -07:00
Gregory Schier
c9d62ae961 Resize titlebar and tweak things 2023-03-21 16:42:52 -07:00
Gregory Schier
a70019927d Remove icon generation from build script 2023-03-21 14:21:07 -07:00
Gregory Schier
01cd7f951a query client cache and better body types 2023-03-21 11:38:37 -07:00
Gregory Schier
50f92bcfab Fix workspace deletion 2023-03-21 09:32:15 -07:00
Gregory Schier
362d9f8e59 Use proper gray for syntax 2023-03-20 17:15:12 -07:00
Gregory Schier
0b1cf53942 fix import 2023-03-20 17:13:14 -07:00
Gregory Schier
a4c769b33c Minor tweaks 2023-03-20 17:12:19 -07:00
Gregory Schier
74a1cb61c1 Fix URL bar spacing 2023-03-20 17:01:29 -07:00
Gregory Schier
268545c728 Better radio dropdown type 2023-03-20 16:54:26 -07:00
Gregory Schier
184bbb01c5 Typesafe routing and CM line height issue 2023-03-20 16:47:36 -07:00
Gregory Schier
66fa7ac419 Better tab dropdown handling 2023-03-20 14:14:30 -07:00
Gregory Schier
a80f3d997e Fix request creation priority 2023-03-20 13:56:03 -07:00
Gregory Schier
efa7c24c9f Remove log 2023-03-20 13:49:35 -07:00
Gregory Schier
91de21c7ad Handle "no body" case 2023-03-20 13:49:21 -07:00
Gregory Schier
1e9ba57ef0 Small fix 2023-03-20 13:37:14 -07:00
Gregory Schier
464389b248 Fix pointer window drag 2023-03-20 13:34:49 -07:00
Gregory Schier
107eb72eda Fix extra dropdown element 2023-03-20 13:19:23 -07:00
Gregory Schier
ee7bf838f4 Remove most of Radix UI 2023-03-20 13:16:58 -07:00
Gregory Schier
f63bcd94d1 Better Header validation 2023-03-20 01:38:05 -07:00
Gregory Schier
16d5cb6ade Tweak sidebar 2023-03-20 01:30:45 -07:00
Gregory Schier
63decdef8b Fix pair editor container 2023-03-20 01:18:44 -07:00
Gregory Schier
e54e88f46d Fix input thingy 2023-03-20 01:14:13 -07:00
Gregory Schier
b6f53d059e Container queries! 2023-03-20 01:08:41 -07:00
Gregory Schier
9e1771c5ec Better pair editor delete button 2023-03-20 00:30:42 -07:00
Gregory Schier
8306bc2198 Pair validation 2023-03-20 00:17:29 -07:00
Gregory Schier
3810fb7d51 Don't send disabled headers 2023-03-20 00:05:19 -07:00
Gregory Schier
5b4984113e Small tweak 2023-03-20 00:04:40 -07:00
Gregory Schier
baf9efe246 Pair checkboxes and fix twig indent 2023-03-20 00:03:33 -07:00
Gregory Schier
f4a3109a31 Rewrote twig grammar 2023-03-19 22:12:11 -07:00
Gregory Schier
241f2f39ec Re-order of pair editor 2023-03-19 13:28:57 -07:00
Gregory Schier
d9b40dca83 Better header editor and added completion data 2023-03-19 11:09:21 -07:00
Gregory Schier
cb3f053057 A couple tweaks 2023-03-19 01:01:13 -07:00
Gregory Schier
c4ab045e57 Persist sort priority! 2023-03-19 00:48:09 -07:00
Gregory Schier
d9b38efd97 Create new workspace, and more optimizations 2023-03-18 19:36:31 -07:00
Gregory Schier
5981588c95 Optimized a few components 2023-03-18 18:49:01 -07:00
Gregory Schier
388bef59b8 Fix sidebar drag-n-drop 2023-03-18 18:09:36 -07:00
Gregory Schier
3d8de61c1c Got drag opacity working 2023-03-18 15:06:38 -07:00
Gregory Schier
91b818f98d Good start to drag-n-drop sidebar! 2023-03-18 14:41:07 -07:00
Gregory Schier
3a7f0898f9 Fix mixed parser 2023-03-17 17:57:43 -07:00
Gregory Schier
c2f6de875a Dropdown highlight 2023-03-17 17:32:24 -07:00
Gregory Schier
0647001807 Beginnings of autocomplete for headers 2023-03-17 16:51:20 -07:00
Gregory Schier
4181d87792 Flatten migrations, kvs lib, fix tabs 2023-03-17 08:36:21 -07:00
Gregory Schier
58cf0a2015 Sidebar item dropdown 2023-03-16 15:37:53 -07:00
Gregory Schier
d80c3d305b Sidebar dragging 2023-03-16 14:34:49 -07:00
Gregory Schier
4d64a2bc2f Add devtools toggle hotkey 2023-03-16 11:25:38 -07:00
Gregory Schier
5c54beaaa9 Adjust window sizes 2023-03-16 11:16:23 -07:00
Gregory Schier
eee98f32b2 Store appearance in k/v 2023-03-16 11:01:30 -07:00
Gregory Schier
0949de66bf Hotkeys and view mode kvs 2023-03-16 09:24:28 -07:00
Gregory Schier
5a6acb24d9 Some fixes 2023-03-15 23:33:46 -07:00
Gregory Schier
2e5cab62c7 Got key values working 2023-03-15 23:24:41 -07:00
Gregory Schier
903db5fffd Fix editor padding 2023-03-15 17:29:35 -07:00
Gregory Schier
e3faf32708 Minor style updates 2023-03-15 17:25:04 -07:00
Gregory Schier
97926ddc03 Add stuff to app header 2023-03-15 16:35:19 -07:00
Gregory Schier
e891804051 Better request delete and formatting 2023-03-15 09:41:38 -07:00
Gregory Schier
a2982f8b77 Fix graphql and other things 2023-03-15 09:06:56 -07:00
Gregory Schier
321941baab Header editor to pair editor 2023-03-15 08:09:45 -07:00
Gregory Schier
e2e25dc30b Better header editor 2023-03-15 07:54:04 -07:00
Gregory Schier
1170ca4789 Strict mode and tweak layout padding 2023-03-14 20:19:45 -07:00
Gregory Schier
d159f62138 Add GraphQL variables editor 2023-03-14 19:56:02 -07:00
Gregory Schier
25005eef1b GraphQL query editor transformer works! 2023-03-14 19:08:18 -07:00
Gregory Schier
b17824c88d Add body type to request and tab dropdown 2023-03-14 11:18:56 -07:00
Gregory Schier
00f4a008f8 Improved header editor 2023-03-14 00:54:41 -07:00
Gregory Schier
3e2bc67b59 Fix platform check 2023-03-14 00:15:01 -07:00
Gregory Schier
efe072c7c4 Some small changes 2023-03-14 00:08:03 -07:00
Gregory Schier
59f1d11e40 Move stuff around 2023-03-13 23:30:14 -07:00
Gregory Schier
5f947ac983 Refactor hooks to be easier to use 2023-03-13 23:25:41 -07:00
Gregory Schier
aa66f957f2 Fix header editor and scroll in general 2023-03-13 19:37:36 -07:00
Gregory Schier
cf5f69271f Lazy load routes 2023-03-13 13:56:13 -07:00
Gregory Schier
c6653af782 Back to React 2023-03-13 09:50:49 -07:00
Gregory Schier
fa1f33a2ac Move some stuff around 2023-03-13 09:24:38 -07:00
Gregory Schier
9f479882ad Fix URL bar 2023-03-13 00:13:25 -07:00
Gregory Schier
41db316489 Fix ButtonLink and edit request names 2023-03-13 00:11:23 -07:00
Gregory Schier
50f0f5885e Remove old rust cache action 2023-03-12 22:48:43 -07:00
Gregory Schier
a609f09d50 Better rust cache 2023-03-12 22:47:43 -07:00
Gregory Schier
43f2aa3068 Start GraphQL support 2023-03-12 22:43:25 -07:00
Gregory Schier
a094e13bd5 Fix artifact tag 2023-03-12 21:41:15 -07:00
Gregory Schier
eb076afbe4 Remove wasm stuff 2023-03-12 21:25:31 -07:00
Gregory Schier
7b41488a38 Use tauri action 2023-03-12 21:13:08 -07:00
Gregory Schier
ca12d48352 Fix traffic lights thingy 2023-03-12 20:47:52 -07:00
Gregory Schier
0331d3b2b0 Cache cargo bin for "install" 2023-03-12 19:10:39 -07:00
Gregory Schier
4d4814583c Refformat 2023-03-12 19:03:27 -07:00
Gregory Schier
da3e158516 Fix artifact upload 2023-03-12 19:01:48 -07:00
Gregory Schier
7b9d6baff0 Fix dev 2023-03-12 18:39:02 -07:00
Gregory Schier
550f1b7c6f Split out macos deps 2023-03-12 18:36:25 -07:00
Gregory Schier
74e8ee1786 Cache workflow 2023-03-12 18:28:14 -07:00
Gregory Schier
55d3ea01b6 Add wasm-pack 2023-03-12 18:19:20 -07:00
Gregory Schier
4cfe51cbb2 Install rsw 2023-03-12 18:14:38 -07:00
Gregory Schier
1f5ac60523 Fix artifact names 2023-03-12 18:13:00 -07:00
Gregory Schier
26bf4f2abd Fix build command 2023-03-12 18:11:24 -07:00
Gregory Schier
54671fff79 Update secrets context 2023-03-12 18:07:57 -07:00
Gregory Schier
378309d763 Update workflow name 2023-03-12 18:05:45 -07:00
Gregory Schier
e7d4bba8b3 Fix workflow 2023-03-12 18:05:13 -07:00
Gregory Schier
fe3de0bc98 Start of auto updates 2023-03-12 18:04:11 -07:00
Gregory Schier
f3e38d7b71 Fix tabbing to tabs 2023-03-11 23:32:39 -08:00
Gregory Schier
eafa3b2de9 Fix eslint errors 2023-03-11 23:29:25 -08:00
Gregory Schier
d8cc075bd0 Got tab content scrolling working 2023-03-11 22:36:13 -08:00
Gregory Schier
bdb877a936 Removed some debug stuff 2023-03-10 10:43:15 -08:00
Gregory Schier
5c96e83a22 Refactor editor to update better 2023-03-10 10:39:23 -08:00
Gregory Schier
43abb57f77 Fix headers persistence and better sending 2023-03-09 13:38:17 -08:00
Gregory Schier
9c6d821978 Hook up header editor! 2023-03-09 13:07:13 -08:00
Gregory Schier
7e9babf515 Fix 2023-03-09 10:58:27 -08:00
Gregory Schier
ee36baf432 Fix blur de-select speed 2023-03-09 10:57:34 -08:00
Gregory Schier
0bf57dcab7 Fix Codemirror performance!! 2023-03-09 10:50:55 -08:00
Gregory Schier
e647d23adc Switch to Preact!!! 2023-03-09 00:47:25 -08:00
Gregory Schier
d1b5b9c371 Move some things around 2023-03-08 23:20:15 -08:00
Gregory Schier
92ec514442 Better scrollbar color 2023-03-08 19:23:24 -08:00
Gregory Schier
107466dd58 Zoom, better sizes, color picker, sidebar footer 2023-03-08 19:22:04 -08:00
Gregory Schier
4246260ce6 Read-only editor 2023-03-08 16:53:13 -08:00
Gregory Schier
936787d327 More theme tweaks 2023-03-08 16:37:20 -08:00
Gregory Schier
f976397283 Debounce autocomplete 2023-03-08 11:25:20 -08:00
Gregory Schier
657c6ad9a9 Minor theme updates again 2023-03-08 09:43:35 -08:00
Gregory Schier
ede07c3b0e Editor tweaks 2023-03-07 23:05:33 -08:00
Gregory Schier
9326e8dcce Remove unneeded space 2023-03-07 22:58:13 -08:00
Gregory Schier
8ff2adf833 Fix small view 2023-03-07 22:55:51 -08:00
Gregory Schier
5e387b513a Minor style tweaks 2023-03-07 22:21:58 -08:00
Gregory Schier
dca316c0d5 Lots more theme stuff 2023-03-07 21:52:21 -08:00
Gregory Schier
db2d786d50 Start of themes 2023-03-07 11:24:38 -08:00
Gregory Schier
c0d7962142 More subtle layout tweaks 2023-03-06 08:57:57 -08:00
Gregory Schier
5d14354ca9 More layout fiddling and error page 2023-03-04 22:26:00 -08:00
Gregory Schier
347dace6de More work on the layout 2023-03-04 21:51:17 -08:00
Gregory Schier
d952c75e3c Try new layout and a bunch of editor fixes 2023-03-04 19:06:12 -08:00
Gregory Schier
abc3745be1 Fix autocomplete inside dialog 2023-03-03 17:03:20 -08:00
Gregory Schier
1382d7c523 Beginnings of Header Editor 2023-03-03 13:18:57 -08:00
Gregory Schier
3de0edf0f9 Fix tailwind dark selector 2023-03-03 07:54:19 -08:00
Gregory Schier
5513d39152 Fix content type in URL 2023-03-02 23:17:09 -08:00
Gregory Schier
1a9547d1d2 Add Dialog component 2023-03-02 18:46:10 -08:00
Gregory Schier
26cc64d3a0 More colors 2023-03-02 17:56:53 -08:00
Gregory Schier
e465b33365 Minor style tweaks 2023-03-02 16:16:41 -08:00
Gregory Schier
957739ba5e Improved autocompletion! 2023-03-02 11:14:51 -08:00
Gregory Schier
59967374c5 Rename, fix autocomplete and singleline, etc... 2023-03-02 10:42:43 -08:00
Gregory Schier
43bc346a2b Editor placeholder 2023-03-01 14:22:10 -08:00
Gregory Schier
5fbd3f67cd Some minor bugs 2023-03-01 14:16:02 -08:00
Gregory Schier
e352343d62 Fix migrations for build and iframe rendering 2023-03-01 10:31:50 -08:00
Gregory Schier
baee0f0c6f Tweaks 2023-03-01 10:19:21 -08:00
Gregory Schier
fcc5eead88 Response streaming 2023-03-01 09:05:00 -08:00
Gregory Schier
29d1f687d1 Autocomplete, and more CM stuff! 2023-02-28 22:54:54 -08:00
Gregory Schier
f568266c7f Some small tweaks 2023-02-28 17:25:59 -08:00
Gregory Schier
a1e42b8ddb Better editor updating 2023-02-28 12:41:03 -08:00
Gregory Schier
e6389b1153 URL highlighting with inline CM 2023-02-28 11:26:26 -08:00
Gregory Schier
f0835acb33 Implement request deletion 2023-02-27 15:42:06 -08:00
Gregory Schier
35b04b219f Tauri events for request model updates 2023-02-27 13:28:50 -08:00
Gregory Schier
01b62e936a Split request upsert command 2023-02-27 10:00:57 -08:00
Gregory Schier
09d16a03ef Add toggle for pretty view 2023-02-27 09:08:48 -08:00
Gregory Schier
bb61602fd2 Small tweaks 2023-02-26 15:25:55 -08:00
Gregory Schier
f30b78ea1f Add variable highlighting widgets 2023-02-26 15:06:14 -08:00
Gregory Schier
6ee652ca75 Dropdown scrolling 2023-02-25 23:33:07 -08:00
Gregory Schier
67d8bbc154 Show response body size 2023-02-25 23:08:19 -08:00
Gregory Schier
b852484559 A bunch more small things 2023-02-25 23:04:31 -08:00
Gregory Schier
0b077e5e88 Added react-router 2023-02-25 18:04:14 -08:00
Gregory Schier
381d957db2 Migrations and initial data stuff 2023-02-25 16:39:18 -08:00
Gregory Schier
f8f77abc12 Minor tweaks 2023-02-24 17:01:48 -08:00
Gregory Schier
0b0484c610 Dummy requests in sidebar 2023-02-24 16:46:56 -08:00
Gregory Schier
2b769088af Codemirror initial value support 2023-02-24 16:43:47 -08:00
Gregory Schier
856d13c603 Send request body 2023-02-24 16:09:19 -08:00
Gregory Schier
76e398b8a1 Vendor basicSetup 2023-02-24 14:51:56 -08:00
Gregory Schier
24a7d85be0 Additional methods and tweaks 2023-02-24 14:10:25 -08:00
Gregory Schier
989271f653 Focus states 2023-02-24 12:35:13 -08:00
Gregory Schier
3fd8cd5713 Hook up theme and clear responses 2023-02-24 12:13:30 -08:00
Gregory Schier
43f1c7caf6 SQLite store in proper dir 2023-02-22 20:18:14 -08:00
Gregory Schier
bd91ac88a3 Started on grid layout 2023-02-22 19:44:44 -08:00
Gregory Schier
fbcbf2e5a5 Save responses in DB 2023-02-22 18:53:44 -08:00
Gregory Schier
31eb03da0d Better URL bar 2023-02-22 16:15:25 -08:00
Gregory Schier
a4dbfed712 Cleaner URL bar and some improvements 2023-02-22 15:58:04 -08:00
Gregory Schier
784cb53ec6 Refactor classname usage 2023-02-21 18:03:57 -08:00
Gregory Schier
43c799bd60 Some minor tweaks 2023-02-21 17:56:48 -08:00
504 changed files with 72937 additions and 10171 deletions

View File

@@ -1,25 +1,37 @@
module.exports = {
extends: [
'eslint:recommended',
'plugin:react/recommended',
'plugin:import/recommended',
'plugin:jsx-a11y/recommended',
'plugin:@typescript-eslint/recommended',
'eslint-config-prettier',
],
ignorePatterns: ['src-tauri/**/*'],
settings: {
react: {
version: 'detect',
},
'import/resolver': {
node: {
paths: ['src-web'],
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
},
},
rules: {
"react/react-in-jsx-scope": "off",
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:import/recommended",
"plugin:jsx-a11y/recommended",
"plugin:@typescript-eslint/recommended",
"eslint-config-prettier"
],
parser: "@typescript-eslint/parser",
parserOptions: {
project: ["./tsconfig.json"]
},
ignorePatterns: ["scripts/**/*", "plugin-runtime/**/*", "src-tauri/**/*", "plugins/**/*"],
settings: {
react: {
version: "detect"
},
"import/resolver": {
node: {
paths: ["src-web"],
extensions: [".ts", ".tsx"]
}
}
},
rules: {
"jsx-a11y/no-autofocus": "off",
"react/react-in-jsx-scope": "off",
"import/no-unresolved": "off",
"@typescript-eslint/consistent-type-imports": ["error", {
prefer: "type-imports",
disallowTypeAnnotations: true,
fixStyle: "separate-type-imports"
}]
}
};

18
.github/workflows/ci-js.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
on:
pull_request:
branches: [develop]
name: CI (JS)
jobs:
test:
name: Lint/Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run lint
- run: npm test

36
.github/workflows/ci-rust.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
on:
pull_request:
branches: [develop]
paths:
- src-tauri/**
- .github/workflows/**
name: CI (Rust)
defaults:
run:
working-directory: src-tauri
jobs:
test:
name: Check/Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev
- uses: dtolnay/rust-toolchain@stable
- uses: actions/cache@v3
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- run: cargo check --all
- run: cargo test --all

120
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,120 @@
name: Generate Artifacts
on:
push:
tags: [ v* ]
env:
YAAK_PLUGINS_DIR: checkout/plugins
jobs:
build-artifacts:
permissions:
contents: write
name: Build
strategy:
fail-fast: false
matrix:
include:
- platform: 'macos-latest' # for Arm-based macs (M1 and above).
args: '--target aarch64-apple-darwin'
yaak_arch: 'arm64'
- platform: 'macos-latest' # for Intel-based macs.
args: '--target x86_64-apple-darwin'
yaak_arch: 'x64'
- platform: 'ubuntu-22.04' # for Tauri v1, you could replace this with ubuntu-20.04.
args: ''
yaak_arch: 'x64'
- platform: 'windows-latest'
args: ''
yaak_arch: 'x64'
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout yaakapp/app
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
# Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- uses: actions/cache@v3
continue-on-error: false
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above.
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
- name: Install Node dependencies
run: |
npm ci
- name: Install plugin-runtime Node dependencies
working-directory: plugin-runtime
run: |
npm ci
- name: Install Protoc for plugin-runtime
uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install yaak CLI
run: go install github.com/yaakapp/yaakcli@latest
- name: Run lint
run: npm run lint
- name: Checkout yaakapp/plugins
uses: actions/checkout@v4
with:
repository: yaakapp/plugins
path: ${{ env.YAAK_PLUGINS_DIR }}
- name: Set version
run: npm run replace-version
env:
YAAK_VERSION: ${{ github.ref_name }}
- uses: tauri-apps/tauri-action@v0
env:
YAAK_PLUGINS_DIR: ${{ env.YAAK_PLUGINS_DIR }}
YAAK_TARGET_ARCH: ${{ matrix.yaak_arch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
with:
tagName: 'v__VERSION__'
releaseName: 'Release __VERSION__'
releaseBody: 'https://yaak.app/changelog/__VERSION__'
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}

9
.gitignore vendored
View File

@@ -22,5 +22,12 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.eslintcache
.rsw
*.sqlite
*.sqlite-*
.cargo
.tmp
tmp

1
.husky/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
_

4
.husky/pre-commit Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged

2
.nvmrc
View File

@@ -1 +1 @@
18
20

View File

@@ -1,3 +1,4 @@
node_modules/
dist/
out/
.prettierrc.cjs

13
.run/Dev Desktop.run.xml Normal file
View File

@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Dev Desktop" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="start" />
</scripts>
<node-interpreter value="project" />
<envs>
</envs>
<method v="2" />
</configuration>
</component>

5
.sqllsrc.json Normal file
View File

@@ -0,0 +1,5 @@
{
"name": "yaak-dev",
"adapter": "sqlite3",
"filename": "src-tauri/db.sqlite"
}

13
Makefile Normal file
View File

@@ -0,0 +1,13 @@
.PHONY: sqlx-prepare, dev, migrate, build
sqlx-prepare:
cd src-tauri && cargo sqlx prepare --database-url 'sqlite://db.sqlite'
dev:
npm run tauri-dev
migrate:
cd src-tauri && cargo sqlx migrate run --database-url 'sqlite://db.sqlite?mode=rw'
build:
./node_modules/.bin/tauri build

View File

@@ -1,3 +1,16 @@
# Tauri REST Client
# Yaak Network Toolkit
It's a REST client, yo.
The most fun you'll ever have working with APIs.
## Common Commands
```sh
# Start dev app
npm run tauri-dev
# Migration commands
cd src-tauri
cargo sqlx migrate add ${MIGRATION_NAME}
cargo sqlx migrate run --database-url 'sqlite://db.sqlite?mode=rw'
cargo sqlx prepare --database-url 'sqlite://db.sqlite'
```

BIN
design/Icons.afdesign Normal file
View File

Binary file not shown.

BIN
design/icon-dev.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
design/icon.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 KiB

BIN
design/logo.afdesign Normal file
View File

Binary file not shown.

View File

@@ -1,15 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri + React + TS</title>
</head>
<head>
<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>
<body>
<div id="root"></div>
<div id="radix-portal"></div>
<script type="module" src="/src-web/main.tsx"></script>
</body>
<!-- Certain elements like webview (and maybe <select>?) will use background
color depending on document background color-->
<style>
html, body {
background-color: white;
}
@media (prefers-color-scheme: dark) {
html, body {
background-color: #1b1a29;
}
}
</style>
</head>
<body class="text-base">
<div id="root"></div>
<div id="cm-portal" class="cm-portal"></div>
<div id="react-portal"></div>
<div id="radix-portal" class="cm-portal"></div>
<script type="module" src="/src-web/main.tsx"></script>
</body>
</html>

15284
package-lock.json generated
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,51 +1,114 @@
{
"name": "tauri-app",
"name": "yaak-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"build": "rsw build && tsc && vite build",
"dev": "vite",
"lint": "eslint . --ext .ts,.tsx",
"preview": "vite preview",
"tauri-dev": "concurrently -n app,rsw \"tauri dev\" \"rsw watch\""
"start": "npm run tauri-dev:desktop",
"tauri-dev:desktop": "tauri dev --no-watch --config ./src-tauri/tauri-dev.conf.json",
"tauri-dev:ios": "tauri ios dev --force-ip-prompt --config ./src-tauri/tauri-dev.conf.json",
"tauri-build": "tauri build",
"tauri": "tauri",
"dev:js": "vite dev",
"lint": "tsc && eslint . --ext .ts,.tsx",
"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: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"
},
"dependencies": {
"@codemirror/lang-html": "^6.4.2",
"@codemirror/lang-javascript": "^6.1.4",
"@codemirror/commands": "^6.2.1",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-json": "^6.0.1",
"@radix-ui/react-dropdown-menu": "^2.0.2",
"@radix-ui/react-icons": "^1.2.0",
"@radix-ui/react-popover": "1.0.3",
"@tauri-apps/api": "^1.2.0",
"@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.52.0",
"@codemirror/lang-xml": "^6.0.2",
"@codemirror/language": "^6.6.0",
"@codemirror/search": "^6.2.3",
"@lezer/generator": "^1.2.2",
"@lezer/highlight": "^1.1.3",
"@lezer/lr": "^1.3.3",
"@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",
"buffer": "^6.0.3",
"classnames": "^2.3.2",
"cm6-graphql": "^0.0.9",
"codemirror": "^6.0.1",
"codemirror-json-schema": "^0.6.1",
"date-fns": "^3.3.1",
"fast-fuzzy": "^1.12.0",
"focus-trap-react": "^10.1.1",
"format-graphql": "^1.4.0",
"framer-motion": "^9.0.4",
"lucide-react": "^0.309.0",
"mime": "^4.0.1",
"papaparse": "^5.4.1",
"parse-color": "^1.0.0",
"react": "^18.2.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.2.0",
"react-helmet-async": "^1.3.0",
"react-pdf": "^9.0.0",
"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",
"@types/node": "^18.7.10",
"@types/papaparse": "^5.3.7",
"@types/parse-color": "^1.0.1",
"@types/parse-json": "^4.0.0",
"@types/react": "^18.0.31",
"@types/react-dom": "^18.0.11",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.13",
"decompress": "^4.2.1",
"eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.2",
"framer-motion": "^9.0.4",
"prettier": "^2.8.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet-async": "^1.3.0"
},
"devDependencies": {
"@tauri-apps/cli": "^1.2.2",
"@types/node": "^18.7.10",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@vitejs/plugin-react": "^3.0.0",
"autoprefixer": "^10.4.13",
"concurrently": "^7.6.0",
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.3",
"internal-ip": "^8.0.0",
"lint-staged": "^15.0.2",
"nodejs-file-downloader": "^4.13.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.21",
"postcss-nesting": "^11.2.1",
"prettier": "^2.8.4",
"react-devtools": "^4.27.2",
"rimraf": "^5.0.7",
"tailwindcss": "^3.2.7",
"typescript": "^4.6.4",
"vite": "^4.0.0",
"vite-plugin-rsw": "^2.0.11",
"vite-plugin-top-level-await": "^1.2.4"
"typescript": "^5.4.5",
"vite": "^5.0.0",
"vite-plugin-static-copy": "^1.0.5",
"vite-plugin-svgr": "^4.2.0",
"vite-plugin-top-level-await": "^1.4.1"
},
"lint-staged": {
"*.{ts,tsx}": "eslint --cache --fix",
"*.{js,css,md}": "prettier --write"
}
}

3
plugin-runtime/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
build
node_modules
*.blob

View File

@@ -0,0 +1,5 @@
{
"watch": ["src"],
"ext": "ts",
"exec": "node -r ts-node/register ./src/index.ts"
}

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
{
"name": "@yaak/plugin-runtime",
"scripts": {
"dev": "nodemon",
"build": "run-p build:*",
"build:main": "esbuild src/index.ts --bundle --platform=node --outfile=build/index.cjs",
"build:worker": "esbuild src/index.worker.ts --bundle --platform=node --outfile=build/index.worker.cjs",
"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": {
"long": "^5.2.3",
"nice-grpc": "^2.1.9",
"protobufjs": "^7.3.2"
},
"devDependencies": {
"grpc-tools": "^1.12.4",
"nodemon": "^3.1.4",
"npm-run-all": "^4.1.5",
"ts-node": "^10.9.2",
"ts-proto": "^1.180.0",
"typescript": "^5.5.2"
}
}

View File

@@ -0,0 +1,92 @@
import { randomUUID } from 'node:crypto';
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>;
export class PluginHandle {
readonly pluginDir: string;
readonly #worker: Worker;
constructor(pluginDir: string) {
this.pluginDir = pluginDir;
const workerPath = path.join(__dirname, 'index.worker.cjs');
this.#worker = new Worker(workerPath, {
workerData: {
pluginDir: this.pluginDir,
},
});
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 });
});
}
async #handleError(err: Error) {
console.error('Plugin errored', this.pluginDir, err);
}
async #handleExit(code: number) {
if (code === 0) {
console.log('Plugin exited successfully', this.pluginDir);
} else {
console.log('Plugin exited with error', code, this.pluginDir);
}
}
}

View File

@@ -0,0 +1,44 @@
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

@@ -0,0 +1,432 @@
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
// versions:
// protoc-gen-ts_proto v1.180.0
// protoc v3.19.1
// source: plugins/runtime.proto
/* eslint-disable */
import { type CallContext, type CallOptions } from "nice-grpc-common";
import * as _m0 from "protobufjs/minimal";
export const protobufPackage = "yaak.plugins.runtime";
export interface PluginInfo {
plugin: string;
}
export interface HookResponse {
info: PluginInfo | undefined;
data: string;
}
export interface HookImportRequest {
data: string;
}
export interface HookResponseFilterRequest {
filter: string;
body: string;
contentType: string;
}
export interface HookExportRequest {
request: string;
}
function createBasePluginInfo(): PluginInfo {
return { plugin: "" };
}
export const PluginInfo = {
encode(message: PluginInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.plugin !== "") {
writer.uint32(10).string(message.plugin);
}
return writer;
},
decode(input: _m0.Reader | Uint8Array, length?: number): PluginInfo {
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBasePluginInfo();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (tag !== 10) {
break;
}
message.plugin = reader.string();
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skipType(tag & 7);
}
return message;
},
fromJSON(object: any): PluginInfo {
return { plugin: isSet(object.plugin) ? globalThis.String(object.plugin) : "" };
},
toJSON(message: PluginInfo): unknown {
const obj: any = {};
if (message.plugin !== "") {
obj.plugin = message.plugin;
}
return obj;
},
create(base?: DeepPartial<PluginInfo>): PluginInfo {
return PluginInfo.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<PluginInfo>): PluginInfo {
const message = createBasePluginInfo();
message.plugin = object.plugin ?? "";
return message;
},
};
function createBaseHookResponse(): HookResponse {
return { info: undefined, data: "" };
}
export const HookResponse = {
encode(message: HookResponse, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.info !== undefined) {
PluginInfo.encode(message.info, writer.uint32(10).fork()).ldelim();
}
if (message.data !== "") {
writer.uint32(18).string(message.data);
}
return writer;
},
decode(input: _m0.Reader | Uint8Array, length?: number): HookResponse {
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseHookResponse();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (tag !== 10) {
break;
}
message.info = PluginInfo.decode(reader, reader.uint32());
continue;
case 2:
if (tag !== 18) {
break;
}
message.data = reader.string();
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skipType(tag & 7);
}
return message;
},
fromJSON(object: any): HookResponse {
return {
info: isSet(object.info) ? PluginInfo.fromJSON(object.info) : undefined,
data: isSet(object.data) ? globalThis.String(object.data) : "",
};
},
toJSON(message: HookResponse): unknown {
const obj: any = {};
if (message.info !== undefined) {
obj.info = PluginInfo.toJSON(message.info);
}
if (message.data !== "") {
obj.data = message.data;
}
return obj;
},
create(base?: DeepPartial<HookResponse>): HookResponse {
return HookResponse.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<HookResponse>): HookResponse {
const message = createBaseHookResponse();
message.info = (object.info !== undefined && object.info !== null)
? PluginInfo.fromPartial(object.info)
: undefined;
message.data = object.data ?? "";
return message;
},
};
function createBaseHookImportRequest(): HookImportRequest {
return { data: "" };
}
export const HookImportRequest = {
encode(message: HookImportRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.data !== "") {
writer.uint32(10).string(message.data);
}
return writer;
},
decode(input: _m0.Reader | Uint8Array, length?: number): HookImportRequest {
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseHookImportRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (tag !== 10) {
break;
}
message.data = reader.string();
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skipType(tag & 7);
}
return message;
},
fromJSON(object: any): HookImportRequest {
return { data: isSet(object.data) ? globalThis.String(object.data) : "" };
},
toJSON(message: HookImportRequest): unknown {
const obj: any = {};
if (message.data !== "") {
obj.data = message.data;
}
return obj;
},
create(base?: DeepPartial<HookImportRequest>): HookImportRequest {
return HookImportRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<HookImportRequest>): HookImportRequest {
const message = createBaseHookImportRequest();
message.data = object.data ?? "";
return message;
},
};
function createBaseHookResponseFilterRequest(): HookResponseFilterRequest {
return { filter: "", body: "", contentType: "" };
}
export const HookResponseFilterRequest = {
encode(message: HookResponseFilterRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.filter !== "") {
writer.uint32(10).string(message.filter);
}
if (message.body !== "") {
writer.uint32(18).string(message.body);
}
if (message.contentType !== "") {
writer.uint32(26).string(message.contentType);
}
return writer;
},
decode(input: _m0.Reader | Uint8Array, length?: number): HookResponseFilterRequest {
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseHookResponseFilterRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (tag !== 10) {
break;
}
message.filter = reader.string();
continue;
case 2:
if (tag !== 18) {
break;
}
message.body = reader.string();
continue;
case 3:
if (tag !== 26) {
break;
}
message.contentType = reader.string();
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skipType(tag & 7);
}
return message;
},
fromJSON(object: any): HookResponseFilterRequest {
return {
filter: isSet(object.filter) ? globalThis.String(object.filter) : "",
body: isSet(object.body) ? globalThis.String(object.body) : "",
contentType: isSet(object.contentType) ? globalThis.String(object.contentType) : "",
};
},
toJSON(message: HookResponseFilterRequest): unknown {
const obj: any = {};
if (message.filter !== "") {
obj.filter = message.filter;
}
if (message.body !== "") {
obj.body = message.body;
}
if (message.contentType !== "") {
obj.contentType = message.contentType;
}
return obj;
},
create(base?: DeepPartial<HookResponseFilterRequest>): HookResponseFilterRequest {
return HookResponseFilterRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<HookResponseFilterRequest>): HookResponseFilterRequest {
const message = createBaseHookResponseFilterRequest();
message.filter = object.filter ?? "";
message.body = object.body ?? "";
message.contentType = object.contentType ?? "";
return message;
},
};
function createBaseHookExportRequest(): HookExportRequest {
return { request: "" };
}
export const HookExportRequest = {
encode(message: HookExportRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.request !== "") {
writer.uint32(10).string(message.request);
}
return writer;
},
decode(input: _m0.Reader | Uint8Array, length?: number): HookExportRequest {
const reader = input instanceof _m0.Reader ? input : _m0.Reader.create(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseHookExportRequest();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (tag !== 10) {
break;
}
message.request = reader.string();
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skipType(tag & 7);
}
return message;
},
fromJSON(object: any): HookExportRequest {
return { request: isSet(object.request) ? globalThis.String(object.request) : "" };
},
toJSON(message: HookExportRequest): unknown {
const obj: any = {};
if (message.request !== "") {
obj.request = message.request;
}
return obj;
},
create(base?: DeepPartial<HookExportRequest>): HookExportRequest {
return HookExportRequest.fromPartial(base ?? {});
},
fromPartial(object: DeepPartial<HookExportRequest>): HookExportRequest {
const message = createBaseHookExportRequest();
message.request = object.request ?? "";
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,
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,
context: CallContext & CallContextExt,
): Promise<DeepPartial<HookResponse>>;
}
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>,
options?: CallOptions & CallOptionsExt,
): Promise<HookResponse>;
}
type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
export type DeepPartial<T> = T extends Builtin ? T
: T extends globalThis.Array<infer U> ? globalThis.Array<DeepPartial<U>>
: T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
: T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
: Partial<T>;
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}

View File

@@ -0,0 +1,87 @@
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';
class PluginRuntimeService implements PluginRuntimeServiceImplementation {
#manager: PluginManager;
constructor() {
this.#manager = PluginManager.instance();
}
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 };
}
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,
) {
try {
return yield* call.next(call.request, context);
} catch (error: unknown) {
if (error instanceof ServerError || isAbortError(error)) {
throw error;
}
let details = String(error);
if (process.env.NODE_ENV === 'development') {
// @ts-ignore
details += `: ${error.stack}`;
}
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

@@ -0,0 +1,76 @@
import { readFileSync } from 'node:fs';
import path from 'node:path';
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 pathPkg = path.join(pluginDir, 'package.json');
let pkg: { [x: string]: any };
try {
pkg = JSON.parse(readFileSync(pathPkg, 'utf8'));
} catch (err) {
// TODO: Do something better here
reject(err);
return;
}
const mod = (await import(`file://${pathMod}`)).default ?? {};
const info: PluginInfo = {
capabilities: [],
name: pkg['name'] ?? 'n/a',
dir: pluginDir,
};
if (typeof mod['pluginHookImport'] === 'function') {
info.capabilities.push('import');
}
if (typeof mod['pluginHookExport'] === 'function') {
info.capabilities.push('export');
}
if (typeof mod['pluginHookResponseFilter'] === 'function') {
info.capabilities.push('filter');
}
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);
}
} catch (err: unknown) {
replyErr(msg, err);
}
});
resolve();
}).catch((err) => {
console.log('failed to boot plugin', err);
});

View File

@@ -0,0 +1,18 @@
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

@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "node16",
"strict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "es2021",
"lib": ["es2021"],
"noImplicitAny": false,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"skipLibCheck": true,
"paths": {
"*": [
"node_modules/*",
"src/types/*"
]
}
},
"include": [
"src/**/*"
]
}

View File

@@ -1,6 +1,7 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
plugins: [
require('@tailwindcss/nesting')(require('postcss-nesting')),
require('tailwindcss'),
require('autoprefixer'),
]
}

View File

@@ -0,0 +1,32 @@
syntax = "proto3";
package yaak.plugins.runtime;
service PluginRuntime {
rpc hookImport (HookImportRequest) returns (HookResponse);
rpc hookExport (HookExportRequest) returns (HookResponse);
rpc hookResponseFilter (HookResponseFilterRequest) returns (HookResponse);
}
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;
}

View File

@@ -1,39 +0,0 @@
name = "rsw"
version = "0.1.0"
#! time interval for file changes to trigger wasm-pack build, default `50` milliseconds
interval = 50
#! link
#! npm link @see https://docs.npmjs.com/cli/v8/commands/npm-link
#! yarn link @see https://classic.yarnpkg.com/en/docs/cli/link
#! pnpm link @see https://pnpm.io/cli/link
#! The link command will only be executed if `[[crates]] link = true`
#! cli: `npm` | `yarn` | `pnpm`, default is `npm`
cli = "npm"
#! ---------------------------
#! rsw new <name>
[new]
#! @see https://rustwasm.github.io/docs/wasm-pack/commands/new.html
#! using: `wasm-pack` | `rsw` | `user`, default is `wasm-pack`
#! 1. wasm-pack: `rsw new <name> --template <template> --mode <normal|noinstall|force>`
#! 2. rsw: `rsw new <name>`, built-in templates
#! 3. user: `rsw new <name>`, if `dir` is not configured, use `wasm-pack new <name>` to initialize the project
using = "wasm-pack"
#! this field needs to be configured when `using = "user"`
#! `using = "wasm-pack"` or `using = "rsw"`, this field will be ignored
#! copy all files in this directory
dir = "my-template"
#! ################# NPM Package #################
#! When there is only `name`, other fields will use the default configuration
#! 📦 -------- package: @rsw --------
[[crates]]
#! npm package name (path: $ROOT/@rsw)
name = "src-wasm/hello"
#! run `npm link`: `true` | `false`, default is `false`
link = true

1
rustfmt.toml Normal file
View File

@@ -0,0 +1 @@
edition = "2018"

View File

@@ -0,0 +1,15 @@
const path = require('path');
const fs = require('fs');
const version = process.env.YAAK_VERSION?.replace('v', '');
if (!version) {
throw new Error('YAAK_VERSION environment variable not set')
}
const tauriConfigPath = path.join(__dirname, '../src-tauri/tauri.conf.json');
const tauriConfig = JSON.parse(fs.readFileSync(tauriConfigPath, 'utf8'));
tauriConfig.version = version;
console.log('Writing version ' + version + ' to ' + tauriConfigPath)
fs.writeFileSync(tauriConfigPath, JSON.stringify(tauriConfig, null, 2));

69
scripts/vendor-node.cjs Normal file
View File

@@ -0,0 +1,69 @@
const path = require('node:path');
const decompress = require('decompress');
const Downloader = require("nodejs-file-downloader");
const {rmSync, cpSync, mkdirSync, existsSync} = require("node:fs");
const {execSync} = require("node:child_process");
const NODE_VERSION = 'v22.5.1';
// `${process.platform}_${process.arch}`
const MAC_ARM = 'darwin_arm64';
const MAC_X64 = 'darwin_x64';
const LNX_X64 = 'linux_x64';
const WIN_X64 = 'win32_x64';
const URL_MAP = {
[MAC_ARM]: `https://nodejs.org/download/release/${NODE_VERSION}/node-${NODE_VERSION}-darwin-arm64.tar.gz`,
[MAC_X64]: `https://nodejs.org/download/release/${NODE_VERSION}/node-${NODE_VERSION}-darwin-x64.tar.gz`,
[LNX_X64]: `https://nodejs.org/download/release/${NODE_VERSION}/node-${NODE_VERSION}-linux-x64.tar.gz`,
[WIN_X64]: `https://nodejs.org/download/release/${NODE_VERSION}/node-${NODE_VERSION}-win-x64.zip`,
};
const SRC_BIN_MAP = {
[MAC_ARM]: `node-${NODE_VERSION}-darwin-arm64/bin/node`,
[MAC_X64]: `node-${NODE_VERSION}-darwin-x64/bin/node`,
[LNX_X64]: `node-${NODE_VERSION}-linux-x64/bin/node`,
[WIN_X64]: `node-${NODE_VERSION}-win-x64/node.exe`,
};
const DST_BIN_MAP = {
darwin_arm64: 'yaaknode-aarch64-apple-darwin',
darwin_x64: 'yaaknode-x86_64-apple-darwin',
linux_x64: 'yaaknode-x86_64-unknown-linux-gnu',
win32_x64: 'yaaknode-x86_64-pc-windows-msvc.exe',
};
const key = `${process.platform}_${process.env.YAAK_TARGET_ARCH ?? process.arch}`;
const destDir = path.join(__dirname, `..`, 'src-tauri', 'vendored', 'node');
const binDest = path.join(destDir, DST_BIN_MAP[key]);
console.log(`Vendoring NodeJS ${NODE_VERSION} for ${key}`);
if (existsSync(binDest) && execSync(`${binDest} --version`).toString('utf-8').trim() === NODE_VERSION) {
console.log("NodeJS already vendored");
return;
}
rmSync(destDir, {recursive: true, force: true});
mkdirSync(destDir, {recursive: true});
(async function () {
const url = URL_MAP[key];
const tmpDir = path.join(__dirname, 'tmp', Date.now().toString());
// Download GitHub release artifact
const {filePath} = await new Downloader({url, directory: tmpDir,}).download();
// Decompress to the same directory
await decompress(filePath, tmpDir, {});
// Copy binary
const binSrc = path.join(tmpDir, SRC_BIN_MAP[key]);
cpSync(binSrc, binDest);
rmSync(tmpDir, {recursive: true, force: true});
console.log("Downloaded NodeJS to", binDest);
})().catch(err => {
console.log('Script failed:', err);
process.exit(1);
});

View File

@@ -0,0 +1,25 @@
const {readdirSync, cpSync} = require("node:fs");
const path = require("node:path");
const {execSync} = require("node:child_process");
const pluginsDir = process.env.YAAK_PLUGINS_DIR;
if (!pluginsDir) {
console.log("YAAK_PLUGINS_DIR is not set");
process.exit(1);
}
console.log('Installing Yaak plugins dependencies', pluginsDir);
execSync('npm ci', {cwd: pluginsDir});
console.log('Building Yaak plugins', pluginsDir);
execSync('npm run build', {cwd: pluginsDir});
console.log('Copying Yaak plugins to', pluginsDir);
const pluginsRoot = path.join(pluginsDir, 'plugins');
for (const name of readdirSync(pluginsRoot)) {
const dir = path.join(pluginsRoot, name);
if (name.startsWith('.')) continue;
const destDir = path.join(__dirname, '../src-tauri/vendored/plugins/', name);
console.log(`Copying ${name} to ${destDir}`);
cpSync(path.join(dir, 'package.json'), path.join(destDir, 'package.json'));
cpSync(path.join(dir, 'build/index.js'), path.join(destDir, 'build/index.js'));
}

62
scripts/vendor-protoc.cjs Normal file
View File

@@ -0,0 +1,62 @@
const decompress = require('decompress');
const Downloader = require("nodejs-file-downloader");
const path = require("node:path");
const {rmSync, mkdirSync, cpSync} = require("node:fs");
// `${process.platform}_${process.arch}`
const MAC_ARM = 'darwin_arm64';
const MAC_X64 = 'darwin_x64';
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',
};
const SRC_BIN_MAP = {
[MAC_ARM]: 'bin/protoc',
[MAC_X64]: 'bin/protoc',
[LNX_X64]: 'bin/protoc',
[WIN_X64]: 'bin/protoc.exe',
};
const DST_BIN_MAP = {
[MAC_ARM]: 'yaakprotoc-aarch64-apple-darwin',
[MAC_X64]: 'yaakprotoc-x86_64-apple-darwin',
[LNX_X64]: 'yaakprotoc-x86_64-unknown-linux-gnu',
[WIN_X64]: 'yaakprotoc-x86_64-pc-windows-msvc.exe',
};
const dstDir = path.join(__dirname, `..`, 'src-tauri', 'vendored', 'protoc');
rmSync(dstDir, {recursive: true, force: true});
mkdirSync(dstDir, {recursive: true});
(async function () {
const key = `${process.platform}_${process.env.YAAK_TARGET_ARCH ?? process.arch}`;
console.log("Vendoring protoc binary for", key);
const url = URL_MAP[key];
const tmpDir = path.join(__dirname, 'tmp', Date.now().toString());
// Download GitHub release artifact
const {filePath} = await new Downloader({url, directory: tmpDir,}).download();
// Decompress to the same directory
await decompress(filePath, tmpDir, {});
// Copy binary
const binSrc = path.join(tmpDir, SRC_BIN_MAP[key]);
const binDst = path.join(dstDir, DST_BIN_MAP[key]);
cpSync(binSrc, binDst);
// Copy other files
const includeSrc = path.join(tmpDir, 'include');
const includeDst = path.join(dstDir, 'include');
cpSync(includeSrc, includeDst, {recursive: true});
rmSync(tmpDir, {recursive: true, force: true});
console.log("Downloaded protoc to", binDst);
})().catch(err => console.log('Script failed:', err));

View File

@@ -2,3 +2,4 @@
# will have compiled files and executables
/target/
vendored

View File

@@ -0,0 +1,50 @@
{
"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

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

View File

@@ -0,0 +1,116 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,104 @@
{
"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

@@ -0,0 +1,80 @@
{
"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

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

View File

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,92 @@
{
"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

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

View File

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

View File

@@ -0,0 +1,62 @@
{
"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

@@ -0,0 +1,110 @@
{
"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

@@ -0,0 +1,56 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,56 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

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

View File

@@ -0,0 +1,74 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,80 @@
{
"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

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

View File

@@ -0,0 +1,74 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,12 @@
{
"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

@@ -0,0 +1,116 @@
{
"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

@@ -0,0 +1,62 @@
{
"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

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

View File

@@ -0,0 +1,12 @@
{
"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

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

View File

@@ -0,0 +1,56 @@
{
"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

@@ -0,0 +1,92 @@
{
"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"
}

View File

@@ -0,0 +1,116 @@
{
"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 workspace_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": "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": "d5e087caa163a0c7bfbbadf07eccb80105501cf5baab706aa6792dfe90af8fc9"
}

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n INSERT INTO key_values (namespace, key, value)\n VALUES (?, ?, ?) ON CONFLICT DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n value = excluded.value\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "d80c09497771e3641022e73ec6c6a87e73a551f88a948a5445d754922b82b50b"
}

View File

@@ -0,0 +1,98 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, created_at, updated_at, theme, appearance,\n theme_dark, theme_light, update_channel,\n interface_font_size, interface_scale, editor_font_size, editor_soft_wrap,\n open_workspace_new_window\n FROM settings\n WHERE id = 'default'\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": "theme",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "appearance",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "theme_dark",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "theme_light",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "update_channel",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "interface_font_size",
"ordinal": 9,
"type_info": "Int64"
},
{
"name": "interface_scale",
"ordinal": 10,
"type_info": "Int64"
},
{
"name": "editor_font_size",
"ordinal": 11,
"type_info": "Int64"
},
{
"name": "editor_soft_wrap",
"ordinal": 12,
"type_info": "Bool"
},
{
"name": "open_workspace_new_window",
"ordinal": 13,
"type_info": "Bool"
}
],
"parameters": {
"Right": 0
},
"nullable": [
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
false,
true
]
},
"hash": "daa61066517df649e7c80a8ce407839ad502e8e5e43aa8c02e049865acbbae75"
}

View File

@@ -0,0 +1,104 @@
{
"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 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": "e1cdba43bd938772631263966a9bee263923c387f4864917f36a04043bec4857"
}

View File

@@ -0,0 +1,110 @@
{
"db_name": "SQLite",
"query": "\n SELECT\n id, model, workspace_id, folder_id, created_at, updated_at, name, url,\n url_parameters AS \"url_parameters!: sqlx::types::Json<Vec<HttpUrlParameter>>\",\n method, body_type, authentication_type, sort_priority,\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 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": "url",
"ordinal": 7,
"type_info": "Text"
},
{
"name": "url_parameters!: sqlx::types::Json<Vec<HttpUrlParameter>>",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "method",
"ordinal": 9,
"type_info": "Text"
},
{
"name": "body_type",
"ordinal": 10,
"type_info": "Text"
},
{
"name": "authentication_type",
"ordinal": 11,
"type_info": "Text"
},
{
"name": "sort_priority",
"ordinal": 12,
"type_info": "Float"
},
{
"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,
false,
true,
true,
false,
false,
false,
false
]
},
"hash": "e61c0dddb3e86d271cb9399faa4e4443342796cb72bdd43a821fae2994ae8e2f"
}

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "\n UPDATE http_responses SET (\n elapsed, elapsed_headers, url, status, status_reason, content_length, body_path,\n error, headers, version, remote_addr, updated_at\n ) = (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP) WHERE id = ?;\n ",
"describe": {
"columns": [],
"parameters": {
"Right": 12
},
"nullable": []
},
"hash": "e7124f5570076bfd65985744f48d8e12cf29d6d243fffdd62ade2ab70c7bddda"
}

View File

@@ -0,0 +1,56 @@
{
"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 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": "f5f20f3b37d932617499a0da50997edad59e4f5998b15c50ed6eae2e97064068"
}

View File

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

6492
src-tauri/Cargo.lock generated
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,34 +1,58 @@
workspace = { members = ["grpc", "templates", "tauri-plugin-plugin-runtime"] }
[package]
name = "tauri-app"
name = "yaak-app"
version = "0.0.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
# Produce a library for mobile support
[lib]
name = "tauri_app_lib"
crate-type = ["staticlib", "cdylib", "lib"]
[profile.release]
strip = true # Automatically strip symbols from the binary.
[build-dependencies]
tauri-build = { version = "1.2", features = [] }
tauri-build = { version = "2.0.0-beta", features = [] }
[target.'cfg(target_os = "macos")'.dependencies]
objc = "0.2.7"
cocoa = "0.25.0"
[target.'cfg(target_os = "linux")'.dependencies]
openssl-sys = { version = "0.9", features = ["vendored"] } # For Ubuntu installation to work
[dependencies]
serde_json = { version = "1.0" }
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.2", features = ["config-toml", "devtools", "shell-open", "system-tray", "window-start-dragging"] }
http = { version = "0.2.8" }
reqwest = { version = "0.11.14", features = ["json"] }
tokio = { version = "1.25.0", features = ["full"] }
futures = { version = "0.3.26" }
deno_core = { version = "0.171.0" }
deno_ast = { version = "0.24.0", features = ["transpiling"] }
objc = { version = "0.2.7" }
cocoa = { version = "0.24.1" }
[features]
# by default Tauri runs in production mode
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
default = ["custom-protocol"]
# this feature is used used for production builds where `devPath` points to the filesystem
# DO NOT remove this
custom-protocol = ["tauri/custom-protocol"]
grpc = { path = "./grpc" }
templates = { path = "./templates" }
plugin_runtime = { path = "tauri-plugin-plugin-runtime" }
anyhow = "1.0.86"
base64 = "0.22.0"
chrono = { version = "0.4.31", features = ["serde"] }
datetime = "0.5.2"
hex_color = "3.0.0"
http = "1"
log = "0.4.21"
rand = "0.8.5"
regex = "1.10.2"
reqwest = { version = "0.12.4", features = ["multipart", "cookies", "gzip", "brotli", "deflate", "json", "native-tls-alpn"] }
reqwest_cookie_store = "0.8.0"
serde = { version = "1.0.198", features = ["derive"] }
serde_json = { version = "1.0.116", features = ["raw_value"] }
serde_yaml = "0.9.34"
sqlx = { version = "0.7.4", features = ["sqlite", "runtime-tokio-rustls", "json", "chrono", "time"] }
tauri = { version = "2.0.0-beta", features = ["devtools", "protocol-asset"] }
tauri-plugin-clipboard-manager = "2.1.0-beta"
tauri-plugin-dialog = "2.0.0-beta"
tauri-plugin-fs = "2.0.0-beta"
tauri-plugin-log = { version = "2.0.0-beta", features = ["colored"] }
tauri-plugin-os = "2.0.0-beta"
tauri-plugin-shell = "2.0.0-beta"
tauri-plugin-updater = "2.0.0-beta"
tauri-plugin-window-state = "2.0.0-beta"
tokio = { version = "1.36.0", features = ["sync"] }
tokio-stream = "0.1.15"
uuid = "1.7.0"
thiserror = "1.0.61"
mime_guess = "2.0.5"

View File

@@ -1,3 +1,3 @@
fn main() {
tauri_build::build()
tauri_build::build()
}

View File

@@ -0,0 +1,46 @@
{
"$schema": "../gen/schemas/capabilities.json",
"identifier": "main",
"description": "Main permissions",
"local": true,
"windows": [
"*"
],
"permissions": [
"os:allow-os-type",
"event:allow-emit",
"clipboard-manager:allow-write-text",
"clipboard-manager:allow-read-text",
"dialog:allow-open",
"dialog:allow-save",
"event:allow-listen",
"event:allow-unlisten",
"fs:allow-read-file",
"fs:allow-read-text-file",
{
"identifier": "fs:scope",
"allow": [
{
"path": "$APPDATA"
},
{
"path": "$APPDATA/**"
}
]
},
"shell:allow-open",
"webview:allow-set-webview-zoom",
"window:allow-close",
"window:allow-is-fullscreen",
"window:allow-maximize",
"window:allow-minimize",
"window:allow-toggle-maximize",
"window:allow-set-decorations",
"window:allow-set-title",
"window:allow-start-dragging",
"window:allow-unmaximize",
"window:allow-theme",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text"
]
}

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"main":{"identifier":"main","description":"Main permissions","local":true,"windows":["*"],"permissions":["os:allow-os-type","event:allow-emit","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-save","event:allow-listen","event:allow-unlisten","fs:allow-read-file","fs:allow-read-text-file",{"identifier":"fs:scope","allow":[{"path":"$APPDATA"},{"path":"$APPDATA/**"}]},"shell:allow-open","webview:allow-set-webview-zoom","window:allow-close","window:allow-is-fullscreen","window:allow-maximize","window:allow-minimize","window:allow-toggle-maximize","window:allow-set-decorations","window:allow-set-title","window:allow-start-dragging","window:allow-unmaximize","window:allow-theme","clipboard-manager:allow-read-text","clipboard-manager:allow-write-text"]}}

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

24
src-tauri/grpc/Cargo.toml Normal file
View File

@@ -0,0 +1,24 @@
[package]
name = "grpc"
version = "0.1.0"
edition = "2021"
[dependencies]
tonic = "0.10.2"
prost = "0.12"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "fs"] }
tonic-reflection = "0.10.2"
tokio-stream = "0.1.14"
prost-types = "0.12.3"
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
prost-reflect = { version = "0.12.0", features = ["serde", "derive"] }
log = "0.4.20"
anyhow = "1.0.79"
hyper = { version = "0.14" }
hyper-rustls = { version = "0.24.0", features = ["http2"] }
uuid = { version = "1.7.0", features = ["v4"] }
tauri = { version = "2.0.0-beta" }
tauri-plugin-shell = "2.0.0-beta"
md5 = "0.7.0"
dunce = "1.0.4"

View File

@@ -0,0 +1,52 @@
use prost_reflect::prost::Message;
use prost_reflect::{DynamicMessage, MethodDescriptor};
use tonic::codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder};
use tonic::Status;
#[derive(Clone)]
pub struct DynamicCodec(MethodDescriptor);
impl DynamicCodec {
#[allow(dead_code)]
pub fn new(md: MethodDescriptor) -> Self {
Self(md)
}
}
impl Codec for DynamicCodec {
type Encode = DynamicMessage;
type Decode = DynamicMessage;
type Encoder = Self;
type Decoder = Self;
fn encoder(&mut self) -> Self::Encoder {
self.clone()
}
fn decoder(&mut self) -> Self::Decoder {
self.clone()
}
}
impl Encoder for DynamicCodec {
type Item = DynamicMessage;
type Error = Status;
fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error> {
item.encode(dst)
.expect("buffer is too small to decode this message");
Ok(())
}
}
impl Decoder for DynamicCodec {
type Item = DynamicMessage;
type Error = Status;
fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error> {
let mut msg = DynamicMessage::new(self.0.output());
msg.merge(src)
.map_err(|err| Status::internal(err.to_string()))?;
Ok(Some(msg))
}
}

View File

@@ -0,0 +1,179 @@
use prost_reflect::{DescriptorPool, MessageDescriptor};
use prost_types::field_descriptor_proto;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Default, Serialize, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct JsonSchemaEntry {
#[serde(skip_serializing_if = "Option::is_none")]
title: Option<String>,
#[serde(rename = "type")]
type_: JsonType,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
properties: Option<HashMap<String, JsonSchemaEntry>>,
#[serde(rename = "enum", skip_serializing_if = "Option::is_none")]
enum_: Option<Vec<String>>,
/// Don't allow any other properties in the object
additional_properties: bool,
/// Set all properties to required
#[serde(skip_serializing_if = "Option::is_none")]
required: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
items: Option<Box<JsonSchemaEntry>>,
}
enum JsonType {
String,
Number,
Object,
Array,
Boolean,
Null,
_UNKNOWN,
}
impl Default for JsonType {
fn default() -> Self {
JsonType::_UNKNOWN
}
}
impl serde::Serialize for JsonType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
JsonType::String => serializer.serialize_str("string"),
JsonType::Number => serializer.serialize_str("number"),
JsonType::Object => serializer.serialize_str("object"),
JsonType::Array => serializer.serialize_str("array"),
JsonType::Boolean => serializer.serialize_str("boolean"),
JsonType::Null => serializer.serialize_str("null"),
JsonType::_UNKNOWN => serializer.serialize_str("unknown"),
}
}
}
impl<'de> serde::Deserialize<'de> for JsonType {
fn deserialize<D>(deserializer: D) -> Result<JsonType, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
match s.as_str() {
"string" => Ok(JsonType::String),
"number" => Ok(JsonType::Number),
"object" => Ok(JsonType::Object),
"array" => Ok(JsonType::Array),
"boolean" => Ok(JsonType::Boolean),
"null" => Ok(JsonType::Null),
_ => Ok(JsonType::_UNKNOWN),
}
}
}
pub fn message_to_json_schema(
pool: &DescriptorPool,
message: MessageDescriptor,
) -> JsonSchemaEntry {
let mut schema = JsonSchemaEntry {
title: Some(message.name().to_string()),
type_: JsonType::Object, // Messages are objects
..Default::default()
};
let mut properties = HashMap::new();
message.fields().for_each(|f| match f.kind() {
prost_reflect::Kind::Message(m) => {
properties.insert(f.name().to_string(), message_to_json_schema(pool, m));
}
prost_reflect::Kind::Enum(e) => {
properties.insert(
f.name().to_string(),
JsonSchemaEntry {
type_: map_proto_type_to_json_type(f.field_descriptor_proto().r#type()),
enum_: Some(e.values().map(|v| v.name().to_string()).collect::<Vec<_>>()),
..Default::default()
},
);
}
_ => {
// TODO: Handle repeated label
match f.field_descriptor_proto().label() {
field_descriptor_proto::Label::Repeated => {
// TODO: Handle more complex repeated types. This just handles primitives for now
properties.insert(
f.name().to_string(),
JsonSchemaEntry {
type_: JsonType::Array,
items: Some(Box::new(JsonSchemaEntry {
type_: map_proto_type_to_json_type(
f.field_descriptor_proto().r#type(),
),
..Default::default()
})),
..Default::default()
},
);
}
_ => {
// Regular JSON field
properties.insert(
f.name().to_string(),
JsonSchemaEntry {
type_: map_proto_type_to_json_type(f.field_descriptor_proto().r#type()),
..Default::default()
},
);
}
};
}
});
schema.properties = Some(properties);
// All proto 3 fields are optional, so maybe we could
// make this a setting?
// schema.required = Some(
// message
// .fields()
// .map(|f| f.name().to_string())
// .collect::<Vec<_>>(),
// );
schema
}
fn map_proto_type_to_json_type(proto_type: field_descriptor_proto::Type) -> JsonType {
match proto_type {
field_descriptor_proto::Type::Double => JsonType::Number,
field_descriptor_proto::Type::Float => JsonType::Number,
field_descriptor_proto::Type::Int64 => JsonType::Number,
field_descriptor_proto::Type::Uint64 => JsonType::Number,
field_descriptor_proto::Type::Int32 => JsonType::Number,
field_descriptor_proto::Type::Fixed64 => JsonType::Number,
field_descriptor_proto::Type::Fixed32 => JsonType::Number,
field_descriptor_proto::Type::Bool => JsonType::Boolean,
field_descriptor_proto::Type::String => JsonType::String,
field_descriptor_proto::Type::Group => JsonType::_UNKNOWN,
field_descriptor_proto::Type::Message => JsonType::Object,
field_descriptor_proto::Type::Bytes => JsonType::String,
field_descriptor_proto::Type::Uint32 => JsonType::Number,
field_descriptor_proto::Type::Enum => JsonType::String,
field_descriptor_proto::Type::Sfixed32 => JsonType::Number,
field_descriptor_proto::Type::Sfixed64 => JsonType::Number,
field_descriptor_proto::Type::Sint32 => JsonType::Number,
field_descriptor_proto::Type::Sint64 => JsonType::Number,
}
}

52
src-tauri/grpc/src/lib.rs Normal file
View File

@@ -0,0 +1,52 @@
use prost_reflect::{DynamicMessage, MethodDescriptor, SerializeOptions};
use serde::{Deserialize, Serialize};
use serde_json::Deserializer;
mod codec;
mod json_schema;
pub mod manager;
mod proto;
pub use tonic::metadata::*;
pub use tonic::Code;
pub fn serialize_options() -> SerializeOptions {
SerializeOptions::new().skip_default_fields(false)
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct ServiceDefinition {
pub name: String,
pub methods: Vec<MethodDefinition>,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(default, rename_all = "camelCase")]
pub struct MethodDefinition {
pub name: String,
pub schema: String,
pub client_streaming: bool,
pub server_streaming: bool,
}
static SERIALIZE_OPTIONS: &'static SerializeOptions = &SerializeOptions::new()
.skip_default_fields(false)
.stringify_64_bit_integers(false);
pub fn serialize_message(msg: &DynamicMessage) -> Result<String, String> {
let mut buf = Vec::new();
let mut se = serde_json::Serializer::pretty(&mut buf);
msg.serialize_with_options(&mut se, SERIALIZE_OPTIONS)
.map_err(|e| e.to_string())?;
let s = String::from_utf8(buf).expect("serde_json to emit valid utf8");
Ok(s)
}
pub fn deserialize_message(msg: &str, method: MethodDescriptor) -> Result<DynamicMessage, String> {
let mut deserializer = Deserializer::from_str(&msg);
let req_message = DynamicMessage::deserialize(method.input(), &mut deserializer)
.map_err(|e| e.to_string())?;
deserializer.end().map_err(|e| e.to_string())?;
Ok(req_message)
}

View File

@@ -0,0 +1,304 @@
use std::collections::HashMap;
use std::path::PathBuf;
use std::str::FromStr;
use hyper::client::HttpConnector;
use hyper::Client;
use hyper_rustls::HttpsConnector;
pub use prost_reflect::DynamicMessage;
use prost_reflect::{DescriptorPool, MethodDescriptor, ServiceDescriptor};
use serde_json::Deserializer;
use tauri::AppHandle;
use tokio_stream::wrappers::ReceiverStream;
use tonic::body::BoxBody;
use tonic::metadata::{MetadataKey, MetadataValue};
use tonic::transport::Uri;
use tonic::{IntoRequest, IntoStreamingRequest, Request, Response, Status, Streaming};
use crate::codec::DynamicCodec;
use crate::proto::{
fill_pool_from_files, fill_pool_from_reflection, get_transport, method_desc_to_path,
};
use crate::{json_schema, MethodDefinition, ServiceDefinition};
#[derive(Clone)]
pub struct GrpcConnection {
pool: DescriptorPool,
conn: Client<HttpsConnector<HttpConnector>, BoxBody>,
pub uri: Uri,
}
#[derive(Default)]
pub struct StreamError {
pub message: String,
pub status: Option<Status>,
}
impl From<String> for StreamError {
fn from(value: String) -> Self {
StreamError {
message: value.to_string(),
status: None,
}
}
}
impl From<Status> for StreamError {
fn from(s: Status) -> Self {
StreamError {
message: s.message().to_string(),
status: Some(s),
}
}
}
impl GrpcConnection {
pub fn service(&self, service: &str) -> Result<ServiceDescriptor, String> {
let service = self
.pool
.get_service_by_name(service)
.ok_or("Failed to find service")?;
Ok(service)
}
pub fn method(&self, service: &str, method: &str) -> Result<MethodDescriptor, String> {
let service = self.service(service)?;
let method = service
.methods()
.find(|m| m.name() == method)
.ok_or("Failed to find method")?;
Ok(method)
}
pub async fn unary(
&self,
service: &str,
method: &str,
message: &str,
metadata: HashMap<String, String>,
) -> Result<Response<DynamicMessage>, StreamError> {
let method = &self.method(&service, &method)?;
let input_message = method.input();
let mut deserializer = Deserializer::from_str(message);
let req_message = DynamicMessage::deserialize(input_message, &mut deserializer)
.map_err(|e| e.to_string())?;
deserializer.end().unwrap();
let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone());
let mut req = req_message.into_request();
decorate_req(metadata, &mut req).map_err(|e| e.to_string())?;
let path = method_desc_to_path(method);
let codec = DynamicCodec::new(method.clone());
client.ready().await.unwrap();
Ok(client.unary(req, path, codec).await?)
}
pub async fn streaming(
&self,
service: &str,
method: &str,
stream: ReceiverStream<DynamicMessage>,
metadata: HashMap<String, String>,
) -> Result<Response<Streaming<DynamicMessage>>, StreamError> {
let method = &self.method(&service, &method)?;
let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone());
let mut req = stream.into_streaming_request();
decorate_req(metadata, &mut req).map_err(|e| e.to_string())?;
let path = method_desc_to_path(method);
let codec = DynamicCodec::new(method.clone());
client.ready().await.map_err(|e| e.to_string())?;
Ok(client.streaming(req, path, codec).await?)
}
pub async fn client_streaming(
&self,
service: &str,
method: &str,
stream: ReceiverStream<DynamicMessage>,
metadata: HashMap<String, String>,
) -> Result<Response<DynamicMessage>, StreamError> {
let method = &self.method(&service, &method)?;
let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone());
let mut req = stream.into_streaming_request();
decorate_req(metadata, &mut req).map_err(|e| e.to_string())?;
let path = method_desc_to_path(method);
let codec = DynamicCodec::new(method.clone());
client.ready().await.unwrap();
client
.client_streaming(req, path, codec)
.await
.map_err(|e| StreamError {
message: e.message().to_string(),
status: Some(e),
})
}
pub async fn server_streaming(
&self,
service: &str,
method: &str,
message: &str,
metadata: HashMap<String, String>,
) -> Result<Response<Streaming<DynamicMessage>>, StreamError> {
let method = &self.method(&service, &method)?;
let input_message = method.input();
let mut deserializer = Deserializer::from_str(message);
let req_message = DynamicMessage::deserialize(input_message, &mut deserializer)
.map_err(|e| e.to_string())?;
deserializer.end().unwrap();
let mut client = tonic::client::Grpc::with_origin(self.conn.clone(), self.uri.clone());
let mut req = req_message.into_request();
decorate_req(metadata, &mut req).map_err(|e| e.to_string())?;
let path = method_desc_to_path(method);
let codec = DynamicCodec::new(method.clone());
client.ready().await.map_err(|e| e.to_string())?;
Ok(client.server_streaming(req, path, codec).await?)
}
}
pub struct GrpcHandle {
app_handle: AppHandle,
pools: HashMap<String, DescriptorPool>,
}
impl GrpcHandle {
pub fn new(app_handle: &AppHandle) -> Self {
let pools = HashMap::new();
Self {
pools,
app_handle: app_handle.clone(),
}
}
}
impl GrpcHandle {
pub async fn reflect(
&mut self,
id: &str,
uri: &str,
proto_files: &Vec<PathBuf>,
) -> Result<(), String> {
let pool = if proto_files.is_empty() {
let full_uri = uri_from_str(uri)?;
fill_pool_from_reflection(&full_uri).await
} else {
fill_pool_from_files(&self.app_handle, proto_files).await
}?;
self.pools
.insert(make_pool_key(id, uri, proto_files), pool.clone());
Ok(())
}
pub async fn services(
&mut self,
id: &str,
uri: &str,
proto_files: &Vec<PathBuf>,
) -> Result<Vec<ServiceDefinition>, String> {
// Ensure reflection is up-to-date
self.reflect(id, uri, proto_files).await?;
let pool = self
.get_pool(id, uri, proto_files)
.ok_or("Failed to get pool".to_string())?;
Ok(self.services_from_pool(&pool))
}
fn services_from_pool(&self, pool: &DescriptorPool) -> Vec<ServiceDefinition> {
pool.services()
.map(|s| {
let mut def = ServiceDefinition {
name: s.full_name().to_string(),
methods: vec![],
};
for method in s.methods() {
let input_message = method.input();
def.methods.push(MethodDefinition {
name: method.name().to_string(),
server_streaming: method.is_server_streaming(),
client_streaming: method.is_client_streaming(),
schema: serde_json::to_string_pretty(&json_schema::message_to_json_schema(
&pool,
input_message,
))
.unwrap(),
})
}
def
})
.collect::<Vec<_>>()
}
pub async fn connect(
&mut self,
id: &str,
uri: &str,
proto_files: &Vec<PathBuf>,
) -> Result<GrpcConnection, String> {
self.reflect(id, uri, proto_files).await?;
let pool = self
.get_pool(id, uri, proto_files)
.ok_or("Failed to get pool")?;
let uri = uri_from_str(uri)?;
let conn = get_transport();
let connection = GrpcConnection {
pool: pool.clone(),
conn,
uri,
};
Ok(connection)
}
fn get_pool(&self, id: &str, uri: &str, proto_files: &Vec<PathBuf>) -> Option<&DescriptorPool> {
self.pools.get(make_pool_key(id, uri, proto_files).as_str())
}
}
fn decorate_req<T>(metadata: HashMap<String, String>, req: &mut Request<T>) -> Result<(), String> {
for (k, v) in metadata {
req.metadata_mut().insert(
MetadataKey::from_str(k.as_str()).map_err(|e| e.to_string())?,
MetadataValue::from_str(v.as_str()).map_err(|e| e.to_string())?,
);
}
Ok(())
}
fn uri_from_str(uri_str: &str) -> Result<Uri, String> {
match Uri::from_str(uri_str) {
Ok(uri) => Ok(uri),
Err(err) => {
// Uri::from_str basically only returns "invalid format" so we add more context here
Err(format!("Failed to parse URL, {}", err.to_string()))
}
}
}
fn make_pool_key(id: &str, uri: &str, proto_files: &Vec<PathBuf>) -> String {
let pool_key = format!(
"{}::{}::{}",
id,
uri,
proto_files
.iter()
.map(|p| p.to_string_lossy().to_string())
.collect::<Vec<String>>()
.join(":")
);
format!("{:x}", md5::compute(pool_key))
}

252
src-tauri/grpc/src/proto.rs Normal file
View File

@@ -0,0 +1,252 @@
use std::env::temp_dir;
use std::ops::Deref;
use std::path::PathBuf;
use std::str::FromStr;
use anyhow::anyhow;
use hyper::client::HttpConnector;
use hyper::Client;
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
use log::{debug, warn};
use prost::Message;
use prost_reflect::{DescriptorPool, MethodDescriptor};
use prost_types::{FileDescriptorProto, FileDescriptorSet};
use tauri::path::BaseDirectory;
use tauri::{AppHandle, Manager};
use tauri_plugin_shell::ShellExt;
use tokio::fs;
use tokio_stream::StreamExt;
use tonic::body::BoxBody;
use tonic::codegen::http::uri::PathAndQuery;
use tonic::transport::Uri;
use tonic::Request;
use tonic_reflection::pb::server_reflection_client::ServerReflectionClient;
use tonic_reflection::pb::server_reflection_request::MessageRequest;
use tonic_reflection::pb::server_reflection_response::MessageResponse;
use tonic_reflection::pb::ServerReflectionRequest;
pub async fn fill_pool_from_files(
app_handle: &AppHandle,
paths: &Vec<PathBuf>,
) -> Result<DescriptorPool, String> {
let mut pool = DescriptorPool::new();
let random_file_name = format!("{}.desc", uuid::Uuid::new_v4());
let desc_path = temp_dir().join(random_file_name);
let global_import_dir = app_handle
.path()
.resolve("protoc-include", BaseDirectory::Resource)
.expect("failed to resolve protoc include directory");
// HACK: Remove UNC prefix for Windows paths
let global_import_dir = dunce::simplified(global_import_dir.as_path())
.to_string_lossy()
.to_string();
let desc_path = dunce::simplified(desc_path.as_path());
let mut args = vec![
"--include_imports".to_string(),
"--include_source_info".to_string(),
"-I".to_string(),
global_import_dir,
"-o".to_string(),
desc_path.to_string_lossy().to_string(),
];
for p in paths {
if p.as_path().exists() {
args.push(p.to_string_lossy().to_string());
} else {
continue;
}
let parent = p.as_path().parent();
if let Some(parent_path) = parent {
args.push("-I".to_string());
args.push(parent_path.to_string_lossy().to_string());
args.push("-I".to_string());
args.push(parent_path.parent().unwrap().to_string_lossy().to_string());
} else {
debug!("ignoring {:?} since it does not exist.", parent)
}
}
let out = app_handle
.shell()
.sidecar("yaakprotoc")
.expect("yaakprotoc not found")
.args(args)
.output()
.await
.expect("yaakprotoc failed to run");
if !out.status.success() {
return Err(format!(
"protoc failed with status {}: {}",
out.status.code().unwrap(),
String::from_utf8_lossy(out.stderr.as_slice())
));
}
let bytes = fs::read(desc_path).await.map_err(|e| e.to_string())?;
let fdp = FileDescriptorSet::decode(bytes.deref()).map_err(|e| e.to_string())?;
pool.add_file_descriptor_set(fdp)
.map_err(|e| e.to_string())?;
fs::remove_file(desc_path)
.await
.map_err(|e| e.to_string())?;
Ok(pool)
}
pub async fn fill_pool_from_reflection(uri: &Uri) -> Result<DescriptorPool, String> {
let mut pool = DescriptorPool::new();
let mut client = ServerReflectionClient::with_origin(get_transport(), uri.clone());
for service in list_services(&mut client).await? {
if service == "grpc.reflection.v1alpha.ServerReflection" {
continue;
}
file_descriptor_set_from_service_name(&service, &mut pool, &mut client).await;
}
Ok(pool)
}
pub fn get_transport() -> Client<HttpsConnector<HttpConnector>, BoxBody> {
let connector = HttpsConnectorBuilder::new().with_native_roots();
let connector = connector.https_or_http().enable_http2().wrap_connector({
let mut http_connector = HttpConnector::new();
http_connector.enforce_http(false);
http_connector
});
Client::builder()
.pool_max_idle_per_host(0)
.http2_only(true)
.build(connector)
}
async fn list_services(
reflect_client: &mut ServerReflectionClient<Client<HttpsConnector<HttpConnector>, BoxBody>>,
) -> Result<Vec<String>, String> {
let response =
send_reflection_request(reflect_client, MessageRequest::ListServices("".into())).await?;
let list_services_response = match response {
MessageResponse::ListServicesResponse(resp) => resp,
_ => panic!("Expected a ListServicesResponse variant"),
};
Ok(list_services_response
.service
.iter()
.map(|s| s.name.clone())
.collect::<Vec<_>>())
}
async fn file_descriptor_set_from_service_name(
service_name: &str,
pool: &mut DescriptorPool,
client: &mut ServerReflectionClient<Client<HttpsConnector<HttpConnector>, BoxBody>>,
) {
let response = match send_reflection_request(
client,
MessageRequest::FileContainingSymbol(service_name.into()),
)
.await
{
Ok(resp) => resp,
Err(e) => {
warn!(
"Error fetching file descriptor for service {}: {}",
service_name, e
);
return;
}
};
let file_descriptor_response = match response {
MessageResponse::FileDescriptorResponse(resp) => resp,
_ => panic!("Expected a FileDescriptorResponse variant"),
};
for fd in file_descriptor_response.file_descriptor_proto {
let fdp = FileDescriptorProto::decode(fd.deref()).unwrap();
// Add deps first or else we'll get an error
for dep_name in fdp.clone().dependency {
file_descriptor_set_by_filename(&dep_name, pool, client).await;
}
pool.add_file_descriptor_proto(fdp)
.expect("add file descriptor proto");
}
}
async fn file_descriptor_set_by_filename(
filename: &str,
pool: &mut DescriptorPool,
client: &mut ServerReflectionClient<Client<HttpsConnector<HttpConnector>, BoxBody>>,
) {
// We already fetched this file
if let Some(_) = pool.get_file_by_name(filename) {
return;
}
let response =
send_reflection_request(client, MessageRequest::FileByFilename(filename.into())).await;
let file_descriptor_response = match response {
Ok(MessageResponse::FileDescriptorResponse(resp)) => resp,
Ok(_) => {
panic!("Expected a FileDescriptorResponse variant")
}
Err(e) => {
warn!("Error fetching file descriptor for {}: {}", filename, e);
return;
}
};
for fd in file_descriptor_response.file_descriptor_proto {
let fdp = FileDescriptorProto::decode(fd.deref()).unwrap();
pool.add_file_descriptor_proto(fdp)
.expect("add file descriptor proto");
}
}
async fn send_reflection_request(
client: &mut ServerReflectionClient<Client<HttpsConnector<HttpConnector>, BoxBody>>,
message: MessageRequest,
) -> Result<MessageResponse, String> {
let reflection_request = ServerReflectionRequest {
host: "".into(), // Doesn't matter
message_request: Some(message),
};
let request = Request::new(tokio_stream::once(reflection_request));
client
.server_reflection_info(request)
.await
.map_err(|e| match e.code() {
tonic::Code::Unavailable => "Failed to connect to endpoint".to_string(),
tonic::Code::Unauthenticated => "Authentication failed".to_string(),
tonic::Code::DeadlineExceeded => "Deadline exceeded".to_string(),
_ => e.to_string(),
})?
.into_inner()
.next()
.await
.expect("steamed response")
.map_err(|e| e.to_string())?
.message_response
.ok_or("No reflection response".to_string())
}
pub fn method_desc_to_path(md: &MethodDescriptor) -> PathAndQuery {
let full_name = md.full_name();
let (namespace, method_name) = full_name
.rsplit_once('.')
.ok_or_else(|| anyhow!("invalid method path"))
.expect("invalid method path");
PathAndQuery::from_str(&format!("/{}/{}", namespace, method_name)).expect("invalid method path")
}

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