From 4258e031c66ee6591c0cfacadada0a2fd6c33199 Mon Sep 17 00:00:00 2001 From: Max Wittig Date: Mon, 16 Oct 2023 14:05:44 +0200 Subject: [PATCH 01/53] docs(readme): add simple installation instructions Many people just want to know how to get it directly from the Github readme --- readme.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/readme.md b/readme.md index 8021a5b7a..006191f5b 100644 --- a/readme.md +++ b/readme.md @@ -22,6 +22,14 @@ Bruno is offline-only. There are no plans to add cloud-sync to Bruno, ever. We v ![bruno](assets/images/landing-2.png)

+### Installation + +Bruno is available as binary download [on our website](https://www.usebruno.com/downloads) or via homebrew + +```sh +brew install bruno +``` + ### Run across multiple platforms 🖥️ ![bruno](assets/images/run-anywhere.png)

From 5df9981e20f5df0a6a3497a963365181d77ce201 Mon Sep 17 00:00:00 2001 From: Vaugen Wakeling Date: Fri, 27 Oct 2023 00:34:16 +0100 Subject: [PATCH 02/53] feat: Adding ability to import postman graphql collections Fixes: #790 --- .../src/utils/importers/postman-collection.js | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/packages/bruno-app/src/utils/importers/postman-collection.js b/packages/bruno-app/src/utils/importers/postman-collection.js index bc7f475e6..d70aac9e8 100644 --- a/packages/bruno-app/src/utils/importers/postman-collection.js +++ b/packages/bruno-app/src/utils/importers/postman-collection.js @@ -14,6 +14,56 @@ const readFile = (files) => { }); }; +/** + * + * @param {string} query + * @returns {string} + */ +const parseGraphQLQuery = (query) => { + return query + .replace(/\s+/g, ' ') + .replace(/{ /g, '{') + .replace(/ {/g, '{') + .replace(/ }/g, '}') + .replace(/, /g, ',') + .replace(/ : /g, ': ') + .replace(/\n/g, ''); +}; + +const parseGraphQLVariables = (string) => { + const cleanedString = string.replace(/[\n\t]/g, '').replace(/\\"/g, '"'); + const variables = JSON.stringify(JSON.parse(cleanedString)); + return typeof variables === 'string' ? variables : ''; +}; + +const parseGraphQLRequest = (graphqlSource) => { + try { + let queryResultObject = { + query: '', + variables: '' + }; + + if (typeof graphqlSource === 'string') { + graphqlSource = JSON.parse(text); + } + + if (graphqlSource.hasOwnProperty('variables') && graphqlSource.variables !== '') { + queryResultObject.variables = parseGraphQLVariables(graphqlSource.variables); + } + + if (graphqlSource.hasOwnProperty('query') && graphqlSource.query !== '') { + queryResultObject.query = parseGraphQLQuery(graphqlSource.query); + } + + return queryResultObject; + } catch (e) { + return { + query: '', + variables: '' + }; + } +}; + const isItemAFolder = (item) => { return !item.request; }; @@ -133,6 +183,12 @@ const importPostmanV2CollectionItem = (brunoParent, item) => { } } + if (bodyMode === 'graphql') { + brunoRequestItem.type = 'graphql-request'; + brunoRequestItem.request.body.mode = 'graphql'; + brunoRequestItem.request.body.graphql = parseGraphQLRequest(i.request.body.graphql); + } + each(i.request.header, (header) => { brunoRequestItem.request.headers.push({ uid: uuid(), From a0fe80604ec52c77d311cac438528dccee339443 Mon Sep 17 00:00:00 2001 From: Max Heidinger Date: Fri, 27 Oct 2023 14:59:09 +0200 Subject: [PATCH 03/53] fix: fix graphql schema interpolation --- packages/bruno-electron/src/ipc/network/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 7c37256e9..dfb94f3f3 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -582,6 +582,7 @@ const registerNetworkIpc = (mainWindow) => { scriptingConfig ); + interpolateVars(preparedRequest, envVars, collection.collectionVariables, processEnvVars); const axiosInstance = await configureRequest( collection.uid, preparedRequest, From 99b25fc5b2e93078351b090c4f50adf2bba1cb48 Mon Sep 17 00:00:00 2001 From: Vaugen Wakeling Date: Fri, 27 Oct 2023 17:21:16 +0100 Subject: [PATCH 04/53] feat: Remove unneeded formatting --- .../src/utils/importers/postman-collection.js | 26 ++----------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/packages/bruno-app/src/utils/importers/postman-collection.js b/packages/bruno-app/src/utils/importers/postman-collection.js index d70aac9e8..eceafac20 100644 --- a/packages/bruno-app/src/utils/importers/postman-collection.js +++ b/packages/bruno-app/src/utils/importers/postman-collection.js @@ -14,28 +14,6 @@ const readFile = (files) => { }); }; -/** - * - * @param {string} query - * @returns {string} - */ -const parseGraphQLQuery = (query) => { - return query - .replace(/\s+/g, ' ') - .replace(/{ /g, '{') - .replace(/ {/g, '{') - .replace(/ }/g, '}') - .replace(/, /g, ',') - .replace(/ : /g, ': ') - .replace(/\n/g, ''); -}; - -const parseGraphQLVariables = (string) => { - const cleanedString = string.replace(/[\n\t]/g, '').replace(/\\"/g, '"'); - const variables = JSON.stringify(JSON.parse(cleanedString)); - return typeof variables === 'string' ? variables : ''; -}; - const parseGraphQLRequest = (graphqlSource) => { try { let queryResultObject = { @@ -48,11 +26,11 @@ const parseGraphQLRequest = (graphqlSource) => { } if (graphqlSource.hasOwnProperty('variables') && graphqlSource.variables !== '') { - queryResultObject.variables = parseGraphQLVariables(graphqlSource.variables); + queryResultObject.variables = graphqlSource.variables; } if (graphqlSource.hasOwnProperty('query') && graphqlSource.query !== '') { - queryResultObject.query = parseGraphQLQuery(graphqlSource.query); + queryResultObject.query = graphqlSource.query; } return queryResultObject; From 3838848b03cdf928eb48afecf3696488b857ae69 Mon Sep 17 00:00:00 2001 From: Tasos Piotopoulos Date: Sat, 28 Oct 2023 15:59:50 +0100 Subject: [PATCH 05/53] Add Digest Auth Support (MD5) --- .../CollectionSettings/Auth/AuthMode/index.js | 9 +++ .../Auth/DigestAuth/StyledWrapper.js | 16 ++++ .../Auth/DigestAuth/index.js | 71 +++++++++++++++++ .../CollectionSettings/Auth/index.js | 4 + .../RequestPane/Auth/AuthMode/index.js | 9 +++ .../Auth/DigestAuth/StyledWrapper.js | 16 ++++ .../RequestPane/Auth/DigestAuth/index.js | 76 ++++++++++++++++++ .../src/components/RequestPane/Auth/index.js | 4 + .../ReduxStore/slices/collections/index.js | 7 ++ .../bruno-app/src/utils/collections/index.js | 4 + .../utils/importers/insomnia-collection.js | 3 +- .../src/utils/importers/openapi-collection.js | 3 +- .../src/ipc/network/digestauth-helper.js | 79 +++++++++++++++++++ .../bruno-electron/src/ipc/network/index.js | 5 ++ .../src/ipc/network/interpolate-vars.js | 6 ++ .../src/ipc/network/prepare-request.js | 11 +++ packages/bruno-lang/v2/src/bruToJson.js | 18 ++++- .../bruno-lang/v2/src/collectionBruToJson.js | 18 ++++- packages/bruno-lang/v2/src/jsonToBru.js | 9 +++ .../bruno-lang/v2/src/jsonToCollectionBru.js | 9 +++ .../v2/tests/fixtures/collection.bru | 5 ++ .../v2/tests/fixtures/collection.json | 4 + .../bruno-lang/v2/tests/fixtures/request.bru | 5 ++ .../bruno-lang/v2/tests/fixtures/request.json | 4 + .../bruno-schema/src/collections/index.js | 12 ++- 25 files changed, 401 insertions(+), 6 deletions(-) create mode 100644 packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/StyledWrapper.js create mode 100644 packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/index.js create mode 100644 packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/StyledWrapper.js create mode 100644 packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/index.js create mode 100644 packages/bruno-electron/src/ipc/network/digestauth-helper.js diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/AuthMode/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/AuthMode/index.js index 5cf3a5f7a..747ee4d61 100644 --- a/packages/bruno-app/src/components/CollectionSettings/Auth/AuthMode/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/Auth/AuthMode/index.js @@ -61,6 +61,15 @@ const AuthMode = ({ collection }) => { > Bearer Token +
{ + dropdownTippyRef.current.hide(); + onModeChange('digest'); + }} + > + Digest Auth +
{ diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/StyledWrapper.js b/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/StyledWrapper.js new file mode 100644 index 000000000..c2bb5d207 --- /dev/null +++ b/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/StyledWrapper.js @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +const Wrapper = styled.div` + label { + font-size: 0.8125rem; + } + + .single-line-editor-wrapper { + padding: 0.15rem 0.4rem; + border-radius: 3px; + border: solid 1px ${(props) => props.theme.input.border}; + background-color: ${(props) => props.theme.input.bg}; + } +`; + +export default Wrapper; diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/index.js new file mode 100644 index 000000000..3e084c06d --- /dev/null +++ b/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/index.js @@ -0,0 +1,71 @@ +import React from 'react'; +import get from 'lodash/get'; +import { useTheme } from 'providers/Theme'; +import { useDispatch } from 'react-redux'; +import SingleLineEditor from 'components/SingleLineEditor'; +import { updateCollectionAuth } from 'providers/ReduxStore/slices/collections'; +import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions'; +import StyledWrapper from './StyledWrapper'; + +const DigestAuth = ({ collection }) => { + const dispatch = useDispatch(); + const { storedTheme } = useTheme(); + + const digestAuth = get(collection, 'root.request.auth.digest', {}); + + const handleSave = () => dispatch(saveCollectionRoot(collection.uid)); + + const handleUsernameChange = (username) => { + dispatch( + updateCollectionAuth({ + mode: 'digest', + collectionUid: collection.uid, + content: { + username: username, + password: digestAuth.password + } + }) + ); + }; + + const handlePasswordChange = (password) => { + dispatch( + updateCollectionAuth({ + mode: 'digest', + collectionUid: collection.uid, + content: { + username: digestAuth.username, + password: password + } + }) + ); + }; + + return ( + + +
+ handleUsernameChange(val)} + collection={collection} + /> +
+ + +
+ handlePasswordChange(val)} + collection={collection} + /> +
+
+ ); +}; + +export default DigestAuth; diff --git a/packages/bruno-app/src/components/CollectionSettings/Auth/index.js b/packages/bruno-app/src/components/CollectionSettings/Auth/index.js index d9e80358b..7873cfcd0 100644 --- a/packages/bruno-app/src/components/CollectionSettings/Auth/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/Auth/index.js @@ -5,6 +5,7 @@ import AuthMode from './AuthMode'; import AwsV4Auth from './AwsV4Auth'; import BearerAuth from './BearerAuth'; import BasicAuth from './BasicAuth'; +import DigestAuth from './DigestAuth'; import { saveCollectionRoot } from 'providers/ReduxStore/slices/collections/actions'; import StyledWrapper from './StyledWrapper'; @@ -25,6 +26,9 @@ const Auth = ({ collection }) => { case 'bearer': { return ; } + case 'digest': { + return ; + } } }; diff --git a/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/index.js b/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/index.js index 10130c3a9..8eb4fee90 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/index.js @@ -62,6 +62,15 @@ const AuthMode = ({ item, collection }) => { > Bearer Token
+
{ + dropdownTippyRef.current.hide(); + onModeChange('digest'); + }} + > + Digest Auth +
{ diff --git a/packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/StyledWrapper.js new file mode 100644 index 000000000..c2bb5d207 --- /dev/null +++ b/packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/StyledWrapper.js @@ -0,0 +1,16 @@ +import styled from 'styled-components'; + +const Wrapper = styled.div` + label { + font-size: 0.8125rem; + } + + .single-line-editor-wrapper { + padding: 0.15rem 0.4rem; + border-radius: 3px; + border: solid 1px ${(props) => props.theme.input.border}; + background-color: ${(props) => props.theme.input.bg}; + } +`; + +export default Wrapper; diff --git a/packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/index.js b/packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/index.js new file mode 100644 index 000000000..e43f18c46 --- /dev/null +++ b/packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/index.js @@ -0,0 +1,76 @@ +import React from 'react'; +import get from 'lodash/get'; +import { useTheme } from 'providers/Theme'; +import { useDispatch } from 'react-redux'; +import SingleLineEditor from 'components/SingleLineEditor'; +import { updateAuth } from 'providers/ReduxStore/slices/collections'; +import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions'; +import StyledWrapper from './StyledWrapper'; + +const DigestAuth = ({ item, collection }) => { + const dispatch = useDispatch(); + const { storedTheme } = useTheme(); + + const digestAuth = item.draft ? get(item, 'draft.request.auth.digest', {}) : get(item, 'request.auth.digest', {}); + + const handleRun = () => dispatch(sendRequest(item, collection.uid)); + const handleSave = () => dispatch(saveRequest(item.uid, collection.uid)); + + const handleUsernameChange = (username) => { + dispatch( + updateAuth({ + mode: 'digest', + collectionUid: collection.uid, + itemUid: item.uid, + content: { + username: username, + password: digestAuth.password + } + }) + ); + }; + + const handlePasswordChange = (password) => { + dispatch( + updateAuth({ + mode: 'digest', + collectionUid: collection.uid, + itemUid: item.uid, + content: { + username: digestAuth.username, + password: password + } + }) + ); + }; + + return ( + + +
+ handleUsernameChange(val)} + onRun={handleRun} + collection={collection} + /> +
+ + +
+ handlePasswordChange(val)} + onRun={handleRun} + collection={collection} + /> +
+
+ ); +}; + +export default DigestAuth; diff --git a/packages/bruno-app/src/components/RequestPane/Auth/index.js b/packages/bruno-app/src/components/RequestPane/Auth/index.js index 669f4a843..bd388737e 100644 --- a/packages/bruno-app/src/components/RequestPane/Auth/index.js +++ b/packages/bruno-app/src/components/RequestPane/Auth/index.js @@ -4,6 +4,7 @@ import AuthMode from './AuthMode'; import AwsV4Auth from './AwsV4Auth'; import BearerAuth from './BearerAuth'; import BasicAuth from './BasicAuth'; +import DigestAuth from './DigestAuth'; import StyledWrapper from './StyledWrapper'; const Auth = ({ item, collection }) => { @@ -20,6 +21,9 @@ const Auth = ({ item, collection }) => { case 'bearer': { return ; } + case 'digest': { + return ; + } } }; diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js index 4ad30d204..24655f4f0 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js @@ -388,6 +388,10 @@ export const collectionsSlice = createSlice({ item.draft.request.auth.mode = 'basic'; item.draft.request.auth.basic = action.payload.content; break; + case 'digest': + item.draft.request.auth.mode = 'digest'; + item.draft.request.auth.digest = action.payload.content; + break; } } } @@ -976,6 +980,9 @@ export const collectionsSlice = createSlice({ case 'basic': set(collection, 'root.request.auth.basic', action.payload.content); break; + case 'digest': + set(collection, 'root.request.auth.digest', action.payload.content); + break; } } }, diff --git a/packages/bruno-app/src/utils/collections/index.js b/packages/bruno-app/src/utils/collections/index.js index 0b98fbc28..05dd0fb43 100644 --- a/packages/bruno-app/src/utils/collections/index.js +++ b/packages/bruno-app/src/utils/collections/index.js @@ -494,6 +494,10 @@ export const humanizeRequestAuthMode = (mode) => { label = 'Bearer Token'; break; } + case 'digest': { + label = 'Digest Auth'; + break; + } } return label; diff --git a/packages/bruno-app/src/utils/importers/insomnia-collection.js b/packages/bruno-app/src/utils/importers/insomnia-collection.js index 8d8113b49..80e9bb0a0 100644 --- a/packages/bruno-app/src/utils/importers/insomnia-collection.js +++ b/packages/bruno-app/src/utils/importers/insomnia-collection.js @@ -80,7 +80,8 @@ const transformInsomniaRequestItem = (request, index, allRequests) => { auth: { mode: 'none', basic: null, - bearer: null + bearer: null, + digest: null }, headers: [], params: [], diff --git a/packages/bruno-app/src/utils/importers/openapi-collection.js b/packages/bruno-app/src/utils/importers/openapi-collection.js index 1ca6e25b7..20a915bd4 100644 --- a/packages/bruno-app/src/utils/importers/openapi-collection.js +++ b/packages/bruno-app/src/utils/importers/openapi-collection.js @@ -69,7 +69,8 @@ const transformOpenapiRequestItem = (request) => { auth: { mode: 'none', basic: null, - bearer: null + bearer: null, + digest: null }, headers: [], params: [], diff --git a/packages/bruno-electron/src/ipc/network/digestauth-helper.js b/packages/bruno-electron/src/ipc/network/digestauth-helper.js new file mode 100644 index 000000000..fdcf77cc2 --- /dev/null +++ b/packages/bruno-electron/src/ipc/network/digestauth-helper.js @@ -0,0 +1,79 @@ +const crypto = require('crypto'); + +function isStrPresent(str) { + return str && str !== '' && str !== 'undefined'; +} + +function stripQuotes(str) { + return str.replace(/"/g, ''); +} + +function containsDigestHeader(response) { + const authHeader = response?.headers?.['www-authenticate']; + return authHeader ? authHeader.trim().toLowerCase().startsWith('digest') : false; +} + +function containsAuthorizationHeader(originalRequest) { + return Boolean(originalRequest.headers['Authorization']); +} + +function md5(input) { + return crypto.createHash('md5').update(input).digest('hex'); +} + +function addDigestInterceptor(axiosInstance, request) { + const { username, password } = request.digestConfig; + + console.debug(request); + + if (!isStrPresent(username) || !isStrPresent(password)) { + console.warn('Required Digest Auth fields are not present'); + return; + } + + axiosInstance.interceptors.response.use( + (response) => response, + (error) => { + const originalRequest = error.config; + + if ( + error.response?.status === 401 && + containsDigestHeader(error.response) && + !containsAuthorizationHeader(originalRequest) + ) { + console.debug(error.response.headers['www-authenticate']); + + const authDetails = error.response.headers['www-authenticate'] + .split(', ') + .map((v) => v.split('=').map(stripQuotes)) + .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}); + console.debug(authDetails); + + const nonceCount = '00000001'; + const cnonce = crypto.randomBytes(24).toString('hex'); + + if (authDetails.algorithm.toUpperCase() !== 'MD5') { + console.warn(`Unsupported Digest algorithm: ${algo}`); + return Promise.reject(error); + } + const HA1 = md5(`${username}:${authDetails['Digest realm']}:${password}`); + const HA2 = md5(`${request.method}:${request.url}`); + const response = md5(`${HA1}:${authDetails.nonce}:${nonceCount}:${cnonce}:auth:${HA2}`); + + const authorizationHeader = + `Digest username="${username}",realm="${authDetails['Digest realm']}",` + + `nonce="${authDetails.nonce}",uri="${request.url}",qop="auth",algorithm="${authDetails.algorithm}",` + + `response="${response}",nc="${nonceCount}",cnonce="${cnonce}"`; + originalRequest.headers['Authorization'] = authorizationHeader; + console.debug(`Authorization: ${originalRequest.headers['Authorization']}`); + + delete originalRequest.digestConfig; + return axiosInstance(originalRequest); + } + + return Promise.reject(error); + } + ); +} + +module.exports = { addDigestInterceptor }; diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index daace4792..6a4969931 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -23,6 +23,7 @@ const { HttpProxyAgent } = require('http-proxy-agent'); const { SocksProxyAgent } = require('socks-proxy-agent'); const { makeAxiosInstance } = require('./axios-instance'); const { addAwsV4Interceptor, resolveAwsV4Credentials } = require('./awsv4auth-helper'); +const { addDigestInterceptor } = require('./digestauth-helper'); const { shouldUseProxy, PatchedHttpsProxyAgent } = require('../../utils/proxy-util'); // override the default escape function to prevent escaping @@ -168,6 +169,10 @@ const configureRequest = async (collectionUid, request, envVars, collectionVaria delete request.awsv4config; } + if (request.digestConfig) { + addDigestInterceptor(axiosInstance, request); + } + request.timeout = preferencesUtil.getRequestTimeout(); return axiosInstance; diff --git a/packages/bruno-electron/src/ipc/network/interpolate-vars.js b/packages/bruno-electron/src/ipc/network/interpolate-vars.js index 31d5cab55..6df6a7c1a 100644 --- a/packages/bruno-electron/src/ipc/network/interpolate-vars.js +++ b/packages/bruno-electron/src/ipc/network/interpolate-vars.js @@ -131,6 +131,12 @@ const interpolateVars = (request, envVars = {}, collectionVariables = {}, proces request.awsv4config.profileName = interpolate(request.awsv4config.profileName) || ''; } + // interpolate vars for digest auth + if (request.digestConfig) { + request.digestConfig.username = interpolate(request.digestConfig.username) || ''; + request.digestConfig.password = interpolate(request.digestConfig.password) || ''; + } + return request; }; diff --git a/packages/bruno-electron/src/ipc/network/prepare-request.js b/packages/bruno-electron/src/ipc/network/prepare-request.js index 6e3f123c1..d5e17a6fd 100644 --- a/packages/bruno-electron/src/ipc/network/prepare-request.js +++ b/packages/bruno-electron/src/ipc/network/prepare-request.js @@ -28,6 +28,12 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { case 'bearer': axiosRequest.headers['authorization'] = `Bearer ${get(collectionAuth, 'bearer.token')}`; break; + case 'digest': + axiosRequest.digestConfig = { + username: get(collectionAuth, 'digest.username'), + password: get(collectionAuth, 'digest.password') + }; + break; } } @@ -52,6 +58,11 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => { case 'bearer': axiosRequest.headers['authorization'] = `Bearer ${get(request, 'auth.bearer.token')}`; break; + case 'digest': + axiosRequest.digestConfig = { + username: get(request, 'auth.digest.username'), + password: get(request, 'auth.digest.password') + }; } } diff --git a/packages/bruno-lang/v2/src/bruToJson.js b/packages/bruno-lang/v2/src/bruToJson.js index d8d51d3b1..fbe289974 100644 --- a/packages/bruno-lang/v2/src/bruToJson.js +++ b/packages/bruno-lang/v2/src/bruToJson.js @@ -23,7 +23,7 @@ const { outdentString } = require('../../v1/src/utils'); */ const grammar = ohm.grammar(`Bru { BruFile = (meta | http | query | headers | auths | bodies | varsandassert | script | tests | docs)* - auths = authawsv4 | authbasic | authbearer + auths = authawsv4 | authbasic | authbearer | authdigest bodies = bodyjson | bodytext | bodyxml | bodysparql | bodygraphql | bodygraphqlvars | bodyforms | body bodyforms = bodyformurlencoded | bodymultipart @@ -79,6 +79,7 @@ const grammar = ohm.grammar(`Bru { authawsv4 = "auth:awsv4" dictionary authbasic = "auth:basic" dictionary authbearer = "auth:bearer" dictionary + authdigest = "auth:digest" dictionary body = "body" st* "{" nl* textblock tagend bodyjson = "body:json" st* "{" nl* textblock tagend @@ -350,6 +351,21 @@ const sem = grammar.createSemantics().addAttribute('ast', { } }; }, + authdigest(_1, dictionary) { + const auth = mapPairListToKeyValPairs(dictionary.ast, false); + const usernameKey = _.find(auth, { name: 'username' }); + const passwordKey = _.find(auth, { name: 'password' }); + const username = usernameKey ? usernameKey.value : ''; + const password = passwordKey ? passwordKey.value : ''; + return { + auth: { + digest: { + username, + password + } + } + }; + }, bodyformurlencoded(_1, dictionary) { return { body: { diff --git a/packages/bruno-lang/v2/src/collectionBruToJson.js b/packages/bruno-lang/v2/src/collectionBruToJson.js index 4569736f1..c24f6e6ae 100644 --- a/packages/bruno-lang/v2/src/collectionBruToJson.js +++ b/packages/bruno-lang/v2/src/collectionBruToJson.js @@ -4,7 +4,7 @@ const { outdentString } = require('../../v1/src/utils'); const grammar = ohm.grammar(`Bru { BruFile = (meta | query | headers | auth | auths | vars | script | tests | docs)* - auths = authawsv4 | authbasic | authbearer + auths = authawsv4 | authbasic | authbearer | authdigest nl = "\\r"? "\\n" st = " " | "\\t" @@ -41,6 +41,7 @@ const grammar = ohm.grammar(`Bru { authawsv4 = "auth:awsv4" dictionary authbasic = "auth:basic" dictionary authbearer = "auth:bearer" dictionary + authdigest = "auth:digest" dictionary script = scriptreq | scriptres scriptreq = "script:pre-request" st* "{" nl* textblock tagend @@ -226,6 +227,21 @@ const sem = grammar.createSemantics().addAttribute('ast', { } }; }, + authdigest(_1, dictionary) { + const auth = mapPairListToKeyValPairs(dictionary.ast, false); + const usernameKey = _.find(auth, { name: 'username' }); + const passwordKey = _.find(auth, { name: 'password' }); + const username = usernameKey ? usernameKey.value : ''; + const password = passwordKey ? passwordKey.value : ''; + return { + auth: { + digest: { + username, + password + } + } + }; + }, varsreq(_1, dictionary) { const vars = mapPairListToKeyValPairs(dictionary.ast); _.each(vars, (v) => { diff --git a/packages/bruno-lang/v2/src/jsonToBru.js b/packages/bruno-lang/v2/src/jsonToBru.js index 56b5ec478..f4959500a 100644 --- a/packages/bruno-lang/v2/src/jsonToBru.js +++ b/packages/bruno-lang/v2/src/jsonToBru.js @@ -114,6 +114,15 @@ ${indentString(`password: ${auth.basic.password}`)} ${indentString(`token: ${auth.bearer.token}`)} } +`; + } + + if (auth && auth.digest) { + bru += `auth:digest { +${indentString(`username: ${auth.digest.username}`)} +${indentString(`password: ${auth.digest.password}`)} +} + `; } diff --git a/packages/bruno-lang/v2/src/jsonToCollectionBru.js b/packages/bruno-lang/v2/src/jsonToCollectionBru.js index ea928a68f..08a3abad5 100644 --- a/packages/bruno-lang/v2/src/jsonToCollectionBru.js +++ b/packages/bruno-lang/v2/src/jsonToCollectionBru.js @@ -102,6 +102,15 @@ ${indentString(`password: ${auth.basic.password}`)} ${indentString(`token: ${auth.bearer.token}`)} } +`; + } + + if (auth && auth.digest) { + bru += `auth:digest { +${indentString(`username: ${auth.digest.username}`)} +${indentString(`password: ${auth.digest.password}`)} +} + `; } diff --git a/packages/bruno-lang/v2/tests/fixtures/collection.bru b/packages/bruno-lang/v2/tests/fixtures/collection.bru index a02be30cb..44a66c8dc 100644 --- a/packages/bruno-lang/v2/tests/fixtures/collection.bru +++ b/packages/bruno-lang/v2/tests/fixtures/collection.bru @@ -21,6 +21,11 @@ auth:bearer { token: 123 } +auth:digest { + username: john + password: secret +} + vars:pre-request { departingDate: 2020-01-01 ~returningDate: 2020-01-02 diff --git a/packages/bruno-lang/v2/tests/fixtures/collection.json b/packages/bruno-lang/v2/tests/fixtures/collection.json index de827d11e..7bda2534d 100644 --- a/packages/bruno-lang/v2/tests/fixtures/collection.json +++ b/packages/bruno-lang/v2/tests/fixtures/collection.json @@ -27,6 +27,10 @@ }, "bearer": { "token": "123" + }, + "digest": { + "username": "john", + "password": "secret" } }, "vars": { diff --git a/packages/bruno-lang/v2/tests/fixtures/request.bru b/packages/bruno-lang/v2/tests/fixtures/request.bru index 22168b194..21b20477b 100644 --- a/packages/bruno-lang/v2/tests/fixtures/request.bru +++ b/packages/bruno-lang/v2/tests/fixtures/request.bru @@ -40,6 +40,11 @@ auth:bearer { token: 123 } +auth:digest { + username: john + password: secret +} + body:json { { "hello": "world" diff --git a/packages/bruno-lang/v2/tests/fixtures/request.json b/packages/bruno-lang/v2/tests/fixtures/request.json index def7b5f08..c23c46474 100644 --- a/packages/bruno-lang/v2/tests/fixtures/request.json +++ b/packages/bruno-lang/v2/tests/fixtures/request.json @@ -59,6 +59,10 @@ }, "bearer": { "token": "123" + }, + "digest": { + "username": "john", + "password": "secret" } }, "body": { diff --git a/packages/bruno-schema/src/collections/index.js b/packages/bruno-schema/src/collections/index.js index e63d8c3d2..37e6629af 100644 --- a/packages/bruno-schema/src/collections/index.js +++ b/packages/bruno-schema/src/collections/index.js @@ -94,11 +94,19 @@ const authBearerSchema = Yup.object({ .noUnknown(true) .strict(); +const authDigestSchema = Yup.object({ + username: Yup.string().nullable(), + password: Yup.string().nullable() +}) + .noUnknown(true) + .strict(); + const authSchema = Yup.object({ - mode: Yup.string().oneOf(['none', 'awsv4', 'basic', 'bearer']).required('mode is required'), + mode: Yup.string().oneOf(['none', 'awsv4', 'basic', 'bearer', 'digest']).required('mode is required'), awsv4: authAwsV4Schema.nullable(), basic: authBasicSchema.nullable(), - bearer: authBearerSchema.nullable() + bearer: authBearerSchema.nullable(), + digest: authDigestSchema.nullable() }) .noUnknown(true) .strict(); From 3f6f4ccd124b0617a233c589c08075665c26ee11 Mon Sep 17 00:00:00 2001 From: DaPutzy <9727551+DaPutzy@users.noreply.github.com> Date: Sun, 29 Oct 2023 13:04:11 +0000 Subject: [PATCH 06/53] chore: fix links and images in translated readme's --- docs/readme/readme_de.md | 10 +++++----- docs/readme/readme_fr.md | 10 +++++----- docs/readme/readme_ru.md | 8 ++++---- docs/readme/readme_tr.md | 8 ++++---- docs/readme/readme_ua.md | 8 ++++---- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/readme/readme_de.md b/docs/readme/readme_de.md index a0ef031d7..863624d1f 100644 --- a/docs/readme/readme_de.md +++ b/docs/readme/readme_de.md @@ -18,17 +18,17 @@ Du kannst Git oder eine andere Versionskontrolle deiner Wahl verwenden, um an de Bruno ist ein reines Offline-Tool. Es gibt keine Pläne, Bruno eine Cloud-Synchronisation hinzuzufügen. Wir schätzen den Schutz Deiner Daten und glauben, dass sie auf Deinem Gerät bleiben sollten. Lies unsere Langzeit-Vision [hier](https://github.com/usebruno/bruno/discussions/269). -![bruno](assets/images/landing-2.png)

+![bruno](/assets/images/landing-2.png)

### Einsatz auf verschiedensten Plattformen 🖥️ -![bruno](assets/images/run-anywhere.png)

+![bruno](/assets/images/run-anywhere.png)

### Zusammenarbeiten mit Git 👩‍💻🧑‍💻 oder eine Versionskontrolle Deiner Wahl -![bruno](assets/images/version-control.png)

+![bruno](/assets/images/version-control.png)

### Wichtige Links 📌 @@ -55,7 +55,7 @@ Wenn Bruno Dir bei Deiner Arbeit und in Deinen Teams geholfen hat, vergiss bitte ### Veröffentlichung in neuen Paketmanagern -Bitte [hier](publishing.md) für mehr Informationen lesen. +Bitte [hier](/publishing.md) für mehr Informationen lesen. ### Mitmachen 👩‍💻🧑‍💻 @@ -90,4 +90,4 @@ Das Logo stammt von [OpenMoji](https://openmoji.org/library/emoji-1F436/). Lizen ### Lizenz 📄 -[MIT](license.md) +[MIT](/license.md) diff --git a/docs/readme/readme_fr.md b/docs/readme/readme_fr.md index 97b327bfa..d16cce9a7 100644 --- a/docs/readme/readme_fr.md +++ b/docs/readme/readme_fr.md @@ -18,17 +18,17 @@ Vous pouvez utiliser git ou tout autre gestionnaire de version pour travailler d Bruno ne fonctionne qu'en mode déconnecté. Il n'y a pas de d'abonnement ou de synchronisation avec le cloud Bruno, il n'y en aura jamais. Nous sommes conscients de la confidentialité de vos données et nous sommes convaincus qu'elles doivent rester sur vos appareils. Vous pouvez lire notre vision à long terme [ici (en anglais)](https://github.com/usebruno/bruno/discussions/269). -![bruno](assets/images/landing-2.png)

+![bruno](/assets/images/landing-2.png)

### Fonctionne sur de multiples platformes 🖥️ -![bruno](assets/images/run-anywhere.png)

+![bruno](/assets/images/run-anywhere.png)

### Collaborer via Git 👩‍💻🧑‍💻 Ou n'importe quel système de gestion de sources -![bruno](assets/images/version-control.png)

+![bruno](/assets/images/version-control.png)

### Liens importants 📌 @@ -55,7 +55,7 @@ Si Bruno vous a aidé dans votre travail, au sein de votre équipe, merci de pen ### Publier Bruno sur un nouveau gestionnaire de paquets -Veuillez regarder [ici](publishing.md) pour plus d'information. +Veuillez regarder [ici](/publishing.md) pour plus d'information. ### Contribuer 👩‍💻🧑‍💻 @@ -91,4 +91,4 @@ Licence: CC [BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) ### Licence 📄 -[MIT](license.md) +[MIT](/license.md) diff --git a/docs/readme/readme_ru.md b/docs/readme/readme_ru.md index 423ab33b1..f962967e4 100644 --- a/docs/readme/readme_ru.md +++ b/docs/readme/readme_ru.md @@ -18,17 +18,17 @@ Bruno хранит ваши коллекции непосредственно в Bruno работает только в автономном режиме. Добавление облачной синхронизации в Bruno не планируется. Мы ценим конфиденциальность ваших данных и считаем, что они должны оставаться на вашем устройстве. Ознакомьтесь с нашим долгосрочным видением [здесь](https://github.com/usebruno/bruno/discussions/269) -![bruno](assets/images/landing-2.png)

+![bruno](/assets/images/landing-2.png)

### Работа на нескольких платформах 🖥️ -![bruno](assets/images/run-anywhere.png)

+![bruno](/assets/images/run-anywhere.png)

### Совместная работа через Git 👩‍💻🧑‍💻 Или другая система контроля версий по вашему выбору -![bruno](assets/images/version-control.png)

+![bruno](/assets/images/version-control.png)

### Важные ссылки 📌 @@ -74,4 +74,4 @@ Bruno работает только в автономном режиме. Доб ### Лицензия 📄 -[MIT](license.md) +[MIT](/license.md) diff --git a/docs/readme/readme_tr.md b/docs/readme/readme_tr.md index 74bd8aa50..c68609ec1 100644 --- a/docs/readme/readme_tr.md +++ b/docs/readme/readme_tr.md @@ -18,17 +18,17 @@ API koleksiyonlarınız üzerinde işbirliği yapmak için git veya seçtiğiniz Bruno yalnızca çevrimdışıdır. Bruno'ya bulut senkronizasyonu eklemek gibi bir planımız yok. Veri gizliliğinize değer veriyoruz ve cihazınızda kalması gerektiğine inanıyoruz. Uzun vadeli vizyonumuzu okuyun [burada](https://github.com/usebruno/bruno/discussions/269) -![bruno](assets/images/landing-2.png)

+![bruno](/assets/images/landing-2.png)

### Birden fazla platformda çalıştırın 🖥️ -![bruno](assets/images/run-anywhere.png)

+![bruno](/assets/images/run-anywhere.png)

### Git üzerinden işbirliği yapın 👩‍💻🧑‍💻 Veya seçtiğiniz herhangi bir sürüm kontrol sistemi -![bruno](assets/images/version-control.png)

+![bruno](/assets/images/version-control.png)

### Önemli Bağlantılar 📌 @@ -75,4 +75,4 @@ Kod yoluyla katkıda bulunamasanız bile, lütfen kullanım durumunuzu çözmek ### Lisans 📄 -[MIT](license.md) +[MIT](/license.md) diff --git a/docs/readme/readme_ua.md b/docs/readme/readme_ua.md index 9b0eb7a0f..eb4a8522f 100644 --- a/docs/readme/readme_ua.md +++ b/docs/readme/readme_ua.md @@ -18,17 +18,17 @@ Bruno зберігає ваші колекції напряму у теці на Bruno є повністю автономним. Немає жодних планів додавати будь-які синхронізації через хмару, ніколи. Ми цінуємо приватність ваших даних, і вважаєм, що вони мають залишитись лише на вашому комп'ютері. Взнати більше про наше бачення у довготривалій перспективі можна [тут](https://github.com/usebruno/bruno/discussions/269) -![bruno](assets/images/landing-2.png)

+![bruno](/assets/images/landing-2.png)

### Кросплатформенність 🖥️ -![bruno](assets/images/run-anywhere.png)

+![bruno](/assets/images/run-anywhere.png)

### Спільна робота через Git 👩‍💻🧑‍💻 Або будь-яку іншу систему контролю версій на ваш вибір -![bruno](assets/images/version-control.png)

+![bruno](/assets/images/version-control.png)

### Важливі посилання 📌 @@ -75,4 +75,4 @@ Bruno є повністю автономним. Немає жодних план ### Ліцензія 📄 -[MIT](license.md) +[MIT](/license.md) From 65f688dbc20c9506a8fc9360fe03f41695ff741c Mon Sep 17 00:00:00 2001 From: DaPutzy <9727551+DaPutzy@users.noreply.github.com> Date: Sun, 29 Oct 2023 13:49:44 +0000 Subject: [PATCH 07/53] chrore: fix logo's in translated readme's --- docs/readme/readme_de.md | 2 +- docs/readme/readme_fr.md | 2 +- docs/readme/readme_ru.md | 2 +- docs/readme/readme_tr.md | 2 +- docs/readme/readme_ua.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/readme/readme_de.md b/docs/readme/readme_de.md index 863624d1f..371672b4c 100644 --- a/docs/readme/readme_de.md +++ b/docs/readme/readme_de.md @@ -1,5 +1,5 @@
- + ### Bruno - Opensource IDE zum Erkunden und Testen von APIs. diff --git a/docs/readme/readme_fr.md b/docs/readme/readme_fr.md index d16cce9a7..9c3fdd6cd 100644 --- a/docs/readme/readme_fr.md +++ b/docs/readme/readme_fr.md @@ -1,5 +1,5 @@
- + ### Bruno - IDE Opensource pour explorer et tester des APIs. diff --git a/docs/readme/readme_ru.md b/docs/readme/readme_ru.md index f962967e4..ddbe8135c 100644 --- a/docs/readme/readme_ru.md +++ b/docs/readme/readme_ru.md @@ -1,5 +1,5 @@
- + ### Bruno - IDE с открытым исходным кодом для изучения и тестирования API. diff --git a/docs/readme/readme_tr.md b/docs/readme/readme_tr.md index c68609ec1..b04738505 100644 --- a/docs/readme/readme_tr.md +++ b/docs/readme/readme_tr.md @@ -1,5 +1,5 @@
- + ### Bruno - API'leri keşfetmek ve test etmek için açık kaynaklı IDE. diff --git a/docs/readme/readme_ua.md b/docs/readme/readme_ua.md index eb4a8522f..cb0ccb9ee 100644 --- a/docs/readme/readme_ua.md +++ b/docs/readme/readme_ua.md @@ -1,5 +1,5 @@
- + ### Bruno - IDE із відкритим кодом для тестування та дослідження API From ff63cea108d32c0bd818585ebc7583bfd4c8c19e Mon Sep 17 00:00:00 2001 From: Martin Sefcik Date: Mon, 30 Oct 2023 18:03:32 +0100 Subject: [PATCH 08/53] fix (#759): fixed axios versions inconsistency --- package-lock.json | 140 ++++++++++++++++---------------- packages/bruno-app/package.json | 2 +- packages/bruno-js/package.json | 2 +- 3 files changed, 74 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 79f3de50f..7e030331b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5546,13 +5546,6 @@ "version": "1.12.0", "license": "MIT" }, - "node_modules/axios": { - "version": "0.26.1", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, "node_modules/babel-jest": { "version": "29.3.1", "dev": true, @@ -13580,6 +13573,7 @@ }, "node_modules/react-is": { "version": "18.2.0", + "dev": true, "license": "MIT" }, "node_modules/react-redux": { @@ -16448,7 +16442,7 @@ "@tippyjs/react": "^4.2.6", "@usebruno/graphql-docs": "0.1.0", "@usebruno/schema": "0.6.0", - "axios": "^0.26.0", + "axios": "^1.5.1", "classnames": "^2.3.1", "codemirror": "^5.65.2", "codemirror-graphql": "^1.2.5", @@ -16512,6 +16506,16 @@ "version": "2.0.1", "license": "Python-2.0" }, + "packages/bruno-app/node_modules/axios": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "packages/bruno-app/node_modules/entities": { "version": "3.0.1", "license": "BSD-2-Clause", @@ -16865,7 +16869,7 @@ "@usebruno/query": "0.1.0", "ajv": "^8.12.0", "atob": "^2.1.2", - "axios": "^0.26.0", + "axios": "^1.5.1", "btoa": "^1.2.1", "chai": "^4.3.7", "chai-string": "^1.5.0", @@ -16896,6 +16900,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "packages/bruno-js/node_modules/axios": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "packages/bruno-js/node_modules/json-schema-traverse": { "version": "1.0.0", "license": "MIT" @@ -20241,8 +20255,7 @@ } }, "@tabler/icons": { - "version": "1.119.0", - "requires": {} + "version": "1.119.0" }, "@tauri-apps/cli": { "version": "1.2.2", @@ -20511,7 +20524,7 @@ "@tippyjs/react": "^4.2.6", "@usebruno/graphql-docs": "0.1.0", "@usebruno/schema": "0.6.0", - "axios": "^0.26.0", + "axios": "^1.5.1", "babel-loader": "^8.2.3", "classnames": "^2.3.1", "codemirror": "^5.65.2", @@ -20567,6 +20580,16 @@ "argparse": { "version": "2.0.1" }, + "axios": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "entities": { "version": "3.0.1" }, @@ -20685,7 +20708,7 @@ "@usebruno/query": "0.1.0", "ajv": "^8.12.0", "atob": "^2.1.2", - "axios": "^0.26.0", + "axios": "^1.5.1", "btoa": "^1.2.1", "chai": "^4.3.7", "chai-string": "^1.5.0", @@ -20708,6 +20731,16 @@ "uri-js": "^4.2.2" } }, + "axios": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", + "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "json-schema-traverse": { "version": "1.0.0" }, @@ -20746,8 +20779,7 @@ } }, "@usebruno/schema": { - "version": "file:packages/bruno-schema", - "requires": {} + "version": "file:packages/bruno-schema" }, "@usebruno/testbench": { "version": "file:packages/bruno-testbench", @@ -20891,8 +20923,7 @@ }, "@webpack-cli/configtest": { "version": "1.2.0", - "dev": true, - "requires": {} + "dev": true }, "@webpack-cli/info": { "version": "1.5.0", @@ -20903,8 +20934,7 @@ }, "@webpack-cli/serve": { "version": "1.7.0", - "dev": true, - "requires": {} + "dev": true }, "@xtuc/ieee754": { "version": "1.2.0", @@ -20981,8 +21011,7 @@ }, "ajv-keywords": { "version": "3.5.2", - "dev": true, - "requires": {} + "dev": true }, "amdefine": { "version": "0.0.8" @@ -21247,12 +21276,6 @@ "aws4": { "version": "1.12.0" }, - "axios": { - "version": "0.26.1", - "requires": { - "follow-redirects": "^1.14.8" - } - }, "babel-jest": { "version": "29.3.1", "dev": true, @@ -21876,8 +21899,7 @@ "chai-string": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/chai-string/-/chai-string-1.5.0.tgz", - "integrity": "sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw==", - "requires": {} + "integrity": "sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw==" }, "chalk": { "version": "4.1.2", @@ -22272,8 +22294,7 @@ }, "css-declaration-sorter": { "version": "6.3.1", - "dev": true, - "requires": {} + "dev": true }, "css-loader": { "version": "6.7.3", @@ -22392,8 +22413,7 @@ }, "cssnano-utils": { "version": "3.1.0", - "dev": true, - "requires": {} + "dev": true }, "csso": { "version": "4.2.0", @@ -23553,8 +23573,7 @@ } }, "goober": { - "version": "2.1.11", - "requires": {} + "version": "2.1.11" }, "got": { "version": "9.6.0", @@ -23917,8 +23936,7 @@ }, "icss-utils": { "version": "5.1.0", - "dev": true, - "requires": {} + "dev": true }, "idb": { "version": "7.1.1" @@ -24520,8 +24538,7 @@ }, "jest-pnp-resolver": { "version": "1.2.3", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { "version": "29.2.0", @@ -25110,8 +25127,7 @@ "version": "1.4.1" }, "meros": { - "version": "1.2.1", - "requires": {} + "version": "1.2.1" }, "methods": { "version": "1.1.2" @@ -25871,23 +25887,19 @@ }, "postcss-discard-comments": { "version": "5.1.2", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-duplicates": { "version": "5.1.0", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-empty": { "version": "5.1.1", - "dev": true, - "requires": {} + "dev": true }, "postcss-discard-overridden": { "version": "5.1.0", - "dev": true, - "requires": {} + "dev": true }, "postcss-js": { "version": "3.0.3", @@ -25969,8 +25981,7 @@ }, "postcss-modules-extract-imports": { "version": "3.0.0", - "dev": true, - "requires": {} + "dev": true }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -26003,8 +26014,7 @@ }, "postcss-normalize-charset": { "version": "5.1.0", - "dev": true, - "requires": {} + "dev": true }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -26399,11 +26409,11 @@ } }, "react-inspector": { - "version": "6.0.2", - "requires": {} + "version": "6.0.2" }, "react-is": { - "version": "18.2.0" + "version": "18.2.0", + "dev": true }, "react-redux": { "version": "7.2.9", @@ -26550,8 +26560,7 @@ } }, "redux-thunk": { - "version": "2.4.2", - "requires": {} + "version": "2.4.2" }, "regenerate": { "version": "1.4.2", @@ -26783,8 +26792,7 @@ }, "rollup-plugin-peer-deps-external": { "version": "2.2.4", - "dev": true, - "requires": {} + "dev": true }, "rollup-plugin-postcss": { "version": "4.0.2", @@ -27278,8 +27286,7 @@ }, "style-loader": { "version": "3.3.1", - "dev": true, - "requires": {} + "dev": true }, "styled-components": { "version": "5.3.6", @@ -27308,8 +27315,7 @@ } }, "styled-jsx": { - "version": "5.0.7", - "requires": {} + "version": "5.0.7" }, "stylehacks": { "version": "5.1.1", @@ -27902,8 +27908,7 @@ } }, "use-sync-external-store": { - "version": "1.2.0", - "requires": {} + "version": "1.2.0" }, "utf8-byte-length": { "version": "1.0.4", @@ -28064,8 +28069,7 @@ }, "acorn-import-assertions": { "version": "1.8.0", - "dev": true, - "requires": {} + "dev": true }, "schema-utils": { "version": "3.1.1", diff --git a/packages/bruno-app/package.json b/packages/bruno-app/package.json index c3f82569f..532902cd2 100644 --- a/packages/bruno-app/package.json +++ b/packages/bruno-app/package.json @@ -20,7 +20,7 @@ "@tippyjs/react": "^4.2.6", "@usebruno/graphql-docs": "0.1.0", "@usebruno/schema": "0.6.0", - "axios": "^0.26.0", + "axios": "^1.5.1", "classnames": "^2.3.1", "codemirror": "^5.65.2", "codemirror-graphql": "^1.2.5", diff --git a/packages/bruno-js/package.json b/packages/bruno-js/package.json index d8161c9ec..274e1ae04 100644 --- a/packages/bruno-js/package.json +++ b/packages/bruno-js/package.json @@ -17,7 +17,7 @@ "@usebruno/query": "0.1.0", "ajv": "^8.12.0", "atob": "^2.1.2", - "axios": "^0.26.0", + "axios": "^1.5.1", "btoa": "^1.2.1", "chai": "^4.3.7", "chai-string": "^1.5.0", From 32d9c4833e46aa93b9e027679bf4a9219039914b Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Mon, 30 Oct 2023 23:33:29 +0530 Subject: [PATCH 09/53] chore: bump version to 1.0.0 --- packages/bruno-app/src/components/Sidebar/index.js | 2 +- packages/bruno-electron/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/index.js b/packages/bruno-app/src/components/Sidebar/index.js index a6df7141c..ae15b8c07 100644 --- a/packages/bruno-app/src/components/Sidebar/index.js +++ b/packages/bruno-app/src/components/Sidebar/index.js @@ -105,7 +105,7 @@ const Sidebar = () => { Star
-
v0.27.2
+
v1.0.0
diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json index 47753da5a..cb3a81c37 100644 --- a/packages/bruno-electron/package.json +++ b/packages/bruno-electron/package.json @@ -1,5 +1,5 @@ { - "version": "v0.27.2", + "version": "v1.0.0", "name": "bruno", "description": "Opensource API Client for Exploring and Testing APIs", "homepage": "https://www.usebruno.com", From aac4a33c92396934dc92fc08725490a5e70ba1a7 Mon Sep 17 00:00:00 2001 From: HardikBandhiya Date: Tue, 31 Oct 2023 01:59:43 +0530 Subject: [PATCH 10/53] Update readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit changed Twitter's old name to new 𝕏 --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1486ad25d..339e72abc 100644 --- a/readme.md +++ b/readme.md @@ -75,7 +75,7 @@ Even if you are not able to make contributions via code, please don't hesitate t ### Stay in touch 🌐 -[Twitter](https://twitter.com/use_bruno)
+[𝕏 (Twitter)](https://twitter.com/use_bruno)
[Website](https://www.usebruno.com)
[Discord](https://discord.com/invite/KgcZUncpjq)
[LinkedIn](https://www.linkedin.com/company/usebruno) From 745cb85f9561f6dc04a26db57fa5fc62893698e6 Mon Sep 17 00:00:00 2001 From: Martin Sefcik Date: Mon, 30 Oct 2023 23:43:44 +0100 Subject: [PATCH 11/53] fix (#680): fixed defined non-string variables to be displayed correctly in code editor --- packages/bruno-app/src/utils/common/codemirror.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bruno-app/src/utils/common/codemirror.js b/packages/bruno-app/src/utils/common/codemirror.js index 78016de6f..6074dbdcf 100644 --- a/packages/bruno-app/src/utils/common/codemirror.js +++ b/packages/bruno-app/src/utils/common/codemirror.js @@ -10,7 +10,7 @@ if (!SERVER_RENDERED) { const pathFoundInVariables = (path, obj) => { const value = get(obj, path); - return isString(value); + return value !== undefined; }; export const defineCodeMirrorBrunoVariablesMode = (variables, mode) => { From 31ecc281a8332cf845f8199ed0501ca2bf3ea02c Mon Sep 17 00:00:00 2001 From: n00o Date: Mon, 30 Oct 2023 20:10:36 -0400 Subject: [PATCH 12/53] Fix response/body cursor offset on resize Now response/body will be refresh each time it gets resized so the cursor always stays in the right place. --- packages/bruno-app/src/components/CodeEditor/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/bruno-app/src/components/CodeEditor/index.js b/packages/bruno-app/src/components/CodeEditor/index.js index b1a115c9e..5750d41e1 100644 --- a/packages/bruno-app/src/components/CodeEditor/index.js +++ b/packages/bruno-app/src/components/CodeEditor/index.js @@ -146,6 +146,9 @@ export default class CodeEditor extends React.Component { } render() { + if (this.editor) { + this.editor.refresh() + } return ( Date: Mon, 30 Oct 2023 20:59:40 -0400 Subject: [PATCH 13/53] Update index.js Pass prettier test. --- packages/bruno-app/src/components/CodeEditor/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bruno-app/src/components/CodeEditor/index.js b/packages/bruno-app/src/components/CodeEditor/index.js index 5750d41e1..0bfd6fdd3 100644 --- a/packages/bruno-app/src/components/CodeEditor/index.js +++ b/packages/bruno-app/src/components/CodeEditor/index.js @@ -147,7 +147,7 @@ export default class CodeEditor extends React.Component { render() { if (this.editor) { - this.editor.refresh() + this.editor.refresh(); } return ( Date: Tue, 31 Oct 2023 09:49:38 +0530 Subject: [PATCH 14/53] capitalize git to Git for clarity --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1486ad25d..0429264c9 100644 --- a/readme.md +++ b/readme.md @@ -16,7 +16,7 @@ Bruno is a new and innovative API client, aimed at revolutionizing the status qu Bruno stores your collections directly in a folder on your filesystem. We use a plain text markup language, Bru, to save information about API requests. -You can use git or any version control of your choice to collaborate over your API collections. +You can use Git or any version control of your choice to collaborate over your API collections. Bruno is offline-only. There are no plans to add cloud-sync to Bruno, ever. We value your data privacy and believe it should stay on your device. Read our long-term vision [here](https://github.com/usebruno/bruno/discussions/269) From bbcab8d33860dd71813190afe396eb65e4c74e96 Mon Sep 17 00:00:00 2001 From: Dipin Jagadish Date: Tue, 31 Oct 2023 19:32:31 +0000 Subject: [PATCH 15/53] feat: add new request from curl feature --- package-lock.json | 28 +++++ packages/bruno-app/package.json | 1 + .../components/Sidebar/NewRequest/index.js | 111 +++++++++++++----- .../ReduxStore/slices/collections/actions.js | 6 +- packages/bruno-app/src/utils/curl/index.js | 65 ++++++++++ 5 files changed, 177 insertions(+), 34 deletions(-) create mode 100644 packages/bruno-app/src/utils/curl/index.js diff --git a/package-lock.json b/package-lock.json index 79f3de50f..cf7a7d95f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12178,6 +12178,14 @@ "xml2js": "^0.4.5" } }, + "node_modules/parse-curl": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/parse-curl/-/parse-curl-0.2.6.tgz", + "integrity": "sha512-ENhXeIxG4A6wFvYSU87b0o3Tp6U+Wup069GYhXCn0ZP/E7evfvomTSM/MeEOs3QTyuye+u2r7fFRj6nX0q9kQA==", + "dependencies": { + "shellwords": "^0.1.0" + } + }, "node_modules/parse-headers": { "version": "2.0.5", "dev": true, @@ -14515,6 +14523,11 @@ "node": ">=8" } }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + }, "node_modules/side-channel": { "version": "1.0.4", "license": "MIT", @@ -16470,6 +16483,7 @@ "mousetrap": "^1.6.5", "nanoid": "3.3.4", "next": "12.3.3", + "parse-curl": "^0.2.6", "path": "^0.12.7", "platform": "^1.3.6", "posthog-node": "^2.1.0", @@ -20540,6 +20554,7 @@ "mousetrap": "^1.6.5", "nanoid": "3.3.4", "next": "12.3.3", + "parse-curl": "*", "path": "^0.12.7", "platform": "^1.3.6", "posthog-node": "^2.1.0", @@ -25603,6 +25618,14 @@ "xml2js": "^0.4.5" } }, + "parse-curl": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/parse-curl/-/parse-curl-0.2.6.tgz", + "integrity": "sha512-ENhXeIxG4A6wFvYSU87b0o3Tp6U+Wup069GYhXCn0ZP/E7evfvomTSM/MeEOs3QTyuye+u2r7fFRj6nX0q9kQA==", + "requires": { + "shellwords": "^0.1.0" + } + }, "parse-headers": { "version": "2.0.5", "dev": true @@ -27036,6 +27059,11 @@ "version": "3.0.0", "dev": true }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + }, "side-channel": { "version": "1.0.4", "requires": { diff --git a/packages/bruno-app/package.json b/packages/bruno-app/package.json index c3f82569f..77ff96b67 100644 --- a/packages/bruno-app/package.json +++ b/packages/bruno-app/package.json @@ -42,6 +42,7 @@ "mousetrap": "^1.6.5", "nanoid": "3.3.4", "next": "12.3.3", + "parse-curl": "^0.2.6", "path": "^0.12.7", "platform": "^1.3.6", "posthog-node": "^2.1.0", diff --git a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js index 2e54b56ad..1476a7de8 100644 --- a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js +++ b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js @@ -11,6 +11,7 @@ import { addTab } from 'providers/ReduxStore/slices/tabs'; import HttpMethodSelector from 'components/RequestPane/QueryUrl/HttpMethodSelector'; import { getDefaultRequestPaneTab } from 'utils/collections'; import StyledWrapper from './StyledWrapper'; +import { getRequestFromCurlCommand } from 'utils/curl'; const NewRequest = ({ collection, item, isEphemeral, onClose }) => { const dispatch = useDispatch(); @@ -21,7 +22,8 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { requestName: '', requestType: 'http-request', requestUrl: '', - requestMethod: 'GET' + requestMethod: 'GET', + curlCommand: '' }, validationSchema: Yup.object({ requestName: Yup.string() @@ -61,6 +63,23 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { onClose(); }) .catch((err) => toast.error(err ? err.message : 'An error occurred while adding the request')); + } else if (values.requestType === 'from-curl') { + getRequestFromCurlCommand(values.curlCommand).then((request) => + dispatch( + newHttpRequest({ + requestName: values.requestName, + requestType: 'http-request', + requestUrl: request.url, + requestMethod: request.method, + collectionUid: collection.uid, + itemUid: item ? item.uid : null, + headers: request.headers, + body: request.body + }) + ) + .then(() => onClose()) + .catch((err) => toast.error(err ? err.message : 'An error occurred while adding the request')) + ); } else { dispatch( newHttpRequest({ @@ -124,9 +143,22 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { + + + + -
+ {formik.values.requestType !== 'from-curl' ? ( + <> +
+ -
- - -
-
- formik.setFieldValue('requestMethod', val)} - /> -
-
- +
+
+ formik.setFieldValue('requestMethod', val)} + /> +
+
+ +
+
+ {formik.touched.requestUrl && formik.errors.requestUrl ? ( +
{formik.errors.requestUrl}
+ ) : null}
+ + ) : ( +
+ +
- {formik.touched.requestUrl && formik.errors.requestUrl ? ( -
{formik.errors.requestUrl}
- ) : null} -
+ )} diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js index 20a68b80e..2ef107954 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js @@ -568,7 +568,7 @@ export const moveItemToRootOfCollection = (collectionUid, draggedItemUid) => (di }; export const newHttpRequest = (params) => (dispatch, getState) => { - const { requestName, requestType, requestUrl, requestMethod, collectionUid, itemUid } = params; + const { requestName, requestType, requestUrl, requestMethod, collectionUid, itemUid, headers, body } = params; return new Promise((resolve, reject) => { const state = getState(); @@ -591,9 +591,9 @@ export const newHttpRequest = (params) => (dispatch, getState) => { request: { method: requestMethod, url: requestUrl, - headers: [], + headers: headers ?? [], params, - body: { + body: body ?? { mode: 'none', json: null, text: null, diff --git a/packages/bruno-app/src/utils/curl/index.js b/packages/bruno-app/src/utils/curl/index.js new file mode 100644 index 000000000..37282f09c --- /dev/null +++ b/packages/bruno-app/src/utils/curl/index.js @@ -0,0 +1,65 @@ +import * as parse from 'parse-curl'; +import { BrunoError } from 'utils/common/error'; +import { parseQueryParams } from 'utils/url'; + +export const getRequestFromCurlCommand = (command) => { + const parseFormData = (parsedBody) => { + parseQueryParams(parsedBody); + }; + return new Promise((resolve, reject) => { + try { + const request = parse(command); + const parsedHeader = request?.header; + const headers = + parsedHeader && + Object.keys(parsedHeader).map((key) => ({ name: key, value: parsedHeader[key], enabled: true })); + + const contentType = headers?.find((h) => h.name.toLowerCase() === 'content-type'); + const body = { + mode: 'none', + json: null, + text: null, + xml: null, + sparql: null, + multipartForm: null, + formUrlEncoded: null + }; + const parsedBody = request?.body; + if (parsedBody && contentType) { + switch (contentType.value.toLowerCase()) { + case 'application/json': + body.mode = 'json'; + body.json = parsedBody; + break; + case 'text/xml': + body.mode = 'xml'; + body.xml = parsedBody; + break; + case 'application/x-www-form-urlencoded': + body.mode = 'formUrlEncoded'; + body.formUrlEncoded = parseFormData(parsedBody); + break; + case 'multipart/form-data': + body.mode = 'multipartForm'; + body.multipartForm = parsedBody; + break; + case 'text/plain': + default: + body.mode = 'text'; + body.text = parsedBody; + break; + } + } + debugger; + console.log(request); + return resolve({ + url: request.url, + method: request.method, + body, + headers: headers + }); + } catch (error) { + return reject(new BrunoError('Unable to parse the cURL command')); + } + }); +}; From 89e0d3ae7edaabb8139ed643920dd11d1bb95f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linhart=20Luk=C3=A1=C5=A1?= Date: Wed, 1 Nov 2023 07:05:05 +0100 Subject: [PATCH 16/53] Fix Multipart Form --- packages/bruno-electron/src/ipc/network/prepare-request.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/bruno-electron/src/ipc/network/prepare-request.js b/packages/bruno-electron/src/ipc/network/prepare-request.js index 6e3f123c1..d38849f69 100644 --- a/packages/bruno-electron/src/ipc/network/prepare-request.js +++ b/packages/bruno-electron/src/ipc/network/prepare-request.js @@ -1,5 +1,6 @@ -const { get, each, filter } = require('lodash'); +const { get, each, filter, forOwn, extend } = require('lodash'); const decomment = require('decomment'); +const FormData = require('form-data'); // Authentication // A request can override the collection auth with another auth From 49f29fa2afede3f917d398259cc0152aefb43f58 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Wed, 1 Nov 2023 14:36:28 +0530 Subject: [PATCH 17/53] fix(#836): Fix graphql blank screen issue --- .../components/RequestPane/GraphQLSchemaActions/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLSchemaActions/index.js b/packages/bruno-app/src/components/RequestPane/GraphQLSchemaActions/index.js index 954efebf7..01ce6f320 100644 --- a/packages/bruno-app/src/components/RequestPane/GraphQLSchemaActions/index.js +++ b/packages/bruno-app/src/components/RequestPane/GraphQLSchemaActions/index.js @@ -1,6 +1,6 @@ import React, { useEffect, useRef, forwardRef } from 'react'; import useGraphqlSchema from './useGraphqlSchema'; -import { IconBook, IconDownload, IconLoader2, IconCheckmark } from '@tabler/icons'; +import { IconBook, IconDownload, IconLoader2, IconRefresh } from '@tabler/icons'; import get from 'lodash/get'; import { findEnvironmentInCollection } from 'utils/collections'; import Dropdown from '../../Dropdown'; @@ -30,8 +30,8 @@ const GraphQLSchemaActions = ({ item, collection, onSchemaLoad, toggleDocs }) => return (
{isSchemaLoading && } - {!isSchemaLoading && schema && } - {!isSchemaLoading && !schema && } + {!isSchemaLoading && schema && } + {!isSchemaLoading && !schema && } Schema
); From 05bf40fa82ee01f963c85410006adac51184fa9b Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Wed, 1 Nov 2023 14:38:33 +0530 Subject: [PATCH 18/53] chore: bumped version to 1.0.1 --- packages/bruno-app/src/components/Sidebar/index.js | 2 +- packages/bruno-electron/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/index.js b/packages/bruno-app/src/components/Sidebar/index.js index ae15b8c07..69be75689 100644 --- a/packages/bruno-app/src/components/Sidebar/index.js +++ b/packages/bruno-app/src/components/Sidebar/index.js @@ -105,7 +105,7 @@ const Sidebar = () => { Star
-
v1.0.0
+
v1.0.1
diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json index cb3a81c37..5f334ac87 100644 --- a/packages/bruno-electron/package.json +++ b/packages/bruno-electron/package.json @@ -1,5 +1,5 @@ { - "version": "v1.0.0", + "version": "v1.0.1", "name": "bruno", "description": "Opensource API Client for Exploring and Testing APIs", "homepage": "https://www.usebruno.com", From dbd3ab6064298e952a726b4c344250090b7ed1ff Mon Sep 17 00:00:00 2001 From: Dipin Jagadish Date: Wed, 1 Nov 2023 10:58:07 +0000 Subject: [PATCH 19/53] fix: validate curl command before submit --- .../components/Sidebar/NewRequest/index.js | 42 +++++--- packages/bruno-app/src/utils/curl/index.js | 101 +++++++++--------- 2 files changed, 74 insertions(+), 69 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js index 1476a7de8..f6bcdfeb0 100644 --- a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js +++ b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js @@ -37,6 +37,14 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { const trimmedValue = value ? value.trim().toLowerCase() : ''; return !['collection', 'folder'].includes(trimmedValue); } + }), + curlCommand: Yup.string() + .min(1, 'must be at least 1 character') + .required('curlCommand is required') + .test({ + name: 'curlCommand', + message: `Invalid cURL Command`, + test: (value) => getRequestFromCurlCommand(value) !== null }) }), onSubmit: (values) => { @@ -64,22 +72,21 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { }) .catch((err) => toast.error(err ? err.message : 'An error occurred while adding the request')); } else if (values.requestType === 'from-curl') { - getRequestFromCurlCommand(values.curlCommand).then((request) => - dispatch( - newHttpRequest({ - requestName: values.requestName, - requestType: 'http-request', - requestUrl: request.url, - requestMethod: request.method, - collectionUid: collection.uid, - itemUid: item ? item.uid : null, - headers: request.headers, - body: request.body - }) - ) - .then(() => onClose()) - .catch((err) => toast.error(err ? err.message : 'An error occurred while adding the request')) - ); + const request = getRequestFromCurlCommand(values.curlCommand); + dispatch( + newHttpRequest({ + requestName: values.requestName, + requestType: 'http-request', + requestUrl: request.url, + requestMethod: request.method, + collectionUid: collection.uid, + itemUid: item ? item.uid : null, + headers: request.headers, + body: request.body + }) + ) + .then(() => onClose()) + .catch((err) => toast.error(err ? err.message : 'An error occurred while adding the request')); } else { dispatch( newHttpRequest({ @@ -227,6 +234,9 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { value={formik.values.curlCommand} onChange={formik.handleChange} > + {formik.touched.curlCommand && formik.errors.curlCommand ? ( +
{formik.errors.curlCommand}
+ ) : null} )} diff --git a/packages/bruno-app/src/utils/curl/index.js b/packages/bruno-app/src/utils/curl/index.js index 37282f09c..30080e467 100644 --- a/packages/bruno-app/src/utils/curl/index.js +++ b/packages/bruno-app/src/utils/curl/index.js @@ -6,60 +6,55 @@ export const getRequestFromCurlCommand = (command) => { const parseFormData = (parsedBody) => { parseQueryParams(parsedBody); }; - return new Promise((resolve, reject) => { - try { - const request = parse(command); - const parsedHeader = request?.header; - const headers = - parsedHeader && - Object.keys(parsedHeader).map((key) => ({ name: key, value: parsedHeader[key], enabled: true })); + try { + const request = parse(command); + const parsedHeader = request?.header; + const headers = + parsedHeader && Object.keys(parsedHeader).map((key) => ({ name: key, value: parsedHeader[key], enabled: true })); - const contentType = headers?.find((h) => h.name.toLowerCase() === 'content-type'); - const body = { - mode: 'none', - json: null, - text: null, - xml: null, - sparql: null, - multipartForm: null, - formUrlEncoded: null - }; - const parsedBody = request?.body; - if (parsedBody && contentType) { - switch (contentType.value.toLowerCase()) { - case 'application/json': - body.mode = 'json'; - body.json = parsedBody; - break; - case 'text/xml': - body.mode = 'xml'; - body.xml = parsedBody; - break; - case 'application/x-www-form-urlencoded': - body.mode = 'formUrlEncoded'; - body.formUrlEncoded = parseFormData(parsedBody); - break; - case 'multipart/form-data': - body.mode = 'multipartForm'; - body.multipartForm = parsedBody; - break; - case 'text/plain': - default: - body.mode = 'text'; - body.text = parsedBody; - break; - } + const contentType = headers?.find((h) => h.name.toLowerCase() === 'content-type'); + const body = { + mode: 'none', + json: null, + text: null, + xml: null, + sparql: null, + multipartForm: null, + formUrlEncoded: null + }; + const parsedBody = request?.body; + if (parsedBody && contentType) { + switch (contentType.value.toLowerCase()) { + case 'application/json': + body.mode = 'json'; + body.json = parsedBody; + break; + case 'text/xml': + body.mode = 'xml'; + body.xml = parsedBody; + break; + case 'application/x-www-form-urlencoded': + body.mode = 'formUrlEncoded'; + body.formUrlEncoded = parseFormData(parsedBody); + break; + case 'multipart/form-data': + body.mode = 'multipartForm'; + body.multipartForm = parsedBody; + break; + case 'text/plain': + default: + body.mode = 'text'; + body.text = parsedBody; + break; } - debugger; - console.log(request); - return resolve({ - url: request.url, - method: request.method, - body, - headers: headers - }); - } catch (error) { - return reject(new BrunoError('Unable to parse the cURL command')); } - }); + return { + url: request.url, + method: request.method, + body, + headers: headers + }; + } catch (error) { + return null; + } }; From cd9276f4d2b5605cfa7ed7fd639bdcc01727cf76 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Wed, 1 Nov 2023 18:23:27 +0530 Subject: [PATCH 20/53] chore: added installation instructions --- readme.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 69f78b0f2..31f50ffa5 100644 --- a/readme.md +++ b/readme.md @@ -24,10 +24,28 @@ Bruno is offline-only. There are no plans to add cloud-sync to Bruno, ever. We v ### Installation -Bruno is available as binary download [on our website](https://www.usebruno.com/downloads) or via homebrew +Bruno is available as binary download [on our website](https://www.usebruno.com/downloads) for Mac, Windows and Linux. + +You can also install Bruno via package managers like Homebrew, Chocolatey, Snap and Apt. ```sh +# On Mac via Homebrew brew install bruno + +# On Windows via Chocolatey +choco install bruno + +# On Linux via Snap +snap install bruno + +# On 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 ``` ### Run across multiple platforms 🖥️ From 9cf8a584a094c7a59012cc4ab9759a178b179d06 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Wed, 1 Nov 2023 18:25:25 +0530 Subject: [PATCH 21/53] chore: added foss 3.0 talk link --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index 31f50ffa5..96a9d7c88 100644 --- a/readme.md +++ b/readme.md @@ -20,6 +20,8 @@ You can use Git or any version control of your choice to collaborate over your A Bruno is offline-only. There are no plans to add cloud-sync to Bruno, ever. We value your data privacy and believe it should stay on your device. Read our long-term vision [here](https://github.com/usebruno/bruno/discussions/269) +📢 Watch our recent talk at India FOSS 3.0 Conference [here](https://www.youtube.com/watch?v=7bSMFpbcPiY) + ![bruno](assets/images/landing-2.png)

### Installation From 09d6bc8169df0e641602e0b153de0458a1fb1ec5 Mon Sep 17 00:00:00 2001 From: Dipin Jagadish Date: Wed, 1 Nov 2023 18:36:39 +0000 Subject: [PATCH 22/53] fix: address validation issue in schema --- .../components/Sidebar/NewRequest/index.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js index f6bcdfeb0..43d91430b 100644 --- a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js +++ b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js @@ -38,14 +38,17 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { return !['collection', 'folder'].includes(trimmedValue); } }), - curlCommand: Yup.string() - .min(1, 'must be at least 1 character') - .required('curlCommand is required') - .test({ - name: 'curlCommand', - message: `Invalid cURL Command`, - test: (value) => getRequestFromCurlCommand(value) !== null - }) + curlCommand: Yup.string().when('requestType', { + is: (requestType) => requestType === 'from-curl', + then: Yup.string() + .min(1, 'must be at least 1 character') + .required('curlCommand is required') + .test({ + name: 'curlCommand', + message: `Invalid cURL Command`, + test: (value) => getRequestFromCurlCommand(value) !== null + }) + }) }), onSubmit: (values) => { if (isEphemeral) { From c46fbfbde39b025c5e1692477508c2162b65f4aa Mon Sep 17 00:00:00 2001 From: Mika Andrianarijaona Date: Thu, 2 Nov 2023 15:52:25 +0100 Subject: [PATCH 23/53] feat: add class when collection name is hovered during drag and drop Resolves #849 --- .../Collections/Collection/CollectionItem/StyledWrapper.js | 3 ++- .../Sidebar/Collections/Collection/CollectionItem/index.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/StyledWrapper.js index ea58fe94e..14d7432fa 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/StyledWrapper.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/StyledWrapper.js @@ -33,7 +33,8 @@ const Wrapper = styled.div` overflow: hidden; } - &:hover { + &:hover, + &.item-hovered { background: ${(props) => props.theme.sidebar.collection.item.hoverBg}; .menu-icon { .dropdown { diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js index 31186e380..b12cfde15 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js @@ -84,7 +84,8 @@ const CollectionItem = ({ item, collection, searchText }) => { }); const itemRowClassName = classnames('flex collection-item-name items-center', { - 'item-focused-in-tab': item.uid == activeTabUid + 'item-focused-in-tab': item.uid == activeTabUid, + 'item-hovered': isOver }); const scrollToTheActiveTab = () => { From 741718ede61bb45f8e4783ac57489500bbea7980 Mon Sep 17 00:00:00 2001 From: szto Date: Fri, 3 Nov 2023 00:37:08 +0900 Subject: [PATCH 24/53] feat: korean transation --- docs/readme/readme_kr.md | 121 +++++++++++++++++++++++++++++++++++++++ readme.md | 2 +- 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 docs/readme/readme_kr.md diff --git a/docs/readme/readme_kr.md b/docs/readme/readme_kr.md new file mode 100644 index 000000000..070fd0866 --- /dev/null +++ b/docs/readme/readme_kr.md @@ -0,0 +1,121 @@ +
+ + +### Bruno - API 탐색 및 테스트를 위한 오픈소스 IDE. + +[![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는 새롭고 혁신적인 API 클라이언트로, Postman과 유사한 툴들을 혁신하는 것을 목표로 합니다. + +Bruno는 사용자의 컬렉션을 파일 시스템의 폴더에 직접 저장합니다. 일반 텍스트 마크업 언어인 Bru를 사용해 API 요청에 대한 정보를 저장합니다. + +Git 또는 원하는 버전 관리 도구를 사용하여 API 컬렉션을 연동할 수 있습니다. + +브루는 오프라인 전용입니다. 브루노에 클라우드 동기화 기능을 추가할 계획은 없습니다. 저희는 사용자의 데이터 프라이버시를 소중히 여기며, 데이터는 사용자의 기기에 남아 있어야 한다고 믿습니다. 장기 비전 읽기 [링크](https://github.com/usebruno/bruno/discussions/269) + +📢 Watch our recent talk at India FOSS 3.0 Conference [here](https://www.youtube.com/watch?v=7bSMFpbcPiY) + +![bruno](/assets/images/landing-2.png)

+ +### 설치 + +Bruno 는 여기에서 다운로드 받을 수 있습니다.[링크](https://www.usebruno.com/downloads) (맥, 윈도우, 리눅스) + +Homebrew, Chocolatey, Snap, Apt 같은 패키지 관리자를 통해서도 Bruno를 설치할 수 있습니다. + +```sh +# On Mac via Homebrew +brew install bruno + +# On Windows via Chocolatey +choco install bruno + +# On Linux via Snap +snap install bruno + +# On 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 +``` + +### 여러 플랫폼에서 실행하세요. 🖥️ + +![bruno](assets/images/run-anywhere.png)

+ +### Git과 연동하세요. 👩‍💻🧑‍💻 + +또는 원하는 버전 관리 시스템을 선택하세요. + +![bruno](assets/images/version-control.png)

+ +### 중요 링크 📌 + +- [Our Long Term Vision](https://github.com/usebruno/bruno/discussions/269) +- [Roadmap](https://github.com/usebruno/bruno/discussions/384) +- [Documentation](https://docs.usebruno.com) +- [Website](https://www.usebruno.com) +- [Pricing](https://www.usebruno.com/pricing) +- [Download](https://www.usebruno.com/downloads) + +### 쇼케이스 🎥 + +- [Testimonials](https://github.com/usebruno/bruno/discussions/343) +- [Knowledge Hub](https://github.com/usebruno/bruno/discussions/386) +- [Scriptmania](https://github.com/usebruno/bruno/discussions/385) + +### 지원 ❤️ + +프로젝트가 마음에 들면 ⭐ 버튼을 눌러 주세요. + +### 후기 공유 📣 + +Bruno가 여러분과 여러분의 팀에 도움이 되었다면, 잊지 말고 공유해 주세요. [Github discussion 공유 링크](https://github.com/usebruno/bruno/discussions/343) + +### 새 패키지 관리자에게 게시 + +더 많은 정보를 확인하시려명 링크를 클릭해 주세요.[배포 가이드](publishing.md) + +### 컨트리뷰트 👩‍💻🧑‍💻 + +컨트리뷰트에 관심이 있으시면 링크를 참고해 주세요. [컨트리뷰트 가이드](contributing.md) + +코드를 통해 기여할 수 없더라도 사용 사례를 해결하기 위해 구현이 필요한 버그나 기능 요청을 주저하지 마시고 제출해 주세요. + +### Authors + + + +### Stay in touch 🌐 + +[𝕏 (Twitter)](https://twitter.com/use_bruno)
+[Website](https://www.usebruno.com)
+[Discord](https://discord.com/invite/KgcZUncpjq)
+[LinkedIn](https://www.linkedin.com/company/usebruno) + +### Trademark + +**Name** + +`Bruno` is a trademark held by [Anoop M D](https://www.helloanoop.com/) + +**Logo** + +The logo is sourced from [OpenMoji](https://openmoji.org/library/emoji-1F436/). License: CC [BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) + +### License 📄 + +[MIT](license.md) diff --git a/readme.md b/readme.md index 96a9d7c88..51bd7db9c 100644 --- a/readme.md +++ b/readme.md @@ -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) +**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) | [한국어](docs/readme/readme_kr.md) Bruno is a new and innovative API client, aimed at revolutionizing the status quo represented by Postman and similar tools out there. From 1f709c6faa13d2775d4e76c83e4f8e587ab34582 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Thu, 2 Nov 2023 22:36:48 +0530 Subject: [PATCH 25/53] chore: cli release 1.0.0 --- packages/bruno-cli/changelog.md | 4 ++++ packages/bruno-cli/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/bruno-cli/changelog.md b/packages/bruno-cli/changelog.md index 44130498a..adfa14c1a 100644 --- a/packages/bruno-cli/changelog.md +++ b/packages/bruno-cli/changelog.md @@ -1,5 +1,9 @@ # Changelog +## 1.0.0 + +- Announcing Stable Release + ## 0.13.0 - feat(#306) Module whitelisting and filesystem access support diff --git a/packages/bruno-cli/package.json b/packages/bruno-cli/package.json index 54fb85fbf..88c6eb91d 100644 --- a/packages/bruno-cli/package.json +++ b/packages/bruno-cli/package.json @@ -1,6 +1,6 @@ { "name": "@usebruno/cli", - "version": "0.15.1", + "version": "1.0.0", "license": "MIT", "main": "src/index.js", "bin": { From 44d90c42ed4b8481ba220c15dc6cb99cdb9f4cdd Mon Sep 17 00:00:00 2001 From: Its-treason <39559178+Its-treason@users.noreply.github.com> Date: Thu, 2 Nov 2023 18:17:21 +0100 Subject: [PATCH 26/53] fix(#853): Allow - in variable names & small refactor --- .../EnvironmentDetails/EnvironmentVariables/index.js | 6 +++++- .../src/components/RequestPane/Vars/VarsTable/index.js | 7 +++++-- packages/bruno-app/src/utils/common/regex.js | 1 + packages/bruno-js/src/bru.js | 8 +++++--- 4 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 packages/bruno-app/src/utils/common/regex.js diff --git a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js index dfd93be33..9a8be4226 100644 --- a/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js +++ b/packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js @@ -10,6 +10,7 @@ import StyledWrapper from './StyledWrapper'; import { useFormik } from 'formik'; import * as Yup from 'yup'; import { uuid } from 'utils/common'; +import { envVariableNameRegex } from 'utils/common/regex'; const EnvironmentVariables = ({ environment, collection }) => { const dispatch = useDispatch(); @@ -23,7 +24,10 @@ const EnvironmentVariables = ({ environment, collection }) => { enabled: Yup.boolean(), name: Yup.string() .required('Name cannot be empty') - .matches(/^(?!\d)\w*$/, 'Name contains invalid characters') + .matches( + envVariableNameRegex, + 'Name contains invalid characters. Must only contain alphanumeric characters, "-" and "_"' + ) .trim(), secret: Yup.boolean(), type: Yup.string(), diff --git a/packages/bruno-app/src/components/RequestPane/Vars/VarsTable/index.js b/packages/bruno-app/src/components/RequestPane/Vars/VarsTable/index.js index 77785e47a..4f0177f75 100644 --- a/packages/bruno-app/src/components/RequestPane/Vars/VarsTable/index.js +++ b/packages/bruno-app/src/components/RequestPane/Vars/VarsTable/index.js @@ -9,6 +9,7 @@ import SingleLineEditor from 'components/SingleLineEditor'; import Tooltip from 'components/Tooltip'; import StyledWrapper from './StyledWrapper'; import toast from 'react-hot-toast'; +import { envVariableNameRegex } from 'utils/common/regex'; const VarsTable = ({ item, collection, vars, varType }) => { const dispatch = useDispatch(); @@ -37,8 +38,10 @@ const VarsTable = ({ item, collection, vars, varType }) => { return; } - if (/^\w*$/.test(value) === false) { - toast.error('Variable contains invalid character! Variables must only contain alpha-numeric characters.'); + if (envVariableNameRegex.test(value) === false) { + toast.error( + 'Variable contains invalid character! Variables must only contain alpha-numeric characters, "-" and "_".' + ); return; } diff --git a/packages/bruno-app/src/utils/common/regex.js b/packages/bruno-app/src/utils/common/regex.js new file mode 100644 index 000000000..d55bb55b8 --- /dev/null +++ b/packages/bruno-app/src/utils/common/regex.js @@ -0,0 +1 @@ +export const envVariableNameRegex = /^(?!\d)[\w-]*$/; diff --git a/packages/bruno-js/src/bru.js b/packages/bruno-js/src/bru.js index 5eaae4cca..078aacc78 100644 --- a/packages/bruno-js/src/bru.js +++ b/packages/bruno-js/src/bru.js @@ -1,6 +1,8 @@ const Handlebars = require('handlebars'); const { cloneDeep } = require('lodash'); +const envVariableNameRegex = /^(?!\d)[\w-]*$/; + class Bru { constructor(envVariables, collectionVariables, processEnvVars, collectionPath) { this.envVariables = envVariables; @@ -59,10 +61,10 @@ class Bru { throw new Error('Key is required'); } - if (/^(?!\d)\w*$/.test(key) === false) { + if (envVariableNameRegex.test(key) === false) { throw new Error( `Variable name: "${key}" contains invalid characters!` + - ' Names must only contain alpha-numeric characters and cannot start with a digit.' + ' Names must only contain alpha-numeric characters, "-", "_" and cannot start with a digit.' ); } @@ -70,7 +72,7 @@ class Bru { } getVar(key) { - if (/^(?!\d)\w*$/.test(key) === false) { + if (envVariableNameRegex.test(key) === false) { throw new Error( `Variable name: "${key}" contains invalid characters!` + ' Names must only contain alpha-numeric characters and cannot start with a digit.' From fdb9b103530d21e7f7bbbde0dda0f21d5b851293 Mon Sep 17 00:00:00 2001 From: Boris Baskovec Date: Fri, 3 Nov 2023 12:25:43 +0100 Subject: [PATCH 27/53] Add node-vault library --- packages/bruno-js/package.json | 3 ++- packages/bruno-js/src/runtime/script-runtime.js | 7 +++++-- packages/bruno-js/src/runtime/test-runtime.js | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/bruno-js/package.json b/packages/bruno-js/package.json index d8161c9ec..b6a83c07b 100644 --- a/packages/bruno-js/package.json +++ b/packages/bruno-js/package.json @@ -28,6 +28,7 @@ "moment": "^2.29.4", "nanoid": "3.3.4", "node-fetch": "2.*", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "node-vault": "^0.10.2" } } diff --git a/packages/bruno-js/src/runtime/script-runtime.js b/packages/bruno-js/src/runtime/script-runtime.js index a39e00a50..f87768510 100644 --- a/packages/bruno-js/src/runtime/script-runtime.js +++ b/packages/bruno-js/src/runtime/script-runtime.js @@ -26,6 +26,7 @@ const axios = require('axios'); const fetch = require('node-fetch'); const chai = require('chai'); const CryptoJS = require('crypto-js'); +const NodeVault = require('node-vault'); class ScriptRuntime { constructor() {} @@ -112,7 +113,8 @@ class ScriptRuntime { 'node-fetch': fetch, 'crypto-js': CryptoJS, ...whitelistedModules, - fs: allowScriptFilesystemAccess ? fs : undefined + fs: allowScriptFilesystemAccess ? fs : undefined, + 'node-vault': NodeVault } } }); @@ -201,7 +203,8 @@ class ScriptRuntime { 'node-fetch': fetch, 'crypto-js': CryptoJS, ...whitelistedModules, - fs: allowScriptFilesystemAccess ? fs : undefined + fs: allowScriptFilesystemAccess ? fs : undefined, + 'node-vault': NodeVault } } }); diff --git a/packages/bruno-js/src/runtime/test-runtime.js b/packages/bruno-js/src/runtime/test-runtime.js index fcaa750c9..cc46fd14c 100644 --- a/packages/bruno-js/src/runtime/test-runtime.js +++ b/packages/bruno-js/src/runtime/test-runtime.js @@ -28,6 +28,7 @@ const nanoid = require('nanoid'); const axios = require('axios'); const fetch = require('node-fetch'); const CryptoJS = require('crypto-js'); +const NodeVault = require('node-vault'); class TestRuntime { constructor() {} @@ -130,7 +131,8 @@ class TestRuntime { 'node-fetch': fetch, 'crypto-js': CryptoJS, ...whitelistedModules, - fs: allowScriptFilesystemAccess ? fs : undefined + fs: allowScriptFilesystemAccess ? fs : undefined, + 'node-vault': NodeVault } } }); From 8fb8eee5ef8360283df52b7e78b397d446584798 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Fri, 3 Nov 2023 20:42:49 +0530 Subject: [PATCH 28/53] chore: bump version 1.1.0 --- package-lock.json | 464 +++++++++++++++--- .../bruno-app/src/components/Sidebar/index.js | 2 +- packages/bruno-electron/package.json | 2 +- 3 files changed, 396 insertions(+), 72 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf7a7d95f..ade21b124 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3568,6 +3568,52 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@postman/form-data": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", + "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@postman/tough-cookie": { + "version": "4.1.3-postman.1", + "resolved": "https://registry.npmjs.org/@postman/tough-cookie/-/tough-cookie-4.1.3-postman.1.tgz", + "integrity": "sha512-txpgUqZOnWYnUHZpHjkfb0IwVH4qJmyq77pPnJLlfhMtdCLMFTEeQHlzQiK906aaNCe4NEB5fGJHo9uzGbFMeA==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@postman/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@postman/tunnel-agent": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz", + "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/@react-dnd/asap": { "version": "5.0.2", "license": "MIT" @@ -5076,7 +5122,6 @@ }, "node_modules/ajv": { "version": "6.12.6", - "devOptional": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -5464,7 +5509,6 @@ }, "node_modules/asn1": { "version": "0.2.6", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" @@ -5472,7 +5516,6 @@ }, "node_modules/assert-plus": { "version": "1.0.0", - "devOptional": true, "license": "MIT", "engines": { "node": ">=0.8" @@ -5536,7 +5579,6 @@ }, "node_modules/aws-sign2": { "version": "0.7.0", - "dev": true, "license": "Apache-2.0", "engines": { "node": "*" @@ -5735,7 +5777,6 @@ }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "tweetnacl": "^0.14.3" @@ -5927,6 +5968,14 @@ "node": ">=8" } }, + "node_modules/brotli": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", + "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", + "dependencies": { + "base64-js": "^1.1.2" + } + }, "node_modules/browserslist": { "version": "4.21.4", "dev": true, @@ -6284,7 +6333,6 @@ }, "node_modules/caseless": { "version": "0.12.0", - "dev": true, "license": "Apache-2.0" }, "node_modules/chai": { @@ -7160,7 +7208,6 @@ }, "node_modules/dashdash": { "version": "1.14.1", - "dev": true, "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" @@ -7637,7 +7684,6 @@ }, "node_modules/ecc-jsbn": { "version": "0.1.2", - "dev": true, "license": "MIT", "dependencies": { "jsbn": "~0.1.0", @@ -8202,7 +8248,6 @@ }, "node_modules/extend": { "version": "3.0.2", - "dev": true, "license": "MIT" }, "node_modules/external-editor": { @@ -8266,7 +8311,6 @@ }, "node_modules/extsprintf": { "version": "1.3.0", - "devOptional": true, "engines": [ "node >=0.6.0" ], @@ -8292,7 +8336,6 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "devOptional": true, "license": "MIT" }, "node_modules/fast-xml-parser": { @@ -8543,7 +8586,6 @@ }, "node_modules/forever-agent": { "version": "0.6.1", - "dev": true, "license": "Apache-2.0", "engines": { "node": "*" @@ -8716,7 +8758,6 @@ }, "node_modules/getpass": { "version": "0.1.7", - "dev": true, "license": "MIT", "dependencies": { "assert-plus": "^1.0.0" @@ -9084,7 +9125,6 @@ }, "node_modules/har-validator": { "version": "5.1.5", - "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.3", @@ -10064,7 +10104,6 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/is-unicode-supported": { @@ -10126,7 +10165,6 @@ }, "node_modules/isstream": { "version": "0.1.2", - "dev": true, "license": "MIT" }, "node_modules/istanbul-lib-coverage": { @@ -10802,7 +10840,6 @@ }, "node_modules/jsbn": { "version": "0.1.1", - "dev": true, "license": "MIT" }, "node_modules/jsesc": { @@ -10832,12 +10869,10 @@ }, "node_modules/json-schema": { "version": "0.4.0", - "dev": true, "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "devOptional": true, "license": "MIT" }, "node_modules/json-schema-typed": { @@ -10846,7 +10881,6 @@ }, "node_modules/json-stringify-safe": { "version": "5.0.1", - "dev": true, "license": "ISC" }, "node_modules/json5": { @@ -11779,6 +11813,20 @@ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, + "node_modules/node-vault": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/node-vault/-/node-vault-0.10.2.tgz", + "integrity": "sha512-//uc9/YImE7Dx0QHdwMiAzLaOumiKUnOUP8DymgtkZ8nsq6/V2LKvEu6kw91Lcruw8lWUfj4DO7CIXNPRWBuuA==", + "dependencies": { + "debug": "^4.3.4", + "mustache": "^4.2.0", + "postman-request": "^2.88.1-postman.33", + "tv4": "^1.3.0" + }, + "engines": { + "node": ">= 16.0.0" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "dev": true, @@ -11870,7 +11918,6 @@ }, "node_modules/oauth-sign": { "version": "0.9.0", - "dev": true, "license": "Apache-2.0", "engines": { "node": "*" @@ -12308,7 +12355,6 @@ }, "node_modules/performance-now": { "version": "2.1.0", - "dev": true, "license": "MIT" }, "node_modules/phantomjs-prebuilt": { @@ -13119,6 +13165,99 @@ "form-data": "^4.0.0" } }, + "node_modules/postman-request": { + "version": "2.88.1-postman.33", + "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.33.tgz", + "integrity": "sha512-uL9sCML4gPH6Z4hreDWbeinKU0p0Ke261nU7OvII95NU22HN6Dk7T/SaVPaj6T4TsQqGKIFw6/woLZnH7ugFNA==", + "dependencies": { + "@postman/form-data": "~3.1.1", + "@postman/tough-cookie": "~4.1.3-postman.1", + "@postman/tunnel-agent": "^0.6.3", + "aws-sign2": "~0.7.0", + "aws4": "^1.12.0", + "brotli": "^1.3.3", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "har-validator": "~5.1.3", + "http-signature": "~1.3.1", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "^2.1.35", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.3", + "safe-buffer": "^5.1.2", + "stream-length": "^1.0.2", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postman-request/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/postman-request/node_modules/http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/postman-request/node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/postman-request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/postman-request/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/postman-request/node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "node_modules/prepend-http": { "version": "2.0.0", "dev": true, @@ -13337,7 +13476,6 @@ }, "node_modules/psl": { "version": "1.9.0", - "dev": true, "license": "MIT" }, "node_modules/pump": { @@ -13400,6 +13538,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/queue-microtask": { "version": "1.2.3", "funding": [ @@ -13980,6 +14123,11 @@ "dev": true, "license": "ISC" }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/reselect": { "version": "4.1.7", "license": "MIT" @@ -14694,7 +14842,6 @@ }, "node_modules/sshpk": { "version": "1.17.0", - "dev": true, "license": "MIT", "dependencies": { "asn1": "~0.2.3", @@ -14755,6 +14902,19 @@ "through": "~2.3.4" } }, + "node_modules/stream-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-length/-/stream-length-1.0.2.tgz", + "integrity": "sha512-aI+qKFiwoDV4rsXiS7WRoCt+v2RX1nUj17+KJC5r2gfh5xoSJIfP6Y3Do/HtvesFcTSWthIuJ3l1cvKQY/+nZg==", + "dependencies": { + "bluebird": "^2.6.2" + } + }, + "node_modules/stream-length/node_modules/bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha512-UfFSr22dmHPQqPP9XWHRhq+gWnHCYguQGkXQlbyPtW5qTnhFWA8/iXg765tH0cAjy7l/zPJ1aBTO0g5XgA7kvQ==" + }, "node_modules/streamsearch": { "version": "1.1.0", "engines": { @@ -15630,9 +15790,16 @@ "node": "*" } }, + "node_modules/tv4": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", + "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/tweetnacl": { "version": "0.14.5", - "dev": true, "license": "Unlicense" }, "node_modules/type-detect": { @@ -15874,6 +16041,15 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/url-parse-lax": { "version": "3.0.0", "dev": true, @@ -16552,7 +16728,7 @@ }, "packages/bruno-cli": { "name": "@usebruno/cli", - "version": "0.15.1", + "version": "1.0.0", "license": "MIT", "dependencies": { "@usebruno/js": "0.9.1", @@ -16644,7 +16820,7 @@ }, "packages/bruno-electron": { "name": "bruno", - "version": "v0.27.2", + "version": "v1.0.1", "dependencies": { "@aws-sdk/credential-providers": "^3.425.0", "@usebruno/js": "0.9.1", @@ -16890,6 +17066,7 @@ "moment": "^2.29.4", "nanoid": "3.3.4", "node-fetch": "2.*", + "node-vault": "^0.10.2", "uuid": "^9.0.0" }, "peerDependencies": { @@ -19475,6 +19652,42 @@ "@popperjs/core": { "version": "2.11.6" }, + "@postman/form-data": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz", + "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "@postman/tough-cookie": { + "version": "4.1.3-postman.1", + "resolved": "https://registry.npmjs.org/@postman/tough-cookie/-/tough-cookie-4.1.3-postman.1.tgz", + "integrity": "sha512-txpgUqZOnWYnUHZpHjkfb0IwVH4qJmyq77pPnJLlfhMtdCLMFTEeQHlzQiK906aaNCe4NEB5fGJHo9uzGbFMeA==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "dependencies": { + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" + } + } + }, + "@postman/tunnel-agent": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz", + "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "@react-dnd/asap": { "version": "5.0.2" }, @@ -20554,7 +20767,7 @@ "mousetrap": "^1.6.5", "nanoid": "3.3.4", "next": "12.3.3", - "parse-curl": "*", + "parse-curl": "^0.2.6", "path": "^0.12.7", "platform": "^1.3.6", "posthog-node": "^2.1.0", @@ -20711,6 +20924,7 @@ "moment": "^2.29.4", "nanoid": "3.3.4", "node-fetch": "2.*", + "node-vault": "^0.10.2", "uuid": "^9.0.0" }, "dependencies": { @@ -20966,7 +21180,6 @@ }, "ajv": { "version": "6.12.6", - "devOptional": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -21219,14 +21432,12 @@ }, "asn1": { "version": "0.2.6", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } }, "assert-plus": { - "version": "1.0.0", - "devOptional": true + "version": "1.0.0" }, "assertion-error": { "version": "1.1.0" @@ -21256,8 +21467,7 @@ "version": "1.7.0" }, "aws-sign2": { - "version": "0.7.0", - "dev": true + "version": "0.7.0" }, "aws4": { "version": "1.12.0" @@ -21383,7 +21593,6 @@ }, "bcrypt-pbkdf": { "version": "1.0.2", - "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -21514,6 +21723,14 @@ "fill-range": "^7.0.1" } }, + "brotli": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz", + "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==", + "requires": { + "base64-js": "^1.1.2" + } + }, "browserslist": { "version": "4.21.4", "dev": true, @@ -21873,8 +22090,7 @@ "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==" }, "caseless": { - "version": "0.12.0", - "dev": true + "version": "0.12.0" }, "chai": { "version": "4.3.7", @@ -22422,7 +22638,6 @@ }, "dashdash": { "version": "1.14.1", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -22726,7 +22941,6 @@ }, "ecc-jsbn": { "version": "0.1.2", - "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -23119,8 +23333,7 @@ } }, "extend": { - "version": "3.0.2", - "dev": true + "version": "3.0.2" }, "external-editor": { "version": "3.1.0", @@ -23165,8 +23378,7 @@ } }, "extsprintf": { - "version": "1.3.0", - "devOptional": true + "version": "1.3.0" }, "fast-deep-equal": { "version": "3.1.3" @@ -23182,8 +23394,7 @@ } }, "fast-json-stable-stringify": { - "version": "2.1.0", - "devOptional": true + "version": "2.1.0" }, "fast-xml-parser": { "version": "4.2.5", @@ -23335,8 +23546,7 @@ "version": "1.15.2" }, "forever-agent": { - "version": "0.6.1", - "dev": true + "version": "0.6.1" }, "form-data": { "version": "4.0.0", @@ -23437,7 +23647,6 @@ }, "getpass": { "version": "0.1.7", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -23686,7 +23895,6 @@ }, "har-validator": { "version": "5.1.5", - "dev": true, "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -24251,8 +24459,7 @@ "dev": true }, "is-typedarray": { - "version": "1.0.0", - "dev": true + "version": "1.0.0" }, "is-unicode-supported": { "version": "1.3.0" @@ -24286,8 +24493,7 @@ "version": "3.0.1" }, "isstream": { - "version": "0.1.2", - "dev": true + "version": "0.1.2" }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -24760,8 +24966,7 @@ } }, "jsbn": { - "version": "0.1.1", - "dev": true + "version": "0.1.1" }, "jsesc": { "version": "2.5.2" @@ -24777,19 +24982,16 @@ "version": "2.2.2" }, "json-schema": { - "version": "0.4.0", - "dev": true + "version": "0.4.0" }, "json-schema-traverse": { - "version": "0.4.1", - "devOptional": true + "version": "0.4.1" }, "json-schema-typed": { "version": "7.0.3" }, "json-stringify-safe": { - "version": "5.0.1", - "dev": true + "version": "5.0.1" }, "json5": { "version": "2.2.3" @@ -25377,6 +25579,17 @@ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, + "node-vault": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/node-vault/-/node-vault-0.10.2.tgz", + "integrity": "sha512-//uc9/YImE7Dx0QHdwMiAzLaOumiKUnOUP8DymgtkZ8nsq6/V2LKvEu6kw91Lcruw8lWUfj4DO7CIXNPRWBuuA==", + "requires": { + "debug": "^4.3.4", + "mustache": "^4.2.0", + "postman-request": "^2.88.1-postman.33", + "tv4": "^1.3.0" + } + }, "normalize-package-data": { "version": "2.5.0", "dev": true, @@ -25435,8 +25648,7 @@ "dev": true }, "oauth-sign": { - "version": "0.9.0", - "dev": true + "version": "0.9.0" }, "object-assign": { "version": "4.1.1" @@ -25705,8 +25917,7 @@ "dev": true }, "performance-now": { - "version": "2.1.0", - "dev": true + "version": "2.1.0" }, "phantomjs-prebuilt": { "version": "2.1.16", @@ -26150,6 +26361,83 @@ } } }, + "postman-request": { + "version": "2.88.1-postman.33", + "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.33.tgz", + "integrity": "sha512-uL9sCML4gPH6Z4hreDWbeinKU0p0Ke261nU7OvII95NU22HN6Dk7T/SaVPaj6T4TsQqGKIFw6/woLZnH7ugFNA==", + "requires": { + "@postman/form-data": "~3.1.1", + "@postman/tough-cookie": "~4.1.3-postman.1", + "@postman/tunnel-agent": "^0.6.3", + "aws-sign2": "~0.7.0", + "aws4": "^1.12.0", + "brotli": "^1.3.3", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "har-validator": "~5.1.3", + "http-signature": "~1.3.1", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "^2.1.35", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.3", + "safe-buffer": "^5.1.2", + "stream-length": "^1.0.2", + "uuid": "^8.3.2" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "http-signature": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", + "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.14.1" + } + }, + "jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + } + } + }, "prepend-http": { "version": "2.0.0", "dev": true @@ -26286,8 +26574,7 @@ "version": "1.1.0" }, "psl": { - "version": "1.9.0", - "dev": true + "version": "1.9.0" }, "pump": { "version": "3.0.0", @@ -26327,6 +26614,11 @@ "side-channel": "^1.0.4" } }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "queue-microtask": { "version": "1.2.3" }, @@ -26713,6 +27005,11 @@ "version": "1.0.1", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "reselect": { "version": "4.1.7" }, @@ -27185,7 +27482,6 @@ }, "sshpk": { "version": "1.17.0", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -27223,6 +27519,21 @@ "through": "~2.3.4" } }, + "stream-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-length/-/stream-length-1.0.2.tgz", + "integrity": "sha512-aI+qKFiwoDV4rsXiS7WRoCt+v2RX1nUj17+KJC5r2gfh5xoSJIfP6Y3Do/HtvesFcTSWthIuJ3l1cvKQY/+nZg==", + "requires": { + "bluebird": "^2.6.2" + }, + "dependencies": { + "bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha512-UfFSr22dmHPQqPP9XWHRhq+gWnHCYguQGkXQlbyPtW5qTnhFWA8/iXg765tH0cAjy7l/zPJ1aBTO0g5XgA7kvQ==" + } + } + }, "streamsearch": { "version": "1.1.0" }, @@ -27783,9 +28094,13 @@ "safe-buffer": "^5.0.1" } }, + "tv4": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", + "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==" + }, "tweetnacl": { - "version": "0.14.5", - "dev": true + "version": "0.14.5" }, "type-detect": { "version": "4.0.8" @@ -27922,6 +28237,15 @@ "punycode": "^2.1.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "url-parse-lax": { "version": "3.0.0", "dev": true, diff --git a/packages/bruno-app/src/components/Sidebar/index.js b/packages/bruno-app/src/components/Sidebar/index.js index 69be75689..0e6153f9d 100644 --- a/packages/bruno-app/src/components/Sidebar/index.js +++ b/packages/bruno-app/src/components/Sidebar/index.js @@ -105,7 +105,7 @@ const Sidebar = () => { Star -
v1.0.1
+
v1.1.0
diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json index 5f334ac87..57dff832f 100644 --- a/packages/bruno-electron/package.json +++ b/packages/bruno-electron/package.json @@ -1,5 +1,5 @@ { - "version": "v1.0.1", + "version": "v1.1.0", "name": "bruno", "description": "Opensource API Client for Exploring and Testing APIs", "homepage": "https://www.usebruno.com", From 3ed86acb46e007002c57d42546375bed3c6d6e29 Mon Sep 17 00:00:00 2001 From: Tathagata Chakraborty Date: Fri, 3 Nov 2023 22:30:00 +0530 Subject: [PATCH 29/53] #876 fix- Bengali translation required --- contributing.md | 2 +- docs/contributing/contributing_bn.md | 87 +++++++++++++++++++ docs/contributing/contributing_de.md | 2 + docs/contributing/contributing_fr.md | 2 + docs/contributing/contributing_ru.md | 2 + docs/contributing/contributing_tr.md | 2 + docs/contributing/contributing_ua.md | 2 + docs/readme/readme_bn.md | 123 +++++++++++++++++++++++++++ docs/readme/readme_de.md | 2 + docs/readme/readme_fr.md | 3 + docs/readme/readme_ru.md | 3 + docs/readme/readme_tr.md | 2 + docs/readme/readme_ua.md | 2 + readme.md | 2 +- 14 files changed, 234 insertions(+), 2 deletions(-) create mode 100644 docs/contributing/contributing_bn.md create mode 100644 docs/readme/readme_bn.md diff --git a/contributing.md b/contributing.md index 0d6efdffa..904fdb168 100644 --- a/contributing.md +++ b/contributing.md @@ -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) | [বাংলা](docs/contributing/contributing_bn.md) ## Let's make bruno better, together !! diff --git a/docs/contributing/contributing_bn.md b/docs/contributing/contributing_bn.md new file mode 100644 index 000000000..e30ecc339 --- /dev/null +++ b/docs/contributing/contributing_bn.md @@ -0,0 +1,87 @@ +[English](/contributing.md) | [Українська](/contributing_ua.md) | [Русский](/contributing_ru.md) | [Türkçe](/contributing_tr.md) | [Deutsch](docs/contributing/contributing_de.md) | [Français](/contributing_fr.md) | **বাংলা** + +## আসুন ব্রুনোকে আরও ভালো করি, একসাথে!! + +আমরা খুশি যে আপনি ব্রুনোর উন্নতি করতে চাইছেন। নীচে আপনার কম্পিউটারে ব্রুনো ইনষ্টল করার নির্দেশিকা রয়েছে৷। + +### Technology Stack (প্রযুক্তি স্ট্যাক) + +ব্রুনো Next.js এবং React ব্যবহার করে নির্মিত। এছাড়াও আমরা একটি ডেস্কটপ সংস্করণ পাঠাতে ইলেক্ট্রন ব্যবহার করি (যা স্থানীয় সংগ্রহ সমর্থন করে) + +নিম্ন লিখিত লাইব্রেরি আমরা ব্যবহার করি - + +- CSS - Tailwind +- Code Editors - Codemirror +- State Management - Redux +- Icons - Tabler Icons +- Forms - formik +- Schema Validation - Yup +- Request Client - axios +- Filesystem Watcher - chokidar + +### Dependencies (নির্ভরতা) + +আপনার প্রয়োজন হবে [নোড v18.x বা সর্বশেষ LTS সংস্করণ](https://nodejs.org/en/) এবং npm 8.x। আমরা প্রকল্পে npm ওয়ার্কস্পেস ব্যবহার করি । + +## Development + +ব্রুনো একটি ডেস্কটপ অ্যাপ হিসেবে তৈরি করা হচ্ছে। আপনাকে একটি টার্মিনালে Next.js অ্যাপটি চালিয়ে অ্যাপটি লোড করতে হবে এবং তারপরে অন্য টার্মিনালে ইলেক্ট্রন অ্যাপটি চালাতে হবে। + +### Dependencies (নির্ভরতা) + +- NodeJS v18 + +### Local Development + +```bash +# nodejs 18 সংস্করণ ব্যবহার করুন +nvm use + +# নির্ভরতা ইনস্টল করুন +npm i --legacy-peer-deps + +# গ্রাফকিউএল ডক্স তৈরি করুন +npm run build:graphql-docs + +# ব্রুনো কোয়েরি তৈরি করুন +npm run build:bruno-query + +# NextJs অ্যাপ চালান (টার্মিনাল 1) +npm run dev:web + +# ইলেক্ট্রন অ্যাপ চালান (টার্মিনাল 2) +npm run dev:electron +``` + +### Troubleshooting (সমস্যা সমাধান) + +আপনি যখন 'npm install' চালান তখন আপনি একটি 'অসমর্থিত প্ল্যাটফর্ম' ত্রুটির সম্মুখীন হতে পারেন৷ এটি ঠিক করতে, আপনাকে `node_modules` এবং `package-lock.json` মুছে ফেলতে হবে এবং `npm install` চালাতে হবে। এটি অ্যাপটি চালানোর জন্য প্রয়োজনীয় সমস্ত প্যাকেজ ইনস্টল করবে যাতে এই ত্রুটি ঠিক হয়ে যেতে পারে । + +```shell +# সাব-ডিরেক্টরিতে নোড_মডিউল মুছুন +find ./ -type d -name "node_modules" -print0 | while read -d $'\0' dir; do + rm -rf "$dir" +done + +# সাব-ডিরেক্টরিতে প্যাকেজ-লক মুছুন +find . -type f -name "package-lock.json" -delete +``` + +### Testing (পরীক্ষা) + +```bash +# bruno-schema +npm test --workspace=packages/bruno-schema + +# bruno-lang +npm test --workspace=packages/bruno-lang +``` + +### Raising Pull Request (পুল অনুরোধ উত্থাপন) + +- অনুগ্রহ করে PR এর আকার ছোট রাখুন এবং একটি বিষয়ে ফোকাস করুন। +- অনুগ্রহ করে শাখা তৈরির বিন্যাস অনুসরণ করুন। + - বৈশিষ্ট্য/[ফিচারের নাম]: এই শাখায় একটি নির্দিষ্ট বৈশিষ্ট্যের জন্য পরিবর্তন থাকতে হবে। + - উদাহরণ: বৈশিষ্ট্য/ডার্ক-মোড। + - বাগফিক্স/[বাগ নাম]: এই শাখায় একটি নির্দিষ্ট বাগ-এর জন্য শুধুমাত্র বাগ ফিক্স থাকা উচিত। + - উদাহরণ বাগফিক্স/বাগ-1। diff --git a/docs/contributing/contributing_de.md b/docs/contributing/contributing_de.md index b0b1b694d..be3126c04 100644 --- a/docs/contributing/contributing_de.md +++ b/docs/contributing/contributing_de.md @@ -1,3 +1,5 @@ +[English](/contributing.md) | [Українська](/contributing_ua.md) | [Русский](/contributing_ru.md) | [Türkçe](/contributing_tr.md) | **Deutsch** | [Français](/contributing_fr.md) | [বাংলা](docs/contributing/contributing_bn.md) + ## Lass uns Bruno noch besser machen, gemeinsam !! Ich freue mich, dass Du Bruno verbessern möchtest. Hier findest Du eine Anleitung, mit der Du Bruno auf Deinem Computer einrichten kannst. diff --git a/docs/contributing/contributing_fr.md b/docs/contributing/contributing_fr.md index b69260e43..006972e9f 100644 --- a/docs/contributing/contributing_fr.md +++ b/docs/contributing/contributing_fr.md @@ -1,3 +1,5 @@ +[English](/contributing.md) | [Українська](/contributing_ua.md) | [Русский](/contributing_ru.md) | [Türkçe](/contributing_tr.md) | [Deutsch](/contributing_de.md) | **Français** | [বাংলা](docs/contributing/contributing_bn.md) + ## Ensemble, améliorons Bruno ! Je suis content de voir que vous envisagez améliorer Bruno. Ci-dessous, vous trouverez les règles et guides pour récupérer Bruno sur votre ordinateur. diff --git a/docs/contributing/contributing_ru.md b/docs/contributing/contributing_ru.md index 6202c8f33..5f3c270b2 100644 --- a/docs/contributing/contributing_ru.md +++ b/docs/contributing/contributing_ru.md @@ -1,3 +1,5 @@ +[English](/contributing.md) | [Українська](/contributing_ua.md) | **Русский** | [Türkçe](/contributing_tr.md) | [Deutsch](/contributing_de.md) | [Français](/contributing_fr.md) | [বাংলা](docs/contributing/contributing_bn.md) + ## Давайте вместе сделаем Бруно лучше!!! Я рад, что Вы хотите усовершенствовать bruno. Ниже приведены рекомендации по запуску bruno на вашем компьютере. diff --git a/docs/contributing/contributing_tr.md b/docs/contributing/contributing_tr.md index 25ff880cc..4d63bd413 100644 --- a/docs/contributing/contributing_tr.md +++ b/docs/contributing/contributing_tr.md @@ -1,3 +1,5 @@ +[English](/readme.md) | [Українська](/contributing_ua.md) | [Русский](/contributing_ru.md) | **Türkçe** | [Deutsch](/contributing_de.md) | [Français](/contributing_fr.md) | [বাংলা](docs/contributing/contributing_bn.md) + ## Bruno'yu birlikte daha iyi hale getirelim !! Bruno'yu geliştirmek istemenizden mutluluk duyuyorum. Aşağıda, bruno'yu bilgisayarınıza getirmeye başlamak için yönergeler bulunmaktadır. diff --git a/docs/contributing/contributing_ua.md b/docs/contributing/contributing_ua.md index 329077cd1..723aa7708 100644 --- a/docs/contributing/contributing_ua.md +++ b/docs/contributing/contributing_ua.md @@ -1,3 +1,5 @@ +[English](/contributing.md) | **Українська** | [Русский](/contributing_ru.md) | [Türkçe](/contributing_tr.md) | [Deutsch](/contributing_de.md) | [Français](/contributing_fr.md) | [বাংলা](docs/contributing/contributing_bn.md) + ## Давайте зробимо Bruno краще, разом !! Я дуже радий що Ви бажаєте покращити Bruno. Нижче наведені вказівки як розпочати розробку Bruno на Вашому комп'ютері. diff --git a/docs/readme/readme_bn.md b/docs/readme/readme_bn.md new file mode 100644 index 000000000..bcf313d61 --- /dev/null +++ b/docs/readme/readme_bn.md @@ -0,0 +1,123 @@ +
+ + +### ব্রুনো - API অন্বেষণ এবং পরীক্ষা করার জন্য ওপেনসোর্স IDE। + +[![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](../../readme.md) | [Українська](docs/readme/readme_ua.md) | [Русский](docs/readme/readme_ru.md) | [Türkçe](docs/readme/readme_tr.md) | [Deutsch](docs/readme/readme_de.md) | [Français](docs/readme/readme_fr.md) | **বাংলা** + +ব্রুনো হল একটি নতুন এবং উদ্ভাবনী API ক্লায়েন্ট, যার লক্ষ্য পোস্টম্যান এবং অনুরূপ সরঞ্জাম দ্বারা প্রতিনিধিত্ব করা স্থিতাবস্থায় বিপ্লব ঘটানো। + +ব্রুনো আপনার সংগ্রহগুলি সরাসরি আপনার ফাইল সিস্টেমের একটি ফোল্ডারে সঞ্চয় করে। আমরা API অনুরোধ সম্পর্কে তথ্য সংরক্ষণ করতে একটি প্লেইন টেক্সট মার্কআপ ভাষা, ব্রু ব্যবহার করি। + +আপনি আপনার API সংগ্রহে সহযোগিতা করতে গিট বা আপনার পছন্দের যেকোনো সংস্করণ নিয়ন্ত্রণ ব্যবহার করতে পারেন। + +ব্রুনো শুধুমাত্র অফলাইন। ব্রুনোতে ক্লাউড-সিঙ্ক যোগ করার কোন পরিকল্পনা নেই, কখনও। আমরা আপনার ডেটা গোপনীয়তার মূল্য দিই এবং বিশ্বাস করি এটি আপনার ডিভাইসে থাকা উচিত। আমাদের দীর্ঘমেয়াদী দৃষ্টি পড়ুন। [এখানে ](https://github.com/usebruno/bruno/discussions/269) + +📢 ইন্ডিয়া FOSS 3.0 সম্মেলনে আমাদের সাম্প্রতিক আলোচনা দেখুন [এখানে](https://www.youtube.com/watch?v=7bSMFpbcPiY) + +![bruno](/assets/images/landing-2.png)

+ +### স্থাপন + +ব্রুনো বাইনারি ডাউনলোড হিসাবে উপলব্ধ [আমাদের ওয়েবসাইটে](https://www.usebruno.com/downloads) ম্যাক, উইন্ডোজ এবং লিনাক্সের জন্য। + +আপনি Homebrew, Chocolatey, Snap এবং Apt এর মত প্যাকেজ ম্যানেজারদের মাধ্যমে ব্রুনো ইনস্টল করতে পারেন। + +```sh +# Homebrew এর মাধ্যমে Mac-এ +brew install bruno + +# চকোলেটির মাধ্যমে উইন্ডোজে +choco install bruno + +# স্ন্যাপ এর মাধ্যমে লিনাক্সে +snap install bruno + +# 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 +``` + +### একাধিক প্ল্যাটফর্মে চালান 🖥️ + +![bruno](/assets/images/run-anywhere.png)

+ +### Git এর মাধ্যমে সহযোগিতা করুন 👩‍💻🧑‍💻 + +অথবা আপনার পছন্দের যেকোনো সংস্করণ নিয়ন্ত্রণ ব্যবস্থা + +![bruno](/assets/images/version-control.png)

+ +### গুরুত্বপূর্ণ লিংক 📌 + +- [আমাদের দীর্ঘমেয়াদী দৃষ্টি](https://github.com/usebruno/bruno/discussions/269) +- [রোডম্যাপ](https://github.com/usebruno/bruno/discussions/384) +- [ডকুমেন্টেশন](https://docs.usebruno.com) +- [ওয়েবসাইট](https://www.usebruno.com) +- [মূল্য](https://www.usebruno.com/pricing) +- [ডাউনলোড করুন](https://www.usebruno.com/downloads) + +### শোকেস 🎥 + +- [প্রশংসাপত্র](https://github.com/usebruno/bruno/discussions/343) +- [নলেজ হাব](https://github.com/usebruno/bruno/discussions/386) +- [স্ক্রিপ্টম্যানিয়া](https://github.com/usebruno/bruno/discussions/385) + +### সমর্থন ❤️ + +উফ ! আপনি যদি প্রকল্পটি পছন্দ করেন তবে ⭐ বোতামটি টিপুন !! + +### প্রশংসাপত্র শেয়ার করুন 📣 + +যদি ব্রুনো আপনাকে কর্মক্ষেত্রে এবং আপনার দলগুলিতে সাহায্য করে থাকে, অনুগ্রহ করে আপনার [আমাদের গিটহাব আলোচনায় প্রশংসাপত্রগুলি](https://github.com/usebruno/bruno/discussions/343) শেয়ার করতে ভুলবেন না + +### নতুন প্যাকেজ পরিচালকদের কাছে প্রকাশ করা হচ্ছে + +আরও তথ্যের জন্য অনুগ্রহ করে [এখানে](publishing.md) দেখুন। + +### অবদান 👩‍💻🧑‍💻 + +আমি খুশি যে আপনি ব্রুনোর উন্নতি করতে চাইছেন। অনুগ্রহ করে [অবদানকারী নির্দেশিকা](contributing.md) দেখুন + +আপনি কোডের মাধ্যমে অবদান রাখতে না পারলেও, অনুগ্রহ করে বাগ এবং বৈশিষ্ট্যের অনুরোধ ফাইল করতে দ্বিধা করবেন না যা আপনার ব্যবহারের ক্ষেত্রে সমাধান করার জন্য প্রয়োগ করা প্রয়োজন। + +### লেখক + + + +### সাথে থাকুন 🌐 + +[𝕏 (টুইটার)](https://twitter.com/use_bruno)
+[ওয়েবসাইট](https://www.usebruno.com)
+[ডিসকর্ড](https://discord.com/invite/KgcZUncpjq)
+[লিঙ্কডইন](https://www.linkedin.com/company/usebruno) + +### ট্রেডমার্ক + +**নাম** + +`Bruno` হল একটি ট্রেডমার্ক [Anoop M D](https://www.helloanoop.com/) + +**লোগো** + +লোগোটি [OpenMoji](https://openmoji.org/library/emoji-1F436/) থেকে নেওয়া হয়েছে। লাইসেন্স: CC [BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) + +### লাইসেন্স 📄 + +[MIT](license.md) diff --git a/docs/readme/readme_de.md b/docs/readme/readme_de.md index 371672b4c..111bb04c0 100644 --- a/docs/readme/readme_de.md +++ b/docs/readme/readme_de.md @@ -10,6 +10,8 @@ [![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](/readme.md) | [Українська](/readme_ua.md) | [Русский](/readme_ru.md) | [Türkçe](/readme_tr.md) | **Deutsch** | [Français](/readme_fr.md) | [বাংলা](docs/readme/readme_bn.md) + Bruno ist ein neuer und innovativer API-Client, der den Status Quo von Postman und ähnlichen Tools revolutionieren soll. Bruno speichert Deine Sammlungen direkt in einem Ordner in Deinem Dateisystem. Wir verwenden eine einfache Textauszeichnungssprache - Bru - um Informationen über API-Anfragen zu speichern. diff --git a/docs/readme/readme_fr.md b/docs/readme/readme_fr.md index 9c3fdd6cd..f350080a3 100644 --- a/docs/readme/readme_fr.md +++ b/docs/readme/readme_fr.md @@ -10,6 +10,9 @@ [![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](/readme.md) | [Українська](/readme_ua.md) | [Русский](/readme_ru.md) | [Türkçe](/readme_tr.md) | [Deutsch](/readme_de.md) | **Français** | [বাংলা](docs/readme/readme_bn.md) + Bruno est un nouveau client API, innovant, qui a pour but de révolutionner le _status quo_ que représente Postman et les autres outils. Bruno sauvegarde vos collections directement sur votre système de fichiers. Nous utilisons un langage de balise de type texte pour décrire les requêtes API. diff --git a/docs/readme/readme_ru.md b/docs/readme/readme_ru.md index ddbe8135c..0779bd5a3 100644 --- a/docs/readme/readme_ru.md +++ b/docs/readme/readme_ru.md @@ -10,6 +10,9 @@ [![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](/readme.md) | [Українська](/readme_ua.md) | **Русский** | [Türkçe](/readme_tr.md) | [Deutsch](/readme_de.md) | [Français](/readme_fr.md) | [বাংলা](docs/readme/readme_bn.md) + Bruno - новый и инновационный клиент API, направленный на революцию в установившейся ситуации, представленной Postman и подобными инструментами. Bruno хранит ваши коллекции непосредственно в папке в вашей файловой системе. Для сохранения информации об API-запросах мы используем язык Bru. diff --git a/docs/readme/readme_tr.md b/docs/readme/readme_tr.md index b04738505..9e67a9807 100644 --- a/docs/readme/readme_tr.md +++ b/docs/readme/readme_tr.md @@ -10,6 +10,8 @@ [![Web Sitesi](https://img.shields.io/badge/Website-Visit-blue)](https://www.usebruno.com) [![İndir](https://img.shields.io/badge/Download-Latest-brightgreen)](https://www.usebruno.com/downloads) +[English](/readme.md) | [Українська](/readme_ua.md) | [Русский](/readme_ru.md) | **Türkçe** | [Deutsch](/readme_de.md) | [Français](/readme_fr.md) | [বাংলা](docs/readme/readme_bn.md) + Bruno, Postman ve benzeri araçlar tarafından temsil edilen statükoda devrim yaratmayı amaçlayan yeni ve yenilikçi bir API istemcisidir. Bruno koleksiyonlarınızı doğrudan dosya sisteminizdeki bir klasörde saklar. API istekleri hakkındaki bilgileri kaydetmek için düz bir metin biçimlendirme dili olan Bru kullanıyoruz. diff --git a/docs/readme/readme_ua.md b/docs/readme/readme_ua.md index cb0ccb9ee..cd58ed569 100644 --- a/docs/readme/readme_ua.md +++ b/docs/readme/readme_ua.md @@ -10,6 +10,8 @@ [![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](/readme.md) | **Українська** | [Русский](/readme_ru.md) | [Türkçe](/readme_tr.md) | [Deutsch](/readme_de.md) | [Français](/readme_fr.md) | [বাংলা](docs/readme/readme_bn.md) + Bruno це новий та іноваційний API клієнт, націлений на революційну зміну статус кво, запровадженого інструментами на кшталт Postman. Bruno зберігає ваші колекції напряму у теці на вашому диску. Він використовує текстову мову розмітки Bru для збереження інформації про ваші API запити. diff --git a/readme.md b/readme.md index 96a9d7c88..d5306e6d1 100644 --- a/readme.md +++ b/readme.md @@ -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) +**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) | [বাংলা](docs/readme/readme_bn.md) Bruno is a new and innovative API client, aimed at revolutionizing the status quo represented by Postman and similar tools out there. From 5be12543e55be32bbb8861a903324d3ea68270ec Mon Sep 17 00:00:00 2001 From: Its-treason <39559178+Its-treason@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:13:24 +0100 Subject: [PATCH 30/53] fix: Fix Content-Security-Policy config --- packages/bruno-electron/src/index.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/bruno-electron/src/index.js b/packages/bruno-electron/src/index.js index 602517b5b..a65dc28c6 100644 --- a/packages/bruno-electron/src/index.js +++ b/packages/bruno-electron/src/index.js @@ -14,16 +14,18 @@ const { loadWindowState, saveBounds, saveMaximized } = require('./utils/window') const lastOpenedCollections = new LastOpenedCollections(); +// Reference: https://content-security-policy.com/ const contentSecurityPolicy = [ - isDev ? "default-src 'self' 'unsafe-inline' 'unsafe-eval'" : "default-src 'self'", - "connect-src 'self' https://api.github.com/repos/usebruno/bruno", - "font-src 'self' https://fonts.gstatic.com", + "default-src 'self'", + "script-src * 'unsafe-inline' 'unsafe-eval'", + "connect-src 'self' api.github.com", + "font-src 'self' https:", "form-action 'none'", - "img-src 'self' blob: data:", - "style-src 'self' https://fonts.googleapis.com" + "img-src 'self' blob: data: https:", + "style-src 'self' 'unsafe-inline' https:" ]; -setContentSecurityPolicy(contentSecurityPolicy.join(';')); +setContentSecurityPolicy(contentSecurityPolicy.join(';') + ';'); const menu = Menu.buildFromTemplate(menuTemplate); Menu.setApplicationMenu(menu); From ce91812ce5f6087aba4c22132d8496a35273280a Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Wed, 8 Nov 2023 01:36:37 +0530 Subject: [PATCH 31/53] feat(#338): curl parser based in curlconverter --- package-lock.json | 467 ++++++++++++++---- packages/bruno-app/package.json | 6 +- .../bruno-app/src/utils/common/codemirror.js | 1 - packages/bruno-app/src/utils/common/index.js | 12 + .../bruno-app/src/utils/common/index.spec.js | 35 +- .../bruno-app/src/utils/curl/curl-to-json.js | 169 +++++++ .../src/utils/curl/curl-to-json.spec.js | 62 +++ packages/bruno-app/src/utils/curl/index.js | 79 +-- .../bruno-app/src/utils/curl/parse-curl.js | 238 +++++++++ 9 files changed, 942 insertions(+), 127 deletions(-) create mode 100644 packages/bruno-app/src/utils/curl/curl-to-json.js create mode 100644 packages/bruno-app/src/utils/curl/curl-to-json.spec.js create mode 100644 packages/bruno-app/src/utils/curl/parse-curl.js diff --git a/package-lock.json b/package-lock.json index b814d03e3..a1e845084 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6241,11 +6241,13 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "license": "MIT", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7320,12 +7322,27 @@ "dev": true, "license": "MIT" }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/define-properties": { - "version": "1.1.4", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "license": "MIT", "optional": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -8673,8 +8690,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "license": "MIT" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/generic-names": { "version": "4.0.0", @@ -8715,12 +8736,14 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "license": "MIT", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8949,6 +8972,17 @@ "csstype": "^3.0.10" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/got": { "version": "9.6.0", "dev": true, @@ -9165,9 +9199,7 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.0", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "get-intrinsic": "^1.1.1" }, @@ -9175,6 +9207,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "license": "MIT", @@ -9213,6 +9256,17 @@ "node": ">=0.10.0" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "dev": true, @@ -11931,8 +11985,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "license": "MIT", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -12218,14 +12273,6 @@ "xml2js": "^0.4.5" } }, - "node_modules/parse-curl": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/parse-curl/-/parse-curl-0.2.6.tgz", - "integrity": "sha512-ENhXeIxG4A6wFvYSU87b0o3Tp6U+Wup069GYhXCn0ZP/E7evfvomTSM/MeEOs3QTyuye+u2r7fFRj6nX0q9kQA==", - "dependencies": { - "shellwords": "^0.1.0" - } - }, "node_modules/parse-headers": { "version": "2.0.5", "dev": true, @@ -13724,7 +13771,6 @@ }, "node_modules/react-is": { "version": "18.2.0", - "dev": true, "license": "MIT" }, "node_modules/react-redux": { @@ -14611,6 +14657,20 @@ "dev": true, "license": "ISC" }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/set-value": { "version": "4.1.0", "funding": [ @@ -14665,11 +14725,6 @@ "node": ">=8" } }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" - }, "node_modules/side-channel": { "version": "1.0.4", "license": "MIT", @@ -14915,6 +14970,14 @@ "node": ">=10.0.0" } }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", + "engines": { + "node": ">=4" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "license": "MIT", @@ -16035,6 +16098,15 @@ "punycode": "^2.1.0" } }, + "node_modules/url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.11.2" + } + }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -16055,6 +16127,25 @@ "node": ">=4" } }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/url/node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/use-sync-external-store": { "version": "1.2.0", "license": "MIT", @@ -16578,7 +16669,8 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "license": "ISC", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "engines": { "node": ">=12" } @@ -16635,6 +16727,7 @@ "classnames": "^2.3.1", "codemirror": "^5.65.2", "codemirror-graphql": "^1.2.5", + "cookie": "^0.6.0", "escape-html": "^1.0.3", "file-dialog": "^0.0.8", "file-saver": "^2.0.5", @@ -16647,17 +16740,18 @@ "httpsnippet": "^3.0.1", "idb": "^7.0.0", "immer": "^9.0.15", + "jsesc": "^3.0.2", "know-your-http-well": "^0.5.0", "lodash": "^4.17.21", "markdown-it": "^13.0.2", "mousetrap": "^1.6.5", "nanoid": "3.3.4", "next": "12.3.3", - "parse-curl": "^0.2.6", "path": "^0.12.7", "platform": "^1.3.6", "posthog-node": "^2.1.0", "qs": "^6.11.0", + "query-string": "^7.0.1", "react": "18.2.0", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", @@ -16670,7 +16764,9 @@ "sass": "^1.46.0", "styled-components": "^5.3.3", "tailwindcss": "^2.2.19", + "url": "^0.11.3", "xml-formatter": "^3.5.0", + "yargs-parser": "^21.1.1", "yup": "^0.32.11" }, "devDependencies": { @@ -16706,6 +16802,22 @@ "proxy-from-env": "^1.1.0" } }, + "packages/bruno-app/node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "packages/bruno-app/node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "engines": { + "node": ">=0.10" + } + }, "packages/bruno-app/node_modules/entities": { "version": "3.0.1", "license": "BSD-2-Clause", @@ -16716,6 +16828,25 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "packages/bruno-app/node_modules/filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "packages/bruno-app/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "packages/bruno-app/node_modules/markdown-it": { "version": "13.0.2", "license": "MIT", @@ -16730,6 +16861,31 @@ "markdown-it": "bin/markdown-it.js" } }, + "packages/bruno-app/node_modules/query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "dependencies": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/bruno-app/node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "engines": { + "node": ">=6" + } + }, "packages/bruno-cli": { "name": "@usebruno/cli", "version": "1.0.0", @@ -16824,7 +16980,7 @@ }, "packages/bruno-electron": { "name": "bruno", - "version": "v1.0.1", + "version": "v1.1.0", "dependencies": { "@aws-sdk/credential-providers": "^3.425.0", "@usebruno/js": "0.9.1", @@ -20482,7 +20638,8 @@ } }, "@tabler/icons": { - "version": "1.119.0" + "version": "1.119.0", + "requires": {} }, "@tauri-apps/cli": { "version": "1.2.2", @@ -20756,6 +20913,7 @@ "classnames": "^2.3.1", "codemirror": "^5.65.2", "codemirror-graphql": "^1.2.5", + "cookie": "^0.6.0", "cross-env": "^7.0.3", "css-loader": "^6.5.1", "escape-html": "^1.0.3", @@ -20773,6 +20931,7 @@ "httpsnippet": "^3.0.1", "idb": "^7.0.0", "immer": "^9.0.15", + "jsesc": "^3.0.2", "know-your-http-well": "^0.5.0", "lodash": "^4.17.21", "markdown-it": "^13.0.2", @@ -20780,12 +20939,12 @@ "mousetrap": "^1.6.5", "nanoid": "3.3.4", "next": "12.3.3", - "parse-curl": "^0.2.6", "path": "^0.12.7", "platform": "^1.3.6", "posthog-node": "^2.1.0", "prettier": "^2.7.1", "qs": "^6.11.0", + "query-string": "^7.0.1", "react": "18.2.0", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", @@ -20799,9 +20958,11 @@ "style-loader": "^3.3.1", "styled-components": "^5.3.3", "tailwindcss": "^2.2.19", + "url": "^0.11.3", "webpack": "^5.64.4", "webpack-cli": "^4.9.1", "xml-formatter": "^3.5.0", + "yargs-parser": "*", "yup": "^0.32.11" }, "dependencies": { @@ -20818,9 +20979,29 @@ "proxy-from-env": "^1.1.0" } }, + "cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" + }, + "decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" + }, "entities": { "version": "3.0.1" }, + "filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==" + }, + "jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==" + }, "markdown-it": { "version": "13.0.2", "requires": { @@ -20830,6 +21011,22 @@ "mdurl": "^1.0.1", "uc.micro": "^1.0.5" } + }, + "query-string": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", + "requires": { + "decode-uri-component": "^0.2.2", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + } + }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" } } }, @@ -21008,7 +21205,8 @@ } }, "@usebruno/schema": { - "version": "file:packages/bruno-schema" + "version": "file:packages/bruno-schema", + "requires": {} }, "@usebruno/testbench": { "version": "file:packages/bruno-testbench", @@ -21152,7 +21350,8 @@ }, "@webpack-cli/configtest": { "version": "1.2.0", - "dev": true + "dev": true, + "requires": {} }, "@webpack-cli/info": { "version": "1.5.0", @@ -21163,7 +21362,8 @@ }, "@webpack-cli/serve": { "version": "1.7.0", - "dev": true + "dev": true, + "requires": {} }, "@xtuc/ieee754": { "version": "1.2.0", @@ -21239,7 +21439,8 @@ }, "ajv-keywords": { "version": "3.5.2", - "dev": true + "dev": true, + "requires": {} }, "amdefine": { "version": "0.0.8" @@ -22064,10 +22265,13 @@ } }, "call-bind": { - "version": "1.0.2", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" } }, "callsites": { @@ -22130,7 +22334,8 @@ "chai-string": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/chai-string/-/chai-string-1.5.0.tgz", - "integrity": "sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw==" + "integrity": "sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw==", + "requires": {} }, "chalk": { "version": "4.1.2", @@ -22525,7 +22730,8 @@ }, "css-declaration-sorter": { "version": "6.3.1", - "dev": true + "dev": true, + "requires": {} }, "css-loader": { "version": "6.7.3", @@ -22644,7 +22850,8 @@ }, "cssnano-utils": { "version": "3.1.0", - "dev": true + "dev": true, + "requires": {} }, "csso": { "version": "4.2.0", @@ -22724,11 +22931,24 @@ "version": "1.1.3", "dev": true }, + "define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "requires": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, "define-properties": { - "version": "1.1.4", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "optional": true, "requires": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } @@ -23621,7 +23841,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "generic-names": { "version": "4.0.0", @@ -23647,11 +23869,14 @@ "version": "2.0.0" }, "get-intrinsic": { - "version": "1.1.3", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-own-enumerable-property-symbols": { @@ -23797,7 +24022,16 @@ } }, "goober": { - "version": "2.1.11" + "version": "2.1.11", + "requires": {} + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } }, "got": { "version": "9.6.0", @@ -23943,12 +24177,15 @@ }, "has-property-descriptors": { "version": "1.0.0", - "dev": true, - "optional": true, "requires": { "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, "has-symbols": { "version": "1.0.3" }, @@ -23970,6 +24207,14 @@ } } }, + "hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "dev": true @@ -24159,7 +24404,8 @@ }, "icss-utils": { "version": "5.1.0", - "dev": true + "dev": true, + "requires": {} }, "idb": { "version": "7.1.1" @@ -24759,7 +25005,8 @@ }, "jest-pnp-resolver": { "version": "1.2.3", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "29.2.0", @@ -25344,7 +25591,8 @@ "version": "1.4.1" }, "meros": { - "version": "1.2.1" + "version": "1.2.1", + "requires": {} }, "methods": { "version": "1.1.2" @@ -25673,7 +25921,9 @@ "version": "2.2.0" }, "object-inspect": { - "version": "1.12.3" + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==" }, "object-keys": { "version": "1.1.1", @@ -25846,14 +26096,6 @@ "xml2js": "^0.4.5" } }, - "parse-curl": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/parse-curl/-/parse-curl-0.2.6.tgz", - "integrity": "sha512-ENhXeIxG4A6wFvYSU87b0o3Tp6U+Wup069GYhXCn0ZP/E7evfvomTSM/MeEOs3QTyuye+u2r7fFRj6nX0q9kQA==", - "requires": { - "shellwords": "^0.1.0" - } - }, "parse-headers": { "version": "2.0.5", "dev": true @@ -26121,19 +26363,23 @@ }, "postcss-discard-comments": { "version": "5.1.2", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-duplicates": { "version": "5.1.0", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-empty": { "version": "5.1.1", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-overridden": { "version": "5.1.0", - "dev": true + "dev": true, + "requires": {} }, "postcss-js": { "version": "3.0.3", @@ -26215,7 +26461,8 @@ }, "postcss-modules-extract-imports": { "version": "3.0.0", - "dev": true + "dev": true, + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.0", @@ -26248,7 +26495,8 @@ }, "postcss-normalize-charset": { "version": "5.1.0", - "dev": true + "dev": true, + "requires": {} }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -26724,11 +26972,11 @@ } }, "react-inspector": { - "version": "6.0.2" + "version": "6.0.2", + "requires": {} }, "react-is": { - "version": "18.2.0", - "dev": true + "version": "18.2.0" }, "react-redux": { "version": "7.2.9", @@ -26875,7 +27123,8 @@ } }, "redux-thunk": { - "version": "2.4.2" + "version": "2.4.2", + "requires": {} }, "regenerate": { "version": "1.4.2", @@ -27112,7 +27361,8 @@ }, "rollup-plugin-peer-deps-external": { "version": "2.2.4", - "dev": true + "dev": true, + "requires": {} }, "rollup-plugin-postcss": { "version": "4.0.2", @@ -27333,6 +27583,17 @@ "version": "2.0.0", "dev": true }, + "set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "requires": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + } + }, "set-value": { "version": "4.1.0", "requires": { @@ -27364,11 +27625,6 @@ "version": "3.0.0", "dev": true }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" - }, "side-channel": { "version": "1.0.4", "requires": { @@ -27545,6 +27801,11 @@ "streamsearch": { "version": "1.1.0" }, + "strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==" + }, "string_decoder": { "version": "1.1.1", "requires": { @@ -27625,7 +27886,8 @@ }, "style-loader": { "version": "3.3.1", - "dev": true + "dev": true, + "requires": {} }, "styled-components": { "version": "5.3.6", @@ -27654,7 +27916,8 @@ } }, "styled-jsx": { - "version": "5.0.7" + "version": "5.0.7", + "requires": {} }, "stylehacks": { "version": "5.1.1", @@ -28243,6 +28506,30 @@ "punycode": "^2.1.0" } }, + "url": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.3.tgz", + "integrity": "sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==", + "requires": { + "punycode": "^1.4.1", + "qs": "^6.11.2" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "requires": { + "side-channel": "^1.0.4" + } + } + } + }, "url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -28260,7 +28547,8 @@ } }, "use-sync-external-store": { - "version": "1.2.0" + "version": "1.2.0", + "requires": {} }, "utf8-byte-length": { "version": "1.0.4", @@ -28421,7 +28709,8 @@ }, "acorn-import-assertions": { "version": "1.8.0", - "dev": true + "dev": true, + "requires": {} }, "schema-utils": { "version": "3.1.1", @@ -28590,7 +28879,9 @@ } }, "yargs-parser": { - "version": "21.1.1" + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" }, "yauzl": { "version": "2.10.0", diff --git a/packages/bruno-app/package.json b/packages/bruno-app/package.json index c2bdc494c..d5ba0b1aa 100644 --- a/packages/bruno-app/package.json +++ b/packages/bruno-app/package.json @@ -24,6 +24,7 @@ "classnames": "^2.3.1", "codemirror": "^5.65.2", "codemirror-graphql": "^1.2.5", + "cookie": "^0.6.0", "escape-html": "^1.0.3", "file-dialog": "^0.0.8", "file-saver": "^2.0.5", @@ -36,17 +37,18 @@ "httpsnippet": "^3.0.1", "idb": "^7.0.0", "immer": "^9.0.15", + "jsesc": "^3.0.2", "know-your-http-well": "^0.5.0", "lodash": "^4.17.21", "markdown-it": "^13.0.2", "mousetrap": "^1.6.5", "nanoid": "3.3.4", "next": "12.3.3", - "parse-curl": "^0.2.6", "path": "^0.12.7", "platform": "^1.3.6", "posthog-node": "^2.1.0", "qs": "^6.11.0", + "query-string": "^7.0.1", "react": "18.2.0", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", @@ -59,7 +61,9 @@ "sass": "^1.46.0", "styled-components": "^5.3.3", "tailwindcss": "^2.2.19", + "url": "^0.11.3", "xml-formatter": "^3.5.0", + "yargs-parser": "^21.1.1", "yup": "^0.32.11" }, "devDependencies": { diff --git a/packages/bruno-app/src/utils/common/codemirror.js b/packages/bruno-app/src/utils/common/codemirror.js index 6074dbdcf..4be4dc473 100644 --- a/packages/bruno-app/src/utils/common/codemirror.js +++ b/packages/bruno-app/src/utils/common/codemirror.js @@ -1,5 +1,4 @@ import get from 'lodash/get'; -import isString from 'lodash/isString'; let CodeMirror; const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true; diff --git a/packages/bruno-app/src/utils/common/index.js b/packages/bruno-app/src/utils/common/index.js index 992ec233e..be6982436 100644 --- a/packages/bruno-app/src/utils/common/index.js +++ b/packages/bruno-app/src/utils/common/index.js @@ -94,3 +94,15 @@ export const getContentType = (headers) => { return ''; }; + +export const startsWith = (str, search) => { + if (!str || !str.length || typeof str !== 'string') { + return false; + } + + if (!search || !search.length || typeof search !== 'string') { + return false; + } + + return str.substr(0, search.length) === search; +}; diff --git a/packages/bruno-app/src/utils/common/index.spec.js b/packages/bruno-app/src/utils/common/index.spec.js index 6d52ed1aa..3484fac9c 100644 --- a/packages/bruno-app/src/utils/common/index.spec.js +++ b/packages/bruno-app/src/utils/common/index.spec.js @@ -1,6 +1,6 @@ const { describe, it, expect } = require('@jest/globals'); -import { normalizeFileName } from './index'; +import { normalizeFileName, startsWith } from './index'; describe('common utils', () => { describe('normalizeFileName', () => { @@ -16,4 +16,37 @@ describe('common utils', () => { expect(normalizeFileName('foo\\bar\\')).toBe('foo-bar-'); }); }); + + describe('startsWith', () => { + it('should return false if str is not a string', () => { + expect(startsWith(null, 'foo')).toBe(false); + expect(startsWith(undefined, 'foo')).toBe(false); + expect(startsWith(123, 'foo')).toBe(false); + expect(startsWith({}, 'foo')).toBe(false); + expect(startsWith([], 'foo')).toBe(false); + }); + + it('should return false if search is not a string', () => { + expect(startsWith('foo', null)).toBe(false); + expect(startsWith('foo', undefined)).toBe(false); + expect(startsWith('foo', 123)).toBe(false); + expect(startsWith('foo', {})).toBe(false); + expect(startsWith('foo', [])).toBe(false); + }); + + it('should return false if str does not start with search', () => { + expect(startsWith('foo', 'bar')).toBe(false); + expect(startsWith('foo', 'baz')).toBe(false); + expect(startsWith('foo', 'bar')).toBe(false); + expect(startsWith('foo', 'baz')).toBe(false); + expect(startsWith('foo', 'bar')).toBe(false); + expect(startsWith('foo', 'baz')).toBe(false); + }); + + it('should return true if str starts with search', () => { + expect(startsWith('foo', 'f')).toBe(true); + expect(startsWith('foo', 'fo')).toBe(true); + expect(startsWith('foo', 'foo')).toBe(true); + }); + }); }); diff --git a/packages/bruno-app/src/utils/curl/curl-to-json.js b/packages/bruno-app/src/utils/curl/curl-to-json.js new file mode 100644 index 000000000..8313e0a79 --- /dev/null +++ b/packages/bruno-app/src/utils/curl/curl-to-json.js @@ -0,0 +1,169 @@ +/** + * Copyright (c) 2014-2016 Nick Carneiro + * https://github.com/curlconverter/curlconverter + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import parseCurlCommand from './parse-curl'; +import * as querystring from 'query-string'; +import * as jsesc from 'jsesc'; + +function getContentType(headers = {}) { + const contentType = Object.keys(headers).find((key) => key.toLowerCase() === 'content-type'); + + return contentType ? headers[contentType] : null; +} + +function repr(value, isKey) { + return isKey ? "'" + jsesc(value, { quotes: 'single' }) + "'" : value; +} + +function getQueries(request) { + const queries = {}; + for (const paramName in request.query) { + const rawValue = request.query[paramName]; + let paramValue; + if (Array.isArray(rawValue)) { + paramValue = rawValue.map(repr); + } else { + paramValue = repr(rawValue); + } + queries[repr(paramName)] = paramValue; + } + + return queries; +} + +function getDataString(request) { + if (typeof request.data === 'number') { + request.data = request.data.toString(); + } + + const contentType = getContentType(request.headers); + + if (contentType && contentType.includes('application/json')) { + return { data: request.data.toString() }; + } + + const parsedQueryString = querystring.parse(request.data, { sort: false }); + const keyCount = Object.keys(parsedQueryString).length; + const singleKeyOnly = keyCount === 1 && !parsedQueryString[Object.keys(parsedQueryString)[0]]; + const singularData = request.isDataBinary || singleKeyOnly; + if (singularData) { + const data = {}; + data[repr(request.data)] = ''; + return { data: data }; + } else { + return getMultipleDataString(request, parsedQueryString); + } +} + +function getMultipleDataString(request, parsedQueryString) { + const data = {}; + + for (const key in parsedQueryString) { + const value = parsedQueryString[key]; + if (Array.isArray(value)) { + data[repr(key)] = value; + } else { + data[repr(key)] = repr(value); + } + } + + return { data: data }; +} + +function getFilesString(request) { + const data = {}; + + data.files = {}; + data.data = {}; + + for (const multipartKey in request.multipartUploads) { + const multipartValue = request.multipartUploads[multipartKey]; + if (multipartValue.startsWith('@')) { + const fileName = multipartValue.slice(1); + data.files[repr(multipartKey)] = repr(fileName); + } else { + data.data[repr(multipartKey)] = repr(multipartValue); + } + } + + if (Object.keys(data.files).length === 0) { + delete data.files; + } + + if (Object.keys(data.data).length === 0) { + delete data.data; + } + + return data; +} + +const curlToJson = (curlCommand) => { + const request = parseCurlCommand(curlCommand); + + const requestJson = {}; + + // curl automatically prepends 'http' if the scheme is missing, but python fails and returns an error + // we tack it on here to mimic curl + if (!request.url.match(/https?:/)) { + request.url = 'http://' + request.url; + } + if (!request.urlWithoutQuery.match(/https?:/)) { + request.urlWithoutQuery = 'http://' + request.urlWithoutQuery; + } + + requestJson.url = request.urlWithoutQuery.replace(/\/$/, ''); + requestJson.raw_url = request.url; + requestJson.method = request.method; + + if (request.cookies) { + const cookies = {}; + for (const cookieName in request.cookies) { + cookies[repr(cookieName)] = repr(request.cookies[cookieName]); + } + + requestJson.cookies = cookies; + } + + if (request.headers) { + const headers = {}; + for (const headerName in request.headers) { + headers[repr(headerName)] = repr(request.headers[headerName]); + } + + requestJson.headers = headers; + } + + if (request.query) { + requestJson.queries = getQueries(request); + } + + if (typeof request.data === 'string' || typeof request.data === 'number') { + Object.assign(requestJson, getDataString(request)); + } else if (request.multipartUploads) { + Object.assign(requestJson, getFilesString(request)); + } + + if (request.insecure) { + requestJson.insecure = false; + } + + if (request.auth) { + const splitAuth = request.auth.split(':'); + const user = splitAuth[0] || ''; + const password = splitAuth[1] || ''; + + requestJson.auth = { + user: repr(user), + password: repr(password) + }; + } + + return Object.keys(requestJson).length ? requestJson : {}; +}; + +export default curlToJson; diff --git a/packages/bruno-app/src/utils/curl/curl-to-json.spec.js b/packages/bruno-app/src/utils/curl/curl-to-json.spec.js new file mode 100644 index 000000000..bf7d836df --- /dev/null +++ b/packages/bruno-app/src/utils/curl/curl-to-json.spec.js @@ -0,0 +1,62 @@ +const { describe, it, expect } = require('@jest/globals'); + +import curlToJson from './curl-to-json'; + +describe('curlToJson', () => { + it('should return a parse a simple curl command', () => { + const curlCommand = 'curl https://www.usebruno.com'; + const result = curlToJson(curlCommand); + + expect(result).toEqual({ + url: 'https://www.usebruno.com', + raw_url: 'https://www.usebruno.com', + method: 'get' + }); + }); + + it('should return a parse a curl command with headers', () => { + const curlCommand = `curl https://www.usebruno.com + -H 'Accept: application/json, text/plain, */*' + -H 'Accept-Language: en-US,en;q=0.9,hi;q=0.8' + `; + + const result = curlToJson(curlCommand); + + expect(result).toEqual({ + url: 'https://www.usebruno.com', + raw_url: 'https://www.usebruno.com', + method: 'get', + headers: { + Accept: 'application/json, text/plain, */*', + 'Accept-Language': 'en-US,en;q=0.9,hi;q=0.8' + } + }); + }); + + it('should return a parse a curl with a post body', () => { + const curlCommand = `curl 'https://www.usebruno.com' + -H 'Accept: application/json, text/plain, */*' + -H 'Accept-Language: en-US,en;q=0.9,hi;q=0.8' + -H 'Content-Type: application/json;charset=utf-8' + -H 'Origin: https://www.usebruno.com' + -H 'Referer: https://www.usebruno.com/' + --data-raw '{"email":"test@usebruno.com","password":"test"}' + `; + + const result = curlToJson(curlCommand); + + expect(result).toEqual({ + url: '%27https://www.usebruno.com%27', + raw_url: "'https://www.usebruno.com'", + method: 'post', + headers: { + Accept: 'application/json, text/plain, */*', + 'Accept-Language': 'en-US,en;q=0.9,hi;q=0.8', + 'Content-Type': 'application/json;charset=utf-8', + Origin: 'https://www.usebruno.com', + Referer: 'https://www.usebruno.com/' + }, + data: '{"email":"test@usebruno.com","password":"test"}' + }); + }); +}); diff --git a/packages/bruno-app/src/utils/curl/index.js b/packages/bruno-app/src/utils/curl/index.js index 30080e467..ecaf582c7 100644 --- a/packages/bruno-app/src/utils/curl/index.js +++ b/packages/bruno-app/src/utils/curl/index.js @@ -1,18 +1,29 @@ -import * as parse from 'parse-curl'; -import { BrunoError } from 'utils/common/error'; -import { parseQueryParams } from 'utils/url'; +import { forOwn } from 'lodash'; +import { safeStringifyJSON } from 'utils/common'; +import curlToJson from './curl-to-json'; -export const getRequestFromCurlCommand = (command) => { +export const getRequestFromCurlCommand = (curlCommand) => { const parseFormData = (parsedBody) => { - parseQueryParams(parsedBody); - }; - try { - const request = parse(command); - const parsedHeader = request?.header; - const headers = - parsedHeader && Object.keys(parsedHeader).map((key) => ({ name: key, value: parsedHeader[key], enabled: true })); + const formData = []; + forOwn(parsedBody, (value, key) => { + formData.push({ name: key, value, enabled: true }); + }); - const contentType = headers?.find((h) => h.name.toLowerCase() === 'content-type'); + return formData; + }; + + try { + if (!curlCommand || typeof curlCommand !== 'string' || curlCommand.length === 0) { + return null; + } + + const request = curlToJson(curlCommand); + const parsedHeaders = request?.headers; + const headers = + parsedHeaders && + Object.keys(parsedHeaders).map((key) => ({ name: key, value: parsedHeaders[key], enabled: true })); + + const contentType = headers?.find((h) => h.name.toLowerCase() === 'content-type')?.value; const body = { mode: 'none', json: null, @@ -22,30 +33,25 @@ export const getRequestFromCurlCommand = (command) => { multipartForm: null, formUrlEncoded: null }; - const parsedBody = request?.body; - if (parsedBody && contentType) { - switch (contentType.value.toLowerCase()) { - case 'application/json': - body.mode = 'json'; - body.json = parsedBody; - break; - case 'text/xml': - body.mode = 'xml'; - body.xml = parsedBody; - break; - case 'application/x-www-form-urlencoded': - body.mode = 'formUrlEncoded'; - body.formUrlEncoded = parseFormData(parsedBody); - break; - case 'multipart/form-data': - body.mode = 'multipartForm'; - body.multipartForm = parsedBody; - break; - case 'text/plain': - default: - body.mode = 'text'; - body.text = parsedBody; - break; + const parsedBody = request.data; + if (parsedBody && contentType && typeof contentType === 'string') { + if (contentType.includes('application/json')) { + body.mode = 'json'; + body.json = safeStringifyJSON(parsedBody); + } else if (contentType.includes('text/xml')) { + body.mode = 'xml'; + body.xml = parsedBody; + } else if (contentType.includes('application/x-www-form-urlencoded')) { + body.mode = 'formUrlEncoded'; + console.log(parsedBody); + console.log(parseFormData(parsedBody)); + body.formUrlEncoded = parseFormData(parsedBody); + } else if (contentType.includes('multipart/form-data')) { + body.mode = 'multipartForm'; + body.multipartForm = parsedBody; + } else if (contentType.includes('text/plain')) { + body.mode = 'text'; + body.text = parsedBody; } } return { @@ -55,6 +61,7 @@ export const getRequestFromCurlCommand = (command) => { headers: headers }; } catch (error) { + console.error(error); return null; } }; diff --git a/packages/bruno-app/src/utils/curl/parse-curl.js b/packages/bruno-app/src/utils/curl/parse-curl.js new file mode 100644 index 000000000..b7f6572f7 --- /dev/null +++ b/packages/bruno-app/src/utils/curl/parse-curl.js @@ -0,0 +1,238 @@ +/** + * Copyright (c) 2014-2016 Nick Carneiro + * https://github.com/curlconverter/curlconverter + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import * as cookie from 'cookie'; +import * as URL from 'url'; +import * as querystring from 'query-string'; +import yargs from 'yargs-parser'; + +const parseCurlCommand = (curlCommand) => { + // Remove newlines (and from continuations) + curlCommand = curlCommand.replace(/\\\r|\\\n/g, ''); + + // Remove extra whitespace + curlCommand = curlCommand.replace(/\s+/g, ' '); + + // yargs parses -XPOST as separate arguments. just prescreen for it. + curlCommand = curlCommand.replace(/ -XPOST/, ' -X POST'); + curlCommand = curlCommand.replace(/ -XGET/, ' -X GET'); + curlCommand = curlCommand.replace(/ -XPUT/, ' -X PUT'); + curlCommand = curlCommand.replace(/ -XPATCH/, ' -X PATCH'); + curlCommand = curlCommand.replace(/ -XDELETE/, ' -X DELETE'); + curlCommand = curlCommand.replace(/ -XOPTIONS/, ' -X OPTIONS'); + // Safari adds `-Xnull` if is unable to determine the request type, it can be ignored + curlCommand = curlCommand.replace(/ -Xnull/, ' '); + curlCommand = curlCommand.trim(); + + const parsedArguments = yargs(curlCommand, { + boolean: ['I', 'head', 'compressed', 'L', 'k', 'silent', 's'], + alias: { + H: 'header', + A: 'user-agent' + } + }); + + let cookieString; + let cookies; + let url = parsedArguments._[1] || ''; + + // remove surrounding quotes if present + if (url && url.length) { + url = url.replace(/^['"]|['"]$/g, ''); + } + + // if url argument wasn't where we expected it, try to find it in the other arguments + if (!url) { + for (const argName in parsedArguments) { + if (typeof parsedArguments[argName] === 'string') { + if (parsedArguments[argName].indexOf('http') === 0 || parsedArguments[argName].indexOf('www.') === 0) { + url = parsedArguments[argName]; + } + } + } + } + + let headers; + + if (parsedArguments.header) { + if (!headers) { + headers = {}; + } + if (!Array.isArray(parsedArguments.header)) { + parsedArguments.header = [parsedArguments.header]; + } + parsedArguments.header.forEach((header) => { + if (header.indexOf('Cookie') !== -1) { + cookieString = header; + } else { + const components = header.split(/:(.*)/); + if (components[1]) { + headers[components[0]] = components[1].trim(); + } + } + }); + } + + if (parsedArguments['user-agent']) { + if (!headers) { + headers = {}; + } + headers['User-Agent'] = parsedArguments['user-agent']; + } + + if (parsedArguments.b) { + cookieString = parsedArguments.b; + } + if (parsedArguments.cookie) { + cookieString = parsedArguments.cookie; + } + let multipartUploads; + if (parsedArguments.F) { + multipartUploads = {}; + if (!Array.isArray(parsedArguments.F)) { + parsedArguments.F = [parsedArguments.F]; + } + parsedArguments.F.forEach((multipartArgument) => { + // input looks like key=value. value could be json or a file path prepended with an @ + const splitArguments = multipartArgument.split('=', 2); + const key = splitArguments[0]; + const value = splitArguments[1]; + multipartUploads[key] = value; + }); + } + if (cookieString) { + const cookieParseOptions = { + decode: function (s) { + return s; + } + }; + // separate out cookie headers into separate data structure + // note: cookie is case insensitive + cookies = cookie.parse(cookieString.replace(/^Cookie: /gi, ''), cookieParseOptions); + } + let method; + if (parsedArguments.X === 'POST') { + method = 'post'; + } else if (parsedArguments.X === 'PUT' || parsedArguments.T) { + method = 'put'; + } else if (parsedArguments.X === 'PATCH') { + method = 'patch'; + } else if (parsedArguments.X === 'DELETE') { + method = 'delete'; + } else if (parsedArguments.X === 'OPTIONS') { + method = 'options'; + } else if ( + (parsedArguments.d || + parsedArguments.data || + parsedArguments['data-ascii'] || + parsedArguments['data-binary'] || + parsedArguments['data-raw'] || + parsedArguments.F || + parsedArguments.form) && + !(parsedArguments.G || parsedArguments.get) + ) { + method = 'post'; + } else if (parsedArguments.I || parsedArguments.head) { + method = 'head'; + } else { + method = 'get'; + } + + const compressed = !!parsedArguments.compressed; + const urlObject = URL.parse(url || ''); + + // if GET request with data, convert data to query string + // NB: the -G flag does not change the http verb. It just moves the data into the url. + if (parsedArguments.G || parsedArguments.get) { + urlObject.query = urlObject.query ? urlObject.query : ''; + const option = 'd' in parsedArguments ? 'd' : 'data' in parsedArguments ? 'data' : null; + if (option) { + let urlQueryString = ''; + + if (url.indexOf('?') < 0) { + url += '?'; + } else { + urlQueryString += '&'; + } + + if (typeof parsedArguments[option] === 'object') { + urlQueryString += parsedArguments[option].join('&'); + } else { + urlQueryString += parsedArguments[option]; + } + urlObject.query += urlQueryString; + url += urlQueryString; + delete parsedArguments[option]; + } + } + if (urlObject.query && urlObject.query.endsWith('&')) { + urlObject.query = urlObject.query.slice(0, -1); + } + const query = querystring.parse(urlObject.query, { sort: false }); + for (const param in query) { + if (query[param] === null) { + query[param] = ''; + } + } + + urlObject.search = null; // Clean out the search/query portion. + const request = { + url: url, + urlWithoutQuery: URL.format(urlObject) + }; + if (compressed) { + request.compressed = true; + } + + if (Object.keys(query).length > 0) { + request.query = query; + } + if (headers) { + request.headers = headers; + } + request.method = method; + + if (cookies) { + request.cookies = cookies; + request.cookieString = cookieString.replace('Cookie: ', ''); + } + if (multipartUploads) { + request.multipartUploads = multipartUploads; + } + if (parsedArguments.data) { + request.data = parsedArguments.data; + } else if (parsedArguments['data-binary']) { + request.data = parsedArguments['data-binary']; + request.isDataBinary = true; + } else if (parsedArguments.d) { + request.data = parsedArguments.d; + } else if (parsedArguments['data-ascii']) { + request.data = parsedArguments['data-ascii']; + } else if (parsedArguments['data-raw']) { + request.data = parsedArguments['data-raw']; + request.isDataRaw = true; + } + + if (parsedArguments.u) { + request.auth = parsedArguments.u; + } + if (parsedArguments.user) { + request.auth = parsedArguments.user; + } + if (Array.isArray(request.data)) { + request.dataArray = request.data; + request.data = request.data.join('&'); + } + + if (parsedArguments.k || parsedArguments.insecure) { + request.insecure = true; + } + return request; +}; + +export default parseCurlCommand; From 50d8577298760b28e1f866164970ed85ae1a4aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAnior=20Sbrissa?= Date: Wed, 8 Nov 2023 14:23:19 -0300 Subject: [PATCH 32/53] docs: add readme pt br translation --- docs/readme/readme_pt_br.md | 121 ++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 docs/readme/readme_pt_br.md diff --git a/docs/readme/readme_pt_br.md b/docs/readme/readme_pt_br.md new file mode 100644 index 000000000..edc47d5e0 --- /dev/null +++ b/docs/readme/readme_pt_br.md @@ -0,0 +1,121 @@ +
+ + +### 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)

+ +### 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)

+ +### Colaboração via Git 👩‍💻🧑‍💻 + +Ou qualquer sistema de controle de versão de sua escolha. + +![bruno](../../assets/images/version-control.png)

+ +### 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 + + + +### Mantenha Contato 🌐 + +[𝕏 (Twitter)](https://twitter.com/use_bruno)
+[Website](https://www.usebruno.com)
+[Discord](https://discord.com/invite/KgcZUncpjq)
+[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) From 159f39dd18637bb697f9dee949537f4007073785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAnior=20Sbrissa?= Date: Wed, 8 Nov 2023 17:22:26 -0300 Subject: [PATCH 33/53] docs: add contributing pt br translation --- docs/contributing/contributing_pt_br.md | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 docs/contributing/contributing_pt_br.md diff --git a/docs/contributing/contributing_pt_br.md b/docs/contributing/contributing_pt_br.md new file mode 100644 index 000000000..46d20f181 --- /dev/null +++ b/docs/contributing/contributing_pt_br.md @@ -0,0 +1,87 @@ +## 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: + +Libraries we use + +- 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 aplicativo 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 From 35a4d46dc51031f5c250279f5a4cc6be786e2668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAnior=20Sbrissa?= Date: Wed, 8 Nov 2023 17:35:49 -0300 Subject: [PATCH 34/53] docs: add publishing pt br translation --- docs/publishing/publishing_pt_br.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/publishing/publishing_pt_br.md diff --git a/docs/publishing/publishing_pt_br.md b/docs/publishing/publishing_pt_br.md new file mode 100644 index 000000000..13d414a40 --- /dev/null +++ b/docs/publishing/publishing_pt_br.md @@ -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, crie uma solicitação 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 From 86553464cc6bf2a39a234eaaa695c5c2de698e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Sch=C3=B6nefeldt?= Date: Wed, 8 Nov 2023 22:19:09 +0100 Subject: [PATCH 35/53] https://github.com/usebruno/bruno/discussions/865: Added ahint to the stackoverflow tag to teh readme --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 96a9d7c88..d6c4db467 100644 --- a/readme.md +++ b/readme.md @@ -65,6 +65,7 @@ Or any version control system of your choice - [Our Long Term Vision](https://github.com/usebruno/bruno/discussions/269) - [Roadmap](https://github.com/usebruno/bruno/discussions/384) - [Documentation](https://docs.usebruno.com) +- [stackoverflow](https://stackoverflow.com/questions/tagged/bruno) - [Website](https://www.usebruno.com) - [Pricing](https://www.usebruno.com/pricing) - [Download](https://www.usebruno.com/downloads) From 07a9d4645f6b18a6b13717296b032c0c1f967299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAnior=20Sbrissa?= Date: Wed, 8 Nov 2023 21:57:43 -0300 Subject: [PATCH 36/53] docs: review pt br translation and add reference links --- contributing.md | 2 +- docs/contributing/contributing_pt_br.md | 4 +--- docs/publishing/publishing_pt_br.md | 2 +- publishing.md | 2 ++ readme.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contributing.md b/contributing.md index 0d6efdffa..5c0b8bb2f 100644 --- a/contributing.md +++ b/contributing.md @@ -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 !! diff --git a/docs/contributing/contributing_pt_br.md b/docs/contributing/contributing_pt_br.md index 46d20f181..7f7baabb3 100644 --- a/docs/contributing/contributing_pt_br.md +++ b/docs/contributing/contributing_pt_br.md @@ -8,8 +8,6 @@ O Bruno é construído usando Next.js e React. Também usamos o Electron para di Bibliotecas que utilizamos: -Libraries we use - - CSS - Tailwind - Editor de Código - Codemirror - Gerenciador de Estado - Redux @@ -25,7 +23,7 @@ Você precisará do [Node v18.x (ou da versão LTS mais recente)](https://nodejs ## Desenvolvimento -Bruno está sendo desenvolvido como um aplicativo de desktop. Você precisa carregar o aplicativo executando o aplicativo Next.js em um terminal e, em seguida, executar o aplicativo Electron em outro terminal. +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 diff --git a/docs/publishing/publishing_pt_br.md b/docs/publishing/publishing_pt_br.md index 13d414a40..b3d580ee0 100644 --- a/docs/publishing/publishing_pt_br.md +++ b/docs/publishing/publishing_pt_br.md @@ -1,5 +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, crie uma solicitação através de uma issue no GitHub. +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 diff --git a/publishing.md b/publishing.md index 430baa94e..0d23e1f36 100644 --- a/publishing.md +++ b/publishing.md @@ -1,3 +1,5 @@ +**English** | [Português (BR)](docs/publishing/publishing_pt_br.md) + ### 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. diff --git a/readme.md b/readme.md index 96a9d7c88..0e3a13bd7 100644 --- a/readme.md +++ b/readme.md @@ -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) +**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. From aab591cb126e8bdaabab3216149da1e9d7eae664 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Thu, 9 Nov 2023 13:20:07 +0530 Subject: [PATCH 37/53] feat(#338): switch to curl mode if a curl cmd is pasted in new request modal --- .../Sidebar/NewRequest/StyledWrapper.js | 4 +++ .../components/Sidebar/NewRequest/index.js | 27 ++++++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/NewRequest/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/NewRequest/StyledWrapper.js index 72d1d8a90..9845bd2ef 100644 --- a/packages/bruno-app/src/components/Sidebar/NewRequest/StyledWrapper.js +++ b/packages/bruno-app/src/components/Sidebar/NewRequest/StyledWrapper.js @@ -35,6 +35,10 @@ const StyledWrapper = styled.div` } } } + + textarea.curl-command { + min-height: 150px; + } `; export default StyledWrapper; diff --git a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js index 43d91430b..377e6bb72 100644 --- a/packages/bruno-app/src/components/Sidebar/NewRequest/index.js +++ b/packages/bruno-app/src/components/Sidebar/NewRequest/index.js @@ -1,4 +1,4 @@ -import React, { useRef, useEffect } from 'react'; +import React, { useRef, useEffect, useCallback } from 'react'; import { useFormik } from 'formik'; import * as Yup from 'yup'; import toast from 'react-hot-toast'; @@ -115,6 +115,25 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { 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 ( @@ -174,7 +193,7 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { Name { spellCheck="false" onChange={formik.handleChange} value={formik.values.requestUrl || ''} + onPaste={handlePaste} /> @@ -232,8 +252,7 @@ const NewRequest = ({ collection, item, isEphemeral, onClose }) => { From a0196a01b3b04041befc41d277b7e65710b66b8b Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Thu, 9 Nov 2023 13:39:24 +0530 Subject: [PATCH 38/53] chore: bumped release version --- packages/bruno-app/src/components/Sidebar/index.js | 2 +- packages/bruno-electron/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/index.js b/packages/bruno-app/src/components/Sidebar/index.js index 0e6153f9d..670d28d23 100644 --- a/packages/bruno-app/src/components/Sidebar/index.js +++ b/packages/bruno-app/src/components/Sidebar/index.js @@ -105,7 +105,7 @@ const Sidebar = () => { Star -
v1.1.0
+
v1.1.1
diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json index 57dff832f..d0c562a70 100644 --- a/packages/bruno-electron/package.json +++ b/packages/bruno-electron/package.json @@ -1,5 +1,5 @@ { - "version": "v1.1.0", + "version": "v1.1.1", "name": "bruno", "description": "Opensource API Client for Exploring and Testing APIs", "homepage": "https://www.usebruno.com", From 3e137ac6b4fe59b1b85f6a85a55b226a9e879c02 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Thu, 9 Nov 2023 13:47:33 +0530 Subject: [PATCH 39/53] fix: fixed failing test --- packages/bruno-app/src/utils/curl/curl-to-json.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bruno-app/src/utils/curl/curl-to-json.spec.js b/packages/bruno-app/src/utils/curl/curl-to-json.spec.js index bf7d836df..c8f7d1c03 100644 --- a/packages/bruno-app/src/utils/curl/curl-to-json.spec.js +++ b/packages/bruno-app/src/utils/curl/curl-to-json.spec.js @@ -46,8 +46,8 @@ describe('curlToJson', () => { const result = curlToJson(curlCommand); expect(result).toEqual({ - url: '%27https://www.usebruno.com%27', - raw_url: "'https://www.usebruno.com'", + url: 'https://www.usebruno.com', + raw_url: 'https://www.usebruno.com', method: 'post', headers: { Accept: 'application/json, text/plain, */*', From ba761098be216e802399e8888974377fbe6bbe4b Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Thu, 9 Nov 2023 16:12:33 +0530 Subject: [PATCH 40/53] chore(#827): bumped bruno cli version to 1.1.0 --- packages/bruno-cli/changelog.md | 4 ++++ packages/bruno-cli/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/bruno-cli/changelog.md b/packages/bruno-cli/changelog.md index adfa14c1a..1d6729309 100644 --- a/packages/bruno-cli/changelog.md +++ b/packages/bruno-cli/changelog.md @@ -1,5 +1,9 @@ # Changelog +## 1.1.0 + +- Upgraded axios to 1.5.1 + ## 1.0.0 - Announcing Stable Release diff --git a/packages/bruno-cli/package.json b/packages/bruno-cli/package.json index 88c6eb91d..d2aa710f4 100644 --- a/packages/bruno-cli/package.json +++ b/packages/bruno-cli/package.json @@ -1,6 +1,6 @@ { "name": "@usebruno/cli", - "version": "1.0.0", + "version": "1.1.0", "license": "MIT", "main": "src/index.js", "bin": { From 043b80171ef088959f041433c9783abcd192b738 Mon Sep 17 00:00:00 2001 From: Adarsh Lilha Date: Fri, 10 Nov 2023 03:27:17 +0530 Subject: [PATCH 41/53] fix headers in code generator --- .../GenerateCodeItem/CodeView/index.js | 3 ++- .../bruno-app/src/utils/codegenerator/har.js | 26 +++++++------------ 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/index.js index 64c229ae4..18734b288 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/index.js @@ -9,10 +9,11 @@ const CodeView = ({ language, item }) => { const { storedTheme } = useTheme(); const preferences = useSelector((state) => state.app.preferences); const { target, client, language: lang } = language; + const headers = item.draft ? get(item, 'draft.request.headers') : get(item, 'request.headers'); let snippet = ''; try { - snippet = new HTTPSnippet(buildHarRequest(item.request)).convert(target, client); + snippet = new HTTPSnippet(buildHarRequest({ request: item.request, headers })).convert(target, client); } catch (e) { console.error(e); snippet = 'Error generating code snippet'; diff --git a/packages/bruno-app/src/utils/codegenerator/har.js b/packages/bruno-app/src/utils/codegenerator/har.js index b48fbc3c7..e0e2b2a6c 100644 --- a/packages/bruno-app/src/utils/codegenerator/har.js +++ b/packages/bruno-app/src/utils/codegenerator/har.js @@ -9,25 +9,17 @@ const createContentType = (mode) => { case 'multipartForm': return 'multipart/form-data'; default: - return 'application/json'; + return ''; } }; -const createHeaders = (headers, mode) => { - const contentType = createContentType(mode); - const headersArray = headers +const createHeaders = (headers) => { + return headers .filter((header) => header.enabled) - .map((header) => { - return { - name: header.name, - value: header.value - }; - }); - const headerNames = headersArray.map((header) => header.name); - if (!headerNames.includes('Content-Type')) { - return [...headersArray, { name: 'Content-Type', value: contentType }]; - } - return headersArray; + .map((header) => ({ + name: header.name, + value: header.value + })); }; const createQuery = (queryParams = []) => { @@ -56,13 +48,13 @@ const createPostData = (body) => { } }; -export const buildHarRequest = (request) => { +export const buildHarRequest = ({ request, headers }) => { return { method: request.method, url: request.url, httpVersion: 'HTTP/1.1', cookies: [], - headers: createHeaders(request.headers, request.body.mode), + headers: createHeaders(headers), queryString: createQuery(request.params), postData: createPostData(request.body), headersSize: 0, From e1a74d0652ecb6b5828683f318f180ecebfb6ff1 Mon Sep 17 00:00:00 2001 From: Mirko Golze Date: Fri, 10 Nov 2023 21:20:30 +0100 Subject: [PATCH 42/53] #937, #921 improve evaluation of proxy configuration, allow empty proxy port --- .../CollectionSettings/ProxySettings/index.js | 14 ++++----- .../Preferences/ProxySettings/index.js | 10 +++---- .../src/runner/run-single-request.js | 7 +++-- .../bruno-electron/src/ipc/network/index.js | 30 +++++-------------- 4 files changed, 21 insertions(+), 40 deletions(-) diff --git a/packages/bruno-app/src/components/CollectionSettings/ProxySettings/index.js b/packages/bruno-app/src/components/CollectionSettings/ProxySettings/index.js index 2ed25b1e5..c8ccb103e 100644 --- a/packages/bruno-app/src/components/CollectionSettings/ProxySettings/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/ProxySettings/index.js @@ -11,22 +11,20 @@ const ProxySettings = ({ proxyConfig, onUpdate }) => { protocol: Yup.string().oneOf(['http', 'https', 'socks4', 'socks5']), hostname: Yup.string() .when('enabled', { - is: true, + is: 'true', then: (hostname) => hostname.required('Specify the hostname for your proxy.'), otherwise: (hostname) => hostname.nullable() }) .max(1024), port: Yup.number() - .when('enabled', { - is: true, - then: (port) => port.required('Specify port between 1 and 65535').typeError('Specify port between 1 and 65535'), - otherwise: (port) => port.nullable().transform((_, val) => (val ? Number(val) : null)) - }) .min(1) - .max(65535), + .max(65535) + .typeError('Specify port between 1 and 65535') + .nullable() + .transform((_, val) => (val ? Number(val) : null)), auth: Yup.object() .when('enabled', { - is: true, + is: 'true', then: Yup.object({ enabled: Yup.boolean(), username: Yup.string() diff --git a/packages/bruno-app/src/components/Preferences/ProxySettings/index.js b/packages/bruno-app/src/components/Preferences/ProxySettings/index.js index 6b3fb7877..788f79270 100644 --- a/packages/bruno-app/src/components/Preferences/ProxySettings/index.js +++ b/packages/bruno-app/src/components/Preferences/ProxySettings/index.js @@ -22,13 +22,11 @@ const ProxySettings = ({ close }) => { }) .max(1024), port: Yup.number() - .when('enabled', { - is: true, - then: (port) => port.required('Specify port between 1 and 65535').typeError('Specify port between 1 and 65535'), - otherwise: (port) => port.nullable().transform((_, val) => (val ? Number(val) : null)) - }) .min(1) - .max(65535), + .max(65535) + .typeError('Specify port between 1 and 65535') + .nullable() + .transform((_, val) => (val ? Number(val) : null)), auth: Yup.object() .when('enabled', { is: true, diff --git a/packages/bruno-cli/src/runner/run-single-request.js b/packages/bruno-cli/src/runner/run-single-request.js index e047969f6..32122f744 100644 --- a/packages/bruno-cli/src/runner/run-single-request.js +++ b/packages/bruno-cli/src/runner/run-single-request.js @@ -3,7 +3,7 @@ const qs = require('qs'); const chalk = require('chalk'); const decomment = require('decomment'); const fs = require('fs'); -const { forOwn, each, extend, get, compact } = require('lodash'); +const { forOwn, isUndefined, isNull, each, extend, get, compact } = require('lodash'); const FormData = require('form-data'); const prepareRequest = require('./prepare-request'); const interpolateVars = require('./interpolate-vars'); @@ -136,14 +136,15 @@ const runSingleRequest = async function ( const proxyAuthEnabled = get(brunoConfig, 'proxy.auth.enabled', false); const socksEnabled = proxyProtocol.includes('socks'); + let uriPort = isUndefined(proxyPort) || isNull(proxyPort) ? '' : `:${proxyPort}`; let proxyUri; if (proxyAuthEnabled) { const proxyAuthUsername = interpolateString(get(brunoConfig, 'proxy.auth.username'), interpolationOptions); const proxyAuthPassword = interpolateString(get(brunoConfig, 'proxy.auth.password'), interpolationOptions); - proxyUri = `${proxyProtocol}://${proxyAuthUsername}:${proxyAuthPassword}@${proxyHostname}:${proxyPort}`; + proxyUri = `${proxyProtocol}://${proxyAuthUsername}:${proxyAuthPassword}@${proxyHostname}${uriPort}`; } else { - proxyUri = `${proxyProtocol}://${proxyHostname}:${proxyPort}`; + proxyUri = `${proxyProtocol}://${proxyHostname}${uriPort}`; } if (socksEnabled) { diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 7e4b7ee2a..9419d4554 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -6,11 +6,10 @@ const axios = require('axios'); const path = require('path'); const decomment = require('decomment'); const Mustache = require('mustache'); -const FormData = require('form-data'); const contentDispositionParser = require('content-disposition'); const mime = require('mime-types'); const { ipcMain } = require('electron'); -const { forOwn, extend, each, get, compact } = require('lodash'); +const { isEmpty, isUndefined, isNull, each, get, compact } = require('lodash'); const { VarsRuntime, AssertRuntime, ScriptRuntime, TestRuntime } = require('@usebruno/js'); const prepareRequest = require('./prepare-request'); const prepareGqlIntrospectionRequest = require('./prepare-gql-introspection-request'); @@ -72,22 +71,6 @@ const getEnvVars = (environment = {}) => { }; }; -const getSize = (data) => { - if (!data) { - return 0; - } - - if (typeof data === 'string') { - return Buffer.byteLength(data, 'utf8'); - } - - if (typeof data === 'object') { - return Buffer.byteLength(safeStringifyJSON(data), 'utf8'); - } - - return 0; -}; - const configureRequest = async ( collectionUid, request, @@ -143,7 +126,7 @@ const configureRequest = async ( // proxy configuration let proxyConfig = get(brunoConfig, 'proxy', {}); - let proxyEnabled = get(proxyConfig, 'enabled', false); + let proxyEnabled = isEmpty(proxyConfig) ? 'global' : get(proxyConfig, 'enabled', false); if (proxyEnabled === 'global') { proxyConfig = preferencesUtil.getGlobalProxyConfig(); proxyEnabled = get(proxyConfig, 'enabled', false); @@ -156,14 +139,15 @@ const configureRequest = async ( const proxyAuthEnabled = get(proxyConfig, 'auth.enabled', false); const socksEnabled = proxyProtocol.includes('socks'); + let uriPort = isUndefined(proxyPort) || isNull(proxyPort) ? '' : `:${proxyPort}`; let proxyUri; if (proxyAuthEnabled) { const proxyAuthUsername = interpolateString(get(proxyConfig, 'auth.username'), interpolationOptions); const proxyAuthPassword = interpolateString(get(proxyConfig, 'auth.password'), interpolationOptions); - proxyUri = `${proxyProtocol}://${proxyAuthUsername}:${proxyAuthPassword}@${proxyHostname}:${proxyPort}`; + proxyUri = `${proxyProtocol}://${proxyAuthUsername}:${proxyAuthPassword}@${proxyHostname}${uriPort}`; } else { - proxyUri = `${proxyProtocol}://${proxyHostname}:${proxyPort}`; + proxyUri = `${proxyProtocol}://${proxyHostname}${uriPort}`; } if (socksEnabled) { @@ -203,10 +187,10 @@ const configureRequest = async ( const parseDataFromResponse = (response) => { const dataBuffer = Buffer.from(response.data); // Parse the charset from content type: https://stackoverflow.com/a/33192813 - const charset = /charset=([^()<>@,;:\"/[\]?.=\s]*)/i.exec(response.headers['Content-Type'] || ''); + const charset = /charset=([^()<>@,;:"/[\]?.=\s]*)/i.exec(response.headers['Content-Type'] || ''); // Overwrite the original data for backwards compatability let data = dataBuffer.toString(charset || 'utf-8'); - // Try to parse response to JSON, this can quitly fail + // Try to parse response to JSON, this can quietly fail try { data = JSON.parse(response.data); } catch {} From a0b2f80508686a278689ddec271d896df4d5e6f8 Mon Sep 17 00:00:00 2001 From: MrLuje Date: Sat, 11 Nov 2023 14:59:57 +0000 Subject: [PATCH 43/53] fix(openapi-import): spec security should be optional --- .../bruno-app/src/utils/importers/openapi-collection.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/bruno-app/src/utils/importers/openapi-collection.js b/packages/bruno-app/src/utils/importers/openapi-collection.js index 20a915bd4..d317fdfe4 100644 --- a/packages/bruno-app/src/utils/importers/openapi-collection.js +++ b/packages/bruno-app/src/utils/importers/openapi-collection.js @@ -267,12 +267,7 @@ const getDefaultUrl = (serverObject) => { }; const getSecurity = (apiSpec) => { - let supportedSchemes = apiSpec.security || []; - if (supportedSchemes.length === 0) { - return { - supported: [] - }; - } + let defaultSchemes = apiSpec.security || []; let securitySchemes = get(apiSpec, 'components.securitySchemes', {}); if (Object.keys(securitySchemes) === 0) { @@ -282,7 +277,7 @@ const getSecurity = (apiSpec) => { } return { - supported: supportedSchemes.map((scheme) => { + supported: defaultSchemes.map((scheme) => { var schemeName = Object.keys(scheme)[0]; return securitySchemes[schemeName]; }), From a5ce7e9c9ccb2c7a208e8d6c6207193b8a61ac21 Mon Sep 17 00:00:00 2001 From: Mirko Golze Date: Sun, 12 Nov 2023 21:41:25 +0100 Subject: [PATCH 44/53] #937, #921 improve evaluation of proxy configuration, allow empty proxy port --- packages/bruno-electron/src/ipc/network/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 9419d4554..d6afbe6f5 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -9,7 +9,7 @@ const Mustache = require('mustache'); const contentDispositionParser = require('content-disposition'); const mime = require('mime-types'); const { ipcMain } = require('electron'); -const { isEmpty, isUndefined, isNull, each, get, compact } = require('lodash'); +const { isUndefined, isNull, each, get, compact } = require('lodash'); const { VarsRuntime, AssertRuntime, ScriptRuntime, TestRuntime } = require('@usebruno/js'); const prepareRequest = require('./prepare-request'); const prepareGqlIntrospectionRequest = require('./prepare-gql-introspection-request'); @@ -126,7 +126,7 @@ const configureRequest = async ( // proxy configuration let proxyConfig = get(brunoConfig, 'proxy', {}); - let proxyEnabled = isEmpty(proxyConfig) ? 'global' : get(proxyConfig, 'enabled', false); + let proxyEnabled = get(proxyConfig, 'enabled', 'global'); if (proxyEnabled === 'global') { proxyConfig = preferencesUtil.getGlobalProxyConfig(); proxyEnabled = get(proxyConfig, 'enabled', false); From 500e3853a598fdcda47823428d08e68f5324551d Mon Sep 17 00:00:00 2001 From: Mika Andrianarijaona Date: Tue, 14 Nov 2023 16:33:27 +0100 Subject: [PATCH 45/53] Improve error message when an empty var is set Fixes #962 --- packages/bruno-js/src/bru.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bruno-js/src/bru.js b/packages/bruno-js/src/bru.js index 078aacc78..884b05a50 100644 --- a/packages/bruno-js/src/bru.js +++ b/packages/bruno-js/src/bru.js @@ -58,7 +58,7 @@ class Bru { setVar(key, value) { if (!key) { - throw new Error('Key is required'); + throw new Error('A variable with an empty name has been created but name is required.'); } if (envVariableNameRegex.test(key) === false) { From f39d9858776c1ae1cef90f07c4500fcd47e7374b Mon Sep 17 00:00:00 2001 From: Art051 <91856576+Art051@users.noreply.github.com> Date: Tue, 14 Nov 2023 18:28:35 +0000 Subject: [PATCH 46/53] Problem: Issue relates to OpenAPI specs which have self referencing components, resulting in infinite loops being made within resolveRefs. Solution: Added basic use of Set to store already-traversed items within the OpenAPI spec. Linked to personal use having import problems as well as this issue raised: https://github.com/usebruno/bruno/issues/939#issue-1986513743 Tested against the API Spec mentioned in the issue both as JSON and YAML. --- .../src/utils/importers/openapi-collection.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/bruno-app/src/utils/importers/openapi-collection.js b/packages/bruno-app/src/utils/importers/openapi-collection.js index d317fdfe4..febe7d61d 100644 --- a/packages/bruno-app/src/utils/importers/openapi-collection.js +++ b/packages/bruno-app/src/utils/importers/openapi-collection.js @@ -187,18 +187,24 @@ const transformOpenapiRequestItem = (request) => { return brunoRequestItem; }; -const resolveRefs = (spec, components = spec.components) => { +const resolveRefs = (spec, components = spec.components, visitedItems = new Set()) => { if (!spec || typeof spec !== 'object') { return spec; } if (Array.isArray(spec)) { - return spec.map((item) => resolveRefs(item, components)); + return spec.map((item) => resolveRefs(item, components, visitedItems)); } if ('$ref' in spec) { const refPath = spec.$ref; + if (visitedItems.has(refPath)) { + return spec; + } else { + visitedItems.add(refPath); + } + if (refPath.startsWith('#/components/')) { // Local reference within components const refKeys = refPath.replace('#/components/', '').split('/'); @@ -213,7 +219,7 @@ const resolveRefs = (spec, components = spec.components) => { } } - return resolveRefs(ref, components); + return resolveRefs(ref, components, visitedItems); } else { // Handle external references (not implemented here) // You would need to fetch the external reference and resolve it. @@ -223,7 +229,7 @@ const resolveRefs = (spec, components = spec.components) => { // Recursively resolve references in nested objects for (const prop in spec) { - spec[prop] = resolveRefs(spec[prop], components); + spec[prop] = resolveRefs(spec[prop], components, visitedItems); } return spec; From d3c854a9da224fa992a152e4c2e2ba309685da48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Sch=C3=B6nefeldt?= <1157580+Andreas-Schoenefeldt@users.noreply.github.com> Date: Wed, 15 Nov 2023 10:22:05 +0100 Subject: [PATCH 47/53] Update readme.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémy Benoist --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index d6c4db467..6485845e5 100644 --- a/readme.md +++ b/readme.md @@ -65,7 +65,7 @@ Or any version control system of your choice - [Our Long Term Vision](https://github.com/usebruno/bruno/discussions/269) - [Roadmap](https://github.com/usebruno/bruno/discussions/384) - [Documentation](https://docs.usebruno.com) -- [stackoverflow](https://stackoverflow.com/questions/tagged/bruno) +- [Stack Overflow](https://stackoverflow.com/questions/tagged/bruno) - [Website](https://www.usebruno.com) - [Pricing](https://www.usebruno.com/pricing) - [Download](https://www.usebruno.com/downloads) From fff687000267b8dc3e79398d59e27ac560fc539e Mon Sep 17 00:00:00 2001 From: Bennieboj <4215739+bennieboj@users.noreply.github.com> Date: Wed, 15 Nov 2023 19:42:53 +0100 Subject: [PATCH 48/53] fix #961 by using trim --- .../bruno-app/src/components/RequestPane/QueryUrl/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js index 0a45f1a7d..f07bd5452 100644 --- a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js +++ b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js @@ -34,7 +34,7 @@ const QueryUrl = ({ item, collection, handleRun }) => { requestUrlChanged({ itemUid: item.uid, collectionUid: collection.uid, - url: value + url: value.trim() }) ); }; @@ -80,7 +80,7 @@ const QueryUrl = ({ item, collection, handleRun }) => { }} > Date: Thu, 16 Nov 2023 13:43:01 -0500 Subject: [PATCH 49/53] feat(#970): Add PDF Preview Any PDF response can be now be previewed. There is no UI fancy UI interface for it for simplicity. This makes it look very similar to Postman. --- package-lock.json | 877 +++++++++++++++++- packages/bruno-app/package.json | 2 + .../QueryResult/QueryResultPreview/index.js | 23 + .../ResponsePane/QueryResult/StyledWrapper.js | 13 + .../ResponsePane/QueryResult/index.js | 2 + 5 files changed, 904 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1e845084..0f1c2a4c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3491,6 +3491,74 @@ "node": ">=10" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, "node_modules/@n1ru4l/push-pull-async-iterable-iterator": { "version": "3.2.0", "license": "MIT", @@ -5068,6 +5136,12 @@ "dev": true, "license": "MIT" }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, "node_modules/about-window": { "version": "1.15.2", "license": "MIT" @@ -5111,7 +5185,7 @@ }, "node_modules/agent-base": { "version": "6.0.2", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "debug": "4" @@ -5351,10 +5425,43 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, "node_modules/arcsecond": { "version": "5.0.0", "license": "MIT" }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/arg": { "version": "5.0.2", "license": "MIT" @@ -6326,6 +6433,21 @@ } ] }, + "node_modules/canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/caseless": { "version": "0.12.0", "license": "Apache-2.0" @@ -6412,6 +6534,15 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true, + "engines": { + "node": ">=10" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "dev": true, @@ -6558,6 +6689,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "dev": true, @@ -6629,6 +6768,15 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, + "bin": { + "color-support": "bin.js" + } + }, "node_modules/colord": { "version": "2.9.3", "dev": true, @@ -6834,6 +6982,12 @@ "typedarray-to-buffer": "^3.1.5" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, "node_modules/content-disposition": { "version": "0.5.4", "license": "MIT", @@ -7383,6 +7537,12 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, "node_modules/depd": { "version": "2.0.0", "license": "MIT", @@ -7398,6 +7558,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "dev": true, @@ -8674,6 +8843,36 @@ "node": ">=14.14" } }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "license": "ISC" @@ -8697,6 +8896,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/generic-names": { "version": "4.0.0", "dev": true, @@ -9228,6 +9447,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, "node_modules/has-yarn": { "version": "2.1.0", "dev": true, @@ -9475,7 +9700,7 @@ }, "node_modules/https-proxy-agent": { "version": "5.0.1", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "agent-base": "6", @@ -11303,9 +11528,17 @@ "node": ">=12" } }, + "node_modules/make-cancellable-promise": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/make-cancellable-promise/-/make-cancellable-promise-1.3.2.tgz", + "integrity": "sha512-GCXh3bq/WuMbS+Ky4JBPW1hYTOU+znU+Q5m9Pu+pI8EoUqIHk9+tviOKC6/qhHh8C4/As3tzJ69IF32kdz85ww==", + "funding": { + "url": "https://github.com/wojtekmaj/make-cancellable-promise?sponsor=1" + } + }, "node_modules/make-dir": { "version": "3.1.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "semver": "^6.0.0" @@ -11322,6 +11555,14 @@ "dev": true, "license": "ISC" }, + "node_modules/make-event-props": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-1.6.2.tgz", + "integrity": "sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA==", + "funding": { + "url": "https://github.com/wojtekmaj/make-event-props?sponsor=1" + } + }, "node_modules/makeerror": { "version": "1.0.12", "dev": true, @@ -11409,6 +11650,22 @@ "version": "1.0.1", "license": "MIT" }, + "node_modules/merge-refs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.2.2.tgz", + "integrity": "sha512-RwcT7GsQR3KbuLw1rRuodq4Nt547BKEBkliZ0qqsrpyNne9bGTFtsFIsIpx82huWhcl3kOlOlH4H0xkPk/DqVw==", + "funding": { + "url": "https://github.com/wojtekmaj/merge-refs?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/merge-stream": { "version": "2.0.0", "dev": true, @@ -11586,6 +11843,46 @@ "dev": true, "license": "MIT" }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, "node_modules/mkdirp": { "version": "0.5.6", "license": "MIT", @@ -11691,6 +11988,12 @@ "version": "0.0.8", "license": "ISC" }, + "node_modules/nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "optional": true + }, "node_modules/nanoclone": { "version": "0.2.1", "license": "MIT" @@ -11874,6 +12177,21 @@ "node": ">= 16.0.0" } }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "dev": true, @@ -11940,6 +12258,18 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "optional": true, + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/nth-check": { "version": "2.1.1", "dev": true, @@ -12371,6 +12701,15 @@ "node": ">=8" } }, + "node_modules/path2d-polyfill": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz", + "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/pathval": { "version": "1.1.1", "license": "MIT", @@ -12388,6 +12727,18 @@ "through": "~2.3" } }, + "node_modules/pdfjs-dist": { + "version": "3.11.174", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", + "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==", + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" + } + }, "node_modules/pend": { "version": "1.2.0", "dev": true, @@ -13773,6 +14124,34 @@ "version": "18.2.0", "license": "MIT" }, + "node_modules/react-pdf": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.5.1.tgz", + "integrity": "sha512-NVno97L3wfX3RLGB3C+QtroOiQrgCKPHLMFKMSQaRqDlH3gkq2CB2NyXJ+IDQNLrT/gSMPPgtZQL8cOUySc/3w==", + "dependencies": { + "clsx": "^2.0.0", + "make-cancellable-promise": "^1.3.1", + "make-event-props": "^1.6.0", + "merge-refs": "^1.2.1", + "pdfjs-dist": "3.11.174", + "prop-types": "^15.6.2", + "tiny-invariant": "^1.0.0", + "tiny-warning": "^1.0.0" + }, + "funding": { + "url": "https://github.com/wojtekmaj/react-pdf?sponsor=1" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-redux": { "version": "7.2.9", "license": "MIT", @@ -14526,7 +14905,7 @@ }, "node_modules/semver": { "version": "6.3.0", - "dev": true, + "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -14654,7 +15033,7 @@ }, "node_modules/set-blocking": { "version": "2.0.0", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/set-function-length": { @@ -14741,6 +15120,61 @@ "version": "3.0.7", "license": "ISC" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true + }, + "node_modules/simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "optional": true, + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-get/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/simple-get/node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "license": "MIT", @@ -15450,6 +15884,41 @@ "node": ">=6" } }, + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "optional": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, "node_modules/temp-file": { "version": "3.4.0", "dev": true, @@ -15635,6 +16104,11 @@ "dev": true, "license": "MIT" }, + "node_modules/tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, "node_modules/tiny-warning": { "version": "1.0.3", "license": "MIT" @@ -16507,6 +16981,15 @@ "dev": true, "license": "ISC" }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/widest-line": { "version": "3.1.0", "dev": true, @@ -16748,6 +17231,7 @@ "nanoid": "3.3.4", "next": "12.3.3", "path": "^0.12.7", + "pdfjs-dist": "^3.11.174", "platform": "^1.3.6", "posthog-node": "^2.1.0", "qs": "^6.11.0", @@ -16759,6 +17243,7 @@ "react-github-btn": "^1.4.0", "react-hot-toast": "^2.4.0", "react-inspector": "^6.0.2", + "react-pdf": "^7.5.1", "react-redux": "^7.2.6", "react-tooltip": "^5.5.2", "sass": "^1.46.0", @@ -16888,7 +17373,7 @@ }, "packages/bruno-cli": { "name": "@usebruno/cli", - "version": "1.0.0", + "version": "1.1.0", "license": "MIT", "dependencies": { "@usebruno/js": "0.9.1", @@ -16980,7 +17465,7 @@ }, "packages/bruno-electron": { "name": "bruno", - "version": "v1.1.0", + "version": "v1.1.1", "dependencies": { "@aws-sdk/credential-providers": "^3.425.0", "@usebruno/js": "0.9.1", @@ -19784,6 +20269,58 @@ } } }, + "@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "optional": true, + "requires": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, "@n1ru4l/push-pull-async-iterable-iterator": { "version": "3.2.0" }, @@ -20940,6 +21477,7 @@ "nanoid": "3.3.4", "next": "12.3.3", "path": "^0.12.7", + "pdfjs-dist": "3.11.174", "platform": "^1.3.6", "posthog-node": "^2.1.0", "prettier": "^2.7.1", @@ -20952,6 +21490,7 @@ "react-github-btn": "^1.4.0", "react-hot-toast": "^2.4.0", "react-inspector": "^6.0.2", + "react-pdf": "^7.5.1", "react-redux": "^7.2.6", "react-tooltip": "^5.5.2", "sass": "^1.46.0", @@ -20962,7 +21501,7 @@ "webpack": "^5.64.4", "webpack-cli": "^4.9.1", "xml-formatter": "^3.5.0", - "yargs-parser": "*", + "yargs-parser": "^21.1.1", "yup": "^0.32.11" }, "dependencies": { @@ -21377,6 +21916,12 @@ "version": "5.1.1", "dev": true }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true + }, "about-window": { "version": "1.15.2" }, @@ -21403,7 +21948,7 @@ }, "agent-base": { "version": "6.0.2", - "dev": true, + "devOptional": true, "requires": { "debug": "4" } @@ -21563,9 +22108,38 @@ "append-field": { "version": "1.0.0" }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true + }, "arcsecond": { "version": "5.0.0" }, + "are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "arg": { "version": "5.0.2" }, @@ -22316,6 +22890,17 @@ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==" }, + "canvas": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", + "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", + "optional": true, + "requires": { + "@mapbox/node-pre-gyp": "^1.0.0", + "nan": "^2.17.0", + "simple-get": "^3.0.3" + } + }, "caseless": { "version": "0.12.0" }, @@ -22367,6 +22952,12 @@ "readdirp": "~3.6.0" } }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true + }, "chrome-trace-event": { "version": "1.0.3", "dev": true @@ -22444,6 +23035,11 @@ "mimic-response": "^1.0.0" } }, + "clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" + }, "co": { "version": "4.6.0", "dev": true @@ -22488,6 +23084,12 @@ "simple-swizzle": "^0.2.2" } }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true + }, "colord": { "version": "2.9.3", "dev": true @@ -22634,6 +23236,12 @@ } } }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true + }, "content-disposition": { "version": "0.5.4", "requires": { @@ -22971,12 +23579,24 @@ "delayed-stream": { "version": "1.0.0" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true + }, "depd": { "version": "2.0.0" }, "destroy": { "version": "1.2.0" }, + "detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "optional": true + }, "detect-newline": { "version": "3.1.0", "dev": true @@ -23833,6 +24453,32 @@ "universalify": "^2.0.0" } }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "optional": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, "fs.realpath": { "version": "1.0.0" }, @@ -23845,6 +24491,23 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, + "gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "optional": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + } + }, "generic-names": { "version": "4.0.0", "dev": true, @@ -24189,6 +24852,12 @@ "has-symbols": { "version": "1.0.3" }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true + }, "has-yarn": { "version": "2.1.0", "dev": true @@ -24348,7 +25017,7 @@ }, "https-proxy-agent": { "version": "5.0.1", - "dev": true, + "devOptional": true, "requires": { "agent-base": "6", "debug": "4" @@ -25513,9 +26182,14 @@ "@jridgewell/sourcemap-codec": "^1.4.13" } }, + "make-cancellable-promise": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/make-cancellable-promise/-/make-cancellable-promise-1.3.2.tgz", + "integrity": "sha512-GCXh3bq/WuMbS+Ky4JBPW1hYTOU+znU+Q5m9Pu+pI8EoUqIHk9+tviOKC6/qhHh8C4/As3tzJ69IF32kdz85ww==" + }, "make-dir": { "version": "3.1.0", - "dev": true, + "devOptional": true, "requires": { "semver": "^6.0.0" } @@ -25524,6 +26198,11 @@ "version": "1.3.6", "dev": true }, + "make-event-props": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/make-event-props/-/make-event-props-1.6.2.tgz", + "integrity": "sha512-iDwf7mA03WPiR8QxvcVHmVWEPfMY1RZXerDVNCRYW7dUr2ppH3J58Rwb39/WG39yTZdRSxr3x+2v22tvI0VEvA==" + }, "makeerror": { "version": "1.0.12", "dev": true, @@ -25583,6 +26262,12 @@ "merge-descriptors": { "version": "1.0.1" }, + "merge-refs": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/merge-refs/-/merge-refs-1.2.2.tgz", + "integrity": "sha512-RwcT7GsQR3KbuLw1rRuodq4Nt547BKEBkliZ0qqsrpyNne9bGTFtsFIsIpx82huWhcl3kOlOlH4H0xkPk/DqVw==", + "requires": {} + }, "merge-stream": { "version": "2.0.0", "dev": true @@ -25681,6 +26366,39 @@ "version": "1.2.0", "dev": true }, + "minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "optional": true + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "optional": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, "mkdirp": { "version": "0.5.6", "requires": { @@ -25747,6 +26465,12 @@ "mute-stream": { "version": "0.0.8" }, + "nan": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", + "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "optional": true + }, "nanoclone": { "version": "0.2.1" }, @@ -25854,6 +26578,15 @@ "tv4": "^1.3.0" } }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "requires": { + "abbrev": "1" + } + }, "normalize-package-data": { "version": "2.5.0", "dev": true, @@ -25897,6 +26630,18 @@ "path-key": "^3.0.0" } }, + "npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "optional": true, + "requires": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "nth-check": { "version": "2.1.1", "dev": true, @@ -26161,6 +26906,12 @@ "path-type": { "version": "4.0.0" }, + "path2d-polyfill": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz", + "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==", + "optional": true + }, "pathval": { "version": "1.1.1" }, @@ -26170,6 +26921,15 @@ "through": "~2.3" } }, + "pdfjs-dist": { + "version": "3.11.174", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz", + "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==", + "requires": { + "canvas": "^2.11.2", + "path2d-polyfill": "^2.0.1" + } + }, "pend": { "version": "1.2.0", "dev": true @@ -26978,6 +27738,21 @@ "react-is": { "version": "18.2.0" }, + "react-pdf": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.5.1.tgz", + "integrity": "sha512-NVno97L3wfX3RLGB3C+QtroOiQrgCKPHLMFKMSQaRqDlH3gkq2CB2NyXJ+IDQNLrT/gSMPPgtZQL8cOUySc/3w==", + "requires": { + "clsx": "^2.0.0", + "make-cancellable-promise": "^1.3.1", + "make-event-props": "^1.6.0", + "merge-refs": "^1.2.1", + "pdfjs-dist": "3.11.174", + "prop-types": "^15.6.2", + "tiny-invariant": "^1.0.0", + "tiny-warning": "^1.0.0" + } + }, "react-redux": { "version": "7.2.9", "requires": { @@ -27488,7 +28263,7 @@ }, "semver": { "version": "6.3.0", - "dev": true + "devOptional": true }, "semver-compare": { "version": "1.0.0", @@ -27581,7 +28356,7 @@ }, "set-blocking": { "version": "2.0.0", - "dev": true + "devOptional": true }, "set-function-length": { "version": "1.1.1", @@ -27636,6 +28411,40 @@ "signal-exit": { "version": "3.0.7" }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "optional": true + }, + "simple-get": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", + "optional": true, + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + }, + "dependencies": { + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "optional": true, + "requires": { + "mimic-response": "^2.0.0" + } + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "optional": true + } + } + }, "simple-swizzle": { "version": "0.2.2", "requires": { @@ -28115,6 +28924,34 @@ "version": "2.2.1", "dev": true }, + "tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "optional": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + } + } + }, "temp-file": { "version": "3.4.0", "dev": true, @@ -28236,6 +29073,11 @@ "version": "1.7.1", "dev": true }, + "tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, "tiny-warning": { "version": "1.0.3" }, @@ -28777,6 +29619,15 @@ "version": "1.0.0", "dev": true }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "widest-line": { "version": "3.1.0", "dev": true, diff --git a/packages/bruno-app/package.json b/packages/bruno-app/package.json index d5ba0b1aa..94e1db53b 100644 --- a/packages/bruno-app/package.json +++ b/packages/bruno-app/package.json @@ -45,6 +45,7 @@ "nanoid": "3.3.4", "next": "12.3.3", "path": "^0.12.7", + "pdfjs-dist": "^3.11.174", "platform": "^1.3.6", "posthog-node": "^2.1.0", "qs": "^6.11.0", @@ -56,6 +57,7 @@ "react-github-btn": "^1.4.0", "react-hot-toast": "^2.4.0", "react-inspector": "^6.0.2", + "react-pdf": "^7.5.1", "react-redux": "^7.2.6", "react-tooltip": "^5.5.2", "sass": "^1.46.0", diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js index 5ed21ee97..157cfa0a3 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js @@ -2,6 +2,11 @@ import CodeEditor from 'components/CodeEditor/index'; import { get } from 'lodash'; import { useDispatch, useSelector } from 'react-redux'; 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 = ({ previewTab, @@ -19,6 +24,10 @@ const QueryResultPreview = ({ const preferences = useSelector((state) => state.app.preferences); 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 if (!allowedPreviewModes.includes(previewTab)) { return null; @@ -45,6 +54,20 @@ const QueryResultPreview = ({ case 'preview-image': { return ; } + case 'preview-pdf': { + return( +
+ + {Array.from(new Array(numPages), (el, index) => ( + + ))} + +
+ ); + } default: case 'raw': { return ( diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js index 07f51b8bd..9b797a638 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js @@ -18,6 +18,19 @@ const StyledWrapper = styled.div` 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'] { .active { color: ${(props) => props.theme.colors.text.yellow}; diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js index b5508ba1b..f49c2491b 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js @@ -49,6 +49,8 @@ const QueryResult = ({ item, collection, data, dataBuffer, width, disableRunEven allowedPreviewModes.unshift('preview-web'); } else if (mode.includes('image')) { allowedPreviewModes.unshift('preview-image'); + } else if (contentType.includes("pdf")) { + allowedPreviewModes.unshift('preview-pdf'); } return allowedPreviewModes; From 52baa69b70e0e1caf53f2ee5b656d552752eb92d Mon Sep 17 00:00:00 2001 From: n00o Date: Thu, 16 Nov 2023 18:55:43 -0500 Subject: [PATCH 50/53] Fix formatting Pass prettier tests --- .../QueryResult/QueryResultPreview/index.js | 21 ++++++++----------- .../ResponsePane/QueryResult/StyledWrapper.js | 2 +- .../ResponsePane/QueryResult/index.js | 2 +- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js index 157cfa0a3..af11ebc23 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/QueryResultPreview/index.js @@ -2,8 +2,8 @@ import CodeEditor from 'components/CodeEditor/index'; import { get } from 'lodash'; import { useDispatch, useSelector } from 'react-redux'; import { sendRequest } from 'providers/ReduxStore/slices/collections/actions'; -import { Document, Page } from "react-pdf"; -import { useState } from "react"; +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'; @@ -55,16 +55,13 @@ const QueryResultPreview = ({ return ; } case 'preview-pdf': { - return( -
- - {Array.from(new Array(numPages), (el, index) => ( - - ))} - + return ( +
+ + {Array.from(new Array(numPages), (el, index) => ( + + ))} +
); } diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js index 9b797a638..64ab32f7e 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/StyledWrapper.js @@ -20,7 +20,7 @@ const StyledWrapper = styled.div` .react-pdf__Page { margin-top: 10px; - background-color:transparent !important; + background-color: transparent !important; } .react-pdf__Page__textContent { border: 1px solid darkgrey; diff --git a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js index f49c2491b..a8f13505c 100644 --- a/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js +++ b/packages/bruno-app/src/components/ResponsePane/QueryResult/index.js @@ -49,7 +49,7 @@ const QueryResult = ({ item, collection, data, dataBuffer, width, disableRunEven allowedPreviewModes.unshift('preview-web'); } else if (mode.includes('image')) { allowedPreviewModes.unshift('preview-image'); - } else if (contentType.includes("pdf")) { + } else if (contentType.includes('pdf')) { allowedPreviewModes.unshift('preview-pdf'); } From e96da632b2d6b1a1f8d310e0b09961fdba508069 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Sat, 18 Nov 2023 08:29:18 +0530 Subject: [PATCH 51/53] chore: version bump @usebruno/js @usebruno/cli --- packages/bruno-cli/package.json | 4 ++-- packages/bruno-js/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bruno-cli/package.json b/packages/bruno-cli/package.json index d2aa710f4..37ea480a8 100644 --- a/packages/bruno-cli/package.json +++ b/packages/bruno-cli/package.json @@ -1,6 +1,6 @@ { "name": "@usebruno/cli", - "version": "1.1.0", + "version": "1.1.1", "license": "MIT", "main": "src/index.js", "bin": { @@ -24,7 +24,7 @@ "package.json" ], "dependencies": { - "@usebruno/js": "0.9.1", + "@usebruno/js": "0.9.2", "@usebruno/lang": "0.9.0", "axios": "^1.5.1", "chai": "^4.3.7", diff --git a/packages/bruno-js/package.json b/packages/bruno-js/package.json index 1152beec5..d751c0328 100644 --- a/packages/bruno-js/package.json +++ b/packages/bruno-js/package.json @@ -1,6 +1,6 @@ { "name": "@usebruno/js", - "version": "0.9.1", + "version": "0.9.2", "license": "MIT", "main": "src/index.js", "files": [ From f8c23ed6da6becf694eb782d331a0f37fd5f2b98 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Sat, 18 Nov 2023 08:29:53 +0530 Subject: [PATCH 52/53] chore: save icon should use yellow color to indicate draft --- packages/bruno-app/src/components/RequestPane/QueryUrl/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js index f07bd5452..3cc297062 100644 --- a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js +++ b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js @@ -80,7 +80,7 @@ const QueryUrl = ({ item, collection, handleRun }) => { }} > Date: Sat, 18 Nov 2023 09:18:40 +0530 Subject: [PATCH 53/53] fix(#962): improved error label when name is not defined while setting env var --- package-lock.json | 49 ++++++++++++++++++++++++---- packages/bruno-electron/package.json | 2 +- packages/bruno-js/src/bru.js | 4 +-- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f1c2a4c5..33807da43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17373,10 +17373,10 @@ }, "packages/bruno-cli": { "name": "@usebruno/cli", - "version": "1.1.0", + "version": "1.1.1", "license": "MIT", "dependencies": { - "@usebruno/js": "0.9.1", + "@usebruno/js": "0.9.2", "@usebruno/lang": "0.9.0", "axios": "^1.5.1", "chai": "^4.3.7", @@ -17468,7 +17468,7 @@ "version": "v1.1.1", "dependencies": { "@aws-sdk/credential-providers": "^3.425.0", - "@usebruno/js": "0.9.1", + "@usebruno/js": "0.9.2", "@usebruno/lang": "0.9.0", "@usebruno/schema": "0.6.0", "about-window": "^1.15.2", @@ -17526,6 +17526,21 @@ "node": ">= 14" } }, + "packages/bruno-electron/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "packages/bruno-electron/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -17658,6 +17673,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "packages/bruno-electron/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "packages/bruno-electron/node_modules/uuid": { "version": "9.0.0", "license": "MIT", @@ -17694,7 +17714,7 @@ }, "packages/bruno-js": { "name": "@usebruno/js", - "version": "0.9.1", + "version": "0.9.2", "license": "MIT", "dependencies": { "@usebruno/query": "0.1.0", @@ -21477,7 +21497,7 @@ "nanoid": "3.3.4", "next": "12.3.3", "path": "^0.12.7", - "pdfjs-dist": "3.11.174", + "pdfjs-dist": "^3.11.174", "platform": "^1.3.6", "posthog-node": "^2.1.0", "prettier": "^2.7.1", @@ -21579,7 +21599,7 @@ "@usebruno/cli": { "version": "file:packages/bruno-cli", "requires": { - "@usebruno/js": "0.9.1", + "@usebruno/js": "0.9.2", "@usebruno/lang": "0.9.0", "axios": "^1.5.1", "chai": "^4.3.7", @@ -22543,7 +22563,7 @@ "version": "file:packages/bruno-electron", "requires": { "@aws-sdk/credential-providers": "^3.425.0", - "@usebruno/js": "0.9.1", + "@usebruno/js": "0.9.2", "@usebruno/lang": "0.9.0", "@usebruno/schema": "0.6.0", "about-window": "^1.15.2", @@ -22592,6 +22612,16 @@ "debug": "^4.3.4" } }, + "ajv": { + "version": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -22675,6 +22705,11 @@ "argparse": "^2.0.1" } }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, "uuid": { "version": "9.0.0" } diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json index d0c562a70..7fa75c1bc 100644 --- a/packages/bruno-electron/package.json +++ b/packages/bruno-electron/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@aws-sdk/credential-providers": "^3.425.0", - "@usebruno/js": "0.9.1", + "@usebruno/js": "0.9.2", "@usebruno/lang": "0.9.0", "@usebruno/schema": "0.6.0", "about-window": "^1.15.2", diff --git a/packages/bruno-js/src/bru.js b/packages/bruno-js/src/bru.js index 884b05a50..4813a73db 100644 --- a/packages/bruno-js/src/bru.js +++ b/packages/bruno-js/src/bru.js @@ -45,7 +45,7 @@ class Bru { setEnvVar(key, value) { if (!key) { - throw new Error('Key is required'); + throw new Error('Creating a env variable without specifying a name is not allowed.'); } // gracefully ignore if key is not present in environment @@ -58,7 +58,7 @@ class Bru { setVar(key, value) { if (!key) { - throw new Error('A variable with an empty name has been created but name is required.'); + throw new Error('Creating a variable without specifying a name is not allowed.'); } if (envVariableNameRegex.test(key) === false) {