mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-03 01:18:32 +00:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87404132ae | ||
|
|
7019a77ec6 | ||
|
|
ad9169d78a | ||
|
|
54e99cbbd7 | ||
|
|
eb9862b8f5 | ||
|
|
7a3cc4e040 | ||
|
|
60cb9da83e | ||
|
|
28e4159c21 | ||
|
|
59ffb0166f | ||
|
|
e8ec74107d | ||
|
|
d027d90ed5 | ||
|
|
7bbc4727be | ||
|
|
386a8df151 | ||
|
|
2ed35108d7 | ||
|
|
a0860febee |
139
docs/readme/readme_ar.md
Normal file
139
docs/readme/readme_ar.md
Normal file
@@ -0,0 +1,139 @@
|
||||
<br />
|
||||
<img src="assets/images/logo-transparent.png" width="80"/>
|
||||
|
||||
### برونو - بيئة تطوير مفتوحة المصدر لاستكشاف واختبار واجهات برمجة التطبيقات (APIs).
|
||||
|
||||
[](https://badge.fury.io/gh/usebruno%bruno)
|
||||
[](https://github.com/usebruno/bruno/workflows/unit-tests.yml)
|
||||
[](https://github.com/usebruno/bruno/pulse)
|
||||
[](https://twitter.com/use_bruno)
|
||||
[](https://www.usebruno.com)
|
||||
[](https://www.usebruno.com/downloads)
|
||||
|
||||
**English** | [Українська](docs/readme/readme_ua.md) | [Русский](docs/readme/readme_ru.md) | [Türkçe](docs/readme/readme_tr.md) | [Deutsch](docs/readme/readme_de.md) | [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)
|
||||
|
||||
برونو هو عميل API جديد ومبتكر، يهدف إلى ثورة الحالة الحالية التي يمثلها برنامج Postman وأدوات مماثلة هناك.
|
||||
|
||||
يقوم برونو بتخزين مجموعاتك مباشرة في مجلد على نظام الملفات الخاص بك. نحن نستخدم لغة ترميز النص العادية، Bru، لحفظ معلومات حول طلبات واجهة برمجة التطبيقات (API).
|
||||
|
||||
يمكنك استخدام Git أو أي نظام تحكم في الإصدار الذي تفضله للتعاون على مجموعات API الخاصة بك.
|
||||
|
||||
برونو هو خاص بالاستخدام دون اتصال بالإنترنت. ليس هناك خطط لإضافة مزامنة السحابة إلى برونو أبدًا. نحن نقدر خصوصية بياناتك ونعتقد أنه يجب أن تظل على جهازك. اقرأ رؤيتنا على المدى الطويل [هنا](https://github.com/usebruno/bruno/discussions/269)
|
||||
|
||||
📢 شاهد حديثنا الأخير في مؤتمر 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~~ **$9** ! <br/>
|
||||
[اشترك هنا](https://usebruno.ck.page/4c65576bd4) لتصلك إشعارات عند الإطلاق.
|
||||
|
||||
### التثبيت
|
||||
|
||||
برونو متاح كتنزيل ثنائي [على موقعنا على الويب](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
|
||||
|
||||
# على نظام 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 [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
|
||||
```
|
||||
### التشغيل عبر منصات متعددة 🖥️
|
||||
|
||||
 <br /><br />
|
||||
|
||||
### التعاون عبر Git 👩💻🧑💻
|
||||
|
||||
أو أي نظام تحكم في الإصدار الذي تفضله
|
||||
|
||||
 <br /><br />
|
||||
|
||||
### الروابط المهمة 📌
|
||||
|
||||
- [رؤيتنا على المدى الطويل](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 Sponsors](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 Sponsors](https://github.com/sponsors/helloanoop).
|
||||
|
||||
### شارك الشهادات 📣
|
||||
|
||||
إذا كان برونو قد ساعدك في العمل وفرقك، فلا تنسى مشاركة [شهاداتك في مناقشتنا على GitHub](https://github.com/usebruno/bruno/discussions/343)
|
||||
|
||||
### نشر إلى مديري الحزم الجديدة
|
||||
|
||||
يرجى الرجوع [هنا](publishing.md) لمزيد من المعلومات.
|
||||
|
||||
### تواصل معنا 🌐
|
||||
|
||||
[𝕏 (تويتر)](https://twitter.com/use_bruno) <br />
|
||||
[الموقع الإلكتروني](https://www.usebruno.com) <br />
|
||||
[ديسكورد](https://discord.com/invite/KgcZUncpjq) <br />
|
||||
[لينكدإن](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)
|
||||
190
package-lock.json
generated
190
package-lock.json
generated
@@ -37,6 +37,7 @@
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
"version": "5.2.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -2771,6 +2772,7 @@
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^5.1.2",
|
||||
@@ -2786,6 +2788,7 @@
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
|
||||
"version": "6.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -2796,6 +2799,7 @@
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
|
||||
"version": "6.2.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
@@ -2806,10 +2810,12 @@
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
@@ -2825,6 +2831,7 @@
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
|
||||
"version": "7.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
@@ -2838,6 +2845,7 @@
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
|
||||
"version": "8.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
@@ -3979,6 +3987,7 @@
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
@@ -5518,6 +5527,7 @@
|
||||
},
|
||||
"node_modules/any-promise": {
|
||||
"version": "1.3.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
@@ -5646,6 +5656,7 @@
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
@@ -6707,6 +6718,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
||||
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
@@ -7469,6 +7481,7 @@
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
@@ -7657,6 +7670,7 @@
|
||||
},
|
||||
"node_modules/cssesc": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"cssesc": "bin/cssesc"
|
||||
@@ -7995,6 +8009,7 @@
|
||||
},
|
||||
"node_modules/didyoumean": {
|
||||
"version": "1.2.2",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/diff-sequences": {
|
||||
@@ -8053,6 +8068,7 @@
|
||||
},
|
||||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dmg-builder": {
|
||||
@@ -8220,6 +8236,7 @@
|
||||
},
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ecc-jsbn": {
|
||||
@@ -9297,6 +9314,7 @@
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.1.1",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
@@ -9311,6 +9329,7 @@
|
||||
},
|
||||
"node_modules/foreground-child/node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
@@ -10710,6 +10729,7 @@
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.13.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.0"
|
||||
@@ -10966,6 +10986,7 @@
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/isobject": {
|
||||
@@ -11091,6 +11112,7 @@
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "2.3.6",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
@@ -12256,6 +12278,7 @@
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "2.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@@ -12842,6 +12865,7 @@
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "5.0.0",
|
||||
"devOptional": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -12942,6 +12966,7 @@
|
||||
},
|
||||
"node_modules/mz": {
|
||||
"version": "2.7.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"any-promise": "^1.0.0",
|
||||
@@ -13296,6 +13321,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
@@ -13642,6 +13668,7 @@
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -13649,10 +13676,12 @@
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-scurry": {
|
||||
"version": "1.10.1",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^9.1.1 || ^10.0.0",
|
||||
@@ -13667,6 +13696,7 @@
|
||||
},
|
||||
"node_modules/path-scurry/node_modules/lru-cache": {
|
||||
"version": "10.2.0",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "14 || >=16.14"
|
||||
@@ -13859,6 +13889,7 @@
|
||||
},
|
||||
"node_modules/pirates": {
|
||||
"version": "4.0.6",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
@@ -14024,6 +14055,7 @@
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.35",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -14138,6 +14170,7 @@
|
||||
},
|
||||
"node_modules/postcss-import": {
|
||||
"version": "15.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.0.0",
|
||||
@@ -14155,6 +14188,7 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
|
||||
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"camelcase-css": "^2.0.1"
|
||||
},
|
||||
@@ -14366,6 +14400,7 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
|
||||
"integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"postcss-selector-parser": "^6.0.11"
|
||||
},
|
||||
@@ -14562,6 +14597,7 @@
|
||||
},
|
||||
"node_modules/postcss-selector-parser": {
|
||||
"version": "6.0.15",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
@@ -14606,6 +14642,7 @@
|
||||
},
|
||||
"node_modules/postcss/node_modules/nanoid": {
|
||||
"version": "3.3.7",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -15233,6 +15270,7 @@
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pify": "^2.3.0"
|
||||
@@ -15240,6 +15278,7 @@
|
||||
},
|
||||
"node_modules/read-cache/node_modules/pify": {
|
||||
"version": "2.3.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -15721,6 +15760,7 @@
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.8",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.13.0",
|
||||
@@ -16275,6 +16315,7 @@
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
@@ -16285,6 +16326,7 @@
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -16637,6 +16679,7 @@
|
||||
"node_modules/string-width-cjs": {
|
||||
"name": "string-width",
|
||||
"version": "4.2.3",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
@@ -16679,6 +16722,7 @@
|
||||
"node_modules/strip-ansi-cjs": {
|
||||
"name": "strip-ansi",
|
||||
"version": "6.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
@@ -16821,6 +16865,7 @@
|
||||
},
|
||||
"node_modules/sucrase": {
|
||||
"version": "3.35.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
@@ -16841,6 +16886,7 @@
|
||||
},
|
||||
"node_modules/sucrase/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
@@ -16848,6 +16894,7 @@
|
||||
},
|
||||
"node_modules/sucrase/node_modules/commander": {
|
||||
"version": "4.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
@@ -16855,6 +16902,7 @@
|
||||
},
|
||||
"node_modules/sucrase/node_modules/glob": {
|
||||
"version": "10.3.10",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
@@ -16875,6 +16923,7 @@
|
||||
},
|
||||
"node_modules/sucrase/node_modules/minimatch": {
|
||||
"version": "9.0.3",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
@@ -16909,6 +16958,7 @@
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -17081,6 +17131,7 @@
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
|
||||
"integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
@@ -17117,6 +17168,7 @@
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
},
|
||||
@@ -17128,6 +17180,7 @@
|
||||
"version": "1.21.0",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
|
||||
"integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
@@ -17136,6 +17189,7 @@
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
|
||||
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -17170,6 +17224,7 @@
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
|
||||
"integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
@@ -17181,6 +17236,7 @@
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
|
||||
"integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
@@ -17359,6 +17415,7 @@
|
||||
},
|
||||
"node_modules/thenify": {
|
||||
"version": "3.3.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"any-promise": "^1.0.0"
|
||||
@@ -17366,6 +17423,7 @@
|
||||
},
|
||||
"node_modules/thenify-all": {
|
||||
"version": "1.6.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"thenify": ">= 3.1.0 < 4"
|
||||
@@ -17540,6 +17598,7 @@
|
||||
},
|
||||
"node_modules/ts-interface-checker": {
|
||||
"version": "0.1.13",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/ts-jest": {
|
||||
@@ -18282,6 +18341,7 @@
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
@@ -18341,6 +18401,7 @@
|
||||
"node_modules/wrap-ansi-cjs": {
|
||||
"name": "wrap-ansi",
|
||||
"version": "7.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
@@ -19688,7 +19749,7 @@
|
||||
},
|
||||
"packages/bruno-electron": {
|
||||
"name": "bruno",
|
||||
"version": "v1.12.3",
|
||||
"version": "v1.13.1",
|
||||
"dependencies": {
|
||||
"@aws-sdk/credential-providers": "3.525.0",
|
||||
"@usebruno/common": "0.1.0",
|
||||
@@ -20870,7 +20931,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": {
|
||||
"version": "5.2.0"
|
||||
"version": "5.2.0",
|
||||
"dev": true
|
||||
},
|
||||
"@ampproject/remapping": {
|
||||
"version": "2.2.1",
|
||||
@@ -22613,6 +22675,7 @@
|
||||
},
|
||||
"@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^5.1.2",
|
||||
"string-width-cjs": "npm:string-width@^4.2.0",
|
||||
@@ -22623,16 +22686,20 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "6.0.1"
|
||||
"version": "6.0.1",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "6.2.1"
|
||||
"version": "6.2.1",
|
||||
"dev": true
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "9.2.2"
|
||||
"version": "9.2.2",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "5.1.2",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
"emoji-regex": "^9.2.2",
|
||||
@@ -22641,12 +22708,14 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "7.1.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "8.1.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
"string-width": "^5.0.1",
|
||||
@@ -23422,6 +23491,7 @@
|
||||
},
|
||||
"@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@playwright/test": {
|
||||
@@ -23949,14 +24019,6 @@
|
||||
"mini-svg-data-uri": "^1.2.3"
|
||||
}
|
||||
},
|
||||
"@tailwindcss/forms": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz",
|
||||
"integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==",
|
||||
"requires": {
|
||||
"mini-svg-data-uri": "^1.2.3"
|
||||
}
|
||||
},
|
||||
"@tippyjs/react": {
|
||||
"version": "4.2.6",
|
||||
"requires": {
|
||||
@@ -25534,7 +25596,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"any-promise": {
|
||||
"version": "1.3.0"
|
||||
"version": "1.3.0",
|
||||
"dev": true
|
||||
},
|
||||
"anymatch": {
|
||||
"version": "3.1.3",
|
||||
@@ -25633,7 +25696,8 @@
|
||||
}
|
||||
},
|
||||
"arg": {
|
||||
"version": "5.0.2"
|
||||
"version": "5.0.2",
|
||||
"dev": true
|
||||
},
|
||||
"argparse": {
|
||||
"version": "2.0.1"
|
||||
@@ -27164,7 +27228,8 @@
|
||||
"camelcase-css": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
||||
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="
|
||||
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
|
||||
"dev": true
|
||||
},
|
||||
"camelize": {
|
||||
"version": "1.0.1"
|
||||
@@ -27650,6 +27715,7 @@
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -27757,7 +27823,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"cssesc": {
|
||||
"version": "3.0.0"
|
||||
"version": "3.0.0",
|
||||
"dev": true
|
||||
},
|
||||
"cssnano": {
|
||||
"version": "5.1.15",
|
||||
@@ -27951,7 +28018,8 @@
|
||||
"optional": true
|
||||
},
|
||||
"didyoumean": {
|
||||
"version": "1.2.2"
|
||||
"version": "1.2.2",
|
||||
"dev": true
|
||||
},
|
||||
"diff-sequences": {
|
||||
"version": "29.6.3",
|
||||
@@ -27990,7 +28058,8 @@
|
||||
}
|
||||
},
|
||||
"dlv": {
|
||||
"version": "1.1.3"
|
||||
"version": "1.1.3",
|
||||
"dev": true
|
||||
},
|
||||
"dmg-builder": {
|
||||
"version": "23.0.2",
|
||||
@@ -28111,7 +28180,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"eastasianwidth": {
|
||||
"version": "0.2.0"
|
||||
"version": "0.2.0",
|
||||
"dev": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
@@ -28817,13 +28887,15 @@
|
||||
},
|
||||
"foreground-child": {
|
||||
"version": "3.1.1",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-spawn": "^7.0.0",
|
||||
"signal-exit": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"signal-exit": {
|
||||
"version": "4.1.0"
|
||||
"version": "4.1.0",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -29678,6 +29750,7 @@
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.13.1",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
@@ -29819,7 +29892,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0"
|
||||
"version": "2.0.0",
|
||||
"dev": true
|
||||
},
|
||||
"isobject": {
|
||||
"version": "3.0.1"
|
||||
@@ -29899,6 +29973,7 @@
|
||||
},
|
||||
"jackspeak": {
|
||||
"version": "2.3.6",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@isaacs/cliui": "^8.0.2",
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
@@ -30690,7 +30765,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"lilconfig": {
|
||||
"version": "2.1.0"
|
||||
"version": "2.1.0",
|
||||
"dev": true
|
||||
},
|
||||
"lines-and-columns": {
|
||||
"version": "1.2.4"
|
||||
@@ -31055,7 +31131,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "5.0.0"
|
||||
"version": "5.0.0",
|
||||
"devOptional": true
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "2.1.2",
|
||||
@@ -31118,6 +31195,7 @@
|
||||
},
|
||||
"mz": {
|
||||
"version": "2.7.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"any-promise": "^1.0.0",
|
||||
"object-assign": "^4.0.1",
|
||||
@@ -31330,7 +31408,8 @@
|
||||
"object-hash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||
"dev": true
|
||||
},
|
||||
"object-inspect": {
|
||||
"version": "1.13.1"
|
||||
@@ -31546,20 +31625,24 @@
|
||||
"dev": true
|
||||
},
|
||||
"path-key": {
|
||||
"version": "3.1.1"
|
||||
"version": "3.1.1",
|
||||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.7"
|
||||
"version": "1.0.7",
|
||||
"dev": true
|
||||
},
|
||||
"path-scurry": {
|
||||
"version": "1.10.1",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lru-cache": "^9.1.1 || ^10.0.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lru-cache": {
|
||||
"version": "10.2.0"
|
||||
"version": "10.2.0",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -31687,7 +31770,8 @@
|
||||
}
|
||||
},
|
||||
"pirates": {
|
||||
"version": "4.0.6"
|
||||
"version": "4.0.6",
|
||||
"dev": true
|
||||
},
|
||||
"pixelmatch": {
|
||||
"version": "4.0.2",
|
||||
@@ -31781,6 +31865,7 @@
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.4.35",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.0",
|
||||
@@ -31788,7 +31873,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"nanoid": {
|
||||
"version": "3.3.7"
|
||||
"version": "3.3.7",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -31840,6 +31926,7 @@
|
||||
},
|
||||
"postcss-import": {
|
||||
"version": "15.1.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"postcss-value-parser": "^4.0.0",
|
||||
"read-cache": "^1.0.0",
|
||||
@@ -31850,6 +31937,7 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
|
||||
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase-css": "^2.0.1"
|
||||
}
|
||||
@@ -31958,6 +32046,7 @@
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
|
||||
"integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"postcss-selector-parser": "^6.0.11"
|
||||
}
|
||||
@@ -32056,6 +32145,7 @@
|
||||
},
|
||||
"postcss-selector-parser": {
|
||||
"version": "6.0.15",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
@@ -32448,12 +32538,14 @@
|
||||
},
|
||||
"read-cache": {
|
||||
"version": "1.0.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pify": "^2.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "2.3.0"
|
||||
"version": "2.3.0",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -32788,6 +32880,7 @@
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.8",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-core-module": "^2.13.0",
|
||||
"path-parse": "^1.0.7",
|
||||
@@ -33142,12 +33235,14 @@
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "3.0.0"
|
||||
"version": "3.0.0",
|
||||
"dev": true
|
||||
},
|
||||
"side-channel": {
|
||||
"version": "1.0.5",
|
||||
@@ -33375,6 +33470,7 @@
|
||||
},
|
||||
"string-width-cjs": {
|
||||
"version": "npm:string-width@4.2.3",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
@@ -33402,6 +33498,7 @@
|
||||
},
|
||||
"strip-ansi-cjs": {
|
||||
"version": "npm:strip-ansi@6.0.1",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
@@ -33472,6 +33569,7 @@
|
||||
},
|
||||
"sucrase": {
|
||||
"version": "3.35.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@jridgewell/gen-mapping": "^0.3.2",
|
||||
"commander": "^4.0.0",
|
||||
@@ -33484,15 +33582,18 @@
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "4.1.1"
|
||||
"version": "4.1.1",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "10.3.10",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^2.3.5",
|
||||
@@ -33503,6 +33604,7 @@
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "9.0.3",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
}
|
||||
@@ -33523,7 +33625,8 @@
|
||||
}
|
||||
},
|
||||
"supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0"
|
||||
"version": "1.0.0",
|
||||
"dev": true
|
||||
},
|
||||
"svg2png": {
|
||||
"version": "4.1.1",
|
||||
@@ -33645,6 +33748,7 @@
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz",
|
||||
"integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
@@ -33674,6 +33778,7 @@
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.3"
|
||||
}
|
||||
@@ -33681,12 +33786,14 @@
|
||||
"jiti": {
|
||||
"version": "1.21.0",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
|
||||
"integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q=="
|
||||
"integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
|
||||
"dev": true
|
||||
},
|
||||
"postcss-load-config": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
|
||||
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lilconfig": "^3.0.0",
|
||||
"yaml": "^2.3.4"
|
||||
@@ -33695,14 +33802,16 @@
|
||||
"lilconfig": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
|
||||
"integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ=="
|
||||
"integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"yaml": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
|
||||
"integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg=="
|
||||
"integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -33812,12 +33921,14 @@
|
||||
},
|
||||
"thenify": {
|
||||
"version": "3.3.1",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"any-promise": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"thenify-all": {
|
||||
"version": "1.6.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"thenify": ">= 3.1.0 < 4"
|
||||
}
|
||||
@@ -33932,7 +34043,8 @@
|
||||
}
|
||||
},
|
||||
"ts-interface-checker": {
|
||||
"version": "0.1.13"
|
||||
"version": "0.1.13",
|
||||
"dev": true
|
||||
},
|
||||
"ts-jest": {
|
||||
"version": "29.1.2",
|
||||
@@ -34379,6 +34491,7 @@
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
@@ -34418,6 +34531,7 @@
|
||||
},
|
||||
"wrap-ansi-cjs": {
|
||||
"version": "npm:wrap-ansi@7.0.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||
"@reduxjs/toolkit": "^1.8.0",
|
||||
"@tabler/icons": "^1.46.0",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"@usebruno/common": "0.1.0",
|
||||
"@usebruno/graphql-docs": "0.1.0",
|
||||
|
||||
@@ -232,7 +232,7 @@ export default class CodeEditor extends React.Component {
|
||||
let curWord = start != end && currentLine.slice(start, end);
|
||||
//Qualify if autocomplete will be shown
|
||||
if (
|
||||
/^(?!Shift|Tab|Enter|ArrowUp|ArrowDown|ArrowLeft|ArrowRight|\s)\w*/.test(event.key) &&
|
||||
/^(?!Shift|Tab|Enter|Escape|ArrowUp|ArrowDown|ArrowLeft|ArrowRight|\s)\w*/.test(event.key) &&
|
||||
curWord.length > 0 &&
|
||||
!/\/\/|\/\*|.*{{|`[^$]*{|`[^{]*$/.test(currentLine.slice(0, end)) &&
|
||||
/(?<!\d)[a-zA-Z\._]$/.test(curWord)
|
||||
|
||||
@@ -9,7 +9,7 @@ const StyledWrapper = styled.div`
|
||||
color: ${(props) => props.theme.colors.text.yellow};
|
||||
}
|
||||
|
||||
input {
|
||||
.non-passphrase-input {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ import { IconCertificate, IconTrash, IconWorld } from '@tabler/icons';
|
||||
import { useFormik } from 'formik';
|
||||
import { uuid } from 'utils/common';
|
||||
import * as Yup from 'yup';
|
||||
import { IconEye, IconEyeOff } from '@tabler/icons';
|
||||
import { useState } from 'react';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
@@ -29,6 +31,8 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
|
||||
formik.values[e.name] = e.files[0].path;
|
||||
};
|
||||
|
||||
const [passwordVisible, setPasswordVisible] = useState(false);
|
||||
|
||||
return (
|
||||
<StyledWrapper className="w-full h-full">
|
||||
<div className="text-xs mb-4 text-muted">Add client certificates to be used for specific domains.</div>
|
||||
@@ -63,7 +67,7 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
|
||||
type="text"
|
||||
name="domain"
|
||||
placeholder="*.example.org"
|
||||
className="block textbox"
|
||||
className="block textbox non-passphrase-input"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.domain || ''}
|
||||
/>
|
||||
@@ -79,7 +83,7 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
|
||||
id="certFilePath"
|
||||
type="file"
|
||||
name="certFilePath"
|
||||
className="block"
|
||||
className="block non-passphrase-input"
|
||||
onChange={(e) => getFile(e.target)}
|
||||
/>
|
||||
{formik.touched.certFilePath && formik.errors.certFilePath ? (
|
||||
@@ -94,7 +98,7 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
|
||||
id="keyFilePath"
|
||||
type="file"
|
||||
name="keyFilePath"
|
||||
className="block"
|
||||
className="block non-passphrase-input"
|
||||
onChange={(e) => getFile(e.target)}
|
||||
/>
|
||||
{formik.touched.keyFilePath && formik.errors.keyFilePath ? (
|
||||
@@ -105,14 +109,23 @@ const ClientCertSettings = ({ clientCertConfig, onUpdate, onRemove }) => {
|
||||
<label className="settings-label" htmlFor="passphrase">
|
||||
Passphrase
|
||||
</label>
|
||||
<input
|
||||
id="passphrase"
|
||||
type="password"
|
||||
name="passphrase"
|
||||
className="block textbox"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.passphrase || ''}
|
||||
/>
|
||||
<div className="textbox flex flex-row items-center w-[300px] h-[1.70rem] relative">
|
||||
<input
|
||||
id="passphrase"
|
||||
type={passwordVisible ? 'text' : 'password'}
|
||||
name="passphrase"
|
||||
className="outline-none w-64 bg-transparent"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.passphrase || ''}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm absolute right-0 l"
|
||||
onClick={() => setPasswordVisible(!passwordVisible)}
|
||||
>
|
||||
{passwordVisible ? <IconEyeOff size={18} strokeWidth={1.5} /> : <IconEye size={18} strokeWidth={1.5} />}
|
||||
</button>
|
||||
</div>
|
||||
{formik.touched.passphrase && formik.errors.passphrase ? (
|
||||
<div className="ml-1 text-red-500">{formik.errors.passphrase}</div>
|
||||
) : null}
|
||||
|
||||
@@ -36,7 +36,7 @@ const Info = ({ collection }) => {
|
||||
</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>
|
||||
<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>
|
||||
|
||||
@@ -4,6 +4,8 @@ import Tooltip from 'components/Tooltip';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import * as Yup from 'yup';
|
||||
import toast from 'react-hot-toast';
|
||||
import { IconEye, IconEyeOff } from '@tabler/icons';
|
||||
import { useState } from 'react';
|
||||
|
||||
const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
const proxySchema = Yup.object({
|
||||
@@ -78,6 +80,7 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
});
|
||||
}
|
||||
});
|
||||
const [passwordVisible, setPasswordVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
formik.setValues({
|
||||
@@ -277,18 +280,27 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => {
|
||||
<label className="settings-label" htmlFor="auth.password">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
id="auth.password"
|
||||
type="password"
|
||||
name="auth.password"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={formik.values.auth.password}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
<div className="textbox flex flex-row items-center w-[13.2rem] h-[1.70rem] relative">
|
||||
<input
|
||||
id="auth.password"
|
||||
type={passwordVisible ? 'text' : 'password'}
|
||||
name="auth.password"
|
||||
className="outline-none bg-transparent w-[10.5rem]"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={formik.values.auth.password}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm absolute right-0"
|
||||
onClick={() => setPasswordVisible(!passwordVisible)}
|
||||
>
|
||||
{passwordVisible ? <IconEyeOff size={18} strokeWidth={1.5} /> : <IconEye size={18} strokeWidth={1.5} />}
|
||||
</button>
|
||||
</div>
|
||||
{formik.touched.auth?.password && formik.errors.auth?.password ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.auth.password}</div>
|
||||
) : null}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
max-height: 200px;
|
||||
overflow: auto;
|
||||
|
||||
.CodeMirror {
|
||||
background: transparent;
|
||||
height: fit-content;
|
||||
font-size: 14px;
|
||||
line-height: 30px;
|
||||
overflow: hidden;
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: hidden !important;
|
||||
${'' /* padding-bottom: 50px !important; */}
|
||||
position: relative;
|
||||
display: contents;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.CodeMirror-vscrollbar,
|
||||
.CodeMirror-hscrollbar,
|
||||
.CodeMirror-scrollbar-filler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-cursor {
|
||||
height: 20px !important;
|
||||
margin-top: 5px !important;
|
||||
border-left: 1px solid ${(props) => props.theme.text} !important;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: Inter, sans-serif !important;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.CodeMirror-line {
|
||||
color: ${(props) => props.theme.text};
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-selected {
|
||||
background-color: rgba(212, 125, 59, 0.3);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledWrapper;
|
||||
140
packages/bruno-app/src/components/MultiLineEditor/index.js
Normal file
140
packages/bruno-app/src/components/MultiLineEditor/index.js
Normal file
@@ -0,0 +1,140 @@
|
||||
import React, { Component } from 'react';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import { getAllVariables } from 'utils/collections';
|
||||
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
let CodeMirror;
|
||||
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
||||
|
||||
if (!SERVER_RENDERED) {
|
||||
CodeMirror = require('codemirror');
|
||||
}
|
||||
|
||||
class MultiLineEditor extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
// Keep a cached version of the value, this cache will be updated when the
|
||||
// editor is updated, which can later be used to protect the editor from
|
||||
// unnecessary updates during the update lifecycle.
|
||||
this.cachedValue = props.value || '';
|
||||
this.editorRef = React.createRef();
|
||||
this.variables = {};
|
||||
}
|
||||
componentDidMount() {
|
||||
// Initialize CodeMirror as a single line editor
|
||||
/** @type {import("codemirror").Editor} */
|
||||
this.editor = CodeMirror(this.editorRef.current, {
|
||||
lineWrapping: false,
|
||||
lineNumbers: false,
|
||||
theme: this.props.theme === 'dark' ? 'monokai' : 'default',
|
||||
mode: 'brunovariables',
|
||||
brunoVarInfo: {
|
||||
variables: getAllVariables(this.props.collection)
|
||||
},
|
||||
scrollbarStyle: null,
|
||||
tabindex: 0,
|
||||
extraKeys: {
|
||||
Enter: () => {
|
||||
if (this.props.onRun) {
|
||||
this.props.onRun();
|
||||
}
|
||||
},
|
||||
'Ctrl-Enter': () => {
|
||||
if (this.props.onRun) {
|
||||
this.props.onRun();
|
||||
}
|
||||
},
|
||||
'Cmd-Enter': () => {
|
||||
if (this.props.onRun) {
|
||||
this.props.onRun();
|
||||
}
|
||||
},
|
||||
'Alt-Enter': () => {
|
||||
this.editor.setValue(this.editor.getValue() + '\n');
|
||||
this.editor.setCursor({ line: this.editor.lineCount(), ch: 0 });
|
||||
},
|
||||
'Shift-Enter': () => {
|
||||
this.editor.setValue(this.editor.getValue() + '\n');
|
||||
this.editor.setCursor({ line: this.editor.lineCount(), ch: 0 });
|
||||
},
|
||||
'Cmd-S': () => {
|
||||
if (this.props.onSave) {
|
||||
this.props.onSave();
|
||||
}
|
||||
},
|
||||
'Ctrl-S': () => {
|
||||
if (this.props.onSave) {
|
||||
this.props.onSave();
|
||||
}
|
||||
},
|
||||
'Cmd-F': () => {},
|
||||
'Ctrl-F': () => {},
|
||||
// Tabbing disabled to make tabindex work
|
||||
Tab: false,
|
||||
'Shift-Tab': false
|
||||
}
|
||||
});
|
||||
if (this.props.autocomplete) {
|
||||
this.editor.on('keyup', (cm, event) => {
|
||||
if (!cm.state.completionActive /*Enables keyboard navigation in autocomplete list*/ && event.keyCode != 13) {
|
||||
/*Enter - do not open autocomplete list just after item has been selected in it*/
|
||||
CodeMirror.commands.autocomplete(cm, CodeMirror.hint.anyword, { autocomplete: this.props.autocomplete });
|
||||
}
|
||||
});
|
||||
}
|
||||
this.editor.setValue(String(this.props.value) || '');
|
||||
this.editor.on('change', this._onEdit);
|
||||
this.addOverlay();
|
||||
}
|
||||
|
||||
_onEdit = () => {
|
||||
if (!this.ignoreChangeEvent && this.editor) {
|
||||
this.cachedValue = this.editor.getValue();
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(this.cachedValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
// Ensure the changes caused by this update are not interpreted as
|
||||
// user-input changes which could otherwise result in an infinite
|
||||
// event loop.
|
||||
this.ignoreChangeEvent = true;
|
||||
|
||||
let variables = getAllVariables(this.props.collection);
|
||||
if (!isEqual(variables, this.variables)) {
|
||||
this.editor.options.brunoVarInfo.variables = variables;
|
||||
this.addOverlay();
|
||||
}
|
||||
if (this.props.theme !== prevProps.theme && this.editor) {
|
||||
this.editor.setOption('theme', this.props.theme === 'dark' ? 'monokai' : 'default');
|
||||
}
|
||||
if (this.props.value !== prevProps.value && this.props.value !== this.cachedValue && this.editor) {
|
||||
this.cachedValue = String(this.props.value);
|
||||
this.editor.setValue(String(this.props.value) || '');
|
||||
}
|
||||
if (this.editorRef?.current) {
|
||||
this.editorRef.current.scrollTo(0, 10000);
|
||||
}
|
||||
this.ignoreChangeEvent = false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.editor.getWrapperElement().remove();
|
||||
}
|
||||
|
||||
addOverlay = () => {
|
||||
let variables = getAllVariables(this.props.collection);
|
||||
this.variables = variables;
|
||||
|
||||
defineCodeMirrorBrunoVariablesMode(variables, 'text/plain');
|
||||
this.editor.setOption('mode', 'brunovariables');
|
||||
};
|
||||
|
||||
render() {
|
||||
return <StyledWrapper ref={this.editorRef} className="single-line-editor"></StyledWrapper>;
|
||||
}
|
||||
}
|
||||
export default MultiLineEditor;
|
||||
@@ -6,6 +6,8 @@ import { savePreferences } from 'providers/ReduxStore/slices/app';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { IconEye, IconEyeOff } from '@tabler/icons';
|
||||
import { useState } from 'react';
|
||||
|
||||
const ProxySettings = ({ close }) => {
|
||||
const preferences = useSelector((state) => state.app.preferences);
|
||||
@@ -88,6 +90,8 @@ const ProxySettings = ({ close }) => {
|
||||
});
|
||||
};
|
||||
|
||||
const [passwordVisible, setPasswordVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
formik.setValues({
|
||||
enabled: preferences.proxy.enabled || false,
|
||||
@@ -164,6 +168,7 @@ const ProxySettings = ({ close }) => {
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-3 flex items-center">
|
||||
<label className="settings-label" htmlFor="hostname">
|
||||
Hostname
|
||||
@@ -240,18 +245,27 @@ const ProxySettings = ({ close }) => {
|
||||
<label className="settings-label" htmlFor="auth.password">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
id="auth.password"
|
||||
type="password"
|
||||
name="auth.password"
|
||||
className="block textbox"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={formik.values.auth.password}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
<div className="textbox flex flex-row items-center w-[13.2rem] h-[2.25rem] relative">
|
||||
<input
|
||||
id="auth.password"
|
||||
type={passwordVisible ? `text` : 'password'}
|
||||
name="auth.password"
|
||||
className="outline-none w-[10.5rem] bg-transparent"
|
||||
autoComplete="off"
|
||||
autoCorrect="off"
|
||||
autoCapitalize="off"
|
||||
spellCheck="false"
|
||||
value={formik.values.auth.password}
|
||||
onChange={formik.handleChange}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm absolute right-0"
|
||||
onClick={() => setPasswordVisible(!passwordVisible)}
|
||||
>
|
||||
{passwordVisible ? <IconEyeOff size={18} strokeWidth={2} /> : <IconEye size={18} strokeWidth={2} />}
|
||||
</button>
|
||||
</div>
|
||||
{formik.touched.auth?.password && formik.errors.auth?.password ? (
|
||||
<div className="ml-3 text-red-500">{formik.errors.auth.password}</div>
|
||||
) : null}
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
updateFormUrlEncodedParam,
|
||||
deleteFormUrlEncodedParam
|
||||
} from 'providers/ReduxStore/slices/collections';
|
||||
import SingleLineEditor from 'components/SingleLineEditor';
|
||||
import MultiLineEditor from 'components/MultiLineEditor';
|
||||
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
@@ -92,7 +92,7 @@ const FormUrlEncodedParams = ({ item, collection }) => {
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<SingleLineEditor
|
||||
<MultiLineEditor
|
||||
value={param.value}
|
||||
theme={storedTheme}
|
||||
onSave={onSave}
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
updateMultipartFormParam,
|
||||
deleteMultipartFormParam
|
||||
} from 'providers/ReduxStore/slices/collections';
|
||||
import SingleLineEditor from 'components/SingleLineEditor';
|
||||
import MultiLineEditor from 'components/MultiLineEditor';
|
||||
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import FilePickerEditor from 'components/FilePickerEditor';
|
||||
@@ -121,7 +121,7 @@ const MultipartFormParams = ({ item, collection }) => {
|
||||
collection={collection}
|
||||
/>
|
||||
) : (
|
||||
<SingleLineEditor
|
||||
<MultiLineEditor
|
||||
onSave={onSave}
|
||||
theme={storedTheme}
|
||||
value={param.value}
|
||||
@@ -137,6 +137,7 @@ const MultipartFormParams = ({ item, collection }) => {
|
||||
)
|
||||
}
|
||||
onRun={handleRun}
|
||||
allowNewlines={true}
|
||||
collection={collection}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -115,6 +115,7 @@ const RequestHeaders = ({ item, collection }) => {
|
||||
)
|
||||
}
|
||||
onRun={handleRun}
|
||||
allowNewlines={true}
|
||||
collection={collection}
|
||||
/>
|
||||
</td>
|
||||
|
||||
@@ -79,7 +79,7 @@ const ImportCollection = ({ onClose, handleSubmit }) => {
|
||||
</div>
|
||||
<div className="flex justify-start w-full mt-4 max-w-[450px]">
|
||||
{Object.entries(options || {}).map(([key, option]) => (
|
||||
<div className="relative flex items-start">
|
||||
<div key={key} className="relative flex items-start">
|
||||
<div className="flex h-6 items-center">
|
||||
<input
|
||||
id="comments"
|
||||
|
||||
@@ -129,7 +129,7 @@ const Sidebar = () => {
|
||||
Star
|
||||
</GitHubButton> */}
|
||||
</div>
|
||||
<div className="flex flex-grow items-center justify-end text-xs mr-2">v1.13.1</div>
|
||||
<div className="flex flex-grow items-center justify-end text-xs mr-2">v1.14.0</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,20 +13,15 @@ const StyledWrapper = styled.div`
|
||||
line-height: 30px;
|
||||
overflow: hidden;
|
||||
|
||||
.CodeMirror-vscrollbar {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: hidden !important;
|
||||
padding-bottom: 50px !important;
|
||||
}
|
||||
|
||||
.CodeMirror-hscrollbar {
|
||||
display: none !important;
|
||||
}
|
||||
.CodeMirror-vscrollbar,
|
||||
.CodeMirror-hscrollbar,
|
||||
.CodeMirror-scrollbar-filler {
|
||||
display: none !important;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.CodeMirror-lines {
|
||||
@@ -46,8 +41,7 @@ const StyledWrapper = styled.div`
|
||||
|
||||
.CodeMirror-line {
|
||||
color: ${(props) => props.theme.text};
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-selected {
|
||||
|
||||
@@ -9,40 +9,6 @@ const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODE
|
||||
|
||||
if (!SERVER_RENDERED) {
|
||||
CodeMirror = require('codemirror');
|
||||
CodeMirror.registerHelper('hint', 'anyword', (editor, options) => {
|
||||
const word = /[\w$-]+/;
|
||||
const wordlist = (options && options.autocomplete) || [];
|
||||
let cur = editor.getCursor(),
|
||||
curLine = editor.getLine(cur.line);
|
||||
let end = cur.ch,
|
||||
start = end;
|
||||
while (start && word.test(curLine.charAt(start - 1))) --start;
|
||||
let curWord = start != end && curLine.slice(start, end);
|
||||
|
||||
// Check if curWord is a valid string before proceeding
|
||||
if (typeof curWord !== 'string' || curWord.length < 3) {
|
||||
return null; // Abort the hint
|
||||
}
|
||||
|
||||
const list = (options && options.list) || [];
|
||||
const re = new RegExp(word.source, 'g');
|
||||
for (let dir = -1; dir <= 1; dir += 2) {
|
||||
let line = cur.line,
|
||||
endLine = Math.min(Math.max(line + dir * 500, editor.firstLine()), editor.lastLine()) + dir;
|
||||
for (; line != endLine; line += dir) {
|
||||
let text = editor.getLine(line),
|
||||
m;
|
||||
while ((m = re.exec(text))) {
|
||||
if (line == cur.line && curWord.length < 3) continue;
|
||||
list.push(...wordlist.filter((el) => el.toLowerCase().startsWith(curWord.toLowerCase())));
|
||||
}
|
||||
}
|
||||
}
|
||||
return { list: [...new Set(list)], from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end) };
|
||||
});
|
||||
CodeMirror.commands.autocomplete = (cm, hint, options) => {
|
||||
cm.showHint({ hint, ...options });
|
||||
};
|
||||
}
|
||||
|
||||
class SingleLineEditor extends Component {
|
||||
|
||||
@@ -41,6 +41,7 @@ if (!SERVER_RENDERED) {
|
||||
|
||||
require('utils/codemirror/brunoVarInfo');
|
||||
require('utils/codemirror/javascript-lint');
|
||||
require('utils/codemirror/autocomplete');
|
||||
}
|
||||
|
||||
export default function Main() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import React from 'react';
|
||||
|
||||
import Bruno from 'components/Bruno/index';
|
||||
|
||||
class ErrorBoundary extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -14,29 +16,61 @@ class ErrorBoundary extends React.Component {
|
||||
}
|
||||
componentDidCatch(error, errorInfo) {
|
||||
console.log({ error, errorInfo });
|
||||
this.setState({ hasError: true, error, errorInfo });
|
||||
}
|
||||
|
||||
returnToApp() {
|
||||
const { ipcRenderer } = window;
|
||||
ipcRenderer.invoke('open-file');
|
||||
|
||||
this.setState({ hasError: false, error: null, errorInfo: null });
|
||||
}
|
||||
|
||||
forceQuit() {
|
||||
const { ipcRenderer } = window;
|
||||
ipcRenderer.invoke('main:force-quit');
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div className="flex items-center justify-center p-10">
|
||||
<div className="bg-white rounded-lg shadow-lg p-4 w-full">
|
||||
<div className="flex text-center justify-center p-20 h-full">
|
||||
<div className="bg-white rounded-lg p-10 w-full">
|
||||
<div className="m-auto" style={{ width: '256px' }}>
|
||||
<Bruno width={256} />
|
||||
</div>
|
||||
|
||||
<h1 className="text-2xl font-semibold text-red-600 mb-2">Oops! Something went wrong</h1>
|
||||
<p className="text-red-600 mb-2">{this.state.error && this.state.error.toString()}</p>
|
||||
{this.state.error && this.state.error.stack && (
|
||||
<pre className="bg-gray-100 p-2 rounded-lg overflow-auto">{this.state.error.stack}</pre>
|
||||
)}
|
||||
<p className="text-red-500 mb-2">
|
||||
If you are using an official production build: the above error is most likely a bug!
|
||||
<br />
|
||||
Please report this under:
|
||||
<a
|
||||
className="text-link hover:underline cursor-pointer ml-2"
|
||||
href="https://github.com/usebruno/bruno/issues"
|
||||
target="_blank"
|
||||
>
|
||||
https://github.com/usebruno/bruno/issues
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<button
|
||||
className="bg-red-500 text-white px-4 py-2 mt-4 rounded hover:bg-red-600 transition"
|
||||
onClick={() => {
|
||||
this.setState({ hasError: false, error: null });
|
||||
}}
|
||||
onClick={() => this.returnToApp()}
|
||||
>
|
||||
Close
|
||||
Return to App
|
||||
</button>
|
||||
|
||||
<div className="text-red-500 mt-3">
|
||||
<a href="" className="hover:underline cursor-pointer" onClick={this.forceQuit}>
|
||||
Force Quit
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ const trackStart = () => {
|
||||
event: 'start',
|
||||
properties: {
|
||||
os: platformLib.os.family,
|
||||
version: '1.13.1'
|
||||
version: '1.14.0'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
40
packages/bruno-app/src/utils/codemirror/autocomplete.js
Normal file
40
packages/bruno-app/src/utils/codemirror/autocomplete.js
Normal file
@@ -0,0 +1,40 @@
|
||||
let CodeMirror;
|
||||
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
||||
|
||||
if (!SERVER_RENDERED) {
|
||||
CodeMirror = require('codemirror');
|
||||
CodeMirror.registerHelper('hint', 'anyword', (editor, options) => {
|
||||
const word = /[\w$-]+/;
|
||||
const wordlist = (options && options.autocomplete) || [];
|
||||
let cur = editor.getCursor(),
|
||||
curLine = editor.getLine(cur.line);
|
||||
let end = cur.ch,
|
||||
start = end;
|
||||
while (start && word.test(curLine.charAt(start - 1))) --start;
|
||||
let curWord = start != end && curLine.slice(start, end);
|
||||
|
||||
// Check if curWord is a valid string before proceeding
|
||||
if (typeof curWord !== 'string' || curWord.length < 3) {
|
||||
return null; // Abort the hint
|
||||
}
|
||||
|
||||
const list = (options && options.list) || [];
|
||||
const re = new RegExp(word.source, 'g');
|
||||
for (let dir = -1; dir <= 1; dir += 2) {
|
||||
let line = cur.line,
|
||||
endLine = Math.min(Math.max(line + dir * 500, editor.firstLine()), editor.lastLine()) + dir;
|
||||
for (; line != endLine; line += dir) {
|
||||
let text = editor.getLine(line),
|
||||
m;
|
||||
while ((m = re.exec(text))) {
|
||||
if (line == cur.line && curWord.length < 3) continue;
|
||||
list.push(...wordlist.filter((el) => el.toLowerCase().startsWith(curWord.toLowerCase())));
|
||||
}
|
||||
}
|
||||
}
|
||||
return { list: [...new Set(list)], from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end) };
|
||||
});
|
||||
CodeMirror.commands.autocomplete = (cm, hint, options) => {
|
||||
cm.showHint({ hint, ...options });
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "v1.13.1",
|
||||
"version": "v1.14.0",
|
||||
"name": "bruno",
|
||||
"description": "Opensource API Client for Exploring and Testing APIs",
|
||||
"homepage": "https://www.usebruno.com",
|
||||
|
||||
@@ -628,6 +628,10 @@ const registerMainEventHandlers = (mainWindow, watcher, lastOpenedCollections) =
|
||||
ipcMain.handle('main:complete-quit-flow', () => {
|
||||
mainWindow.destroy();
|
||||
});
|
||||
|
||||
ipcMain.handle('main:force-quit', () => {
|
||||
process.exit();
|
||||
});
|
||||
};
|
||||
|
||||
const registerCollectionsIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
||||
|
||||
@@ -35,12 +35,16 @@ const grammar = ohm.grammar(`Bru {
|
||||
keychar = ~(tagend | st | nl | ":") any
|
||||
valuechar = ~(nl | tagend) any
|
||||
|
||||
// Multiline text block surrounded by '''
|
||||
multilinetextblockdelimiter = "'''"
|
||||
multilinetextblock = multilinetextblockdelimiter (~multilinetextblockdelimiter any)* multilinetextblockdelimiter
|
||||
|
||||
// Dictionary Blocks
|
||||
dictionary = st* "{" pairlist? tagend
|
||||
pairlist = optionalnl* pair (~tagend stnl* pair)* (~tagend space)*
|
||||
pair = st* key st* ":" st* value st*
|
||||
key = keychar*
|
||||
value = valuechar*
|
||||
value = multilinetextblock | valuechar*
|
||||
|
||||
// Dictionary for Assert Block
|
||||
assertdictionary = st* "{" assertpairlist? tagend
|
||||
@@ -186,6 +190,19 @@ const sem = grammar.createSemantics().addAttribute('ast', {
|
||||
return chars.sourceString ? chars.sourceString.trim() : '';
|
||||
},
|
||||
value(chars) {
|
||||
try {
|
||||
let isMultiline = chars.sourceString?.startsWith(`'''`) && chars.sourceString?.endsWith(`'''`);
|
||||
if (isMultiline) {
|
||||
const multilineString = chars.sourceString?.replace(/^'''|'''$/g, '');
|
||||
return multilineString
|
||||
.split('\n')
|
||||
.map((line) => line.slice(4))
|
||||
.join('\n');
|
||||
}
|
||||
return chars.sourceString ? chars.sourceString.trim() : '';
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
return chars.sourceString ? chars.sourceString.trim() : '';
|
||||
},
|
||||
assertdictionary(_1, _2, pairlist, _3) {
|
||||
|
||||
@@ -12,6 +12,23 @@ const stripLastLine = (text) => {
|
||||
return text.replace(/(\r?\n)$/, '');
|
||||
};
|
||||
|
||||
const getValueString = (value) => {
|
||||
const hasNewLines = value.includes('\n');
|
||||
|
||||
if (!hasNewLines) {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Add one level of indentation to the contents of the multistring
|
||||
const indentedLines = value
|
||||
.split('\n')
|
||||
.map((line) => ` ${line}`)
|
||||
.join('\n');
|
||||
|
||||
// Join the lines back together with newline characters and enclose them in triple single quotes
|
||||
return `'''\n${indentedLines}\n'''`;
|
||||
};
|
||||
|
||||
const jsonToBru = (json) => {
|
||||
const { meta, http, query, headers, auth, body, script, tests, vars, assertions, docs } = json;
|
||||
|
||||
@@ -202,24 +219,23 @@ ${indentString(body.sparql)}
|
||||
}
|
||||
|
||||
if (body && body.formUrlEncoded && body.formUrlEncoded.length) {
|
||||
bru += `body:form-urlencoded {`;
|
||||
bru += `body:form-urlencoded {\n`;
|
||||
|
||||
if (enabled(body.formUrlEncoded).length) {
|
||||
bru += `\n${indentString(
|
||||
enabled(body.formUrlEncoded)
|
||||
.map((item) => `${item.name}: ${item.value}`)
|
||||
.join('\n')
|
||||
)}`;
|
||||
const enabledValues = enabled(body.formUrlEncoded)
|
||||
.map((item) => `${item.name}: ${getValueString(item.value)}`)
|
||||
.join('\n');
|
||||
bru += `${indentString(enabledValues)}\n`;
|
||||
}
|
||||
|
||||
if (disabled(body.formUrlEncoded).length) {
|
||||
bru += `\n${indentString(
|
||||
disabled(body.formUrlEncoded)
|
||||
.map((item) => `~${item.name}: ${item.value}`)
|
||||
.join('\n')
|
||||
)}`;
|
||||
const disabledValues = disabled(body.formUrlEncoded)
|
||||
.map((item) => `~${item.name}: ${getValueString(item.value)}`)
|
||||
.join('\n');
|
||||
bru += `${indentString(disabledValues)}\n`;
|
||||
}
|
||||
|
||||
bru += '\n}\n\n';
|
||||
bru += '}\n\n';
|
||||
}
|
||||
|
||||
if (body && body.multipartForm && body.multipartForm.length) {
|
||||
|
||||
54
packages/bruno-tests/collection/scripting/get-env-name.bru
Normal file
54
packages/bruno-tests/collection/scripting/get-env-name.bru
Normal file
@@ -0,0 +1,54 @@
|
||||
meta {
|
||||
name: get-env-name
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
auth:awsv4 {
|
||||
accessKeyId: a
|
||||
secretAccessKey: b
|
||||
sessionToken: c
|
||||
service: d
|
||||
region: e
|
||||
profileName: f
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
const envName = bru.getEnvName();
|
||||
bru.setVar("testEnvName", envName);
|
||||
}
|
||||
|
||||
tests {
|
||||
test("should get env name in scripts", function() {
|
||||
const testEnvName = bru.getVar("testEnvName");
|
||||
expect(testEnvName).to.equal("Prod");
|
||||
});
|
||||
}
|
||||
|
||||
docs {
|
||||
# API Documentation
|
||||
|
||||
## Introduction
|
||||
|
||||
Welcome to the API documentation for [Your API Name]. This document provides instructions on how to make requests to the API and covers available authentication methods.
|
||||
|
||||
## Authentication
|
||||
|
||||
Before making requests to the API, you need to authenticate your application. [Your API Name] supports the following authentication methods:
|
||||
|
||||
### API Key
|
||||
|
||||
To use API key authentication, include your API key in the request headers as follows:
|
||||
|
||||
```http
|
||||
GET /api/endpoint
|
||||
Host: api.example.com
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
}
|
||||
49
packages/bruno-tests/collection/scripting/get-env-var.bru
Normal file
49
packages/bruno-tests/collection/scripting/get-env-var.bru
Normal file
@@ -0,0 +1,49 @@
|
||||
meta {
|
||||
name: get-env-var
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
auth:awsv4 {
|
||||
accessKeyId: a
|
||||
secretAccessKey: b
|
||||
sessionToken: c
|
||||
service: d
|
||||
region: e
|
||||
profileName: f
|
||||
}
|
||||
|
||||
tests {
|
||||
test("should get env var in scripts", function() {
|
||||
const host = bru.getEnvVar("host")
|
||||
expect(host).to.equal("https://testbench-sanity.usebruno.com");
|
||||
});
|
||||
}
|
||||
|
||||
docs {
|
||||
# API Documentation
|
||||
|
||||
## Introduction
|
||||
|
||||
Welcome to the API documentation for [Your API Name]. This document provides instructions on how to make requests to the API and covers available authentication methods.
|
||||
|
||||
## Authentication
|
||||
|
||||
Before making requests to the API, you need to authenticate your application. [Your API Name] supports the following authentication methods:
|
||||
|
||||
### API Key
|
||||
|
||||
To use API key authentication, include your API key in the request headers as follows:
|
||||
|
||||
```http
|
||||
GET /api/endpoint
|
||||
Host: api.example.com
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
}
|
||||
54
packages/bruno-tests/collection/scripting/set-env-var.bru
Normal file
54
packages/bruno-tests/collection/scripting/set-env-var.bru
Normal file
@@ -0,0 +1,54 @@
|
||||
meta {
|
||||
name: set-env-var
|
||||
type: http
|
||||
seq: 3
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
auth:awsv4 {
|
||||
accessKeyId: a
|
||||
secretAccessKey: b
|
||||
sessionToken: c
|
||||
service: d
|
||||
region: e
|
||||
profileName: f
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
bru.setEnvVar("testSetEnvVar", "bruno-29653")
|
||||
}
|
||||
|
||||
tests {
|
||||
test("should set env var in scripts", function() {
|
||||
const testSetEnvVar = bru.getEnvVar("testSetEnvVar")
|
||||
console.log(testSetEnvVar);
|
||||
expect(testSetEnvVar).to.equal("bruno-29653");
|
||||
});
|
||||
}
|
||||
|
||||
docs {
|
||||
# API Documentation
|
||||
|
||||
## Introduction
|
||||
|
||||
Welcome to the API documentation for [Your API Name]. This document provides instructions on how to make requests to the API and covers available authentication methods.
|
||||
|
||||
## Authentication
|
||||
|
||||
Before making requests to the API, you need to authenticate your application. [Your API Name] supports the following authentication methods:
|
||||
|
||||
### API Key
|
||||
|
||||
To use API key authentication, include your API key in the request headers as follows:
|
||||
|
||||
```http
|
||||
GET /api/endpoint
|
||||
Host: api.example.com
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
[](https://www.usebruno.com)
|
||||
[](https://www.usebruno.com/downloads)
|
||||
|
||||
**English** | [Українська](docs/readme/readme_ua.md) | [Русский](docs/readme/readme_ru.md) | [Türkçe](docs/readme/readme_tr.md) | [Deutsch](docs/readme/readme_de.md) | [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)
|
||||
**English** | [Українська](docs/readme/readme_ua.md) | [Русский](docs/readme/readme_ru.md) | [Türkçe](docs/readme/readme_tr.md) | [Deutsch](docs/readme/readme_de.md) | [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)
|
||||
|
||||
Bruno is a new and innovative API client, aimed at revolutionizing the status quo represented by Postman and similar tools out there.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user