mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-03 17:38:36 +00:00
Compare commits
495 Commits
v1.25.0
...
feat/parse
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
758ef9fc96 | ||
|
|
ced9d38abc | ||
|
|
98f3a524dc | ||
|
|
a06a339d0c | ||
|
|
e34ac3de7c | ||
|
|
074c6be5f4 | ||
|
|
fee631d496 | ||
|
|
d03de2b622 | ||
|
|
31b2818821 | ||
|
|
8a71dfc022 | ||
|
|
3e6204e49b | ||
|
|
dab4bb6a1c | ||
|
|
3c8cb702f5 | ||
|
|
2df7fd6588 | ||
|
|
e5d7cd1be9 | ||
|
|
2bce9b3716 | ||
|
|
5bfcc9b6e7 | ||
|
|
472b5452f7 | ||
|
|
5b04e0c189 | ||
|
|
3da12a05db | ||
|
|
a73d2a02cf | ||
|
|
63d3cb380d | ||
|
|
10a5935a12 | ||
|
|
cf2cb0736e | ||
|
|
6abd063749 | ||
|
|
dbf1cad124 | ||
|
|
00c5298b7d | ||
|
|
27ef28ae9b | ||
|
|
abb0a7b0db | ||
|
|
d2d7638a54 | ||
|
|
5500070b49 | ||
|
|
72b8c547b2 | ||
|
|
15b870996d | ||
|
|
3cb15fc001 | ||
|
|
96d6bf1664 | ||
|
|
f5ff40abfa | ||
|
|
c5de2343e9 | ||
|
|
39e8b66135 | ||
|
|
9f9294d161 | ||
|
|
5f63cc4ab4 | ||
|
|
539d22125c | ||
|
|
36343b30b3 | ||
|
|
b5ae2b2b45 | ||
|
|
704977f20f | ||
|
|
c852257bda | ||
|
|
55eac64ca5 | ||
|
|
52672e67a2 | ||
|
|
d32f987bc6 | ||
|
|
5fe9208089 | ||
|
|
14ecc09cde | ||
|
|
949bf539b8 | ||
|
|
c4be6a88e4 | ||
|
|
99302e3a1d | ||
|
|
1d3cbd2335 | ||
|
|
218d6527df | ||
|
|
42ada4a364 | ||
|
|
548f958a0f | ||
|
|
005eb273bf | ||
|
|
343e6dae47 | ||
|
|
7b86febc87 | ||
|
|
ca5fbea7b6 | ||
|
|
f34711c6e0 | ||
|
|
cd722a2bd9 | ||
|
|
75a9959d47 | ||
|
|
754a15dd58 | ||
|
|
2a6f6704c3 | ||
|
|
7d67239b11 | ||
|
|
e0ab274452 | ||
|
|
776afbd28a | ||
|
|
ca8f96fba0 | ||
|
|
5c1ab647fc | ||
|
|
83e63e749e | ||
|
|
9d94ad9b73 | ||
|
|
395fb188fe | ||
|
|
f09fd19ca0 | ||
|
|
f578c188fb | ||
|
|
0d2b449b27 | ||
|
|
e897dc1eb0 | ||
|
|
85b6cae03d | ||
|
|
d215cf740b | ||
|
|
4b277aa874 | ||
|
|
e9378d7895 | ||
|
|
78aa0d07ae | ||
|
|
e4574e3a56 | ||
|
|
795cd196f2 | ||
|
|
7b935bd206 | ||
|
|
43e892f9b0 | ||
|
|
1f2bee1f90 | ||
|
|
767db75730 | ||
|
|
b6b4b7362f | ||
|
|
54d8fbc478 | ||
|
|
9a2d8bfff3 | ||
|
|
907f6a19ad | ||
|
|
b612da4f3c | ||
|
|
625140d1f4 | ||
|
|
284519cd43 | ||
|
|
26daee5d98 | ||
|
|
87988b6879 | ||
|
|
f8711a91d9 | ||
|
|
582e8e5eac | ||
|
|
236bc48d98 | ||
|
|
a63afd6c0b | ||
|
|
fec99f0780 | ||
|
|
bf142af6d9 | ||
|
|
57a85e535c | ||
|
|
f72d643e02 | ||
|
|
aea25842ce | ||
|
|
0831b610cf | ||
|
|
f871bc0fa2 | ||
|
|
db90d31b3f | ||
|
|
e44dcad01a | ||
|
|
7a8d1624d1 | ||
|
|
0ad0af041b | ||
|
|
ad59e3f8d1 | ||
|
|
b9ec0acab4 | ||
|
|
0d126abfbd | ||
|
|
a5096ce413 | ||
|
|
3bf98aab3b | ||
|
|
9b83cd7b84 | ||
|
|
21f9e80706 | ||
|
|
e8bc32b39b | ||
|
|
380047e025 | ||
|
|
434ae6c70f | ||
|
|
22612a7dbe | ||
|
|
06c0b7c78a | ||
|
|
c154dec2b5 | ||
|
|
3abe611752 | ||
|
|
f3cfacdd43 | ||
|
|
af4b2105be | ||
|
|
7ae64605c2 | ||
|
|
83bbbe3fb3 | ||
|
|
73ea5f155d | ||
|
|
366bd99e92 | ||
|
|
6b6fc9a3dc | ||
|
|
6323b54c38 | ||
|
|
57e6af703c | ||
|
|
09120a96e8 | ||
|
|
f1e6d5eefe | ||
|
|
ba41f17439 | ||
|
|
d37e9aaafa | ||
|
|
5a9bda2a0f | ||
|
|
eaa4f4e57b | ||
|
|
8992a457a8 | ||
|
|
b181aba646 | ||
|
|
47179535d5 | ||
|
|
316b632338 | ||
|
|
dc469afeea | ||
|
|
ee715a6dc6 | ||
|
|
19ad0ecef7 | ||
|
|
993424a2b8 | ||
|
|
086c4c063e | ||
|
|
a6ac98b709 | ||
|
|
22ecd0284f | ||
|
|
33e86a9097 | ||
|
|
3efcdf254e | ||
|
|
ea1f385d1c | ||
|
|
4dcaaab52c | ||
|
|
6326dc3d9c | ||
|
|
a55ed9bd50 | ||
|
|
57d86eb118 | ||
|
|
85c6b2d97f | ||
|
|
0c574aeb1e | ||
|
|
3fe0d43bdc | ||
|
|
67ead9739e | ||
|
|
36021b5b38 | ||
|
|
1e45725ba1 | ||
|
|
d4616c78c8 | ||
|
|
5e5656d268 | ||
|
|
52e01935f5 | ||
|
|
99f912312d | ||
|
|
915ebf3387 | ||
|
|
bb18c532da | ||
|
|
4b4bd3bc95 | ||
|
|
482cb05d63 | ||
|
|
32153c4dbf | ||
|
|
7535b3d4ba | ||
|
|
4dd4800ee9 | ||
|
|
e1ebaabcc7 | ||
|
|
f110d898f5 | ||
|
|
5b6172e5ac | ||
|
|
fd22ff8962 | ||
|
|
5f5cc5eb22 | ||
|
|
eb6944a1c9 | ||
|
|
b4ea101350 | ||
|
|
0a8217e4ab | ||
|
|
514da55923 | ||
|
|
bd2cf554b6 | ||
|
|
2f752085f3 | ||
|
|
f2cfcab091 | ||
|
|
4283bb4bb0 | ||
|
|
707cddea90 | ||
|
|
39a44e9b4f | ||
|
|
fb8c54dd7a | ||
|
|
7400d890e4 | ||
|
|
3a29e2e333 | ||
|
|
1fb4298681 | ||
|
|
6d8cc38946 | ||
|
|
9d4246d74b | ||
|
|
1238bf7270 | ||
|
|
e9d459fa5e | ||
|
|
1c4acf7301 | ||
|
|
6385d00807 | ||
|
|
157389424d | ||
|
|
1b30229903 | ||
|
|
72bd1b4cbf | ||
|
|
4a4481a26f | ||
|
|
0bec17facd | ||
|
|
1c86b5f340 | ||
|
|
917205299a | ||
|
|
916f28633e | ||
|
|
6c2451b6f2 | ||
|
|
24563bdaaf | ||
|
|
28d30b1ef7 | ||
|
|
6442e3ceca | ||
|
|
56c3bf0899 | ||
|
|
11a3ea9fbb | ||
|
|
84095a4183 | ||
|
|
d92dd46d4e | ||
|
|
a752921413 | ||
|
|
44debfd9b9 | ||
|
|
278ca8bf29 | ||
|
|
23c22a96bc | ||
|
|
77d3fa7e1e | ||
|
|
412a0ed078 | ||
|
|
1cb0d4e191 | ||
|
|
aff7c405cd | ||
|
|
59108472a2 | ||
|
|
c4492b5d94 | ||
|
|
7fd7eafdcb | ||
|
|
41040bc296 | ||
|
|
ad5b625655 | ||
|
|
cd629451e4 | ||
|
|
dc77ee7c04 | ||
|
|
c322baa9c8 | ||
|
|
b206b70d2e | ||
|
|
9a325caeee | ||
|
|
d0ef70473d | ||
|
|
4894ac2754 | ||
|
|
df206dc4d9 | ||
|
|
45cc97ee20 | ||
|
|
642413e35c | ||
|
|
abb6490232 | ||
|
|
40001949b8 | ||
|
|
bdfe9c16f1 | ||
|
|
d007feb3d1 | ||
|
|
f827b85f47 | ||
|
|
e025ed8436 | ||
|
|
be4fc2d9ad | ||
|
|
5fa7a75284 | ||
|
|
7ddb8c3f4d | ||
|
|
fa22c728ef | ||
|
|
ca2ee673f3 | ||
|
|
9e07c698d8 | ||
|
|
c4148b9e40 | ||
|
|
a580f88f63 | ||
|
|
fe2b45f9ea | ||
|
|
381103663f | ||
|
|
425c90b6eb | ||
|
|
6bebbfe9f3 | ||
|
|
22bc1d4ac5 | ||
|
|
e8530a1022 | ||
|
|
f8f00f1daa | ||
|
|
9aa84a259c | ||
|
|
4ea141fd73 | ||
|
|
2f9d54151e | ||
|
|
796fa0c27c | ||
|
|
a7f05db1d6 | ||
|
|
0c7d513d9e | ||
|
|
d92e806899 | ||
|
|
d70d4a482b | ||
|
|
c82203a059 | ||
|
|
66bb32a683 | ||
|
|
6588dcf2fd | ||
|
|
432d54acca | ||
|
|
0af5f72374 | ||
|
|
f43775e245 | ||
|
|
b82a2c3312 | ||
|
|
ac67c4c0d8 | ||
|
|
e947a8335a | ||
|
|
cc8f3de8be | ||
|
|
ca6c2ebb03 | ||
|
|
bb14ec22f7 | ||
|
|
dddc79c709 | ||
|
|
b900d3070d | ||
|
|
a0fcb6c91f | ||
|
|
a4ad4f6073 | ||
|
|
a2d9249515 | ||
|
|
a880e030eb | ||
|
|
3ef7df57e2 | ||
|
|
40fad99803 | ||
|
|
43cb2b82f3 | ||
|
|
2fc79e0e7f | ||
|
|
dce96e0f13 | ||
|
|
c0dc329861 | ||
|
|
d4814569ed | ||
|
|
ec5c593de4 | ||
|
|
0fa0b3ef85 | ||
|
|
4211575f01 | ||
|
|
90834b8c7d | ||
|
|
7a77afc64a | ||
|
|
8ab8af6b3f | ||
|
|
4e8e2e87dc | ||
|
|
ce8ebb0c1a | ||
|
|
5c5e3d18fc | ||
|
|
7a5b309664 | ||
|
|
93f8d916c4 | ||
|
|
5afafb5944 | ||
|
|
6bc8acd1e1 | ||
|
|
96e58f2f40 | ||
|
|
4797119657 | ||
|
|
1fe7af4fad | ||
|
|
de2053f988 | ||
|
|
95e56cd9c9 | ||
|
|
02a82c5371 | ||
|
|
e2baed6724 | ||
|
|
d448599a53 | ||
|
|
f35b715c6f | ||
|
|
f088cdb504 | ||
|
|
d8bf27f288 | ||
|
|
a8fce54e97 | ||
|
|
727fa26e44 | ||
|
|
1adfad6316 | ||
|
|
72de78025e | ||
|
|
2e4051b022 | ||
|
|
25f43f12c7 | ||
|
|
2dd5ae400c | ||
|
|
8e222189bc | ||
|
|
a1719a33fc | ||
|
|
1f17d39a91 | ||
|
|
63d4757bfa | ||
|
|
5889e114d4 | ||
|
|
1c110f0cb0 | ||
|
|
5fd6773f43 | ||
|
|
9c2c86baf6 | ||
|
|
3a58c6d3bd | ||
|
|
4ef5534d41 | ||
|
|
641f261733 | ||
|
|
4d820af4e0 | ||
|
|
bebb18fc99 | ||
|
|
6e4d7a6f76 | ||
|
|
da9f669a2d | ||
|
|
ed20eccc25 | ||
|
|
eb33504f19 | ||
|
|
858afdbf03 | ||
|
|
7107fa37a1 | ||
|
|
03e7c27d8d | ||
|
|
fc79436787 | ||
|
|
6c6693757e | ||
|
|
bad1302cb5 | ||
|
|
f5a4525161 | ||
|
|
d7ff4e7ee0 | ||
|
|
637e53421e | ||
|
|
b60c799645 | ||
|
|
563683b5c1 | ||
|
|
e019a96cd5 | ||
|
|
dd2b93e8cd | ||
|
|
89c8956523 | ||
|
|
00fcd30348 | ||
|
|
07baa63e9d | ||
|
|
938e0560a2 | ||
|
|
8b6e55dfc0 | ||
|
|
572c7ea2ae | ||
|
|
260996a0ce | ||
|
|
3cb3f8094f | ||
|
|
4f7cefe41d | ||
|
|
238c790f9b | ||
|
|
5e4a96792e | ||
|
|
4419634db7 | ||
|
|
19501812fc | ||
|
|
6d239929da | ||
|
|
0ddfca4c22 | ||
|
|
50d93bc249 | ||
|
|
ea9111748f | ||
|
|
721d0e1e49 | ||
|
|
f31c997fed | ||
|
|
3dfb27d447 | ||
|
|
7dd639192c | ||
|
|
b3c72b1640 | ||
|
|
e680d0d71d | ||
|
|
1057f54f2f | ||
|
|
d971aa9596 | ||
|
|
3d5ae98e04 | ||
|
|
83e505979c | ||
|
|
0d3fde5efd | ||
|
|
0937bab7f5 | ||
|
|
8856e8ec71 | ||
|
|
9614ab069f | ||
|
|
81d8c30d84 | ||
|
|
a08573f120 | ||
|
|
776866b3b4 | ||
|
|
9a57f3870f | ||
|
|
98a7aa1357 | ||
|
|
087bab6fb4 | ||
|
|
0b4e9e7640 | ||
|
|
62babef678 | ||
|
|
1c0ff13483 | ||
|
|
5d7f44fc61 | ||
|
|
c85d7b0c77 | ||
|
|
ab8afed8f9 | ||
|
|
450b1d3ae3 | ||
|
|
2191550061 | ||
|
|
4bd31fb083 | ||
|
|
bcc8811f65 | ||
|
|
a10e6ee858 | ||
|
|
46017a6c50 | ||
|
|
cb395e7649 | ||
|
|
5931f0bb4e | ||
|
|
2a93a6fa65 | ||
|
|
8a233fb489 | ||
|
|
b102898709 | ||
|
|
c5c343c543 | ||
|
|
c1ec95dc29 | ||
|
|
93080de2a8 | ||
|
|
36ef38be6a | ||
|
|
4726f5008e | ||
|
|
091b02c2c3 | ||
|
|
600940226c | ||
|
|
ee7f886c03 | ||
|
|
682c7bd1b1 | ||
|
|
e1aa5b4eb5 | ||
|
|
6bd9d4c480 | ||
|
|
a38d09a117 | ||
|
|
82985d1b43 | ||
|
|
d34d3a45ff | ||
|
|
25ccb38202 | ||
|
|
5f6a5f59b1 | ||
|
|
9e5148f032 | ||
|
|
b4fd350334 | ||
|
|
ad388e5a6a | ||
|
|
4ddccefee3 | ||
|
|
b121afe7bb | ||
|
|
f6c6a3b2bf | ||
|
|
cf02ea2572 | ||
|
|
9343f1e070 | ||
|
|
d000625c39 | ||
|
|
4bdbfb5c0c | ||
|
|
4fbd2f0bdb | ||
|
|
5ae3f0e75a | ||
|
|
b80269b68f | ||
|
|
67de396927 | ||
|
|
65b80cfd06 | ||
|
|
caa0a22e74 | ||
|
|
c7f0335d96 | ||
|
|
22fab7f599 | ||
|
|
c0d214f2bc | ||
|
|
9efbd7377a | ||
|
|
b63cf46734 | ||
|
|
73ac969d35 | ||
|
|
dc21206fc0 | ||
|
|
8f58235e17 | ||
|
|
fd6b3630a5 | ||
|
|
25e57d2578 | ||
|
|
cef6f85845 | ||
|
|
5f0e6f13eb | ||
|
|
0b9554c8cc | ||
|
|
8b76ecede3 | ||
|
|
44d70ca02a | ||
|
|
4d55b50250 | ||
|
|
6320a80cbe | ||
|
|
d1c34bd379 | ||
|
|
71ffe1f8d4 | ||
|
|
04ccb2f6ee | ||
|
|
99ddd8021c | ||
|
|
ee8e162f3d | ||
|
|
b1a140a4e0 | ||
|
|
e4407f3981 | ||
|
|
74e75a7da2 | ||
|
|
4aff61b665 | ||
|
|
e31c552dee | ||
|
|
753a576c3c | ||
|
|
3ad4eda861 | ||
|
|
d3e57d0ea6 | ||
|
|
77750ecc0b | ||
|
|
a1783c46ed | ||
|
|
017d2235b8 | ||
|
|
df120787ca | ||
|
|
b872fdfe6d | ||
|
|
f0b7bf3430 | ||
|
|
4169bb7ea4 | ||
|
|
74b1527513 | ||
|
|
3b8909e301 | ||
|
|
1bedfc2046 | ||
|
|
8de6b72ab9 | ||
|
|
9d84906f57 | ||
|
|
eceb114d6c | ||
|
|
a703b84681 | ||
|
|
9ba03a5f02 | ||
|
|
cdf56fcec1 | ||
|
|
f27e79cb01 | ||
|
|
40872f6e9e | ||
|
|
b7f4edac24 | ||
|
|
8e99ed3258 | ||
|
|
c3c91d61c8 | ||
|
|
39f60daca7 | ||
|
|
dce1481185 |
5
.github/workflows/npm-bru-cli.yml
vendored
5
.github/workflows/npm-bru-cli.yml
vendored
@@ -20,7 +20,10 @@ permissions:
|
||||
jobs:
|
||||
test:
|
||||
name: CLI Tests
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
|
||||
16
.github/workflows/tests.yml
vendored
16
.github/workflows/tests.yml
vendored
@@ -5,6 +5,9 @@ on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
unit-test:
|
||||
name: Unit Tests
|
||||
@@ -25,8 +28,14 @@ jobs:
|
||||
run: |
|
||||
npm run build --workspace=packages/bruno-common
|
||||
npm run build --workspace=packages/bruno-query
|
||||
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
|
||||
|
||||
# tests
|
||||
- name: Test Package bruno-js
|
||||
run: npm run test --workspace=packages/bruno-js
|
||||
- name: Test Package bruno-cli
|
||||
run: npm run test --workspace=packages/bruno-cli
|
||||
|
||||
# test
|
||||
- name: Test Package bruno-query
|
||||
run: npm run test --workspace=packages/bruno-query
|
||||
- name: Test Package bruno-lang
|
||||
@@ -35,12 +44,8 @@ jobs:
|
||||
run: npm run test --workspace=packages/bruno-schema
|
||||
- name: Test Package bruno-app
|
||||
run: npm run test --workspace=packages/bruno-app
|
||||
- name: Test Package bruno-js
|
||||
run: npm run test --workspace=packages/bruno-js
|
||||
- name: Test Package bruno-common
|
||||
run: npm run test --workspace=packages/bruno-common
|
||||
- name: Test Package bruno-cli
|
||||
run: npm run test --workspace=packages/bruno-cli
|
||||
- name: Test Package bruno-electron
|
||||
run: npm run test --workspace=packages/bruno-electron
|
||||
|
||||
@@ -62,6 +67,7 @@ jobs:
|
||||
run: |
|
||||
npm run build --workspace=packages/bruno-query
|
||||
npm run build --workspace=packages/bruno-common
|
||||
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
| [正體中文](docs/contributing/contributing_zhtw.md)
|
||||
| [日本語](docs/contributing/contributing_ja.md)
|
||||
| [हिंदी](docs/contributing/contributing_hi.md)
|
||||
| [Nederlands](docs/contributing/contributing_nl.md)
|
||||
|
||||
## Let's make Bruno better, together!!
|
||||
|
||||
@@ -34,10 +35,11 @@ Libraries we use
|
||||
- Schema Validation - Yup
|
||||
- Request Client - axios
|
||||
- Filesystem Watcher - chokidar
|
||||
- i18n - i18next
|
||||
|
||||
### Dependencies
|
||||
|
||||
You would need [Node v18.x or the latest LTS version](https://nodejs.org/en/) and npm 8.x. We use npm workspaces in the project
|
||||
You would need [Node v20.x or the latest LTS version](https://nodejs.org/en/) and npm 8.x. We use npm workspaces in the project
|
||||
|
||||
## Development
|
||||
|
||||
@@ -46,7 +48,7 @@ Bruno is being developed as a desktop app. You need to load the app by running t
|
||||
### Local Development
|
||||
|
||||
```bash
|
||||
# use nodejs 18 version
|
||||
# use nodejs 20 version
|
||||
nvm use
|
||||
|
||||
# install deps
|
||||
@@ -57,6 +59,9 @@ npm run build:graphql-docs
|
||||
npm run build:bruno-query
|
||||
npm run build:bruno-common
|
||||
|
||||
# bundle js sandbox libraries
|
||||
npm run sandbox:bundle-libraries --workspace=packages/bruno-js
|
||||
|
||||
# run next app (terminal 1)
|
||||
npm run dev:web
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| **বাংলা**
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## আসুন ব্রুনোকে আরও ভালো করি, একসাথে!!
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| **简体中文**
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## 让我们一起改进 Bruno!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bruno 基于 NextJs 和 React 构建。我们使用 Electron 来封装桌面版
|
||||
|
||||
### 依赖项
|
||||
|
||||
您需要 [Node v18.x 或最新的 LTS 版本](https://nodejs.org/en/) 和 npm 8.x。我们在这个项目中也使用 npm 工作区(_npm workspaces_)。
|
||||
您需要 [Node v20.x 或最新的 LTS 版本](https://nodejs.org/en/) 和 npm 8.x。我们在这个项目中也使用 npm 工作区(_npm workspaces_)。
|
||||
|
||||
## 开发
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| **Deutsch**
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Lass uns Bruno noch besser machen, gemeinsam!!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bibliotheken die wir benutzen
|
||||
|
||||
### Abhängigkeiten
|
||||
|
||||
Du benötigst [Node v18.x oder die neuste LTS Version](https://nodejs.org/en/) und npm 8.x. Wir benutzen npm workspaces in dem Projekt.
|
||||
Du benötigst [Node v20.x oder die neuste LTS Version](https://nodejs.org/en/) und npm 8.x. Wir benutzen npm workspaces in dem Projekt.
|
||||
|
||||
### Lass uns coden
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| **Español**
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## ¡Juntos, hagamos a Bruno mejor!
|
||||
|
||||
@@ -37,7 +21,7 @@ Librerías que utilizamos:
|
||||
|
||||
### Dependencias
|
||||
|
||||
Necesitarás [Node v18.x o la última versión LTS](https://nodejs.org/es) y npm 8.x. Ten en cuenta que utilizamos espacios de trabajo de npm en el proyecto.
|
||||
Necesitarás [Node v20.x o la última versión LTS](https://nodejs.org/es) y npm 8.x. Ten en cuenta que utilizamos espacios de trabajo de npm en el proyecto.
|
||||
|
||||
## Desarrollo
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| **Français**
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Ensemble, améliorons Bruno !
|
||||
|
||||
@@ -37,7 +21,7 @@ Les librairies que nous utilisons :
|
||||
|
||||
### Dépendances
|
||||
|
||||
Vous aurez besoin de [Node v18.x ou la dernière version LTS](https://nodejs.org/en/) et npm 8.x. Nous utilisons aussi les espaces de travail npm (_npm workspaces_) dans ce projet.
|
||||
Vous aurez besoin de [Node v20.x ou la dernière version LTS](https://nodejs.org/en/) et npm 8.x. Nous utilisons aussi les espaces de travail npm (_npm workspaces_) dans ce projet.
|
||||
|
||||
## Développement
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| **हिंदी**
|
||||
|
||||
## आइए मिलकर Bruno को बेहतर बनाएं !!
|
||||
|
||||
@@ -37,7 +21,7 @@ Libraries जिनका हम उपयोग करते हैं
|
||||
|
||||
### निर्भरताएँ
|
||||
|
||||
आपको [Node v18.x या नवीनतम LTS संस्करण](https://nodejs.org/en/) और npm 8.x की आवश्यकता होगी। हम प्रोजेक्ट में npm वर्कस्पेस का उपयोग करते हैं
|
||||
आपको [Node v20.x या नवीनतम LTS संस्करण](https://nodejs.org/en/) और npm 8.x की आवश्यकता होगी। हम प्रोजेक्ट में npm वर्कस्पेस का उपयोग करते हैं
|
||||
|
||||
## डेवलपमेंट
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| **Italiano**
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Insieme, miglioriamo Bruno!
|
||||
|
||||
@@ -37,7 +21,7 @@ Le librerie che utilizziamo sono:
|
||||
|
||||
### Dependences
|
||||
|
||||
Hai bisogno di [Node v18.x o dell'ultima versione LTS](https://nodejs.org/en/) di npm 8.x. Utilizziamo gli spazi di lavoro npm (_npm workspaces_) in questo progetto.
|
||||
Hai bisogno di [Node v20.x o dell'ultima versione LTS](https://nodejs.org/en/) di npm 8.x. Utilizziamo gli spazi di lavoro npm (_npm workspaces_) in questo progetto.
|
||||
|
||||
### Iniziamo a codificare
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| **日本語**
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## 一緒に Bruno をよりよいものにしていきましょう!!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bruno は Next.js と React で作られています。デスクトップアプ
|
||||
|
||||
### 依存関係
|
||||
|
||||
[Node v18.x もしくは最新の LTS バージョン](https://nodejs.org/en/)と npm 8.x が必要です。プロジェクトに npm ワークスペースを使用しています。
|
||||
[Node v20.x もしくは最新の LTS バージョン](https://nodejs.org/en/)と npm 8.x が必要です。プロジェクトに npm ワークスペースを使用しています。
|
||||
|
||||
## 開発
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| **한국어**
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## 함께 Bruno를 더 좋게 만들어요!!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bruno는 Next.js와 React로 구축되었습니다. 또한, (로컬 컬렉션을
|
||||
|
||||
### 의존성
|
||||
|
||||
[Node v18.x 혹은 최신 LTS version](https://nodejs.org/en/)과 npm 8.x 버전이 필요합니다. 우리는 이 프로젝트에서 npm workspaces를 사용합니다.
|
||||
[Node v20.x 혹은 최신 LTS version](https://nodejs.org/en/)과 npm 8.x 버전이 필요합니다. 우리는 이 프로젝트에서 npm workspaces를 사용합니다.
|
||||
|
||||
## 개발
|
||||
|
||||
|
||||
82
docs/contributing/contributing_nl.md
Normal file
82
docs/contributing/contributing_nl.md
Normal file
@@ -0,0 +1,82 @@
|
||||
[English](../../contributing.md)
|
||||
|
||||
## Laten we Bruno samen beter maken !!
|
||||
|
||||
We zijn blij dat je Bruno wilt verbeteren. Hieronder staan de richtlijnen om Bruno op je computer op te zetten.
|
||||
|
||||
### Technologiestack
|
||||
|
||||
Bruno is gebouwd met Next.js en React. We gebruiken ook Electron om een desktopversie te leveren (die lokale collecties ondersteunt).
|
||||
|
||||
Bibliotheken die we gebruiken:
|
||||
|
||||
- CSS - Tailwind
|
||||
- Code Editors - Codemirror
|
||||
- State Management - Redux
|
||||
- Iconen - Tabler Icons
|
||||
- Formulieren - formik
|
||||
- Schema Validatie - Yup
|
||||
- Request Client - axios
|
||||
- Bestandsysteem Watcher - chokidar
|
||||
|
||||
### Afhankelijkheden
|
||||
|
||||
Je hebt [Node v18.x of de nieuwste LTS-versie](https://nodejs.org/en/) en npm 8.x nodig. We gebruiken npm workspaces in het project.
|
||||
|
||||
## Ontwikkeling
|
||||
|
||||
Bruno wordt ontwikkeld als een desktop-app. Je moet de app laden door de Next.js app in één terminal te draaien en daarna de Electron app in een andere terminal te draaien.
|
||||
|
||||
### Lokale Ontwikkeling
|
||||
|
||||
```bash
|
||||
# gebruik voorgeschreven node versie
|
||||
nvm use
|
||||
|
||||
# installeer afhankelijkheden
|
||||
npm i --legacy-peer-deps
|
||||
|
||||
# build pakketten
|
||||
npm run build:graphql-docs
|
||||
npm run build:bruno-query
|
||||
npm run build:bruno-common
|
||||
|
||||
# draai next app (terminal 1)
|
||||
npm run dev:web
|
||||
|
||||
# draai electron app (terminal 2)
|
||||
npm run dev:electron
|
||||
```
|
||||
|
||||
### Problemen oplossen
|
||||
|
||||
Je kunt een `Unsupported platform`-fout tegenkomen wanneer je `npm install` uitvoert. Om dit te verhelpen, moet je `node_modules` en `package-lock.json` verwijderen en `npm install` uitvoeren. Dit zou alle benodigde afhankelijkheden moeten installeren om de app te draaien.
|
||||
|
||||
```shell
|
||||
# Verwijder node_modules in subdirectories
|
||||
find ./ -type d -name "node_modules" -print0 | while read -d $'\0' dir; do
|
||||
rm -rf "$dir"
|
||||
done
|
||||
|
||||
# Verwijder package-lock in subdirectories
|
||||
find . -type f -name "package-lock.json" -delete
|
||||
```
|
||||
|
||||
### Testen
|
||||
|
||||
```bash
|
||||
# bruno-schema
|
||||
npm test --workspace=packages/bruno-schema
|
||||
|
||||
# bruno-lang
|
||||
npm test --workspace=packages/bruno-lang
|
||||
```
|
||||
|
||||
### Pull Requests indienen
|
||||
|
||||
- Houd de PR's klein en gefocust op één ding
|
||||
- Volg het formaat voor het aanmaken van branches
|
||||
- feature/[feature naam]: Deze branch moet wijzigingen voor een specifieke functie bevatten
|
||||
- Voorbeeld: feature/dark-mode
|
||||
- bugfix/[bug naam]: Deze branch moet alleen bugfixes voor een specifieke bug bevatten
|
||||
- Voorbeeld: bugfix/bug-1
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| **Polski**
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Wspólnie uczynijmy Bruno lepszym !!
|
||||
|
||||
@@ -37,7 +21,7 @@ Biblioteki, których używamy
|
||||
|
||||
### Zależności
|
||||
|
||||
Będziesz potrzebować [Node v18.x lub najnowszej wersji LTS](https://nodejs.org/en/) oraz npm 8.x. W projekcie używamy npm workspaces
|
||||
Będziesz potrzebować [Node v20.x lub najnowszej wersji LTS](https://nodejs.org/en/) oraz npm 8.x. W projekcie używamy npm workspaces
|
||||
|
||||
## Rozwój
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| **Português (BR)**
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Vamos tornar o Bruno melhor, juntos!!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bibliotecas que utilizamos:
|
||||
|
||||
### Dependências
|
||||
|
||||
Você precisará do [Node v18.x (ou da versão LTS mais recente)](https://nodejs.org/en/) e do npm na versão 8.x. Nós utilizamos npm workspaces no projeto.
|
||||
Você precisará do [Node v20.x (ou da versão LTS mais recente)](https://nodejs.org/en/) e do npm na versão 8.x. Nós utilizamos npm workspaces no projeto.
|
||||
|
||||
## Desenvolvimento
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| **Română**
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Haideţi să îmbunătățim Bruno, împreună!!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bibliotecile pe care le folosim
|
||||
|
||||
### Dependențele
|
||||
|
||||
Veți avea nevoie de [Node v18.x sau cea mai recentă versiune LTS](https://nodejs.org/en/) și npm 8.x. Noi folosim spații de lucru npm în proiect
|
||||
Veți avea nevoie de [Node v20.x sau cea mai recentă versiune LTS](https://nodejs.org/en/) și npm 8.x. Noi folosim spații de lucru npm în proiect
|
||||
|
||||
## Dezvoltarea
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| **Русский**
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Давайте вместе сделаем Бруно лучше!!!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bruno построен с использованием Next.js и React. Мы т
|
||||
|
||||
### Зависимости
|
||||
|
||||
Вам потребуется [Node v18.x или последняя версия LTS](https://nodejs.org/en/) и npm 8.x. В проекте мы используем рабочие пространства npm
|
||||
Вам потребуется [Node v20.x или последняя версия LTS](https://nodejs.org/en/) и npm 8.x. В проекте мы используем рабочие пространства npm
|
||||
|
||||
### Приступим к коду
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| **Türkçe**
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Bruno'yu birlikte daha iyi hale getirelim!!!
|
||||
|
||||
@@ -37,7 +21,7 @@ Kullandığımız kütüphaneler
|
||||
|
||||
### Bağımlılıklar
|
||||
|
||||
[Node v18.x veya en son LTS sürümüne](https://nodejs.org/en/) ve npm 8.x'e ihtiyacınız olacaktır. Projede npm çalışma alanlarını kullanıyoruz
|
||||
[Node v20.x veya en son LTS sürümüne](https://nodejs.org/en/) ve npm 8.x'e ihtiyacınız olacaktır. Projede npm çalışma alanlarını kullanıyoruz
|
||||
|
||||
## Gelişim
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| **Українська**
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| [正體中文](./contributing_zhtw.md)
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## Давайте зробимо Bruno краще, разом !!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bruno побудований на Next.js та React. Також для деск
|
||||
|
||||
### Залежності
|
||||
|
||||
Вам знадобиться [Node v18.x або остання LTS версія](https://nodejs.org/en/) та npm 8.x. Ми використовуєм npm workspaces в цьому проекті
|
||||
Вам знадобиться [Node v20.x або остання LTS версія](https://nodejs.org/en/) та npm 8.x. Ми використовуєм npm workspaces в цьому проекті
|
||||
|
||||
### Починаєм писати код
|
||||
|
||||
|
||||
@@ -1,20 +1,4 @@
|
||||
[English](../../contributing.md)
|
||||
| [Українська](./contributing_ua.md)
|
||||
| [Русский](./contributing_ru.md)
|
||||
| [Türkçe](./contributing_tr.md)
|
||||
| [Deutsch](./contributing_de.md)
|
||||
| [Français](./contributing_fr.md)
|
||||
| [Português (BR)](./contributing_pt_br.md)
|
||||
| [한국어](./contributing_kr.md)
|
||||
| [বাংলা](./contributing_bn.md)
|
||||
| [Español](./contributing_es.md)
|
||||
| [Italiano](./contributing_it.md)
|
||||
| [Română](./contributing_ro.md)
|
||||
| [Polski](./contributing_pl.md)
|
||||
| [简体中文](./contributing_cn.md)
|
||||
| **正體中文**
|
||||
| [日本語](./contributing_ja.md)
|
||||
| [हिंदी](./contributing_hi.md)
|
||||
|
||||
## 讓我們一起來讓 Bruno 變得更好!
|
||||
|
||||
@@ -37,7 +21,7 @@ Bruno 使用 Next.js 和 React 構建。我們使用 Electron 來封裝及發佈
|
||||
|
||||
### 依賴關係
|
||||
|
||||
您需要使用 [Node v18.x 或最新的 LTS 版本](https://nodejs.org/en/) 和 npm 8.x。我們在這個專案中使用 npm 工作區(_npm workspaces_)。
|
||||
您需要使用 [Node v20.x 或最新的 LTS 版本](https://nodejs.org/en/) 和 npm 8.x。我們在這個專案中使用 npm 工作區(_npm workspaces_)。
|
||||
|
||||
## 開發
|
||||
|
||||
|
||||
7
docs/publishing/publishin_nl.md
Normal file
7
docs/publishing/publishin_nl.md
Normal file
@@ -0,0 +1,7 @@
|
||||
[English](../../publishing.md)
|
||||
|
||||
### Bruno publiceren naar een nieuwe pakketbeheerder
|
||||
|
||||
Hoewel onze code open source is en beschikbaar voor iedereen, verzoeken we je vriendelijk om contact met ons op te nemen voordat je publicatie overweegt op nieuwe pakketbeheerders. Als de maker van Bruno houd ik het handelsmerk `Bruno` voor dit project en wil ik het distributieproces beheren. Als je Bruno op een nieuwe pakketbeheerder wilt zien, dien dan een GitHub-issue in.
|
||||
|
||||
Hoewel de meerderheid van onze functies gratis en open source zijn (die REST en GraphQL API's dekken), streven we ernaar een harmonieuze balans te vinden tussen open-source principes en duurzaamheid - https://github.com/usebruno/bruno/discussions/269
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| [Français](./publishing_fr.md)
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| **বাংলা**
|
||||
| [Română](./publishing_ro.md)
|
||||
| [Polski](./publishing_pl.md)
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### ব্রুনোকে নতুন প্যাকেজ ম্যানেজারে প্রকাশ করা
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| [Français](./publishing_fr.md)
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| [Română](./publishing_ro.md)
|
||||
| [Polski](./publishing_pl.md)
|
||||
| **简体中文**
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### 将 Bruno 发布到新的包管理器
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| **Deutsch**
|
||||
| [Français](./publishing_fr.md)
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| [Română](./publishing_ro.md)
|
||||
| [Polski](./publishing_pl.md)
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### Veröffentlichung von Bruno über neue Paket-Manager
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| **Français**
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| [Română](./publishing_ro.md)
|
||||
| [Polski](./publishing_pl.md)
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### Publier Bruno dans un nouveau gestionnaire de paquets
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| [Français](./publishing_fr.md)
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| [Română](./publishing_ro.md)
|
||||
| [Polski](./publishing_pl.md)
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| **日本語**
|
||||
|
||||
### Bruno を新しいパッケージマネージャに公開する場合の注意
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| [Français](./publishing_fr.md)
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| [Română](./publishing_ro.md)
|
||||
| **Polski**
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### Publikowanie Bruno w nowym menedżerze pakietów
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| [Français](./publishing_fr.md)
|
||||
| **Português (BR)**
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| [Română](./publishing_ro.md)
|
||||
| [Polski](./publishing_pl.md)
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### Publicando Bruno em um novo gerenciador de pacotes
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| [Français](./publishing_fr.md)
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| **Română**
|
||||
| [Polski](./publishing_pl.md)
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### Publicarea lui Bruno la un gestionar de pachete nou
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| **Türkçe**
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| [Français](./publishing_fr.md)
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| [Română](./publishing_ro.md)
|
||||
| [Polski](./publishing_pl.md)
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| [正體中文](./publishing_zhtw.md)
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### Bruno'yu yeni bir paket yöneticisine yayınlama
|
||||
|
||||
|
||||
@@ -1,14 +1,4 @@
|
||||
[English](../../publishing.md)
|
||||
| [Türkçe](./publishing_tr.md)
|
||||
| [Deutsch](./publishing_de.md)
|
||||
| [Français](./publishing_fr.md)
|
||||
| [Português (BR)](./publishing_pt_br.md)
|
||||
| [বাংলা](./publishing_bn.md)
|
||||
| [Română](./publishing_ro.md)
|
||||
| [Polski](./publishing_pl.md)
|
||||
| [简体中文](./publishing_cn.md)
|
||||
| **正體中文**
|
||||
| [日本語](./publishing_ja.md)
|
||||
|
||||
### 將 Bruno 發佈到新的套件管理器
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| **العربية**
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
برونو هو عميل API جديد ومبتكر، يهدف إلى ثورة الحالة الحالية التي يمثلها برنامج Postman وأدوات مماثلة هناك.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
ব্রুনো হল একটি নতুন এবং উদ্ভাবনী API ক্লায়েন্ট, যার লক্ষ্য পোস্টম্যান এবং অনুরূপ সরঞ্জাম দ্বারা প্রতিনিধিত্ব করা স্থিতাবস্থায় বিপ্লব ঘটানো।
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno 是一款全新且创新的 API 客户端,旨在颠覆 Postman 和其他类似工具。
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno ist ein neuer und innovativer API-Client, der den Status Quo von Postman und ähnlichen Tools revolutionieren soll.
|
||||
|
||||
@@ -38,7 +39,7 @@ Bruno ist ein reines Offline-Tool. Es gibt keine Pläne, Bruno um eine Cloud-Syn
|
||||
|
||||
[Download Bruno](https://www.usebruno.com/downloads)
|
||||
|
||||
📢 Sehen Sie sich unseren Vortrag auf der India FOSS 3.0 Conference [hier](https://www.youtube.com/watch?v=7bSMFpbcPiY) an.
|
||||
📢 Sieh Dir unseren Vortrag auf der India FOSS 3.0 Conference [hier](https://www.youtube.com/watch?v=7bSMFpbcPiY) an.
|
||||
|
||||
 <br /><br />
|
||||
|
||||
@@ -47,13 +48,13 @@ Bruno ist ein reines Offline-Tool. Es gibt keine Pläne, Bruno um eine Cloud-Syn
|
||||
Die meisten unserer Funktionen sind kostenlos und quelloffen.
|
||||
Wir bemühen uns um ein Gleichgewicht zwischen [Open-Source-Prinzipien und Nachhaltigkeit](https://github.com/usebruno/bruno/discussions/269)
|
||||
|
||||
Sie können die [Golden Edition](https://www.usebruno.com/pricing) vorbestellen ~~$19~~ **$9** ! <br/>
|
||||
Du kannst die [Golden Edition](https://www.usebruno.com/pricing) bestellen **$19**! <br/>
|
||||
|
||||
### Installation
|
||||
|
||||
Bruno ist als Download [auf unserer Website](https://www.usebruno.com/downloads) für Mac, Windows und Linux verfügbar.
|
||||
|
||||
Sie können Bruno auch über Paketmanager wie Homebrew, Chocolatey, Scoop, Snap, Flatpak und Apt installieren.
|
||||
Du kannst Bruno auch über Paketmanager wie Homebrew, Chocolatey, Scoop, Snap, Flatpak und Apt installieren.
|
||||
|
||||
```sh
|
||||
# Auf Mac via Homebrew
|
||||
@@ -122,11 +123,11 @@ Oder einer Versionskontrolle deiner Wahl
|
||||
|
||||
### Unterstützung ❤️
|
||||
|
||||
Wuff! Wenn du dieses Projekt magst, klick den ⭐ Button !!
|
||||
Wuff! Wenn du dieses Projekt magst, klick auf den ⭐ Button !!
|
||||
|
||||
### Teile Erfahrungsberichte 📣
|
||||
|
||||
Wenn Bruno dir und in deinen Teams bei der Arbeit geholfen hat, vergiss bitte nicht, deine [Erfahrungsberichte auf unserer GitHub-Diskussion](https://github.com/usebruno/bruno/discussions/343) zu teilen.
|
||||
Wenn Bruno dir und in deinem Team bei der Arbeit geholfen hat, vergiss bitte nicht, deine [Erfahrungsberichte in unserer GitHub-Diskussion](https://github.com/usebruno/bruno/discussions/343) zu teilen.
|
||||
|
||||
### Bereitstellung in neuen Paket-Managern
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno es un cliente de APIs nuevo e innovador, creado con el objetivo de revolucionar el panorama actual representado por Postman y otras herramientas similares.
|
||||
|
||||
Bruno almacena tus colecciones directamente en una carpeta de tu sistema de archivos. Usamos un lenguaje de marcado de texto plano, llamado Bru, para guardar información sobre las peticiones a tus APIs.
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno est un nouveau client API, innovant, qui a pour but de révolutionner le _statu quo_ que représentent Postman et les autres outils.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno è un nuovo ed innovativo API client, mirato a rivoluzionare lo status quo rappresentato da Postman e strumenti simili disponibili.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| **日本語**
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno は革新的な API クライアントです。Postman を代表する API クライアントツールの現状に一石を投じることを目指しています。
|
||||
|
||||
|
||||
176
docs/readme/readme_ka.md
Normal file
176
docs/readme/readme_ka.md
Normal file
@@ -0,0 +1,176 @@
|
||||
<br />
|
||||
<img src="../../assets/images/logo-transparent.png" width="80"/>
|
||||
|
||||
### ბრუნო - ღია წყაროების IDE API-ების შესწავლისა და ტესტირებისათვის.
|
||||
|
||||
[](https://badge.fury.io/gh/usebruno%bruno)
|
||||
[](https://github.com/usebruno/bruno/actions/workflows/tests.yml)
|
||||
[](https://github.com/usebruno/bruno/pulse)
|
||||
[](https://twitter.com/use_bruno)
|
||||
[](https://www.usebruno.com)
|
||||
[](https://www.usebruno.com/downloads)
|
||||
|
||||
[English](../../readme.md)
|
||||
| [Українська](./readme_ua.md)
|
||||
| [Русский](./readme_ru.md)
|
||||
| [Türkçe](./readme_tr.md)
|
||||
| [Deutsch](./readme_de.md)
|
||||
| [Français](./readme_fr.md)
|
||||
| [Português (BR)](./readme_pt_br.md)
|
||||
| [한국어](./readme_kr.md)
|
||||
| [বাংলা](./readme_bn.md)
|
||||
| [Español](./readme_es.md)
|
||||
| [Italiano](./readme_it.md)
|
||||
| [Română](./readme_ro.md)
|
||||
| [Polski](./readme_pl.md)
|
||||
| [简体中文](./readme_cn.md)
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| **ქართული**
|
||||
|
||||
ბრუნო არის ახალი და ინოვაციური API კლიენტი, რომელიც მიზნად ისახავს პოსტმანისა და მსგავსი ინსტრუმენტების არსებული მდგომარეობის რევოლუციას.
|
||||
|
||||
ბრუნო თქვენი კოლექციების შენახვას უშუალოდ თქვენს ფაილური სისტემის ერთ-ერთ საქაღალოში ახდენს. ჩვენ ვხმარობთ უბრალო ტექსტურ მარკაპ ენის, Bru-ს, API მოთხოვნების შესახებ ინფორმაციის შენახვისთვის.
|
||||
|
||||
თქვენ შეგიძლიათ გამოიყენოთ Git ან ნებისმიერი ვერსიის კონტროლის სისტემა თქვენი API კოლექციების გასაზიარებლად.
|
||||
|
||||
ბრუნო მხოლოდ ოფლაინ რეჟიმში მუშაობს. ბრუნოში ღრუბლური სინქრონიზაციის დამატების გეგმები არ არის. ჩვენ ვაფასებთ თქვენი მონაცემების პრივატობას და creemos, რომ ისინი თქვენს მოწყობილობაში უნდა დარჩეს. წაიკითხეთ ჩვენი გრძელვადიანი ხედვა [აქ](https://github.com/usebruno/bruno/discussions/269)
|
||||
|
||||
[დამატებით ბრუნო](https://www.usebruno.com/downloads)
|
||||
|
||||
📢 შეიტყვეთ ჩვენი უახლესი საუბრის შესახებ India FOSS 3.0 კონფერენციაზე [აქ](https://www.youtube.com/watch?v=7bSMFpbcPiY)
|
||||
|
||||
 <br /><br />
|
||||
|
||||
### ოქროს გამოცემა ✨
|
||||
|
||||
მთავარი ფუნქციების უმეტესობა უფასოა და ღია წყაროა. ჩვენ ვცდილობთ ჰარმონიული ბალანსის დაცვას [ღია წყაროების პრინციპებსა და მდგრადობას შორის](https://github.com/usebruno/bruno/discussions/269)
|
||||
|
||||
თქვენ შეგიძლიათ შეიძინოთ [ოქროს გამოცემა](https://www.usebruno.com/pricing) ერთჯერადი გადახდით **19 დოლარად**! <br/>
|
||||
|
||||
### ინსტალაცია
|
||||
|
||||
ბრუნო ხელმისაწვდომია როგორც ბინარული ჩამოტვირთვა [ჩვენ的网站上](https://www.usebruno.com/downloads) Mac-ის, Windows-ისა და Linux-ისთვის.
|
||||
|
||||
თქვენ ასევე შეგიძლიათ დააინსტალიროთ ბრუნო პაკეტის მენეჯერების საშუალებით, როგორიცაა Homebrew, Chocolatey, Scoop, Snap, Flatpak და Apt.
|
||||
|
||||
```sh
|
||||
# Mac-ზე Homebrew-ს საშუალებით
|
||||
brew install bruno
|
||||
|
||||
# Windows-ზე Chocolatey-ს საშუალებით
|
||||
choco install bruno
|
||||
|
||||
# Windows-ზე Scoop-ის საშუალებით
|
||||
scoop bucket add extras
|
||||
scoop install bruno
|
||||
|
||||
# Windows-ზე winget-ის საშუალებით
|
||||
winget install Bruno.Bruno
|
||||
|
||||
# Linux-ზე Snap-ის საშუალებით
|
||||
snap install bruno
|
||||
|
||||
# Linux-ზე Flatpak-ის საშუალებით
|
||||
flatpak install com.usebruno.Bruno
|
||||
|
||||
# Linux-ზე Apt-ის საშუალებით
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
sudo gpg --no-default-keyring --keyring /etc/apt/keyrings/bruno.gpg --keyserver keyserver.ubuntu.com --recv-keys 9FA6017ECABE0266
|
||||
|
||||
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/bruno.gpg] http://debian.usebruno.com/ bruno stable" | sudo tee /etc/apt/sources.list.d/bruno.list
|
||||
|
||||
sudo apt update
|
||||
sudo apt install bruno
|
||||
```
|
||||
|
||||
### პლატფორმებს შორის მუშაობა 🖥️
|
||||
|
||||
 <br /><br />
|
||||
|
||||
### თანამშრომლობა Git-ის საშუალებით 👩💻🧑💻
|
||||
|
||||
ან ნებისმიერი ვერსიის კონტროლის სისტემის საშუალებით
|
||||
|
||||
 <br /><br />
|
||||
|
||||
### სპონსორები
|
||||
|
||||
#### ოქროს სპონსორები
|
||||
|
||||
<img src="../../assets/images/sponsors/samagata.png" width="150"/>
|
||||
|
||||
#### ვერცხლის სპონსორები
|
||||
|
||||
<img src="../../assets/images/sponsors/commit-company.png" width="70"/>
|
||||
|
||||
#### ბრინჯის სპონსორები
|
||||
|
||||
<a href="https://zuplo.link/bruno">
|
||||
<img src="../../assets/images/sponsors/zuplo.png" width="120"/>
|
||||
</a>
|
||||
|
||||
### მნიშვნელოვანი ბმულები 📌
|
||||
|
||||
- [ჩვენი გრძელვადიანი ხედვა](https://github.com/usebruno/bruno/discussions/269)
|
||||
- [გეგმა](https://github.com/usebruno/bruno/discussions/384)
|
||||
- [დოკუმენტაცია](https://docs.usebruno.com)
|
||||
- [Stack Overflow](https://stackoverflow.com/questions/tagged/bruno)
|
||||
- [ვებსაიტი](https://www.usebruno.com)
|
||||
- [ფასები](https://www.usebruno.com/pricing)
|
||||
- [დამატება](https://www.usebruno.com/downloads)
|
||||
- [GitHub სპონსორები](https://github.com/sponsors/helloanoop).
|
||||
|
||||
### ვიტრინა 🎥
|
||||
|
||||
- [მოწონებები](https://github.com/usebruno/bruno/discussions/343)
|
||||
- [მეცნიერების ჰაბი](https://github.com/usebruno/bruno/discussions/386)
|
||||
- [Scriptmania](https://github.com/usebruno/bruno/discussions/385)
|
||||
|
||||
### მხარდაჭერა ❤️
|
||||
|
||||
თუ გიყვართ ბრუნო და გინდათ მხარი დაუჭიროთ ჩვენს ღია წყაროების მუშაობას, გაითვალისწინეთ ჩვენი დახმარება [GitHub სპონსორების საშუალებით](https://github.com/sponsors/helloanoop).
|
||||
|
||||
### გააზიარეთ მოწმობები 📣
|
||||
|
||||
თუ ბრუნო დაგეხმარათ თქვენს სამუშაოში და გუნდებში, გთხოვთ, არ დაგავიწყდეთ ჩვენი [მოწონებების გაზიარება ჩვენს GitHub განხილვაში](https://github.com/usebruno/bruno/discussions/343)
|
||||
|
||||
### ახალი პაკეტის მენეჯერებში გამოქვეყნება
|
||||
|
||||
იხილეთ [აქ](../../publishing.md) მეტი ინფორმაციისათვის.
|
||||
|
||||
### დაინტერესდით 🌐
|
||||
|
||||
[𝕎 (Twitter)](https://twitter.com/use_bruno) <br />
|
||||
[ვებსაიტი](https://www.usebruno.com) <br />
|
||||
[Discord](https://discord.com/invite/KgcZUncpjq) <br />
|
||||
[LinkedIn](https://www.linkedin.com/company/usebruno)
|
||||
|
||||
### სავაჭრო ნიშანი
|
||||
|
||||
**სახელი**
|
||||
|
||||
`ბრუნო` არის სავაჭრო ნიშანი, რომელსაც ფლობს [ანუპ მ. დ.](https://www.helloanoop.com/)
|
||||
|
||||
**ლოგო**
|
||||
|
||||
ლოგო არის [OpenMoji](https://openmoji.org/library/emoji-1F436/) სურათებიდან. ლიცენზია: CC [BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)
|
||||
|
||||
### თანამშრომლობა 👩💻🧑💻
|
||||
|
||||
მიხარია, რომ დაინტერესებული ხართ ბრუნოს გაუმჯობესებით. გთხოვთ, გადახედეთ [თანამშრომლობის სახელმძღვანელოს](../../contributing.md)
|
||||
|
||||
თუნდაც ვერ მოახერხოთ კოდის საშუალებით კონტრიბუცია, ნუ ინანებთ პრობლემების და ფუნქციის მოთხოვნების ჩაწერას, რომლებიც უნდა განხორციელდეს თქვენი შემთხვევის გადასაჭრელად.
|
||||
|
||||
### ავტორები
|
||||
|
||||
<div align="center">
|
||||
<a href="https://github.com/usebruno/bruno/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=usebruno/bruno" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
### ლიცენზია 📄
|
||||
|
||||
[MIT](../../license.md)
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno는 새롭고 혁신적인 API 클라이언트로, Postman과 유사한 툴들을 혁신하는 것을 목표로 합니다.
|
||||
|
||||
|
||||
157
docs/readme/readme_nl.md
Normal file
157
docs/readme/readme_nl.md
Normal file
@@ -0,0 +1,157 @@
|
||||
<br />
|
||||
<img src="../../assets/images/logo-transparent.png" width="80"/>
|
||||
|
||||
### Bruno - Open source IDE voor het verkennen en testen van API's.
|
||||
|
||||
[](https://badge.fury.io/gh/usebruno%bruno)
|
||||
[](https://github.com/usebruno/bruno/actions/workflows/tests.yml)
|
||||
[](https://github.com/usebruno/bruno/pulse)
|
||||
[](https://twitter.com/use_bruno)
|
||||
[](https://www.usebruno.com)
|
||||
[](https://www.usebruno.com/downloads)
|
||||
|
||||
[English](../../readme.md) | [Українська](docs/readme/readme_ua.md) | [Русский](docs/readme/readme_ru.md) | [Türkçe](docs/readme/readme_tr.md) | [Deutsch](docs/readme/readme_de.md) | ** Nederlands ** | [Français](docs/readme/readme_fr.md) | [Português (BR)](docs/readme/readme_pt_br.md) | [한국어](docs/readme/readme_kr.md) | [বাংলা](docs/readme/readme_bn.md) | [Español](docs/readme/readme_es.md) | [Italiano](docs/readme/readme_it.md) | [Română](docs/readme/readme_ro.md) | [Polski](docs/readme/readme_pl.md) | [简体中文](docs/readme/readme_cn.md) | [正體中文](docs/readme/readme_zhtw.md) | [العربية](docs/readme/readme_ar.md) | [日本語](docs/readme/readme_ja.md)
|
||||
|
||||
Bruno is een nieuwe en innovatieve API-client, gericht op het revolutioneren van de status quo die wordt vertegenwoordigd door Postman en vergelijkbare tools.
|
||||
|
||||
Bruno slaat je collecties direct op in een map op je bestandssysteem. We gebruiken een platte tekst opmaaktaal, Bru, om informatie over API-verzoeken op te slaan.
|
||||
|
||||
Je kunt Git of elke versiebeheertool naar keuze gebruiken om samen te werken aan je API-collecties.
|
||||
|
||||
Bruno is uitsluitend offline. Er zijn geen plannen om ooit cloud-synchronisatie aan Bruno toe te voegen. We waarderen je gegevensprivacy en geloven dat deze op je apparaat moet blijven. Lees onze langetermijnvisie [hier](https://github.com/usebruno/bruno/discussions/269)
|
||||
|
||||
[Download Bruno](https://www.usebruno.com/downloads)
|
||||
|
||||
📢 Bekijk onze recente presentatie op de India FOSS 3.0 Conference [hier](https://www.youtube.com/watch?v=7bSMFpbcPiY)
|
||||
|
||||
 <br /><br />
|
||||
|
||||
### Golden Edition ✨
|
||||
|
||||
De meeste van onze functies zijn gratis en open source.
|
||||
We streven naar een harmonieuze balans tussen [open-source principes en duurzaamheid](https://github.com/usebruno/bruno/discussions/269).
|
||||
|
||||
Je kunt de [Golden Edition](https://www.usebruno.com/pricing) kopen voor een eenmalige betaling van **$19**! <br/>
|
||||
|
||||
### Installatie
|
||||
|
||||
Bruno is beschikbaar als binaire download [op onze website](https://www.usebruno.com/downloads) voor Mac, Windows en Linux.
|
||||
|
||||
Je kunt Bruno ook installeren via pakketbeheerders zoals Homebrew, Chocolatey, Scoop, Snap, Flatpak en Apt.
|
||||
|
||||
```sh
|
||||
# Op Mac via Homebrew
|
||||
brew install bruno
|
||||
|
||||
# Op Windows via Chocolatey
|
||||
choco install bruno
|
||||
|
||||
# Op Windows via Scoop
|
||||
scoop bucket add extras
|
||||
scoop install bruno
|
||||
|
||||
# Op Windows via winget
|
||||
winget install Bruno.Bruno
|
||||
|
||||
# Op Linux via Snap
|
||||
snap install bruno
|
||||
|
||||
# Op Linux via Flatpak
|
||||
flatpak install com.usebruno.Bruno
|
||||
|
||||
# Op Linux via Apt
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
sudo gpg --no-default-keyring --keyring /etc/apt/keyrings/bruno.gpg --keyserver keyserver.ubuntu.com --recv-keys 9FA6017ECABE0266
|
||||
|
||||
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/bruno.gpg] http://debian.usebruno.com/ bruno stable" | sudo tee /etc/apt/sources.list.d/bruno.list
|
||||
|
||||
sudo apt update
|
||||
sudo apt install bruno
|
||||
```
|
||||
|
||||
### Draai op meerdere platformen 🖥️
|
||||
|
||||
 <br /><br />
|
||||
|
||||
### Samenwerken via Git 👩💻🧑💻
|
||||
|
||||
Of elk versiebeheersysteem naar keuze
|
||||
|
||||
 <br /><br />
|
||||
|
||||
### Sponsors
|
||||
|
||||
#### Gouden Sponsors
|
||||
|
||||
<img src="../../assets/images/sponsors/samagata.png" width="150"/>
|
||||
|
||||
#### Zilveren Sponsors
|
||||
|
||||
<img src="../../assets/images/sponsors/commit-company.png" width="70"/>
|
||||
|
||||
#### Bronzen Sponsors
|
||||
|
||||
<a href="https://zuplo.link/bruno">
|
||||
<img src="../../assets/images/sponsors/zuplo.png" width="120"/>
|
||||
</a>
|
||||
|
||||
### Belangrijke Links 📌
|
||||
|
||||
- [Onze Langetermijnvisie](https://github.com/usebruno/bruno/discussions/269)
|
||||
- [Roadmap](https://github.com/usebruno/bruno/discussions/384)
|
||||
- [Documentatie](https://docs.usebruno.com)
|
||||
- [Stack Overflow](https://stackoverflow.com/questions/tagged/bruno)
|
||||
- [Website](https://www.usebruno.com)
|
||||
- [Prijzen](https://www.usebruno.com/pricing)
|
||||
- [Download](https://www.usebruno.com/downloads)
|
||||
- [GitHub Sponsors](https://github.com/sponsors/helloanoop)
|
||||
|
||||
### Showcase 🎥
|
||||
|
||||
- [Getuigenissen](https://github.com/usebruno/bruno/discussions/343)
|
||||
- [Kenniscentrum](https://github.com/usebruno/bruno/discussions/386)
|
||||
- [Scriptmania](https://github.com/usebruno/bruno/discussions/385)
|
||||
|
||||
### Ondersteuning ❤️
|
||||
|
||||
Als je Bruno leuk vindt en ons open-source werk wilt ondersteunen, overweeg dan om ons te sponsoren via [GitHub Sponsors](https://github.com/sponsors/helloanoop).
|
||||
|
||||
### Deel Getuigenissen 📣
|
||||
|
||||
Als Bruno je heeft geholpen op je werk en in je teams, deel dan je [getuigenissen op onze GitHub-discussie](https://github.com/usebruno/bruno/discussions/343).
|
||||
|
||||
|
||||
### Blijf in contact 🌐
|
||||
|
||||
[𝕏 (Twitter)](https://twitter.com/use_bruno) <br />
|
||||
[Website](https://www.usebruno.com) <br />
|
||||
[Discord](https://discord.com/invite/KgcZUncpjq) <br />
|
||||
[LinkedIn](https://www.linkedin.com/company/usebruno)
|
||||
|
||||
### Handelsmerk
|
||||
|
||||
**Naam**
|
||||
|
||||
`Bruno` is een handelsmerk in bezit van [Anoop M D](https://www.helloanoop.com/).
|
||||
|
||||
**Logo**
|
||||
|
||||
Het logo is afkomstig van [OpenMoji](https://openmoji.org/library/emoji-1F436/). Licentie: CC [BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)
|
||||
|
||||
### Bijdragen 👩💻🧑💻
|
||||
|
||||
Ik ben blij dat je Bruno wilt verbeteren. Bekijk de [bijdragegids](contributing.md).
|
||||
|
||||
Zelfs als je geen bijdragen via code kunt leveren, aarzel dan niet om bugs en functieverzoeken in te dienen die moeten worden geïmplementeerd om jouw gebruiksscenario op te lossen.
|
||||
|
||||
### Auteurs
|
||||
|
||||
<div align="center">
|
||||
<a href="https://github.com/usebruno/bruno/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=usebruno/bruno" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
### Licentie 📄
|
||||
|
||||
[MIT](../../license.md)
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno to nowy i innowacyjny klient API, którego celem jest zrewolucjonizowanie status quo reprezentowanego przez narzędzia takie jak Postman.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno é um novo e inovador cliente de API, com o objetivo de revolucionar o status quo representado por ferramentas como o Postman e outras semelhantes.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno este un client API nou și inovativ, care vizează să revoluționeze status quo-ul reprezentat de Postman și alte instrumente similare.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno - новый и инновационный клиент API, направленный на революцию в установившейся ситуации, представленной Postman и подобными инструментами.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno, Postman ve benzeri araçlar tarafından temsil edilen statükoda devrim yaratmayı amaçlayan yeni ve yenilikçi bir API istemcisidir.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| [正體中文](./readme_zhtw.md)
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno це новий та іноваційний API клієнт, націлений на революційну зміну статус кво, запровадженого інструментами на кшталт Postman.
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
| **正體中文**
|
||||
| [العربية](./readme_ar.md)
|
||||
| [日本語](./readme_ja.md)
|
||||
| [ქართული](./readme_ka.md)
|
||||
|
||||
Bruno 是一個全新且有創新性的 API 用戶端,目的在徹底改變以 Postman 和其他類似工具的現況。
|
||||
|
||||
|
||||
33334
package-lock.json
generated
33334
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
package.json
11
package.json
@@ -20,14 +20,18 @@
|
||||
"@jest/globals": "^29.2.0",
|
||||
"@playwright/test": "^1.27.1",
|
||||
"@types/jest": "^29.5.11",
|
||||
"concurrently": "^8.2.2",
|
||||
"fs-extra": "^11.1.1",
|
||||
"husky": "^8.0.3",
|
||||
"jest": "^29.2.0",
|
||||
"pretty-quick": "^3.1.3",
|
||||
"randomstring": "^1.2.2",
|
||||
"rimraf": "^6.0.1",
|
||||
"ts-jest": "^29.0.5"
|
||||
},
|
||||
"scripts": {
|
||||
"setup": "node ./scripts/setup.js",
|
||||
"dev": "concurrently --kill-others \"npm run dev:web\" \"npm run dev:electron\"",
|
||||
"dev:web": "npm run dev --workspace=packages/bruno-app",
|
||||
"build:web": "npm run build --workspace=packages/bruno-app",
|
||||
"prettier:web": "npm run prettier --workspace=packages/bruno-app",
|
||||
@@ -47,12 +51,7 @@
|
||||
"test:prettier:web": "npm run test:prettier --workspace=packages/bruno-app",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
|
||||
"overrides": {
|
||||
"rollup": "3.2.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"json-bigint": "^1.0.0",
|
||||
"lossless-json": "^4.0.1"
|
||||
"rollup": "3.29.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"presets": ["next/babel"],
|
||||
"presets": ["@babel/preset-env"],
|
||||
"plugins": [["styled-components", { "ssr": true }]]
|
||||
}
|
||||
4
packages/bruno-app/.gitignore
vendored
4
packages/bruno-app/.gitignore
vendored
@@ -31,4 +31,6 @@ yarn-error.log*
|
||||
|
||||
# next.js
|
||||
.next/
|
||||
out/
|
||||
dist/
|
||||
|
||||
.env
|
||||
16
packages/bruno-app/jest.config.js
Normal file
16
packages/bruno-app/jest.config.js
Normal file
@@ -0,0 +1,16 @@
|
||||
module.exports = {
|
||||
rootDir: '.',
|
||||
moduleNameMapper: {
|
||||
'^assets/(.*)$': '<rootDir>/src/assets/$1',
|
||||
'^components/(.*)$': '<rootDir>/src/components/$1',
|
||||
'^hooks/(.*)$': '<rootDir>/src/hooks/$1',
|
||||
'^themes/(.*)$': '<rootDir>/src/themes/$1',
|
||||
'^api/(.*)$': '<rootDir>/src/api/$1',
|
||||
'^pageComponents/(.*)$': '<rootDir>/src/pageComponents/$1',
|
||||
'^providers/(.*)$': '<rootDir>/src/providers/$1',
|
||||
'^utils/(.*)$': '<rootDir>/src/utils/$1'
|
||||
},
|
||||
clearMocks: true,
|
||||
moduleDirectories: ['node_modules', 'src'],
|
||||
testEnvironment: 'node'
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
module.exports = {
|
||||
reactStrictMode: false,
|
||||
publicRuntimeConfig: {
|
||||
CI: process.env.CI,
|
||||
PLAYWRIGHT: process.env.PLAYWRIGHT,
|
||||
ENV: process.env.ENV
|
||||
},
|
||||
webpack: (config, { isServer }) => {
|
||||
// Fixes npm packages that depend on `fs` module
|
||||
if (!isServer) {
|
||||
config.resolve.fallback.fs = false;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
};
|
||||
@@ -3,70 +3,70 @@
|
||||
"version": "0.3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "cross-env ENV=dev next dev -p 3000",
|
||||
"build": "next build && next export",
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"dev": "rsbuild dev",
|
||||
"build": "rsbuild build -m production",
|
||||
"preview": "rsbuild preview",
|
||||
"test": "jest",
|
||||
"test:prettier": "prettier --check \"./src/**/*.{js,jsx,json,ts,tsx}\"",
|
||||
"prettier": "prettier --write \"./src/**/*.{js,jsx,json,ts,tsx}\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||
"@babel/preset-env": "^7.26.0",
|
||||
"@fontsource/inter": "^5.0.15",
|
||||
"@prantlf/jsonlint": "^16.0.0",
|
||||
"@reduxjs/toolkit": "^1.8.0",
|
||||
"@tabler/icons": "^1.46.0",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@usebruno/common": "0.1.0",
|
||||
"@usebruno/graphql-docs": "0.1.0",
|
||||
"@usebruno/schema": "0.7.0",
|
||||
"axios": "^1.5.1",
|
||||
"axios": "1.7.5",
|
||||
"classnames": "^2.3.1",
|
||||
"codemirror": "5.65.2",
|
||||
"codemirror-graphql": "1.2.5",
|
||||
"cookie": "^0.6.0",
|
||||
"codemirror-graphql": "2.1.1",
|
||||
"cookie": "0.7.1",
|
||||
"escape-html": "^1.0.3",
|
||||
"file": "^0.2.2",
|
||||
"file-dialog": "^0.0.8",
|
||||
"file-saver": "^2.0.5",
|
||||
"formik": "^2.2.9",
|
||||
"github-markdown-css": "^5.2.0",
|
||||
"graphiql": "^1.5.9",
|
||||
"graphiql": "3.7.1",
|
||||
"graphql": "^16.6.0",
|
||||
"graphql-request": "^3.7.0",
|
||||
"httpsnippet": "^3.0.1",
|
||||
"httpsnippet": "^3.0.6",
|
||||
"i18next": "24.1.2",
|
||||
"idb": "^7.0.0",
|
||||
"immer": "^9.0.15",
|
||||
"jsesc": "^3.0.2",
|
||||
"jshint": "^2.13.6",
|
||||
"json5": "^2.2.3",
|
||||
"jsonc-parser": "^3.2.1",
|
||||
"jsonlint": "^1.6.3",
|
||||
"jsonpath-plus": "^7.2.0",
|
||||
"jsonpath-plus": "10.2.0",
|
||||
"know-your-http-well": "^0.5.0",
|
||||
"lodash": "^4.17.21",
|
||||
"markdown-it": "^13.0.2",
|
||||
"markdown-it-replace-link": "^1.2.0",
|
||||
"mousetrap": "^1.6.5",
|
||||
"nanoid": "3.3.4",
|
||||
"next": "12.3.3",
|
||||
"nanoid": "3.3.8",
|
||||
"path": "^0.12.7",
|
||||
"pdfjs-dist": "^3.11.174",
|
||||
"pdfjs-dist": "4.4.168",
|
||||
"platform": "^1.3.6",
|
||||
"posthog-node": "^2.1.0",
|
||||
"posthog-node": "4.2.1",
|
||||
"prettier": "^2.7.1",
|
||||
"qs": "^6.11.0",
|
||||
"query-string": "^7.0.1",
|
||||
"react": "18.2.0",
|
||||
"react": "19.0.0",
|
||||
"react-copy-to-clipboard": "^5.1.0",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-github-btn": "^1.4.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-hot-toast": "^2.4.0",
|
||||
"react-i18next": "^15.0.1",
|
||||
"react-inspector": "^6.0.2",
|
||||
"react-pdf": "^7.5.1",
|
||||
"react-redux": "^7.2.6",
|
||||
"react-pdf": "9.1.1",
|
||||
"react-player": "^2.16.0",
|
||||
"react-redux": "^7.2.9",
|
||||
"react-tooltip": "^5.5.2",
|
||||
"sass": "^1.46.0",
|
||||
"strip-json-comments": "^5.0.1",
|
||||
@@ -78,20 +78,21 @@
|
||||
"yup": "^0.32.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.16.0",
|
||||
"@babel/plugin-transform-spread": "^7.16.7",
|
||||
"@babel/preset-env": "^7.16.4",
|
||||
"@babel/preset-react": "^7.16.0",
|
||||
"@babel/runtime": "^7.16.3",
|
||||
"autoprefixer": "^10.4.17",
|
||||
"babel-loader": "^8.2.3",
|
||||
"@rsbuild/core": "^1.1.2",
|
||||
"@rsbuild/plugin-babel": "^1.0.3",
|
||||
"@rsbuild/plugin-node-polyfill": "^1.2.0",
|
||||
"@rsbuild/plugin-react": "^1.0.7",
|
||||
"@rsbuild/plugin-sass": "^1.1.0",
|
||||
"@rsbuild/plugin-styled-components": "1.1.0",
|
||||
"autoprefixer": "10.4.20",
|
||||
"babel-plugin-react-compiler": "19.0.0-beta-a7bf2bd-20241110",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^6.5.1",
|
||||
"css-loader": "7.1.2",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-loader": "^3.0.1",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"mini-css-extract-plugin": "^2.4.5",
|
||||
"postcss": "^8.4.35",
|
||||
"postcss": "8.4.47",
|
||||
"style-loader": "^3.3.1",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"webpack": "^5.64.4",
|
||||
|
||||
39
packages/bruno-app/rsbuild.config.mjs
Normal file
39
packages/bruno-app/rsbuild.config.mjs
Normal file
@@ -0,0 +1,39 @@
|
||||
import { defineConfig } from '@rsbuild/core';
|
||||
import { pluginReact } from '@rsbuild/plugin-react';
|
||||
import { pluginBabel } from '@rsbuild/plugin-babel';
|
||||
import { pluginStyledComponents } from '@rsbuild/plugin-styled-components';
|
||||
import { pluginSass } from '@rsbuild/plugin-sass';
|
||||
import { pluginNodePolyfill } from '@rsbuild/plugin-node-polyfill'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
pluginNodePolyfill(),
|
||||
pluginReact(),
|
||||
pluginStyledComponents(),
|
||||
pluginSass(),
|
||||
pluginBabel({
|
||||
include: /\.(?:js|jsx|tsx)$/,
|
||||
babelLoaderOptions(opts) {
|
||||
opts.plugins?.unshift('babel-plugin-react-compiler');
|
||||
}
|
||||
})
|
||||
],
|
||||
source: {
|
||||
tsconfigPath: './jsconfig.json', // Specifies the path to the JavaScript/TypeScript configuration file
|
||||
},
|
||||
html: {
|
||||
title: 'Bruno'
|
||||
},
|
||||
tools: {
|
||||
rspack: {
|
||||
module: {
|
||||
parser: {
|
||||
javascript: {
|
||||
// This loads the JavaScript contents from a library along with the main JavaScript bundle.
|
||||
dynamicImportMode: "eager",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
});
|
||||
@@ -5,15 +5,49 @@ const StyledWrapper = styled.div`
|
||||
background: ${(props) => props.theme.codemirror.bg};
|
||||
border: solid 1px ${(props) => props.theme.codemirror.border};
|
||||
font-family: ${(props) => (props.font ? props.font : 'default')};
|
||||
font-size: ${(props) => (props.fontSize ? `${props.fontSize}px` : 'inherit')};
|
||||
line-break: anywhere;
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
/* Removes the glow outline around the folded json */
|
||||
.CodeMirror-foldmarker {
|
||||
text-shadow: none;
|
||||
color: ${(props) => props.theme.textLink};
|
||||
background: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-overlayscroll-horizontal div,
|
||||
.CodeMirror-overlayscroll-vertical div {
|
||||
background: #d2d7db;
|
||||
}
|
||||
|
||||
.CodeMirror-dialog {
|
||||
overflow: visible;
|
||||
input {
|
||||
background: transparent;
|
||||
border: 1px solid #d3d6db;
|
||||
outline: none;
|
||||
border-radius: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
#search-results-count {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: calc(100% + 1px);
|
||||
right: 0;
|
||||
border-width: 0 0 1px 1px;
|
||||
border-style: solid;
|
||||
border-color: ${(props) => props.theme.codemirror.border};
|
||||
padding: 0.1em 0.8em;
|
||||
background-color: ${(props) => props.theme.codemirror.bg};
|
||||
color: rgb(102, 102, 102);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
textarea.cm-editor {
|
||||
position: relative;
|
||||
}
|
||||
@@ -50,6 +84,18 @@ const StyledWrapper = styled.div`
|
||||
.cm-variable-invalid {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.CodeMirror-search-hint {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.cm-s-default span.cm-property {
|
||||
color: #1f61a0 !important;
|
||||
}
|
||||
|
||||
.cm-s-default span.cm-variable {
|
||||
color: #397d13 !important;
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledWrapper;
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { getEnvironmentVariables } from 'utils/collections';
|
||||
import { isEqual, escapeRegExp } from 'lodash';
|
||||
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import jsonlint from 'jsonlint';
|
||||
import * as jsonlint from '@prantlf/jsonlint';
|
||||
import { JSHINT } from 'jshint';
|
||||
import stripJsonComments from 'strip-json-comments';
|
||||
import { getAllVariables } from 'utils/collections';
|
||||
|
||||
let CodeMirror;
|
||||
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
||||
const SERVER_RENDERED = typeof window === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
||||
const TAB_SIZE = 2;
|
||||
|
||||
if (!SERVER_RENDERED) {
|
||||
@@ -55,18 +55,32 @@ if (!SERVER_RENDERED) {
|
||||
'req.setMaxRedirects(maxRedirects)',
|
||||
'req.getTimeout()',
|
||||
'req.setTimeout(timeout)',
|
||||
'req.getExecutionMode()',
|
||||
'bru',
|
||||
'bru.cwd()',
|
||||
'bru.getEnvName(key)',
|
||||
'bru.getEnvName()',
|
||||
'bru.getProcessEnv(key)',
|
||||
'bru.hasEnvVar(key)',
|
||||
'bru.getEnvVar(key)',
|
||||
'bru.getFolderVar(key)',
|
||||
'bru.getCollectionVar(key)',
|
||||
'bru.setEnvVar(key,value)',
|
||||
'bru.deleteEnvVar(key)',
|
||||
'bru.hasVar(key)',
|
||||
'bru.getVar(key)',
|
||||
'bru.setVar(key,value)',
|
||||
'bru.deleteVar(key)',
|
||||
'bru.setNextRequest(requestName)'
|
||||
'bru.deleteAllVars()',
|
||||
'bru.setNextRequest(requestName)',
|
||||
'req.disableParsingResponseJson()',
|
||||
'bru.getRequestVar(key)',
|
||||
'bru.sleep(ms)',
|
||||
'bru.getGlobalEnvVar(key)',
|
||||
'bru.setGlobalEnvVar(key, value)',
|
||||
'bru.runner',
|
||||
'bru.runner.setNextRequest(requestName)',
|
||||
'bru.runner.skipRequest()',
|
||||
'bru.runner.stopExecution()'
|
||||
];
|
||||
CodeMirror.registerHelper('hint', 'brunoJS', (editor, options) => {
|
||||
const cursor = editor.getCursor();
|
||||
@@ -88,7 +102,7 @@ if (!SERVER_RENDERED) {
|
||||
if (curWordBru) {
|
||||
hintWords.forEach((h) => {
|
||||
if (h.includes('.') == curWordBru.includes('.') && h.startsWith(curWordBru)) {
|
||||
result.list.push(curWordBru.includes('.') ? h.split('.')[1] : h);
|
||||
result.list.push(curWordBru.includes('.') ? h.split('.')?.at(-1) : h);
|
||||
}
|
||||
});
|
||||
result.list?.sort();
|
||||
@@ -109,6 +123,7 @@ export default class CodeEditor extends React.Component {
|
||||
// unnecessary updates during the update lifecycle.
|
||||
this.cachedValue = props.value || '';
|
||||
this.variables = {};
|
||||
this.searchResultsCountElementId = 'search-results-count';
|
||||
|
||||
this.lintOptions = {
|
||||
esversion: 11,
|
||||
@@ -155,8 +170,16 @@ export default class CodeEditor extends React.Component {
|
||||
this.props.onSave();
|
||||
}
|
||||
},
|
||||
'Cmd-F': 'findPersistent',
|
||||
'Ctrl-F': 'findPersistent',
|
||||
'Cmd-F': (cm) => {
|
||||
cm.execCommand('findPersistent');
|
||||
this._bindSearchHandler();
|
||||
this._appendSearchResultsCount();
|
||||
},
|
||||
'Ctrl-F': (cm) => {
|
||||
cm.execCommand('findPersistent');
|
||||
this._bindSearchHandler();
|
||||
this._appendSearchResultsCount();
|
||||
},
|
||||
'Cmd-H': 'replace',
|
||||
'Ctrl-H': 'replace',
|
||||
Tab: function (cm) {
|
||||
@@ -171,32 +194,8 @@ export default class CodeEditor extends React.Component {
|
||||
'Cmd-Y': 'foldAll',
|
||||
'Ctrl-I': 'unfoldAll',
|
||||
'Cmd-I': 'unfoldAll',
|
||||
'Cmd-/': (cm) => {
|
||||
// comment/uncomment every selected line(s)
|
||||
const selections = cm.listSelections();
|
||||
selections.forEach((range) => {
|
||||
for (let i = range.from().line; i <= range.to().line; i++) {
|
||||
const selectedLine = cm.getLine(i);
|
||||
// if commented line, remove comment
|
||||
if (selectedLine.trim().startsWith('//')) {
|
||||
cm.replaceRange(
|
||||
selectedLine.replace(/^(\s*)\/\/\s?/, '$1'),
|
||||
{ line: i, ch: 0 },
|
||||
{ line: i, ch: selectedLine.length }
|
||||
);
|
||||
continue;
|
||||
}
|
||||
// otherwise add comment
|
||||
cm.replaceRange(
|
||||
selectedLine.search(/\S|$/) >= TAB_SIZE
|
||||
? ' '.repeat(TAB_SIZE) + '// ' + selectedLine.trim()
|
||||
: '// ' + selectedLine,
|
||||
{ line: i, ch: 0 },
|
||||
{ line: i, ch: selectedLine.length }
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
'Ctrl-/': 'toggleComment',
|
||||
'Cmd-/': 'toggleComment'
|
||||
},
|
||||
foldOptions: {
|
||||
widget: (from, to) => {
|
||||
@@ -233,17 +232,20 @@ export default class CodeEditor extends React.Component {
|
||||
return found;
|
||||
}
|
||||
let jsonlint = window.jsonlint.parser || window.jsonlint;
|
||||
jsonlint.parseError = function (str, hash) {
|
||||
let loc = hash.loc;
|
||||
found.push({
|
||||
from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
|
||||
to: CodeMirror.Pos(loc.last_line - 1, loc.last_column),
|
||||
message: str
|
||||
});
|
||||
};
|
||||
try {
|
||||
jsonlint.parse(stripJsonComments(text.replace(/(?<!"[^":{]*){{[^}]*}}(?![^"},]*")/g, '1')));
|
||||
} catch (e) {}
|
||||
} catch (error) {
|
||||
const { message, location } = error;
|
||||
const line = location?.start?.line;
|
||||
const column = location?.start?.column;
|
||||
if (line && column) {
|
||||
found.push({
|
||||
from: CodeMirror.Pos(line - 1, column),
|
||||
to: CodeMirror.Pos(line - 1, column),
|
||||
message
|
||||
});
|
||||
}
|
||||
}
|
||||
return found;
|
||||
});
|
||||
if (editor) {
|
||||
@@ -260,9 +262,9 @@ export default class CodeEditor extends React.Component {
|
||||
while (end < currentLine.length && /[^{}();\s\[\]\,]/.test(currentLine.charAt(end))) ++end;
|
||||
while (start && /[^{}();\s\[\]\,]/.test(currentLine.charAt(start - 1))) --start;
|
||||
let curWord = start != end && currentLine.slice(start, end);
|
||||
//Qualify if autocomplete will be shown
|
||||
// Qualify if autocomplete will be shown
|
||||
if (
|
||||
/^(?!Shift|Tab|Enter|Escape|ArrowUp|ArrowDown|ArrowLeft|ArrowRight|\s)\w*/.test(event.key) &&
|
||||
/^(?!Shift|Tab|Enter|Escape|ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Meta|Alt|Home|End\s)\w*/.test(event.key) &&
|
||||
curWord.length > 0 &&
|
||||
!/\/\/|\/\*|.*{{|`[^$]*{|`[^{]*$/.test(currentLine.slice(0, end)) &&
|
||||
/(?<!\d)[a-zA-Z\._]$/.test(curWord)
|
||||
@@ -291,7 +293,7 @@ export default class CodeEditor extends React.Component {
|
||||
}
|
||||
|
||||
if (this.editor) {
|
||||
let variables = getEnvironmentVariables(this.props.collection);
|
||||
let variables = getAllVariables(this.props.collection, this.props.item);
|
||||
if (!isEqual(variables, this.variables)) {
|
||||
this.addOverlay();
|
||||
}
|
||||
@@ -308,6 +310,8 @@ export default class CodeEditor extends React.Component {
|
||||
this.editor.off('change', this._onEdit);
|
||||
this.editor = null;
|
||||
}
|
||||
|
||||
this._unbindSearchHandler();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -316,9 +320,10 @@ export default class CodeEditor extends React.Component {
|
||||
}
|
||||
return (
|
||||
<StyledWrapper
|
||||
className="h-full w-full flex flex-col relative"
|
||||
className="h-full w-full flex flex-col relative graphiql-container"
|
||||
aria-label="Code Editor"
|
||||
font={this.props.font}
|
||||
fontSize={this.props.fontSize}
|
||||
ref={(node) => {
|
||||
this._node = node;
|
||||
}}
|
||||
@@ -328,7 +333,7 @@ export default class CodeEditor extends React.Component {
|
||||
|
||||
addOverlay = () => {
|
||||
const mode = this.props.mode || 'application/ld+json';
|
||||
let variables = getEnvironmentVariables(this.props.collection);
|
||||
let variables = getAllVariables(this.props.collection, this.props.item);
|
||||
this.variables = variables;
|
||||
|
||||
defineCodeMirrorBrunoVariablesMode(variables, mode);
|
||||
@@ -344,4 +349,63 @@ export default class CodeEditor extends React.Component {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind handler to search input to count number of search results
|
||||
*/
|
||||
_bindSearchHandler = () => {
|
||||
const searchInput = document.querySelector('.CodeMirror-search-field');
|
||||
|
||||
if (searchInput) {
|
||||
searchInput.addEventListener('input', this._countSearchResults);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Unbind handler to search input to count number of search results
|
||||
*/
|
||||
_unbindSearchHandler = () => {
|
||||
const searchInput = document.querySelector('.CodeMirror-search-field');
|
||||
|
||||
if (searchInput) {
|
||||
searchInput.removeEventListener('input', this._countSearchResults);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Append search results count to search dialog
|
||||
*/
|
||||
_appendSearchResultsCount = () => {
|
||||
const dialog = document.querySelector('.CodeMirror-dialog.CodeMirror-dialog-top');
|
||||
|
||||
if (dialog) {
|
||||
const searchResultsCount = document.createElement('span');
|
||||
searchResultsCount.id = this.searchResultsCountElementId;
|
||||
dialog.appendChild(searchResultsCount);
|
||||
|
||||
this._countSearchResults();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Count search results and update state
|
||||
*/
|
||||
_countSearchResults = () => {
|
||||
let count = 0;
|
||||
|
||||
const searchInput = document.querySelector('.CodeMirror-search-field');
|
||||
|
||||
if (searchInput && searchInput.value.length > 0) {
|
||||
// Escape special characters in search input to prevent RegExp crashes. Fixes #3051
|
||||
const text = new RegExp(escapeRegExp(searchInput.value), 'gi');
|
||||
const matches = this.editor.getValue().match(text);
|
||||
count = matches ? matches.length : 0;
|
||||
}
|
||||
|
||||
const searchResultsCountElement = document.querySelector(`#${this.searchResultsCountElementId}`);
|
||||
|
||||
if (searchResultsCountElement) {
|
||||
searchResultsCountElement.innerText = `${count} results`;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
label {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.single-line-editor-wrapper {
|
||||
padding: 0.15rem 0.4rem;
|
||||
border-radius: 3px;
|
||||
border: solid 1px ${(props) => props.theme.input.border};
|
||||
background-color: ${(props) => props.theme.input.bg};
|
||||
}
|
||||
|
||||
.auth-placement-selector {
|
||||
padding: 0.5rem 0px;
|
||||
border-radius: 3px;
|
||||
border: solid 1px ${(props) => props.theme.input.border};
|
||||
background-color: ${(props) => props.theme.input.bg};
|
||||
|
||||
.dropdown {
|
||||
width: fit-content;
|
||||
|
||||
div[data-tippy-root] {
|
||||
width: fit-content;
|
||||
}
|
||||
.tippy-box {
|
||||
width: fit-content;
|
||||
max-width: none !important;
|
||||
|
||||
.tippy-content: {
|
||||
width: fit-content;
|
||||
max-width: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.auth-type-label {
|
||||
width: fit-content;
|
||||
color: ${(props) => props.theme.colors.text.yellow};
|
||||
justify-content: space-between;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: 0.2rem 0.6rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
.caret {
|
||||
color: rgb(140, 140, 140);
|
||||
fill: rgb(140 140 140);
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@@ -0,0 +1,109 @@
|
||||
import React, { useRef, forwardRef, useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import get from 'lodash/get';
|
||||
import { IconCaretDown } from '@tabler/icons';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import { useTheme } from 'providers/Theme';
|
||||
import SingleLineEditor from 'components/SingleLineEditor';
|
||||
import { updateCollectionAuth } from 'providers/ReduxStore/slices/collections';
|
||||
import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { humanizeRequestAPIKeyPlacement } from 'utils/collections';
|
||||
|
||||
const ApiKeyAuth = ({ collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { storedTheme } = useTheme();
|
||||
const dropdownTippyRef = useRef();
|
||||
const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref);
|
||||
|
||||
const apikeyAuth = get(collection, 'root.request.auth.apikey', {});
|
||||
|
||||
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
|
||||
|
||||
const Icon = forwardRef((props, ref) => {
|
||||
return (
|
||||
<div ref={ref} className="flex items-center justify-end auth-type-label select-none">
|
||||
{humanizeRequestAPIKeyPlacement(apikeyAuth?.placement)}
|
||||
<IconCaretDown className="caret ml-1 mr-1" size={14} strokeWidth={2} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const handleAuthChange = (property, value) => {
|
||||
dispatch(
|
||||
updateCollectionAuth({
|
||||
mode: 'apikey',
|
||||
collectionUid: collection.uid,
|
||||
content: {
|
||||
...apikeyAuth,
|
||||
[property]: value
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
!apikeyAuth?.placement &&
|
||||
dispatch(
|
||||
updateCollectionAuth({
|
||||
mode: 'apikey',
|
||||
collectionUid: collection.uid,
|
||||
content: {
|
||||
placement: 'header'
|
||||
}
|
||||
})
|
||||
);
|
||||
}, [apikeyAuth]);
|
||||
|
||||
return (
|
||||
<StyledWrapper className="mt-2 w-full">
|
||||
<label className="block font-medium mb-2">Key</label>
|
||||
<div className="single-line-editor-wrapper mb-2">
|
||||
<SingleLineEditor
|
||||
value={apikeyAuth.key || ''}
|
||||
theme={storedTheme}
|
||||
onSave={handleSave}
|
||||
onChange={(val) => handleAuthChange('key', val)}
|
||||
collection={collection}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="block font-medium mb-2">Value</label>
|
||||
<div className="single-line-editor-wrapper mb-2">
|
||||
<SingleLineEditor
|
||||
value={apikeyAuth.value || ''}
|
||||
theme={storedTheme}
|
||||
onSave={handleSave}
|
||||
onChange={(val) => handleAuthChange('value', val)}
|
||||
collection={collection}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="block font-medium mb-2">Add To</label>
|
||||
<div className="inline-flex items-center cursor-pointer auth-placement-selector w-fit">
|
||||
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement="bottom-end">
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
handleAuthChange('placement', 'header');
|
||||
}}
|
||||
>
|
||||
Header
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
handleAuthChange('placement', 'queryparams');
|
||||
}}
|
||||
>
|
||||
Query Params
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default ApiKeyAuth;
|
||||
@@ -52,6 +52,15 @@ const AuthMode = ({ collection }) => {
|
||||
>
|
||||
Basic Auth
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
onModeChange('wsse');
|
||||
}}
|
||||
>
|
||||
WSSE Auth
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
@@ -70,6 +79,15 @@ const AuthMode = ({ collection }) => {
|
||||
>
|
||||
Digest Auth
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
onModeChange('ntlm');
|
||||
}}
|
||||
>
|
||||
NTLM Auth
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
@@ -79,6 +97,15 @@ const AuthMode = ({ collection }) => {
|
||||
>
|
||||
Oauth2
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
onModeChange('apikey');
|
||||
}}
|
||||
>
|
||||
API Key
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={() => {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
label {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.single-line-editor-wrapper {
|
||||
max-width: 400px;
|
||||
padding: 0.15rem 0.4rem;
|
||||
border-radius: 3px;
|
||||
border: solid 1px ${(props) => props.theme.input.border};
|
||||
background-color: ${(props) => props.theme.input.bg};
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@@ -0,0 +1,110 @@
|
||||
import React from 'react';
|
||||
import get from 'lodash/get';
|
||||
import { useTheme } from 'providers/Theme';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import SingleLineEditor from 'components/SingleLineEditor';
|
||||
import { updateCollectionAuth } from 'providers/ReduxStore/slices/collections';
|
||||
import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const NTLMAuth = ({ collection }) => {
|
||||
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const { storedTheme } = useTheme();
|
||||
|
||||
const ntlmAuth = get(collection, 'root.request.auth.ntlm', {});
|
||||
|
||||
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
|
||||
|
||||
|
||||
const handleUsernameChange = (username) => {
|
||||
dispatch(
|
||||
updateCollectionAuth({
|
||||
mode: 'ntlm',
|
||||
collectionUid: collection.uid,
|
||||
content: {
|
||||
username: username,
|
||||
password: ntlmAuth.password,
|
||||
domain: ntlmAuth.domain
|
||||
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handlePasswordChange = (password) => {
|
||||
dispatch(
|
||||
updateCollectionAuth({
|
||||
mode: 'ntlm',
|
||||
collectionUid: collection.uid,
|
||||
content: {
|
||||
username: ntlmAuth.username,
|
||||
password: password,
|
||||
domain: ntlmAuth.domain
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleDomainChange = (domain) => {
|
||||
dispatch(
|
||||
updateCollectionAuth({
|
||||
mode: 'ntlm',
|
||||
collectionUid: collection.uid,
|
||||
content: {
|
||||
username: ntlmAuth.username,
|
||||
password: ntlmAuth.password,
|
||||
domain: domain
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<StyledWrapper className="mt-2 w-full">
|
||||
<label className="block font-medium mb-2">Username</label>
|
||||
<div className="single-line-editor-wrapper mb-2">
|
||||
<SingleLineEditor
|
||||
value={ntlmAuth.username || ''}
|
||||
theme={storedTheme}
|
||||
onSave={handleSave}
|
||||
onChange={(val) => handleUsernameChange(val)}
|
||||
collection={collection}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="block font-medium mb-2">Password</label>
|
||||
<div className="single-line-editor-wrapper">
|
||||
<SingleLineEditor
|
||||
value={ntlmAuth.password || ''}
|
||||
theme={storedTheme}
|
||||
onSave={handleSave}
|
||||
onChange={(val) => handlePasswordChange(val)}
|
||||
collection={collection}
|
||||
isSecret={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="block font-medium mb-2">Domain</label>
|
||||
<div className="single-line-editor-wrapper">
|
||||
<SingleLineEditor
|
||||
value={ntlmAuth.domain || ''}
|
||||
theme={storedTheme}
|
||||
onSave={handleSave}
|
||||
onChange={(val) => handleDomainChange(val)}
|
||||
collection={collection}
|
||||
/>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default NTLMAuth;
|
||||
@@ -1,5 +1,7 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div``;
|
||||
const Wrapper = styled.div`
|
||||
max-width: 800px;
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
label {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.single-line-editor-wrapper {
|
||||
padding: 0.15rem 0.4rem;
|
||||
border-radius: 3px;
|
||||
border: solid 1px ${(props) => props.theme.input.border};
|
||||
background-color: ${(props) => props.theme.input.bg};
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@@ -0,0 +1,71 @@
|
||||
import React from 'react';
|
||||
import get from 'lodash/get';
|
||||
import { useTheme } from 'providers/Theme';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import SingleLineEditor from 'components/SingleLineEditor';
|
||||
import { updateCollectionAuth } from 'providers/ReduxStore/slices/collections';
|
||||
import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const WsseAuth = ({ collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { storedTheme } = useTheme();
|
||||
|
||||
const wsseAuth = get(collection, 'root.request.auth.wsse', {});
|
||||
|
||||
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
|
||||
|
||||
const handleUserChange = (username) => {
|
||||
dispatch(
|
||||
updateCollectionAuth({
|
||||
mode: 'wsse',
|
||||
collectionUid: collection.uid,
|
||||
content: {
|
||||
username,
|
||||
password: wsseAuth.password
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handlePasswordChange = (password) => {
|
||||
dispatch(
|
||||
updateCollectionAuth({
|
||||
mode: 'wsse',
|
||||
collectionUid: collection.uid,
|
||||
content: {
|
||||
username: wsseAuth.username,
|
||||
password
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledWrapper className="mt-2 w-full">
|
||||
<label className="block font-medium mb-2">Username</label>
|
||||
<div className="single-line-editor-wrapper mb-2">
|
||||
<SingleLineEditor
|
||||
value={wsseAuth.username || ''}
|
||||
theme={storedTheme}
|
||||
onSave={handleSave}
|
||||
onChange={(val) => handleUserChange(val)}
|
||||
collection={collection}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="block font-medium mb-2">Password</label>
|
||||
<div className="single-line-editor-wrapper">
|
||||
<SingleLineEditor
|
||||
value={wsseAuth.password || ''}
|
||||
theme={storedTheme}
|
||||
onSave={handleSave}
|
||||
onChange={(val) => handlePasswordChange(val)}
|
||||
collection={collection}
|
||||
/>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default WsseAuth;
|
||||
@@ -6,9 +6,13 @@ import AwsV4Auth from './AwsV4Auth';
|
||||
import BearerAuth from './BearerAuth';
|
||||
import BasicAuth from './BasicAuth';
|
||||
import DigestAuth from './DigestAuth';
|
||||
import WsseAuth from './WsseAuth';
|
||||
import ApiKeyAuth from './ApiKeyAuth/';
|
||||
import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import OAuth2 from './OAuth2';
|
||||
import NTLMAuth from './NTLMAuth';
|
||||
|
||||
|
||||
const Auth = ({ collection }) => {
|
||||
const authMode = get(collection, 'root.request.auth.mode');
|
||||
@@ -30,9 +34,18 @@ const Auth = ({ collection }) => {
|
||||
case 'digest': {
|
||||
return <DigestAuth collection={collection} />;
|
||||
}
|
||||
case 'ntlm': {
|
||||
return <NTLMAuth collection={collection} />;
|
||||
}
|
||||
case 'oauth2': {
|
||||
return <OAuth2 collection={collection} />;
|
||||
}
|
||||
case 'wsse': {
|
||||
return <WsseAuth collection={collection} />;
|
||||
}
|
||||
case 'apikey': {
|
||||
return <ApiKeyAuth collection={collection} />;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -10,8 +10,9 @@ import StyledWrapper from './StyledWrapper';
|
||||
import { useRef } from 'react';
|
||||
import path from 'path';
|
||||
import slash from 'utils/common/slash';
|
||||
import { isWindowsOS } from 'utils/common/platform';
|
||||
|
||||
const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
|
||||
const ClientCertSettings = ({ root, clientCertConfig, onUpdate, onRemove }) => {
|
||||
const certFilePathInputRef = useRef();
|
||||
const keyFilePathInputRef = useRef();
|
||||
const pfxFilePathInputRef = useRef();
|
||||
@@ -67,7 +68,16 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
|
||||
});
|
||||
|
||||
const getFile = (e) => {
|
||||
e.files?.[0]?.path && formik.setFieldValue(e.name, e.files?.[0]?.path);
|
||||
const filePath = window?.ipcRenderer?.getFilePath(e?.files?.[0]);
|
||||
if (filePath) {
|
||||
let relativePath;
|
||||
if (isWindowsOS()) {
|
||||
relativePath = slash(path.win32.relative(root, filePath));
|
||||
} else {
|
||||
relativePath = path.posix.relative(root, filePath);
|
||||
}
|
||||
formik.setFieldValue(e.name, relativePath);
|
||||
}
|
||||
};
|
||||
|
||||
const resetFileInputFields = () => {
|
||||
@@ -102,10 +112,14 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
|
||||
: clientCertConfig.map((clientCert) => (
|
||||
<li key={uuid()} className="flex items-center available-certificates p-2 rounded-lg mb-2">
|
||||
<div className="flex items-center w-full justify-between">
|
||||
<div className="flex items-center">
|
||||
<div className="flex w-full items-center">
|
||||
<IconWorld className="mr-2" size={18} strokeWidth={1.5} />
|
||||
{clientCert.domain}
|
||||
</div>
|
||||
<div className="flex w-full items-center">
|
||||
<IconCertificate className="mr-2 flex-shrink-0" size={18} strokeWidth={1.5} />
|
||||
{clientCert.type === 'cert' ? clientCert.certFilePath : clientCert.pfxFilePath}
|
||||
</div>
|
||||
<button onClick={() => onRemove(clientCert)} className="remove-certificate ml-2">
|
||||
<IconTrash size={18} strokeWidth={1.5} />
|
||||
</button>
|
||||
|
||||
@@ -2,16 +2,12 @@ import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
div.CodeMirror {
|
||||
/* todo: find a better way */
|
||||
height: calc(100vh - 240px);
|
||||
|
||||
.CodeMirror-scroll {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
}
|
||||
.editing-mode {
|
||||
cursor: pointer;
|
||||
color: ${(props) => props.theme.colors.text.yellow};
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/acti
|
||||
import Markdown from 'components/MarkDown';
|
||||
import CodeEditor from 'components/CodeEditor';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { IconEdit, IconX, IconFileText } from '@tabler/icons';
|
||||
|
||||
const Docs = ({ collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -29,29 +30,95 @@ const Docs = ({ collection }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const onSave = () => dispatch(saveCollectionRoot(collection.uid));
|
||||
const handleDiscardChanges = () => {
|
||||
dispatch(
|
||||
updateCollectionDocs({
|
||||
collectionUid: collection.uid,
|
||||
docs: docs
|
||||
})
|
||||
);
|
||||
toggleViewMode();
|
||||
}
|
||||
|
||||
const onSave = () => {
|
||||
dispatch(saveCollectionRoot(collection.uid));
|
||||
toggleViewMode();
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledWrapper className="mt-1 h-full w-full relative">
|
||||
<div className="editing-mode mb-2" role="tab" onClick={toggleViewMode}>
|
||||
{isEditing ? 'Preview' : 'Edit'}
|
||||
<StyledWrapper className="mt-1 h-full w-full relative flex flex-col">
|
||||
<div className='flex flex-row w-full justify-between items-center mb-4'>
|
||||
<div className='text-lg font-medium flex items-center gap-2'>
|
||||
<IconFileText size={20} strokeWidth={1.5} />
|
||||
Documentation
|
||||
</div>
|
||||
<div className='flex flex-row gap-2 items-center justify-center'>
|
||||
{isEditing ? (
|
||||
<>
|
||||
<div className="editing-mode" role="tab" onClick={handleDiscardChanges}>
|
||||
<IconX className="cursor-pointer" size={20} strokeWidth={1.5} />
|
||||
</div>
|
||||
<button type="submit" className="submit btn btn-sm btn-secondary" onClick={onSave}>
|
||||
Save
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<div className="editing-mode" role="tab" onClick={toggleViewMode}>
|
||||
<IconEdit className="cursor-pointer" size={20} strokeWidth={1.5} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isEditing ? (
|
||||
<CodeEditor
|
||||
collection={collection}
|
||||
theme={displayedTheme}
|
||||
value={docs || ''}
|
||||
value={docs}
|
||||
onEdit={onEdit}
|
||||
onSave={onSave}
|
||||
mode="application/text"
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
fontSize={get(preferences, 'font.codeFontSize')}
|
||||
/>
|
||||
) : (
|
||||
<Markdown onDoubleClick={toggleViewMode} content={docs} />
|
||||
<div className='h-full overflow-auto pl-1'>
|
||||
<div className='h-[1px] min-h-[500px]'>
|
||||
{
|
||||
docs?.length > 0 ?
|
||||
<Markdown collectionPath={collection.pathname} onDoubleClick={toggleViewMode} content={docs} />
|
||||
:
|
||||
<Markdown collectionPath={collection.pathname} onDoubleClick={toggleViewMode} content={documentationPlaceholder} />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default Docs;
|
||||
|
||||
|
||||
const documentationPlaceholder = `
|
||||
Welcome to your collection documentation! This space is designed to help you document your API collection effectively.
|
||||
|
||||
## Overview
|
||||
Use this section to provide a high-level overview of your collection. You can describe:
|
||||
- The purpose of these API endpoints
|
||||
- Key features and functionalities
|
||||
- Target audience or users
|
||||
|
||||
## Best Practices
|
||||
- Keep documentation up to date
|
||||
- Include request/response examples
|
||||
- Document error scenarios
|
||||
- Add relevant links and references
|
||||
|
||||
## Markdown Support
|
||||
This documentation supports Markdown formatting! You can use:
|
||||
- **Bold** and *italic* text
|
||||
- \`code blocks\` and syntax highlighting
|
||||
- Tables and lists
|
||||
- [Links](https://example.com)
|
||||
- And more!
|
||||
`;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
max-width: 800px;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import React from 'react';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { getTotalRequestCountInCollection } from 'utils/collections/';
|
||||
|
||||
const Info = ({ collection }) => {
|
||||
const totalRequestsInCollection = getTotalRequestCountInCollection(collection);
|
||||
|
||||
return (
|
||||
<StyledWrapper className="w-full flex flex-col h-full">
|
||||
<div className="text-xs mb-4 text-muted">General information about the collection.</div>
|
||||
<table className="w-full border-collapse">
|
||||
<tbody>
|
||||
<tr className="">
|
||||
<td className="py-2 px-2 text-right">Name :</td>
|
||||
<td className="py-2 px-2">{collection.name}</td>
|
||||
</tr>
|
||||
<tr className="">
|
||||
<td className="py-2 px-2 text-right">Location :</td>
|
||||
<td className="py-2 px-2 break-all">{collection.pathname}</td>
|
||||
</tr>
|
||||
<tr className="">
|
||||
<td className="py-2 px-2 text-right">Ignored files :</td>
|
||||
<td className="py-2 px-2 break-all">{collection.brunoConfig?.ignore?.map((x) => `'${x}'`).join(', ')}</td>
|
||||
</tr>
|
||||
<tr className="">
|
||||
<td className="py-2 px-2 text-right">Environments :</td>
|
||||
<td className="py-2 px-2">{collection.environments?.length || 0}</td>
|
||||
</tr>
|
||||
<tr className="">
|
||||
<td className="py-2 px-2 text-right">Requests :</td>
|
||||
<td className="py-2 px-2">{totalRequestsInCollection}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default Info;
|
||||
@@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
import { getTotalRequestCountInCollection } from 'utils/collections/';
|
||||
import { IconFolder, IconFileOff, IconWorld, IconApi } from '@tabler/icons';
|
||||
|
||||
const Info = ({ collection }) => {
|
||||
const totalRequestsInCollection = getTotalRequestCountInCollection(collection);
|
||||
|
||||
return (
|
||||
<div className="w-full flex flex-col h-fit">
|
||||
<div className="rounded-lg py-6">
|
||||
<div className="grid gap-6">
|
||||
{/* Location Row */}
|
||||
<div className="flex items-start">
|
||||
<div className="flex-shrink-0 p-3 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
|
||||
<IconFolder className="w-5 h-5 text-blue-500" stroke={1.5} />
|
||||
</div>
|
||||
<div className="ml-4">
|
||||
<div className="font-semibold text-sm">Location</div>
|
||||
<div className="mt-1 text-sm text-muted break-all">
|
||||
{collection.pathname}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Environments Row */}
|
||||
<div className="flex items-start">
|
||||
<div className="flex-shrink-0 p-3 bg-green-50 dark:bg-green-900/20 rounded-lg">
|
||||
<IconWorld className="w-5 h-5 text-green-500" stroke={1.5} />
|
||||
</div>
|
||||
<div className="ml-4">
|
||||
<div className="font-semibold text-sm">Environments</div>
|
||||
<div className="mt-1 text-sm text-muted">
|
||||
{collection.environments?.length || 0} environment{collection.environments?.length !== 1 ? 's' : ''} configured
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Requests Row */}
|
||||
<div className="flex items-start">
|
||||
<div className="flex-shrink-0 p-3 bg-purple-50 dark:bg-purple-900/20 rounded-lg">
|
||||
<IconApi className="w-5 h-5 text-purple-500" stroke={1.5} />
|
||||
</div>
|
||||
<div className="ml-4">
|
||||
<div className="font-semibold text-sm">Requests</div>
|
||||
<div className="mt-1 text-sm text-muted">
|
||||
{totalRequestsInCollection} request{totalRequestsInCollection !== 1 ? 's' : ''} in collection
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Info;
|
||||
@@ -0,0 +1,25 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
&.card {
|
||||
background-color: ${(props) => props.theme.requestTabPanel.card.bg};
|
||||
|
||||
.title {
|
||||
border-top: 1px solid ${(props) => props.theme.requestTabPanel.cardTable.border};
|
||||
border-left: 1px solid ${(props) => props.theme.requestTabPanel.cardTable.border};
|
||||
border-right: 1px solid ${(props) => props.theme.requestTabPanel.cardTable.border};
|
||||
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
.table {
|
||||
thead {
|
||||
background-color: ${(props) => props.theme.requestTabPanel.cardTable.table.thead.bg};
|
||||
color: ${(props) => props.theme.requestTabPanel.cardTable.table.thead.color};
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledWrapper;
|
||||
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
import { flattenItems } from "utils/collections";
|
||||
import { IconAlertTriangle } from '@tabler/icons';
|
||||
import StyledWrapper from "./StyledWrapper";
|
||||
|
||||
const RequestsNotLoaded = ({ collection }) => {
|
||||
const flattenedItems = flattenItems(collection.items);
|
||||
const itemsFailedLoading = flattenedItems?.filter(item => item?.partial && !item?.loading);
|
||||
|
||||
if (!itemsFailedLoading?.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledWrapper className="w-full card my-2">
|
||||
<div className="flex items-center gap-2 px-3 py-2 title bg-yellow-50 dark:bg-yellow-900/20">
|
||||
<IconAlertTriangle size={16} className="text-yellow-500" />
|
||||
<span className="font-medium">Following requests were not loaded</span>
|
||||
</div>
|
||||
<table className="w-full border-collapse">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="py-2 px-3 text-left font-medium">
|
||||
Pathname
|
||||
</th>
|
||||
<th className="py-2 px-3 text-left font-medium">
|
||||
Size
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{flattenedItems?.map((item, index) => (
|
||||
item?.partial && !item?.loading ? (
|
||||
<tr key={index}>
|
||||
<td className="py-1.5 px-3">
|
||||
{item?.pathname?.split(`${collection?.pathname}/`)?.[1]}
|
||||
</td>
|
||||
<td className="py-1.5 px-3">
|
||||
{item?.size?.toFixed?.(2)} MB
|
||||
</td>
|
||||
</tr>
|
||||
) : null
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default RequestsNotLoaded;
|
||||
@@ -0,0 +1,25 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
.partial {
|
||||
color: ${(props) => props.theme.colors.text.yellow};
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.loading {
|
||||
color: ${(props) => props.theme.colors.text.muted};
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.completed {
|
||||
color: ${(props) => props.theme.colors.text.green};
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.failed {
|
||||
color: ${(props) => props.theme.colors.text.danger};
|
||||
opacity: 0.8;
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledWrapper;
|
||||
@@ -0,0 +1,27 @@
|
||||
import StyledWrapper from "./StyledWrapper";
|
||||
import Docs from "../Docs";
|
||||
import Info from "./Info";
|
||||
import { IconBox } from '@tabler/icons';
|
||||
import RequestsNotLoaded from "./RequestsNotLoaded";
|
||||
|
||||
const Overview = ({ collection }) => {
|
||||
return (
|
||||
<div className="h-full">
|
||||
<div className="grid grid-cols-5 gap-4 h-full">
|
||||
<div className="col-span-2">
|
||||
<div className="text-xl font-semibold flex items-center gap-2">
|
||||
<IconBox size={24} stroke={1.5} />
|
||||
{collection?.name}
|
||||
</div>
|
||||
<Info collection={collection} />
|
||||
<RequestsNotLoaded collection={collection} />
|
||||
</div>
|
||||
<div className="col-span-3">
|
||||
<Docs collection={collection} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Overview;
|
||||
@@ -1,6 +1,8 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
max-width: 800px;
|
||||
|
||||
.settings-label {
|
||||
width: 110px;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useFormik } from 'formik';
|
||||
import Tooltip from 'components/Tooltip';
|
||||
import InfoTip from 'components/InfoTip';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import * as Yup from 'yup';
|
||||
import toast from 'react-hot-toast';
|
||||
@@ -104,7 +104,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label flex items-center" htmlFor="enabled">
|
||||
Config
|
||||
<Tooltip
|
||||
<InfoTip
|
||||
text={`
|
||||
<div>
|
||||
<ul>
|
||||
@@ -114,7 +114,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
</ul>
|
||||
</div>
|
||||
`}
|
||||
tooltipId="request-var"
|
||||
infotipId="request-var"
|
||||
/>
|
||||
</label>
|
||||
<div className="flex items-center">
|
||||
@@ -336,4 +336,4 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default ProxySettings;
|
||||
export default ProxySettings;
|
||||
@@ -1,6 +1,8 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
max-width: 800px;
|
||||
|
||||
div.CodeMirror {
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ const Script = ({ collection }) => {
|
||||
mode="javascript"
|
||||
onSave={handleSave}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
fontSize={get(preferences, 'font.codeFontSize')}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex-1 mt-6">
|
||||
@@ -64,6 +65,7 @@ const Script = ({ collection }) => {
|
||||
mode="javascript"
|
||||
onSave={handleSave}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
fontSize={get(preferences, 'font.codeFontSize')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
max-width: 800px;
|
||||
|
||||
div.tabs {
|
||||
div.tab {
|
||||
padding: 6px 0px;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div``;
|
||||
const StyledWrapper = styled.div`
|
||||
max-width: 800px;
|
||||
`;
|
||||
|
||||
export default StyledWrapper;
|
||||
|
||||
@@ -36,6 +36,7 @@ const Tests = ({ collection }) => {
|
||||
mode="javascript"
|
||||
onSave={handleSave}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
fontSize={get(preferences, 'font.codeFontSize')}
|
||||
/>
|
||||
|
||||
<div className="mt-6">
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
table {
|
||||
td {
|
||||
&:first-child {
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
max-width: 800px;
|
||||
|
||||
div.title {
|
||||
color: var(--color-tab-inactive);
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-weight: 600;
|
||||
table-layout: fixed;
|
||||
|
||||
thead,
|
||||
td {
|
||||
border: 1px solid ${(props) => props.theme.table.border};
|
||||
}
|
||||
|
||||
thead {
|
||||
color: ${(props) => props.theme.table.thead.color};
|
||||
font-size: 0.8125rem;
|
||||
user-select: none;
|
||||
}
|
||||
td {
|
||||
padding: 6px 10px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-add-var {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
input[type='text'] {
|
||||
width: 100%;
|
||||
border: solid 1px transparent;
|
||||
outline: none !important;
|
||||
background-color: inherit;
|
||||
|
||||
&:focus {
|
||||
outline: none !important;
|
||||
border: solid 1px transparent;
|
||||
}
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
||||
@@ -0,0 +1,161 @@
|
||||
import React from 'react';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { IconTrash } from '@tabler/icons';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useTheme } from 'providers/Theme';
|
||||
import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import SingleLineEditor from 'components/SingleLineEditor';
|
||||
import InfoTip from 'components/InfoTip';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import toast from 'react-hot-toast';
|
||||
import { variableNameRegex } from 'utils/common/regex';
|
||||
import {
|
||||
addCollectionVar,
|
||||
deleteCollectionVar,
|
||||
updateCollectionVar
|
||||
} from 'providers/ReduxStore/slices/collections/index';
|
||||
|
||||
const VarsTable = ({ collection, vars, varType }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { storedTheme } = useTheme();
|
||||
|
||||
const addVar = () => {
|
||||
dispatch(
|
||||
addCollectionVar({
|
||||
collectionUid: collection.uid,
|
||||
type: varType
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const onSave = () => dispatch(saveCollectionRoot(collection.uid));
|
||||
const handleVarChange = (e, v, type) => {
|
||||
const _var = cloneDeep(v);
|
||||
switch (type) {
|
||||
case 'name': {
|
||||
const value = e.target.value;
|
||||
|
||||
if (variableNameRegex.test(value) === false) {
|
||||
toast.error(
|
||||
'Variable contains invalid characters! Variables must only contain alpha-numeric characters, "-", "_", "."'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
_var.name = value;
|
||||
break;
|
||||
}
|
||||
case 'value': {
|
||||
_var.value = e.target.value;
|
||||
break;
|
||||
}
|
||||
case 'enabled': {
|
||||
_var.enabled = e.target.checked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dispatch(
|
||||
updateCollectionVar({
|
||||
type: varType,
|
||||
var: _var,
|
||||
collectionUid: collection.uid
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleRemoveVar = (_var) => {
|
||||
dispatch(
|
||||
deleteCollectionVar({
|
||||
type: varType,
|
||||
varUid: _var.uid,
|
||||
collectionUid: collection.uid
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledWrapper className="w-full">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Name</td>
|
||||
{varType === 'request' ? (
|
||||
<td>
|
||||
<div className="flex items-center">
|
||||
<span>Value</span>
|
||||
</div>
|
||||
</td>
|
||||
) : (
|
||||
<td>
|
||||
<div className="flex items-center">
|
||||
<span>Expr</span>
|
||||
<InfoTip text="You can write any valid JS Template Literal here" infotipId="request-var" />
|
||||
</div>
|
||||
</td>
|
||||
)}
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{vars && vars.length
|
||||
? vars.map((_var) => {
|
||||
return (
|
||||
<tr key={_var.uid}>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={_var.name}
|
||||
className="mousetrap"
|
||||
onChange={(e) => handleVarChange(e, _var, 'name')}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<SingleLineEditor
|
||||
value={_var.value}
|
||||
theme={storedTheme}
|
||||
onSave={onSave}
|
||||
onChange={(newValue) =>
|
||||
handleVarChange(
|
||||
{
|
||||
target: {
|
||||
value: newValue
|
||||
}
|
||||
},
|
||||
_var,
|
||||
'value'
|
||||
)
|
||||
}
|
||||
collection={collection}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={_var.enabled}
|
||||
tabIndex="-1"
|
||||
className="mr-3 mousetrap"
|
||||
onChange={(e) => handleVarChange(e, _var, 'enabled')}
|
||||
/>
|
||||
<button tabIndex="-1" onClick={() => handleRemoveVar(_var)}>
|
||||
<IconTrash strokeWidth={1.5} size={20} />
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})
|
||||
: null}
|
||||
</tbody>
|
||||
</table>
|
||||
<button className="btn-add-var text-link pr-2 py-3 mt-2 select-none" onClick={addVar}>
|
||||
+ Add
|
||||
</button>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
export default VarsTable;
|
||||
@@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import get from 'lodash/get';
|
||||
import VarsTable from './VarsTable';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
const Vars = ({ collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
const requestVars = get(collection, 'root.request.vars.req', []);
|
||||
const responseVars = get(collection, 'root.request.vars.res', []);
|
||||
const handleSave = () => dispatch(saveCollectionRoot(collection.uid));
|
||||
return (
|
||||
<StyledWrapper className="w-full flex flex-col">
|
||||
<div className="flex-1 mt-2">
|
||||
<div className="mb-1 title text-xs">Pre Request</div>
|
||||
<VarsTable collection={collection} vars={requestVars} varType="request" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="mt-1 mb-1 title text-xs">Post Response</div>
|
||||
<VarsTable collection={collection} vars={responseVars} varType="response" />
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
<button type="submit" className="submit btn btn-sm btn-secondary" onClick={handleSave}>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default Vars;
|
||||
@@ -12,10 +12,19 @@ import Headers from './Headers';
|
||||
import Auth from './Auth';
|
||||
import Script from './Script';
|
||||
import Test from './Tests';
|
||||
import Docs from './Docs';
|
||||
import Presets from './Presets';
|
||||
import Info from './Info';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import Vars from './Vars/index';
|
||||
import DotIcon from 'components/Icons/Dot';
|
||||
import Overview from './Overview/index';
|
||||
|
||||
const ContentIndicator = () => {
|
||||
return (
|
||||
<sup className="ml-[.125rem] opacity-80 font-medium">
|
||||
<DotIcon width="10"></DotIcon>
|
||||
</sup>
|
||||
);
|
||||
};
|
||||
|
||||
const CollectionSettings = ({ collection }) => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -29,10 +38,23 @@ const CollectionSettings = ({ collection }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const proxyConfig = get(collection, 'brunoConfig.proxy', {});
|
||||
const root = collection?.root;
|
||||
const hasScripts = root?.request?.script?.res || root?.request?.script?.req;
|
||||
const hasTests = root?.request?.tests;
|
||||
const hasDocs = root?.docs;
|
||||
|
||||
const headers = get(collection, 'root.request.headers', []);
|
||||
const activeHeadersCount = headers.filter((header) => header.enabled).length;
|
||||
|
||||
const requestVars = get(collection, 'root.request.vars.req', []);
|
||||
const responseVars = get(collection, 'root.request.vars.res', []);
|
||||
const activeVarsCount = requestVars.filter((v) => v.enabled).length + responseVars.filter((v) => v.enabled).length;
|
||||
const auth = get(collection, 'root.request.auth', {}).mode;
|
||||
|
||||
const proxyConfig = get(collection, 'brunoConfig.proxy', {});
|
||||
const clientCertConfig = get(collection, 'brunoConfig.clientCertificates.certs', []);
|
||||
|
||||
|
||||
const onProxySettingsUpdate = (config) => {
|
||||
const brunoConfig = cloneDeep(collection.brunoConfig);
|
||||
brunoConfig.proxy = config;
|
||||
@@ -74,9 +96,15 @@ const CollectionSettings = ({ collection }) => {
|
||||
|
||||
const getTabPanel = (tab) => {
|
||||
switch (tab) {
|
||||
case 'overview': {
|
||||
return <Overview collection={collection} />;
|
||||
}
|
||||
case 'headers': {
|
||||
return <Headers collection={collection} />;
|
||||
}
|
||||
case 'vars': {
|
||||
return <Vars collection={collection} />;
|
||||
}
|
||||
case 'auth': {
|
||||
return <Auth collection={collection} />;
|
||||
}
|
||||
@@ -95,18 +123,13 @@ const CollectionSettings = ({ collection }) => {
|
||||
case 'clientCert': {
|
||||
return (
|
||||
<ClientCertSettings
|
||||
root={collection.pathname}
|
||||
clientCertConfig={clientCertConfig}
|
||||
onUpdate={onClientCertSettingsUpdate}
|
||||
onRemove={onClientCertSettingsRemove}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case 'docs': {
|
||||
return <Docs collection={collection} />;
|
||||
}
|
||||
case 'info': {
|
||||
return <Info collection={collection} />;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -119,32 +142,39 @@ const CollectionSettings = ({ collection }) => {
|
||||
return (
|
||||
<StyledWrapper className="flex flex-col h-full relative px-4 py-4">
|
||||
<div className="flex flex-wrap items-center tabs" role="tablist">
|
||||
<div className={getTabClassname('overview')} role="tab" onClick={() => setTab('overview')}>
|
||||
Overview
|
||||
</div>
|
||||
<div className={getTabClassname('headers')} role="tab" onClick={() => setTab('headers')}>
|
||||
Headers
|
||||
{activeHeadersCount > 0 && <sup className="ml-1 font-medium">{activeHeadersCount}</sup>}
|
||||
</div>
|
||||
<div className={getTabClassname('vars')} role="tab" onClick={() => setTab('vars')}>
|
||||
Vars
|
||||
{activeVarsCount > 0 && <sup className="ml-1 font-medium">{activeVarsCount}</sup>}
|
||||
</div>
|
||||
<div className={getTabClassname('auth')} role="tab" onClick={() => setTab('auth')}>
|
||||
Auth
|
||||
{auth !== 'none' && <ContentIndicator />}
|
||||
</div>
|
||||
<div className={getTabClassname('script')} role="tab" onClick={() => setTab('script')}>
|
||||
Script
|
||||
{hasScripts && <ContentIndicator />}
|
||||
</div>
|
||||
<div className={getTabClassname('tests')} role="tab" onClick={() => setTab('tests')}>
|
||||
Tests
|
||||
{hasTests && <ContentIndicator />}
|
||||
</div>
|
||||
<div className={getTabClassname('presets')} role="tab" onClick={() => setTab('presets')}>
|
||||
Presets
|
||||
</div>
|
||||
<div className={getTabClassname('proxy')} role="tab" onClick={() => setTab('proxy')}>
|
||||
Proxy
|
||||
{Object.keys(proxyConfig).length > 0 && <ContentIndicator />}
|
||||
</div>
|
||||
<div className={getTabClassname('clientCert')} role="tab" onClick={() => setTab('clientCert')}>
|
||||
Client Certificates
|
||||
</div>
|
||||
<div className={getTabClassname('docs')} role="tab" onClick={() => setTab('docs')}>
|
||||
Docs
|
||||
</div>
|
||||
<div className={getTabClassname('info')} role="tab" onClick={() => setTab('info')}>
|
||||
Info
|
||||
{clientCertConfig.length > 0 && <ContentIndicator />}
|
||||
</div>
|
||||
</div>
|
||||
<section className="mt-4 h-full">{getTabPanel(tab)}</section>
|
||||
|
||||
@@ -3,7 +3,6 @@ import styled from 'styled-components';
|
||||
const StyledWrapper = styled.div`
|
||||
.editing-mode {
|
||||
cursor: pointer;
|
||||
color: ${(props) => props.theme.colors.text.yellow};
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -47,13 +47,14 @@ const Documentation = ({ item, collection }) => {
|
||||
collection={collection}
|
||||
theme={displayedTheme}
|
||||
font={get(preferences, 'font.codeFont', 'default')}
|
||||
fontSize={get(preferences, 'font.codeFontSize')}
|
||||
value={docs || ''}
|
||||
onEdit={onEdit}
|
||||
onSave={onSave}
|
||||
mode="application/text"
|
||||
/>
|
||||
) : (
|
||||
<Markdown onDoubleClick={toggleViewMode} content={docs} />
|
||||
<Markdown collectionPath={collection.pathname} onDoubleClick={toggleViewMode} content={docs} />
|
||||
)}
|
||||
</StyledWrapper>
|
||||
);
|
||||
|
||||
@@ -36,14 +36,26 @@ const Wrapper = styled.div`
|
||||
padding: 0.35rem 0.6rem;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
color: ${(props) => props.theme.colors.text.yellow} !important;
|
||||
.icon {
|
||||
color: ${(props) => props.theme.colors.text.yellow} !important;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
color: ${(props) => props.theme.dropdown.iconColor};
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:hover:not(:disabled) {
|
||||
background-color: ${(props) => props.theme.dropdown.hoverBg};
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
&.border-top {
|
||||
border-top: solid 1px ${(props) => props.theme.dropdown.separator};
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ import React from 'react';
|
||||
import Tippy from '@tippyjs/react';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const Dropdown = ({ icon, children, onCreate, placement }) => {
|
||||
const Dropdown = ({ icon, children, onCreate, placement, transparent }) => {
|
||||
return (
|
||||
<StyledWrapper className="dropdown">
|
||||
<StyledWrapper className="dropdown" transparent={transparent}>
|
||||
<Tippy
|
||||
content={children}
|
||||
placement={placement || 'bottom-end'}
|
||||
|
||||
@@ -19,7 +19,7 @@ const EnvironmentSelector = ({ collection }) => {
|
||||
const Icon = forwardRef((props, ref) => {
|
||||
return (
|
||||
<div ref={ref} className="current-environment flex items-center justify-center pl-3 pr-2 py-1 select-none">
|
||||
{activeEnvironment ? activeEnvironment.name : 'No Environment'}
|
||||
<p className="text-nowrap truncate max-w-32">{activeEnvironment ? activeEnvironment.name : 'No Environment'}</p>
|
||||
<IconCaretDown className="caret" size={14} strokeWidth={2} />
|
||||
</div>
|
||||
);
|
||||
@@ -53,10 +53,11 @@ const EnvironmentSelector = ({ collection }) => {
|
||||
<StyledWrapper>
|
||||
<div className="flex items-center cursor-pointer environment-selector">
|
||||
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement="bottom-end">
|
||||
<div className="label-item font-medium">Collection Environments</div>
|
||||
{environments && environments.length
|
||||
? environments.map((e) => (
|
||||
<div
|
||||
className="dropdown-item"
|
||||
className={`dropdown-item ${e?.uid === activeEnvironmentUid ? 'active' : ''}`}
|
||||
key={e.uid}
|
||||
onClick={() => {
|
||||
onSelect(e);
|
||||
@@ -77,7 +78,10 @@ const EnvironmentSelector = ({ collection }) => {
|
||||
<IconDatabaseOff size={18} strokeWidth={1.5} />
|
||||
<span className="ml-2">No Environment</span>
|
||||
</div>
|
||||
<div className="dropdown-item border-top" onClick={handleSettingsIconClick}>
|
||||
<div className="dropdown-item border-top" onClick={() => {
|
||||
handleSettingsIconClick();
|
||||
dropdownTippyRef.current.hide();
|
||||
}}>
|
||||
<div className="pr-2 text-gray-600">
|
||||
<IconSettings size={18} strokeWidth={1.5} />
|
||||
</div>
|
||||
|
||||
@@ -44,7 +44,7 @@ const CopyEnvironment = ({ collection, environment, onClose }) => {
|
||||
return (
|
||||
<Portal>
|
||||
<Modal size="sm" title={'Copy Environment'} confirmText="Copy" handleConfirm={onSubmit} handleCancel={onClose}>
|
||||
<form className="bruno-form" onSubmit={formik.handleSubmit}>
|
||||
<form className="bruno-form" onSubmit={e => e.preventDefault()}>
|
||||
<div>
|
||||
<label htmlFor="name" className="block font-semibold">
|
||||
New Environment Name
|
||||
|
||||
@@ -10,6 +10,11 @@ import Modal from 'components/Modal';
|
||||
const CreateEnvironment = ({ collection, onClose }) => {
|
||||
const dispatch = useDispatch();
|
||||
const inputRef = useRef();
|
||||
|
||||
const validateEnvironmentName = (name) => {
|
||||
return !collection?.environments?.some((env) => env?.name?.toLowerCase().trim() === name?.toLowerCase().trim());
|
||||
};
|
||||
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
initialValues: {
|
||||
@@ -17,9 +22,10 @@ const CreateEnvironment = ({ collection, onClose }) => {
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
name: Yup.string()
|
||||
.min(1, 'must be at least 1 character')
|
||||
.max(50, 'must be 50 characters or less')
|
||||
.required('name is required')
|
||||
.min(1, 'Must be at least 1 character')
|
||||
.max(50, 'Must be 50 characters or less')
|
||||
.required('Name is required')
|
||||
.test('duplicate-name', 'Environment already exists', validateEnvironmentName)
|
||||
}),
|
||||
onSubmit: (values) => {
|
||||
dispatch(addEnvironment(values.name, collection.uid))
|
||||
@@ -50,7 +56,7 @@ const CreateEnvironment = ({ collection, onClose }) => {
|
||||
handleConfirm={onSubmit}
|
||||
handleCancel={onClose}
|
||||
>
|
||||
<form className="bruno-form" onSubmit={formik.handleSubmit}>
|
||||
<form className="bruno-form" onSubmit={e => e.preventDefault()}>
|
||||
<div>
|
||||
<label htmlFor="name" className="block font-semibold">
|
||||
Environment Name
|
||||
|
||||
@@ -39,6 +39,11 @@ const Wrapper = styled.div`
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
.tooltip-mod {
|
||||
font-size: 11px !important;
|
||||
width: 150px !important;
|
||||
}
|
||||
|
||||
input[type='text'] {
|
||||
width: 100%;
|
||||
border: solid 1px transparent;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import React from 'react';
|
||||
import { IconTrash } from '@tabler/icons';
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { IconTrash, IconAlertCircle, IconDeviceFloppy, IconRefresh, IconCircleCheck } from '@tabler/icons';
|
||||
import { useTheme } from 'providers/Theme';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { selectEnvironment } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import SingleLineEditor from 'components/SingleLineEditor';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { uuid } from 'utils/common';
|
||||
@@ -9,12 +11,13 @@ import { useFormik } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
import { variableNameRegex } from 'utils/common/regex';
|
||||
import { saveEnvironment } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import toast from 'react-hot-toast';
|
||||
import { Tooltip } from 'react-tooltip';
|
||||
|
||||
const EnvironmentVariables = ({ environment, collection, setIsModified, originalEnvironmentVariables }) => {
|
||||
const EnvironmentVariables = ({ environment, collection, setIsModified, originalEnvironmentVariables, onClose }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { storedTheme } = useTheme();
|
||||
const addButtonRef = useRef(null);
|
||||
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
@@ -58,14 +61,15 @@ const EnvironmentVariables = ({ environment, collection, setIsModified, original
|
||||
|
||||
const ErrorMessage = ({ name }) => {
|
||||
const meta = formik.getFieldMeta(name);
|
||||
if (!meta.error) {
|
||||
const id = uuid();
|
||||
if (!meta.error || !meta.touched) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<label htmlFor={name} className="text-red-500">
|
||||
{meta.error}
|
||||
</label>
|
||||
<span>
|
||||
<IconAlertCircle id={id} className="text-red-600 cursor-pointer " size={20} />
|
||||
<Tooltip className="tooltip-mod" anchorId={id} html={meta.error || ''} />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -81,10 +85,31 @@ const EnvironmentVariables = ({ environment, collection, setIsModified, original
|
||||
formik.setFieldValue(formik.values.length, newVariable, false);
|
||||
};
|
||||
|
||||
const onActivate = () => {
|
||||
dispatch(selectEnvironment(environment ? environment.uid : null, collection.uid))
|
||||
.then(() => {
|
||||
if (environment) {
|
||||
toast.success(`Environment changed to ${environment.name}`);
|
||||
onClose();
|
||||
} else {
|
||||
toast.success(`No Environments are active now`);
|
||||
}
|
||||
})
|
||||
.catch((err) => console.log(err) && toast.error('An error occurred while selecting the environment'));
|
||||
};
|
||||
|
||||
const handleRemoveVar = (id) => {
|
||||
formik.setValues(formik.values.filter((variable) => variable.uid !== id));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (formik.dirty) {
|
||||
// Smooth scrolling to the changed parameter is temporarily disabled
|
||||
// due to UX issues when editing the first row in a long list of environment variables.
|
||||
// addButtonRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||
}
|
||||
}, [formik.values, formik.dirty]);
|
||||
|
||||
const handleReset = () => {
|
||||
formik.resetForm({ originalEnvironmentVariables });
|
||||
};
|
||||
@@ -115,19 +140,21 @@ const EnvironmentVariables = ({ environment, collection, setIsModified, original
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
className="mousetrap"
|
||||
id={`${index}.name`}
|
||||
name={`${index}.name`}
|
||||
value={variable.name}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
<ErrorMessage name={`${index}.name`} />
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
type="text"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
className="mousetrap"
|
||||
id={`${index}.name`}
|
||||
name={`${index}.name`}
|
||||
value={variable.name}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
<ErrorMessage name={`${index}.name`} />
|
||||
</div>
|
||||
</td>
|
||||
<td className="flex flex-row flex-nowrap">
|
||||
<div className="overflow-hidden grow w-full relative">
|
||||
@@ -159,20 +186,30 @@ const EnvironmentVariables = ({ environment, collection, setIsModified, original
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<button className="btn-add-param text-link pr-2 py-3 mt-2 select-none" onClick={addVariable}>
|
||||
+ Add Variable
|
||||
</button>
|
||||
<div>
|
||||
<button
|
||||
ref={addButtonRef}
|
||||
className="btn-add-param text-link pr-2 py-3 mt-2 select-none"
|
||||
onClick={addVariable}
|
||||
>
|
||||
+ Add Variable
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button type="submit" className="submit btn btn-md btn-secondary mt-2" onClick={formik.handleSubmit}>
|
||||
<div className="flex items-center">
|
||||
<button type="submit" className="submit btn btn-sm btn-secondary mt-2 flex items-center" onClick={formik.handleSubmit}>
|
||||
<IconDeviceFloppy size={16} strokeWidth={1.5} className="mr-1" />
|
||||
Save
|
||||
</button>
|
||||
<button type="submit" className="ml-2 px-1 submit btn btn-md btn-secondary mt-2" onClick={handleReset}>
|
||||
<button type="submit" className="ml-2 px-1 submit btn btn-sm btn-close mt-2 flex items-center" onClick={handleReset}>
|
||||
<IconRefresh size={16} strokeWidth={1.5} className="mr-1" />
|
||||
Reset
|
||||
</button>
|
||||
<button type="submit" className="submit btn btn-sm btn-close mt-2 flex items-center" onClick={onActivate}>
|
||||
<IconCircleCheck size={16} strokeWidth={1.5} className="mr-1" />
|
||||
Activate
|
||||
</button>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user