├── .nvmrc
├── packages
├── bruno-tests
│ ├── .nvmrc
│ ├── collection
│ │ ├── .nvmrc
│ │ ├── .gitignore
│ │ ├── .env
│ │ ├── file.json
│ │ ├── lib
│ │ │ └── math.js
│ │ ├── readme.md
│ │ ├── auth
│ │ │ ├── cookie
│ │ │ │ ├── Login.bru
│ │ │ │ └── Check.bru
│ │ │ ├── basic
│ │ │ │ ├── via auth
│ │ │ │ │ ├── Basic Auth 401.bru
│ │ │ │ │ └── Basic Auth 200.bru
│ │ │ │ └── via script
│ │ │ │ │ ├── Basic Auth 401.bru
│ │ │ │ │ └── Basic Auth 200.bru
│ │ │ ├── inherit auth
│ │ │ │ └── inherit Bearer Auth 200.bru
│ │ │ └── bearer
│ │ │ │ ├── via auth
│ │ │ │ └── Bearer Auth 200.bru
│ │ │ │ └── via headers
│ │ │ │ └── Bearer Auth 200.bru
│ │ ├── echo
│ │ │ ├── echo bom json.bru
│ │ │ ├── echo xml raw.bru
│ │ │ ├── echo plaintext.bru
│ │ │ ├── echo xml parsed.bru
│ │ │ └── echo json.bru
│ │ ├── package.json
│ │ ├── environments
│ │ │ └── Prod.bru
│ │ ├── collection.bru
│ │ ├── graphql
│ │ │ └── spacex.bru
│ │ ├── preview
│ │ │ ├── image
│ │ │ │ └── bruno.bru
│ │ │ └── html
│ │ │ │ └── bruno.bru
│ │ ├── redirects
│ │ │ ├── Test Redirect.bru
│ │ │ └── Disable Redirect.bru
│ │ ├── string interpolation
│ │ │ ├── env vars.bru
│ │ │ ├── process env vars.bru
│ │ │ └── missing values.bru
│ │ ├── bruno.json
│ │ └── scripting
│ │ │ ├── local modules
│ │ │ └── sum.bru
│ │ │ └── npm modules
│ │ │ └── fakerjs.bru
│ ├── collection_oauth2
│ │ ├── .nvmrc
│ │ ├── .gitignore
│ │ ├── .env
│ │ ├── file.json
│ │ ├── readme.md
│ │ ├── package.json
│ │ ├── environments
│ │ │ └── Prod.bru
│ │ ├── collection.bru
│ │ ├── auth
│ │ │ └── oauth2
│ │ │ │ ├── password_credentials
│ │ │ │ ├── resource.bru
│ │ │ │ └── token.bru
│ │ │ │ ├── authorization_code
│ │ │ │ ├── resource.bru
│ │ │ │ ├── token with authorize.bru
│ │ │ │ ├── github token with authorize.bru
│ │ │ │ └── google token with authorize.bru
│ │ │ │ └── client_credentials
│ │ │ │ ├── resource.bru
│ │ │ │ └── token.bru
│ │ ├── bruno.json
│ │ └── package-lock.json
│ ├── collection_level_oauth2
│ │ ├── .nvmrc
│ │ ├── .gitignore
│ │ ├── readme.md
│ │ ├── package.json
│ │ ├── environments
│ │ │ └── Prod.bru
│ │ ├── resource.bru
│ │ ├── bruno.json
│ │ ├── collection.bru
│ │ └── package-lock.json
│ ├── src
│ │ └── auth
│ │ │ ├── bearer.js
│ │ │ ├── basic.js
│ │ │ └── index.js
│ ├── readme.md
│ └── package.json
├── bruno-app
│ ├── src
│ │ ├── styles
│ │ │ ├── _buttons.scss
│ │ │ └── app.scss
│ │ ├── utils
│ │ │ ├── common
│ │ │ │ ├── regex.js
│ │ │ │ ├── cache.js
│ │ │ │ └── error.js
│ │ │ ├── network
│ │ │ │ └── cancelTokens.js
│ │ │ ├── tabs
│ │ │ │ └── index.js
│ │ │ ├── codegenerator
│ │ │ │ └── auth.js
│ │ │ ├── collections
│ │ │ │ └── search.js
│ │ │ └── idb
│ │ │ │ └── index.js
│ │ ├── providers
│ │ │ ├── ReduxStore
│ │ │ │ ├── middlewares
│ │ │ │ │ ├── tasks
│ │ │ │ │ │ └── utils.js
│ │ │ │ │ └── debug
│ │ │ │ │ │ └── middleware.js
│ │ │ │ └── index.js
│ │ │ ├── App
│ │ │ │ ├── StyledWrapper.js
│ │ │ │ └── ConfirmAppClose
│ │ │ │ │ └── index.js
│ │ │ └── Toaster
│ │ │ │ └── index.js
│ │ ├── themes
│ │ │ └── index.js
│ │ ├── components
│ │ │ ├── CollectionSettings
│ │ │ │ ├── Auth
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ ├── OAuth2
│ │ │ │ │ │ ├── ClientCredentials
│ │ │ │ │ │ │ ├── inputsConfig.js
│ │ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ │ ├── AuthorizationCode
│ │ │ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ │ │ └── inputsConfig.js
│ │ │ │ │ │ └── PasswordCredentials
│ │ │ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ │ │ └── inputsConfig.js
│ │ │ │ │ ├── AwsV4Auth
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ ├── BasicAuth
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ ├── BearerAuth
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ ├── DigestAuth
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ └── AuthMode
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Tests
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Info
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Script
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Docs
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Presets
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ └── ProxySettings
│ │ │ │ │ └── StyledWrapper.js
│ │ │ ├── FolderSettings
│ │ │ │ ├── Tests
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Vars
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ └── Script
│ │ │ │ │ └── StyledWrapper.js
│ │ │ ├── RequestTabs
│ │ │ │ ├── CollectionToolBar
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ └── RequestTab
│ │ │ │ │ └── StyledWrapper.js
│ │ │ ├── Preferences
│ │ │ │ ├── Theme
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Font
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── General
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Support
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── ProxySettings
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── Sidebar
│ │ │ │ ├── Collections
│ │ │ │ │ ├── CreateOrOpenCollection
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ ├── Collection
│ │ │ │ │ │ └── CollectionItem
│ │ │ │ │ │ │ ├── RunCollectionItem
│ │ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ │ │ ├── DeleteCollectionItem
│ │ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ │ │ ├── GenerateCodeItem
│ │ │ │ │ │ │ └── CodeView
│ │ │ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ │ │ └── RequestMethod
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ ├── SelectCollection
│ │ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── TitleBar
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ └── GoldenEdition
│ │ │ │ │ └── StyledWrapper.js
│ │ │ ├── RequestPane
│ │ │ │ ├── Vars
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── RequestBody
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── RequestBodyMode
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Tests
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Auth
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ ├── OAuth2
│ │ │ │ │ │ ├── ClientCredentials
│ │ │ │ │ │ │ ├── inputsConfig.js
│ │ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ │ ├── AuthorizationCode
│ │ │ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ │ │ └── inputsConfig.js
│ │ │ │ │ │ └── PasswordCredentials
│ │ │ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ │ │ └── inputsConfig.js
│ │ │ │ │ ├── AwsV4Auth
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ ├── BasicAuth
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ ├── BearerAuth
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ ├── DigestAuth
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ │ └── AuthMode
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── GraphQLVariables
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Script
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── SaveRequest
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── QueryUrl
│ │ │ │ │ └── HttpMethodSelector
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── GraphQLRequestPane
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ └── HttpRequestPane
│ │ │ │ │ └── StyledWrapper.js
│ │ │ ├── Portal
│ │ │ │ └── index.js
│ │ │ ├── ResponsePane
│ │ │ │ ├── ResponseSave
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── ResponseClear
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── ResponseSize
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── ResponseTime
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── Placeholder
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── StatusCode
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── TestResults
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── Timeline
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── ResponseHeaders
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── Overlay
│ │ │ │ │ └── StyledWrapper.js
│ │ │ │ ├── NetworkError
│ │ │ │ │ └── index.js
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── Environments
│ │ │ │ ├── EnvironmentSettings
│ │ │ │ │ ├── StyledWrapper.js
│ │ │ │ │ └── DeleteEnvironment
│ │ │ │ │ │ └── StyledWrapper.js
│ │ │ │ └── EnvironmentSelector
│ │ │ │ │ └── StyledWrapper.js
│ │ │ ├── Cookies
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── Spinner
│ │ │ │ ├── index.js
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── Icons
│ │ │ │ └── Send
│ │ │ │ │ └── index.js
│ │ │ ├── Navbar
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── BrunoSupport
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── Documentation
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── VariablesEditor
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── Welcome
│ │ │ │ └── StyledWrapper.js
│ │ │ ├── Dropdown
│ │ │ │ └── index.js
│ │ │ ├── RunnerResults
│ │ │ │ ├── StyledWrapper.js
│ │ │ │ └── ResponsePane
│ │ │ │ │ └── StyledWrapper.js
│ │ │ ├── StopWatch
│ │ │ │ └── index.js
│ │ │ ├── Toast
│ │ │ │ └── index.js
│ │ │ └── MarkDown
│ │ │ │ └── index.jsx
│ │ ├── assets
│ │ │ ├── send.svg
│ │ │ └── github.svg
│ │ ├── hooks
│ │ │ ├── usePrevious
│ │ │ │ └── index.js
│ │ │ └── useLocalStorage
│ │ │ │ └── index.js
│ │ └── pages
│ │ │ ├── index.js
│ │ │ └── Bruno
│ │ │ └── StyledWrapper.js
│ ├── .env.production
│ ├── .babelrc
│ ├── public
│ │ ├── favicon.ico
│ │ └── theme
│ │ │ ├── index.js
│ │ │ ├── dark.js
│ │ │ └── light.js
│ ├── postcss.config.js
│ ├── .prettierrc.json
│ ├── tailwind.config.js
│ ├── next.config.js
│ ├── .gitignore
│ └── jsconfig.json
├── bruno-electron
│ ├── .env.sample
│ ├── src
│ │ ├── about
│ │ │ ├── 256x256.png
│ │ │ └── about.css
│ │ ├── utils
│ │ │ ├── cancel-token.js
│ │ │ └── filesystem.test.js
│ │ ├── store
│ │ │ ├── bruno-config.js
│ │ │ └── window-state.js
│ │ ├── preload.js
│ │ └── ipc
│ │ │ └── notifications.js
│ ├── resources
│ │ ├── icons
│ │ │ ├── mac
│ │ │ │ └── icon.icns
│ │ │ ├── png
│ │ │ │ ├── 16x16.png
│ │ │ │ ├── 24x24.png
│ │ │ │ ├── 32x32.png
│ │ │ │ ├── 48x48.png
│ │ │ │ ├── 64x64.png
│ │ │ │ ├── 128x128.png
│ │ │ │ ├── 256x256.png
│ │ │ │ ├── 512x512.png
│ │ │ │ └── 1024x1024.png
│ │ │ └── win
│ │ │ │ └── icon.ico
│ │ └── entitlements.mac.plist
│ ├── .gitignore
│ ├── readme.md
│ ├── tests
│ │ └── network
│ │ │ ├── authorize-user.spec.js
│ │ │ ├── prepare-request.spec.js
│ │ │ └── index.spec.js
│ └── notarize.js
├── bruno-cli
│ ├── bin
│ │ └── bru.js
│ ├── .gitignore
│ ├── assets
│ │ └── images
│ │ │ └── cli-demo.png
│ ├── src
│ │ ├── utils
│ │ │ └── common.js
│ │ ├── reporters
│ │ │ └── html.js
│ │ ├── index.js
│ │ └── constants.js
│ └── tests
│ │ └── runner
│ │ └── prepare-request.spec.js
├── bruno-lang
│ ├── .gitignore
│ ├── v1
│ │ ├── tests
│ │ │ ├── fixtures
│ │ │ │ └── env.bru
│ │ │ ├── bru-to-env-json.spec.js
│ │ │ └── env-json-to-bru.spec.js
│ │ └── src
│ │ │ ├── tests-tag.js
│ │ │ ├── params-tag.js
│ │ │ ├── script-tag.js
│ │ │ ├── headers-tag.js
│ │ │ ├── env-vars-tag.js
│ │ │ ├── utils.js
│ │ │ └── inline-tag.js
│ ├── readme.md
│ ├── v2
│ │ ├── src
│ │ │ ├── dotenvToJson.js
│ │ │ └── jsonToEnv.js
│ │ └── tests
│ │ │ ├── assert.spec.js
│ │ │ ├── index.spec.js
│ │ │ ├── fixtures
│ │ │ └── collection.bru
│ │ │ ├── script.spec.js
│ │ │ └── collection.spec.js
│ ├── package.json
│ ├── src
│ │ └── index.js
│ └── example
│ │ └── request.json
├── bruno-schema
│ ├── .gitignore
│ ├── src
│ │ ├── index.js
│ │ ├── common
│ │ │ └── index.js
│ │ └── utils
│ │ │ └── testUtils.js
│ └── package.json
├── bruno-common
│ ├── src
│ │ ├── index.ts
│ │ └── utils
│ │ │ └── index.ts
│ ├── jest.config.js
│ ├── readme.md
│ ├── .gitignore
│ ├── tsconfig.json
│ └── package.json
├── bruno-graphql-docs
│ ├── src
│ │ ├── index.ts
│ │ ├── components
│ │ │ └── DocExplorer
│ │ │ │ ├── Directive.tsx
│ │ │ │ ├── types.ts
│ │ │ │ ├── MarkdownContent.tsx
│ │ │ │ ├── Argument.tsx
│ │ │ │ └── DefaultValue.tsx
│ │ └── utility
│ │ │ └── debounce.ts
│ ├── readme.md
│ ├── .gitignore
│ ├── tsconfig.json
│ └── package.json
├── bruno-query
│ ├── jest.config.js
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── readme.md
│ └── package.json
├── bruno-js
│ ├── readme.md
│ ├── src
│ │ ├── test-results.js
│ │ ├── index.js
│ │ ├── interpolate-string.js
│ │ ├── test.js
│ │ └── bruno-response.js
│ └── package.json
├── bruno-toml
│ ├── tests
│ │ ├── methods
│ │ │ ├── get
│ │ │ │ ├── request.toml
│ │ │ │ └── request.json
│ │ │ └── delete
│ │ │ │ ├── request.toml
│ │ │ │ └── request.json
│ │ ├── scripts
│ │ │ ├── pre-request
│ │ │ │ ├── request.toml
│ │ │ │ └── request.json
│ │ │ ├── tests
│ │ │ │ ├── request.toml
│ │ │ │ └── request.json
│ │ │ └── post-response
│ │ │ │ ├── request.toml
│ │ │ │ └── request.json
│ │ └── headers
│ │ │ ├── empty-header
│ │ │ ├── request.toml
│ │ │ └── request.json
│ │ │ ├── simple-header
│ │ │ ├── request.toml
│ │ │ └── request.json
│ │ │ ├── unicode-in-header
│ │ │ ├── request.toml
│ │ │ └── request.json
│ │ │ ├── spaces-in-header
│ │ │ ├── request.toml
│ │ │ └── request.json
│ │ │ ├── dotted-header
│ │ │ ├── request.toml
│ │ │ └── request.json
│ │ │ ├── disabled-header
│ │ │ ├── request.toml
│ │ │ └── request.json
│ │ │ ├── reserved-header
│ │ │ ├── request.toml
│ │ │ └── request.json
│ │ │ └── duplicate-header
│ │ │ ├── request.toml
│ │ │ └── request.json
│ └── package.json
└── bruno-docs
│ ├── package.json
│ └── readme.md
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── config.yaml
│ └── FeatureRequest.yaml
└── PULL_REQUEST_TEMPLATE.md
├── assets
└── images
│ ├── logo.png
│ ├── cli-demo.png
│ ├── landing-2.png
│ ├── run-anywhere.png
│ ├── sponsors
│ ├── zuplo.png
│ ├── samagata.png
│ └── commit-company.png
│ ├── version-control.png
│ ├── local-collections.png
│ └── logo-transparent.png
├── .husky
└── pre-commit
├── .prettierrc.json
├── tests
└── utils
│ └── data-faker.js
├── docs
└── publishing
│ ├── publishing_cn.md
│ ├── publishing_zhtw.md
│ ├── publishing_ja.md
│ ├── publishing_tr.md
│ ├── publishing_bn.md
│ ├── publishing_pl.md
│ ├── publishing_de.md
│ ├── publishing_fr.md
│ ├── publishing_pt_br.md
│ └── publishing_ro.md
└── .gitignore
/.nvmrc:
--------------------------------------------------------------------------------
1 | v20.9.0
--------------------------------------------------------------------------------
/packages/bruno-tests/.nvmrc:
--------------------------------------------------------------------------------
1 | v20
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: helloanoop
2 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/styles/_buttons.scss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/.nvmrc:
--------------------------------------------------------------------------------
1 | v18
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/.gitignore:
--------------------------------------------------------------------------------
1 | !.env
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/.nvmrc:
--------------------------------------------------------------------------------
1 | v18
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/.env:
--------------------------------------------------------------------------------
1 | PROC_ENV_VAR=woof
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/.nvmrc:
--------------------------------------------------------------------------------
1 | v18
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/.gitignore:
--------------------------------------------------------------------------------
1 | !.env
--------------------------------------------------------------------------------
/packages/bruno-app/src/styles/app.scss:
--------------------------------------------------------------------------------
1 | @import 'buttons';
2 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/.gitignore:
--------------------------------------------------------------------------------
1 | !.env
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/.env:
--------------------------------------------------------------------------------
1 | PROC_ENV_VAR=woof
--------------------------------------------------------------------------------
/packages/bruno-app/.env.production:
--------------------------------------------------------------------------------
1 | ENV=production
2 |
3 | NEXT_PUBLIC_ENV=prod
--------------------------------------------------------------------------------
/packages/bruno-electron/.env.sample:
--------------------------------------------------------------------------------
1 | BRUNO_INFO_ENDPOINT = http://localhost:8081
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/file.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello": "bruno"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/file.json:
--------------------------------------------------------------------------------
1 | {
2 | "hello": "bruno"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/bruno-cli/bin/bru.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | require('../src').run();
4 |
--------------------------------------------------------------------------------
/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/logo.png
--------------------------------------------------------------------------------
/packages/bruno-app/src/utils/common/regex.js:
--------------------------------------------------------------------------------
1 | export const variableNameRegex = /^[\w-.]*$/;
2 |
--------------------------------------------------------------------------------
/assets/images/cli-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/cli-demo.png
--------------------------------------------------------------------------------
/assets/images/landing-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/landing-2.png
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx pretty-quick --staged
5 |
--------------------------------------------------------------------------------
/assets/images/run-anywhere.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/run-anywhere.png
--------------------------------------------------------------------------------
/assets/images/sponsors/zuplo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/sponsors/zuplo.png
--------------------------------------------------------------------------------
/assets/images/version-control.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/version-control.png
--------------------------------------------------------------------------------
/assets/images/local-collections.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/local-collections.png
--------------------------------------------------------------------------------
/assets/images/logo-transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/logo-transparent.png
--------------------------------------------------------------------------------
/assets/images/sponsors/samagata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/sponsors/samagata.png
--------------------------------------------------------------------------------
/packages/bruno-cli/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | web
3 | out
4 |
5 | pnpm-lock.yaml
6 | package-lock.json
7 | yarn.lock
8 |
--------------------------------------------------------------------------------
/packages/bruno-lang/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | web
3 | out
4 |
5 | pnpm-lock.yaml
6 | package-lock.json
7 | yarn.lock
8 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/lib/math.js:
--------------------------------------------------------------------------------
1 | const sum = (a, b) => a + b;
2 |
3 | module.exports = {
4 | sum
5 | };
6 |
--------------------------------------------------------------------------------
/packages/bruno-app/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["next/babel"],
3 | "plugins": [["styled-components", { "ssr": true }]]
4 | }
--------------------------------------------------------------------------------
/packages/bruno-app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-app/public/favicon.ico
--------------------------------------------------------------------------------
/packages/bruno-schema/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | web
3 | out
4 |
5 | pnpm-lock.yaml
6 | package-lock.json
7 | yarn.lock
8 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-tests collection
2 |
3 | API Collection to run sanity tests on Bruno CLI.
4 |
--------------------------------------------------------------------------------
/assets/images/sponsors/commit-company.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/assets/images/sponsors/commit-company.png
--------------------------------------------------------------------------------
/packages/bruno-common/src/index.ts:
--------------------------------------------------------------------------------
1 | import interpolate from './interpolate';
2 |
3 | export default {
4 | interpolate
5 | };
6 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-tests collection
2 |
3 | API Collection to run sanity tests on Bruno CLI.
4 |
--------------------------------------------------------------------------------
/packages/bruno-app/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {}
5 | }
6 | };
7 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/providers/ReduxStore/middlewares/tasks/utils.js:
--------------------------------------------------------------------------------
1 | export const taskTypes = {
2 | OPEN_REQUEST: 'OPEN_REQUEST'
3 | };
4 |
--------------------------------------------------------------------------------
/packages/bruno-cli/assets/images/cli-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-cli/assets/images/cli-demo.png
--------------------------------------------------------------------------------
/packages/bruno-electron/src/about/256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/src/about/256x256.png
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-tests collection
2 |
3 | API Collection to run sanity tests on Bruno CLI.
4 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "none",
3 | "tabWidth": 2,
4 | "semi": true,
5 | "singleQuote": true,
6 | "printWidth": 120
7 | }
8 |
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/mac/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/mac/icon.icns
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/16x16.png
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/24x24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/24x24.png
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/32x32.png
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/48x48.png
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/64x64.png
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/win/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/win/icon.ico
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/tests/fixtures/env.bru:
--------------------------------------------------------------------------------
1 | vars
2 | 1 host https://www.google.com
3 | 1 jwt secret
4 | 0 Content-type application/json
5 | /vars
6 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/themes/index.js:
--------------------------------------------------------------------------------
1 | import light from './light';
2 | import dark from './dark';
3 |
4 | export default {
5 | light,
6 | dark
7 | };
8 |
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/128x128.png
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/256x256.png
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/512x512.png
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/icons/png/1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PDDStudio/bruno/main/packages/bruno-electron/resources/icons/png/1024x1024.png
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/src/index.ts:
--------------------------------------------------------------------------------
1 | import { DocExplorer } from './components/DocExplorer';
2 |
3 | import './index.css';
4 |
5 | export { DocExplorer };
6 |
--------------------------------------------------------------------------------
/packages/bruno-app/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "none",
3 | "tabWidth": 2,
4 | "semi": true,
5 | "singleQuote": true,
6 | "printWidth": 120
7 | }
8 |
--------------------------------------------------------------------------------
/packages/bruno-query/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('ts-jest').JestConfigWithTsJest} */
2 | module.exports = {
3 | preset: 'ts-jest',
4 | testEnvironment: 'node',
5 | };
--------------------------------------------------------------------------------
/packages/bruno-common/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('ts-jest').JestConfigWithTsJest} */
2 | module.exports = {
3 | preset: 'ts-jest',
4 | testEnvironment: 'node'
5 | };
6 |
--------------------------------------------------------------------------------
/packages/bruno-js/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-js
2 |
3 | Provides the script, test, vars and assert runtimes.
4 |
5 | ### Publish to Npm Registry
6 | ```bash
7 | npm publish --access=public
8 | ```
--------------------------------------------------------------------------------
/packages/bruno-lang/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-lang
2 |
3 | The language utils for working with `.bru` files
4 |
5 | ### Publish to Npm Registry
6 | ```bash
7 | npm publish --access=public
8 | ```
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div``;
4 |
5 | export default Wrapper;
6 |
--------------------------------------------------------------------------------
/packages/bruno-electron/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | web
3 | out
4 | dist
5 | .env
6 |
7 | // certs
8 | sectigo.*
9 |
10 | pnpm-lock.yaml
11 | package-lock.json
12 | yarn.lock
13 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/methods/get/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
--------------------------------------------------------------------------------
/packages/bruno-app/public/theme/index.js:
--------------------------------------------------------------------------------
1 | import darkTheme from './dark';
2 | import lightTheme from './light';
3 |
4 | export default {
5 | Light: lightTheme,
6 | Dark: darkTheme
7 | };
8 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Tests/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div``;
4 |
5 | export default StyledWrapper;
6 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/FolderSettings/Tests/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div``;
4 |
5 | export default StyledWrapper;
6 |
--------------------------------------------------------------------------------
/packages/bruno-electron/src/about/about.css:
--------------------------------------------------------------------------------
1 | .versions {
2 | -webkit-user-select: text;
3 | user-select: text;
4 | }
5 | .title {
6 | -webkit-user-select: text;
7 | user-select: text;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/test-collection",
3 | "version": "0.0.1",
4 | "dependencies": {
5 | "@faker-js/faker": "^8.4.0"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/methods/delete/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Delete User'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'DELETE'
8 | url = 'https://reqres.in/api/users/2'
9 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestTabs/CollectionToolBar/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div``;
4 |
5 | export default StyledWrapper;
6 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/test-collection",
3 | "version": "0.0.1",
4 | "dependencies": {
5 | "@faker-js/faker": "^8.4.0"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/cookie/Login.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Login
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: {{host}}/api/auth/cookie/login
9 | body: none
10 | auth: none
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Preferences/Theme/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | color: var(--color-text);
5 | `;
6 |
7 | export default StyledWrapper;
8 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/cookie/Check.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Check
3 | type: http
4 | seq: 2
5 | }
6 |
7 | get {
8 | url: {{host}}/api/auth/cookie/protected
9 | body: none
10 | auth: none
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/echo/echo bom json.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: echo bom json
3 | type: http
4 | seq: 1
5 | }
6 |
7 | get {
8 | url: {{host}}/api/echo/bom-json-test
9 | body: none
10 | auth: none
11 | }
--------------------------------------------------------------------------------
/packages/bruno-docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/docs",
3 | "version": "0.0.1",
4 | "main": "src/index.js",
5 | "files": [
6 | "src",
7 | "package.json"
8 | ],
9 | "dependencies": {
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Preferences/Font/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | color: ${(props) => props.theme.text};
5 | `;
6 |
7 | export default StyledWrapper;
8 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Preferences/General/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | color: ${(props) => props.theme.text};
5 | `;
6 |
7 | export default StyledWrapper;
8 |
--------------------------------------------------------------------------------
/packages/bruno-common/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-common
2 |
3 | A collection of common utilities used across Bruno App, Electron and CLI packages.
4 |
5 | ### Publish to Npm Registry
6 |
7 | ```bash
8 | npm publish --access=public
9 | ```
10 |
--------------------------------------------------------------------------------
/packages/bruno-docs/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-docs
2 |
3 | This is a wip.
4 |
5 | We have a request to generate docs in a html file that can be hosted on a server so that the visitor can view the API and make requests without downloading/installing anything.
--------------------------------------------------------------------------------
/packages/bruno-electron/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-electron
2 |
3 | ```bash
4 | # electron dev
5 | npm start
6 |
7 | # generate pfx file for signing windows build
8 | openssl pkcs12 -export -inkey sectigo.key -in sectigo.pem -out sectigo.pfx
9 | ```
10 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-graphql-docs
2 |
3 | Standalone graphql docs explorer module forked from [graphiql](https://github.com/graphql/graphiql)
4 |
5 | ### Publish to Npm Registry
6 | ```bash
7 | npm publish --access=public
8 | ```
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/methods/get/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/assets/send.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v2/src/dotenvToJson.js:
--------------------------------------------------------------------------------
1 | const dotenv = require('dotenv');
2 |
3 | const parser = (input) => {
4 | const buf = Buffer.from(input);
5 | const parsed = dotenv.parse(buf);
6 | return parsed;
7 | };
8 |
9 | module.exports = parser;
10 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/CreateOrOpenCollection/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | color: ${(props) => props.theme.colors.text.muted};
5 | `;
6 |
7 | export default Wrapper;
8 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/utils/common/cache.js:
--------------------------------------------------------------------------------
1 | class Cache {
2 | get(key) {
3 | return window.localStorage.getItem(key);
4 | }
5 | set(key, val) {
6 | window.localStorage.setItem(key, val);
7 | }
8 | }
9 |
10 | module.exports = new Cache();
11 |
--------------------------------------------------------------------------------
/packages/bruno-app/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | darkMode: ['class'],
4 | content: ['./src/**/*.{js,jsx}'],
5 | prefix: '',
6 | theme: {
7 | extend: {}
8 | },
9 | plugins: []
10 | };
11 |
--------------------------------------------------------------------------------
/packages/bruno-schema/src/index.js:
--------------------------------------------------------------------------------
1 | const { collectionSchema, itemSchema, environmentSchema, environmentsSchema } = require('./collections');
2 |
3 | module.exports = {
4 | itemSchema,
5 | environmentSchema,
6 | environmentsSchema,
7 | collectionSchema
8 | };
9 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/test-collection",
3 | "version": "0.0.1",
4 | "dependencies": {
5 | "@faker-js/faker": "^8.4.0",
6 | "jsonwebtoken": "^9.0.2",
7 | "lru-map-cache": "^0.1.0"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/methods/delete/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Delete User",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "DELETE",
9 | "url": "https://reqres.in/api/users/2"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Vars/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.title {
5 | color: var(--color-tab-inactive);
6 | }
7 | `;
8 |
9 | export default StyledWrapper;
10 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/FolderSettings/Vars/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.title {
5 | color: var(--color-tab-inactive);
6 | }
7 | `;
8 |
9 | export default StyledWrapper;
10 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/providers/App/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | color: ${(props) => props.theme.text};
5 | background-color: ${(props) => props.theme.bg};
6 | `;
7 |
8 | export default StyledWrapper;
9 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/environments/Prod.bru:
--------------------------------------------------------------------------------
1 | vars {
2 | host: https://testbench-sanity.usebruno.com
3 | bearer_auth_token: your_secret_token
4 | basic_auth_password: della
5 | env.var1: envVar1
6 | env-var2: envVar2
7 | bark: {{process.env.PROC_ENV_VAR}}
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/scripts/pre-request/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [script]
11 | pre-request = '''
12 | req.body.id = uuid();
13 | '''
14 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/environments/Prod.bru:
--------------------------------------------------------------------------------
1 | vars {
2 | host: https://testbench-sanity.usebruno.com
3 | bearer_auth_token: your_secret_token
4 | basic_auth_password: della
5 | env.var1: envVar1
6 | env-var2: envVar2
7 | bark: {{process.env.PROC_ENV_VAR}}
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/empty-header/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [headers]
11 | Content-Type = 'application/json'
12 | Empty-Header = ''
13 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/simple-header/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [headers]
11 | Content-Type = 'application/json'
12 | Cookie = 'foo=bar'
13 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/unicode-in-header/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [headers]
11 | Content-Type = 'application/json'
12 | '🐶' = '🚀'
13 |
--------------------------------------------------------------------------------
/tests/utils/data-faker.js:
--------------------------------------------------------------------------------
1 | const { faker } = require('@faker-js/faker');
2 |
3 | export let randomWords = faker.random.words();
4 | export let randomVerb = faker.hacker.verb();
5 | export let randomHttpMethod = faker.internet.httpMethod();
6 | export let randomUrl = faker.internet.url();
7 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/environments/Prod.bru:
--------------------------------------------------------------------------------
1 | vars {
2 | host: https://testbench-sanity.usebruno.com
3 | bearer_auth_token: your_secret_token
4 | basic_auth_password: della
5 | env.var1: envVar1
6 | env-var2: envVar2
7 | bark: {{process.env.PROC_ENV_VAR}}
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/collection.bru:
--------------------------------------------------------------------------------
1 | headers {
2 | check: again
3 | }
4 |
5 | auth {
6 | mode: none
7 | }
8 |
9 | docs {
10 | # bruno-testbench 🐶
11 |
12 | This is a test collection that I am using to test various functionalities around bruno
13 | }
14 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/echo/echo xml raw.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: echo xml raw
3 | type: http
4 | seq: 4
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/xml-raw
9 | body: xml
10 | auth: none
11 | }
12 |
13 | body:xml {
14 | bruno
15 | }
16 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/spaces-in-header/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [headers]
11 | Content-Type = 'application/json'
12 | 'Spaces In Header' = ''
13 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Portal/index.js:
--------------------------------------------------------------------------------
1 | import { createPortal } from 'react-dom';
2 |
3 | function Portal({ children, wrapperId }) {
4 | wrapperId = wrapperId || 'bruno-app-body';
5 |
6 | return createPortal(children, document.getElementById(wrapperId));
7 | }
8 | export default Portal;
9 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseSave/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | font-size: 0.8125rem;
5 | color: ${(props) => props.theme.requestTabPanel.responseStatus};
6 | `;
7 |
8 | export default StyledWrapper;
9 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/RequestBody/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | div.CodeMirror {
5 | /* todo: find a better way */
6 | height: calc(100vh - 220px);
7 | }
8 | `;
9 |
10 | export default Wrapper;
11 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseClear/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | font-size: 0.8125rem;
5 | color: ${(props) => props.theme.requestTabPanel.responseStatus};
6 | `;
7 |
8 | export default StyledWrapper;
9 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RunCollectionItem/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | .bruno-modal-content {
5 | padding-bottom: 1rem;
6 | }
7 | `;
8 |
9 | export default Wrapper;
10 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Tests/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.CodeMirror {
5 | /* todo: find a better way */
6 | height: calc(100vh - 220px);
7 | }
8 | `;
9 |
10 | export default StyledWrapper;
11 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/dotted-header/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [headers]
11 | Content-Type = 'application/json'
12 | 'Dots.In.Header.Key' = 'Dots.In.Header.Value'
13 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseSize/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | font-size: 0.75rem;
5 | font-weight: 600;
6 | color: ${(props) => props.theme.requestTabPanel.responseStatus};
7 | `;
8 |
9 | export default Wrapper;
10 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseTime/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | font-size: 0.75rem;
5 | font-weight: 600;
6 | color: ${(props) => props.theme.requestTabPanel.responseStatus};
7 | `;
8 |
9 | export default Wrapper;
10 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/disabled-header/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [headers]
11 | Content-Type = 'application/json'
12 |
13 | [headers.disabled]
14 | Cookie = 'foo=bar'
15 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Info/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | table {
5 | td {
6 | &:first-child {
7 | width: 120px;
8 | }
9 | }
10 | }
11 | `;
12 |
13 | export default StyledWrapper;
14 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | .inherit-mode-text {
5 | color: ${(props) => props.theme.colors.text.yellow};
6 | }
7 | .inherit-mode-label {
8 | }
9 | `;
10 |
11 | export default Wrapper;
12 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/GraphQLVariables/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.CodeMirror {
5 | /* todo: find a better way */
6 | height: calc(100vh - 220px);
7 | }
8 | `;
9 |
10 | export default StyledWrapper;
11 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/scripts/pre-request/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "script": {
12 | "req": "req.body.id = uuid();"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/FolderSettings/Script/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.CodeMirror {
5 | height: inherit;
6 | }
7 |
8 | div.title {
9 | color: var(--color-tab-inactive);
10 | }
11 | `;
12 |
13 | export default StyledWrapper;
14 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Script/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.CodeMirror {
5 | height: inherit;
6 | }
7 |
8 | div.title {
9 | color: var(--color-tab-inactive);
10 | }
11 | `;
12 |
13 | export default StyledWrapper;
14 |
--------------------------------------------------------------------------------
/packages/bruno-common/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules
3 | yarn.lock
4 | pnpm-lock.yaml
5 | package-lock.json
6 | .pnp
7 | .pnp.js
8 |
9 | # testing
10 | coverage
11 |
12 | # production
13 | dist
14 |
15 | # misc
16 | .DS_Store
17 | *.pem
18 |
19 | # debug
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
--------------------------------------------------------------------------------
/packages/bruno-query/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules
3 | yarn.lock
4 | pnpm-lock.yaml
5 | package-lock.json
6 | .pnp
7 | .pnp.js
8 |
9 | # testing
10 | coverage
11 |
12 | # production
13 | dist
14 |
15 | # misc
16 | .DS_Store
17 | *.pem
18 |
19 | # debug
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
--------------------------------------------------------------------------------
/packages/bruno-schema/src/common/index.js:
--------------------------------------------------------------------------------
1 | const Yup = require('yup');
2 |
3 | const uidSchema = Yup.string()
4 | .length(21, 'uid must be 21 characters in length')
5 | .matches(/^[a-zA-Z0-9]*$/, 'uid must be alphanumeric')
6 | .required('uid is required')
7 | .strict();
8 |
9 | module.exports = {
10 | uidSchema
11 | };
12 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/scripts/tests/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [script]
11 | tests = '''
12 | test('Status code is 200', function () {
13 | expect(res.statusCode).to.eql(200);
14 | });
15 | '''
16 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Script/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.CodeMirror {
5 | height: inherit;
6 | }
7 |
8 | div.title {
9 | color: var(--color-tab-inactive);
10 | }
11 | `;
12 |
13 | export default StyledWrapper;
14 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules
3 | yarn.lock
4 | pnpm-lock.yaml
5 | package-lock.json
6 | .pnp
7 | .pnp.js
8 |
9 | # testing
10 | coverage
11 |
12 | # production
13 | dist
14 |
15 | # misc
16 | .DS_Store
17 | *.pem
18 |
19 | # debug
20 | npm-debug.log*
21 | yarn-debug.log*
22 | yarn-error.log*
23 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/scripts/post-response/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [script]
11 | post-response = '''
12 | bru.setVar('token', res.body.token);
13 | console.log('token: ' + res.body.token);
14 | '''
15 |
--------------------------------------------------------------------------------
/packages/bruno-schema/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/schema",
3 | "version": "0.7.0",
4 | "license": "MIT",
5 | "main": "src/index.js",
6 | "files": [
7 | "src",
8 | "package.json"
9 | ],
10 | "scripts": {
11 | "test": "jest"
12 | },
13 | "peerDependencies": {
14 | "yup": "^0.32.11"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/collection.bru:
--------------------------------------------------------------------------------
1 | headers {
2 | check: again
3 | }
4 |
5 | auth {
6 | mode: bearer
7 | }
8 |
9 | auth:bearer {
10 | token: {{bearer_auth_token}}
11 | }
12 |
13 | docs {
14 | # bruno-testbench 🐶
15 |
16 | This is a test collection that I am using to test various functionalities around bruno
17 | }
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Environments/EnvironmentSettings/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | button.btn-create-environment {
5 | &:hover {
6 | span {
7 | text-decoration: underline;
8 | }
9 | }
10 | }
11 | `;
12 |
13 | export default StyledWrapper;
14 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/Placeholder/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | padding-top: 20%;
5 | width: 100%;
6 |
7 | .send-icon {
8 | color: ${(props) => props.theme.requestTabPanel.responseSendIcon};
9 | }
10 | `;
11 |
12 | export default StyledWrapper;
13 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/resource.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: resource
3 | type: http
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: {{host}}/api/auth/oauth2/authorization_code/resource?token={{access_token_set_by_collection}}
9 | body: json
10 | auth: none
11 | }
12 |
13 | query {
14 | token: {{access_token_set_by_collection}}
15 | }
16 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/auth/oauth2/password_credentials/resource.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: resource
3 | type: http
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: {{host}}/api/auth/oauth2/password_credentials/resource
9 | body: none
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{passwordCredentials_access_token}}
15 | }
16 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/scripts/tests/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "tests": "test('Status code is 200', function () {\n expect(res.statusCode).to.eql(200);\n});"
12 | }
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yaml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: Discussions
4 | url: https://github.com/usebruno/bruno/discussions
5 | about: You can ask general questions or give feedback here.
6 | - name: Discord Server
7 | url: https://discord.com/invite/KgcZUncpjq
8 | about: Join our Discord community to chat about Bruno.
9 |
--------------------------------------------------------------------------------
/packages/bruno-electron/src/utils/cancel-token.js:
--------------------------------------------------------------------------------
1 | const cancelTokens = {};
2 |
3 | const saveCancelToken = (uid, abortController) => {
4 | cancelTokens[uid] = abortController;
5 | };
6 |
7 | const deleteCancelToken = (uid) => {
8 | delete cancelTokens[uid];
9 | };
10 |
11 | module.exports = {
12 | cancelTokens,
13 | saveCancelToken,
14 | deleteCancelToken
15 | };
16 |
--------------------------------------------------------------------------------
/packages/bruno-js/src/test-results.js:
--------------------------------------------------------------------------------
1 | const { nanoid } = require('nanoid');
2 |
3 | class TestResults {
4 | constructor() {
5 | this.results = [];
6 | }
7 |
8 | addResult(result) {
9 | result.uid = nanoid();
10 | this.results.push(result);
11 | }
12 |
13 | getResults() {
14 | return this.results;
15 | }
16 | }
17 |
18 | module.exports = TestResults;
19 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/auth/oauth2/authorization_code/resource.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: resource
3 | type: http
4 | seq: 3
5 | }
6 |
7 | post {
8 | url: {{host}}/api/auth/oauth2/authorization_code/resource?token={{authorization_code_access_token}}
9 | body: json
10 | auth: none
11 | }
12 |
13 | query {
14 | token: {{authorization_code_access_token}}
15 | }
--------------------------------------------------------------------------------
/packages/bruno-js/src/index.js:
--------------------------------------------------------------------------------
1 | const ScriptRuntime = require('./runtime/script-runtime');
2 | const TestRuntime = require('./runtime/test-runtime');
3 | const VarsRuntime = require('./runtime/vars-runtime');
4 | const AssertRuntime = require('./runtime/assert-runtime');
5 |
6 | module.exports = {
7 | ScriptRuntime,
8 | TestRuntime,
9 | VarsRuntime,
10 | AssertRuntime
11 | };
12 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/graphql/spacex.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: spacex
3 | type: graphql
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: https://spacex-production.up.railway.app/
9 | body: graphql
10 | auth: none
11 | }
12 |
13 | body:graphql {
14 | {
15 | company {
16 | ceo
17 | }
18 | }
19 |
20 | }
21 |
22 | assert {
23 | res.status: eq 200
24 | }
25 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/auth/oauth2/client_credentials/resource.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: resource
3 | type: http
4 | seq: 2
5 | }
6 |
7 | get {
8 | url: {{host}}/api/auth/oauth2/client_credentials/resource?token={{client_credentials_access_token}}
9 | body: none
10 | auth: none
11 | }
12 |
13 | query {
14 | token: {{client_credentials_access_token}}
15 | }
16 |
--------------------------------------------------------------------------------
/packages/bruno-toml/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/toml",
3 | "version": "0.1.0",
4 | "license": "MIT",
5 | "main": "src/index.js",
6 | "files": [
7 | "lib",
8 | "src",
9 | "package.json"
10 | ],
11 | "scripts": {
12 | "test": "jest"
13 | },
14 | "dependencies": {
15 | "@iarna/toml": "^2.2.5",
16 | "lodash": "^4.17.21"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/scripts/post-response/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "script": {
12 | "res": "bru.setVar('token', res.body.token);\nconsole.log('token: ' + res.body.token);"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/basic/via auth/Basic Auth 401.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Basic Auth 400
3 | type: http
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: {{host}}/api/auth/basic/protected
9 | body: json
10 | auth: none
11 | }
12 |
13 | auth:basic {
14 | username: bruno
15 | password: invalid
16 | }
17 |
18 | assert {
19 | res.status: 401
20 | res.body: Unauthorized
21 | }
22 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Cookies/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | table {
5 | width: 100%;
6 | table-layout: fixed;
7 |
8 | thead {
9 | color: ${(props) => props.theme.table.thead.color};
10 | font-size: 0.8125rem;
11 | user-select: none;
12 | }
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/src/tests-tag.js:
--------------------------------------------------------------------------------
1 | const { between, regex, everyCharUntil } = require('arcsecond');
2 |
3 | const testsBegin = regex(/^tests\s*\r?\n/);
4 | const testsEnd = regex(/^[\r?\n]+\/tests[\s\r?\n]*/);
5 |
6 | const testsTag = between(testsBegin)(testsEnd)(everyCharUntil(testsEnd)).map((tests) => {
7 | return {
8 | tests: tests
9 | };
10 | });
11 |
12 | module.exports = testsTag;
13 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/src/params-tag.js:
--------------------------------------------------------------------------------
1 | const { between, regex } = require('arcsecond');
2 | const keyValLines = require('./key-val-lines');
3 |
4 | const begin = regex(/^params\s*\r?\n/);
5 | const end = regex(/^[\r?\n]*\/params\s*[\r?\n]*/);
6 |
7 | const paramsTag = between(begin)(end)(keyValLines).map(([params]) => {
8 | return {
9 | params
10 | };
11 | });
12 |
13 | module.exports = paramsTag;
14 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/src/script-tag.js:
--------------------------------------------------------------------------------
1 | const { between, regex, everyCharUntil } = require('arcsecond');
2 |
3 | const scriptBegin = regex(/^script\s*\r?\n/);
4 | const scriptEnd = regex(/^[\r?\n]+\/script[\s\r?\n]*/);
5 |
6 | const scriptTag = between(scriptBegin)(scriptEnd)(everyCharUntil(scriptEnd)).map((script) => {
7 | return {
8 | script: script
9 | };
10 | });
11 |
12 | module.exports = scriptTag;
13 |
--------------------------------------------------------------------------------
/packages/bruno-electron/resources/entitlements.mac.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.cs.allow-jit
6 |
7 | com.apple.security.cs.allow-unsigned-executable-memory
8 |
9 |
10 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/src/headers-tag.js:
--------------------------------------------------------------------------------
1 | const { between, regex } = require('arcsecond');
2 | const keyValLines = require('./key-val-lines');
3 |
4 | const begin = regex(/^headers\s*\r?\n/);
5 | const end = regex(/^[\r?\n]*\/headers\s*[\r?\n]*/);
6 |
7 | const headersTag = between(begin)(end)(keyValLines).map(([headers]) => {
8 | return {
9 | headers
10 | };
11 | });
12 |
13 | module.exports = headersTag;
14 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/bruno.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "name": "collection_oauth2",
4 | "type": "collection",
5 | "scripts": {
6 | "moduleWhitelist": ["crypto"],
7 | "filesystemAccess": {
8 | "allow": true
9 | }
10 | },
11 | "clientCertificates": {
12 | "enabled": true,
13 | "certs": []
14 | },
15 | "presets": {
16 | "requestType": "http"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/preview/image/bruno.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: bruno
3 | type: http
4 | seq: 1
5 | }
6 |
7 | get {
8 | url: https://www.usebruno.com/images/landing-2.png
9 | body: none
10 | auth: none
11 | }
12 |
13 | tests {
14 | test("should return parsed xml", function() {
15 | const headers = res.getHeaders();
16 | expect(headers['content-type']).to.eql("image/png");
17 | });
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Spinner/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import StyledWrapper from './StyledWrapper';
3 |
4 | // Todo: Size, Color config support
5 | const Spinner = ({ size, color, children }) => {
6 | return (
7 |
8 |
9 | {children && {children}
}
10 |
11 | );
12 | };
13 |
14 | export default Spinner;
15 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/bruno.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "name": "collection_level_oauth2",
4 | "type": "collection",
5 | "scripts": {
6 | "moduleWhitelist": ["crypto"],
7 | "filesystemAccess": {
8 | "allow": true
9 | }
10 | },
11 | "clientCertificates": {
12 | "enabled": true,
13 | "certs": []
14 | },
15 | "presets": {
16 | "requestType": "http"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Icons/Send/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const SendIcon = ({ color, width }) => {
4 | return (
5 |
6 |
7 |
8 |
9 | );
10 | };
11 |
12 | export default SendIcon;
13 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Navbar/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .collection-dropdown {
5 | color: rgb(110 110 110);
6 |
7 | &:hover {
8 | color: inherit;
9 | }
10 |
11 | .tippy-box {
12 | top: -0.5rem;
13 | position: relative;
14 | user-select: none;
15 | }
16 | }
17 | `;
18 |
19 | export default StyledWrapper;
20 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/basic/via auth/Basic Auth 200.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Basic Auth 200
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: {{host}}/api/auth/basic/protected
9 | body: json
10 | auth: basic
11 | }
12 |
13 | auth:basic {
14 | username: bruno
15 | password: {{basic_auth_password}}
16 | }
17 |
18 | assert {
19 | res.status: 200
20 | res.body.message: Authentication successful
21 | }
22 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/inherit auth/inherit Bearer Auth 200.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: inherit Bearer Auth 200
3 | type: http
4 | seq: 2
5 | }
6 |
7 | get {
8 | url: {{host}}/api/auth/bearer/protected
9 | body: none
10 | auth: inherit
11 | }
12 |
13 | assert {
14 | res.status: 200
15 | res.body.message: Authentication successful
16 | }
17 |
18 | script:post-response {
19 | bru.setEnvVar("foo", "bar");
20 | }
21 |
--------------------------------------------------------------------------------
/packages/bruno-app/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | reactStrictMode: false,
3 | publicRuntimeConfig: {
4 | CI: process.env.CI,
5 | PLAYWRIGHT: process.env.PLAYWRIGHT,
6 | ENV: process.env.ENV
7 | },
8 | webpack: (config, { isServer }) => {
9 | // Fixes npm packages that depend on `fs` module
10 | if (!isServer) {
11 | config.resolve.fallback.fs = false;
12 | }
13 | return config;
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Environments/EnvironmentSettings/DeleteEnvironment/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | button.submit {
5 | color: white;
6 | background-color: var(--color-background-danger) !important;
7 | border: inherit !important;
8 |
9 | &:hover {
10 | border: inherit !important;
11 | }
12 | }
13 | `;
14 |
15 | export default Wrapper;
16 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/StatusCode/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | font-size: 0.75rem;
5 | font-weight: 600;
6 |
7 | &.text-ok {
8 | color: ${(props) => props.theme.requestTabPanel.responseOk};
9 | }
10 |
11 | &.text-error {
12 | color: ${(props) => props.theme.requestTabPanel.responseError};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/inputsConfig.js:
--------------------------------------------------------------------------------
1 | const inputsConfig = [
2 | {
3 | key: 'accessTokenUrl',
4 | label: 'Access Token URL'
5 | },
6 | {
7 | key: 'clientId',
8 | label: 'Client ID'
9 | },
10 | {
11 | key: 'clientSecret',
12 | label: 'Client Secret'
13 | },
14 | {
15 | key: 'scope',
16 | label: 'Scope'
17 | }
18 | ];
19 |
20 | export { inputsConfig };
21 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/hooks/usePrevious/index.js:
--------------------------------------------------------------------------------
1 | import { useRef, useEffect } from 'react';
2 |
3 | function usePrevious(value) {
4 | const ref = useRef();
5 |
6 | useEffect(() => {
7 | ref.current = value; //assign the value of ref to the argument
8 | }, [value]); //this code will run when the value of 'value' changes
9 |
10 | return ref.current; //in the end, return the current ref value.
11 | }
12 |
13 | export default usePrevious;
14 |
--------------------------------------------------------------------------------
/packages/bruno-lang/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/lang",
3 | "version": "0.12.0",
4 | "license": "MIT",
5 | "main": "src/index.js",
6 | "files": [
7 | "src",
8 | "v1",
9 | "v2",
10 | "package.json"
11 | ],
12 | "scripts": {
13 | "test": "jest"
14 | },
15 | "dependencies": {
16 | "arcsecond": "^5.0.0",
17 | "dotenv": "^16.3.1",
18 | "lodash": "^4.17.21",
19 | "ohm-js": "^16.6.0"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/ClientCredentials/inputsConfig.js:
--------------------------------------------------------------------------------
1 | const inputsConfig = [
2 | {
3 | key: 'accessTokenUrl',
4 | label: 'Access Token URL'
5 | },
6 | {
7 | key: 'clientId',
8 | label: 'Client ID'
9 | },
10 | {
11 | key: 'clientSecret',
12 | label: 'Client Secret'
13 | },
14 | {
15 | key: 'scope',
16 | label: 'Scope'
17 | }
18 | ];
19 |
20 | export { inputsConfig };
21 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/redirects/Test Redirect.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Test Redirect
3 | type: http
4 | seq: 2
5 | }
6 |
7 | get {
8 | url: {{host}}/redirect-to-ping
9 | body: none
10 | auth: none
11 | }
12 |
13 | assert {
14 | res.status: 200
15 | res.body: pong
16 | }
17 |
18 | tests {
19 | test("should redirect to ping", function() {
20 | const data = res.getBody();
21 | expect(data).to.equal('pong');
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/DeleteCollectionItem/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | button.submit {
5 | color: white;
6 | background-color: var(--color-background-danger) !important;
7 | border: inherit !important;
8 |
9 | &:hover {
10 | border: inherit !important;
11 | }
12 | }
13 | `;
14 |
15 | export default Wrapper;
16 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/utils/network/cancelTokens.js:
--------------------------------------------------------------------------------
1 | // we maintain cancel tokens for a request separately as redux does not recommend to store
2 | // non-serializable value in the store
3 |
4 | const cancelTokens = {};
5 |
6 | export default cancelTokens;
7 |
8 | export const saveCancelToken = (uid, axiosRequest) => {
9 | cancelTokens[uid] = axiosRequest;
10 | };
11 |
12 | export const deleteCancelToken = (uid) => {
13 | delete cancelTokens[uid];
14 | };
15 |
--------------------------------------------------------------------------------
/packages/bruno-cli/src/utils/common.js:
--------------------------------------------------------------------------------
1 | const lpad = (str, width) => {
2 | let paddedStr = str;
3 | while (paddedStr.length < width) {
4 | paddedStr = ' ' + paddedStr;
5 | }
6 | return paddedStr;
7 | };
8 |
9 | const rpad = (str, width) => {
10 | let paddedStr = str;
11 | while (paddedStr.length < width) {
12 | paddedStr = paddedStr + ' ';
13 | }
14 | return paddedStr;
15 | };
16 |
17 | module.exports = {
18 | lpad,
19 | rpad
20 | };
21 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/pages/index.js:
--------------------------------------------------------------------------------
1 | import Head from 'next/head';
2 | import Bruno from './Bruno';
3 | import GlobalStyle from '../globalStyles';
4 |
5 | export default function Home() {
6 | return (
7 |
8 |
9 |
Bruno
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/SaveRequest/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | .folder-list {
5 | border: 1px solid #ccc;
6 | border-radius: 5px;
7 |
8 | .folder-name {
9 | padding-block: 8px;
10 | padding-inline: 12px;
11 | cursor: pointer;
12 | &:hover {
13 | background-color: #e8e8e8;
14 | }
15 | }
16 | `;
17 |
18 | export default Wrapper;
19 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/preview/html/bruno.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: bruno
3 | type: http
4 | seq: 1
5 | }
6 |
7 | get {
8 | url: https://www.usebruno.com
9 | body: none
10 | auth: none
11 | }
12 |
13 | assert {
14 | res.status: eq 200
15 | }
16 |
17 | tests {
18 | test("should return parsed xml", function() {
19 | const headers = res.getHeaders();
20 | expect(headers['content-type']).to.eql("text/html; charset=utf-8");
21 | });
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Environments/EnvironmentSelector/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | .current-environment {
5 | background-color: ${(props) => props.theme.sidebar.badge.bg};
6 | border-radius: 15px;
7 |
8 | .caret {
9 | margin-left: 0.25rem;
10 | color: rgb(140, 140, 140);
11 | fill: rgb(140, 140, 140);
12 | }
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Preferences/Support/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | color: ${(props) => props.theme.text};
5 | .rows {
6 | svg {
7 | position: relative;
8 | top: -1px;
9 | }
10 |
11 | .label {
12 | cursor: pointer;
13 | &:hover {
14 | text-decoration: underline;
15 | }
16 | }
17 | }
18 | `;
19 |
20 | export default StyledWrapper;
21 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/reserved-header/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [headers]
11 | bru = '''
12 | [
13 | {
14 | "name": "disabled",
15 | "value": "foo",
16 | "enabled": true
17 | },
18 | {
19 | "name": "disabled-header-name",
20 | "value": "disabled-header-value",
21 | "enabled": false
22 | }
23 | ]
24 | '''
25 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/utils/tabs/index.js:
--------------------------------------------------------------------------------
1 | import find from 'lodash/find';
2 |
3 | export const isItemARequest = (item) => {
4 | return item.hasOwnProperty('request') && ['http-request', 'graphql-request'].includes(item.type);
5 | };
6 |
7 | export const isItemAFolder = (item) => {
8 | return !item.hasOwnProperty('request') && item.type === 'folder';
9 | };
10 |
11 | export const itemIsOpenedInTabs = (item, tabs) => {
12 | return find(tabs, (t) => t.uid === item.uid);
13 | };
14 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/duplicate-header/request.toml:
--------------------------------------------------------------------------------
1 | [meta]
2 | name = 'Get users'
3 | type = 'http'
4 | seq = 1
5 |
6 | [http]
7 | method = 'GET'
8 | url = 'https://reqres.in/api/users'
9 |
10 | [headers]
11 | bru = '''
12 | [
13 | {
14 | "name": "Content-Type",
15 | "value": "application/json",
16 | "enabled": true
17 | },
18 | {
19 | "name": "Content-Type",
20 | "value": "application/ld+json",
21 | "enabled": true
22 | }
23 | ]
24 | '''
25 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/BrunoSupport/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | color: ${(props) => props.theme.text};
5 | .collection-options {
6 | svg {
7 | position: relative;
8 | top: -1px;
9 | }
10 |
11 | .label {
12 | cursor: pointer;
13 | &:hover {
14 | text-decoration: underline;
15 | }
16 | }
17 | }
18 | `;
19 |
20 | export default StyledWrapper;
21 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/TestResults/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .test-success {
5 | color: ${(props) => props.theme.colors.text.green};
6 | }
7 |
8 | .test-failure {
9 | color: ${(props) => props.theme.colors.text.danger};
10 | }
11 |
12 | .error-message {
13 | color: ${(props) => props.theme.colors.text.muted};
14 | }
15 | `;
16 |
17 | export default StyledWrapper;
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/TitleBar/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .collection-dropdown {
5 | color: ${(props) => props.theme.sidebar.dropdownIcon.color};
6 |
7 | &:hover {
8 | color: inherit;
9 | }
10 |
11 | .tippy-box {
12 | top: -0.5rem;
13 | position: relative;
14 | user-select: none;
15 | }
16 | }
17 | `;
18 |
19 | export default StyledWrapper;
20 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/bearer/via auth/Bearer Auth 200.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Bearer Auth 200
3 | type: http
4 | seq: 1
5 | }
6 |
7 | get {
8 | url: {{host}}/api/auth/bearer/protected
9 | body: none
10 | auth: bearer
11 | }
12 |
13 | auth:bearer {
14 | token: {{bearer_auth_token}}
15 | }
16 |
17 | assert {
18 | res.status: 200
19 | res.body.message: Authentication successful
20 | }
21 |
22 | script:post-response {
23 | bru.setEnvVar("foo", "bar");
24 | }
25 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/AwsV4Auth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 |
8 | .single-line-editor-wrapper {
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/BasicAuth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 |
8 | .single-line-editor-wrapper {
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/BearerAuth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 |
8 | .single-line-editor-wrapper {
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/DigestAuth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 |
8 | .single-line-editor-wrapper {
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Documentation/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.CodeMirror {
5 | /* todo: find a better way */
6 | height: calc(100vh - 240px);
7 |
8 | .CodeMirror-scroll {
9 | padding-bottom: 0px;
10 | }
11 | }
12 | .editing-mode {
13 | cursor: pointer;
14 | color: ${(props) => props.theme.colors.text.yellow};
15 | }
16 | `;
17 |
18 | export default StyledWrapper;
19 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/GoldenEdition/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | color: ${(props) => props.theme.text};
5 | .collection-options {
6 | svg {
7 | position: relative;
8 | top: -1px;
9 | }
10 |
11 | .label {
12 | cursor: pointer;
13 | &:hover {
14 | text-decoration: underline;
15 | }
16 | }
17 | }
18 | `;
19 |
20 | export default StyledWrapper;
21 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Spinner/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .spinner {
5 | display: inline-block;
6 | width: 2rem;
7 | height: 2rem;
8 | vertical-align: text-bottom;
9 | border: 0.25em solid currentColor;
10 | border-right-color: transparent;
11 | border-radius: 50%;
12 | animation: spinner-border 0.75s linear infinite;
13 | }
14 | `;
15 |
16 | export default StyledWrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/echo/echo plaintext.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: echo plaintext
3 | type: http
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/text
9 | body: text
10 | auth: none
11 | }
12 |
13 | body:text {
14 | hello
15 | }
16 |
17 | assert {
18 | res.status: eq 200
19 | }
20 |
21 | tests {
22 | test("should return plain text", function() {
23 | const data = res.getBody();
24 | expect(res.getBody()).to.eql("hello");
25 | });
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/packages/bruno-cli/src/reporters/html.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const makeHtmlOutput = async (results, outputPath) => {
5 | const resultsJson = JSON.stringify(results, null, 2);
6 |
7 | const reportPath = path.join(__dirname, 'html-template.html');
8 | const template = fs.readFileSync(reportPath, 'utf8');
9 |
10 | fs.writeFileSync(outputPath, template.replace('__RESULTS_JSON__', resultsJson));
11 | };
12 |
13 | module.exports = makeHtmlOutput;
14 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Docs/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.CodeMirror {
5 | /* todo: find a better way */
6 | height: calc(100vh - 240px);
7 |
8 | .CodeMirror-scroll {
9 | padding-bottom: 0px;
10 | }
11 | }
12 | .editing-mode {
13 | cursor: pointer;
14 | color: ${(props) => props.theme.colors.text.yellow};
15 | }
16 | `;
17 |
18 | export default StyledWrapper;
19 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 | .single-line-editor-wrapper {
8 | max-width: 400px;
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 | .single-line-editor-wrapper {
8 | max-width: 400px;
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/AwsV4Auth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 |
8 | .single-line-editor-wrapper {
9 | max-width: 400px;
10 | padding: 0.15rem 0.4rem;
11 | border-radius: 3px;
12 | border: solid 1px ${(props) => props.theme.input.border};
13 | background-color: ${(props) => props.theme.input.bg};
14 | }
15 | `;
16 |
17 | export default Wrapper;
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/BasicAuth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 |
8 | .single-line-editor-wrapper {
9 | max-width: 400px;
10 | padding: 0.15rem 0.4rem;
11 | border-radius: 3px;
12 | border: solid 1px ${(props) => props.theme.input.border};
13 | background-color: ${(props) => props.theme.input.bg};
14 | }
15 | `;
16 |
17 | export default Wrapper;
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/BearerAuth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 |
8 | .single-line-editor-wrapper {
9 | max-width: 400px;
10 | padding: 0.15rem 0.4rem;
11 | border-radius: 3px;
12 | border: solid 1px ${(props) => props.theme.input.border};
13 | background-color: ${(props) => props.theme.input.bg};
14 | }
15 | `;
16 |
17 | export default Wrapper;
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/DigestAuth/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 |
8 | .single-line-editor-wrapper {
9 | max-width: 400px;
10 | padding: 0.15rem 0.4rem;
11 | border-radius: 3px;
12 | border: solid 1px ${(props) => props.theme.input.border};
13 | background-color: ${(props) => props.theme.input.bg};
14 | }
15 | `;
16 |
17 | export default Wrapper;
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/GenerateCodeItem/CodeView/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | position: relative;
5 |
6 | .copy-to-clipboard {
7 | position: absolute;
8 | cursor: pointer;
9 | top: 10px;
10 | right: 10px;
11 | z-index: 10;
12 | opacity: 0.5;
13 |
14 | &:hover {
15 | opacity: 1;
16 | }
17 | }
18 | `;
19 |
20 | export default StyledWrapper;
21 |
--------------------------------------------------------------------------------
/packages/bruno-electron/src/store/bruno-config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This modules stores the configs loaded from bruno.json
3 | */
4 |
5 | const config = {};
6 |
7 | // collectionUid is a hash based on the collection path)
8 | const getBrunoConfig = (collectionUid) => {
9 | return config[collectionUid] || {};
10 | };
11 |
12 | const setBrunoConfig = (collectionUid, brunoConfig) => {
13 | config[collectionUid] = brunoConfig;
14 | };
15 |
16 | module.exports = {
17 | getBrunoConfig,
18 | setBrunoConfig
19 | };
20 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/unicode-in-header/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "headers": [
12 | {
13 | "name": "Content-Type",
14 | "value": "application/json",
15 | "enabled": true
16 | },
17 | {
18 | "name": "🐶",
19 | "value": "🚀",
20 | "enabled": true
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.collection {
5 | padding: 4px 6px;
6 | padding-left: 8px;
7 | display: flex;
8 | align-items: center;
9 | border-radius: 3px;
10 | cursor: pointer;
11 |
12 | &:hover {
13 | background-color: ${(props) => props.theme.plainGrid.hoverBg};
14 | }
15 | }
16 | `;
17 |
18 | export default StyledWrapper;
19 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/empty-header/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "headers": [
12 | {
13 | "name": "Content-Type",
14 | "value": "application/json",
15 | "enabled": true
16 | },
17 | {
18 | "name": "Empty-Header",
19 | "value": "",
20 | "enabled": true
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/simple-header/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "headers": [
12 | {
13 | "name": "Content-Type",
14 | "value": "application/json",
15 | "enabled": true
16 | },
17 | {
18 | "name": "Cookie",
19 | "value": "foo=bar",
20 | "enabled": true
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 | .single-line-editor-wrapper {
8 | max-width: 400px;
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/ClientCredentials/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 | .single-line-editor-wrapper {
8 | max-width: 400px;
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 | .single-line-editor-wrapper {
8 | max-width: 400px;
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/VariablesEditor/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | table {
5 | thead,
6 | td {
7 | border: 1px solid ${(props) => props.theme.table.border};
8 |
9 | li {
10 | background-color: ${(props) => props.theme.bg} !important;
11 | }
12 | }
13 | }
14 |
15 | .muted {
16 | color: ${(props) => props.theme.colors.text.muted};
17 | }
18 | `;
19 |
20 | export default StyledWrapper;
21 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/disabled-header/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "headers": [
12 | {
13 | "name": "Content-Type",
14 | "value": "application/json",
15 | "enabled": true
16 | },
17 | {
18 | "name": "Cookie",
19 | "value": "foo=bar",
20 | "enabled": false
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/spaces-in-header/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "headers": [
12 | {
13 | "name": "Content-Type",
14 | "value": "application/json",
15 | "enabled": true
16 | },
17 | {
18 | "name": "Spaces In Header",
19 | "value": "",
20 | "enabled": true
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/AuthorizationCode/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 | .single-line-editor-wrapper {
8 | max-width: 400px;
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/ClientCredentials/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 | .single-line-editor-wrapper {
8 | max-width: 400px;
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/PasswordCredentials/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | label {
5 | font-size: 0.8125rem;
6 | }
7 | .single-line-editor-wrapper {
8 | max-width: 400px;
9 | padding: 0.15rem 0.4rem;
10 | border-radius: 3px;
11 | border: solid 1px ${(props) => props.theme.input.border};
12 | background-color: ${(props) => props.theme.input.bg};
13 | }
14 | `;
15 |
16 | export default Wrapper;
17 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/reserved-header/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "headers": [
12 | {
13 | "name": "disabled",
14 | "value": "foo",
15 | "enabled": true
16 | },
17 | {
18 | "name": "disabled-header-name",
19 | "value": "disabled-header-value",
20 | "enabled": false
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/duplicate-header/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "headers": [
12 | {
13 | "name": "Content-Type",
14 | "value": "application/json",
15 | "enabled": true
16 | },
17 | {
18 | "name": "Content-Type",
19 | "value": "application/ld+json",
20 | "enabled": true
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/src/env-vars-tag.js:
--------------------------------------------------------------------------------
1 | const { between, regex } = require('arcsecond');
2 | const { each } = require('lodash');
3 | const keyValLines = require('./key-val-lines');
4 |
5 | const begin = regex(/^vars\s*\r?\n/);
6 | const end = regex(/^[\r?\n]*\/vars\s*[\r?\n]*/);
7 |
8 | const envVarsTag = between(begin)(end)(keyValLines).map(([variables]) => {
9 | each(variables, (variable) => {
10 | variable.type = 'text';
11 | });
12 |
13 | return {
14 | variables
15 | };
16 | });
17 |
18 | module.exports = envVarsTag;
19 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/redirects/Disable Redirect.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Disable Redirect
3 | type: http
4 | seq: 1
5 | }
6 |
7 | get {
8 | url: {{host}}/redirect-to-ping
9 | body: none
10 | auth: none
11 | }
12 |
13 | assert {
14 | res.status: 302
15 | }
16 |
17 | script:pre-request {
18 | req.setMaxRedirects(0);
19 | }
20 |
21 | tests {
22 | test("should disable redirect to ping", function() {
23 | const data = res.getBody();
24 | expect(data).to.equal('Found. Redirecting to /ping');
25 | });
26 | }
27 |
--------------------------------------------------------------------------------
/packages/bruno-toml/tests/headers/dotted-header/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "meta": {
3 | "name": "Get users",
4 | "type": "http",
5 | "seq": 1
6 | },
7 | "http": {
8 | "method": "GET",
9 | "url": "https://reqres.in/api/users"
10 | },
11 | "headers": [
12 | {
13 | "name": "Content-Type",
14 | "value": "application/json",
15 | "enabled": true
16 | },
17 | {
18 | "name": "Dots.In.Header.Key",
19 | "value": "Dots.In.Header.Value",
20 | "enabled": true
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/pages/Bruno/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | display: flex;
5 | width: 100%;
6 | height: 100%;
7 | min-height: 100vh;
8 | max-height: 100vh;
9 |
10 | &.is-dragging {
11 | cursor: col-resize !important;
12 | }
13 |
14 | section.main {
15 | display: flex;
16 |
17 | section.request-pane,
18 | section.response-pane {
19 | }
20 | }
21 |
22 | .fw-600 {
23 | font-weight: 600;
24 | }
25 | `;
26 |
27 | export default Wrapper;
28 |
--------------------------------------------------------------------------------
/packages/bruno-electron/src/preload.js:
--------------------------------------------------------------------------------
1 | const { ipcRenderer, contextBridge } = require('electron');
2 |
3 | contextBridge.exposeInMainWorld('ipcRenderer', {
4 | invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args),
5 | on: (channel, handler) => {
6 | // Deliberately strip event as it includes `sender`
7 | const subscription = (event, ...args) => handler(...args);
8 | ipcRenderer.on(channel, subscription);
9 |
10 | return () => {
11 | ipcRenderer.removeListener(channel, subscription);
12 | };
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/bearer/via headers/Bearer Auth 200.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Bearer Auth 200
3 | type: http
4 | seq: 1
5 | }
6 |
7 | get {
8 | url: {{host}}/api/auth/bearer/protected
9 | body: json
10 | auth: none
11 | }
12 |
13 | headers {
14 | Authorization: Bearer your_secret_token
15 | }
16 |
17 | vars:pre-request {
18 | a-c: foo
19 | }
20 |
21 | assert {
22 | res.status: 200
23 | res.body.message: Authentication successful
24 | }
25 |
26 | script:post-response {
27 | bru.setEnvVar("foo", "bar");
28 | }
29 |
--------------------------------------------------------------------------------
/packages/bruno-tests/src/auth/bearer.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 |
4 | const authenticateToken = (req, res, next) => {
5 | const token = req.header('Authorization');
6 |
7 | if (!token || token !== `Bearer your_secret_token`) {
8 | return res.status(401).json({ message: 'Unauthorized' });
9 | }
10 |
11 | next();
12 | };
13 |
14 | router.get('/protected', authenticateToken, (req, res) => {
15 | res.status(200).json({ message: 'Authentication successful' });
16 | });
17 |
18 | module.exports = router;
19 |
--------------------------------------------------------------------------------
/packages/bruno-common/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export const flattenObject = (obj: Record, parentKey: string = ''): Record => {
2 | return Object.entries(obj).reduce((acc: Record, [key, value]: [string, any]) => {
3 | const newKey = parentKey ? (Array.isArray(obj) ? `${parentKey}[${key}]` : `${parentKey}.${key}`) : key;
4 | if (typeof value === 'object' && value !== null) {
5 | Object.assign(acc, flattenObject(value, newKey));
6 | } else {
7 | acc[newKey] = value;
8 | }
9 | return acc;
10 | }, {});
11 | };
12 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/auth/oauth2/password_credentials/token.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: token
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url:
9 | body: none
10 | auth: oauth2
11 | }
12 |
13 | auth:oauth2 {
14 | grant_type: password
15 | access_token_url: {{password_credentials_access_token_url}}
16 | username: {{password_credentials_username}}
17 | password: {{password_credentials_password}}
18 | scope:
19 | }
20 |
21 | script:post-response {
22 | bru.setEnvVar('passwordCredentials_access_token', res.body.access_token);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-common/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "esModuleInterop": true,
5 | "strict": true,
6 | "skipLibCheck": true,
7 | "jsx": "react",
8 | "module": "ESNext",
9 | "declaration": true,
10 | "declarationDir": "types",
11 | "sourceMap": true,
12 | "outDir": "dist",
13 | "moduleResolution": "node",
14 | "emitDeclarationOnly": true,
15 | "allowSyntheticDefaultImports": true,
16 | "forceConsistentCasingInFileNames": true
17 | },
18 | "exclude": ["dist", "node_modules", "tests"]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/bruno-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 | pnpm-lock.yaml
8 | package-lock.json
9 | yarn.lock
10 |
11 | # testing
12 | coverage
13 |
14 | # production
15 | build
16 |
17 | # misc
18 | .DS_Store
19 | *.pem
20 |
21 | # debug
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | # local env files
27 | .env.local
28 | .env.development.local
29 | .env.test.local
30 | .env.production.local
31 |
32 | # next.js
33 | .next/
34 | out/
35 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | .collections-badge {
5 | margin-inline: 0.5rem;
6 | background-color: ${(props) => props.theme.sidebar.badge.bg};
7 | border-radius: 5px;
8 |
9 | .caret {
10 | margin-left: 0.25rem;
11 | color: rgb(140, 140, 140);
12 | fill: rgb(140, 140, 140);
13 | }
14 | }
15 |
16 | span.close-icon {
17 | color: ${(props) => props.theme.colors.text.muted};
18 | }
19 | `;
20 |
21 | export default Wrapper;
22 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/PasswordCredentials/inputsConfig.js:
--------------------------------------------------------------------------------
1 | const inputsConfig = [
2 | {
3 | key: 'accessTokenUrl',
4 | label: 'Access Token URL'
5 | },
6 | {
7 | key: 'username',
8 | label: 'Username'
9 | },
10 | {
11 | key: 'password',
12 | label: 'Password'
13 | },
14 | {
15 | key: 'clientId',
16 | label: 'Client ID'
17 | },
18 | {
19 | key: 'clientSecret',
20 | label: 'Client Secret'
21 | },
22 | {
23 | key: 'scope',
24 | label: 'Scope'
25 | }
26 | ];
27 |
28 | export { inputsConfig };
29 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/PasswordCredentials/inputsConfig.js:
--------------------------------------------------------------------------------
1 | const inputsConfig = [
2 | {
3 | key: 'accessTokenUrl',
4 | label: 'Access Token URL'
5 | },
6 | {
7 | key: 'username',
8 | label: 'Username'
9 | },
10 | {
11 | key: 'password',
12 | label: 'Password'
13 | },
14 | {
15 | key: 'clientId',
16 | label: 'Client ID'
17 | },
18 | {
19 | key: 'clientSecret',
20 | label: 'Client Secret'
21 | },
22 | {
23 | key: 'scope',
24 | label: 'Scope'
25 | }
26 | ];
27 |
28 | export { inputsConfig };
29 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "esModuleInterop": true,
4 | "strict": true,
5 | "skipLibCheck": true,
6 | "jsx": "react",
7 | "module": "ESNext",
8 | "declaration": true,
9 | "declarationDir": "types",
10 | "sourceMap": true,
11 | "outDir": "dist",
12 | "moduleResolution": "node",
13 | "emitDeclarationOnly": true,
14 | "allowSyntheticDefaultImports": true,
15 | "forceConsistentCasingInFileNames": true
16 | },
17 | "exclude": [
18 | "dist",
19 | "node_modules",
20 | "src/**/*.test.tsx"
21 | ],
22 | }
--------------------------------------------------------------------------------
/packages/bruno-tests/src/auth/basic.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 | const basicAuth = require('express-basic-auth');
4 |
5 | const users = {
6 | bruno: 'della'
7 | };
8 |
9 | const basicAuthMiddleware = basicAuth({
10 | users,
11 | challenge: true, // Sends a 401 Unauthorized response when authentication fails
12 | unauthorizedResponse: 'Unauthorized'
13 | });
14 |
15 | router.post('/protected', basicAuthMiddleware, (req, res) => {
16 | res.status(200).json({ message: 'Authentication successful' });
17 | });
18 |
19 | module.exports = router;
20 |
--------------------------------------------------------------------------------
/packages/bruno-query/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "esModuleInterop": true,
5 | "strict": true,
6 | "skipLibCheck": true,
7 | "jsx": "react",
8 | "module": "ESNext",
9 | "declaration": true,
10 | "declarationDir": "types",
11 | "sourceMap": true,
12 | "outDir": "dist",
13 | "moduleResolution": "node",
14 | "emitDeclarationOnly": true,
15 | "allowSyntheticDefaultImports": true,
16 | "forceConsistentCasingInFileNames": true
17 | },
18 | "exclude": [
19 | "dist",
20 | "node_modules",
21 | "tests"
22 | ],
23 | }
--------------------------------------------------------------------------------
/packages/bruno-app/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "jsx": "react",
4 | "target": "es2017",
5 | "allowSyntheticDefaultImports": false,
6 | "baseUrl": "./",
7 | "paths": {
8 | "assets/*": ["src/assets/*"],
9 | "components/*": ["src/components/*"],
10 | "hooks/*": ["src/hooks/*"],
11 | "themes/*": ["src/themes/*"],
12 | "api/*": ["src/api/*"],
13 | "pageComponents/*": ["src/pageComponents/*"],
14 | "providers/*": ["src/providers/*"],
15 | "utils/*": ["src/utils/*"]
16 | }
17 | },
18 | "exclude": ["node_modules", "dist"]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/auth/oauth2/client_credentials/token.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: token
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url:
9 | body: none
10 | auth: oauth2
11 | }
12 |
13 | auth:oauth2 {
14 | grant_type: client_credentials
15 | access_token_url: {{client_credentials_access_token_url}}
16 | client_id: {{client_credentials_client_id}}
17 | client_secret: {{client_credentials_client_secret}}
18 | scope: {{client_credentials_scope}}
19 | }
20 |
21 | script:post-response {
22 | bru.setEnvVar('client_credentials_access_token', res.body.access_token);
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/Timeline/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .line {
5 | white-space: pre-line;
6 | word-wrap: break-word;
7 | word-break: break-all;
8 | font-family: Inter, sans-serif !important;
9 |
10 | .arrow {
11 | opacity: 0.5;
12 | }
13 |
14 | &.request {
15 | color: ${(props) => props.theme.colors.text.green};
16 | }
17 |
18 | &.response {
19 | color: ${(props) => props.theme.colors.text.purple};
20 | }
21 | }
22 | `;
23 |
24 | export default StyledWrapper;
25 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/basic/via script/Basic Auth 401.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Basic Auth 401
3 | type: http
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: {{host}}/api/auth/basic/protected
9 | body: json
10 | auth: none
11 | }
12 |
13 | assert {
14 | res.status: 401
15 | res.body: Unauthorized
16 | }
17 |
18 | script:pre-request {
19 | const username = "bruno";
20 | const password = "invalid";
21 |
22 | const authString = `${username}:${password}`;
23 | const encodedAuthString = require('btoa')(authString);
24 |
25 | req.setHeader("Authorization", `Basic ${encodedAuthString}`);
26 | }
27 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/providers/ReduxStore/middlewares/debug/middleware.js:
--------------------------------------------------------------------------------
1 | import { createListenerMiddleware } from '@reduxjs/toolkit';
2 |
3 | const debugMiddleware = createListenerMiddleware();
4 |
5 | debugMiddleware.startListening({
6 | predicate: () => true, // it'll track every change
7 | effect: (action, listenerApi) => {
8 | console.debug('---redux action---');
9 | console.debug('action', action.type); // which action did it
10 | console.debug('action.payload', action.payload);
11 | console.debug(listenerApi.getState()); // the updated store
12 | }
13 | });
14 |
15 | export default debugMiddleware;
16 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Welcome/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .heading {
5 | color: ${(props) => props.theme.welcome.heading};
6 | font-size: 0.75rem;
7 | }
8 |
9 | .muted {
10 | color: ${(props) => props.theme.welcome.muted};
11 | }
12 |
13 | .collection-options {
14 | cursor: pointer;
15 |
16 | svg {
17 | position: relative;
18 | top: -1px;
19 | }
20 |
21 | .label {
22 | &:hover {
23 | text-decoration: underline;
24 | }
25 | }
26 | }
27 | `;
28 |
29 | export default StyledWrapper;
30 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/auth/basic/via script/Basic Auth 200.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: Basic Auth 200
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: {{host}}/api/auth/basic/protected
9 | body: json
10 | auth: none
11 | }
12 |
13 | assert {
14 | res.status: eq 200
15 | res.body.message: Authentication successful
16 | }
17 |
18 | script:pre-request {
19 | const username = "bruno";
20 | const password = "della";
21 |
22 | const authString = `${username}:${password}`;
23 | const encodedAuthString = require('btoa')(authString);
24 |
25 | req.setHeader("Authorization", `Basic ${encodedAuthString}`);
26 | }
27 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/echo/echo xml parsed.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: echo xml parsed
3 | type: http
4 | seq: 3
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/xml-parsed
9 | body: xml
10 | auth: none
11 | }
12 |
13 | body:xml {
14 |
15 | bruno
16 |
17 | }
18 |
19 | assert {
20 | res.status: eq 200
21 | }
22 |
23 | tests {
24 | test("should return parsed xml", function() {
25 | const data = res.getBody();
26 | expect(res.getBody()).to.eql({
27 | "hello": {
28 | "world": [
29 | "bruno"
30 | ]
31 | }
32 | });
33 | });
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/hooks/useLocalStorage/index.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 |
3 | export default function useLocalStorage(key, defaultValue) {
4 | const [value, setValue] = useState(() => {
5 | try {
6 | const saved = localStorage.getItem(key);
7 | if (saved !== null) {
8 | return JSON.parse(saved);
9 | }
10 | return defaultValue;
11 | } catch {
12 | return defaultValue;
13 | }
14 | });
15 |
16 | useEffect(() => {
17 | const rawValue = JSON.stringify(value);
18 | localStorage.setItem(key, rawValue);
19 | }, [key, value]);
20 |
21 | return [value, setValue];
22 | }
23 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/AuthMode/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | font-size: 0.8125rem;
5 |
6 | .auth-mode-selector {
7 | background: transparent;
8 |
9 | .auth-mode-label {
10 | color: ${(props) => props.theme.colors.text.yellow};
11 | }
12 |
13 | .dropdown-item {
14 | padding: 0.2rem 0.6rem !important;
15 | }
16 |
17 | .label-item {
18 | padding: 0.2rem 0.6rem !important;
19 | }
20 | }
21 |
22 | .caret {
23 | color: rgb(140, 140, 140);
24 | fill: rgb(140 140 140);
25 | }
26 | `;
27 |
28 | export default Wrapper;
29 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/src/components/DocExplorer/Directive.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2021 GraphQL Contributors.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | import React from 'react';
9 | import { DirectiveNode } from 'graphql';
10 |
11 | type DirectiveProps = {
12 | directive: DirectiveNode;
13 | };
14 |
15 | export default function Directive({ directive }: DirectiveProps) {
16 | return (
17 |
18 | {'@'}
19 | {directive.name.value}
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/AuthMode/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | font-size: 0.8125rem;
5 |
6 | .auth-mode-selector {
7 | background: transparent;
8 |
9 | .auth-mode-label {
10 | color: ${(props) => props.theme.colors.text.yellow};
11 | }
12 |
13 | .dropdown-item {
14 | padding: 0.2rem 0.6rem !important;
15 | }
16 |
17 | .label-item {
18 | padding: 0.2rem 0.6rem !important;
19 | }
20 | }
21 |
22 | .caret {
23 | color: rgb(140, 140, 140);
24 | fill: rgb(140 140 140);
25 | }
26 | `;
27 |
28 | export default Wrapper;
29 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Auth/OAuth2/AuthorizationCode/inputsConfig.js:
--------------------------------------------------------------------------------
1 | const inputsConfig = [
2 | {
3 | key: 'callbackUrl',
4 | label: 'Callback URL'
5 | },
6 | {
7 | key: 'authorizationUrl',
8 | label: 'Authorization URL'
9 | },
10 | {
11 | key: 'accessTokenUrl',
12 | label: 'Access Token URL'
13 | },
14 | {
15 | key: 'clientId',
16 | label: 'Client ID'
17 | },
18 | {
19 | key: 'clientSecret',
20 | label: 'Client Secret'
21 | },
22 | {
23 | key: 'scope',
24 | label: 'Scope'
25 | },
26 | {
27 | key: 'state',
28 | label: 'State'
29 | }
30 | ];
31 |
32 | export { inputsConfig };
33 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseTime/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import StyledWrapper from './StyledWrapper';
3 |
4 | const ResponseTime = ({ duration }) => {
5 | let durationToDisplay = '';
6 |
7 | if (duration > 1000) {
8 | // duration greater than a second
9 | let seconds = Math.floor(duration / 1000);
10 | let decimal = ((duration % 1000) / 1000) * 100;
11 | durationToDisplay = seconds + '.' + decimal.toFixed(0) + 's';
12 | } else {
13 | durationToDisplay = duration + 'ms';
14 | }
15 |
16 | return {durationToDisplay} ;
17 | };
18 | export default ResponseTime;
19 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/QueryUrl/HttpMethodSelector/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | font-size: 0.8125rem;
5 |
6 | .dropdown {
7 | width: 100%;
8 | }
9 |
10 | .method-selector {
11 | border-radius: 3px;
12 | min-width: 90px;
13 |
14 | .tippy-box {
15 | max-width: 150px !important;
16 | min-width: 110px !important;
17 | }
18 |
19 | .dropdown-item {
20 | padding: 0.25rem 0.6rem !important;
21 | }
22 | }
23 |
24 | .caret {
25 | color: rgb(140, 140, 140);
26 | fill: rgb(140 140 140);
27 | }
28 | `;
29 |
30 | export default Wrapper;
31 |
--------------------------------------------------------------------------------
/packages/bruno-js/src/interpolate-string.js:
--------------------------------------------------------------------------------
1 | const { interpolate } = require('@usebruno/common');
2 |
3 | const interpolateString = (
4 | str,
5 | { envVariables = {}, collectionVariables = {}, processEnvVars = {}, requestVariables = {} }
6 | ) => {
7 | if (!str || !str.length || typeof str !== 'string') {
8 | return str;
9 | }
10 |
11 | const combinedVars = {
12 | ...envVariables,
13 | ...requestVariables,
14 | ...collectionVariables,
15 | process: {
16 | env: {
17 | ...processEnvVars
18 | }
19 | }
20 | };
21 |
22 | return interpolate(str, combinedVars);
23 | };
24 |
25 | module.exports = {
26 | interpolateString
27 | };
28 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Auth/OAuth2/AuthorizationCode/inputsConfig.js:
--------------------------------------------------------------------------------
1 | const inputsConfig = [
2 | {
3 | key: 'callbackUrl',
4 | label: 'Callback URL'
5 | },
6 | {
7 | key: 'authorizationUrl',
8 | label: 'Authorization URL'
9 | },
10 | {
11 | key: 'accessTokenUrl',
12 | label: 'Access Token URL'
13 | },
14 | {
15 | key: 'clientId',
16 | label: 'Client ID'
17 | },
18 | {
19 | key: 'clientSecret',
20 | label: 'Client Secret'
21 | },
22 | {
23 | key: 'scope',
24 | label: 'Scope'
25 | },
26 | {
27 | key: 'state',
28 | label: 'State'
29 | }
30 | ];
31 |
32 | export { inputsConfig };
33 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_cn.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | [Deutsch](./publishing_de.md)
4 | | [Français](./publishing_fr.md)
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | [বাংলা](./publishing_bn.md)
7 | | [Română](./publishing_ro.md)
8 | | [Polski](./publishing_pl.md)
9 | | **简体中文**
10 | | [正體中文](./publishing_zhtw.md)
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### 将 Bruno 发布到新的包管理器
14 |
15 | 虽然我们的代码是开源的,每个人都可以使用,但我们恳请您在考虑在新的包管理器上发布之前与我们联系。作为 Bruno 的创建者,我拥有这个项目的 Bruno 商标并希望管理其发行。如果您希望看到它使用新的包管理器,请提交一个 GitHub issue。
16 |
17 | 虽然我们的大部分功能都是免费与开源的 (涵盖 REST 和 GraphQL APIs) ,但我们努力在开源原则和可持续性之间取得和谐的平衡 - https://github.com/usebruno/bruno/discussions/269
18 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_zhtw.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | [Deutsch](./publishing_de.md)
4 | | [Français](./publishing_fr.md)
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | [বাংলা](./publishing_bn.md)
7 | | [Română](./publishing_ro.md)
8 | | [Polski](./publishing_pl.md)
9 | | [简体中文](./publishing_cn.md)
10 | | **正體中文**
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### 將 Bruno 發佈到新的套件管理器
14 |
15 | 雖然我們的程式碼是開源的並且可供所有人使用,但我們懇請您在考慮在新的套件管理器上發布之前與我們聯繫。作為 Bruno 的創建者,我擁有這個專案的 Bruno 商標並希望管理其發行。如果您希望看到 Bruno 使用新的套件管理器,請提出一個 GitHub issue。
16 |
17 | 雖然我們的大部分功能都是免費和開源(涵蓋 REST 和 GraphQL APIs),但我們努力在開源的原則和永續性之間,取得和諧的平衡 - https://github.com/usebruno/bruno/discussions/269
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Dropdown/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Tippy from '@tippyjs/react';
3 | import StyledWrapper from './StyledWrapper';
4 |
5 | const Dropdown = ({ icon, children, onCreate, placement }) => {
6 | return (
7 |
8 |
18 | {icon}
19 |
20 |
21 | );
22 | };
23 |
24 | export default Dropdown;
25 |
--------------------------------------------------------------------------------
/packages/bruno-schema/src/utils/testUtils.js:
--------------------------------------------------------------------------------
1 | const { customAlphabet } = require('nanoid');
2 | const { expect } = require('@jest/globals');
3 |
4 | // a customized version of nanoid without using _ and -
5 | const uuid = () => {
6 | // https://github.com/ai/nanoid/blob/main/url-alphabet/index.js
7 | const urlAlphabet = 'useandom26T198340PX75pxJACKVERYMINDBUSHWOLFGQZbfghjklqvwyzrict';
8 | const customNanoId = customAlphabet(urlAlphabet, 21);
9 |
10 | return customNanoId();
11 | };
12 |
13 | const validationErrorWithMessages = (...errors) => {
14 | return expect.objectContaining({
15 | errors
16 | });
17 | };
18 |
19 | module.exports = {
20 | uuid,
21 | validationErrorWithMessages
22 | };
23 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseHeaders/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | table {
5 | width: 100%;
6 | border-collapse: collapse;
7 |
8 | thead {
9 | color: #777777;
10 | font-size: 0.75rem;
11 | font-weight: 600;
12 | text-transform: uppercase;
13 | }
14 |
15 | td {
16 | padding: 6px 10px;
17 |
18 | &.value {
19 | word-break: break-all;
20 | }
21 | }
22 |
23 | tbody {
24 | tr:nth-child(odd) {
25 | background-color: ${(props) => props.theme.table.striped};
26 | }
27 | }
28 | }
29 | `;
30 |
31 | export default Wrapper;
32 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseSize/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import StyledWrapper from './StyledWrapper';
3 |
4 | const ResponseSize = ({ size }) => {
5 | let sizeToDisplay = '';
6 |
7 | if (size > 1024) {
8 | // size is greater than 1kb
9 | let kb = Math.floor(size / 1024);
10 | let decimal = Math.round(((size % 1024) / 1024).toFixed(2) * 100);
11 | sizeToDisplay = kb + '.' + decimal + 'KB';
12 | } else {
13 | sizeToDisplay = size + 'B';
14 | }
15 |
16 | return (
17 |
18 | {sizeToDisplay}
19 |
20 | );
21 | };
22 | export default ResponseSize;
23 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/string interpolation/env vars.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: env vars
3 | type: http
4 | seq: 2
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/json
9 | body: json
10 | auth: none
11 | }
12 |
13 | auth:basic {
14 | username: asd
15 | password: j
16 | }
17 |
18 | auth:bearer {
19 | token:
20 | }
21 |
22 | body:json {
23 | {
24 | "envVar1": "{{env.var1}}",
25 | "envVar2": "{{env-var2}}"
26 | }
27 | }
28 |
29 | assert {
30 | res.status: eq 200
31 | }
32 |
33 | tests {
34 | test("should return json", function() {
35 | expect(res.getBody()).to.eql({
36 | "envVar1": "envVar1",
37 | "envVar2": "envVar2"
38 | });
39 | });
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/auth/oauth2/authorization_code/token with authorize.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: token with authorize
3 | type: http
4 | seq: 4
5 | }
6 |
7 | post {
8 | url:
9 | body: none
10 | auth: oauth2
11 | }
12 |
13 | auth:oauth2 {
14 | grant_type: authorization_code
15 | callback_url: {{authorization_code_callback_url}}
16 | authorization_url: {{authorization_code_authorize_url}}
17 | access_token_url: {{authorization_code_access_token_url}}
18 | client_id: {{client_id}}
19 | client_secret: {{client_secret}}
20 | scope:
21 | pkce: true
22 | }
23 |
24 | script:post-response {
25 | bru.setEnvVar('authorization_code_access_token', res.body.access_token);
26 | }
27 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/string interpolation/process env vars.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: process env vars
3 | type: http
4 | seq: 4
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/json
9 | body: json
10 | auth: none
11 | }
12 |
13 | auth:basic {
14 | username: asd
15 | password: j
16 | }
17 |
18 | auth:bearer {
19 | token:
20 | }
21 |
22 | body:json {
23 | {
24 | "bark": "{{bark}}",
25 | "bark2": "{{process.env.PROC_ENV_VAR}}"
26 | }
27 | }
28 |
29 | assert {
30 | res.status: eq 200
31 | }
32 |
33 | tests {
34 | test("should return json", function() {
35 | expect(res.getBody()).to.eql({
36 | "bark": "woof",
37 | "bark2": "woof"
38 | });
39 | });
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/Overlay/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | position: absolute;
5 | height: 100%;
6 | z-index: 1;
7 | background-color: ${(props) => props.theme.requestTabPanel.responseOverlayBg};
8 |
9 | div.overlay {
10 | height: 100%;
11 | z-index: 9;
12 | display: flex;
13 | flex-direction: column;
14 | align-items: center;
15 | padding-top: 20%;
16 | overflow: hidden;
17 | text-align: center;
18 |
19 | .loading-icon {
20 | transform: scaleY(-1);
21 | animation: rotateCounterClockwise 1s linear infinite;
22 | }
23 | }
24 | `;
25 |
26 | export default StyledWrapper;
27 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/src/utils.js:
--------------------------------------------------------------------------------
1 | // safely parse json
2 | const safeParseJson = (json) => {
3 | try {
4 | return JSON.parse(json);
5 | } catch (e) {
6 | return null;
7 | }
8 | };
9 |
10 | const indentString = (str) => {
11 | if (!str || !str.length) {
12 | return str || '';
13 | }
14 |
15 | return str
16 | .split('\n')
17 | .map((line) => ' ' + line)
18 | .join('\n');
19 | };
20 |
21 | const outdentString = (str) => {
22 | if (!str || !str.length) {
23 | return str || '';
24 | }
25 |
26 | return str
27 | .split('\n')
28 | .map((line) => line.replace(/^ /, ''))
29 | .join('\n');
30 | };
31 |
32 | module.exports = {
33 | safeParseJson,
34 | indentString,
35 | outdentString
36 | };
37 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/RequestBody/RequestBodyMode/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | font-size: 0.8125rem;
5 |
6 | .body-mode-selector {
7 | background: transparent;
8 | border-radius: 3px;
9 |
10 | .dropdown-item {
11 | padding: 0.2rem 0.6rem !important;
12 | padding-left: 1.5rem !important;
13 | }
14 |
15 | .label-item {
16 | padding: 0.2rem 0.6rem !important;
17 | }
18 |
19 | .selected-body-mode {
20 | color: ${(props) => props.theme.colors.text.yellow};
21 | }
22 | }
23 |
24 | .caret {
25 | color: rgb(140, 140, 140);
26 | fill: rgb(140 140 140);
27 | }
28 | `;
29 |
30 | export default Wrapper;
31 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/bruno.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1",
3 | "name": "bruno-testbench",
4 | "type": "collection",
5 | "proxy": {
6 | "enabled": false,
7 | "protocol": "http",
8 | "hostname": "{{proxyHostname}}",
9 | "port": 4000,
10 | "auth": {
11 | "enabled": false,
12 | "username": "anoop",
13 | "password": "password"
14 | },
15 | "bypassProxy": ""
16 | },
17 | "scripts": {
18 | "moduleWhitelist": ["crypto", "buffer"],
19 | "filesystemAccess": {
20 | "allow": true
21 | }
22 | },
23 | "clientCertificates": {
24 | "enabled": true,
25 | "certs": []
26 | },
27 | "presets": {
28 | "requestType": "http",
29 | "requestUrl": "http://localhost:6000"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/scripting/local modules/sum.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: sum
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/json
9 | body: json
10 | auth: none
11 | }
12 |
13 | body:json {
14 | {
15 | "a": 1,
16 | "b": 2
17 | }
18 | }
19 |
20 | assert {
21 | res.status: eq 200
22 | }
23 |
24 | script:pre-request {
25 | const math = require("./lib/math");
26 |
27 | const body = req.getBody();
28 | body.sum = body.a + body.b;
29 |
30 | req.setBody(body);
31 | }
32 |
33 | tests {
34 | test("should return json", function() {
35 | const data = res.getBody();
36 | expect(res.getBody()).to.eql({
37 | "a": 1,
38 | "b": 2,
39 | "sum": 3
40 | });
41 | });
42 | }
43 |
--------------------------------------------------------------------------------
/packages/bruno-lang/src/index.js:
--------------------------------------------------------------------------------
1 | const bruToJsonV2 = require('../v2/src/bruToJson');
2 | const jsonToBruV2 = require('../v2/src/jsonToBru');
3 | const bruToEnvJsonV2 = require('../v2/src/envToJson');
4 | const envJsonToBruV2 = require('../v2/src/jsonToEnv');
5 | const dotenvToJson = require('../v2/src/dotenvToJson');
6 |
7 | const collectionBruToJson = require('../v2/src/collectionBruToJson');
8 | const jsonToCollectionBru = require('../v2/src/jsonToCollectionBru');
9 |
10 | // Todo: remove V2 suffixes
11 | // Changes will have to be made to the CLI and GUI
12 |
13 | module.exports = {
14 | bruToJsonV2,
15 | jsonToBruV2,
16 | bruToEnvJsonV2,
17 | envJsonToBruV2,
18 |
19 | collectionBruToJson,
20 | jsonToCollectionBru,
21 |
22 | dotenvToJson
23 | };
24 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v2/tests/assert.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This test file is used to test the text parser.
3 | */
4 | const parser = require('../src/bruToJson');
5 |
6 | describe('assert parser', () => {
7 | it('should parse assert statement', () => {
8 | const input = `
9 | assert {
10 | res("data.airports").filter(a => a.code ==="BLR").name: "Bangalore International Airport"
11 | }
12 | `;
13 |
14 | const output = parser(input);
15 | const expected = {
16 | assertions: [
17 | {
18 | name: 'res("data.airports").filter(a => a.code ==="BLR").name',
19 | value: '"Bangalore International Airport"',
20 | enabled: true
21 | }
22 | ]
23 | };
24 | expect(output).toEqual(expected);
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/echo/echo json.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: echo json
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/json
9 | body: json
10 | auth: none
11 | }
12 |
13 | headers {
14 | foo: bar
15 | }
16 |
17 | auth:basic {
18 | username: asd
19 | password: j
20 | }
21 |
22 | auth:bearer {
23 | token:
24 | }
25 |
26 | body:json {
27 | {
28 | "hello": "bruno"
29 | }
30 | }
31 |
32 | assert {
33 | res.status: eq 200
34 | }
35 |
36 | script:pre-request {
37 | bru.setVar("foo", "foo-world-2");
38 | }
39 |
40 | tests {
41 | test("should return json", function() {
42 | const data = res.getBody();
43 | expect(res.getBody()).to.eql({
44 | "hello": "bruno"
45 | });
46 | });
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Preferences/ProxySettings/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .settings-label {
5 | width: 80px;
6 | }
7 |
8 | .textbox {
9 | border: 1px solid #ccc;
10 | padding: 0.15rem 0.45rem;
11 | box-shadow: none;
12 | outline: none;
13 | transition: border-color ease-in-out 0.1s;
14 | border-radius: 3px;
15 | background-color: ${(props) => props.theme.modal.input.bg};
16 | border: 1px solid ${(props) => props.theme.modal.input.border};
17 |
18 | &:focus {
19 | border: solid 1px ${(props) => props.theme.modal.input.focusBorder} !important;
20 | outline: none !important;
21 | }
22 | }
23 | `;
24 |
25 | export default StyledWrapper;
26 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RunnerResults/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | .item-path {
5 | .link {
6 | color: ${(props) => props.theme.textLink};
7 | }
8 | }
9 | .danger {
10 | color: ${(props) => props.theme.colors.text.danger};
11 | }
12 |
13 | .test-summary {
14 | color: ${(props) => props.theme.tabs.active.border};
15 | }
16 |
17 | /* test results */
18 | .test-success {
19 | color: ${(props) => props.theme.colors.text.green};
20 | }
21 |
22 | .test-failure {
23 | color: ${(props) => props.theme.colors.text.danger};
24 |
25 | .error-message {
26 | color: ${(props) => props.theme.colors.text.muted};
27 | }
28 | }
29 | `;
30 |
31 | export default Wrapper;
32 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_ja.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | [Deutsch](./publishing_de.md)
4 | | [Français](./publishing_fr.md)
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | [বাংলা](./publishing_bn.md)
7 | | [Română](./publishing_ro.md)
8 | | [Polski](./publishing_pl.md)
9 | | [简体中文](./publishing_cn.md)
10 | | [正體中文](./publishing_zhtw.md)
11 | | **日本語**
12 |
13 | ### Bruno を新しいパッケージマネージャに公開する場合の注意
14 |
15 | 私たちのソースコードはオープンソースで誰でも使用できますが、新しいパッケージマネージャで公開を検討する前に、私たちにご連絡ください。私は Bruno の製作者として、このプロジェクト「Bruno」の商標を保有しており、その配布を管理したいと考えています。もし新しいパッケージマネージャで Bruno を使いたい場合は、GitHub の issue を立ててください。
16 |
17 | 私たちの機能の大部分が無料でオープンソース(REST や GraphQL の API も含む)ですが、
18 | 私たちはオープンソースの原則と長期的な維持の間でよいバランスをとれるように努力しています- https://github.com/usebruno/bruno/discussions/269
19 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/auth/oauth2/authorization_code/github token with authorize.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: github token with authorize
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url:
9 | body: none
10 | auth: oauth2
11 | }
12 |
13 | auth:oauth2 {
14 | grant_type: authorization_code
15 | callback_url: {{authorization_code_callback_url}}
16 | authorization_url: {{authorization_code_github_authorize_url}}
17 | access_token_url: {{authorization_code_github_access_token_url}}
18 | client_id: {{authorization_code_github_client_id}}
19 | client_secret: {{authorization_code_github_client_secret}}
20 | scope: repo,gist
21 | }
22 |
23 | script:post-response {
24 | bru.setEnvVar('github_access_token',res.body.split('access_token=')[1]?.split('&scope')[0]);
25 | }
26 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/auth/oauth2/authorization_code/google token with authorize.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: google token with authorize
3 | type: http
4 | seq: 4
5 | }
6 |
7 | post {
8 | url:
9 | body: none
10 | auth: oauth2
11 | }
12 |
13 | auth:oauth2 {
14 | grant_type: authorization_code
15 | callback_url: {{authorization_code_callback_url}}
16 | authorization_url: {{authorization_code_google_auth_url}}
17 | access_token_url: {{authorization_code_google_access_token_url}}
18 | client_id: {{authorization_code_google_client_id}}
19 | client_secret: {{authorization_code_google_client_secret}}
20 | scope: {{authorization_code_google_scope}}
21 | }
22 |
23 | script:post-response {
24 | bru.setEnvVar('authorization_code_access_token', res.body.access_token);
25 | }
26 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/src/inline-tag.js:
--------------------------------------------------------------------------------
1 | const { sequenceOf, str, regex, choice, endOfInput, everyCharUntil } = require('arcsecond');
2 |
3 | const whitespace = regex(/^[ \t]*/);
4 | const newline = regex(/^\r?\n/);
5 | const newLineOrEndOfInput = choice([endOfInput, newline]);
6 |
7 | const inlineTag = sequenceOf([
8 | choice([str('type'), str('name'), str('method'), str('url'), str('seq'), str('body-mode')]),
9 | whitespace,
10 | choice([newline, everyCharUntil(newLineOrEndOfInput)])
11 | ]).map(([key, _, val]) => {
12 | if (val === '\n' || val === '\r\n') {
13 | val = '';
14 | }
15 |
16 | if (key === 'body-mode') {
17 | return {
18 | body: {
19 | mode: val
20 | }
21 | };
22 | }
23 |
24 | return { [key]: val };
25 | });
26 |
27 | module.exports = inlineTag;
28 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/src/utility/debounce.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2021 GraphQL Contributors.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | /**
9 | * Provided a duration and a function, returns a new function which is called
10 | * `duration` milliseconds after the last call.
11 | */
12 | export default function debounce any>(duration: number, fn: F) {
13 | let timeout: number | null;
14 | return function (this: any, ...args: Parameters) {
15 | if (timeout) {
16 | window.clearTimeout(timeout);
17 | }
18 | timeout = window.setTimeout(() => {
19 | timeout = null;
20 | fn.apply(this, args);
21 | }, duration);
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/providers/Toaster/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Toaster } from 'react-hot-toast';
3 | import { useTheme } from 'providers/Theme';
4 |
5 | export const ToastContext = React.createContext();
6 |
7 | export const ToastProvider = (props) => {
8 | const { storedTheme } = useTheme();
9 |
10 | const toastOptions = { duration: 2000 };
11 | if (storedTheme === 'dark') {
12 | toastOptions.style = {
13 | borderRadius: '10px',
14 | background: '#3d3d3d',
15 | color: '#fff'
16 | };
17 | }
18 |
19 | return (
20 |
21 |
22 | {props.children}
23 |
24 | );
25 | };
26 |
27 | export default ToastProvider;
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | bun.lockb
5 | node_modules
6 | yarn.lock
7 | pnpm-lock.yaml
8 | .pnp
9 | .pnp.js
10 | bun.lockb
11 | bun.lock
12 |
13 | # testing
14 | coverage
15 |
16 | # production
17 | build
18 | chrome-extension
19 | chrome-extension.pem
20 | chrome-extension.crx
21 | bruno.zip
22 | *.zip
23 |
24 | # misc
25 | .DS_Store
26 | *.pem
27 |
28 | # debug
29 | npm-debug.log*
30 | yarn-debug.log*
31 | yarn-error.log*
32 |
33 | # local env files
34 | .env.local
35 | .env.development.local
36 | .env.test.local
37 | .env.production.local
38 |
39 | # next.js
40 | /renderer
41 | /renderer/.next/
42 | /renderer/out/
43 | /test-results/
44 | /playwright-report/
45 | /playwright/.cache/
46 |
47 | #dev editor
48 | bruno.iml
49 | .idea
--------------------------------------------------------------------------------
/packages/bruno-app/src/assets/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/collection.bru:
--------------------------------------------------------------------------------
1 | headers {
2 | check: again
3 | }
4 |
5 | auth {
6 | mode: oauth2
7 | }
8 |
9 | auth:oauth2 {
10 | grant_type: authorization_code
11 | callback_url: {{authorization_code_callback_url}}
12 | authorization_url: {{authorization_code_authorize_url}}
13 | access_token_url: {{authorization_code_access_token_url}}
14 | client_id: {{client_id}}
15 | client_secret: {{client_secret}}
16 | scope:
17 | pkce: true
18 | }
19 |
20 | script:post-response {
21 | if(req.getAuthMode() == 'oauth2' && res.body.access_token) {
22 | bru.setEnvVar('access_token_set_by_collection',res.body.access_token)
23 | }
24 | }
25 |
26 | docs {
27 | # bruno-testbench 🐶
28 |
29 | This is a test collection that I am using to test various functionalities around bruno
30 | }
31 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/src/components/DocExplorer/types.ts:
--------------------------------------------------------------------------------
1 | import { MouseEvent } from 'react';
2 | import {
3 | GraphQLField,
4 | GraphQLInputField,
5 | GraphQLArgument,
6 | GraphQLObjectType,
7 | GraphQLInterfaceType,
8 | GraphQLInputObjectType,
9 | GraphQLType,
10 | GraphQLNamedType
11 | } from 'graphql';
12 |
13 | export type FieldType = GraphQLField<{}, {}, {}> | GraphQLInputField | GraphQLArgument;
14 |
15 | export type OnClickFieldFunction = (
16 | field: FieldType,
17 | type?: GraphQLObjectType | GraphQLInterfaceType | GraphQLInputObjectType | GraphQLType,
18 | event?: MouseEvent
19 | ) => void;
20 |
21 | export type OnClickTypeFunction = (type: GraphQLNamedType, event?: MouseEvent) => void;
22 |
23 | export type OnClickFieldOrTypeFunction = OnClickFieldFunction | OnClickTypeFunction;
24 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/Presets/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .settings-label {
5 | width: 110px;
6 | }
7 |
8 | .textbox {
9 | border: 1px solid #ccc;
10 | padding: 0.15rem 0.45rem;
11 | box-shadow: none;
12 | border-radius: 0px;
13 | outline: none;
14 | box-shadow: none;
15 | transition: border-color ease-in-out 0.1s;
16 | border-radius: 3px;
17 | background-color: ${(props) => props.theme.modal.input.bg};
18 | border: 1px solid ${(props) => props.theme.modal.input.border};
19 |
20 | &:focus {
21 | border: solid 1px ${(props) => props.theme.modal.input.focusBorder} !important;
22 | outline: none !important;
23 | }
24 | }
25 | `;
26 |
27 | export default StyledWrapper;
28 |
--------------------------------------------------------------------------------
/packages/bruno-tests/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-tests
2 |
3 | This package is used to test the Bruno CLI.
4 | We have a collection that sits in the `collection` directory.
5 |
6 | ### Test Server
7 |
8 | This will start the server on port 80 which exposes endpoints that the collection will hit.
9 |
10 | ```bash
11 | # install node dependencies
12 | npm install
13 |
14 | # start server
15 | npm start
16 | ```
17 |
18 | ### Run Bru CLI on Collection
19 |
20 | ```bash
21 | cd collection
22 |
23 | # run collection against local server
24 | node ../../bruno-cli/bin/bru.js run --env Local --output junit.xml --format junit
25 |
26 | # run collection against prod server hosted at https://testbench.usebruno.com
27 | node ../../bruno-cli/bin/bru.js run --env Prod --output junit.xml --format junit
28 | ```
29 |
30 | ### License
31 |
32 | [MIT](LICENSE)
33 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/CollectionSettings/ProxySettings/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .settings-label {
5 | width: 80px;
6 | }
7 |
8 | .textbox {
9 | border: 1px solid #ccc;
10 | padding: 0.15rem 0.45rem;
11 | box-shadow: none;
12 | border-radius: 0px;
13 | outline: none;
14 | box-shadow: none;
15 | transition: border-color ease-in-out 0.1s;
16 | border-radius: 3px;
17 | background-color: ${(props) => props.theme.modal.input.bg};
18 | border: 1px solid ${(props) => props.theme.modal.input.border};
19 |
20 | &:focus {
21 | border: solid 1px ${(props) => props.theme.modal.input.focusBorder} !important;
22 | outline: none !important;
23 | }
24 | }
25 | `;
26 |
27 | export default StyledWrapper;
28 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/StopWatch/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 |
3 | const StopWatch = ({ requestTimestamp }) => {
4 | const [milliseconds, setMilliseconds] = useState(0);
5 |
6 | const tickInterval = 200;
7 | const tick = () => {
8 | setMilliseconds(milliseconds + tickInterval);
9 | };
10 |
11 | useEffect(() => {
12 | let timerID = setInterval(() => tick(), tickInterval);
13 | return () => {
14 | clearInterval(timerID);
15 | };
16 | });
17 |
18 | useEffect(() => {
19 | setMilliseconds(Date.now() - requestTimestamp);
20 | }, [requestTimestamp]);
21 |
22 | if (milliseconds < 1000) {
23 | return 'Loading...';
24 | }
25 |
26 | let seconds = milliseconds / 1000;
27 | return {seconds.toFixed(1)}s ;
28 | };
29 |
30 | export default StopWatch;
31 |
--------------------------------------------------------------------------------
/packages/bruno-js/src/test.js:
--------------------------------------------------------------------------------
1 | const Test = (__brunoTestResults, chai) => async (description, callback) => {
2 | try {
3 | await callback();
4 | __brunoTestResults.addResult({ description, status: 'pass' });
5 | } catch (error) {
6 | console.log(chai.AssertionError);
7 | if (error instanceof chai.AssertionError) {
8 | const { message, actual, expected } = error;
9 | __brunoTestResults.addResult({
10 | description,
11 | status: 'fail',
12 | error: message,
13 | actual,
14 | expected
15 | });
16 | } else {
17 | __brunoTestResults.addResult({
18 | description,
19 | status: 'fail',
20 | error: error.message || 'An unexpected error occurred.'
21 | });
22 | }
23 | console.log(error);
24 | }
25 | };
26 |
27 | module.exports = Test;
28 |
--------------------------------------------------------------------------------
/packages/bruno-tests/src/auth/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 |
4 | const authBearer = require('./bearer');
5 | const authBasic = require('./basic');
6 | const authCookie = require('./cookie');
7 | const authOAuth2PasswordCredentials = require('./oauth2/passwordCredentials');
8 | const authOAuth2AuthorizationCode = require('./oauth2/authorizationCode');
9 | const authOAuth2ClientCredentials = require('./oauth2/clientCredentials');
10 |
11 | router.use('/oauth2/password_credentials', authOAuth2PasswordCredentials);
12 | router.use('/oauth2/authorization_code', authOAuth2AuthorizationCode);
13 | router.use('/oauth2/client_credentials', authOAuth2ClientCredentials);
14 | router.use('/bearer', authBearer);
15 | router.use('/basic', authBasic);
16 | router.use('/cookie', authCookie);
17 |
18 | module.exports = router;
19 |
--------------------------------------------------------------------------------
/packages/bruno-cli/src/index.js:
--------------------------------------------------------------------------------
1 | const yargs = require('yargs');
2 | const chalk = require('chalk');
3 |
4 | const { CLI_EPILOGUE, CLI_VERSION } = require('./constants');
5 |
6 | const printBanner = () => {
7 | console.log(chalk.yellow(`Bru CLI ${CLI_VERSION}`));
8 | };
9 |
10 | const run = async () => {
11 | const argLength = process.argv.length;
12 | const commandsToPrintBanner = ['--help', '-h'];
13 |
14 | if (argLength <= 2 || process.argv.find((arg) => commandsToPrintBanner.includes(arg))) {
15 | printBanner();
16 | }
17 |
18 | const { argv } = yargs
19 | .strict()
20 | .commandDir('commands')
21 | .epilogue(CLI_EPILOGUE)
22 | .usage('Usage: $0 [options]')
23 | .demandCommand(1, "Woof!! Let's play with some APIs!!")
24 | .help('h')
25 | .alias('h', 'help');
26 | };
27 |
28 | module.exports = {
29 | run
30 | };
31 |
--------------------------------------------------------------------------------
/packages/bruno-js/src/bruno-response.js:
--------------------------------------------------------------------------------
1 | class BrunoResponse {
2 | constructor(res) {
3 | this.res = res;
4 | this.status = res ? res.status : null;
5 | this.statusText = res ? res.statusText : null;
6 | this.headers = res ? res.headers : null;
7 | this.body = res ? res.data : null;
8 | this.responseTime = res ? res.responseTime : null;
9 | }
10 |
11 | getStatus() {
12 | return this.res ? this.res.status : null;
13 | }
14 |
15 | getHeader(name) {
16 | return this.res && this.res.headers ? this.res.headers[name] : null;
17 | }
18 |
19 | getHeaders() {
20 | return this.res ? this.res.headers : null;
21 | }
22 |
23 | getBody() {
24 | return this.res ? this.res.data : null;
25 | }
26 |
27 | getResponseTime() {
28 | return this.res ? this.res.responseTime : null;
29 | }
30 | }
31 |
32 | module.exports = BrunoResponse;
33 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.tabs {
5 | div.tab {
6 | padding: 6px 0px;
7 | border: none;
8 | border-bottom: solid 2px transparent;
9 | margin-right: 1.25rem;
10 | color: var(--color-tab-inactive);
11 | cursor: pointer;
12 |
13 | &:focus,
14 | &:active,
15 | &:focus-within,
16 | &:focus-visible,
17 | &:target {
18 | outline: none !important;
19 | box-shadow: none !important;
20 | }
21 |
22 | &.active {
23 | color: ${(props) => props.theme.tabs.active.color} !important;
24 | border-bottom: solid 2px ${(props) => props.theme.tabs.active.border} !important;
25 | }
26 | }
27 | }
28 | `;
29 |
30 | export default StyledWrapper;
31 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/HttpRequestPane/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.tabs {
5 | div.tab {
6 | padding: 6px 0px;
7 | border: none;
8 | border-bottom: solid 2px transparent;
9 | margin-right: 1.25rem;
10 | color: var(--color-tab-inactive);
11 | cursor: pointer;
12 |
13 | &:focus,
14 | &:active,
15 | &:focus-within,
16 | &:focus-visible,
17 | &:target {
18 | outline: none !important;
19 | box-shadow: none !important;
20 | }
21 |
22 | &.active {
23 | color: ${(props) => props.theme.tabs.active.color} !important;
24 | border-bottom: solid 2px ${(props) => props.theme.tabs.active.border} !important;
25 | }
26 | }
27 | }
28 | `;
29 |
30 | export default StyledWrapper;
31 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/src/components/DocExplorer/MarkdownContent.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2021 GraphQL Contributors.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | import React from 'react';
9 | import MD from 'markdown-it';
10 |
11 | type Maybe = T | null | undefined;
12 |
13 | const md = new MD({
14 | // render urls as links, à la github-flavored markdown
15 | linkify: true
16 | });
17 |
18 | type MarkdownContentProps = {
19 | markdown?: Maybe;
20 | className?: string;
21 | };
22 |
23 | export default function MarkdownContent({ markdown, className }: MarkdownContentProps) {
24 | if (!markdown) {
25 | return
;
26 | }
27 |
28 | return
;
29 | }
30 |
--------------------------------------------------------------------------------
/packages/bruno-electron/tests/network/authorize-user.spec.js:
--------------------------------------------------------------------------------
1 | const { matchesCallbackUrl } = require('../../src/ipc/network/authorize-user-in-window');
2 |
3 | describe('matchesCallbackUrl', () => {
4 | const testCases = [
5 | { url: 'https://random-url/endpoint', expected: false },
6 | { url: 'https://random-url/endpoint?code=abcd', expected: false },
7 | { url: 'https://callback.url/endpoint?code=abcd', expected: true },
8 | { url: 'https://callback.url/endpoint/?code=abcd', expected: true },
9 | { url: 'https://callback.url/random-endpoint/?code=abcd', expected: false }
10 | ];
11 |
12 | it.each(testCases)('$url - should be $expected', ({ url, expected }) => {
13 | let callBackUrl = 'https://callback.url/endpoint';
14 |
15 | let actual = matchesCallbackUrl(new URL(url), new URL(callBackUrl));
16 |
17 | expect(actual).toBe(expected);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/packages/bruno-query/readme.md:
--------------------------------------------------------------------------------
1 | # bruno-query
2 |
3 | Bruno query with deep navigation, filter and map support
4 |
5 | Easy array navigation
6 | ```js
7 | get(data, 'customer.orders.items.amount')
8 | ```
9 | Deep navigation .. double dots
10 | ```js
11 | get(data, '..items.amount')
12 | ```
13 | Array indexing
14 | ```js
15 | get(data, '..items[0].amount')
16 | ```
17 | Array filtering [?] with corresponding filter function
18 | ```js
19 | get(data, '..items[?].amount', i => i.amount > 20)
20 | ```
21 | Array filtering [?] with simple object predicate, same as (i => i.id === 2 && i.amount === 20)
22 | ```js
23 | get(data, '..items[?]', { id: 2, amount: 20 })
24 | ```
25 | Array mapping [?] with corresponding mapper function
26 | ```js
27 | get(data, '..items[?].amount', i => i.amount + 10)
28 | ```
29 |
30 | ### Publish to Npm Registry
31 | ```bash
32 | npm publish --access=public
33 | ```
34 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v2/tests/index.spec.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const bruToJson = require('../src/bruToJson');
4 | const jsonToBru = require('../src/jsonToBru');
5 |
6 | describe('bruToJson', () => {
7 | it('should parse the bru file', () => {
8 | const input = fs.readFileSync(path.join(__dirname, 'fixtures', 'request.bru'), 'utf8');
9 | const expected = require('./fixtures/request.json');
10 | const output = bruToJson(input);
11 |
12 | expect(output).toEqual(expected);
13 | });
14 | });
15 |
16 | describe('jsonToBru', () => {
17 | it('should parse the json file', () => {
18 | const input = require('./fixtures/request.json');
19 | const expected = fs.readFileSync(path.join(__dirname, 'fixtures', 'request.bru'), 'utf8');
20 | const output = jsonToBru(input);
21 |
22 | expect(output).toEqual(expected);
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/packages/bruno-js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/js",
3 | "version": "0.12.0",
4 | "license": "MIT",
5 | "main": "src/index.js",
6 | "files": [
7 | "src",
8 | "package.json"
9 | ],
10 | "peerDependencies": {
11 | "@n8n/vm2": "^3.9.23"
12 | },
13 | "scripts": {
14 | "test": "jest --testPathIgnorePatterns test.js"
15 | },
16 | "dependencies": {
17 | "@usebruno/common": "0.1.0",
18 | "@usebruno/query": "0.1.0",
19 | "ajv": "^8.12.0",
20 | "ajv-formats": "^2.1.1",
21 | "atob": "^2.1.2",
22 | "axios": "^1.5.1",
23 | "btoa": "^1.2.1",
24 | "chai": "^4.3.7",
25 | "chai-string": "^1.5.0",
26 | "crypto-js": "^4.1.1",
27 | "json-query": "^2.2.2",
28 | "lodash": "^4.17.21",
29 | "moment": "^2.29.4",
30 | "nanoid": "3.3.4",
31 | "node-fetch": "2.*",
32 | "node-vault": "^0.10.2",
33 | "uuid": "^9.0.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/string interpolation/missing values.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: missing values
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/json?foo={{undefinedVar}}
9 | body: json
10 | auth: none
11 | }
12 |
13 | query {
14 | foo: {{undefinedVar}}
15 | }
16 |
17 | auth:basic {
18 | username: asd
19 | password: j
20 | }
21 |
22 | auth:bearer {
23 | token:
24 | }
25 |
26 | body:json {
27 | {
28 | "hello": "{{undefinedVar2}}"
29 | }
30 | }
31 |
32 | assert {
33 | res.status: eq 200
34 | }
35 |
36 | tests {
37 | test("should return json", function() {
38 | const url = req.getUrl();
39 | const query = url.split("?")[1];
40 | expect(query).to.equal("foo={{undefinedVar}}");
41 |
42 | const data = res.getBody();
43 | expect(res.getBody()).to.eql({
44 | "hello": "{{undefinedVar2}}"
45 | });
46 | });
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 |
4 |
5 | ### Contribution Checklist:
6 |
7 | - [ ] **The pull request only addresses one issue or adds one feature.**
8 | - [ ] **The pull request does not introduce any breaking changes**
9 | - [ ] **I have added screenshots or gifs to help explain the change if applicable.**
10 | - [ ] **I have read the [contribution guidelines](https://github.com/usebruno/bruno/blob/main/contributing.md).**
11 | - [ ] **Create an issue and link to the pull request.**
12 |
13 | Note: Keeping the PR small and focused helps make it easier to review and merge. If you have multiple changes you want to make, please consider submitting them as separate pull requests.
14 |
15 | ### Publishing to New Package Managers
16 |
17 | Please see [here](../publishing.md) for more information.
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/NetworkError/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const NetworkError = ({ onClose }) => {
4 | return (
5 |
6 |
13 |
14 |
18 | Close
19 |
20 |
21 |
22 | );
23 | };
24 |
25 | export default NetworkError;
26 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v2/tests/fixtures/collection.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | type: collection
3 | }
4 |
5 | headers {
6 | content-type: application/json
7 | Authorization: Bearer 123
8 | ~transaction-id: {{transactionId}}
9 | }
10 |
11 | auth {
12 | mode: none
13 | }
14 |
15 | auth:basic {
16 | username: john
17 | password: secret
18 | }
19 |
20 | auth:bearer {
21 | token: 123
22 | }
23 |
24 | auth:digest {
25 | username: john
26 | password: secret
27 | }
28 |
29 | vars:pre-request {
30 | departingDate: 2020-01-01
31 | ~returningDate: 2020-01-02
32 | }
33 |
34 | vars:post-response {
35 | ~transactionId: $res.body.transactionId
36 | }
37 |
38 | script:pre-request {
39 | console.log("In Collection pre Request Script");
40 | }
41 |
42 | script:post-response {
43 | console.log("In Collection post Request Script");
44 | }
45 |
46 | docs {
47 | This request needs auth token to be set in the headers.
48 | }
49 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/FeatureRequest.yaml:
--------------------------------------------------------------------------------
1 | name: Feature Request
2 | description: Suggest an idea for this project.
3 | labels: ['enhancement']
4 | body:
5 | - type: checkboxes
6 | attributes:
7 | label: 'I have checked the following:'
8 | options:
9 | - label: I've searched existing issues and found nothing related to my issue.
10 | required: true
11 | - type: markdown
12 | attributes:
13 | value: |
14 | Suggest an idea for this project.
15 | - type: textarea
16 | attributes:
17 | label: Describe the feature you want to add
18 | description: A clear and concise description of the feature you want to be added.
19 | validations:
20 | required: true
21 | - type: textarea
22 | attributes:
23 | label: Mockups or Images of the feature
24 | description: Add some images to support your feature.
25 | validations:
26 | required: true
27 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseClear/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { IconEraser } from '@tabler/icons';
3 | import { useDispatch } from 'react-redux';
4 | import StyledWrapper from './StyledWrapper';
5 | import { responseCleared } from 'providers/ReduxStore/slices/collections/index';
6 |
7 | const ResponseClear = ({ collection, item }) => {
8 | const dispatch = useDispatch();
9 |
10 | const clearResponse = () =>
11 | dispatch(
12 | responseCleared({
13 | itemUid: item.uid,
14 | collectionUid: collection.uid,
15 | response: null
16 | })
17 | );
18 |
19 | return (
20 |
21 |
22 |
23 |
24 |
25 | );
26 | };
27 | export default ResponseClear;
28 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/StatusCode/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames';
3 | import statusCodePhraseMap from './get-status-code-phrase';
4 | import StyledWrapper from './StyledWrapper';
5 |
6 | // Todo: text-error class is not getting pulled in for 500 errors
7 | const StatusCode = ({ status }) => {
8 | const getTabClassname = (status) => {
9 | return classnames('ml-2', {
10 | 'text-ok': status >= 100 && status < 200,
11 | 'text-ok': status >= 200 && status < 300,
12 | 'text-error': status >= 300 && status < 400,
13 | 'text-error': status >= 400 && status < 500,
14 | 'text-error': status >= 500 && status < 600
15 | });
16 | };
17 |
18 | return (
19 |
20 | {status} {statusCodePhraseMap[status]}
21 |
22 | );
23 | };
24 | export default StatusCode;
25 |
--------------------------------------------------------------------------------
/packages/bruno-electron/src/ipc/notifications.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const { ipcMain } = require('electron');
3 | const fetch = require('node-fetch');
4 |
5 | const registerNotificationsIpc = (mainWindow, watcher) => {
6 | ipcMain.handle('renderer:fetch-notifications', async () => {
7 | try {
8 | const notifications = await fetchNotifications();
9 | return Promise.resolve(notifications);
10 | } catch (error) {
11 | return Promise.reject(error);
12 | }
13 | });
14 | };
15 |
16 | module.exports = registerNotificationsIpc;
17 |
18 | const fetchNotifications = async () => {
19 | try {
20 | let url = process.env.BRUNO_INFO_ENDPOINT || 'https://appinfo.usebruno.com';
21 | const data = await fetch(url).then((res) => res.json());
22 |
23 | return data?.notifications || [];
24 | } catch (error) {
25 | return Promise.reject('Error while fetching notifications!', error);
26 | }
27 | };
28 |
--------------------------------------------------------------------------------
/packages/bruno-query/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/query",
3 | "version": "0.1.0",
4 | "license" : "MIT",
5 | "main": "dist/cjs/index.js",
6 | "module": "dist/esm/index.js",
7 | "types": "dist/index.d.ts",
8 | "files": [
9 | "dist",
10 | "src",
11 | "package.json"
12 | ],
13 | "scripts": {
14 | "clean": "rimraf dist",
15 | "test": "jest",
16 | "prebuild": "npm run clean",
17 | "build": "rollup -c",
18 | "prepack": "npm run test && npm run build"
19 | },
20 | "devDependencies": {
21 | "@rollup/plugin-commonjs": "^23.0.2",
22 | "@rollup/plugin-node-resolve": "^15.0.1",
23 | "@rollup/plugin-typescript": "^9.0.2",
24 | "rollup": "3.2.5",
25 | "rollup-plugin-dts": "^5.0.0",
26 | "rollup-plugin-peer-deps-external": "^2.2.4",
27 | "rollup-plugin-terser": "^7.0.2",
28 | "typescript": "^4.8.4"
29 | },
30 | "overrides": {
31 | "rollup": "3.2.5"
32 | }
33 | }
--------------------------------------------------------------------------------
/packages/bruno-cli/tests/runner/prepare-request.spec.js:
--------------------------------------------------------------------------------
1 | const { describe, it, expect } = require('@jest/globals');
2 |
3 | const prepareRequest = require('../../src/runner/prepare-request');
4 |
5 | describe('prepare-request: prepareRequest', () => {
6 | describe('Decomments request body', () => {
7 | it('If request body is valid JSON', async () => {
8 | const body = { mode: 'json', json: '{\n"test": "{{someVar}}" // comment\n}' };
9 | const expected = { test: '{{someVar}}' };
10 | const result = prepareRequest({ body });
11 | expect(result.data).toEqual(expected);
12 | });
13 |
14 | it('If request body is not valid JSON', async () => {
15 | const body = { mode: 'json', json: '{\n"test": {{someVar}} // comment\n}' };
16 | const expected = '{\n"test": {{someVar}} \n}';
17 | const result = prepareRequest({ body });
18 | expect(result.data).toEqual(expected);
19 | });
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Preferences/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.tabs {
5 | margin-top: -0.5rem;
6 |
7 | div.tab {
8 | padding: 6px 0px;
9 | border: none;
10 | border-bottom: solid 2px transparent;
11 | margin-right: 1.25rem;
12 | color: var(--color-tab-inactive);
13 | cursor: pointer;
14 |
15 | &:focus,
16 | &:active,
17 | &:focus-within,
18 | &:focus-visible,
19 | &:target {
20 | outline: none !important;
21 | box-shadow: none !important;
22 | }
23 |
24 | &.active {
25 | color: ${(props) => props.theme.tabs.active.color} !important;
26 | border-bottom: solid 2px ${(props) => props.theme.tabs.active.border} !important;
27 | }
28 | }
29 | }
30 |
31 | section.tab-panel {
32 | min-height: 300px;
33 | }
34 | `;
35 |
36 | export default StyledWrapper;
37 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_oauth2/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/test-collection",
3 | "version": "0.0.1",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@usebruno/test-collection",
9 | "version": "0.0.1",
10 | "dependencies": {
11 | "@faker-js/faker": "^8.4.0"
12 | }
13 | },
14 | "node_modules/@faker-js/faker": {
15 | "version": "8.4.0",
16 | "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.4.0.tgz",
17 | "integrity": "sha512-htW87352wzUCdX1jyUQocUcmAaFqcR/w082EC8iP/gtkF0K+aKcBp0hR5Arb7dzR8tQ1TrhE9DNa5EbJELm84w==",
18 | "funding": [
19 | {
20 | "type": "opencollective",
21 | "url": "https://opencollective.com/fakerjs"
22 | }
23 | ],
24 | "engines": {
25 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0",
26 | "npm": ">=6.14.13"
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/utils/codegenerator/auth.js:
--------------------------------------------------------------------------------
1 | import get from 'lodash/get';
2 |
3 | export const getAuthHeaders = (collectionRootAuth, requestAuth) => {
4 | const auth = collectionRootAuth && ['inherit'].includes(requestAuth?.mode) ? collectionRootAuth : requestAuth;
5 |
6 | switch (auth.mode) {
7 | case 'basic':
8 | const username = get(auth, 'basic.username', '');
9 | const password = get(auth, 'basic.password', '');
10 | const basicToken = Buffer.from(`${username}:${password}`).toString('base64');
11 |
12 | return [
13 | {
14 | enabled: true,
15 | name: 'Authorization',
16 | value: `Basic ${basicToken}`
17 | }
18 | ];
19 | case 'bearer':
20 | return [
21 | {
22 | enabled: true,
23 | name: 'Authorization',
24 | value: `Bearer ${get(auth, 'bearer.token', '')}`
25 | }
26 | ];
27 | default:
28 | return [];
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/packages/bruno-electron/src/store/window-state.js:
--------------------------------------------------------------------------------
1 | const Store = require('electron-store');
2 |
3 | const DEFAULT_WINDOW_WIDTH = 1280;
4 | const DEFAULT_WINDOW_HEIGHT = 768;
5 |
6 | const DEFAULT_MAXIMIZED = false;
7 |
8 | class WindowStateStore {
9 | constructor() {
10 | this.store = new Store({
11 | name: 'preferences',
12 | clearInvalidConfig: true
13 | });
14 | }
15 |
16 | getBounds() {
17 | return (
18 | this.store.get('window-bounds') || {
19 | x: 0,
20 | y: 0,
21 | width: DEFAULT_WINDOW_WIDTH,
22 | height: DEFAULT_WINDOW_HEIGHT
23 | }
24 | );
25 | }
26 |
27 | setBounds(bounds) {
28 | this.store.set('window-bounds', bounds);
29 | }
30 |
31 | getMaximized() {
32 | return this.store.get('maximized') || DEFAULT_MAXIMIZED;
33 | }
34 |
35 | setMaximized(isMaximized) {
36 | this.store.set('maximized', isMaximized);
37 | }
38 | }
39 |
40 | module.exports = WindowStateStore;
41 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection_level_oauth2/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/test-collection",
3 | "version": "0.0.1",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@usebruno/test-collection",
9 | "version": "0.0.1",
10 | "dependencies": {
11 | "@faker-js/faker": "^8.4.0"
12 | }
13 | },
14 | "node_modules/@faker-js/faker": {
15 | "version": "8.4.0",
16 | "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.4.0.tgz",
17 | "integrity": "sha512-htW87352wzUCdX1jyUQocUcmAaFqcR/w082EC8iP/gtkF0K+aKcBp0hR5Arb7dzR8tQ1TrhE9DNa5EbJELm84w==",
18 | "funding": [
19 | {
20 | "type": "opencollective",
21 | "url": "https://opencollective.com/fakerjs"
22 | }
23 | ],
24 | "engines": {
25 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0",
26 | "npm": ">=6.14.13"
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/bruno-common/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/common",
3 | "version": "0.1.0",
4 | "license": "MIT",
5 | "main": "dist/cjs/index.js",
6 | "module": "dist/esm/index.js",
7 | "types": "dist/index.d.ts",
8 | "files": [
9 | "dist",
10 | "src",
11 | "package.json"
12 | ],
13 | "scripts": {
14 | "clean": "rimraf dist",
15 | "test": "jest",
16 | "test:watch": "jest --watch",
17 | "prebuild": "npm run clean",
18 | "build": "rollup -c",
19 | "prepack": "npm run test && npm run build"
20 | },
21 | "devDependencies": {
22 | "@rollup/plugin-commonjs": "^23.0.2",
23 | "@rollup/plugin-node-resolve": "^15.0.1",
24 | "@rollup/plugin-typescript": "^9.0.2",
25 | "rollup": "3.2.5",
26 | "rollup-plugin-dts": "^5.0.0",
27 | "rollup-plugin-peer-deps-external": "^2.2.4",
28 | "rollup-plugin-terser": "^7.0.2",
29 | "typescript": "^4.8.4"
30 | },
31 | "overrides": {
32 | "rollup": "3.2.5"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/tests/bru-to-env-json.spec.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const { bruToEnvJson } = require('../src');
5 |
6 | describe('bruToEnvJson', () => {
7 | it('should parse .bru file contents', () => {
8 | const requestFile = fs.readFileSync(path.join(__dirname, 'fixtures', 'env.bru'), 'utf8');
9 | const result = bruToEnvJson(requestFile);
10 |
11 | expect(result).toEqual({
12 | variables: [
13 | {
14 | enabled: true,
15 | name: 'host',
16 | value: 'https://www.google.com',
17 | type: 'text'
18 | },
19 | {
20 | enabled: true,
21 | name: 'jwt',
22 | value: 'secret',
23 | type: 'text'
24 | },
25 | {
26 | enabled: false,
27 | name: 'Content-type',
28 | value: 'application/json',
29 | type: 'text'
30 | }
31 | ]
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/packages/bruno-electron/tests/network/prepare-request.spec.js:
--------------------------------------------------------------------------------
1 | const { describe, it, expect } = require('@jest/globals');
2 |
3 | const prepareRequest = require('../../src/ipc/network/prepare-request');
4 |
5 | describe('prepare-request: prepareRequest', () => {
6 | describe('Decomments request body', () => {
7 | it('If request body is valid JSON', async () => {
8 | const body = { mode: 'json', json: '{\n"test": "{{someVar}}" // comment\n}' };
9 | const expected = { test: '{{someVar}}' };
10 | const result = prepareRequest({ request: { body } }, {});
11 | expect(result.data).toEqual(expected);
12 | });
13 |
14 | it('If request body is not valid JSON', async () => {
15 | const body = { mode: 'json', json: '{\n"test": {{someVar}} // comment\n}' };
16 | const expected = '{\n"test": {{someVar}} \n}';
17 | const result = prepareRequest({ request: { body } }, {});
18 | expect(result.data).toEqual(expected);
19 | });
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/bruno-tests/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/tests",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "start": "node ."
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/usebruno/bruno-testbench.git"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "MIT",
16 | "bugs": {
17 | "url": "https://github.com/usebruno/bruno-testbench/issues"
18 | },
19 | "homepage": "https://github.com/usebruno/bruno-testbench#readme",
20 | "dependencies": {
21 | "axios": "^1.5.1",
22 | "body-parser": "^1.20.0",
23 | "cookie-parser": "^1.4.6",
24 | "cors": "^2.8.5",
25 | "express": "^4.18.1",
26 | "express-basic-auth": "^1.2.1",
27 | "express-xml-bodyparser": "^0.3.0",
28 | "http-proxy": "^1.18.1",
29 | "js-yaml": "^4.1.0",
30 | "jsonwebtoken": "^9.0.2",
31 | "lodash": "^4.17.21",
32 | "multer": "^1.4.5-lts.1"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/bruno-tests/collection/scripting/npm modules/fakerjs.bru:
--------------------------------------------------------------------------------
1 | meta {
2 | name: fakerjs
3 | type: http
4 | seq: 1
5 | }
6 |
7 | post {
8 | url: {{host}}/api/echo/json
9 | body: json
10 | auth: none
11 | }
12 |
13 | body:json {
14 | {
15 | "hello": "bruno"
16 | }
17 | }
18 |
19 | assert {
20 | res.status: eq 200
21 | }
22 |
23 | script:pre-request {
24 | const { faker } = require('@faker-js/faker');
25 | const uuid = faker.string.uuid();
26 |
27 | const data = req.getBody();
28 | data.uuid = uuid;
29 |
30 | req.setBody(data);
31 | }
32 |
33 | tests {
34 | test("should return json", function() {
35 | const data = res.getBody();
36 | const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
37 | const isUUID = (inputString) => {
38 | return uuidRegex.test(inputString);
39 | };
40 |
41 | expect(data.hello).to.equal("bruno");
42 | expect(isUUID(data.uuid)).to.be.true;
43 | });
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v2/tests/script.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This test file is used to test the text parser.
3 | */
4 | const parser = require('../src/bruToJson');
5 |
6 | describe('script parser', () => {
7 | it('should parse request script', () => {
8 | const input = `
9 | script:pre-request {
10 | $req.setHeader('Content-Type', 'application/json');
11 | }
12 | `;
13 |
14 | const output = parser(input);
15 | const expected = {
16 | script: {
17 | req: "$req.setHeader('Content-Type', 'application/json');"
18 | }
19 | };
20 | expect(output).toEqual(expected);
21 | });
22 |
23 | it('should parse response script', () => {
24 | const input = `
25 | script:post-response {
26 | expect(response.status).to.equal(200);
27 | }
28 | `;
29 |
30 | const output = parser(input);
31 | const expected = {
32 | script: {
33 | res: 'expect(response.status).to.equal(200);'
34 | }
35 | };
36 | expect(output).toEqual(expected);
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/providers/App/ConfirmAppClose/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { useDispatch } from 'react-redux';
3 | import SaveRequestsModal from './SaveRequestsModal';
4 | import { isElectron } from 'utils/common/platform';
5 |
6 | const ConfirmAppClose = () => {
7 | const { ipcRenderer } = window;
8 | const [showConfirmClose, setShowConfirmClose] = useState(false);
9 | const dispatch = useDispatch();
10 |
11 | useEffect(() => {
12 | if (!isElectron()) {
13 | return;
14 | }
15 |
16 | const clearListener = ipcRenderer.on('main:start-quit-flow', () => {
17 | setShowConfirmClose(true);
18 | });
19 |
20 | return () => {
21 | clearListener();
22 | };
23 | }, [isElectron, ipcRenderer, dispatch, setShowConfirmClose]);
24 |
25 | if (!showConfirmClose) {
26 | return null;
27 | }
28 |
29 | return setShowConfirmClose(false)} />;
30 | };
31 |
32 | export default ConfirmAppClose;
33 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/src/components/DocExplorer/Argument.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2021 GraphQL Contributors.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | import React from 'react';
9 | import { GraphQLArgument } from 'graphql';
10 | import TypeLink from './TypeLink';
11 | import DefaultValue from './DefaultValue';
12 | import { OnClickTypeFunction } from './types';
13 |
14 | type ArgumentProps = {
15 | arg: GraphQLArgument;
16 | onClickType: OnClickTypeFunction;
17 | showDefaultValue?: boolean;
18 | };
19 |
20 | export default function Argument({ arg, onClickType, showDefaultValue }: ArgumentProps) {
21 | return (
22 |
23 | {arg.name}
24 | {': '}
25 |
26 | {showDefaultValue !== false && }
27 |
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/utils/collections/search.js:
--------------------------------------------------------------------------------
1 | import { flattenItems, isItemARequest } from './index';
2 | import filter from 'lodash/filter';
3 | import find from 'lodash/find';
4 |
5 | export const doesRequestMatchSearchText = (request, searchText = '') => {
6 | return request.name.toLowerCase().includes(searchText.toLowerCase());
7 | };
8 |
9 | export const doesFolderHaveItemsMatchSearchText = (item, searchText = '') => {
10 | let flattenedItems = flattenItems(item.items);
11 | let requestItems = filter(flattenedItems, (item) => isItemARequest(item));
12 |
13 | return find(requestItems, (request) => doesRequestMatchSearchText(request, searchText));
14 | };
15 |
16 | export const doesCollectionHaveItemsMatchingSearchText = (collection, searchText = '') => {
17 | let flattenedItems = flattenItems(collection.items);
18 | let requestItems = filter(flattenedItems, (item) => isItemARequest(item));
19 |
20 | return find(requestItems, (request) => doesRequestMatchSearchText(request, searchText));
21 | };
22 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v2/tests/collection.spec.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const collectionBruToJson = require('../src/collectionBruToJson');
4 | const jsonToCollectionBru = require('../src/jsonToCollectionBru');
5 |
6 | describe('collectionBruToJson', () => {
7 | it('should parse the collection bru file', () => {
8 | const input = fs.readFileSync(path.join(__dirname, 'fixtures', 'collection.bru'), 'utf8');
9 | const expected = require('./fixtures/collection.json');
10 | const output = collectionBruToJson(input);
11 |
12 | expect(output).toEqual(expected);
13 | });
14 | });
15 |
16 | describe('jsonToCollectionBru', () => {
17 | it('should convert the collection json to bru', () => {
18 | const input = require('./fixtures/collection.json');
19 | const expected = fs.readFileSync(path.join(__dirname, 'fixtures', 'collection.bru'), 'utf8');
20 | const output = jsonToCollectionBru(input);
21 |
22 | expect(output).toEqual(expected);
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestTabs/RequestTab/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | .tab-label {
5 | overflow: hidden;
6 | }
7 |
8 | .tab-name {
9 | overflow: hidden;
10 | text-overflow: ellipsis;
11 | white-space: nowrap;
12 | }
13 |
14 | .close-icon-container {
15 | min-height: 20px;
16 | min-width: 24px;
17 | margin-left: 4px;
18 | border-radius: 3px;
19 |
20 | .close-icon {
21 | display: none;
22 | color: ${(props) => props.theme.requestTabs.icon.color};
23 | width: 8px;
24 | padding-bottom: 6px;
25 | padding-top: 6px;
26 | }
27 |
28 | &:hover,
29 | &:hover .close-icon {
30 | color: ${(props) => props.theme.requestTabs.icon.hoverColor};
31 | background-color: ${(props) => props.theme.requestTabs.icon.hoverBg};
32 | }
33 |
34 | .has-changes-icon {
35 | height: 24px;
36 | }
37 | }
38 | `;
39 |
40 | export default StyledWrapper;
41 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/utils/common/error.js:
--------------------------------------------------------------------------------
1 | import toast from 'react-hot-toast';
2 |
3 | // levels: 'warning, error'
4 | export class BrunoError extends Error {
5 | constructor(message, level) {
6 | super(message);
7 | this.name = 'BrunoError';
8 | this.level = level || 'error';
9 | }
10 | }
11 |
12 | export const parseError = (error, defaultErrorMsg = 'An error occurred') => {
13 | if (error instanceof BrunoError) {
14 | return error.message;
15 | }
16 |
17 | return error.message ? error.message : defaultErrorMsg;
18 | };
19 |
20 | export const toastError = (error, defaultErrorMsg = 'An error occurred') => {
21 | let errorMsg = parseError(error, defaultErrorMsg);
22 |
23 | if (error instanceof BrunoError) {
24 | if (error.level === 'warning') {
25 | return toast(errorMsg, {
26 | icon: '⚠️',
27 | duration: 3000
28 | });
29 | }
30 | return toast.error(errorMsg, {
31 | duration: 3000
32 | });
33 | }
34 |
35 | return toast.error(errorMsg);
36 | };
37 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v1/tests/env-json-to-bru.spec.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const { envJsonToBru } = require('../src');
5 |
6 | describe('envJsonToBru', () => {
7 | it('should convert json file into .bru file', () => {
8 | const env = {
9 | variables: [
10 | {
11 | enabled: true,
12 | name: 'host',
13 | value: 'https://www.google.com',
14 | type: 'text'
15 | },
16 | {
17 | enabled: true,
18 | name: 'jwt',
19 | value: 'secret',
20 | type: 'text'
21 | },
22 | {
23 | enabled: false,
24 | name: 'Content-type',
25 | value: 'application/json',
26 | type: 'text'
27 | }
28 | ]
29 | };
30 |
31 | const expectedBruFile = fs.readFileSync(path.join(__dirname, 'fixtures', 'env.bru'), 'utf8');
32 | const actualBruFile = envJsonToBru(env);
33 |
34 | expect(expectedBruFile).toEqual(actualBruFile);
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseHeaders/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import StyledWrapper from './StyledWrapper';
3 |
4 | const ResponseHeaders = ({ headers }) => {
5 | const headersArray = typeof headers === 'object' ? Object.entries(headers) : [];
6 |
7 | return (
8 |
9 |
10 |
11 |
12 | Name
13 | Value
14 |
15 |
16 |
17 | {headersArray && headersArray.length
18 | ? headersArray.map((header, index) => {
19 | return (
20 |
21 | {header[0]}
22 | {header[1]}
23 |
24 | );
25 | })
26 | : null}
27 |
28 |
29 |
30 | );
31 | };
32 | export default ResponseHeaders;
33 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_tr.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | **Türkçe**
3 | | [Deutsch](./publishing_de.md)
4 | | [Français](./publishing_fr.md)
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | [বাংলা](./publishing_bn.md)
7 | | [Română](./publishing_ro.md)
8 | | [Polski](./publishing_pl.md)
9 | | [简体中文](./publishing_cn.md)
10 | | [正體中文](./publishing_zhtw.md)
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### Bruno'yu yeni bir paket yöneticisine yayınlama
14 |
15 | Kodumuz açık kaynak kodlu ve herkesin kullanımına açık olsa da, yeni paket yöneticilerinde yayınlamayı düşünmeden önce bize ulaşmanızı rica ediyoruz. Bruno'nun yaratıcısı olarak, bu proje için `Bruno` ticari markasına sahibim ve dağıtımını yönetmek istiyorum. Bruno'yu yeni bir paket yöneticisinde görmek istiyorsanız, lütfen bir GitHub sorunu oluşturun.
16 |
17 | Özelliklerimizin çoğu ücretsiz ve açık kaynak olsa da (REST ve GraphQL Apis'i kapsar),
18 | açık kaynak ilkeleri ile sürdürülebilirlik arasında uyumlu bir denge kurmaya çalışıyoruz - https://github.com/usebruno/bruno/discussions/269
19 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_bn.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | [Deutsch](./publishing_de.md)
4 | | [Français](./publishing_fr.md)
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | **বাংলা**
7 | | [Română](./publishing_ro.md)
8 | | [Polski](./publishing_pl.md)
9 | | [简体中文](./publishing_cn.md)
10 | | [正體中文](./publishing_zhtw.md)
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### ব্রুনোকে নতুন প্যাকেজ ম্যানেজারে প্রকাশ করা
14 |
15 | যদিও আমাদের কোড ওপেন সোর্স এবং সবার ব্যবহারের জন্য উপলব্ধ, তবে আমরা নতুন প্যাকেজ ম্যানেজারে প্রকাশনা বিবেচনা করার আগে আমাদের সাথে যোগাযোগ করার জন্য অনুরোধ করি। ব্রুনোর স্রষ্টা হিসাবে, আমি এই প্রকল্পের জন্য `Bruno` ট্রেডমার্ক ধারণ করি এবং এর বিতরণ পরিচালনা করতে চাই। যদি আপনি একটি নতুন প্যাকেজ ম্যানেজারে ব্রুনো দেখতে চান, দয়া করে একটি GitHub ইস্যু তুলুন।
16 |
17 | যদিও আমাদের বেশিরভাগ বৈশিষ্ট্য বিনামূল্যে এবং ওপেন সোর্স (যা REST এবং GraphQL API গুলিকে কভার করে), আমরা ওপেন-সোর্স নীতি এবং স্থায়িত্বের মধ্যে একটি সুসঙ্গত ভারসাম্য বজায় রাখার জন্য চেষ্টা করি - https://github.com/usebruno/bruno/discussions/269
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RequestPane/Vars/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import get from 'lodash/get';
3 | import VarsTable from './VarsTable';
4 | import StyledWrapper from './StyledWrapper';
5 |
6 | const Vars = ({ item, collection }) => {
7 | const requestVars = item.draft ? get(item, 'draft.request.vars.req') : get(item, 'request.vars.req');
8 | const responseVars = item.draft ? get(item, 'draft.request.vars.res') : get(item, 'request.vars.res');
9 |
10 | return (
11 |
12 |
13 |
Pre Request
14 |
15 |
16 |
17 |
Post Response
18 |
19 |
20 |
21 | );
22 | };
23 |
24 | export default Vars;
25 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_pl.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | [Deutsch](./publishing_de.md)
4 | | [Français](./publishing_fr.md)
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | [বাংলা](./publishing_bn.md)
7 | | [Română](./publishing_ro.md)
8 | | **Polski**
9 | | [简体中文](./publishing_cn.md)
10 | | [正體中文](./publishing_zhtw.md)
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### Publikowanie Bruno w nowym menedżerze pakietów
14 |
15 | Chociaż nasz kod jest otwartoźródłowy i dostępny dla każdego do użytku, uprzejmie prosimy o kontakt z nami przed rozważeniem publikacji w nowych menedżerach pakietów. Jako twórca Bruno, posiadam znak towarowy `Bruno` dla tego projektu i chciałbym zarządzać jego dystrybucją. Jeśli chcesz zobaczyć Bruno w nowym menedżerze pakietów, proszę zgłoś problem na GitHubie.
16 |
17 | Chociaż większość naszych funkcji jest darmowa i otwartoźródłowa (co obejmuje REST i GraphQL Apis),
18 | staramy się osiągnąć harmonijny balans między zasadami open-source a zrównoważonym rozwojem - https://github.com/usebruno/bruno/discussions/269
19 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/utils/idb/index.js:
--------------------------------------------------------------------------------
1 | export const saveCollectionToIdb = (connection, collection) => {
2 | return new Promise((resolve, reject) => {
3 | connection
4 | .then((db) => {
5 | let tx = db.transaction(`collection`, 'readwrite');
6 | let collectionStore = tx.objectStore('collection');
7 |
8 | collectionStore.put(collection);
9 |
10 | resolve(collection);
11 | })
12 | .catch((err) => reject(err));
13 | });
14 | };
15 |
16 | export const getCollectionsFromIdb = (connection) => {
17 | return new Promise((resolve, reject) => {
18 | connection
19 | .then((db) => {
20 | let tx = db.transaction('collection');
21 | let collectionStore = tx.objectStore('collection');
22 | return collectionStore.getAll();
23 | })
24 | .then((collections) => {
25 | if (!Array.isArray(collections)) {
26 | return new Error('IDB Corrupted');
27 | }
28 |
29 | return resolve(collections);
30 | })
31 | .catch((err) => reject(err));
32 | });
33 | };
34 |
--------------------------------------------------------------------------------
/packages/bruno-electron/src/utils/filesystem.test.js:
--------------------------------------------------------------------------------
1 | const { sanitizeDirectoryName } = require('./filesystem.js');
2 |
3 | describe('sanitizeDirectoryName', () => {
4 | it('should replace invalid characters with hyphens', () => {
5 | const input = '<>:"/\\|?*\x00-\x1F';
6 | const expectedOutput = '---';
7 | expect(sanitizeDirectoryName(input)).toEqual(expectedOutput);
8 | });
9 |
10 | it('should not modify valid directory names', () => {
11 | const input = 'my-directory';
12 | expect(sanitizeDirectoryName(input)).toEqual(input);
13 | });
14 |
15 | it('should replace multiple invalid characters with a single hyphen', () => {
16 | const input = 'my<>invalid?directory';
17 | const expectedOutput = 'my-invalid-directory';
18 | expect(sanitizeDirectoryName(input)).toEqual(expectedOutput);
19 | });
20 |
21 | it('should handle names with slashes', () => {
22 | const input = 'my/invalid/directory';
23 | const expectedOutput = 'my-invalid-directory';
24 | expect(sanitizeDirectoryName(input)).toEqual(expectedOutput);
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/src/components/DocExplorer/DefaultValue.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2021 GraphQL Contributors.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | */
7 |
8 | import React from 'react';
9 | import { astFromValue, print, ValueNode } from 'graphql';
10 | import { FieldType } from './types';
11 |
12 | const printDefault = (ast?: ValueNode | null): string => {
13 | if (!ast) {
14 | return '';
15 | }
16 | return print(ast);
17 | };
18 |
19 | type DefaultValueProps = {
20 | field: FieldType;
21 | };
22 |
23 | export default function DefaultValue({ field }: DefaultValueProps) {
24 | // field.defaultValue could be null or false, so be careful here!
25 | if ('defaultValue' in field && field.defaultValue !== undefined) {
26 | return (
27 |
28 | {' = '}
29 | {printDefault(astFromValue(field.defaultValue, field.type))}
30 |
31 | );
32 | }
33 |
34 | return null;
35 | }
36 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.tabs {
5 | div.tab {
6 | padding: 6px 0px;
7 | border: none;
8 | border-bottom: solid 2px transparent;
9 | margin-right: 1.25rem;
10 | color: var(--color-tab-inactive);
11 | cursor: pointer;
12 |
13 | &:focus,
14 | &:active,
15 | &:focus-within,
16 | &:focus-visible,
17 | &:target {
18 | outline: none !important;
19 | box-shadow: none !important;
20 | }
21 |
22 | &.active {
23 | color: ${(props) => props.theme.tabs.active.color} !important;
24 | border-bottom: solid 2px ${(props) => props.theme.tabs.active.border} !important;
25 | }
26 | }
27 | }
28 |
29 | .some-tests-failed {
30 | color: ${(props) => props.theme.colors.text.danger} !important;
31 | }
32 |
33 | .all-tests-passed {
34 | color: ${(props) => props.theme.colors.text.green} !important;
35 | }
36 | `;
37 |
38 | export default StyledWrapper;
39 |
--------------------------------------------------------------------------------
/packages/bruno-electron/tests/network/index.spec.js:
--------------------------------------------------------------------------------
1 | // damn jest throws an error when no tests are found in a file
2 | // --passWithNoTests doesn't work
3 |
4 | describe('dummy test', () => {
5 | it('should pass', () => {
6 | expect(true).toBe(true);
7 | });
8 | });
9 |
10 | // todo: fix this failing test
11 | // const { configureRequest } = require('../../src/ipc/network/index');
12 |
13 | // describe('index: configureRequest', () => {
14 | // it("Should add 'http://' to the URL if no protocol is specified", async () => {
15 | // const request = { method: 'GET', url: 'test-domain', body: {} };
16 | // await configureRequest(null, request, null, null, null, null);
17 | // expect(request.url).toEqual('http://test-domain');
18 | // });
19 |
20 | // it("Should NOT add 'http://' to the URL if a protocol is specified", async () => {
21 | // const request = { method: 'GET', url: 'ftp://test-domain', body: {} };
22 | // await configureRequest(null, request, null, null, null, null);
23 | // expect(request.url).toEqual('ftp://test-domain');
24 | // });
25 | // });
26 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import classnames from 'classnames';
3 | import StyledWrapper from './StyledWrapper';
4 |
5 | const RequestMethod = ({ item }) => {
6 | if (!['http-request', 'graphql-request'].includes(item.type)) {
7 | return null;
8 | }
9 |
10 | const getClassname = (method = '') => {
11 | method = method.toLocaleLowerCase();
12 | return classnames('mr-1', {
13 | 'method-get': method === 'get',
14 | 'method-post': method === 'post',
15 | 'method-put': method === 'put',
16 | 'method-delete': method === 'delete',
17 | 'method-patch': method === 'patch',
18 | 'method-head': method === 'head',
19 | 'method-options': method == 'options'
20 | });
21 | };
22 |
23 | return (
24 |
25 |
26 | {item.request.method}
27 |
28 |
29 | );
30 | };
31 |
32 | export default RequestMethod;
33 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/providers/ReduxStore/index.js:
--------------------------------------------------------------------------------
1 | import getConfig from 'next/config';
2 | import { configureStore } from '@reduxjs/toolkit';
3 | import tasksMiddleware from './middlewares/tasks/middleware';
4 | import debugMiddleware from './middlewares/debug/middleware';
5 | import appReducer from './slices/app';
6 | import collectionsReducer from './slices/collections';
7 | import tabsReducer from './slices/tabs';
8 | import notificationsReducer from './slices/notifications';
9 |
10 | const { publicRuntimeConfig } = getConfig();
11 | const isDevEnv = () => {
12 | return publicRuntimeConfig.ENV === 'dev';
13 | };
14 |
15 | let middleware = [tasksMiddleware.middleware];
16 | if (isDevEnv()) {
17 | middleware = [...middleware, debugMiddleware.middleware];
18 | }
19 |
20 | export const store = configureStore({
21 | reducer: {
22 | app: appReducer,
23 | collections: collectionsReducer,
24 | tabs: tabsReducer,
25 | notifications: notificationsReducer
26 | },
27 | middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(middleware)
28 | });
29 |
30 | export default store;
31 |
--------------------------------------------------------------------------------
/packages/bruno-lang/v2/src/jsonToEnv.js:
--------------------------------------------------------------------------------
1 | const _ = require('lodash');
2 |
3 | const envToJson = (json) => {
4 | const variables = _.get(json, 'variables', []);
5 | const vars = variables
6 | .filter((variable) => !variable.secret)
7 | .map((variable) => {
8 | const { name, value, enabled } = variable;
9 | const prefix = enabled ? '' : '~';
10 | return ` ${prefix}${name}: ${value}`;
11 | });
12 |
13 | const secretVars = variables
14 | .filter((variable) => variable.secret)
15 | .map((variable) => {
16 | const { name, enabled } = variable;
17 | const prefix = enabled ? '' : '~';
18 | return ` ${prefix}${name}`;
19 | });
20 |
21 | if (!variables || !variables.length) {
22 | return `vars {
23 | }
24 | `;
25 | }
26 |
27 | let output = '';
28 | if (vars.length) {
29 | output += `vars {
30 | ${vars.join('\n')}
31 | }
32 | `;
33 | }
34 |
35 | if (secretVars.length) {
36 | output += `vars:secret [
37 | ${secretVars.join(',\n')}
38 | ]
39 | `;
40 | }
41 |
42 | return output;
43 | };
44 |
45 | module.exports = envToJson;
46 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/RunnerResults/ResponsePane/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const StyledWrapper = styled.div`
4 | div.tabs {
5 | div.tab {
6 | padding: 6px 0px;
7 | border: none;
8 | border-bottom: solid 2px transparent;
9 | margin-right: 1.25rem;
10 | color: var(--color-tab-inactive);
11 | cursor: pointer;
12 |
13 | &:focus,
14 | &:active,
15 | &:focus-within,
16 | &:focus-visible,
17 | &:target {
18 | outline: none !important;
19 | box-shadow: none !important;
20 | }
21 |
22 | &.active {
23 | color: ${(props) => props.theme.tabs.active.color} !important;
24 | border-bottom: solid 2px ${(props) => props.theme.tabs.active.border} !important;
25 | }
26 | }
27 | }
28 |
29 | .some-tests-failed {
30 | color: ${(props) => props.theme.colors.text.danger} !important;
31 | }
32 |
33 | .all-tests-passed {
34 | color: ${(props) => props.theme.colors.text.green} !important;
35 | }
36 | `;
37 |
38 | export default StyledWrapper;
39 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RequestMethod/StyledWrapper.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components';
2 |
3 | const Wrapper = styled.div`
4 | font-size: 0.6875rem;
5 | display: flex;
6 | align-self: stretch;
7 | align-items: center;
8 | min-width: 34px;
9 | flex-shrink: 0;
10 |
11 | span {
12 | position: relative;
13 | top: 1px;
14 | }
15 |
16 | .method-get {
17 | color: ${(props) => props.theme.request.methods.get};
18 | }
19 | .method-post {
20 | color: ${(props) => props.theme.request.methods.post};
21 | }
22 | .method-put {
23 | color: ${(props) => props.theme.request.methods.put};
24 | }
25 | .method-delete {
26 | color: ${(props) => props.theme.request.methods.delete};
27 | }
28 | .method-patch {
29 | color: ${(props) => props.theme.request.methods.patch};
30 | }
31 | .method-options {
32 | color: ${(props) => props.theme.request.methods.options};
33 | }
34 | .method-head {
35 | color: ${(props) => props.theme.request.methods.head};
36 | }
37 | `;
38 |
39 | export default Wrapper;
40 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Toast/index.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from 'react';
2 | import StyledWrapper from './StyledWrapper';
3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
4 | import { faTimes } from '@fortawesome/free-solid-svg-icons';
5 |
6 | const ToastContent = ({ type, text, handleClose }) => (
7 |
8 |
{text}
9 |
10 |
11 |
12 |
13 | );
14 |
15 | const Toast = ({ text, type, duration, handleClose }) => {
16 | let lifetime = duration ? duration : 3000;
17 |
18 | useEffect(() => {
19 | if (text) {
20 | setTimeout(handleClose, lifetime);
21 | }
22 | }, [text]);
23 |
24 | return (
25 |
26 |
27 |
28 |
29 |
30 | );
31 | };
32 |
33 | export default Toast;
34 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/MarkDown/index.jsx:
--------------------------------------------------------------------------------
1 | import MarkdownIt from 'markdown-it';
2 | import StyledWrapper from './StyledWrapper';
3 | import React from 'react';
4 |
5 | const md = new MarkdownIt();
6 |
7 | const Markdown = ({ onDoubleClick, content }) => {
8 | const handleOnClick = (event) => {
9 | const target = event.target;
10 | if (target.tagName === 'A') {
11 | event.preventDefault();
12 | const href = target.getAttribute('href');
13 | if (href) {
14 | window.open(href, '_blank');
15 | return;
16 | }
17 | }
18 | };
19 |
20 | const handleOnDoubleClick = (event) => {
21 | if (event.detail === 2) {
22 | onDoubleClick();
23 | }
24 | };
25 |
26 | const htmlFromMarkdown = md.render(content || '');
27 |
28 | return (
29 |
30 |
36 |
37 | );
38 | };
39 |
40 | export default Markdown;
41 |
--------------------------------------------------------------------------------
/packages/bruno-graphql-docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@usebruno/graphql-docs",
3 | "version": "0.1.0",
4 | "license" : "MIT",
5 | "main": "dist/cjs/index.js",
6 | "module": "dist/esm/index.js",
7 | "files": [
8 | "dist",
9 | "package.json"
10 | ],
11 | "scripts": {
12 | "build": "rollup -c"
13 | },
14 | "devDependencies": {
15 | "@rollup/plugin-commonjs": "^23.0.2",
16 | "@rollup/plugin-node-resolve": "^15.0.1",
17 | "@rollup/plugin-typescript": "^9.0.2",
18 | "@types/markdown-it": "^12.2.3",
19 | "@types/react": "^18.0.25",
20 | "graphql": "^16.6.0",
21 | "markdown-it": "^13.0.1",
22 | "postcss": "^8.4.18",
23 | "react": "18.2.0",
24 | "react-dom": "18.2.0",
25 | "rollup": "3.2.5",
26 | "rollup-plugin-dts": "^5.0.0",
27 | "rollup-plugin-peer-deps-external": "^2.2.4",
28 | "rollup-plugin-postcss": "^4.0.2",
29 | "rollup-plugin-terser": "^7.0.2",
30 | "typescript": "^4.8.4"
31 | },
32 | "peerDependencies": {
33 | "graphql": "^16.6.0",
34 | "markdown-it": "^13.0.1"
35 | },
36 | "overrides": {
37 | "rollup": "3.2.5"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_de.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | **Deutsch**
4 | | [Français](./publishing_fr.md)
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | [বাংলা](./publishing_bn.md)
7 | | [Română](./publishing_ro.md)
8 | | [Polski](./publishing_pl.md)
9 | | [简体中文](./publishing_cn.md)
10 | | [正體中文](./publishing_zhtw.md)
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### Veröffentlichung von Bruno über neue Paket-Manager
14 |
15 | Obwohl Bruno Open Source und für alle frei zugänglich ist, bitten wir dich Kontakt zu uns aufzunehmen, bevor du Bruno über weitere Paket-Manager veröffentlichst.
16 | Als Schöpfer von Bruno liegen alle Marktrechte von `Bruno` bei mir und ich möchte die volle Kontrolle über alle Verbreitungswege behalten.
17 | Falls Bruno über einen weiteren Paketmanager veröffentlicht werden soll, eröffne bitte ein GitHub-Issue.
18 |
19 | Während ein Großteil der Features kostenlos und Open Source ist (beinhaltet REST und GraphQL APIs),
20 | bemühen wir uns um ein harmonisches Gleichgewicht zwischen Open-Source-Prinzipien und Nachhaltigkeit - https://github.com/usebruno/bruno/discussions/269
21 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/ResponsePane/ResponseSave/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import StyledWrapper from './StyledWrapper';
3 | import toast from 'react-hot-toast';
4 | import get from 'lodash/get';
5 | import { IconDownload } from '@tabler/icons';
6 |
7 | const ResponseSave = ({ item }) => {
8 | const { ipcRenderer } = window;
9 | const response = item.response || {};
10 |
11 | const saveResponseToFile = () => {
12 | return new Promise((resolve, reject) => {
13 | ipcRenderer
14 | .invoke('renderer:save-response-to-file', response, item.requestSent.url)
15 | .then(resolve)
16 | .catch((err) => {
17 | toast.error(get(err, 'error.message') || 'Something went wrong!');
18 | reject(err);
19 | });
20 | });
21 | };
22 |
23 | return (
24 |
25 |
26 |
27 |
28 |
29 | );
30 | };
31 | export default ResponseSave;
32 |
--------------------------------------------------------------------------------
/packages/bruno-app/public/theme/dark.js:
--------------------------------------------------------------------------------
1 | const darkTheme = {
2 | brand: '#546de5',
3 | text: 'rgb(52 52 52)',
4 | 'primary-text': '#ffffff',
5 | 'primary-theme': '#1e1e1e',
6 | 'secondary-text': '#929292',
7 | 'sidebar-collection-item-active-indent-border': '#d0d0d0',
8 | 'sidebar-collection-item-active-background': '#e1e1e1',
9 | 'sidebar-background': '#252526',
10 | 'sidebar-bottom-bg': '#68217a',
11 | 'request-dragbar-background': '#efefef',
12 | 'request-dragbar-background-active': 'rgb(200, 200, 200)',
13 | 'tab-inactive': 'rgb(155 155 155)',
14 | 'tab-active-border': '#546de5',
15 | 'layout-border': '#dedede',
16 | 'codemirror-border': '#efefef',
17 | 'codemirror-background': 'rgb(243, 243, 243)',
18 | 'text-link': '#1663bb',
19 | 'text-danger': 'rgb(185, 28, 28)',
20 | 'background-danger': '#dc3545',
21 | 'method-get': 'rgb(5, 150, 105)',
22 | 'method-post': '#8e44ad',
23 | 'method-delete': 'rgb(185, 28, 28)',
24 | 'method-patch': 'rgb(52 52 52)',
25 | 'method-options': 'rgb(52 52 52)',
26 | 'method-head': 'rgb(52 52 52)',
27 | 'table-stripe': '#f3f3f3'
28 | };
29 |
30 | export default darkTheme;
31 |
--------------------------------------------------------------------------------
/packages/bruno-electron/notarize.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config({ path: process.env.DOTENV_PATH });
2 | const fs = require('fs');
3 | const path = require('path');
4 | const electron_notarize = require('electron-notarize');
5 |
6 | const notarize = async function (params) {
7 | if (process.platform !== 'darwin') {
8 | return;
9 | }
10 |
11 | let appId = 'com.usebruno.app';
12 |
13 | let appPath = path.join(params.appOutDir, `${params.packager.appInfo.productFilename}.app`);
14 | if (!fs.existsSync(appPath)) {
15 | console.error(`Cannot find application at: ${appPath}`);
16 | return;
17 | }
18 |
19 | console.log(`Notarizing ${appId} found at ${appPath} using Apple ID ${process.env.APPLE_ID}`);
20 |
21 | try {
22 | await electron_notarize.notarize({
23 | appBundleId: appId,
24 | appPath: appPath,
25 | appleId: process.env.APPLE_ID,
26 | appleIdPassword: process.env.APPLE_ID_PASSWORD,
27 | ascProvider: 'W7LPPWA48L'
28 | });
29 | } catch (error) {
30 | console.error(error);
31 | }
32 |
33 | console.log(`Done notarizing ${appId}`);
34 | };
35 |
36 | module.exports = notarize;
--------------------------------------------------------------------------------
/docs/publishing/publishing_fr.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | [Deutsch](./publishing_de.md)
4 | | **Français**
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | [বাংলা](./publishing_bn.md)
7 | | [Română](./publishing_ro.md)
8 | | [Polski](./publishing_pl.md)
9 | | [简体中文](./publishing_cn.md)
10 | | [正體中文](./publishing_zhtw.md)
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### Publier Bruno dans un nouveau gestionnaire de paquets
14 |
15 | Bien que notre code soit open source et disponible pour tout le monde, nous vous remercions de nous contacter avant de considérer sa publication sur un nouveau gestionnaire de paquets. En tant que créateur de Bruno, je détiens la marque `Bruno` pour ce projet et j'aimerais gérer moi-même sa distribution. Si vous voyez Bruno sur un nouveau gestionnaire de paquets, merci de créer une _issue_ GitHub.
16 |
17 | Bien que la majorité de nos fonctionnalités soient gratuites et open source (ce qui couvre les APIs REST et GraphQL), nous nous efforçons de trouver un équilibre harmonieux entre les principes de l'open source et la pérennité - https://github.com/usebruno/bruno/discussions/269
18 |
--------------------------------------------------------------------------------
/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Modal from 'components/Modal/index';
3 | import { IconFiles } from '@tabler/icons';
4 | import { useSelector } from 'react-redux';
5 | import StyledWrapper from './StyledWrapper';
6 |
7 | const SelectCollection = ({ onClose, onSelect, title }) => {
8 | const { collections } = useSelector((state) => state.collections);
9 |
10 | return (
11 |
12 |
13 |
24 |
25 |
26 | );
27 | };
28 |
29 | export default SelectCollection;
30 |
--------------------------------------------------------------------------------
/packages/bruno-app/public/theme/light.js:
--------------------------------------------------------------------------------
1 | const lightTheme = {
2 | brand: '#546de5',
3 | text: 'rgb(52 52 52)',
4 | 'primary-text': 'rgb(52 52 52)',
5 | 'primary-theme': '#ffffff',
6 | 'secondary-text': '#929292',
7 | 'sidebar-collection-item-active-indent-border': '#d0d0d0',
8 | 'sidebar-collection-item-active-background': '#e1e1e1',
9 | 'sidebar-background': '#f3f3f3',
10 | 'sidebar-bottom-bg': '#f3f3f3',
11 | 'request-dragbar-background': '#efefef',
12 | 'request-dragbar-background-active': 'rgb(200, 200, 200)',
13 | 'tab-inactive': 'rgb(155 155 155)',
14 | 'tab-active-border': '#546de5',
15 | 'layout-border': '#dedede',
16 | 'codemirror-border': '#efefef',
17 | 'codemirror-background': 'rgb(243, 243, 243)',
18 | 'text-link': '#1663bb',
19 | 'text-danger': 'rgb(185, 28, 28)',
20 | 'background-danger': '#dc3545',
21 | 'method-get': 'rgb(5, 150, 105)',
22 | 'method-post': '#8e44ad',
23 | 'method-delete': 'rgb(185, 28, 28)',
24 | 'method-patch': 'rgb(52 52 52)',
25 | 'method-options': 'rgb(52 52 52)',
26 | 'method-head': 'rgb(52 52 52)',
27 | 'table-stripe': '#f3f3f3'
28 | };
29 |
30 | export default lightTheme;
31 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_pt_br.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | [Deutsch](./publishing_de.md)
4 | | [Français](./publishing_fr.md)
5 | | **Português (BR)**
6 | | [বাংলা](./publishing_bn.md)
7 | | [Română](./publishing_ro.md)
8 | | [Polski](./publishing_pl.md)
9 | | [简体中文](./publishing_cn.md)
10 | | [正體中文](./publishing_zhtw.md)
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### Publicando Bruno em um novo gerenciador de pacotes
14 |
15 | 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.
16 |
17 | 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
18 |
--------------------------------------------------------------------------------
/docs/publishing/publishing_ro.md:
--------------------------------------------------------------------------------
1 | [English](../../publishing.md)
2 | | [Türkçe](./publishing_tr.md)
3 | | [Deutsch](./publishing_de.md)
4 | | [Français](./publishing_fr.md)
5 | | [Português (BR)](./publishing_pt_br.md)
6 | | [বাংলা](./publishing_bn.md)
7 | | **Română**
8 | | [Polski](./publishing_pl.md)
9 | | [简体中文](./publishing_cn.md)
10 | | [正體中文](./publishing_zhtw.md)
11 | | [日本語](./publishing_ja.md)
12 |
13 | ### Publicarea lui Bruno la un gestionar de pachete nou
14 |
15 | Deși codul nostru este cu sursă deschisă și disponibil pentru utilizare pentru toată lumea, vă rugăm să ne contactați înainte de a considera publicarea pe gestionari de pachete noi. În calitate de creator al lui Bruno, dețin marca comercială `Bruno` pentru acest proiect și aș dori să gestionez distribuția acestuia. Dacă doriți să-l vedeți pe Bruno pe un gestionar de pachete nou, vă rugăm să creați un issue pe GitHub.
16 |
17 | În timp ce majoritatea funcțiilor noastre sunt gratuite și cu sursă deschisă (ceea ce acoperă API-uri REST și GraphQL),
18 | ne străduim să găsim un echilibru armonios între principiile de sursă deschisă și sustenabilitate - https://github.com/usebruno/bruno/discussions/269
19 |
--------------------------------------------------------------------------------
/packages/bruno-cli/src/constants.js:
--------------------------------------------------------------------------------
1 | const { version } = require('../package.json');
2 |
3 | const CLI_EPILOGUE = `Documentation: https://docs.usebruno.com (v${version})`;
4 | const CLI_VERSION = version;
5 |
6 | // Exit codes
7 | const EXIT_STATUS = {
8 | // One or more assertions, tests, or requests failed
9 | ERROR_FAILED_COLLECTION: 1,
10 | // The specified output dir does not exist
11 | ERROR_MISSING_OUTPUT_DIR: 2,
12 | // request chain caused an endless loop
13 | ERROR_INFINTE_LOOP: 3,
14 | // bru was called outside of a collection root
15 | ERROR_NOT_IN_COLLECTION: 4,
16 | // The specified file was not found
17 | ERROR_FILE_NOT_FOUND: 5,
18 | // The specified environment was not found
19 | ERROR_ENV_NOT_FOUND: 6,
20 | // Environment override not presented as string or object
21 | ERROR_MALFORMED_ENV_OVERRIDE: 7,
22 | // Environment overrides format incorrect
23 | ERROR_INCORRECT_ENV_OVERRIDE: 8,
24 | // Invalid output format requested
25 | ERROR_INCORRECT_OUTPUT_FORMAT: 9,
26 | // Everything else
27 | ERROR_GENERIC: 255,
28 | };
29 |
30 | module.exports = {
31 | CLI_EPILOGUE,
32 | CLI_VERSION,
33 | EXIT_STATUS
34 | };
35 |
--------------------------------------------------------------------------------
/packages/bruno-lang/example/request.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "http-request",
3 | "name": "Send Bulk SMS",
4 | "request": {
5 | "method": "GET",
6 | "url": "https://api.textlocal.in/bulk_json?apiKey=secret=&numbers=998877665&message=hello&sender=600010",
7 | "params": [
8 | {
9 | "name": "apiKey",
10 | "value": "secret",
11 | "enabled": true
12 | },
13 | {
14 | "name": "numbers",
15 | "value": "998877665",
16 | "enabled": true
17 | },
18 | {
19 | "name": "message",
20 | "value": "hello",
21 | "enabled": true
22 | },
23 | {
24 | "name": "sender",
25 | "value": "600010",
26 | "enabled": true
27 | }
28 | ],
29 | "headers": [],
30 | "body": {
31 | "mode": "json",
32 | "json": "{\n apikey: \"secret\",\n numbers: \"+919988776655\",\n data: {\n sender: \"TXTLCL\",\n messages: [{\n numbers: \"+919988776655\",\n message: \"Hello World\"\n }]\n }\n}",
33 | "text": null,
34 | "xml": null,
35 | "multipartForm": null,
36 | "formUrlEncoded": null
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------