Merge branch 'main' into feature/CodeMirror_AutoComplete

This commit is contained in:
n00o 2023-11-17 08:51:55 -05:00
commit 4f56506dac
19 changed files with 1145 additions and 61 deletions

View File

@ -1,4 +1,4 @@
**English** | [Українська](docs/contributing/contributing_ua.md) | [Русский](docs/contributing/contributing_ru.md) | [Türkçe](docs/contributing/contributing_tr.md) | [Deutsch](docs/contributing/contributing_de.md) | [Français](docs/contributing/contributing_fr.md) **English** | [Українська](docs/contributing/contributing_ua.md) | [Русский](docs/contributing/contributing_ru.md) | [Türkçe](docs/contributing/contributing_tr.md) | [Deutsch](docs/contributing/contributing_de.md) | [Français](docs/contributing/contributing_fr.md) | [Português (BR)](docs/contributing/contributing_pt_br.md)
## Let's make bruno better, together !! ## Let's make bruno better, together !!

View File

@ -0,0 +1,85 @@
## Vamos tornar o Bruno melhor, juntos!!
Estamos felizes que você queira ajudar a melhorar o Bruno. Abaixo estão as diretrizes e orientações para começar a executar o Bruno no seu computador.
### Stack de Tecnologias
O Bruno é construído usando Next.js e React. Também usamos o Electron para disponibilizar uma versão para desktop (que suporta coleções locais).
Bibliotecas que utilizamos:
- CSS - Tailwind
- Editor de Código - Codemirror
- Gerenciador de Estado - Redux
- Ícones - Tabler Icons
- Formulários - formik
- Validador de Schema - Yup
- Cliente de Requisições - axios
- Monitor de Arquivos - chokidar
### Dependências
Você precisará do [Node v18.x (ou da versão LTS mais recente)](https://nodejs.org/en/) e do npm na versão 8.x. Nós utilizamos npm workspaces no projeto.
## Desenvolvimento
Bruno está sendo desenvolvido como um aplicativo de desktop. Você precisa carregar o programa executando o aplicativo Next.js em um terminal e, em seguida, executar o aplicativo Electron em outro terminal.
### Dependências
- NodeJS v18
### Desenvolvimento Local
```bash
# use nodejs 18 version
nvm use
# install deps
npm i --legacy-peer-deps
# build graphql docs
npm run build:graphql-docs
# build bruno query
npm run build:bruno-query
# run next app (terminal 1)
npm run dev:web
# run electron app (terminal 2)
npm run dev:electron
```
### Troubleshooting
Você pode se deparar com o erro `Unsupported platform` ao executar o comando `npm install`. Para corrigir isso, você precisará excluir a pasta `node_modules` e o arquivo `package-lock.json` e, em seguida, executar o comando `npm install` novamente. Isso deve instalar todos os pacotes necessários para executar o aplicativo.
```shell
# delete node_modules in sub-directories
find ./ -type d -name "node_modules" -print0 | while read -d $'\0' dir; do
rm -rf "$dir"
done
# delete package-lock in sub-directories
find . -type f -name "package-lock.json" -delete
```
### Testando
```bash
# bruno-schema
npm test --workspace=packages/bruno-schema
# bruno-lang
npm test --workspace=packages/bruno-lang
```
### Envio de Pull Request
- Por favor, mantenha os PRs pequenos e focados em uma única coisa.
- Siga o formato de criação de branches.
- feature/[nome da funcionalidade]: Esta branch deve conter alterações para uma funcionalidade específica.
- Exemplo: feature/dark-mode
- bugfix/[nome do bug]: Esta branch deve conter apenas correções para um bug específico.
- Exemplo: bugfix/bug-1

View File

@ -0,0 +1,5 @@
### Publicando Bruno em um novo gerenciador de pacotes
Embora nosso código seja de código aberto e esteja disponível para todos usarem, pedimos gentilmente que entre em contato conosco antes de considerar a publicação em novos gerenciadores de pacotes. Como o criador da ferramenta, mantenho a marca registrada `Bruno` para este projeto e gostaria de gerenciar sua distribuição. Se deseja ver o Bruno em um novo gerenciador de pacotes, por favor, solicite através de uma issue no GitHub.
Embora a maioria de nossas funcionalidades seja gratuita e de código aberto (o que abrange API's REST e GraphQL), buscamos alcançar um equilíbrio harmonioso entre os princípios de código aberto e sustentabilidade. - https://github.com/usebruno/bruno/discussions/269

121
docs/readme/readme_pt_br.md Normal file
View File

@ -0,0 +1,121 @@
<br />
<img src="../../assets/images/logo-transparent.png" width="80"/>
### Bruno - IDE de código aberto para explorar e testar 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)
Bruno é um novo e inovador cliente de API, com o objetivo de revolucionar o status quo representado por ferramentas como o Postman e outras semelhantes.
Bruno armazena suas coleções diretamente em uma pasta no seu sistema de arquivos. Utilizamos uma linguagem de marcação de texto simples, chamada Bru, para salvar informações sobre requisições de API.
Você pode usar o Git ou qualquer sistema de controle de versão de sua escolha para colaborar em suas coleções de API.
Bruno é totalmente offline. Não há planos de adicionar sincronização em nuvem ao Bruno, nunca. Valorizamos a privacidade de seus dados e acreditamos que eles devem permanecer em seu dispositivo. Saiba mais sobre nossa visão a longo prazo [aqui](https://github.com/usebruno/bruno/discussions/269).
📢 Assista à nossa palestra recente na India FOSS 3.0 Conference [aqui](https://www.youtube.com/watch?v=7bSMFpbcPiY).
![bruno](../../assets/images/landing-2.png) <br /><br />
### Instalação
Bruno está disponível para download como binário [em nosso site](https://www.usebruno.com/downloads) para Mac, Windows e Linux.
Você também pode instalar o Bruno via gerenciadores de pacotes como Homebrew, Chocolatey, Snap e Apt.
```sh
# Mac via Homebrew
brew install bruno
# Windows via Chocolatey
choco install bruno
# Linux via Snap
snap install bruno
# Linux via Apt
sudo mkdir -p /etc/apt/keyrings
sudo gpg --no-default-keyring --keyring /etc/apt/keyrings/bruno.gpg --keyserver keyserver.ubuntu.com --recv-keys 9FA6017ECABE0266
echo "deb [signed-by=/etc/apt/keyrings/bruno.gpg] http://debian.usebruno.com/ bruno stable" | sudo tee /etc/apt/sources.list.d/bruno.list
sudo apt update
sudo apt install bruno
```
### Execute em várias plataformas 🖥️
![bruno](../../assets/images/run-anywhere.png) <br /><br />
### Colaboração via Git 👩‍💻🧑‍💻
Ou qualquer sistema de controle de versão de sua escolha.
![bruno](../../assets/images/version-control.png) <br /><br />
### Links Importantes 📌
- [Nossa Visão de Longo Prazo](https://github.com/usebruno/bruno/discussions/269)
- [Roadmap](https://github.com/usebruno/bruno/discussions/384)
- [Documentação](https://docs.usebruno.com)
- [Website](https://www.usebruno.com)
- [Preços](https://www.usebruno.com/pricing)
- [Download](https://www.usebruno.com/downloads)
### Showcase 🎥
- [Depoimentos](https://github.com/usebruno/bruno/discussions/343)
- [Hub de Conhecimento](https://github.com/usebruno/bruno/discussions/386)
- [Scriptmania](https://github.com/usebruno/bruno/discussions/385)
### Apoie ❤️
Au-au! Se você gosta do projeto, clique no botão ⭐!!
### Compartilhe sua experiência 📣
Se o Bruno ajudou no seu trabalho e/ou no trabalho de sua equipe, por favor, não se esqueça de compartilhar seu [depoimento em nossas discussões no GitHub](https://github.com/usebruno/bruno/discussions/343).
### Publicando em Novos Gerenciadores de Pacotes
Por favor, verifique [aqui](../publishing/publishing_pt_br.md) mais informações.
### Colabore 👩‍💻🧑‍💻
Fico feliz que você queira melhorar o Bruno. Por favor, confira o [guia de colaboração](../contributing/contributing_pt_br.md).
Mesmo que você não possa contribuir codificando, não deixe de relatar problemas e solicitar recursos que precisam ser implementados para atender ao contexto de seu dia a dia.
### Authors
<div align="center">
<a href="https://github.com/usebruno/bruno/graphs/contributors">
<img src="https://contrib.rocks/image?repo=usebruno/bruno" />
</a>
</div>
### Mantenha Contato 🌐
[𝕏 (Twitter)](https://twitter.com/use_bruno) <br />
[Website](https://www.usebruno.com) <br />
[Discord](https://discord.com/invite/KgcZUncpjq) <br />
[LinkedIn](https://www.linkedin.com/company/usebruno)
### Trademark
**Nome**
`Bruno` é uma marca registrada de [Anoop M D](https://www.helloanoop.com/).
**Logo**
A logo é original do [OpenMoji](https://openmoji.org/library/emoji-1F436/). Licença: CC [BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/).
### Licença 📄
[MIT](license.md)

897
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,7 @@
"nanoid": "3.3.4", "nanoid": "3.3.4",
"next": "12.3.3", "next": "12.3.3",
"path": "^0.12.7", "path": "^0.12.7",
"pdfjs-dist": "^3.11.174",
"platform": "^1.3.6", "platform": "^1.3.6",
"posthog-node": "^2.1.0", "posthog-node": "^2.1.0",
"qs": "^6.11.0", "qs": "^6.11.0",
@ -59,6 +60,7 @@
"react-github-btn": "^1.4.0", "react-github-btn": "^1.4.0",
"react-hot-toast": "^2.4.0", "react-hot-toast": "^2.4.0",
"react-inspector": "^6.0.2", "react-inspector": "^6.0.2",
"react-pdf": "^7.5.1",
"react-redux": "^7.2.6", "react-redux": "^7.2.6",
"react-tooltip": "^5.5.2", "react-tooltip": "^5.5.2",
"sass": "^1.46.0", "sass": "^1.46.0",

View File

@ -2,6 +2,11 @@ import CodeEditor from 'components/CodeEditor/index';
import { get } from 'lodash'; import { get } from 'lodash';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { sendRequest } from 'providers/ReduxStore/slices/collections/actions'; import { sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import { Document, Page } from 'react-pdf';
import { useState } from 'react';
import 'pdfjs-dist/build/pdf.worker';
import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
import 'react-pdf/dist/esm/Page/TextLayer.css';
const QueryResultPreview = ({ const QueryResultPreview = ({
previewTab, previewTab,
@ -19,6 +24,10 @@ const QueryResultPreview = ({
const preferences = useSelector((state) => state.app.preferences); const preferences = useSelector((state) => state.app.preferences);
const dispatch = useDispatch(); const dispatch = useDispatch();
const [numPages, setNumPages] = useState(null);
function onDocumentLoadSuccess({ numPages }) {
setNumPages(numPages);
}
// Fail safe, so we don't render anything with an invalid tab // Fail safe, so we don't render anything with an invalid tab
if (!allowedPreviewModes.includes(previewTab)) { if (!allowedPreviewModes.includes(previewTab)) {
return null; return null;
@ -45,6 +54,17 @@ const QueryResultPreview = ({
case 'preview-image': { case 'preview-image': {
return <img src={`data:${contentType.replace(/\;(.*)/, '')};base64,${dataBuffer}`} className="mx-auto" />; return <img src={`data:${contentType.replace(/\;(.*)/, '')};base64,${dataBuffer}`} className="mx-auto" />;
} }
case 'preview-pdf': {
return (
<div className="preview-pdf" style={{ height: '100%', overflow: 'auto', maxHeight: 'calc(100vh - 220px)' }}>
<Document file={`data:application/pdf;base64,${dataBuffer}`} onLoadSuccess={onDocumentLoadSuccess}>
{Array.from(new Array(numPages), (el, index) => (
<Page key={`page_${index + 1}`} pageNumber={index + 1} renderAnnotationLayer={false} />
))}
</Document>
</div>
);
}
default: default:
case 'raw': { case 'raw': {
return ( return (

View File

@ -18,6 +18,19 @@ const StyledWrapper = styled.div`
width: 100%; width: 100%;
} }
.react-pdf__Page {
margin-top: 10px;
background-color: transparent !important;
}
.react-pdf__Page__textContent {
border: 1px solid darkgrey;
box-shadow: 5px 5px 5px 1px #ccc;
border-radius: 0px;
margin: 0 auto;
}
.react-pdf__Page__canvas {
margin: 0 auto;
}
div[role='tablist'] { div[role='tablist'] {
.active { .active {
color: ${(props) => props.theme.colors.text.yellow}; color: ${(props) => props.theme.colors.text.yellow};

View File

@ -49,6 +49,8 @@ const QueryResult = ({ item, collection, data, dataBuffer, width, disableRunEven
allowedPreviewModes.unshift('preview-web'); allowedPreviewModes.unshift('preview-web');
} else if (mode.includes('image')) { } else if (mode.includes('image')) {
allowedPreviewModes.unshift('preview-image'); allowedPreviewModes.unshift('preview-image');
} else if (contentType.includes('pdf')) {
allowedPreviewModes.unshift('preview-pdf');
} }
return allowedPreviewModes; return allowedPreviewModes;

View File

@ -35,6 +35,10 @@ const StyledWrapper = styled.div`
} }
} }
} }
textarea.curl-command {
min-height: 150px;
}
`; `;
export default StyledWrapper; export default StyledWrapper;

View File

@ -1,4 +1,4 @@
import React, { useRef, useEffect } from 'react'; import React, { useRef, useEffect, useCallback } from 'react';
import { useFormik } from 'formik'; import { useFormik } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
@ -115,6 +115,25 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => {
const onSubmit = () => formik.handleSubmit(); const onSubmit = () => formik.handleSubmit();
const handlePaste = useCallback(
(event) => {
const clipboardData = event.clipboardData || window.clipboardData;
const pastedData = clipboardData.getData('Text');
// Check if pasted data looks like a cURL command
const curlCommandRegex = /^\s*curl\s/i;
if (curlCommandRegex.test(pastedData)) {
// Switch to the 'from-curl' request type
formik.setFieldValue('requestType', 'from-curl');
formik.setFieldValue('curlCommand', pastedData);
// Prevent the default paste behavior to avoid pasting into the textarea
event.preventDefault();
}
},
[formik]
);
return ( return (
<StyledWrapper> <StyledWrapper>
<Modal size="md" title="New Request" confirmText="Create" handleConfirm={onSubmit} handleCancel={onClose}> <Modal size="md" title="New Request" confirmText="Create" handleConfirm={onSubmit} handleCancel={onClose}>
@ -174,7 +193,7 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => {
Name Name
</label> </label>
<input <input
id="collection-name" id="request-name"
type="text" type="text"
name="requestName" name="requestName"
ref={inputRef} ref={inputRef}
@ -216,6 +235,7 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => {
spellCheck="false" spellCheck="false"
onChange={formik.handleChange} onChange={formik.handleChange}
value={formik.values.requestUrl || ''} value={formik.values.requestUrl || ''}
onPaste={handlePaste}
/> />
</div> </div>
</div> </div>
@ -232,8 +252,7 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => {
<textarea <textarea
name="curlCommand" name="curlCommand"
placeholder="Enter cURL request here.." placeholder="Enter cURL request here.."
className="block textbox w-full mt-4" className="block textbox w-full mt-4 curl-command"
style={{ resize: 'none' }}
value={formik.values.curlCommand} value={formik.values.curlCommand}
onChange={formik.handleChange} onChange={formik.handleChange}
></textarea> ></textarea>

View File

@ -105,7 +105,7 @@ const Sidebar = () => {
Star Star
</GitHubButton> </GitHubButton>
</div> </div>
<div className="flex flex-grow items-center justify-end text-xs mr-2">v1.1.0</div> <div className="flex flex-grow items-center justify-end text-xs mr-2">v1.1.1</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -46,8 +46,8 @@ describe('curlToJson', () => {
const result = curlToJson(curlCommand); const result = curlToJson(curlCommand);
expect(result).toEqual({ expect(result).toEqual({
url: '%27https://www.usebruno.com%27', url: 'https://www.usebruno.com',
raw_url: "'https://www.usebruno.com'", raw_url: 'https://www.usebruno.com',
method: 'post', method: 'post',
headers: { headers: {
Accept: 'application/json, text/plain, */*', Accept: 'application/json, text/plain, */*',

View File

@ -267,12 +267,7 @@ const getDefaultUrl = (serverObject) => {
}; };
const getSecurity = (apiSpec) => { const getSecurity = (apiSpec) => {
let supportedSchemes = apiSpec.security || []; let defaultSchemes = apiSpec.security || [];
if (supportedSchemes.length === 0) {
return {
supported: []
};
}
let securitySchemes = get(apiSpec, 'components.securitySchemes', {}); let securitySchemes = get(apiSpec, 'components.securitySchemes', {});
if (Object.keys(securitySchemes) === 0) { if (Object.keys(securitySchemes) === 0) {
@ -282,7 +277,7 @@ const getSecurity = (apiSpec) => {
} }
return { return {
supported: supportedSchemes.map((scheme) => { supported: defaultSchemes.map((scheme) => {
var schemeName = Object.keys(scheme)[0]; var schemeName = Object.keys(scheme)[0];
return securitySchemes[schemeName]; return securitySchemes[schemeName];
}), }),

View File

@ -1,5 +1,9 @@
# Changelog # Changelog
## 1.1.0
- Upgraded axios to 1.5.1
## 1.0.0 ## 1.0.0
- Announcing Stable Release - Announcing Stable Release

View File

@ -1,6 +1,6 @@
{ {
"name": "@usebruno/cli", "name": "@usebruno/cli",
"version": "1.0.0", "version": "1.1.0",
"license": "MIT", "license": "MIT",
"main": "src/index.js", "main": "src/index.js",
"bin": { "bin": {

View File

@ -1,5 +1,5 @@
{ {
"version": "v1.1.0", "version": "v1.1.1",
"name": "bruno", "name": "bruno",
"description": "Opensource API Client for Exploring and Testing APIs", "description": "Opensource API Client for Exploring and Testing APIs",
"homepage": "https://www.usebruno.com", "homepage": "https://www.usebruno.com",

View File

@ -1,3 +1,5 @@
**English** | [Português (BR)](docs/publishing/publishing_pt_br.md)
### Publishing Bruno to a new package manager ### Publishing Bruno to a new package manager
While our code is open source and available for everyone to use, we kindly request that you reach out to us before considering publication on new package managers. As the creator of Bruno, I hold the trademark `Bruno` for this project and would like to manage its distribution. If you'd like to see Bruno on a new package manager, please raise a GitHub issue. While our code is open source and available for everyone to use, we kindly request that you reach out to us before considering publication on new package managers. As the creator of Bruno, I hold the trademark `Bruno` for this project and would like to manage its distribution. If you'd like to see Bruno on a new package manager, please raise a GitHub issue.

View File

@ -10,7 +10,7 @@
[![Website](https://img.shields.io/badge/Website-Visit-blue)](https://www.usebruno.com) [![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) [![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) **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)
Bruno is a new and innovative API client, aimed at revolutionizing the status quo represented by Postman and similar tools out there. Bruno is a new and innovative API client, aimed at revolutionizing the status quo represented by Postman and similar tools out there.
@ -65,6 +65,7 @@ Or any version control system of your choice
- [Our Long Term Vision](https://github.com/usebruno/bruno/discussions/269) - [Our Long Term Vision](https://github.com/usebruno/bruno/discussions/269)
- [Roadmap](https://github.com/usebruno/bruno/discussions/384) - [Roadmap](https://github.com/usebruno/bruno/discussions/384)
- [Documentation](https://docs.usebruno.com) - [Documentation](https://docs.usebruno.com)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/bruno)
- [Website](https://www.usebruno.com) - [Website](https://www.usebruno.com)
- [Pricing](https://www.usebruno.com/pricing) - [Pricing](https://www.usebruno.com/pricing)
- [Download](https://www.usebruno.com/downloads) - [Download](https://www.usebruno.com/downloads)