mirror of
https://github.com/mountain-loop/yaak.git
synced 2025-12-30 18:08:49 -05:00
Compare commits
985 Commits
feat/mcp-s
...
v2024.7.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d586ec5fb4 | ||
|
|
ad8a4933da | ||
|
|
499d0b09ba | ||
|
|
ac1181c1b4 | ||
|
|
b9671781d3 | ||
|
|
42fd7cb21e | ||
|
|
fe9f765c1d | ||
|
|
087a1e5ea1 | ||
|
|
6e156497da | ||
|
|
ad3c2ed113 | ||
|
|
166bae6104 | ||
|
|
b3e6a2b34f | ||
|
|
547f1c9139 | ||
|
|
4d7ded61f8 | ||
|
|
c92472dbac | ||
|
|
d347f2db77 | ||
|
|
80c1675331 | ||
|
|
23fba45fcb | ||
|
|
80777f712c | ||
|
|
6ffb0015c6 | ||
|
|
9d9b855c04 | ||
|
|
e7cbcc7b20 | ||
|
|
20a5ab3666 | ||
|
|
311fda887f | ||
|
|
55e33df8d6 | ||
|
|
71c9c8ba8c | ||
|
|
11c2b9bb2c | ||
|
|
5cfd208c23 | ||
|
|
3a0b647ce4 | ||
|
|
8367835061 | ||
|
|
55276b968e | ||
|
|
9e04226097 | ||
|
|
51487d5412 | ||
|
|
0dccba4ab2 | ||
|
|
13183ae837 | ||
|
|
f24fd13c45 | ||
|
|
972dffe959 | ||
|
|
9f7033ab06 | ||
|
|
cd07123157 | ||
|
|
b62901e295 | ||
|
|
96996f73d5 | ||
|
|
4782fd376b | ||
|
|
41dfa15feb | ||
|
|
47d4fffc20 | ||
|
|
994f314cff | ||
|
|
0f8f086e01 | ||
|
|
19280c3bbc | ||
|
|
3cd7c1ef2e | ||
|
|
6a5f61e84b | ||
|
|
a444984aed | ||
|
|
c0e253ef84 | ||
|
|
7910d1b0fc | ||
|
|
d26d20180e | ||
|
|
54d9a78474 | ||
|
|
216c41d8cf | ||
|
|
bf2c392380 | ||
|
|
1835fa3ba4 | ||
|
|
d701381041 | ||
|
|
89c19858df | ||
|
|
01136921df | ||
|
|
17ab201b96 | ||
|
|
5d3182da4c | ||
|
|
293a91012f | ||
|
|
a43f601b6a | ||
|
|
447932697d | ||
|
|
0c75c2289e | ||
|
|
c97c9b599d | ||
|
|
fc972b04f7 | ||
|
|
e8410f70a1 | ||
|
|
70c63fc63c | ||
|
|
c4e1353b51 | ||
|
|
fd6959e868 | ||
|
|
854c19c1a1 | ||
|
|
9370b4879b | ||
|
|
0b2da8e7ae | ||
|
|
2e0982b999 | ||
|
|
2ec3be4374 | ||
|
|
b1e6f52396 | ||
|
|
5ce928068c | ||
|
|
76b1e5b103 | ||
|
|
4a95128416 | ||
|
|
cae6eb2b24 | ||
|
|
cdcfb585cf | ||
|
|
d4d56dfe1b | ||
|
|
f6c491498b | ||
|
|
e01cdd1dad | ||
|
|
9e41d366c1 | ||
|
|
fee46de974 | ||
|
|
fa14b7aaf8 | ||
|
|
bb44bfca49 | ||
|
|
6fcb3948ce | ||
|
|
f716291328 | ||
|
|
9f8eabe22b | ||
|
|
6d9e14784f | ||
|
|
1d5f3260e2 | ||
|
|
883fcdb6b8 | ||
|
|
c9040a6e5f | ||
|
|
151450f55b | ||
|
|
5722880890 | ||
|
|
d361a40903 | ||
|
|
cd9e720835 | ||
|
|
50e2ab3a03 | ||
|
|
dc5dfeb022 | ||
|
|
0b8a18edae | ||
|
|
0bb3f14b4c | ||
|
|
c18d30b89f | ||
|
|
8f06a834c8 | ||
|
|
bd948f9cd6 | ||
|
|
d70254bcdc | ||
|
|
fac5385d5d | ||
|
|
e8bcc695bb | ||
|
|
88aeb0e530 | ||
|
|
92b1582232 | ||
|
|
196990c077 | ||
|
|
c42b8cf538 | ||
|
|
085274c960 | ||
|
|
7ef187abf6 | ||
|
|
12eac34d95 | ||
|
|
c29b3c6509 | ||
|
|
7faa423aba | ||
|
|
5b2162e48d | ||
|
|
ee776143b2 | ||
|
|
7a18fb29e4 | ||
|
|
4485cad9e8 | ||
|
|
33763b6d2f | ||
|
|
641fe86cf7 | ||
|
|
65e7c804d7 | ||
|
|
23ec8bee8f | ||
|
|
8aeeaa2e09 | ||
|
|
57f01d249e | ||
|
|
6c5a914db6 | ||
|
|
155e51aa74 | ||
|
|
012a984456 | ||
|
|
25800202f2 | ||
|
|
a058064f1f | ||
|
|
9f40804532 | ||
|
|
26cc467858 | ||
|
|
be1cf7bf65 | ||
|
|
ea4f104ca7 | ||
|
|
32a28a3170 | ||
|
|
6215914212 | ||
|
|
a2dbd7f849 | ||
|
|
5bb9815f4b | ||
|
|
7cd8ac3b21 | ||
|
|
456d3aaf52 | ||
|
|
113743f7cf | ||
|
|
01a4d6f4ac | ||
|
|
ff5cfe744e | ||
|
|
29c4b51f54 | ||
|
|
2f74bf8db8 | ||
|
|
b30d784d06 | ||
|
|
ac0adaf3d8 | ||
|
|
c246d3a748 | ||
|
|
ae40728c1e | ||
|
|
0430ec883b | ||
|
|
eba6f33536 | ||
|
|
dae2873376 | ||
|
|
cb2f56d9a1 | ||
|
|
7d82aa70a4 | ||
|
|
adea234987 | ||
|
|
37d0b487b8 | ||
|
|
d507f8c99f | ||
|
|
60406ac83f | ||
|
|
8fe6f3a335 | ||
|
|
69e027c302 | ||
|
|
4232bdd298 | ||
|
|
ef1c5da027 | ||
|
|
e250326868 | ||
|
|
125f503cfa | ||
|
|
8f086425fe | ||
|
|
ae2da73873 | ||
|
|
3cd6688ffb | ||
|
|
8538da8879 | ||
|
|
b0e4ece278 | ||
|
|
5e058af03e | ||
|
|
5108bc92f3 | ||
|
|
3c5fdcb18d | ||
|
|
4672de4a47 | ||
|
|
239f6da141 | ||
|
|
ec148d1736 | ||
|
|
392b549646 | ||
|
|
993d4dc65d | ||
|
|
e326405f4f | ||
|
|
a83e094f00 | ||
|
|
e683a2cb2a | ||
|
|
1f231c2722 | ||
|
|
0fc2575ef6 | ||
|
|
44c718e6bc | ||
|
|
495df847ab | ||
|
|
5dbb9852f3 | ||
|
|
82d3304c38 | ||
|
|
5e2218fd64 | ||
|
|
5b12fad173 | ||
|
|
8d6f23eacb | ||
|
|
75a09859bc | ||
|
|
dc47c4ceba | ||
|
|
8ae0290aed | ||
|
|
f01d1e704b | ||
|
|
3f72996e64 | ||
|
|
fe862517fb | ||
|
|
b39335dc4f | ||
|
|
8f3bdb5039 | ||
|
|
b47ec01f9c | ||
|
|
36728d1d1f | ||
|
|
c3f0351445 | ||
|
|
9a5364187c | ||
|
|
a9db14994f | ||
|
|
2383e8468f | ||
|
|
a79d485b6a | ||
|
|
7eb931d689 | ||
|
|
995cd2aa7b | ||
|
|
1ce50e0c1b | ||
|
|
bce3d26a1a | ||
|
|
d9680ad0fa | ||
|
|
e2e026e1ff | ||
|
|
16739d9a37 | ||
|
|
524a4f2275 | ||
|
|
ba66883dc2 | ||
|
|
2caa735a2e | ||
|
|
90637fda6b | ||
|
|
2cef46b46a | ||
|
|
14b3abf76c | ||
|
|
8cd3961f87 | ||
|
|
5eb2e2b5a2 | ||
|
|
5dd897e042 | ||
|
|
9c77ec296d | ||
|
|
696e72323b | ||
|
|
3e8c01f436 | ||
|
|
80fc4dec09 | ||
|
|
671885fc8c | ||
|
|
002b61f0d7 | ||
|
|
d32b462bd9 | ||
|
|
5c8b47288a | ||
|
|
8e662e6feb | ||
|
|
83aaeb94f6 | ||
|
|
8606940dee | ||
|
|
60e469a1c9 | ||
|
|
57d548743f | ||
|
|
dab7ee2492 | ||
|
|
9360fd7e43 | ||
|
|
7b4bc53c0f | ||
|
|
0f7969d10a | ||
|
|
6b373b5985 | ||
|
|
c0068a1561 | ||
|
|
fad5e03f8b | ||
|
|
a22fc68764 | ||
|
|
59a442e8c0 | ||
|
|
35e8155ecf | ||
|
|
8b9a5cb5fb | ||
|
|
29f9825f04 | ||
|
|
ad8a6beacf | ||
|
|
194ac78814 | ||
|
|
0542f1ebea | ||
|
|
8de917ea5e | ||
|
|
0b494bbfbf | ||
|
|
7e74f71c79 | ||
|
|
bd7fd676a5 | ||
|
|
cb1c6a4d8c | ||
|
|
b640f0c357 | ||
|
|
967590c7ff | ||
|
|
321d6ec9d7 | ||
|
|
79b4fd7829 | ||
|
|
52eb4d338f | ||
|
|
4b8b48e92f | ||
|
|
e3f45b58e5 | ||
|
|
a5f1922446 | ||
|
|
22e7b15a63 | ||
|
|
c6bb2a73f8 | ||
|
|
bde961f95d | ||
|
|
c4867b3f68 | ||
|
|
1c36e9a2f0 | ||
|
|
1c82d8a738 | ||
|
|
a2df591102 | ||
|
|
c950ee0fb8 | ||
|
|
0ce5a9fcce | ||
|
|
bd1970a805 | ||
|
|
3aaa4b1050 | ||
|
|
31d2426846 | ||
|
|
25c4e4edaf | ||
|
|
1a5bf53b02 | ||
|
|
e2d1b62044 | ||
|
|
6186104d11 | ||
|
|
f1e97eaea4 | ||
|
|
bb0e58bf8b | ||
|
|
dc802fa055 | ||
|
|
3c8e19367f | ||
|
|
a89887eab8 | ||
|
|
7d3f0ad549 | ||
|
|
5608db1334 | ||
|
|
10443b3c02 | ||
|
|
7d272f3cd6 | ||
|
|
d60a62ab24 | ||
|
|
2b0f73b7c5 | ||
|
|
0915ea8585 | ||
|
|
ed9a0b8ac7 | ||
|
|
7437f39ed3 | ||
|
|
27f80cd97b | ||
|
|
04cf688a9b | ||
|
|
178af308ce | ||
|
|
d40732a910 | ||
|
|
d8a579b7b3 | ||
|
|
bf8ef40708 | ||
|
|
41060d5d43 | ||
|
|
ab6cef064c | ||
|
|
829d10d7b9 | ||
|
|
57e1f641a7 | ||
|
|
7df965e74b | ||
|
|
0e1153fdfd | ||
|
|
9797bc1830 | ||
|
|
9d00eb98d2 | ||
|
|
88f6e882c6 | ||
|
|
230a773909 | ||
|
|
e6da1afa82 | ||
|
|
a70d9e57be | ||
|
|
8afe0c0755 | ||
|
|
e47c2513a8 | ||
|
|
276bcfceeb | ||
|
|
6fd1b35a50 | ||
|
|
bc33244549 | ||
|
|
33c982b288 | ||
|
|
98493a1167 | ||
|
|
a8c10f9601 | ||
|
|
1051f84bbf | ||
|
|
eea137e677 | ||
|
|
27cf4e925f | ||
|
|
6b239c4e3f | ||
|
|
4c7ee5ef80 | ||
|
|
3ddb79899e | ||
|
|
b14595a3e2 | ||
|
|
82c94369ae | ||
|
|
7e77d2e9a8 | ||
|
|
ce5ce76b21 | ||
|
|
27d6b30cf9 | ||
|
|
9285dd5d70 | ||
|
|
977234808e | ||
|
|
e1ccd327f5 | ||
|
|
a0e3e71a4b | ||
|
|
2d4037da37 | ||
|
|
d21608bb82 | ||
|
|
f16239de73 | ||
|
|
d00f34c240 | ||
|
|
fd77437f59 | ||
|
|
f9cd8d24a1 | ||
|
|
c0a9f79834 | ||
|
|
ca63c101a1 | ||
|
|
dbd0b46ef2 | ||
|
|
89793ebe2f | ||
|
|
e1ffc387ea | ||
|
|
1efd0852ef | ||
|
|
59d532ed4d | ||
|
|
f034cda7cd | ||
|
|
5c1cf1e57d | ||
|
|
780960f5de | ||
|
|
aada95e9da | ||
|
|
89b5003cce | ||
|
|
3559333461 | ||
|
|
fbb6cab567 | ||
|
|
30fca29c6d | ||
|
|
ec1e521b39 | ||
|
|
a8998cd696 | ||
|
|
df178baed6 | ||
|
|
e2f75371e6 | ||
|
|
9f25ab39c6 | ||
|
|
937df6a024 | ||
|
|
7deb7182a8 | ||
|
|
82b14c56be | ||
|
|
58b98734c9 | ||
|
|
c2f58f328c | ||
|
|
36eabe7528 | ||
|
|
8347093e8b | ||
|
|
75282cb43a | ||
|
|
3a253a758d | ||
|
|
f2955c26c1 | ||
|
|
e6c0317b37 | ||
|
|
0cfb218b07 | ||
|
|
8ef103fbde | ||
|
|
ec5cdfb025 | ||
|
|
7f4d082c17 | ||
|
|
e10011ef34 | ||
|
|
1eb6999c37 | ||
|
|
35596916bf | ||
|
|
d61b22dd87 | ||
|
|
5565a9db9a | ||
|
|
b803655306 | ||
|
|
20df2bf13a | ||
|
|
e8fab85ce5 | ||
|
|
ce730f3dbe | ||
|
|
2328973de5 | ||
|
|
37dea50c91 | ||
|
|
40dfc8b30a | ||
|
|
72971bb9ec | ||
|
|
f835599502 | ||
|
|
0caa4f8099 | ||
|
|
71d3c9acd1 | ||
|
|
239ffa174a | ||
|
|
eae79ab14b | ||
|
|
ef7912615a | ||
|
|
7f20b67380 | ||
|
|
504337c178 | ||
|
|
d6b4f06ac8 | ||
|
|
28cbf5474d | ||
|
|
d797b84d4e | ||
|
|
720745857d | ||
|
|
a74ea1aeda | ||
|
|
643f5e7f26 | ||
|
|
a208b934e4 | ||
|
|
5892774082 | ||
|
|
13bfc1c3bd | ||
|
|
00289734c7 | ||
|
|
09c7c2cb91 | ||
|
|
bbe62abd20 | ||
|
|
cae9a4fd36 | ||
|
|
e7ee4a8867 | ||
|
|
b020574c88 | ||
|
|
192e1da5b6 | ||
|
|
0640079e59 | ||
|
|
a9d99aa17f | ||
|
|
b4667e1f88 | ||
|
|
7bc26fd448 | ||
|
|
94a9a5d5d5 | ||
|
|
bcfa2c411f | ||
|
|
1e3d43dbae | ||
|
|
c6b5e4d5df | ||
|
|
1293870e11 | ||
|
|
8309c19167 | ||
|
|
63a381c55a | ||
|
|
d891f891b7 | ||
|
|
0b12a6b318 | ||
|
|
0144ab05a0 | ||
|
|
1f71d4372f | ||
|
|
5ed1ea07ef | ||
|
|
4d2b101278 | ||
|
|
1dfdadde98 | ||
|
|
d19729869e | ||
|
|
5f782ad109 | ||
|
|
27dbdc9b5a | ||
|
|
4892863dd7 | ||
|
|
dc077209cc | ||
|
|
d8d5344d21 | ||
|
|
d148a8384d | ||
|
|
6884e9428b | ||
|
|
25ebccfcd7 | ||
|
|
7adb0cbb50 | ||
|
|
50866abda4 | ||
|
|
c83d904cf0 | ||
|
|
160447f8f6 | ||
|
|
184b13cc2a | ||
|
|
8fa965e055 | ||
|
|
1dd0b69079 | ||
|
|
be8dd107e3 | ||
|
|
8f139f10ef | ||
|
|
8b0823984b | ||
|
|
d82d2229d4 | ||
|
|
4be1bc17f3 | ||
|
|
e6af0c6009 | ||
|
|
e5d10bd72b | ||
|
|
9426885bb8 | ||
|
|
89e5d4f235 | ||
|
|
eecb3fbc7f | ||
|
|
244f1319b4 | ||
|
|
6a2b76e760 | ||
|
|
bc0278fce9 | ||
|
|
959841fb22 | ||
|
|
fbc878dbe5 | ||
|
|
7d183c6580 | ||
|
|
0555420ad9 | ||
|
|
ae25561c7e | ||
|
|
92e2b2b8f9 | ||
|
|
2a4a830fb7 | ||
|
|
0ad4c7cd7e | ||
|
|
41413d52ad | ||
|
|
eabc1bd305 | ||
|
|
9c312e12c1 | ||
|
|
18ea9dda3d | ||
|
|
56d4212f68 | ||
|
|
d932c19513 | ||
|
|
b800f00b7e | ||
|
|
e43af5234f | ||
|
|
aa59d96e55 | ||
|
|
5be04ceea6 | ||
|
|
da3392ac53 | ||
|
|
a2c9c98b21 | ||
|
|
8298d6e031 | ||
|
|
d6331022ad | ||
|
|
5e75d8c9a7 | ||
|
|
51944a212a | ||
|
|
49ed756479 | ||
|
|
1d207d5fbd | ||
|
|
6b1d15415d | ||
|
|
df3bfaaab7 | ||
|
|
ad0b8a8e7d | ||
|
|
d5459229b9 | ||
|
|
adbf596f0b | ||
|
|
c740966394 | ||
|
|
7adab73af3 | ||
|
|
c964f255d8 | ||
|
|
a7ffed9716 | ||
|
|
488d66d248 | ||
|
|
93cb469cb8 | ||
|
|
03a2fc8ee5 | ||
|
|
2d72e5792e | ||
|
|
9bf9a87f12 | ||
|
|
e2fca399e0 | ||
|
|
e13fdddf98 | ||
|
|
890eea299d | ||
|
|
9beac00981 | ||
|
|
1a64d7d9e6 | ||
|
|
bd5ae12f2e | ||
|
|
dbaf1da3ce | ||
|
|
a03c5df440 | ||
|
|
0776f6a2be | ||
|
|
ac9d050d9e | ||
|
|
b885c358a3 | ||
|
|
84d447973e | ||
|
|
019ec4de20 | ||
|
|
26189067cd | ||
|
|
caf39071af | ||
|
|
08a1223482 | ||
|
|
24bd90745e | ||
|
|
7a72920e66 | ||
|
|
81a8276e2b | ||
|
|
8fb6f51555 | ||
|
|
b0026aff66 | ||
|
|
3ced7f7c18 | ||
|
|
33f6995193 | ||
|
|
8af526682a | ||
|
|
d0d4324957 | ||
|
|
2bcd0e0bbe | ||
|
|
1b99c7e10f | ||
|
|
2831bb61b8 | ||
|
|
320670de2a | ||
|
|
1f39a36f26 | ||
|
|
1f84ba716e | ||
|
|
d034965d9c | ||
|
|
5eb30489e5 | ||
|
|
05458a0753 | ||
|
|
7975ef0699 | ||
|
|
5f810a1b4c | ||
|
|
c4093e79cf | ||
|
|
956f8ed2ea | ||
|
|
7b32f76a1e | ||
|
|
0dd11bc051 | ||
|
|
aa38df28af | ||
|
|
32962a6336 | ||
|
|
b268b72a4a | ||
|
|
eb0c90311b | ||
|
|
1070bf8e8f | ||
|
|
9bdb01987c | ||
|
|
3130fb948a | ||
|
|
e46de9eebd | ||
|
|
4360355c8c | ||
|
|
3baaddba0b | ||
|
|
e77c1c2a46 | ||
|
|
38422d59fd | ||
|
|
c884cedfc2 | ||
|
|
91074a35d8 | ||
|
|
9a02b63a6b | ||
|
|
4470409a24 | ||
|
|
8a978420be | ||
|
|
dfc01d51ca | ||
|
|
758154fa14 | ||
|
|
ef23a85577 | ||
|
|
e4533088ed | ||
|
|
4ffce4a534 | ||
|
|
6b77a62934 | ||
|
|
f603867040 | ||
|
|
b6eb7418aa | ||
|
|
39c97681cf | ||
|
|
2d0f0d8f6b | ||
|
|
209a767c91 | ||
|
|
71f2a724cb | ||
|
|
4b89b95738 | ||
|
|
b535722acd | ||
|
|
a9806a06a2 | ||
|
|
948e19b82f | ||
|
|
cd841fa13a | ||
|
|
3ffcf91abd | ||
|
|
9fd84a3bfc | ||
|
|
627c451cd1 | ||
|
|
e6ee89464a | ||
|
|
136e9f2738 | ||
|
|
d97986e526 | ||
|
|
7661aa9819 | ||
|
|
b7596f3f78 | ||
|
|
4e2231674c | ||
|
|
d36d023a5c | ||
|
|
3d5a7ebe3d | ||
|
|
819384e952 | ||
|
|
2f34c5e821 | ||
|
|
0c89c154ee | ||
|
|
060dce7440 | ||
|
|
91707529bd | ||
|
|
22f182a8eb | ||
|
|
6ccc42dc3f | ||
|
|
655f5a8eed | ||
|
|
cd06a72d6f | ||
|
|
0a5d71ecc2 | ||
|
|
9c214b619c | ||
|
|
6fddb727be | ||
|
|
b5d3b9a803 | ||
|
|
a74c8a94db | ||
|
|
abc6d0ff1e | ||
|
|
afdbcd0a38 | ||
|
|
c31ae805a6 | ||
|
|
7c1afd7fe5 | ||
|
|
ad470a3fd2 | ||
|
|
7755d06bba | ||
|
|
5aed4b79be | ||
|
|
f0e3f29606 | ||
|
|
abbcc525bf | ||
|
|
ef8ade45b1 | ||
|
|
8919d598c2 | ||
|
|
e21e42f5fe | ||
|
|
658aed8a29 | ||
|
|
a666f7d216 | ||
|
|
62429df469 | ||
|
|
7aed699c3f | ||
|
|
a14db0ab74 | ||
|
|
7b67770dc7 | ||
|
|
7766d8439b | ||
|
|
fac0683a71 | ||
|
|
79e04967f5 | ||
|
|
47eb8947f5 | ||
|
|
959c55315c | ||
|
|
b392f0c00f | ||
|
|
c8e674d015 | ||
|
|
90fbb81e1d | ||
|
|
21e58ca644 | ||
|
|
cfb0aa55ea | ||
|
|
9e0c021481 | ||
|
|
4acca8dd06 | ||
|
|
88eea09428 | ||
|
|
90d2743267 | ||
|
|
89945532a0 | ||
|
|
671860e053 | ||
|
|
a87ca6af47 | ||
|
|
b59ea4991c | ||
|
|
b6fd59219f | ||
|
|
38ce7650c1 | ||
|
|
2b21e28096 | ||
|
|
3206651248 | ||
|
|
ba8aa0e218 | ||
|
|
975a001635 | ||
|
|
30e7f7ccfe | ||
|
|
cca8d97d63 | ||
|
|
455e6c3520 | ||
|
|
d05ee3ec16 | ||
|
|
b1b5d08e89 | ||
|
|
6202e59daa | ||
|
|
c4a8603b81 | ||
|
|
5d15d1565c | ||
|
|
045ff558f8 | ||
|
|
504ed583cc | ||
|
|
15087f2d5a | ||
|
|
eb1cd1c14b | ||
|
|
0918d86654 | ||
|
|
d0e2220df7 | ||
|
|
ccb04f0b45 | ||
|
|
54b6e1c7c3 | ||
|
|
7c8acdc956 | ||
|
|
3973ae15be | ||
|
|
86dadf4f5e | ||
|
|
dc4cb4be74 | ||
|
|
2a29c4b551 | ||
|
|
2f64f45aba | ||
|
|
2f998ddfb6 | ||
|
|
93369a779d | ||
|
|
74e28123a8 | ||
|
|
fef7db8710 | ||
|
|
cb5d7626ac | ||
|
|
e74f9f33c0 | ||
|
|
0d27c17e28 | ||
|
|
f0b6d32639 | ||
|
|
9ebd506056 | ||
|
|
a5a91d2444 | ||
|
|
4435a66ece | ||
|
|
874a1079c3 | ||
|
|
1dc239d243 | ||
|
|
73a04276c0 | ||
|
|
9955064484 | ||
|
|
7975b528ec | ||
|
|
7d9fbda975 | ||
|
|
fce06747e3 | ||
|
|
db0cca54a7 | ||
|
|
4424caecc5 | ||
|
|
b866dcd566 | ||
|
|
9e4e6435ab | ||
|
|
41b10ff442 | ||
|
|
79f3307104 | ||
|
|
026629cd6d | ||
|
|
cf570a8f88 | ||
|
|
4a64384468 | ||
|
|
a9065c3380 | ||
|
|
e5e5548562 | ||
|
|
44cf2f670f | ||
|
|
d04d91d6dd | ||
|
|
3eb25b1507 | ||
|
|
a95cae5610 | ||
|
|
9cc6e62f28 | ||
|
|
24117f7c8d | ||
|
|
7245e6e593 | ||
|
|
4a5b1f4da3 | ||
|
|
c1ac67cc31 | ||
|
|
4085361b7e | ||
|
|
8b4227dbff | ||
|
|
3f7ed9e177 | ||
|
|
f9f1ba9e24 | ||
|
|
29309500a6 | ||
|
|
6b07fe105f | ||
|
|
90b03a0b97 | ||
|
|
d54a468006 | ||
|
|
7e98b6d853 | ||
|
|
8069094201 | ||
|
|
b28dc01e6b | ||
|
|
6bc1f9f494 | ||
|
|
e85dd32005 | ||
|
|
efc4e3bf6c | ||
|
|
768a13ff4d | ||
|
|
a8d73f74f4 | ||
|
|
4dddfc0cc5 | ||
|
|
4163bebe3b | ||
|
|
ad13744d14 | ||
|
|
9f9b3a5b21 | ||
|
|
63e68baeb1 | ||
|
|
4382ca6582 | ||
|
|
99f2f4c211 | ||
|
|
6b23379e5a | ||
|
|
4deda36e8f | ||
|
|
0ce7831cfb | ||
|
|
4e9005e240 | ||
|
|
9147252e5b | ||
|
|
b6b549ca18 | ||
|
|
85c25fb71e | ||
|
|
50637ba9fd | ||
|
|
bfe55dd55a | ||
|
|
1a2bb3d12e | ||
|
|
452a0c3ed5 | ||
|
|
b594a4690f | ||
|
|
7d2ba43463 | ||
|
|
107db42c33 | ||
|
|
dbacb9fc8d | ||
|
|
1fa3499ca6 | ||
|
|
62f3198d27 | ||
|
|
529550934b | ||
|
|
ca3b22a881 | ||
|
|
0ecf2d9123 | ||
|
|
af9bb7138b | ||
|
|
6cbfa74f97 | ||
|
|
2845fb8d35 | ||
|
|
fbe2660a57 | ||
|
|
1519282ac6 | ||
|
|
5d8d8dca70 | ||
|
|
0254e2c31d | ||
|
|
368b494d62 | ||
|
|
00d2213d05 | ||
|
|
b04602bcb9 | ||
|
|
80bfbd503a | ||
|
|
bfa186aebb | ||
|
|
818595e961 | ||
|
|
b5e9852f8d | ||
|
|
ff3734d65a | ||
|
|
4aa771ba29 | ||
|
|
5848c381fa | ||
|
|
03b35beae4 | ||
|
|
49856bb6f7 | ||
|
|
0cb56f1a85 | ||
|
|
4a0d698776 | ||
|
|
a4ebdb5736 | ||
|
|
6a5ecc2880 | ||
|
|
7a5bd92442 | ||
|
|
63c1111608 | ||
|
|
5704fb560a | ||
|
|
33dc3b719d | ||
|
|
d3329b4628 | ||
|
|
42e2c9f96f | ||
|
|
3e8a10757f | ||
|
|
8028d82fd0 | ||
|
|
4ad9feba68 | ||
|
|
ef469be7a9 | ||
|
|
14cd73d75a | ||
|
|
fbe6039845 | ||
|
|
f3fbd070dd | ||
|
|
7c2611a5a7 | ||
|
|
ae949f4616 | ||
|
|
89da434c0e | ||
|
|
4a98d1d655 | ||
|
|
bb41f0e4fe | ||
|
|
d2e0717d91 | ||
|
|
7912204fcb | ||
|
|
83e41ad618 | ||
|
|
dd7e46c2cc | ||
|
|
fb7424714a | ||
|
|
47481b711e | ||
|
|
0f86c3a731 | ||
|
|
b91d1b8b3c | ||
|
|
cd5ae6691c | ||
|
|
0f58986b4c | ||
|
|
af9755c513 | ||
|
|
56ce25f953 | ||
|
|
ed70c15ee9 | ||
|
|
d88ae99425 | ||
|
|
cf7ef55b7d | ||
|
|
2f12424f8d | ||
|
|
96aacec4fc | ||
|
|
7e57bb98a8 | ||
|
|
298f5c5a99 | ||
|
|
bf44ea7864 | ||
|
|
9abdc45e93 | ||
|
|
0d82cc7574 | ||
|
|
402b2a551f | ||
|
|
700c589ae2 | ||
|
|
8929d736d9 | ||
|
|
8c65fce357 | ||
|
|
b81f1e9e6b | ||
|
|
44d083d773 | ||
|
|
2b308282d4 | ||
|
|
c7738743c5 | ||
|
|
abc60667c6 | ||
|
|
53162e8bca | ||
|
|
6b95574e3d | ||
|
|
c9d62ae961 | ||
|
|
a70019927d | ||
|
|
01cd7f951a | ||
|
|
50f92bcfab | ||
|
|
362d9f8e59 | ||
|
|
0b1cf53942 | ||
|
|
a4c769b33c | ||
|
|
74a1cb61c1 | ||
|
|
268545c728 | ||
|
|
184bbb01c5 | ||
|
|
66fa7ac419 | ||
|
|
a80f3d997e | ||
|
|
efa7c24c9f | ||
|
|
91de21c7ad | ||
|
|
1e9ba57ef0 | ||
|
|
464389b248 | ||
|
|
107eb72eda | ||
|
|
ee7bf838f4 | ||
|
|
f63bcd94d1 | ||
|
|
16d5cb6ade | ||
|
|
63decdef8b | ||
|
|
e54e88f46d | ||
|
|
b6f53d059e | ||
|
|
9e1771c5ec | ||
|
|
8306bc2198 | ||
|
|
3810fb7d51 | ||
|
|
5b4984113e | ||
|
|
baf9efe246 | ||
|
|
f4a3109a31 | ||
|
|
241f2f39ec | ||
|
|
d9b40dca83 | ||
|
|
cb3f053057 | ||
|
|
c4ab045e57 | ||
|
|
d9b38efd97 | ||
|
|
5981588c95 | ||
|
|
388bef59b8 | ||
|
|
3d8de61c1c | ||
|
|
91b818f98d | ||
|
|
3a7f0898f9 | ||
|
|
c2f6de875a | ||
|
|
0647001807 | ||
|
|
4181d87792 | ||
|
|
58cf0a2015 | ||
|
|
d80c3d305b | ||
|
|
4d64a2bc2f | ||
|
|
5c54beaaa9 | ||
|
|
eee98f32b2 | ||
|
|
0949de66bf | ||
|
|
5a6acb24d9 | ||
|
|
2e5cab62c7 | ||
|
|
903db5fffd | ||
|
|
e3faf32708 | ||
|
|
97926ddc03 | ||
|
|
e891804051 | ||
|
|
a2982f8b77 | ||
|
|
321941baab | ||
|
|
e2e25dc30b | ||
|
|
1170ca4789 | ||
|
|
d159f62138 | ||
|
|
25005eef1b | ||
|
|
b17824c88d | ||
|
|
00f4a008f8 | ||
|
|
3e2bc67b59 | ||
|
|
efe072c7c4 | ||
|
|
59f1d11e40 | ||
|
|
5f947ac983 | ||
|
|
aa66f957f2 | ||
|
|
cf5f69271f | ||
|
|
c6653af782 | ||
|
|
fa1f33a2ac | ||
|
|
9f479882ad | ||
|
|
41db316489 | ||
|
|
50f0f5885e | ||
|
|
a609f09d50 | ||
|
|
43f2aa3068 | ||
|
|
a094e13bd5 | ||
|
|
eb076afbe4 | ||
|
|
7b41488a38 | ||
|
|
ca12d48352 | ||
|
|
0331d3b2b0 | ||
|
|
4d4814583c | ||
|
|
da3e158516 | ||
|
|
7b9d6baff0 | ||
|
|
550f1b7c6f | ||
|
|
74e8ee1786 | ||
|
|
55d3ea01b6 | ||
|
|
4cfe51cbb2 | ||
|
|
1f5ac60523 | ||
|
|
26bf4f2abd | ||
|
|
54671fff79 | ||
|
|
378309d763 | ||
|
|
e7d4bba8b3 | ||
|
|
fe3de0bc98 | ||
|
|
f3e38d7b71 | ||
|
|
eafa3b2de9 | ||
|
|
d8cc075bd0 | ||
|
|
bdb877a936 | ||
|
|
5c96e83a22 | ||
|
|
43abb57f77 | ||
|
|
9c6d821978 | ||
|
|
7e9babf515 | ||
|
|
ee36baf432 | ||
|
|
0bf57dcab7 | ||
|
|
e647d23adc | ||
|
|
d1b5b9c371 | ||
|
|
92ec514442 | ||
|
|
107466dd58 | ||
|
|
4246260ce6 | ||
|
|
936787d327 | ||
|
|
f976397283 | ||
|
|
657c6ad9a9 | ||
|
|
ede07c3b0e | ||
|
|
9326e8dcce | ||
|
|
8ff2adf833 | ||
|
|
5e387b513a | ||
|
|
dca316c0d5 | ||
|
|
db2d786d50 | ||
|
|
c0d7962142 | ||
|
|
5d14354ca9 | ||
|
|
347dace6de | ||
|
|
d952c75e3c | ||
|
|
abc3745be1 | ||
|
|
1382d7c523 | ||
|
|
3de0edf0f9 | ||
|
|
5513d39152 | ||
|
|
1a9547d1d2 | ||
|
|
26cc64d3a0 | ||
|
|
e465b33365 | ||
|
|
957739ba5e | ||
|
|
59967374c5 | ||
|
|
43bc346a2b | ||
|
|
5fbd3f67cd | ||
|
|
e352343d62 | ||
|
|
baee0f0c6f | ||
|
|
fcc5eead88 | ||
|
|
29d1f687d1 | ||
|
|
f568266c7f | ||
|
|
a1e42b8ddb | ||
|
|
e6389b1153 | ||
|
|
f0835acb33 | ||
|
|
35b04b219f | ||
|
|
01b62e936a | ||
|
|
09d16a03ef | ||
|
|
bb61602fd2 | ||
|
|
f30b78ea1f | ||
|
|
6ee652ca75 | ||
|
|
67d8bbc154 | ||
|
|
b852484559 | ||
|
|
0b077e5e88 | ||
|
|
381d957db2 | ||
|
|
f8f77abc12 | ||
|
|
0b0484c610 | ||
|
|
2b769088af | ||
|
|
856d13c603 | ||
|
|
76e398b8a1 | ||
|
|
24a7d85be0 | ||
|
|
989271f653 | ||
|
|
3fd8cd5713 | ||
|
|
43f1c7caf6 | ||
|
|
bd91ac88a3 | ||
|
|
fbcbf2e5a5 | ||
|
|
31eb03da0d | ||
|
|
a4dbfed712 | ||
|
|
784cb53ec6 | ||
|
|
43c799bd60 |
@@ -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
18
.github/workflows/ci-js.yml
vendored
Normal 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
36
.github/workflows/ci-rust.yml
vendored
Normal 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
120
.github/workflows/release.yml
vendored
Normal 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
9
.gitignore
vendored
@@ -22,5 +22,12 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.eslintcache
|
||||
|
||||
.rsw
|
||||
*.sqlite
|
||||
*.sqlite-*
|
||||
|
||||
.cargo
|
||||
|
||||
.tmp
|
||||
tmp
|
||||
|
||||
1
.husky/.gitignore
vendored
Normal file
1
.husky/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
_
|
||||
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
@@ -1,3 +1,4 @@
|
||||
node_modules/
|
||||
dist/
|
||||
out/
|
||||
.prettierrc.cjs
|
||||
|
||||
13
.run/Dev Desktop.run.xml
Normal file
13
.run/Dev Desktop.run.xml
Normal 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
5
.sqllsrc.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "yaak-dev",
|
||||
"adapter": "sqlite3",
|
||||
"filename": "src-tauri/db.sqlite"
|
||||
}
|
||||
13
Makefile
Normal file
13
Makefile
Normal 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
|
||||
17
README.md
17
README.md
@@ -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
BIN
design/Icons.afdesign
Normal file
Binary file not shown.
BIN
design/icon-dev.png
Normal file
BIN
design/icon-dev.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
BIN
design/icon.png
Normal file
BIN
design/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 356 KiB |
BIN
design/logo.afdesign
Normal file
BIN
design/logo.afdesign
Normal file
Binary file not shown.
38
index.html
38
index.html
@@ -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
15284
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
127
package.json
127
package.json
@@ -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
3
plugin-runtime/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
build
|
||||
node_modules
|
||||
*.blob
|
||||
5
plugin-runtime/nodemon.json
Normal file
5
plugin-runtime/nodemon.json
Normal 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
3004
plugin-runtime/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
plugin-runtime/package.json
Normal file
23
plugin-runtime/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
92
plugin-runtime/src/PluginHandle.ts
Normal file
92
plugin-runtime/src/PluginHandle.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
plugin-runtime/src/PluginManager.ts
Normal file
44
plugin-runtime/src/PluginManager.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
432
plugin-runtime/src/gen/plugins/runtime.ts
Normal file
432
plugin-runtime/src/gen/plugins/runtime.ts
Normal 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;
|
||||
}
|
||||
87
plugin-runtime/src/index.ts
Normal file
87
plugin-runtime/src/index.ts
Normal 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));
|
||||
}
|
||||
});
|
||||
76
plugin-runtime/src/index.worker.ts
Normal file
76
plugin-runtime/src/index.worker.ts
Normal 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);
|
||||
});
|
||||
18
plugin-runtime/src/plugins.ts
Normal file
18
plugin-runtime/src/plugins.ts
Normal 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));
|
||||
}
|
||||
25
plugin-runtime/tsconfig.json
Normal file
25
plugin-runtime/tsconfig.json
Normal 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/**/*"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/nesting')(require('postcss-nesting')),
|
||||
require('tailwindcss'),
|
||||
require('autoprefixer'),
|
||||
]
|
||||
}
|
||||
|
||||
32
proto/plugins/runtime.proto
Normal file
32
proto/plugins/runtime.proto
Normal 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;
|
||||
}
|
||||
39
rsw.toml
39
rsw.toml
@@ -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
1
rustfmt.toml
Normal file
@@ -0,0 +1 @@
|
||||
edition = "2018"
|
||||
15
scripts/replace-version.cjs
Normal file
15
scripts/replace-version.cjs
Normal 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
69
scripts/vendor-node.cjs
Normal 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);
|
||||
});
|
||||
25
scripts/vendor-plugins.cjs
Normal file
25
scripts/vendor-plugins.cjs
Normal 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
62
scripts/vendor-protoc.cjs
Normal 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));
|
||||
1
src-tauri/.gitignore
vendored
1
src-tauri/.gitignore
vendored
@@ -2,3 +2,4 @@
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
vendored
|
||||
|
||||
50
src-tauri/.sqlx/query-06aaf8f4a17566f1d25da2a60f0baf4b5fc28c3cf0c001a84e25edf9eab3c7e3.json
generated
Normal file
50
src-tauri/.sqlx/query-06aaf8f4a17566f1d25da2a60f0baf4b5fc28c3cf0c001a84e25edf9eab3c7e3.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-07d1a1c7b4f3d9625a766e60fd57bb779b71dae30e5bbce34885a911a5a42428.json
generated
Normal file
12
src-tauri/.sqlx/query-07d1a1c7b4f3d9625a766e60fd57bb779b71dae30e5bbce34885a911a5a42428.json
generated
Normal 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"
|
||||
}
|
||||
116
src-tauri/.sqlx/query-0fa6b56f8c996d14908a56928674b4b35af5fa36f63dc48b9b66ee6dfde78976.json
generated
Normal file
116
src-tauri/.sqlx/query-0fa6b56f8c996d14908a56928674b4b35af5fa36f63dc48b9b66ee6dfde78976.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-12b265491d1ebba19e1ce8a660e458ffbcd8c0850aef16ba1f70e358623ac66a.json
generated
Normal file
12
src-tauri/.sqlx/query-12b265491d1ebba19e1ce8a660e458ffbcd8c0850aef16ba1f70e358623ac66a.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-13cb883199e81966174e6fda9c252bf7213fe01b5346266c0a89dc0ac89eda64.json
generated
Normal file
12
src-tauri/.sqlx/query-13cb883199e81966174e6fda9c252bf7213fe01b5346266c0a89dc0ac89eda64.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-14930955e8a914e292dfbebfce2ea43cc41c1d517386ed816c16d436bf626bf3.json
generated
Normal file
12
src-tauri/.sqlx/query-14930955e8a914e292dfbebfce2ea43cc41c1d517386ed816c16d436bf626bf3.json
generated
Normal 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"
|
||||
}
|
||||
104
src-tauri/.sqlx/query-1821c2f60b9fa4514d58eb73b23e25ad683b80b9bd0c2944063190a0d0a19ee5.json
generated
Normal file
104
src-tauri/.sqlx/query-1821c2f60b9fa4514d58eb73b23e25ad683b80b9bd0c2944063190a0d0a19ee5.json
generated
Normal 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"
|
||||
}
|
||||
80
src-tauri/.sqlx/query-18ada3bb42c29f1940ab2e61961d79cdd69210f3dc2076aedcadeba8e34dcb6e.json
generated
Normal file
80
src-tauri/.sqlx/query-18ada3bb42c29f1940ab2e61961d79cdd69210f3dc2076aedcadeba8e34dcb6e.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-2c181a4dc13efc52fe6a5a68291c5678a9624020df4ea744e78396f6926d5c88.json
generated
Normal file
12
src-tauri/.sqlx/query-2c181a4dc13efc52fe6a5a68291c5678a9624020df4ea744e78396f6926d5c88.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-2c9658a639c5e4994ae9c8ec30bd4e40a1945d640962991f879928619950ef62.json
generated
Normal file
12
src-tauri/.sqlx/query-2c9658a639c5e4994ae9c8ec30bd4e40a1945d640962991f879928619950ef62.json
generated
Normal 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"
|
||||
}
|
||||
92
src-tauri/.sqlx/query-3e8651cca7feecc208a676dfd24c7d8775040d5287c16890056dcb474674edfb.json
generated
Normal file
92
src-tauri/.sqlx/query-3e8651cca7feecc208a676dfd24c7d8775040d5287c16890056dcb474674edfb.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-42bc0ded60b44dab19daf6d8fc7df83d83af5d88ea0b84514fdc877a668c27cd.json
generated
Normal file
12
src-tauri/.sqlx/query-42bc0ded60b44dab19daf6d8fc7df83d83af5d88ea0b84514fdc877a668c27cd.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-448a1d1f1866ab42c0f81fcf8eb2930bf21dfdd43ca4831bc1a198cf45ac3732.json
generated
Normal file
12
src-tauri/.sqlx/query-448a1d1f1866ab42c0f81fcf8eb2930bf21dfdd43ca4831bc1a198cf45ac3732.json
generated
Normal 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"
|
||||
}
|
||||
62
src-tauri/.sqlx/query-558e72df3c6f2635c6b3d52a199f9a5f7a3d82b379ff9af36645dcfb92548fdd.json
generated
Normal file
62
src-tauri/.sqlx/query-558e72df3c6f2635c6b3d52a199f9a5f7a3d82b379ff9af36645dcfb92548fdd.json
generated
Normal 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"
|
||||
}
|
||||
110
src-tauri/.sqlx/query-573db23160de025e5c72efb90be7fff5e3ec4619b962d149fdd4d618fe02c680.json
generated
Normal file
110
src-tauri/.sqlx/query-573db23160de025e5c72efb90be7fff5e3ec4619b962d149fdd4d618fe02c680.json
generated
Normal 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"
|
||||
}
|
||||
56
src-tauri/.sqlx/query-5765e9565a8b89c5bc2d72197e0e4a1093739e9abba69f6fe5527d453fab4db8.json
generated
Normal file
56
src-tauri/.sqlx/query-5765e9565a8b89c5bc2d72197e0e4a1093739e9abba69f6fe5527d453fab4db8.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-5af82cd333895d3d7d67a92f37b0feb338f615b88aea2bd09cb5809008c645a3.json
generated
Normal file
12
src-tauri/.sqlx/query-5af82cd333895d3d7d67a92f37b0feb338f615b88aea2bd09cb5809008c645a3.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-5f2f40062abbe93e23b38876319cf16d4d2b3f8d0be32ffe7848528c725e1429.json
generated
Normal file
12
src-tauri/.sqlx/query-5f2f40062abbe93e23b38876319cf16d4d2b3f8d0be32ffe7848528c725e1429.json
generated
Normal 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"
|
||||
}
|
||||
56
src-tauri/.sqlx/query-612efa9ac45723dc604a88f5e7e288b4055fec4ba7d9102131bd255c037fa021.json
generated
Normal file
56
src-tauri/.sqlx/query-612efa9ac45723dc604a88f5e7e288b4055fec4ba7d9102131bd255c037fa021.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-66deed028199c78ed15ea2f837907887c2a2cb564d1d076dd4ebf0ecbc82e098.json
generated
Normal file
12
src-tauri/.sqlx/query-66deed028199c78ed15ea2f837907887c2a2cb564d1d076dd4ebf0ecbc82e098.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-6b5edf45a6799cd7f87c23a3c7f818ad110d58c601f694a619d9345ae9e8e11d.json
generated
Normal file
12
src-tauri/.sqlx/query-6b5edf45a6799cd7f87c23a3c7f818ad110d58c601f694a619d9345ae9e8e11d.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-84be2b954870ab181738656ecd4d03fca2ff21012947014c79626abfce8e999b.json
generated
Normal file
12
src-tauri/.sqlx/query-84be2b954870ab181738656ecd4d03fca2ff21012947014c79626abfce8e999b.json
generated
Normal 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"
|
||||
}
|
||||
74
src-tauri/.sqlx/query-8dfbae65ddec905ea3734448cc9f7029b6c78de227c6fa3a85d75d0a7f21e0e9.json
generated
Normal file
74
src-tauri/.sqlx/query-8dfbae65ddec905ea3734448cc9f7029b6c78de227c6fa3a85d75d0a7f21e0e9.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-9238f94c688d91f42627e5b73c627c514bab4039ab5edadc79b77dfdfd63b208.json
generated
Normal file
12
src-tauri/.sqlx/query-9238f94c688d91f42627e5b73c627c514bab4039ab5edadc79b77dfdfd63b208.json
generated
Normal 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"
|
||||
}
|
||||
80
src-tauri/.sqlx/query-92d8f003a8f7df692345f2d2fd2504c9222645976e3433e32e190f4ee4bf100d.json
generated
Normal file
80
src-tauri/.sqlx/query-92d8f003a8f7df692345f2d2fd2504c9222645976e3433e32e190f4ee4bf100d.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-93aea3881dffb70a82325263740a0bb6477e78f27991ce7456b394e84383acb6.json
generated
Normal file
12
src-tauri/.sqlx/query-93aea3881dffb70a82325263740a0bb6477e78f27991ce7456b394e84383acb6.json
generated
Normal 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"
|
||||
}
|
||||
74
src-tauri/.sqlx/query-9ba3f783238b77637ffded4171b2fbb5e5ad0be952a0d832448d65cc5f0effc1.json
generated
Normal file
74
src-tauri/.sqlx/query-9ba3f783238b77637ffded4171b2fbb5e5ad0be952a0d832448d65cc5f0effc1.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-a690a04cd1ebe8c3dbfd0cd98ae4ef093a1696d7b7ecaf694d12e5fafd62b685.json
generated
Normal file
12
src-tauri/.sqlx/query-a690a04cd1ebe8c3dbfd0cd98ae4ef093a1696d7b7ecaf694d12e5fafd62b685.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-ac1b4ffbd98b67f0a1a74e3525387d679dd6f44c561d55c7bbea747053e53671.json
generated
Normal file
12
src-tauri/.sqlx/query-ac1b4ffbd98b67f0a1a74e3525387d679dd6f44c561d55c7bbea747053e53671.json
generated
Normal 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"
|
||||
}
|
||||
116
src-tauri/.sqlx/query-ac38621cd947c3be9ca0d8ea73325fe35c3866d16f6482fc32c23762f112dc83.json
generated
Normal file
116
src-tauri/.sqlx/query-ac38621cd947c3be9ca0d8ea73325fe35c3866d16f6482fc32c23762f112dc83.json
generated
Normal 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"
|
||||
}
|
||||
62
src-tauri/.sqlx/query-ae98a7b35a5cb80a4bcd04faa22545deac2a5e9bfb814b60191f16b98ed49796.json
generated
Normal file
62
src-tauri/.sqlx/query-ae98a7b35a5cb80a4bcd04faa22545deac2a5e9bfb814b60191f16b98ed49796.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-aeb0712785a9964d516dc8939bc54aa8206ad852e608b362d014b67a0f21b0ed.json
generated
Normal file
12
src-tauri/.sqlx/query-aeb0712785a9964d516dc8939bc54aa8206ad852e608b362d014b67a0f21b0ed.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-b3fae40a793a6724dd2286a9ca4bc0a9c000a631ee0d751a9dc4f3e76de3d57c.json
generated
Normal file
12
src-tauri/.sqlx/query-b3fae40a793a6724dd2286a9ca4bc0a9c000a631ee0d751a9dc4f3e76de3d57c.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-b98609f65dd3a6bbd1ea8dc8bed2840a6d5d13fec1bbc0aa61ca4f60de98a09c.json
generated
Normal file
12
src-tauri/.sqlx/query-b98609f65dd3a6bbd1ea8dc8bed2840a6d5d13fec1bbc0aa61ca4f60de98a09c.json
generated
Normal 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"
|
||||
}
|
||||
56
src-tauri/.sqlx/query-ba2b34a77723f24f86e4c3c45274dbfec6ca130e16e592f948844c037bdc0593.json
generated
Normal file
56
src-tauri/.sqlx/query-ba2b34a77723f24f86e4c3c45274dbfec6ca130e16e592f948844c037bdc0593.json
generated
Normal 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"
|
||||
}
|
||||
92
src-tauri/.sqlx/query-d4b64c466624eb75e0f5bd201ebfb6a73d25eb7c9e09cb9690afdb7fef5fca8b.json
generated
Normal file
92
src-tauri/.sqlx/query-d4b64c466624eb75e0f5bd201ebfb6a73d25eb7c9e09cb9690afdb7fef5fca8b.json
generated
Normal 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"
|
||||
}
|
||||
116
src-tauri/.sqlx/query-d5e087caa163a0c7bfbbadf07eccb80105501cf5baab706aa6792dfe90af8fc9.json
generated
Normal file
116
src-tauri/.sqlx/query-d5e087caa163a0c7bfbbadf07eccb80105501cf5baab706aa6792dfe90af8fc9.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-d80c09497771e3641022e73ec6c6a87e73a551f88a948a5445d754922b82b50b.json
generated
Normal file
12
src-tauri/.sqlx/query-d80c09497771e3641022e73ec6c6a87e73a551f88a948a5445d754922b82b50b.json
generated
Normal 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"
|
||||
}
|
||||
98
src-tauri/.sqlx/query-daa61066517df649e7c80a8ce407839ad502e8e5e43aa8c02e049865acbbae75.json
generated
Normal file
98
src-tauri/.sqlx/query-daa61066517df649e7c80a8ce407839ad502e8e5e43aa8c02e049865acbbae75.json
generated
Normal 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"
|
||||
}
|
||||
104
src-tauri/.sqlx/query-e1cdba43bd938772631263966a9bee263923c387f4864917f36a04043bec4857.json
generated
Normal file
104
src-tauri/.sqlx/query-e1cdba43bd938772631263966a9bee263923c387f4864917f36a04043bec4857.json
generated
Normal 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"
|
||||
}
|
||||
110
src-tauri/.sqlx/query-e61c0dddb3e86d271cb9399faa4e4443342796cb72bdd43a821fae2994ae8e2f.json
generated
Normal file
110
src-tauri/.sqlx/query-e61c0dddb3e86d271cb9399faa4e4443342796cb72bdd43a821fae2994ae8e2f.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-e7124f5570076bfd65985744f48d8e12cf29d6d243fffdd62ade2ab70c7bddda.json
generated
Normal file
12
src-tauri/.sqlx/query-e7124f5570076bfd65985744f48d8e12cf29d6d243fffdd62ade2ab70c7bddda.json
generated
Normal 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"
|
||||
}
|
||||
56
src-tauri/.sqlx/query-f5f20f3b37d932617499a0da50997edad59e4f5998b15c50ed6eae2e97064068.json
generated
Normal file
56
src-tauri/.sqlx/query-f5f20f3b37d932617499a0da50997edad59e4f5998b15c50ed6eae2e97064068.json
generated
Normal 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"
|
||||
}
|
||||
12
src-tauri/.sqlx/query-fe0652396bc30d926cf99083651c1cbd668bcf00ebe1a5f36616700c84972b39.json
generated
Normal file
12
src-tauri/.sqlx/query-fe0652396bc30d926cf99083651c1cbd668bcf00ebe1a5f36616700c84972b39.json
generated
Normal 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
6492
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
tauri_build::build()
|
||||
}
|
||||
|
||||
46
src-tauri/capabilities/capabilities.json
Normal file
46
src-tauri/capabilities/capabilities.json
Normal 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"
|
||||
]
|
||||
}
|
||||
1
src-tauri/gen/schemas/acl-manifests.json
Normal file
1
src-tauri/gen/schemas/acl-manifests.json
Normal file
File diff suppressed because one or more lines are too long
1
src-tauri/gen/schemas/capabilities.json
Normal file
1
src-tauri/gen/schemas/capabilities.json
Normal 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"]}}
|
||||
6924
src-tauri/gen/schemas/desktop-schema.json
Normal file
6924
src-tauri/gen/schemas/desktop-schema.json
Normal file
File diff suppressed because it is too large
Load Diff
6861
src-tauri/gen/schemas/linux-schema.json
Normal file
6861
src-tauri/gen/schemas/linux-schema.json
Normal file
File diff suppressed because it is too large
Load Diff
6924
src-tauri/gen/schemas/macOS-schema.json
Normal file
6924
src-tauri/gen/schemas/macOS-schema.json
Normal file
File diff suppressed because it is too large
Load Diff
6924
src-tauri/gen/schemas/windows-schema.json
Normal file
6924
src-tauri/gen/schemas/windows-schema.json
Normal file
File diff suppressed because it is too large
Load Diff
24
src-tauri/grpc/Cargo.toml
Normal file
24
src-tauri/grpc/Cargo.toml
Normal 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"
|
||||
52
src-tauri/grpc/src/codec.rs
Normal file
52
src-tauri/grpc/src/codec.rs
Normal 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))
|
||||
}
|
||||
}
|
||||
179
src-tauri/grpc/src/json_schema.rs
Normal file
179
src-tauri/grpc/src/json_schema.rs
Normal 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
52
src-tauri/grpc/src/lib.rs
Normal 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)
|
||||
}
|
||||
304
src-tauri/grpc/src/manager.rs
Normal file
304
src-tauri/grpc/src/manager.rs
Normal 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
252
src-tauri/grpc/src/proto.rs
Normal 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
Reference in New Issue
Block a user