Merge branch 'usebruno:main' into feature/1602-multipart-content-type

This commit is contained in:
busy-panda🐼🐼 2024-04-24 11:47:07 +02:00 committed by GitHub
commit cdf56fcec1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 279 additions and 149 deletions

View File

@ -1,51 +0,0 @@
name: Publish to Snapcraft
on:
workflow_dispatch:
inputs:
build:
description: 'Build and publish to Snapcraft'
required: true
default: 'true'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Check package-lock.json
run: npm ci --legacy-peer-deps
- name: Install dependencies
run: npm install --legacy-peer-deps
- name: Build Electron app
run: |
npm run build:bruno-common
npm run build:bruno-query
npm run build:graphql-docs
npm run build:web
npm run build:electron:snap
- name: Install Snapcraft
run: |
sudo snap install snapcraft --classic
continue-on-error: true
- name: Configure Snapcraft
run: snapcraft whoami
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_API_KEY }}
- name: Publish to Snapcraft
run: |
snapcraft upload --release=stable packages/bruno-electron/out/*.snap
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAPCRAFT_API_KEY }}

139
docs/readme/readme_ar.md Normal file
View File

@ -0,0 +1,139 @@
<br />
<img src="assets/images/logo-transparent.png" width="80"/>
### برونو - بيئة تطوير مفتوحة المصدر لاستكشاف واختبار واجهات برمجة التطبيقات (APIs).
[![GitHub version](https://badge.fury.io/gh/usebruno%2Fbruno.svg)](https://badge.fury.io/gh/usebruno%bruno)
[![CI](https://github.com/usebruno/bruno/actions/workflows/unit-tests.yml/badge.svg?branch=main)](https://github.com/usebruno/bruno/workflows/unit-tests.yml)
[![Commit Activity](https://img.shields.io/github/commit-activity/m/usebruno/bruno)](https://github.com/usebruno/bruno/pulse)
[![X](https://img.shields.io/twitter/follow/use_bruno?style=social&logo=x)](https://twitter.com/use_bruno)
[![Website](https://img.shields.io/badge/Website-Visit-blue)](https://www.usebruno.com)
[![Download](https://img.shields.io/badge/Download-Latest-brightgreen)](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)
![bruno](https://github.com/usebruno/bruno/blob/main/assets/images/landing-2.png) <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
```
### التشغيل عبر منصات متعددة 🖥️
![bruno](https://github.com/usebruno/bruno/blob/main/assets/images/run-anywhere.png) <br /><br />
### التعاون عبر Git 👩‍💻🧑‍💻
أو أي نظام تحكم في الإصدار الذي تفضله
![bruno](https://github.com/usebruno/bruno/blob/main/assets/images/version-control.png) <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)

48
package-lock.json generated
View File

@ -4791,17 +4791,6 @@
}
}
},
"node_modules/@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==",
"dependencies": {
"mini-svg-data-uri": "^1.2.3"
},
"peerDependencies": {
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1"
}
},
"node_modules/@tippyjs/react": {
"version": "4.2.6",
"license": "MIT",
@ -12837,14 +12826,6 @@
"url": "https://opencollective.com/webpack"
}
},
"node_modules/mini-svg-data-uri": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
"integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
"bin": {
"mini-svg-data-uri": "cli.js"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"license": "ISC",
@ -18611,7 +18592,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",
@ -18705,13 +18685,13 @@
},
"packages/bruno-cli": {
"name": "@usebruno/cli",
"version": "1.11.0",
"version": "1.14.0",
"license": "MIT",
"dependencies": {
"@aws-sdk/credential-providers": "3.525.0",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.11.0",
"@usebruno/lang": "0.11.0",
"@usebruno/lang": "0.12.0",
"aws4-axios": "^3.3.0",
"axios": "^1.5.1",
"chai": "^4.3.7",
@ -19749,12 +19729,12 @@
},
"packages/bruno-electron": {
"name": "bruno",
"version": "v1.13.1",
"version": "v1.14.0",
"dependencies": {
"@aws-sdk/credential-providers": "3.525.0",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.11.0",
"@usebruno/lang": "0.11.0",
"@usebruno/lang": "0.12.0",
"@usebruno/schema": "0.7.0",
"about-window": "^1.15.2",
"aws4-axios": "^3.3.0",
@ -20868,7 +20848,7 @@
},
"packages/bruno-lang": {
"name": "@usebruno/lang",
"version": "0.11.0",
"version": "0.12.0",
"license": "MIT",
"dependencies": {
"arcsecond": "^5.0.0",
@ -24006,14 +23986,6 @@
"@tabler/icons": {
"version": "1.119.0"
},
"@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": {
@ -24270,7 +24242,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",
@ -24356,7 +24327,7 @@
"@aws-sdk/credential-providers": "3.525.0",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.11.0",
"@usebruno/lang": "0.11.0",
"@usebruno/lang": "0.12.0",
"aws4-axios": "^3.3.0",
"axios": "^1.5.1",
"chai": "^4.3.7",
@ -26168,7 +26139,7 @@
"@aws-sdk/credential-providers": "3.525.0",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.11.0",
"@usebruno/lang": "0.11.0",
"@usebruno/lang": "0.12.0",
"@usebruno/schema": "0.7.0",
"about-window": "^1.15.2",
"aws4-axios": "^3.3.0",
@ -31098,11 +31069,6 @@
}
}
},
"mini-svg-data-uri": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
"integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg=="
},
"minimatch": {
"version": "3.1.2",
"requires": {

View File

@ -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",

View File

@ -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)

View File

@ -9,7 +9,7 @@ const StyledWrapper = styled.div`
color: ${(props) => props.theme.colors.text.yellow};
}
input {
.non-passphrase-input {
width: 300px;
}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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"

View File

@ -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>

View File

@ -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;
}
}

View File

@ -60,7 +60,7 @@ const trackStart = () => {
event: 'start',
properties: {
os: platformLib.os.family,
version: '1.13.1'
version: '1.14.0'
}
});
};

View File

@ -1,6 +1,6 @@
{
"name": "@usebruno/cli",
"version": "1.11.0",
"version": "1.14.0",
"license": "MIT",
"main": "src/index.js",
"bin": {
@ -27,7 +27,7 @@
"@aws-sdk/credential-providers": "3.525.0",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.11.0",
"@usebruno/lang": "0.11.0",
"@usebruno/lang": "0.12.0",
"aws4-axios": "^3.3.0",
"axios": "^1.5.1",
"chai": "^4.3.7",

View File

@ -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",
@ -22,7 +22,7 @@
"@aws-sdk/credential-providers": "3.525.0",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.11.0",
"@usebruno/lang": "0.11.0",
"@usebruno/lang": "0.12.0",
"@usebruno/schema": "0.7.0",
"about-window": "^1.15.2",
"aws4-axios": "^3.3.0",

View File

@ -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) => {

View File

@ -1,6 +1,6 @@
{
"name": "@usebruno/lang",
"version": "0.11.0",
"version": "0.12.0",
"license": "MIT",
"main": "src/index.js",
"files": [

View File

@ -10,7 +10,7 @@
[![Website](https://img.shields.io/badge/Website-Visit-blue)](https://www.usebruno.com)
[![Download](https://img.shields.io/badge/Download-Latest-brightgreen)](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.