├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── BugReport.yaml │ ├── FeatureRequest.yaml │ └── config.yaml ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── npm-bru-cli.yml │ └── tests.yml ├── .gitignore ├── .nvmrc ├── .prettierrc.json ├── assets └── images │ ├── cli-demo.png │ ├── landing-2.png │ ├── local-collections.png │ ├── logo-transparent.png │ ├── logo.png │ ├── run-anywhere.png │ └── version-control.png ├── contributing.md ├── docs ├── contributing │ ├── contributing_bn.md │ ├── contributing_cn.md │ ├── contributing_de.md │ ├── contributing_es.md │ ├── contributing_fr.md │ ├── contributing_hi.md │ ├── contributing_it.md │ ├── contributing_ja.md │ ├── contributing_kr.md │ ├── contributing_nl.md │ ├── contributing_pl.md │ ├── contributing_pt_br.md │ ├── contributing_ro.md │ ├── contributing_ru.md │ ├── contributing_sk.md │ ├── contributing_tr.md │ ├── contributing_ua.md │ └── contributing_zhtw.md ├── publishing │ ├── publishing_bn.md │ ├── publishing_cn.md │ ├── publishing_de.md │ ├── publishing_fr.md │ ├── publishing_ja.md │ ├── publishing_nl.md │ ├── publishing_pl.md │ ├── publishing_pt_br.md │ ├── publishing_ro.md │ ├── publishing_tr.md │ └── publishing_zhtw.md └── readme │ ├── readme_ar.md │ ├── readme_bn.md │ ├── readme_cn.md │ ├── readme_de.md │ ├── readme_es.md │ ├── readme_fr.md │ ├── readme_it.md │ ├── readme_ja.md │ ├── readme_ka.md │ ├── readme_kr.md │ ├── readme_nl.md │ ├── readme_pl.md │ ├── readme_pt_br.md │ ├── readme_ro.md │ ├── readme_ru.md │ ├── readme_tr.md │ ├── readme_ua.md │ └── readme_zhtw.md ├── e2e-tests ├── 001-sanity-tests │ ├── 001-home-screen.spec.ts │ └── 002-create-new-collection.spec.ts ├── bruno-testbench │ ├── init-user-data │ │ └── preferences.json │ └── run-testbench-requests.spec.ts └── preferences │ └── verify-support-links-in-preferences.spec.js ├── eslint.config.js ├── license.md ├── package-lock.json ├── package.json ├── packages ├── bruno-app │ ├── .babelrc │ ├── .env.production │ ├── .gitignore │ ├── .prettierrc.json │ ├── jest.config.js │ ├── jsconfig.json │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ └── theme │ │ │ ├── dark.js │ │ │ ├── index.js │ │ │ └── light.js │ ├── rsbuild.config.mjs │ ├── src │ │ ├── assets │ │ │ ├── github.svg │ │ │ └── send.svg │ │ ├── components │ │ │ ├── Accordion │ │ │ │ ├── index.js │ │ │ │ └── styledWrapper.js │ │ │ ├── Bruno │ │ │ │ └── index.js │ │ │ ├── BrunoSupport │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── CodeEditor │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── CollectionSettings │ │ │ │ ├── Auth │ │ │ │ │ ├── ApiKeyAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── AuthMode │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── AwsV4Auth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── BasicAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── BearerAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── DigestAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── NTLMAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── OAuth2 │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ ├── WsseAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ └── index.js │ │ │ │ ├── ClientCertSettings │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Docs │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Headers │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Overview │ │ │ │ │ ├── Info │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── RequestsNotLoaded │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Presets │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ProxySettings │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Script │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ ├── Tests │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Vars │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ ├── VarsTable │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ ├── Cookies │ │ │ │ ├── ModifyCookieModal │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── Documentation │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── Dropdown │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── Environments │ │ │ │ ├── EnvironmentSelector │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ └── EnvironmentSettings │ │ │ │ │ ├── CopyEnvironment │ │ │ │ │ └── index.js │ │ │ │ │ ├── CreateEnvironment │ │ │ │ │ └── index.js │ │ │ │ │ ├── DeleteEnvironment │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ │ ├── EnvironmentList │ │ │ │ │ ├── ConfirmSwitchEnv.js │ │ │ │ │ ├── EnvironmentDetails │ │ │ │ │ │ ├── EnvironmentVariables │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ │ ├── ImportEnvironment │ │ │ │ │ └── index.js │ │ │ │ │ ├── ManageSecrets │ │ │ │ │ └── index.js │ │ │ │ │ ├── RenameEnvironment │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ ├── FilePickerEditor │ │ │ │ └── index.js │ │ │ ├── FolderSettings │ │ │ │ ├── Auth │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── AuthMode │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Documentation │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Headers │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Script │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ ├── Tests │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Vars │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ ├── VarsTable │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ ├── GlobalEnvironments │ │ │ │ ├── EnvironmentSelector │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ └── EnvironmentSettings │ │ │ │ │ ├── CopyEnvironment │ │ │ │ │ └── index.js │ │ │ │ │ ├── CreateEnvironment │ │ │ │ │ └── index.js │ │ │ │ │ ├── DeleteEnvironment │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ │ ├── EnvironmentList │ │ │ │ │ ├── ConfirmSwitchEnv.js │ │ │ │ │ ├── EnvironmentDetails │ │ │ │ │ │ ├── EnvironmentVariables │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ │ ├── ImportEnvironment │ │ │ │ │ └── index.js │ │ │ │ │ ├── RenameEnvironment │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ ├── Help │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── Icons │ │ │ │ ├── Dot │ │ │ │ │ └── index.js │ │ │ │ ├── Help │ │ │ │ │ └── index.js │ │ │ │ ├── OpenAPILogo │ │ │ │ │ └── index.js │ │ │ │ └── Send │ │ │ │ │ └── index.js │ │ │ ├── InfoTip │ │ │ │ └── index.js │ │ │ ├── MarkDown │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.jsx │ │ │ ├── Modal │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── MultiLineEditor │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── Notifications │ │ │ │ ├── StyleWrapper.js │ │ │ │ └── index.js │ │ │ ├── PathDisplay │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── Portal │ │ │ │ └── index.js │ │ │ ├── Preferences │ │ │ │ ├── Display │ │ │ │ │ ├── Font │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── Theme │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ └── index.js │ │ │ │ ├── General │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Keybindings │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ProxySettings │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ ├── Support │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ ├── ReorderTable │ │ │ │ └── index.js │ │ │ ├── RequestPane │ │ │ │ ├── Assertions │ │ │ │ │ ├── AssertionOperator │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── AssertionRow │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Auth │ │ │ │ │ ├── ApiKeyAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── AuthMode │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── AwsV4Auth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── BasicAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── BearerAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── DigestAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── NTLMAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── OAuth2 │ │ │ │ │ │ ├── AuthorizationCode │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── inputsConfig.js │ │ │ │ │ │ ├── ClientCredentials │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── inputsConfig.js │ │ │ │ │ │ ├── GrantTypeSelector │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Oauth2ActionButtons │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Oauth2TokenViewer │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── PasswordCredentials │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── inputsConfig.js │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ ├── WsseAuth │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ └── index.js │ │ │ │ ├── FileBody │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── FormUrlEncodedParams │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── GraphQLRequestPane │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── GraphQLSchemaActions │ │ │ │ │ ├── index.js │ │ │ │ │ └── useGraphqlSchema.js │ │ │ │ ├── GraphQLVariables │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── HttpRequestPane │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── MultipartFormParams │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── QueryEditor │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── onHasCompletion.js │ │ │ │ ├── QueryParams │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── QueryUrl │ │ │ │ │ ├── HttpMethodSelector │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── RequestBody │ │ │ │ │ ├── RequestBodyMode │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── RequestHeaders │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Script │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Tests │ │ │ │ │ └── index.js │ │ │ │ └── Vars │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ ├── VarsTable │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ │ └── index.js │ │ │ ├── RequestTabPanel │ │ │ │ ├── FolderNotFound │ │ │ │ │ └── index.js │ │ │ │ ├── RequestIsLoading │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── RequestNotFound │ │ │ │ │ └── index.js │ │ │ │ ├── RequestNotLoaded │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── RequestTabs │ │ │ │ ├── CollectionToolBar │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── RequestTab │ │ │ │ │ ├── CloseTabIcon.js │ │ │ │ │ ├── ConfirmRequestClose │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── DraftTabIcon.js │ │ │ │ │ ├── RequestTabNotFound.js │ │ │ │ │ ├── SpecialTab.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── ResponsePane │ │ │ │ ├── ClearTimeline │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── NetworkError │ │ │ │ │ └── index.js │ │ │ │ ├── Overlay │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── Placeholder │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── QueryResult │ │ │ │ │ ├── QueryResultFilter │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── QueryResultPreview │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ResponseClear │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ResponseHeaders │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ResponseSave │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ResponseSize │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ResponseTime │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── RunnerTimeline │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ScriptError │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ScriptErrorIcon │ │ │ │ │ └── index.js │ │ │ │ ├── SkippedRequest │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StatusCode │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ ├── get-status-code-phrase.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ ├── TestResults │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── TestResultsLabel │ │ │ │ │ └── index.js │ │ │ │ ├── Timeline │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ ├── TimelineItem │ │ │ │ │ │ ├── Common │ │ │ │ │ │ │ ├── Body │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── Headers │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── Method │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── Status │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ └── Time │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Network │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Request │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── Response │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ └── index.js │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ ├── RunnerResults │ │ │ │ ├── ResponsePane │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.jsx │ │ │ ├── SecuritySettings │ │ │ │ ├── JsSandboxMode │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── JsSandboxModeModal │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── ShareCollection │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── Sidebar │ │ │ │ ├── Collections │ │ │ │ │ ├── Collection │ │ │ │ │ │ ├── CloneCollection │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── CollectionItem │ │ │ │ │ │ │ ├── CloneCollectionItem │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── CollectionItemDragPreview │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── CollectionItemIcon │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── CollectionItemInfo │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── DeleteCollectionItem │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── GenerateCodeItem │ │ │ │ │ │ │ │ ├── CodeView │ │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── RenameCollectionItem │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── RequestMethod │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── RunCollectionItem │ │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── ExportCollection │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── RemoveCollection │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── RenameCollection │ │ │ │ │ │ │ └── index.js │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── CreateOrOpenCollection │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── SelectCollection │ │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── CreateCollection │ │ │ │ │ └── index.js │ │ │ │ ├── GoldenEdition │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── ImportCollection │ │ │ │ │ └── index.js │ │ │ │ ├── ImportCollectionLocation │ │ │ │ │ └── index.js │ │ │ │ ├── NewFolder │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── NewRequest │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ ├── TitleBar │ │ │ │ │ ├── StyledWrapper.js │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ ├── SingleLineEditor │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── Spinner │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── StopWatch │ │ │ │ └── index.js │ │ │ ├── Table │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── ToggleSwitch │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── ToolHint │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── VariablesEditor │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ └── Welcome │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ ├── globalStyles.js │ │ ├── hooks │ │ │ ├── useFocusTrap │ │ │ │ └── index.js │ │ │ ├── useLocalStorage │ │ │ │ └── index.js │ │ │ ├── useOnClickOutside │ │ │ │ └── index.js │ │ │ └── usePrevious │ │ │ │ └── index.js │ │ ├── i18n │ │ │ ├── index.js │ │ │ └── translation │ │ │ │ └── en.json │ │ ├── index.js │ │ ├── pages │ │ │ ├── Bruno │ │ │ │ ├── StyledWrapper.js │ │ │ │ └── index.js │ │ │ ├── ErrorBoundary │ │ │ │ └── index.js │ │ │ ├── Main.js │ │ │ └── index.js │ │ ├── providers │ │ │ ├── App │ │ │ │ ├── ConfirmAppClose │ │ │ │ │ ├── SaveRequestsModal.js │ │ │ │ │ └── index.js │ │ │ │ ├── StyledWrapper.js │ │ │ │ ├── index.js │ │ │ │ ├── useIpcEvents.js │ │ │ │ └── useTelemetry.js │ │ │ ├── Hotkeys │ │ │ │ ├── index.js │ │ │ │ └── keyMappings.js │ │ │ ├── ReduxStore │ │ │ │ ├── index.js │ │ │ │ ├── middlewares │ │ │ │ │ ├── debug │ │ │ │ │ │ └── middleware.js │ │ │ │ │ ├── draft │ │ │ │ │ │ ├── middleware.js │ │ │ │ │ │ └── utils.js │ │ │ │ │ └── tasks │ │ │ │ │ │ ├── middleware.js │ │ │ │ │ │ └── utils.js │ │ │ │ └── slices │ │ │ │ │ ├── app.js │ │ │ │ │ ├── collections │ │ │ │ │ ├── actions.js │ │ │ │ │ └── index.js │ │ │ │ │ ├── global-environments.js │ │ │ │ │ ├── notifications.js │ │ │ │ │ ├── notifications.spec.js │ │ │ │ │ └── tabs.js │ │ │ ├── Theme │ │ │ │ └── index.js │ │ │ └── Toaster │ │ │ │ └── index.js │ │ ├── selectors │ │ │ └── tab.js │ │ ├── styles │ │ │ ├── _buttons.scss │ │ │ ├── app.scss │ │ │ └── globals.css │ │ ├── themes │ │ │ ├── dark.js │ │ │ ├── index.js │ │ │ └── light.js │ │ └── utils │ │ │ ├── codegenerator │ │ │ ├── auth.js │ │ │ ├── har.js │ │ │ └── targets.js │ │ │ ├── codemirror │ │ │ ├── autocomplete.js │ │ │ ├── autocompleteConstants.js │ │ │ ├── brunoVarInfo.js │ │ │ └── javascript-lint.js │ │ │ ├── collections │ │ │ ├── export.js │ │ │ ├── index.js │ │ │ └── search.js │ │ │ ├── common │ │ │ ├── codemirror.js │ │ │ ├── error.js │ │ │ ├── index.js │ │ │ ├── index.spec.js │ │ │ ├── ipc.js │ │ │ ├── path.js │ │ │ ├── platform.js │ │ │ ├── regex.js │ │ │ ├── regex.spec.js │ │ │ └── setupPolyfills.js │ │ │ ├── curl │ │ │ ├── curl-to-json.js │ │ │ ├── curl-to-json.spec.js │ │ │ ├── index.js │ │ │ ├── parse-curl.js │ │ │ └── parse-curl.spec.js │ │ │ ├── exporters │ │ │ └── postman-collection.js │ │ │ ├── idb │ │ │ └── index.js │ │ │ ├── importers │ │ │ ├── bruno-collection.js │ │ │ ├── common.js │ │ │ ├── insomnia-collection.js │ │ │ ├── openapi-collection.js │ │ │ ├── postman-collection.js │ │ │ └── postman-environment.js │ │ │ ├── network │ │ │ ├── cancelTokens.js │ │ │ └── index.js │ │ │ ├── tabs │ │ │ └── index.js │ │ │ ├── tests │ │ │ └── collections │ │ │ │ └── items-sequencing.spec.js │ │ │ └── url │ │ │ ├── index.js │ │ │ └── index.spec.js │ └── tailwind.config.js ├── bruno-cli │ ├── .gitignore │ ├── assets │ │ └── images │ │ │ └── cli-demo.png │ ├── bin │ │ └── bru.js │ ├── changelog.md │ ├── examples │ │ ├── report.html │ │ └── report.json │ ├── license.md │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── commands │ │ │ ├── import.js │ │ │ └── run.js │ │ ├── constants.js │ │ ├── index.js │ │ ├── reporters │ │ │ ├── html-template.html │ │ │ ├── html.js │ │ │ └── junit.js │ │ ├── runner │ │ │ ├── awsv4auth-helper.js │ │ │ ├── interpolate-string.js │ │ │ ├── interpolate-vars.js │ │ │ ├── oauth2.js │ │ │ ├── prepare-request.js │ │ │ ├── run-single-request.js │ │ │ └── tokenStore.js │ │ └── utils │ │ │ ├── axios-instance.js │ │ │ ├── bru.js │ │ │ ├── collection.js │ │ │ ├── common.js │ │ │ ├── cookies.js │ │ │ ├── filesystem.js │ │ │ ├── form-data.js │ │ │ └── proxy-util.js │ └── tests │ │ ├── reporters │ │ └── junit.spec.js │ │ └── runner │ │ ├── collection-json-from-pathname.spec.js │ │ ├── fixtures │ │ └── collection-json-from-pathname │ │ │ └── collection │ │ │ ├── bruno.json │ │ │ ├── collection.bru │ │ │ ├── folder_1 │ │ │ ├── folder.bru │ │ │ ├── folder_1 │ │ │ │ ├── folder.bru │ │ │ │ ├── request_1.bru │ │ │ │ ├── request_2.bru │ │ │ │ └── request_3.bru │ │ │ ├── folder_2 │ │ │ │ ├── folder.bru │ │ │ │ ├── request_1.bru │ │ │ │ ├── request_2.bru │ │ │ │ └── request_3.bru │ │ │ ├── request_1.bru │ │ │ ├── request_2.bru │ │ │ └── request_3.bru │ │ │ ├── folder_2 │ │ │ ├── folder.bru │ │ │ ├── request_1.bru │ │ │ ├── request_2.bru │ │ │ └── request_3.bru │ │ │ ├── request_1.bru │ │ │ ├── request_2.bru │ │ │ └── request_3.bru │ │ └── prepare-request.spec.js ├── bruno-common │ ├── .gitignore │ ├── babel.config.js │ ├── jest.config.js │ ├── license.md │ ├── package.json │ ├── readme.md │ ├── rollup.config.js │ ├── src │ │ ├── index.ts │ │ ├── interpolate │ │ │ ├── index.spec.ts │ │ │ └── index.ts │ │ ├── runner │ │ │ ├── index.ts │ │ │ ├── reports │ │ │ │ └── html │ │ │ │ │ ├── generate-report.ts │ │ │ │ │ └── template.ts │ │ │ ├── runner-summary.ts │ │ │ ├── types │ │ │ │ └── index.ts │ │ │ └── utils │ │ │ │ └── index.ts │ │ └── utils │ │ │ ├── faker-functions.spec.ts │ │ │ └── faker-functions.ts │ └── tsconfig.json ├── bruno-converters │ ├── .gitignore │ ├── babel.config.js │ ├── jest.config.js │ ├── jest.setup.js │ ├── license.md │ ├── package.json │ ├── readme.md │ ├── rollup.config.js │ ├── src │ │ ├── common │ │ │ └── index.js │ │ ├── constants │ │ │ ├── index.js │ │ │ └── regex.js │ │ ├── index.js │ │ ├── insomnia │ │ │ └── insomnia-to-bruno.js │ │ ├── openapi │ │ │ └── openapi-to-bruno.js │ │ ├── postman │ │ │ ├── bruno-to-postman.js │ │ │ ├── postman-env-to-bruno-env.js │ │ │ ├── postman-to-bruno.js │ │ │ └── postman-translations.js │ │ ├── utils │ │ │ └── jscode-shift-translator.js │ │ └── workers │ │ │ ├── postman-translator-worker.js │ │ │ └── scripts │ │ │ └── translate-postman-scripts.js │ ├── tests │ │ ├── insomnia │ │ │ ├── insomnia-collection-v5.spec.js │ │ │ └── insomnia-collection.spec.js │ │ ├── openapi │ │ │ └── openapi-to-bruno │ │ │ │ ├── openapi-circular-references.spec.js │ │ │ │ └── openapi-to-bruno.spec.js │ │ ├── postman │ │ │ ├── bruno-to-postman.spec.js │ │ │ ├── postman-env-to-bruno-env.spec.js │ │ │ ├── postman-to-bruno │ │ │ │ ├── collection-auth.spec.js │ │ │ │ ├── folder-auth.spec.js │ │ │ │ ├── postman-to-bruno.spec.js │ │ │ │ ├── postman-translations │ │ │ │ │ ├── postman-request.spec.js │ │ │ │ │ └── postman-response.spec.js │ │ │ │ └── request-auth.spec.js │ │ │ └── postman-translations │ │ │ │ ├── postman-comments.spec.js │ │ │ │ ├── postman-edge-cases.spec.js │ │ │ │ ├── postman-test-commands.spec.js │ │ │ │ ├── postman-variables.spec.js │ │ │ │ └── transpiler-tests │ │ │ │ ├── combined.test.js │ │ │ │ ├── environment.test.js │ │ │ │ ├── exec-flow.test.js │ │ │ │ ├── legacy-tests-syntax.test.js │ │ │ │ ├── multiline-syntax.test.js │ │ │ │ ├── postman-references.test.js │ │ │ │ ├── request.test.js │ │ │ │ ├── response.test.js │ │ │ │ ├── scoped-variables.test.js │ │ │ │ ├── testing-framework.test.js │ │ │ │ ├── variable-chaining.test.js │ │ │ │ └── variables.test.js │ │ └── utils │ │ │ └── getMemberExpressionString.test.js │ ├── tsconfig.json │ └── types │ │ └── common.d.ts ├── bruno-docs │ ├── package.json │ └── readme.md ├── bruno-electron │ ├── .env.sample │ ├── .gitignore │ ├── electron-builder-config.js │ ├── notarize.js │ ├── package.json │ ├── readme.md │ ├── resources │ │ ├── entitlements.mac.plist │ │ └── icons │ │ │ ├── mac │ │ │ └── icon.icns │ │ │ ├── png │ │ │ ├── 1024x1024.png │ │ │ ├── 128x128.png │ │ │ ├── 16x16.png │ │ │ ├── 24x24.png │ │ │ ├── 256x256.png │ │ │ ├── 32x32.png │ │ │ ├── 48x48.png │ │ │ ├── 512x512.png │ │ │ └── 64x64.png │ │ │ └── win │ │ │ └── icon.ico │ ├── src │ │ ├── about │ │ │ ├── 256x256.png │ │ │ └── about.css │ │ ├── app │ │ │ ├── about-bruno.js │ │ │ ├── collections.js │ │ │ ├── menu-template.js │ │ │ └── watcher.js │ │ ├── bru │ │ │ ├── index.js │ │ │ └── workers │ │ │ │ ├── index.js │ │ │ │ └── scripts │ │ │ │ ├── bru-to-json.js │ │ │ │ └── json-to-bru.js │ │ ├── cache │ │ │ └── requestUids.js │ │ ├── index.js │ │ ├── ipc │ │ │ ├── collection.js │ │ │ ├── global-environments.js │ │ │ ├── network │ │ │ │ ├── authorize-user-in-window.js │ │ │ │ ├── awsv4auth-helper.js │ │ │ │ ├── axios-instance.js │ │ │ │ ├── index.js │ │ │ │ ├── interpolate-string.js │ │ │ │ ├── interpolate-vars.js │ │ │ │ ├── prepare-gql-introspection-request.js │ │ │ │ └── prepare-request.js │ │ │ ├── notifications.js │ │ │ └── preferences.js │ │ ├── preload.js │ │ ├── store │ │ │ ├── bruno-config.js │ │ │ ├── collection-security.js │ │ │ ├── env-secrets.js │ │ │ ├── global-environments.js │ │ │ ├── last-opened-collections.js │ │ │ ├── oauth2.js │ │ │ ├── preferences.js │ │ │ ├── process-env.js │ │ │ ├── ui-state-snapshot.js │ │ │ └── window-state.js │ │ ├── utils │ │ │ ├── cancel-token.js │ │ │ ├── collection.js │ │ │ ├── common.js │ │ │ ├── cookies.js │ │ │ ├── encryption.js │ │ │ ├── filesystem.js │ │ │ ├── filesystem.test.js │ │ │ ├── form-data.js │ │ │ ├── oauth2.js │ │ │ ├── proxy-util.js │ │ │ ├── tests │ │ │ │ ├── filesystem │ │ │ │ │ └── index.spec.js │ │ │ │ └── fixtures │ │ │ │ │ └── filesystem │ │ │ │ │ └── copypath-removepath.js │ │ │ └── window.js │ │ └── workers │ │ │ └── index.js │ └── tests │ │ ├── network │ │ ├── authorize-user.spec.js │ │ ├── index.spec.js │ │ ├── interpolate-vars.spec.js │ │ └── prepare-request.spec.js │ │ └── utils │ │ ├── collection.spec.js │ │ ├── common.spec.js │ │ ├── encryption.spec.js │ │ └── proxy-util.spec.js ├── bruno-graphql-docs │ ├── .gitignore │ ├── license.md │ ├── package.json │ ├── readme.md │ ├── rollup.config.js │ ├── src │ │ ├── components │ │ │ ├── DocExplorer.tsx │ │ │ └── DocExplorer │ │ │ │ ├── Argument.tsx │ │ │ │ ├── DefaultValue.tsx │ │ │ │ ├── Directive.tsx │ │ │ │ ├── FieldDoc.tsx │ │ │ │ ├── MarkdownContent.tsx │ │ │ │ ├── SchemaDoc.tsx │ │ │ │ ├── SearchBox.tsx │ │ │ │ ├── SearchResults.tsx │ │ │ │ ├── TypeDoc.tsx │ │ │ │ ├── TypeLink.tsx │ │ │ │ └── types.ts │ │ ├── index.css │ │ ├── index.ts │ │ └── utility │ │ │ └── debounce.ts │ └── tsconfig.json ├── bruno-js │ ├── .gitignore │ ├── license.md │ ├── package.json │ ├── readme.md │ ├── src │ │ ├── bru.js │ │ ├── bruno-request.js │ │ ├── bruno-response.js │ │ ├── index.js │ │ ├── interpolate-string.js │ │ ├── runtime │ │ │ ├── assert-runtime.js │ │ │ ├── script-runtime.js │ │ │ ├── test-runtime.js │ │ │ └── vars-runtime.js │ │ ├── sandbox │ │ │ ├── bundle-libraries.js │ │ │ └── quickjs │ │ │ │ ├── index.js │ │ │ │ ├── shims │ │ │ │ ├── bru.js │ │ │ │ ├── bruno-request.js │ │ │ │ ├── bruno-response.js │ │ │ │ ├── console.js │ │ │ │ ├── lib │ │ │ │ │ ├── axios.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── nanoid.js │ │ │ │ │ ├── path.js │ │ │ │ │ └── uuid.js │ │ │ │ ├── local-module.js │ │ │ │ └── test.js │ │ │ │ └── utils │ │ │ │ └── index.js │ │ ├── test-results.js │ │ ├── test.js │ │ └── utils.js │ └── tests │ │ ├── runtime.spec.js │ │ └── utils.spec.js ├── bruno-lang │ ├── .gitignore │ ├── example │ │ ├── request.bru │ │ ├── request.json │ │ └── request.next.bru │ ├── license.md │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.js │ ├── v1 │ │ ├── src │ │ │ ├── body-tag.js │ │ │ ├── env-vars-tag.js │ │ │ ├── headers-tag.js │ │ │ ├── index.js │ │ │ ├── inline-tag.js │ │ │ ├── key-val-lines.js │ │ │ ├── params-tag.js │ │ │ ├── script-tag.js │ │ │ ├── tests-tag.js │ │ │ └── utils.js │ │ └── tests │ │ │ ├── body-tag.spec.js │ │ │ ├── bru-to-env-json.spec.js │ │ │ ├── bru-to-json.spec.js │ │ │ ├── env-json-to-bru.spec.js │ │ │ ├── fixtures │ │ │ ├── env.bru │ │ │ └── request.bru │ │ │ ├── inline-tag.spec.js │ │ │ ├── json-to-bru.spec.js │ │ │ ├── key-val-lines.spec.js │ │ │ ├── script-tag.spec.js │ │ │ ├── tests-tag.spec.js │ │ │ └── utils.spec.js │ └── v2 │ │ ├── src │ │ ├── bruToJson.js │ │ ├── collectionBruToJson.js │ │ ├── dotenvToJson.js │ │ ├── envToJson.js │ │ ├── jsonToBru.js │ │ ├── jsonToCollectionBru.js │ │ ├── jsonToEnv.js │ │ └── utils.js │ │ └── tests │ │ ├── assert.spec.js │ │ ├── collection.spec.js │ │ ├── defaults.spec.js │ │ ├── dictionary.spec.js │ │ ├── dotenvToJson.spec.js │ │ ├── envToJson.spec.js │ │ ├── fixtures │ │ ├── collection.bru │ │ ├── collection.json │ │ ├── request.bru │ │ └── request.json │ │ ├── index.spec.js │ │ ├── jsonToEnv.spec.js │ │ └── script.spec.js ├── bruno-query │ ├── .gitignore │ ├── jest.config.js │ ├── license.md │ ├── package.json │ ├── readme.md │ ├── rollup.config.js │ ├── src │ │ └── index.ts │ ├── tests │ │ └── index.spec.ts │ └── tsconfig.json ├── bruno-requests │ ├── .gitignore │ ├── package.json │ ├── rollup.config.js │ ├── src │ │ ├── auth │ │ │ ├── digestauth-helper.js │ │ │ ├── index.ts │ │ │ └── oauth2-helper.ts │ │ ├── index.ts │ │ └── utils │ │ │ ├── cookie-utils.js │ │ │ └── index.ts │ └── tsconfig.json ├── bruno-schema │ ├── .gitignore │ ├── license.md │ ├── package.json │ ├── readme.md │ └── src │ │ ├── collections │ │ ├── index.js │ │ ├── index.spec.js │ │ ├── itemSchema.spec.js │ │ └── requestSchema.spec.js │ │ ├── common │ │ └── index.js │ │ ├── index.js │ │ └── utils │ │ └── testUtils.js ├── bruno-tests │ ├── .gitignore │ ├── .nvmrc │ ├── collection │ │ ├── .env │ │ ├── .gitignore │ │ ├── .nvmrc │ │ ├── asserts │ │ │ └── test-assert-combinations.bru │ │ ├── auth │ │ │ ├── basic │ │ │ │ ├── via auth │ │ │ │ │ ├── Basic Auth 200.bru │ │ │ │ │ └── Basic Auth 401.bru │ │ │ │ └── via script │ │ │ │ │ ├── Basic Auth 200.bru │ │ │ │ │ └── Basic Auth 401.bru │ │ │ ├── bearer │ │ │ │ ├── via auth │ │ │ │ │ └── Bearer Auth 200.bru │ │ │ │ └── via headers │ │ │ │ │ └── Bearer Auth 200.bru │ │ │ ├── cookie │ │ │ │ ├── Check.bru │ │ │ │ └── Login.bru │ │ │ ├── digest │ │ │ │ ├── Digest Auth 200.bru │ │ │ │ ├── Digest Auth 401.bru │ │ │ │ └── folder.bru │ │ │ └── inherit auth │ │ │ │ └── inherit Bearer Auth 200.bru │ │ ├── bruno.json │ │ ├── bruno.png │ │ ├── collection.bru │ │ ├── echo │ │ │ ├── echo bom json.bru │ │ │ ├── echo form-url-encoded.bru │ │ │ ├── echo headers.bru │ │ │ ├── echo json.bru │ │ │ ├── echo multipart scripting.bru │ │ │ ├── echo multipart.bru │ │ │ ├── echo numbers.bru │ │ │ ├── echo plaintext.bru │ │ │ ├── echo xml parsed(self closing tags).bru │ │ │ ├── echo xml parsed.bru │ │ │ ├── echo xml raw.bru │ │ │ ├── multiline │ │ │ │ └── echo binary.bru │ │ │ ├── test echo any.bru │ │ │ └── test echo-any json.bru │ │ ├── environments │ │ │ ├── Local.bru │ │ │ └── Prod.bru │ │ ├── file.json │ │ ├── file.txt │ │ ├── graphql │ │ │ └── spacex.bru │ │ ├── lib │ │ │ ├── constants.js │ │ │ ├── math.js │ │ │ └── notes.js │ │ ├── multipart │ │ │ └── small.png │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── ping.bru │ │ ├── preview │ │ │ ├── html │ │ │ │ └── bruno.bru │ │ │ └── image │ │ │ │ └── bruno.bru │ │ ├── readme.md │ │ ├── redirects │ │ │ ├── Disable Redirect.bru │ │ │ └── Test Redirect.bru │ │ ├── response-parsing │ │ │ ├── test JSON false response.bru │ │ │ ├── test JSON null response.bru │ │ │ ├── test JSON number response.bru │ │ │ ├── test JSON response.bru │ │ │ ├── test JSON string response.bru │ │ │ ├── test JSON string with quotes response.bru │ │ │ ├── test JSON true response.bru │ │ │ ├── test JSON unsafe-int response.bru │ │ │ ├── test binary response.bru │ │ │ ├── test html response.bru │ │ │ ├── test image response.bru │ │ │ ├── test invalid JSON response with formatting.bru │ │ │ ├── test plain text response with formatting.bru │ │ │ ├── test plain text response.bru │ │ │ ├── test plain text utf16 response.bru │ │ │ ├── test plain text utf16-be with BOM response.bru │ │ │ ├── test plain text utf16-le with BOM response.bru │ │ │ ├── test plain text utf8 with BOM response.bru │ │ │ └── test xml response.bru │ │ ├── scripting │ │ │ ├── api │ │ │ │ ├── bru │ │ │ │ │ ├── folder.bru │ │ │ │ │ ├── getCollectionName.bru │ │ │ │ │ ├── getCollectionVar.bru │ │ │ │ │ ├── getEnvName.bru │ │ │ │ │ ├── getEnvVar.bru │ │ │ │ │ ├── getFolderVar.bru │ │ │ │ │ ├── getProcessEnv.bru │ │ │ │ │ ├── getRequestVar.bru │ │ │ │ │ ├── getVar.bru │ │ │ │ │ ├── interpolate.bru │ │ │ │ │ ├── runRequest-1.bru │ │ │ │ │ ├── runRequest-2.bru │ │ │ │ │ ├── runRequest.bru │ │ │ │ │ ├── runner │ │ │ │ │ │ ├── 1.bru │ │ │ │ │ │ ├── 2.bru │ │ │ │ │ │ └── 3.bru │ │ │ │ │ ├── setEnvVar.bru │ │ │ │ │ └── setVar.bru │ │ │ │ ├── req │ │ │ │ │ ├── getBody.bru │ │ │ │ │ ├── getHeader.bru │ │ │ │ │ ├── getHeaders.bru │ │ │ │ │ ├── getMethod.bru │ │ │ │ │ ├── getName.bru │ │ │ │ │ ├── getUrl.bru │ │ │ │ │ ├── setBody.bru │ │ │ │ │ ├── setHeader.bru │ │ │ │ │ ├── setHeaders.bru │ │ │ │ │ ├── setMethod.bru │ │ │ │ │ └── setUrl.bru │ │ │ │ └── res │ │ │ │ │ ├── getBody.bru │ │ │ │ │ ├── getHeader.bru │ │ │ │ │ ├── getHeaders.bru │ │ │ │ │ ├── getResponseTime.bru │ │ │ │ │ ├── getStatus.bru │ │ │ │ │ ├── getStatusText.bru │ │ │ │ │ └── setBody │ │ │ │ │ ├── array.bru │ │ │ │ │ ├── boolean.bru │ │ │ │ │ ├── folder.bru │ │ │ │ │ ├── null.bru │ │ │ │ │ ├── number.bru │ │ │ │ │ ├── object.bru │ │ │ │ │ ├── string.bru │ │ │ │ │ └── undefined.bru │ │ │ ├── inbuilt modules │ │ │ │ ├── axios │ │ │ │ │ └── axios-pre-req-script.bru │ │ │ │ ├── cheerio │ │ │ │ │ └── cheerio.bru │ │ │ │ ├── crypto-js │ │ │ │ │ └── crypto-js-pre-request-script.bru │ │ │ │ ├── nanoid │ │ │ │ │ └── nanoid.bru │ │ │ │ ├── tv4 │ │ │ │ │ ├── folder.bru │ │ │ │ │ └── tv4.bru │ │ │ │ ├── uuid │ │ │ │ │ └── uuid.bru │ │ │ │ └── xml2js │ │ │ │ │ └── xml2js.bru │ │ │ ├── js │ │ │ │ ├── data types - request vars.bru │ │ │ │ ├── data types.bru │ │ │ │ ├── folder-collection script-tests pre.bru │ │ │ │ ├── folder-collection script-tests.bru │ │ │ │ ├── folder.bru │ │ │ │ └── setTimeout.bru │ │ │ ├── local modules │ │ │ │ ├── invalid and valid module imports.bru │ │ │ │ ├── sum (without js extn).bru │ │ │ │ └── sum.bru │ │ │ └── npm modules │ │ │ │ └── fakerjs.bru │ │ └── string interpolation │ │ │ ├── env vars.bru │ │ │ ├── folder.bru │ │ │ ├── missing values.bru │ │ │ ├── objects-arrays interpolation.bru │ │ │ ├── process env vars.bru │ │ │ └── runtime vars.bru │ ├── collection_level_oauth2 │ │ ├── .gitignore │ │ ├── .nvmrc │ │ ├── bruno.json │ │ ├── collection.bru │ │ ├── environments │ │ │ ├── Local.bru │ │ │ └── Prod.bru │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── readme.md │ │ └── resource.bru │ ├── collection_oauth2 │ │ ├── .env │ │ ├── .gitignore │ │ ├── .nvmrc │ │ ├── auth │ │ │ └── oauth2 │ │ │ │ ├── authorization_code │ │ │ │ ├── github token with authorize.bru │ │ │ │ ├── google token with authorize.bru │ │ │ │ ├── resource.bru │ │ │ │ └── token with authorize.bru │ │ │ │ ├── client_credentials │ │ │ │ ├── resource.bru │ │ │ │ └── token.bru │ │ │ │ └── password_credentials │ │ │ │ ├── resource.bru │ │ │ │ └── token.bru │ │ ├── bruno.json │ │ ├── collection.bru │ │ ├── environments │ │ │ ├── Local.bru │ │ │ └── Prod.bru │ │ ├── file.json │ │ ├── package-lock.json │ │ ├── package.json │ │ └── readme.md │ ├── keycloak-authorization_code │ │ ├── bruno.json │ │ ├── collection.bru │ │ ├── environments │ │ │ └── oauth2.bru │ │ ├── user_info_coll-auth.bru │ │ ├── user_info_custom.bru │ │ └── user_info_request-auth.bru │ ├── keycloak-client-credentials │ │ ├── bruno.json │ │ ├── collection.bru │ │ ├── environments │ │ │ └── oauth2.bru │ │ ├── user_info_coll-auth.bru │ │ ├── user_info_custom.bru │ │ └── user_info_request-auth.bru │ ├── keycloak-password-credentials │ │ ├── bruno.json │ │ ├── collection.bru │ │ ├── environments │ │ │ └── oauth2.bru │ │ ├── user_info_coll-auth.bru │ │ ├── user_info_custom.bru │ │ └── user_info_request-auth.bru │ ├── package.json │ ├── readme.md │ ├── sandwich_exec │ │ ├── bruno.json │ │ ├── collection.bru │ │ └── folder │ │ │ ├── folder.bru │ │ │ └── request.bru │ ├── sequential_exec │ │ ├── bruno.json │ │ ├── collection.bru │ │ └── folder │ │ │ ├── folder.bru │ │ │ └── request.bru │ └── src │ │ ├── auth │ │ ├── basic.js │ │ ├── bearer.js │ │ ├── cookie.js │ │ ├── index.js │ │ ├── oauth2 │ │ │ ├── authorizationCode.js │ │ │ ├── clientCredentials.js │ │ │ └── passwordCredentials.js │ │ └── wsse.js │ │ ├── echo │ │ └── index.js │ │ ├── index.js │ │ ├── multipart │ │ ├── form-data-parser.js │ │ └── index.js │ │ └── utils │ │ └── xmlParser.js └── bruno-toml │ ├── lib │ └── stringify │ ├── package.json │ ├── src │ ├── jsonToToml.js │ └── tomlToJson.js │ └── tests │ ├── headers │ ├── disabled-header │ │ ├── request.json │ │ └── request.toml │ ├── dotted-header │ │ ├── request.json │ │ └── request.toml │ ├── duplicate-header │ │ ├── request.json │ │ └── request.toml │ ├── empty-header │ │ ├── request.json │ │ └── request.toml │ ├── reserved-header │ │ ├── request.json │ │ └── request.toml │ ├── simple-header │ │ ├── request.json │ │ └── request.toml │ ├── spaces-in-header │ │ ├── request.json │ │ └── request.toml │ └── unicode-in-header │ │ ├── request.json │ │ └── request.toml │ ├── index.spec.js │ ├── methods │ ├── delete │ │ ├── request.json │ │ └── request.toml │ └── get │ │ ├── request.json │ │ └── request.toml │ └── scripts │ ├── post-response │ ├── request.json │ └── request.toml │ ├── pre-request │ ├── request.json │ └── request.toml │ └── tests │ ├── request.json │ └── request.toml ├── playwright.config.ts ├── playwright ├── codegen.ts ├── electron.ts └── index.ts ├── publishing.md ├── readme.md ├── scripts ├── build-electron.js ├── build-electron.sh └── setup.js └── security.md /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @helloanoop @maintainer-bruno @lohit-bruno @naman-bruno 2 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v22.11.0 2 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true, 6 | "printWidth": 120 7 | } 8 | -------------------------------------------------------------------------------- /assets/images/cli-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/assets/images/cli-demo.png -------------------------------------------------------------------------------- /assets/images/landing-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/assets/images/landing-2.png -------------------------------------------------------------------------------- /assets/images/local-collections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/assets/images/local-collections.png -------------------------------------------------------------------------------- /assets/images/logo-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/assets/images/logo-transparent.png -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/assets/images/logo.png -------------------------------------------------------------------------------- /assets/images/run-anywhere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/assets/images/run-anywhere.png -------------------------------------------------------------------------------- /assets/images/version-control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/assets/images/version-control.png -------------------------------------------------------------------------------- /docs/publishing/publishing_bn.md: -------------------------------------------------------------------------------- 1 | [English](../../publishing.md) 2 | 3 | ### ব্রুনোকে নতুন প্যাকেজ ম্যানেজারে প্রকাশ করা 4 | 5 | যদিও আমাদের কোড ওপেন সোর্স এবং সবার ব্যবহারের জন্য উপলব্ধ, তবে আমরা নতুন প্যাকেজ ম্যানেজারে প্রকাশনা বিবেচনা করার আগে আমাদের সাথে যোগাযোগ করার জন্য অনুরোধ করি। ব্রুনোর স্রষ্টা হিসাবে, আমি এই প্রকল্পের জন্য `Bruno` ট্রেডমার্ক ধারণ করি এবং এর বিতরণ পরিচালনা করতে চাই। যদি আপনি একটি নতুন প্যাকেজ ম্যানেজারে ব্রুনো দেখতে চান, দয়া করে একটি GitHub ইস্যু তুলুন। 6 | 7 | যদিও আমাদের বেশিরভাগ বৈশিষ্ট্য বিনামূল্যে এবং ওপেন সোর্স (যা REST এবং GraphQL API গুলিকে কভার করে), আমরা ওপেন-সোর্স নীতি এবং স্থায়িত্বের মধ্যে একটি সুসঙ্গত ভারসাম্য বজায় রাখার জন্য চেষ্টা করি - https://github.com/usebruno/bruno/discussions/269 8 | -------------------------------------------------------------------------------- /docs/publishing/publishing_cn.md: -------------------------------------------------------------------------------- 1 | [English](../../publishing.md) 2 | 3 | ### 将 Bruno 发布到新的包管理器 4 | 5 | 虽然我们的代码是开源的,每个人都可以使用,但我们恳请您在考虑在新的包管理器上发布之前与我们联系。作为 Bruno 的创建者,我拥有这个项目的 Bruno 商标并希望管理其发行。如果您希望看到它使用新的包管理器,请提交一个 GitHub issue。 6 | 7 | 虽然我们的大部分功能都是免费与开源的 (涵盖 REST 和 GraphQL APIs) ,但我们努力在开源原则和可持续性之间取得和谐的平衡 - https://github.com/usebruno/bruno/discussions/269 8 | -------------------------------------------------------------------------------- /docs/publishing/publishing_ja.md: -------------------------------------------------------------------------------- 1 | [English](../../publishing.md) 2 | 3 | ### Bruno を新しいパッケージマネージャに公開する場合の注意 4 | 5 | 私たちのソースコードはオープンソースで誰でも使用できますが、新しいパッケージマネージャで公開を検討する前に、私たちにご連絡ください。私は Bruno の製作者として、このプロジェクト「Bruno」の商標を保有しており、その配布を管理したいと考えています。もし新しいパッケージマネージャで Bruno を使いたい場合は、GitHub の issue を立ててください。 6 | 7 | 私たちの機能の大部分が無料でオープンソース(REST や GraphQL の API も含む)ですが、 8 | 私たちはオープンソースの原則と長期的な維持の間でよいバランスをとれるように努力しています- https://github.com/usebruno/bruno/discussions/269 9 | -------------------------------------------------------------------------------- /docs/publishing/publishing_nl.md: -------------------------------------------------------------------------------- 1 | [English](../../publishing.md) 2 | 3 | ### Bruno publiceren naar een nieuwe pakketbeheerder 4 | 5 | Hoewel onze code open source is en beschikbaar voor iedereen, verzoeken we je vriendelijk om contact met ons op te nemen voordat je publicatie overweegt op nieuwe pakketbeheerders. Als de maker van Bruno houd ik het handelsmerk `Bruno` voor dit project en wil ik het distributieproces beheren. Als je Bruno op een nieuwe pakketbeheerder wilt zien, dien dan een GitHub-issue in. 6 | 7 | Hoewel de meerderheid van onze functies gratis en open source zijn (die REST en GraphQL API's dekken), streven we ernaar een harmonieuze balans te vinden tussen open-source principes en duurzaamheid - https://github.com/usebruno/bruno/discussions/269 -------------------------------------------------------------------------------- /docs/publishing/publishing_pl.md: -------------------------------------------------------------------------------- 1 | [English](../../publishing.md) 2 | 3 | ### Publikowanie Bruno w nowym menedżerze pakietów 4 | 5 | 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. 6 | 7 | Chociaż większość naszych funkcji jest darmowa i otwartoźródłowa (co obejmuje REST i GraphQL Apis), 8 | staramy się osiągnąć harmonijny balans między zasadami open-source a zrównoważonym rozwojem - https://github.com/usebruno/bruno/discussions/269 9 | -------------------------------------------------------------------------------- /docs/publishing/publishing_tr.md: -------------------------------------------------------------------------------- 1 | [English](../../publishing.md) 2 | 3 | ### Bruno'yu yeni bir paket yöneticisine yayınlama 4 | 5 | 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. 6 | 7 | Özelliklerimizin çoğu ücretsiz ve açık kaynak olsa da (REST ve GraphQL Apis'i kapsar), 8 | açık kaynak ilkeleri ile sürdürülebilirlik arasında uyumlu bir denge kurmaya çalışıyoruz - https://github.com/usebruno/bruno/discussions/269 9 | -------------------------------------------------------------------------------- /docs/publishing/publishing_zhtw.md: -------------------------------------------------------------------------------- 1 | [English](../../publishing.md) 2 | 3 | ### 將 Bruno 發佈到新的套件管理器 4 | 5 | 雖然我們的程式碼是開源的並且可供所有人使用,但我們懇請您在考慮在新的套件管理器上發布之前與我們聯繫。作為 Bruno 的創建者,我擁有這個專案的 Bruno 商標並希望管理其發行。如果您希望看到 Bruno 使用新的套件管理器,請提出一個 GitHub issue。 6 | 7 | 雖然我們的大部分功能都是免費和開源(涵蓋 REST 和 GraphQL APIs),但我們努力在開源的原則和永續性之間,取得和諧的平衡 - https://github.com/usebruno/bruno/discussions/269 8 | -------------------------------------------------------------------------------- /e2e-tests/001-sanity-tests/001-home-screen.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '../../playwright'; 2 | 3 | test('Check if the logo on top left is visible', async ({ page }) => { 4 | await expect(page.getByRole('button', { name: 'bruno' })).toBeVisible(); 5 | }); -------------------------------------------------------------------------------- /e2e-tests/bruno-testbench/init-user-data/preferences.json: -------------------------------------------------------------------------------- 1 | { 2 | "maximized": true, 3 | "lastOpenedCollections": ["{{projectRoot}}/packages/bruno-tests/collection"] 4 | } -------------------------------------------------------------------------------- /packages/bruno-app/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"], 3 | "plugins": [["styled-components", { "ssr": true }]] 4 | } -------------------------------------------------------------------------------- /packages/bruno-app/.env.production: -------------------------------------------------------------------------------- 1 | ENV=production 2 | 3 | NEXT_PUBLIC_ENV=prod -------------------------------------------------------------------------------- /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 | dist/ 35 | 36 | .env -------------------------------------------------------------------------------- /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-app/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rootDir: '.', 3 | moduleNameMapper: { 4 | '^assets/(.*)$': '/src/assets/$1', 5 | '^components/(.*)$': '/src/components/$1', 6 | '^hooks/(.*)$': '/src/hooks/$1', 7 | '^themes/(.*)$': '/src/themes/$1', 8 | '^api/(.*)$': '/src/api/$1', 9 | '^pageComponents/(.*)$': '/src/pageComponents/$1', 10 | '^providers/(.*)$': '/src/providers/$1', 11 | '^utils/(.*)$': '/src/utils/$1' 12 | }, 13 | clearMocks: true, 14 | moduleDirectories: ['node_modules', 'src'], 15 | testEnvironment: 'node' 16 | }; 17 | -------------------------------------------------------------------------------- /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-app/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {} 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /packages/bruno-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-app/public/favicon.ico -------------------------------------------------------------------------------- /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/assets/send.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /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/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/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/CollectionSettings/Auth/NTLMAuth/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/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/CollectionSettings/Auth/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | max-width: 800px; 5 | `; 6 | 7 | export default Wrapper; 8 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/CollectionSettings/Auth/WsseAuth/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/Docs/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | 5 | .editing-mode { 6 | cursor: pointer; 7 | } 8 | `; 9 | 10 | export default StyledWrapper; 11 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/CollectionSettings/Overview/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .partial { 5 | color: ${(props) => props.theme.colors.text.yellow}; 6 | opacity: 0.8; 7 | } 8 | 9 | .loading { 10 | color: ${(props) => props.theme.colors.text.muted}; 11 | opacity: 0.8; 12 | } 13 | 14 | .completed { 15 | color: ${(props) => props.theme.colors.text.green}; 16 | opacity: 0.8; 17 | } 18 | 19 | .failed { 20 | color: ${(props) => props.theme.colors.text.danger}; 21 | opacity: 0.8; 22 | } 23 | `; 24 | 25 | export default StyledWrapper; 26 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/CollectionSettings/Script/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | max-width: 800px; 5 | 6 | div.CodeMirror { 7 | height: inherit; 8 | } 9 | 10 | div.title { 11 | color: var(--color-tab-inactive); 12 | } 13 | `; 14 | 15 | export default StyledWrapper; 16 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/CollectionSettings/Tests/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | max-width: 800px; 5 | `; 6 | 7 | export default StyledWrapper; 8 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/CollectionSettings/Vars/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | max-width: 800px; 5 | 6 | div.title { 7 | color: var(--color-tab-inactive); 8 | } 9 | `; 10 | 11 | export default StyledWrapper; 12 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/Cookies/ModifyCookieModal/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/Documentation/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .editing-mode { 5 | cursor: pointer; 6 | } 7 | `; 8 | 9 | export default StyledWrapper; 10 | -------------------------------------------------------------------------------- /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, transparent }) => { 6 | return ( 7 | 8 | 18 | {icon} 19 | 20 | 21 | ); 22 | }; 23 | 24 | export default Dropdown; 25 | -------------------------------------------------------------------------------- /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/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/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/FolderSettings/Auth/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 | .inherit-mode-text { 15 | color: ${(props) => props.theme.colors.text.yellow}; 16 | } 17 | .auth-mode-label { 18 | color: ${(props) => props.theme.colors.text.yellow}; 19 | } 20 | `; 21 | 22 | export default Wrapper; -------------------------------------------------------------------------------- /packages/bruno-app/src/components/FolderSettings/AuthMode/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .auth-mode-selector { 5 | border: 1px solid ${({ theme }) => theme.colors.border}; 6 | padding: 4px 8px; 7 | border-radius: 4px; 8 | font-size: 0.8125rem; 9 | } 10 | 11 | .auth-mode-label { 12 | color: ${({ theme }) => theme.colors.text}; 13 | } 14 | `; 15 | 16 | export default StyledWrapper; -------------------------------------------------------------------------------- /packages/bruno-app/src/components/FolderSettings/Documentation/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .editing-mode { 5 | cursor: pointer; 6 | color: ${(props) => props.theme.colors.text.yellow}; 7 | } 8 | `; 9 | 10 | export default StyledWrapper; 11 | -------------------------------------------------------------------------------- /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/FolderSettings/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/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/GlobalEnvironments/EnvironmentSelector/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | .current-environment { 5 | } 6 | .environment-active { 7 | padding: 0.3rem 0.4rem; 8 | color: ${(props) => props.theme.colors.text.yellow}; 9 | border: solid 1px ${(props) => props.theme.colors.text.yellow} !important; 10 | } 11 | .environment-selector { 12 | .active: { 13 | color: ${(props) => props.theme.colors.text.yellow}; 14 | } 15 | } 16 | `; 17 | 18 | export default Wrapper; 19 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/GlobalEnvironments/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/GlobalEnvironments/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/Help/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | font-weight: 400; 5 | font-size: 0.75rem; 6 | background-color: ${props => props.theme.infoTip.bg}; 7 | border: 1px solid ${props => props.theme.infoTip.border}; 8 | box-shadow: ${props => props.theme.infoTip.boxShadow}; 9 | `; 10 | 11 | export default Wrapper; 12 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/Icons/Dot/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const DotIcon = ({ width }) => { 4 | return ( 5 | 10 | 11 | 12 | 13 | ); 14 | }; 15 | 16 | export default DotIcon; -------------------------------------------------------------------------------- /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/Portal/index.js: -------------------------------------------------------------------------------- 1 | import { createPortal } from 'react-dom'; 2 | 3 | function Portal({ children }) { 4 | return createPortal(children, document.body); 5 | } 6 | export default Portal; 7 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/Preferences/Display/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/Display/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-app/src/components/Preferences/Display/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Font from './Font/index'; 3 | import Theme from './Theme/index'; 4 | 5 | const Display = ({ close }) => { 6 | return ( 7 |
8 |
9 | 10 | Theme 11 | 12 | 13 |
14 |
15 |
16 | 17 |
18 |
19 | ); 20 | }; 21 | 22 | export default Display; 23 | -------------------------------------------------------------------------------- /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-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-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-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/RequestPane/Auth/NTLMAuth/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/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 | isSecret: true 22 | }, 23 | { 24 | key: 'scope', 25 | label: 'Scope' 26 | }, 27 | { 28 | key: 'state', 29 | label: 'State' 30 | } 31 | ]; 32 | 33 | export { inputsConfig }; 34 | -------------------------------------------------------------------------------- /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 | isSecret: true 14 | }, 15 | { 16 | key: 'scope', 17 | label: 'Scope' 18 | } 19 | ]; 20 | 21 | export { inputsConfig }; 22 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/RequestPane/Auth/OAuth2/Oauth2TokenViewer/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | ol[role="tree"] { 5 | overflow: hidden; 6 | } 7 | ol[role="group"] span { 8 | line-break: anywhere; 9 | } 10 | `; 11 | 12 | export default Wrapper; 13 | -------------------------------------------------------------------------------- /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 | isSecret: true 14 | }, 15 | { 16 | key: 'clientId', 17 | label: 'Client ID' 18 | }, 19 | { 20 | key: 'clientSecret', 21 | label: 'Client Secret', 22 | isSecret: true 23 | }, 24 | { 25 | key: 'scope', 26 | label: 'Scope' 27 | } 28 | ]; 29 | 30 | export { inputsConfig }; 31 | -------------------------------------------------------------------------------- /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/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/Auth/WsseAuth/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/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-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-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-app/src/components/RequestPane/RequestBody/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | `; 5 | 6 | export default Wrapper; 7 | -------------------------------------------------------------------------------- /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-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/RequestTabPanel/RequestIsLoading/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | div.card { 5 | background: ${(props) => props.theme.requestTabPanel.card.bg}; 6 | border: 1px solid ${(props) => props.theme.requestTabPanel.card.border}; 7 | 8 | div.hr { 9 | border-bottom: 1px solid ${(props) => props.theme.requestTabPanel.card.hr}; 10 | height: 1px; 11 | } 12 | 13 | div.border-top { 14 | border-top: 1px solid ${(props) => props.theme.requestTabPanel.card.border}; 15 | } 16 | } 17 | `; 18 | 19 | export default StyledWrapper; 20 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/RequestTabPanel/RequestNotLoaded/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | div.card { 5 | background: ${(props) => props.theme.requestTabPanel.card.bg}; 6 | border: 1px solid ${(props) => props.theme.requestTabPanel.card.border}; 7 | 8 | div.hr { 9 | border-bottom: 1px solid ${(props) => props.theme.requestTabPanel.card.hr}; 10 | height: 1px; 11 | } 12 | 13 | div.border-top { 14 | border-top: 1px solid ${(props) => props.theme.requestTabPanel.card.border}; 15 | } 16 | } 17 | `; 18 | 19 | export default StyledWrapper; 20 | -------------------------------------------------------------------------------- /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; -------------------------------------------------------------------------------- /packages/bruno-app/src/components/RequestTabs/RequestTab/CloseTabIcon.js: -------------------------------------------------------------------------------- 1 | const CloseTabIcon = () => ( 2 | 3 | 7 | 8 | ); 9 | 10 | export default CloseTabIcon; 11 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/RequestTabs/RequestTab/DraftTabIcon.js: -------------------------------------------------------------------------------- 1 | const DraftTabIcon = () => ( 2 | 11 | 12 | 13 | ); 14 | 15 | export default DraftTabIcon; 16 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/ResponsePane/ClearTimeline/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/ResponsePane/Overlay/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | position: absolute; 5 | height: 100%; 6 | width: calc(100% - 0.75rem); 7 | z-index: 1; 8 | background-color: ${(props) => props.theme.requestTabPanel.responseOverlayBg}; 9 | 10 | div.overlay { 11 | height: 100%; 12 | z-index: 9; 13 | display: flex; 14 | flex-direction: column; 15 | align-items: center; 16 | padding-top: 20%; 17 | overflow: hidden; 18 | text-align: center; 19 | 20 | .loading-icon { 21 | transform: scaleY(-1); 22 | animation: rotateCounterClockwise 1s linear infinite; 23 | } 24 | } 25 | `; 26 | 27 | export default StyledWrapper; 28 | -------------------------------------------------------------------------------- /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-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/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/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/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-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/ResponsePane/RunnerTimeline/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-app/src/components/ResponsePane/SkippedRequest/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | padding-top: 20%; 5 | width: 100%; 6 | .send-icon { 7 | color: ${(props) => props.theme.requestTabPanel.responseSendIcon}; 8 | } 9 | `; 10 | 11 | export default StyledWrapper; -------------------------------------------------------------------------------- /packages/bruno-app/src/components/ResponsePane/SkippedRequest/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { IconCircleOff } from '@tabler/icons'; 3 | import StyledWrapper from './StyledWrapper'; 4 | 5 | const SkippedRequest = () => { 6 | return ( 7 | 8 |
9 | 10 |
11 |
12 | Request skipped 13 |
14 |
15 | ); 16 | }; 17 | 18 | export default SkippedRequest; -------------------------------------------------------------------------------- /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/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 | .skipped-request { 17 | color: ${(props) => props.theme.colors.text.muted}; 18 | } 19 | `; 20 | 21 | export default StyledWrapper; 22 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Common/Method/index.js: -------------------------------------------------------------------------------- 1 | const Method = ({ method }) => { 2 | return ( 3 | 4 | {method?.toUpperCase()} 5 | 6 | ) 7 | } 8 | 9 | const methodColors = { 10 | GET: 'text-green-500', 11 | POST: 'text-blue-500', 12 | PUT: 'text-yellow-500', 13 | DELETE: 'text-red-500', 14 | PATCH: 'text-purple-500', 15 | OPTIONS: 'text-gray-500', 16 | HEAD: 'text-gray-500', 17 | }; 18 | 19 | export default Method; -------------------------------------------------------------------------------- /packages/bruno-app/src/components/SecuritySettings/JsSandboxMode/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .safe-mode { 5 | padding: 0.15rem 0.3rem; 6 | color: ${(props) => props.theme.colors.text.green}; 7 | border: solid 1px ${(props) => props.theme.colors.text.green} !important; 8 | } 9 | .developer-mode { 10 | padding: 0.15rem 0.3rem; 11 | color: ${(props) => props.theme.colors.text.yellow}; 12 | border: solid 1px ${(props) => props.theme.colors.text.yellow} !important; 13 | } 14 | `; 15 | 16 | export default StyledWrapper; 17 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/SecuritySettings/JsSandboxModeModal/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | max-width: 800px; 5 | 6 | span.beta-tag { 7 | display: flex; 8 | align-items: center; 9 | padding: 0.1rem 0.25rem; 10 | font-size: 0.75rem; 11 | border-radius: 0.25rem; 12 | color: ${(props) => props.theme.colors.text.green}; 13 | border: solid 1px ${(props) => props.theme.colors.text.green} !important; 14 | } 15 | 16 | span.developer-mode-warning { 17 | font-weight: 400; 18 | color: ${(props) => props.theme.colors.text.yellow}; 19 | } 20 | `; 21 | 22 | export default StyledWrapper; 23 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/SecuritySettings/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | max-width: 800px; 5 | 6 | span.beta-tag { 7 | display: flex; 8 | align-items: center; 9 | padding: 0.1rem 0.25rem; 10 | font-size: 0.75rem; 11 | border-radius: 0.25rem; 12 | color: ${(props) => props.theme.colors.text.green}; 13 | border: solid 1px ${(props) => props.theme.colors.text.green} !important; 14 | } 15 | 16 | span.developer-mode-warning { 17 | font-weight: 400; 18 | color: ${(props) => props.theme.colors.text.yellow}; 19 | } 20 | `; 21 | 22 | export default StyledWrapper; 23 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .advanced-options { 5 | .caret { 6 | color: ${(props) => props.theme.textLink}; 7 | fill: ${(props) => props.theme.textLink}; 8 | } 9 | } 10 | `; 11 | 12 | export default StyledWrapper; -------------------------------------------------------------------------------- /packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemDragPreview/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .drag-preview { 5 | background-color: ${(props) => props.theme.sidebar.collection.item.hoverBg}; 6 | } 7 | `; 8 | 9 | export default StyledWrapper; 10 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/CollectionItemIcon/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | .partial { 5 | color: ${(props) => props.theme.colors.text.yellow}; 6 | } 7 | .error { 8 | color: ${(props) => props.theme.colors.text.danger}; 9 | } 10 | `; 11 | 12 | export default Wrapper; 13 | -------------------------------------------------------------------------------- /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/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 | height: 100%; 6 | 7 | .copy-to-clipboard { 8 | position: absolute; 9 | cursor: pointer; 10 | top: 10px; 11 | right: 10px; 12 | z-index: 10; 13 | opacity: 0.5; 14 | 15 | &:hover { 16 | opacity: 1; 17 | } 18 | } 19 | `; 20 | 21 | export default StyledWrapper; 22 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/RenameCollectionItem/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .advanced-options { 5 | .caret { 6 | color: ${(props) => props.theme.textLink}; 7 | fill: ${(props) => props.theme.textLink}; 8 | } 9 | } 10 | `; 11 | 12 | export default StyledWrapper; -------------------------------------------------------------------------------- /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 | .warning { 8 | color: ${(props) => props.theme.colors.text.danger}; 9 | } 10 | `; 11 | 12 | export default Wrapper; 13 | -------------------------------------------------------------------------------- /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/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-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/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/Sidebar/NewFolder/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const StyledWrapper = styled.div` 4 | .advanced-options { 5 | .caret { 6 | color: ${(props) => props.theme.textLink}; 7 | fill: ${(props) => props.theme.textLink}; 8 | } 9 | } 10 | `; 11 | 12 | export default StyledWrapper; -------------------------------------------------------------------------------- /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-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-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-app/src/components/ToggleSwitch/index.js: -------------------------------------------------------------------------------- 1 | import { Checkbox, Inner, Label, Switch, SwitchButton } from './StyledWrapper'; 2 | 3 | const ToggleSwitch = ({ isOn, handleToggle, size = 'm', ...props }) => { 4 | return ( 5 | 6 | 7 | 11 | 12 | ); 13 | }; 14 | 15 | export default ToggleSwitch; 16 | -------------------------------------------------------------------------------- /packages/bruno-app/src/components/ToolHint/StyledWrapper.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | const Wrapper = styled.div` 4 | background-color: ${(props) => props.theme.sidebar.badge}; 5 | color: ${(props) => props.theme.text}; 6 | `; 7 | 8 | export default Wrapper; 9 | -------------------------------------------------------------------------------- /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-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-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/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-app/src/i18n/index.js: -------------------------------------------------------------------------------- 1 | import i18n from 'i18next'; 2 | import { initReactI18next } from 'react-i18next'; 3 | import translationEn from './translation/en.json'; 4 | 5 | const resources = { 6 | en: { 7 | translation: translationEn, 8 | }, 9 | }; 10 | 11 | i18n 12 | .use(initReactI18next) // passes i18n down to react-i18next 13 | .init({ 14 | resources, 15 | lng: 'en', // Use "en" as the default language. "cimode" can be used to debug / show translation placeholder 16 | 17 | ns: 'translation', // Use translation as the default Namespace that will be loaded by default 18 | 19 | interpolation: { 20 | escapeValue: false // react already safes from xss 21 | } 22 | }); 23 | 24 | export default i18n; 25 | -------------------------------------------------------------------------------- /packages/bruno-app/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './pages/index'; 4 | import { DndProvider } from 'react-dnd'; 5 | import { HTML5Backend } from 'react-dnd-html5-backend'; 6 | 7 | const rootElement = document.getElementById('root'); 8 | 9 | if (rootElement) { 10 | const root = ReactDOM.createRoot(rootElement); 11 | root.render( 12 | 13 | 14 | 15 | 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /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-app/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import Bruno from './Bruno'; 2 | import GlobalStyle from '../globalStyles'; 3 | import '../i18n'; 4 | import Main from './Main'; 5 | 6 | export default function App() { 7 | return ( 8 |
9 |
10 |
11 | 12 | 13 |
14 |
15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /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-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/providers/ReduxStore/middlewares/tasks/utils.js: -------------------------------------------------------------------------------- 1 | export const taskTypes = { 2 | OPEN_REQUEST: 'OPEN_REQUEST' 3 | }; 4 | -------------------------------------------------------------------------------- /packages/bruno-app/src/selectors/tab.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from '@reduxjs/toolkit'; 2 | 3 | export const isTabForItemActive = ({ itemUid }) => createSelector([ 4 | (state) => state.tabs?.activeTabUid 5 | ], (activeTabUid) => activeTabUid === itemUid); 6 | 7 | export const isTabForItemPresent = ({ itemUid }) => createSelector([ 8 | (state) => state.tabs.tabs, 9 | ], (tabs) => tabs.some((tab) => tab.uid === itemUid)); -------------------------------------------------------------------------------- /packages/bruno-app/src/styles/_buttons.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-app/src/styles/_buttons.scss -------------------------------------------------------------------------------- /packages/bruno-app/src/styles/app.scss: -------------------------------------------------------------------------------- 1 | @import 'buttons'; 2 | -------------------------------------------------------------------------------- /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-app/src/utils/common/ipc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Wrapper for ipcRenderer.invoke that handles error cases 3 | * @param {string} channel - The IPC channel name 4 | * @param {...any} args - Arguments to pass to the channel 5 | * @returns {Promise} - Resolves with the result or rejects with error 6 | */ 7 | export const callIpc = (channel, ...args) => { 8 | const { ipcRenderer } = window; 9 | if (!ipcRenderer) { 10 | return Promise.reject(new Error('IPC Renderer not available')); 11 | } 12 | 13 | return ipcRenderer.invoke(channel, ...args); 14 | }; -------------------------------------------------------------------------------- /packages/bruno-app/src/utils/common/path.js: -------------------------------------------------------------------------------- 1 | import platform from 'platform'; 2 | import path from 'path'; 3 | 4 | const isWindowsOS = () => { 5 | const os = platform.os; 6 | const osFamily = os.family.toLowerCase(); 7 | return osFamily.includes('windows'); 8 | }; 9 | 10 | const brunoPath = isWindowsOS() ? path.win32 : path.posix; 11 | 12 | export default brunoPath; 13 | -------------------------------------------------------------------------------- /packages/bruno-app/src/utils/exporters/postman-collection.js: -------------------------------------------------------------------------------- 1 | import * as FileSaver from 'file-saver'; 2 | import { brunoToPostman } from '@usebruno/converters'; 3 | 4 | export const exportCollection = (collection) => { 5 | 6 | const collectionToExport = brunoToPostman(collection); 7 | 8 | const fileName = `${collection.name}.json`; 9 | const fileBlob = new Blob([JSON.stringify(collectionToExport, null, 2)], { type: 'application/json' }); 10 | 11 | FileSaver.saveAs(fileBlob, fileName); 12 | }; 13 | 14 | export default exportCollection; 15 | -------------------------------------------------------------------------------- /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-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 | 15 | export const scrollToTheActiveTab = () => { 16 | const activeTab = document.querySelector('.request-tab.active'); 17 | if (activeTab) { 18 | activeTab.scrollIntoView({ behavior: 'smooth', block: 'start' }); 19 | } 20 | }; -------------------------------------------------------------------------------- /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-cli/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | web 3 | out 4 | 5 | pnpm-lock.yaml 6 | package-lock.json 7 | yarn.lock 8 | -------------------------------------------------------------------------------- /packages/bruno-cli/assets/images/cli-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-cli/assets/images/cli-demo.png -------------------------------------------------------------------------------- /packages/bruno-cli/bin/bru.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('../src').run(); 4 | -------------------------------------------------------------------------------- /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-cli/src/runner/oauth2.js: -------------------------------------------------------------------------------- 1 | const { getOAuth2Token } = require('@usebruno/requests'); 2 | const tokenStore = require('./tokenStore'); 3 | 4 | module.exports = { 5 | getOAuth2Token: (oauth2Config) => getOAuth2Token(oauth2Config, tokenStore) 6 | }; -------------------------------------------------------------------------------- /packages/bruno-cli/src/runner/tokenStore.js: -------------------------------------------------------------------------------- 1 | // In-memory token store implementation for OAuth2 tokens 2 | const tokenStore = { 3 | tokens: new Map(), 4 | 5 | // Save a token with optional expiry information 6 | async saveToken(serviceId, account, token) { 7 | this.tokens.set(`${serviceId}:${account}`, token); 8 | return true; 9 | }, 10 | 11 | // Get a token 12 | async getToken(serviceId, account) { 13 | return this.tokens.get(`${serviceId}:${account}`); 14 | }, 15 | 16 | // Delete a token 17 | async deleteToken(serviceId, account) { 18 | return this.tokens.delete(`${serviceId}:${account}`); 19 | } 20 | }; 21 | 22 | module.exports = tokenStore; -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: folder_1 3 | seq: 5 4 | } 5 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder_1/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: folder_1 3 | seq: 2 4 | } 5 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder_1/request_1.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_1 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder_1/request_2.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_2 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder_1/request_3.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_3 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder_2/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: folder_2 3 | seq: 1 4 | } 5 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder_2/request_1.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_1 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder_2/request_2.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_2 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/folder_2/request_3.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_3 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/request_1.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_1 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/request_2.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_2 3 | type: http 4 | seq: 5 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_1/request_3.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_3 3 | type: http 4 | seq: 4 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_2/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: folder_2 3 | seq: 1 4 | } 5 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_2/request_1.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_1 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_2/request_2.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_2 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/folder_2/request_3.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_3 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/request_1.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_1 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-cli/tests/runner/fixtures/collection-json-from-pathname/collection/request_3.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request_3 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: https://echo.usebruno.com 9 | body: text 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /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-common/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | ['@babel/preset-env', { modules: 'auto' }], 4 | '@babel/preset-typescript', 5 | ], 6 | }; 7 | -------------------------------------------------------------------------------- /packages/bruno-common/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: { 3 | '^.+\\.(ts|js)$': 'babel-jest', 4 | }, 5 | transformIgnorePatterns: [ 6 | '/node_modules/(?!(lodash-es)/)', 7 | ], 8 | testEnvironment: 'node' 9 | }; 10 | -------------------------------------------------------------------------------- /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-common/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default as interpolate } from './interpolate'; 2 | -------------------------------------------------------------------------------- /packages/bruno-common/src/runner/index.ts: -------------------------------------------------------------------------------- 1 | import { generateHtmlReport } from "./reports/html/generate-report"; 2 | import { getRunnerSummary } from "./runner-summary"; 3 | 4 | export { generateHtmlReport, getRunnerSummary }; -------------------------------------------------------------------------------- /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 | "sourceMap": true, 10 | "outDir": "dist", 11 | "moduleResolution": "node", 12 | "allowSyntheticDefaultImports": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "allowJs": true, 15 | "checkJs": false 16 | }, 17 | "include": ["src/**/*.ts", "src/**/*.js"], 18 | "exclude": ["dist", "node_modules", "tests"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/bruno-converters/.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-converters/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [['@babel/preset-env', { targets: { node: 'current' } }]], 3 | }; 4 | -------------------------------------------------------------------------------- /packages/bruno-converters/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | transform: { 3 | '^.+\\.js$': 'babel-jest', 4 | }, 5 | setupFiles: ['/jest.setup.js'], 6 | transformIgnorePatterns: [ 7 | 'node_modules/(?!(nanoid)/)' 8 | ], 9 | testEnvironment: 'node', 10 | moduleNameMapper: { 11 | '^nanoid(/(.*)|$)': 'nanoid$1' 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/bruno-converters/jest.setup.js: -------------------------------------------------------------------------------- 1 | // Mock the uuid function 2 | jest.mock('./src/common', () => { 3 | // Import the original module to keep other functions intact 4 | const originalModule = jest.requireActual('./src/common'); 5 | 6 | return { 7 | __esModule: true, // Use this property to indicate it's an ES module 8 | ...originalModule, 9 | uuid: jest.fn(() => 'mockeduuidvalue123456'), // Mock uuid to return a fixed value 10 | }; 11 | }); -------------------------------------------------------------------------------- /packages/bruno-converters/src/constants/index.js: -------------------------------------------------------------------------------- 1 | import { invalidVariableCharacterRegex } from './regex'; 2 | 3 | export { invalidVariableCharacterRegex }; 4 | -------------------------------------------------------------------------------- /packages/bruno-converters/src/constants/regex.js: -------------------------------------------------------------------------------- 1 | export const invalidVariableCharacterRegex = /[^\w-.]/g; -------------------------------------------------------------------------------- /packages/bruno-converters/src/index.js: -------------------------------------------------------------------------------- 1 | export { default as postmanToBruno } from './postman/postman-to-bruno.js'; 2 | export { default as postmanToBrunoEnvironment } from './postman/postman-env-to-bruno-env.js'; 3 | export { default as brunoToPostman } from './postman/bruno-to-postman.js'; 4 | export { default as openApiToBruno } from './openapi/openapi-to-bruno.js'; 5 | export { default as insomniaToBruno } from './insomnia/insomnia-to-bruno.js'; 6 | export { default as postmanTranslation } from './postman/postman-translations.js'; -------------------------------------------------------------------------------- /packages/bruno-converters/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-converters/types/common.d.ts: -------------------------------------------------------------------------------- 1 | export declare const uuid: () => string; 2 | export declare const normalizeFileName: (name: string) => string; 3 | export declare const validateSchema: (collection?: {}) => Promise; 4 | export declare const updateUidsInCollection: (_collection: any) => any; 5 | export declare const transformItemsInCollection: (collection: any) => any; 6 | export declare const hydrateSeqInCollection: (collection: any) => any; 7 | -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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/.env.sample: -------------------------------------------------------------------------------- 1 | BRUNO_INFO_ENDPOINT = http://localhost:8081 -------------------------------------------------------------------------------- /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-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-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-electron/resources/icons/mac/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/mac/icon.icns -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/1024x1024.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/128x128.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/16x16.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/24x24.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/256x256.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/32x32.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/48x48.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/512x512.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/png/64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/png/64x64.png -------------------------------------------------------------------------------- /packages/bruno-electron/resources/icons/win/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/resources/icons/win/icon.ico -------------------------------------------------------------------------------- /packages/bruno-electron/src/about/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-electron/src/about/256x256.png -------------------------------------------------------------------------------- /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-electron/src/bru/workers/scripts/bru-to-json.js: -------------------------------------------------------------------------------- 1 | const { parentPort } = require('worker_threads'); 2 | const { 3 | bruToJsonV2, 4 | } = require('@usebruno/lang'); 5 | 6 | parentPort.on('message', (workerData) => { 7 | try { 8 | const bru = workerData; 9 | const json = bruToJsonV2(bru); 10 | parentPort.postMessage(json); 11 | } 12 | catch(error) { 13 | console.error(error); 14 | parentPort.postMessage({ error: error?.message }); 15 | } 16 | }); -------------------------------------------------------------------------------- /packages/bruno-electron/src/bru/workers/scripts/json-to-bru.js: -------------------------------------------------------------------------------- 1 | const { parentPort } = require('worker_threads'); 2 | const { 3 | jsonToBruV2, 4 | } = require('@usebruno/lang'); 5 | 6 | parentPort.on('message', (workerData) => { 7 | try { 8 | const json = workerData; 9 | const bru = jsonToBruV2(json); 10 | parentPort.postMessage(bru); 11 | } 12 | catch(error) { 13 | console.error(error); 14 | parentPort.postMessage({ error: error?.message }); 15 | } 16 | }); -------------------------------------------------------------------------------- /packages/bruno-electron/src/preload.js: -------------------------------------------------------------------------------- 1 | const { ipcRenderer, contextBridge, webUtils } = 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 | getFilePath (file) { 15 | const path = webUtils.getPathForFile(file) 16 | return path; 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /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-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-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-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-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-graphql-docs/src/index.ts: -------------------------------------------------------------------------------- 1 | import { DocExplorer } from './components/DocExplorer'; 2 | 3 | import './index.css'; 4 | 5 | export { DocExplorer }; 6 | -------------------------------------------------------------------------------- /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-js/.gitignore: -------------------------------------------------------------------------------- 1 | src/sandbox/bundle-browser-rollup.js -------------------------------------------------------------------------------- /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-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-js/src/sandbox/quickjs/shims/lib/index.js: -------------------------------------------------------------------------------- 1 | const addAxiosShimToContext = require('./axios'); 2 | const addNanoidShimToContext = require('./nanoid'); 3 | const addPathShimToContext = require('./path'); 4 | const addUuidShimToContext = require('./uuid'); 5 | 6 | const addLibraryShimsToContext = async (vm) => { 7 | await addNanoidShimToContext(vm); 8 | await addAxiosShimToContext(vm); 9 | await addUuidShimToContext(vm); 10 | await addPathShimToContext(vm); 11 | }; 12 | 13 | module.exports = addLibraryShimsToContext; 14 | -------------------------------------------------------------------------------- /packages/bruno-js/src/sandbox/quickjs/shims/lib/nanoid.js: -------------------------------------------------------------------------------- 1 | const { nanoid } = require('nanoid'); 2 | const { marshallToVm } = require('../../utils'); 3 | 4 | const addNanoidShimToContext = async (vm) => { 5 | let _nanoid = vm.newFunction('nanoid', function () { 6 | let v = nanoid(); 7 | return marshallToVm(v, vm); 8 | }); 9 | vm.setProp(vm.global, '__bruno__nanoid', _nanoid); 10 | _nanoid.dispose(); 11 | 12 | vm.evalCode( 13 | ` 14 | globalThis.nanoid = {}; 15 | globalThis.nanoid.nanoid = globalThis.__bruno__nanoid; 16 | globalThis.requireObject = { 17 | ...globalThis.requireObject, 18 | 'nanoid': globalThis.nanoid 19 | } 20 | ` 21 | ); 22 | }; 23 | 24 | module.exports = addNanoidShimToContext; 25 | -------------------------------------------------------------------------------- /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-lang/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | web 3 | out 4 | 5 | pnpm-lock.yaml 6 | package-lock.json 7 | yarn.lock 8 | -------------------------------------------------------------------------------- /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-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-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/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-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-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-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/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-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-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-lang/v2/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-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-query/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | }; -------------------------------------------------------------------------------- /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-requests/.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-requests/src/auth/index.ts: -------------------------------------------------------------------------------- 1 | export { addDigestInterceptor } from './digestauth-helper'; 2 | export { getOAuth2Token } from './oauth2-helper'; -------------------------------------------------------------------------------- /packages/bruno-requests/src/index.ts: -------------------------------------------------------------------------------- 1 | export { addDigestInterceptor, getOAuth2Token } from './auth'; 2 | 3 | export * as utils from './utils'; 4 | -------------------------------------------------------------------------------- /packages/bruno-requests/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './cookie-utils'; 2 | -------------------------------------------------------------------------------- /packages/bruno-requests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ESNext", 5 | "strict": true, 6 | "esModuleInterop": true, 7 | "skipLibCheck": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "outDir": "./dist", 10 | "rootDir": "./src", 11 | "resolveJsonModule": true, 12 | "allowSyntheticDefaultImports": true, 13 | "moduleResolution": "node", 14 | "declaration": true, 15 | "declarationDir": "./dist/types", 16 | "allowJs": true, 17 | "checkJs": false 18 | }, 19 | "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js"], 20 | "exclude": ["node_modules", "dist"] 21 | } -------------------------------------------------------------------------------- /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-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 | "dependencies": { 17 | "nanoid": "3.3.8" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /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-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-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-tests/.nvmrc: -------------------------------------------------------------------------------- 1 | v20 2 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/.env: -------------------------------------------------------------------------------- 1 | PROC_ENV_VAR=woof -------------------------------------------------------------------------------- /packages/bruno-tests/collection/.gitignore: -------------------------------------------------------------------------------- 1 | !.env -------------------------------------------------------------------------------- /packages/bruno-tests/collection/.nvmrc: -------------------------------------------------------------------------------- 1 | v18 -------------------------------------------------------------------------------- /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/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-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/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-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-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/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/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-tests/collection/auth/digest/Digest Auth 200.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Digest Auth 200 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: https://httpbin.org/digest-auth/auth/foo/passwd 9 | body: none 10 | auth: digest 11 | } 12 | 13 | auth:digest { 14 | username: foo 15 | password: passwd 16 | } 17 | 18 | assert { 19 | res.status: eq 200 20 | res.body.authenticated: isTruthy 21 | } 22 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/auth/digest/Digest Auth 401.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: Digest Auth 401 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: https://httpbin.org/digest-auth/auth/foo/passw 9 | body: none 10 | auth: digest 11 | } 12 | 13 | auth:digest { 14 | username: foo 15 | password: passwd 16 | } 17 | 18 | assert { 19 | res.status: eq 401 20 | } 21 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/auth/digest/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: digest 3 | } 4 | -------------------------------------------------------------------------------- /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-tests/collection/bruno.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-tests/collection/bruno.png -------------------------------------------------------------------------------- /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-tests/collection/echo/echo form-url-encoded.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: echo form-url-encoded 3 | type: http 4 | seq: 9 5 | } 6 | 7 | post { 8 | url: {{echo-host}} 9 | body: formUrlEncoded 10 | auth: none 11 | } 12 | 13 | body:form-urlencoded { 14 | form-data-key: {{form-data-key}} 15 | form-data-stringified-object: {{form-data-stringified-object}} 16 | } 17 | 18 | assert { 19 | res.body: eq form-data-key=form-data-value&form-data-stringified-object=%7B%22foo%22%3A123%7D 20 | } 21 | 22 | script:pre-request { 23 | let obj = JSON.stringify({foo:123}); 24 | bru.setVar('form-data-key', 'form-data-value'); 25 | bru.setVar('form-data-stringified-object', obj); 26 | } 27 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/echo/echo headers.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: echo headers 3 | type: http 4 | seq: 13 5 | } 6 | 7 | post { 8 | url: {{echo-host}} 9 | body: none 10 | auth: inherit 11 | } 12 | 13 | headers { 14 | Custom-Header-String: bruno 15 | } 16 | 17 | tests { 18 | test("test headers",function() { 19 | expect(res.getHeaders()).to.have.property("Custom-Header-String".toLowerCase()) 20 | expect(res.getHeaders()).to.have.property("Custom-Header-String".toLowerCase(), "bruno") 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/echo/echo multipart scripting.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: echo multipart via scripting 3 | type: http 4 | seq: 10 5 | } 6 | 7 | post { 8 | url: {{echo-host}} 9 | body: multipartForm 10 | auth: none 11 | } 12 | 13 | assert { 14 | res.body: contains form-data-value 15 | } 16 | 17 | script:pre-request { 18 | const FormData = require("form-data"); 19 | const form = new FormData(); 20 | form.append('form-data-key', 'form-data-value'); 21 | req.setBody(form); 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/echo/echo plaintext.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: echo plaintext 3 | type: http 4 | seq: 3 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-tests/collection/echo/echo xml parsed(self closing tags).bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: echo xml parsed(self closing tags) 3 | type: http 4 | seq: 6 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 | 20 | assert { 21 | res.status: eq 200 22 | } 23 | 24 | tests { 25 | test("should return parsed xml", function() { 26 | const data = res.getBody(); 27 | expect(res.getBody()).to.eql({ 28 | "hello": { 29 | "world": [ 30 | "bruno", 31 | "" 32 | ] 33 | } 34 | }); 35 | }); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/echo/echo xml parsed.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: echo xml parsed 3 | type: http 4 | seq: 4 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": ["bruno"] 29 | } 30 | }); 31 | }); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/echo/echo xml raw.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: echo xml raw 3 | type: http 4 | seq: 5 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-tests/collection/echo/multiline/echo binary.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: echo binary 3 | type: http 4 | seq: 1 5 | } 6 | 7 | post { 8 | url: {{echo-host}} 9 | body: file 10 | auth: none 11 | } 12 | 13 | body:file { 14 | file: @file(bruno.png) @contentType(image/png) 15 | } 16 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/echo/test echo any.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test echo any 3 | type: http 4 | seq: 11 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "text/plain" }, 16 | "content": "hello" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq hello 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/echo/test echo-any json.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test echo-any json 3 | type: http 4 | seq: 12 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "type": "application/json", 16 | "contentJSON": {"x": 42} 17 | } 18 | } 19 | 20 | assert { 21 | res.body.x: eq 42 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/environments/Prod.bru: -------------------------------------------------------------------------------- 1 | vars { 2 | host: https://testbench-sanity.usebruno.com 3 | httpfaker: https://www.httpfaker.org 4 | bearer_auth_token: your_secret_token 5 | basic_auth_password: della 6 | env.var1: envVar1 7 | env-var2: envVar2 8 | bark: {{process.env.PROC_ENV_VAR}} 9 | foo: bar 10 | testSetEnvVar: bruno-29653 11 | echo-host: https://echo.usebruno.com 12 | } 13 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "hello": "bruno" 3 | } 4 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/file.txt: -------------------------------------------------------------------------------- 1 | file.txt 2 | 3 | hello, bruno 4 | -------------------------------------------------------------------------------- /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/lib/constants.js: -------------------------------------------------------------------------------- 1 | const PI = 3.14; 2 | 3 | module.exports = { 4 | PI 5 | }; -------------------------------------------------------------------------------- /packages/bruno-tests/collection/lib/math.js: -------------------------------------------------------------------------------- 1 | const { PI } = require('./constants'); 2 | 3 | const sum = (a, b) => a + b; 4 | const areaOfCircle = (radius) => PI * radius * radius; 5 | 6 | module.exports = { 7 | sum, 8 | areaOfCircle 9 | }; 10 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/multipart/small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/usebruno/bruno/223f79a3e26958653befe535fdb86dd7c35ee294/packages/bruno-tests/collection/multipart/small.png -------------------------------------------------------------------------------- /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-tests/collection/ping.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: ping 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:pre-request { 14 | bru.runner.stopExecution(); 15 | } 16 | -------------------------------------------------------------------------------- /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-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/favicon.ico 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/x-icon"); 17 | }); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/readme.md: -------------------------------------------------------------------------------- 1 | # bruno-tests collection 2 | 3 | API Collection to run sanity tests on Bruno CLI. 4 | -------------------------------------------------------------------------------- /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-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-tests/collection/response-parsing/test JSON false response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test JSON false response 3 | type: http 4 | seq: 11 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "content": "false" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq false 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test JSON null response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test JSON null response 3 | type: http 4 | seq: 6 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "content": "null" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq null 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test JSON number response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test JSON number response 3 | type: http 4 | seq: 12 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "content": "3.1" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq 3.1 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test JSON response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test JSON response 3 | type: http 4 | seq: 2 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "contentJSON": { "message": "hello" } 17 | } 18 | } 19 | 20 | assert { 21 | res.body.message: eq hello 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test JSON string response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test JSON string response 3 | type: http 4 | seq: 7 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "content": "\"ok\"" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq ok 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test JSON string with quotes response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test JSON string with quotes response 3 | type: http 4 | seq: 8 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "contentJSON": "\"ok\"" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq '"ok"' 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test JSON true response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test JSON true response 3 | type: http 4 | seq: 10 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "content": "true" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq true 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test JSON unsafe-int response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test JSON unsafe-int response 3 | type: http 4 | seq: 13 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "content": "90071992547409919876" 17 | } 18 | } 19 | 20 | assert { 21 | res.body.toString(): eq 90071992547409920000 22 | } 23 | 24 | docs { 25 | Note: This test is not perfect, we should match the unparsed raw-response with the expected string version of the unsafe-integer 26 | } 27 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test html response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test html response 3 | type: http 4 | seq: 5 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "text/html" }, 16 | "content": "

hello

" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq

hello

22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test invalid JSON response with formatting.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test invalid JSON response with formatting 3 | type: http 4 | seq: 19 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/json" }, 16 | "content": "hello\n\tworld" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq hello\n\tworld 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test plain text response with formatting.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test plain text response with formatting 3 | type: http 4 | seq: 18 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "text/plain" }, 16 | "content": "hello\n\tworld" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq hello\n\tworld 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test plain text response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test plain text response 3 | type: http 4 | seq: 1 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "text/plain" }, 16 | "content": "hello" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq hello 22 | } 23 | 24 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test plain text utf16 response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test plain text utf16 response 3 | type: http 4 | seq: 14 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "text/plain; charset=utf-16" }, 16 | "contentBase64": "dABoAGkAcwAgAGkAcwAgAGUAbgBjAG8AZABlAGQAIAB3AGkAdABoACAAdQB0AGYAMQA2AA==" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq "this is encoded with utf16" 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test plain text utf16-be with BOM response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test plain text utf16-be with BOM response 3 | type: http 4 | seq: 15 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "text/plain; charset=utf-16" }, 16 | "contentBase64": "/v8AdABoAGkAcwAgAGkAcwAgAGUAbgBjAG8AZABlAGQAIAB3AGkAdABoACAAdQB0AGYAMQA2AC0AYgBlACAAdwBpAHQAaAAgAEIATwBN" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq "this is encoded with utf16-be with BOM" 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test plain text utf16-le with BOM response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test plain text utf16-le with BOM response 3 | type: http 4 | seq: 16 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "text/plain; charset=utf-16" }, 16 | "contentBase64": "//50AGgAaQBzACAAaQBzACAAZQBuAGMAbwBkAGUAZAAgAHcAaQB0AGgAIAB1AHQAZgAxADYALQBsAGUAIAB3AGkAdABoACAAQgBPAE0A" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq "this is encoded with utf16-le with BOM" 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test plain text utf8 with BOM response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test plain text utf8 with BOM response 3 | type: http 4 | seq: 17 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "text/plain; charset=utf8" }, 16 | "contentBase64": "77u/dGhpcyBpcyB1dGY4IGVuY29kZWQgd2l0aCBCT00sIHdoeSBub3Q/" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq "this is utf8 encoded with BOM, why not?" 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/response-parsing/test xml response.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: test xml response 3 | type: http 4 | seq: 9 5 | } 6 | 7 | post { 8 | url: {{httpfaker}}/api/echo/custom 9 | body: json 10 | auth: none 11 | } 12 | 13 | body:json { 14 | { 15 | "headers": { "content-type": "application/xml" }, 16 | "content": "hello" 17 | } 18 | } 19 | 20 | assert { 21 | res.body: eq hello 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: bru 3 | } 4 | 5 | vars:pre-request { 6 | folder-var: folder-var-value 7 | } 8 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/getCollectionName.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getCollectionName 3 | type: http 4 | seq: 13 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: inherit 11 | } 12 | 13 | tests { 14 | test("Check if collection name is bruno-testbench", function () { 15 | expect(bru.getCollectionName()).to.eql("bruno-testbench"); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/getCollectionVar.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getCollectionVar 3 | type: http 4 | seq: 9 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | tests { 14 | test("should get collection var in scripts", function() { 15 | const testVar = bru.getCollectionVar("collection-var"); 16 | expect(testVar).to.equal("collection-var-value"); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/getEnvName.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getEnvName 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:pre-request { 14 | const envName = bru.getEnvName(); 15 | bru.setVar("testEnvName", envName); 16 | } 17 | 18 | tests { 19 | test("should get env name in scripts", function() { 20 | const testEnvName = bru.getVar("testEnvName"); 21 | expect(testEnvName).to.equal("Prod"); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/getEnvVar.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getEnvVar 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | 14 | tests { 15 | test("should get env var in scripts", function() { 16 | const host = bru.getEnvVar("host") 17 | expect(host).to.equal("https://testbench-sanity.usebruno.com"); 18 | }); 19 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/getFolderVar.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getFolderVar 3 | type: http 4 | seq: 8 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | tests { 14 | test("should get folder var in scripts", function() { 15 | const testVar = bru.getFolderVar("folder-var"); 16 | expect(testVar).to.equal("folder-var-value"); 17 | }); 18 | } 19 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/getProcessEnv.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getProcessEnv 3 | type: http 4 | seq: 6 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | 14 | tests { 15 | test("bru.getProcessEnv()", function() { 16 | const v = bru.getProcessEnv("PROC_ENV_VAR"); 17 | expect(v).to.equal("woof"); 18 | }); 19 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/getRequestVar.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getRequestVar 3 | type: http 4 | seq: 7 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | vars:pre-request { 14 | request-var: request-var-value 15 | } 16 | 17 | tests { 18 | test("should get request var in scripts", function() { 19 | const testVar = bru.getRequestVar("request-var"); 20 | expect(testVar).to.equal("request-var-value"); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/getVar.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getVar 3 | type: http 4 | seq: 5 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | 14 | tests { 15 | test("should get var in scripts", function() { 16 | const testSetVar = bru.getVar("testSetVar"); 17 | expect(testSetVar).to.equal("bruno-test-87267"); 18 | }); 19 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/runRequest-2.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: runRequest-2 3 | type: http 4 | seq: 11 5 | } 6 | 7 | post { 8 | url: {{echo-host}} 9 | body: text 10 | auth: none 11 | } 12 | 13 | body:text { 14 | bruno 15 | } 16 | 17 | script:pre-request { 18 | bru.setVar('run-request-runtime-var', 'run-request-runtime-var-value'); 19 | bru.setEnvVar('run-request-env-var', 'run-request-env-var-value'); 20 | bru.setGlobalEnvVar('run-request-global-env-var', 'run-request-global-env-var-value'); 21 | } 22 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/runner/1.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: 1 3 | type: http 4 | seq: 1 5 | } 6 | 7 | post { 8 | url: https://echo.usebruno.com 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:pre-request { 14 | bru.setVar('bru-runner-req', 1); 15 | } 16 | 17 | script:post-response { 18 | bru.setVar('bru.runner.skipRequest', true); 19 | } 20 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/runner/2.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: 2 3 | type: http 4 | seq: 2 5 | } 6 | 7 | post { 8 | url: https://echo.usebruno.com 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:pre-request { 14 | bru.runner.skipRequest(); 15 | } 16 | 17 | script:post-response { 18 | bru.setVar('bru.runner.skipRequest', false); 19 | } 20 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/runner/3.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: 3 3 | type: http 4 | seq: 3 5 | } 6 | 7 | post { 8 | url: https://echo.usebruno.com 9 | body: none 10 | auth: none 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/setEnvVar.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: setEnvVar 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | 14 | script:post-response { 15 | bru.setEnvVar("testSetEnvVar", "bruno-29653") 16 | } 17 | 18 | tests { 19 | test("should set env var in scripts", function() { 20 | const testSetEnvVar = bru.getEnvVar("testSetEnvVar") 21 | expect(testSetEnvVar).to.equal("bruno-29653"); 22 | }); 23 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/bru/setVar.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: setVar 3 | type: http 4 | seq: 4 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:post-response { 14 | bru.setVar("testSetVar", "bruno-test-87267") 15 | } 16 | 17 | tests { 18 | test("should get var in scripts", function() { 19 | const testSetVar = bru.getVar("testSetVar"); 20 | expect(testSetVar).to.equal("bruno-test-87267"); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/getBody.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getBody 3 | type: http 4 | seq: 9 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 | "hello": "bruno" 25 | } 26 | } 27 | 28 | assert { 29 | res.status: eq 200 30 | } 31 | 32 | tests { 33 | test("req.getBody()", function() { 34 | const data = res.getBody(); 35 | expect(data).to.eql({ 36 | "hello": "bruno" 37 | }); 38 | }); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/getHeader.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getHeader 3 | type: http 4 | seq: 5 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | headers { 14 | bruno: is-awesome 15 | } 16 | 17 | 18 | assert { 19 | res.status: eq 200 20 | res.body: eq pong 21 | } 22 | 23 | tests { 24 | test("req.getHeader(name)", function() { 25 | const h = req.getHeader('bruno'); 26 | expect(h).to.equal("is-awesome"); 27 | }); 28 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/getHeaders.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getHeaders 3 | type: http 4 | seq: 7 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | headers { 14 | bruno: is-awesome 15 | della: is-beautiful 16 | } 17 | 18 | 19 | assert { 20 | res.status: eq 200 21 | res.body: eq pong 22 | } 23 | 24 | tests { 25 | test("req.getHeaders()", function() { 26 | const h = req.getHeaders(); 27 | expect(h.bruno).to.equal("is-awesome"); 28 | expect(h.della).to.equal("is-beautiful"); 29 | }); 30 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/getMethod.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getMethod 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | 14 | assert { 15 | res.status: eq 200 16 | res.body: eq pong 17 | } 18 | 19 | tests { 20 | test("req.getMethod()()", function() { 21 | const method = req.getMethod(); 22 | expect(method).to.equal("GET"); 23 | }); 24 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/getName.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getName 3 | type: http 4 | seq: 11 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: inherit 11 | } 12 | 13 | tests { 14 | test("Check if request name is getName", function () { 15 | expect(req.getName()).to.eql("getName"); 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/getUrl.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getUrl 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | assert { 14 | res.status: eq 200 15 | res.body: eq pong 16 | } 17 | 18 | tests { 19 | test("req.getUrl()", function() { 20 | const url = req.getUrl(); 21 | expect(url).to.equal("https://testbench-sanity.usebruno.com/ping"); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/setBody.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: setBody 3 | type: http 4 | seq: 10 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 | "hello": "bruno" 25 | } 26 | } 27 | 28 | assert { 29 | res.status: eq 200 30 | } 31 | 32 | script:pre-request { 33 | req.setBody({ 34 | "bruno": "is awesome" 35 | }); 36 | } 37 | 38 | tests { 39 | test("req.setBody()", function() { 40 | const data = res.getBody(); 41 | expect(data).to.eql({ 42 | "bruno": "is awesome" 43 | }); 44 | }); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/setHeader.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: setHeader 3 | type: http 4 | seq: 6 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | headers { 14 | bruno: is-awesome 15 | } 16 | 17 | 18 | assert { 19 | res.status: eq 200 20 | res.body: eq pong 21 | } 22 | 23 | script:pre-request { 24 | req.setHeader('bruno', 'is-the-future'); 25 | } 26 | 27 | tests { 28 | test("req.setHeader(name)", function() { 29 | const h = req.getHeader('bruno'); 30 | expect(h).to.equal("is-the-future"); 31 | }); 32 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/setHeaders.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: setHeaders 3 | type: http 4 | seq: 8 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | headers { 14 | bruno: is-awesome 15 | della: is-beautiful 16 | } 17 | 18 | 19 | assert { 20 | res.status: eq 200 21 | res.body: eq pong 22 | } 23 | 24 | script:pre-request { 25 | req.setHeaders({ 26 | "content-type": "application/text", 27 | "transaction-id": "foobar" 28 | }); 29 | } 30 | 31 | tests { 32 | test("req.setHeaders()", function() { 33 | const h = req.getHeaders(); 34 | expect(h['content-type']).to.equal("application/text"); 35 | expect(h['transaction-id']).to.equal("foobar"); 36 | }); 37 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/setMethod.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: setMethod 3 | type: http 4 | seq: 4 5 | } 6 | 7 | post { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | 14 | assert { 15 | res.status: eq 200 16 | res.body: eq pong 17 | } 18 | 19 | script:pre-request { 20 | req.setMethod("GET"); 21 | } 22 | 23 | tests { 24 | test("req.setMethod()()", function() { 25 | const method = req.getMethod(); 26 | expect(method).to.equal("GET"); 27 | }); 28 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/req/setUrl.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: setUrl 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: {{host}}/ping/invalid 9 | body: none 10 | auth: none 11 | } 12 | 13 | 14 | assert { 15 | res.status: eq 200 16 | res.body: eq pong 17 | } 18 | 19 | script:pre-request { 20 | req.setUrl("https://testbench-sanity.usebruno.com/ping"); 21 | } 22 | 23 | tests { 24 | test("req.setUrl()", function() { 25 | const url = req.getUrl(); 26 | expect(url).to.equal("https://testbench-sanity.usebruno.com/ping"); 27 | }); 28 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/getBody.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getBody 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 | "hello": "bruno" 25 | } 26 | } 27 | 28 | assert { 29 | res.status: eq 200 30 | } 31 | 32 | tests { 33 | test("res.getBody()", function() { 34 | const data = res.getBody(); 35 | expect(data).to.eql({ 36 | "hello": "bruno" 37 | }); 38 | }); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/getHeader.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getHeader 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 | "hello": "bruno" 25 | } 26 | } 27 | 28 | assert { 29 | res.status: eq 200 30 | } 31 | 32 | tests { 33 | test("res.getHeader(name)", function() { 34 | const server = res.getHeader('x-powered-by'); 35 | expect(server).to.eql('Express'); 36 | }); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/getHeaders.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getHeaders 3 | type: http 4 | seq: 3 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 | "hello": "bruno" 25 | } 26 | } 27 | 28 | assert { 29 | res.status: eq 200 30 | } 31 | 32 | tests { 33 | test("res.getHeaders(name)", function() { 34 | const h = res.getHeaders(); 35 | expect(h['x-powered-by']).to.eql('Express'); 36 | expect(h['content-length']).to.eql('17'); 37 | }); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/getResponseTime.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getResponseTime 3 | type: http 4 | seq: 5 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 | "hello": "bruno" 25 | } 26 | } 27 | 28 | assert { 29 | res.status: eq 200 30 | } 31 | 32 | tests { 33 | test("res.getResponseTime()", function() { 34 | const responseTime = res.getResponseTime(); 35 | expect(typeof responseTime).to.eql("number"); 36 | expect(responseTime > 0).to.be.true; 37 | }); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/getStatus.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getStatus 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | 14 | assert { 15 | res.status: eq 200 16 | res.body: eq pong 17 | } 18 | 19 | tests { 20 | test("res.getStatus()", function() { 21 | const status = res.getStatus() 22 | expect(status).to.equal(200); 23 | }); 24 | } -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/getStatusText.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: getStatusText 3 | type: http 4 | seq: 6 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | assert { 14 | res.statusText: eq OK 15 | res.body: eq pong 16 | } 17 | 18 | tests { 19 | test("res.getStatusText()", function() { 20 | const statusText = res.getStatusText() 21 | expect(statusText).to.equal('OK'); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/setBody/boolean.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: boolean 3 | type: http 4 | seq: 7 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:post-response { 24 | res.setBody(true) 25 | } 26 | 27 | tests { 28 | test("res.setBody(boolean)", function() { 29 | const body = res.getBody(); 30 | expect(body).to.be.true; 31 | }); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/setBody/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: setBody 3 | } 4 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/setBody/null.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: null 3 | type: http 4 | seq: 6 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:post-response { 24 | res.setBody(null) 25 | } 26 | 27 | tests { 28 | test("res.setBody(null)", function() { 29 | const body = res.getBody(); 30 | expect(body).to.be.null; 31 | }); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/setBody/number.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: number 3 | type: http 4 | seq: 3 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:post-response { 24 | res.setBody(2) 25 | } 26 | 27 | tests { 28 | test("res.setBody(number)", function() { 29 | const body = res.getBody(); 30 | expect(body).to.eql(2); 31 | }); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/setBody/object.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: object 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:post-response { 24 | res.setBody({ 25 | hello : "hello from post-res" 26 | }) 27 | } 28 | 29 | tests { 30 | test("res.setBody(object)", function() { 31 | const body = res.getBody(); 32 | expect(body.hello).to.eql("hello from post-res"); 33 | }); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/api/res/setBody/string.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: string 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 | body:json { 14 | { 15 | "hello": "bruno" 16 | } 17 | } 18 | 19 | assert { 20 | res.status: eq 200 21 | } 22 | 23 | script:post-response { 24 | res.setBody("hello from post-res") 25 | } 26 | 27 | tests { 28 | test("res.setBody(string)", function() { 29 | const body = res.getBody(); 30 | expect(body).to.eql("hello from post-res"); 31 | }); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/inbuilt modules/nanoid/nanoid.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: nanoid 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:pre-request { 14 | const { nanoid } = require("nanoid"); 15 | 16 | bru.setVar("nanoid-test-id", nanoid()); 17 | } 18 | 19 | tests { 20 | test("nanoid var", function() { 21 | const id = bru.getVar('nanoid-test-id'); 22 | let isValidNanoid = /^[a-zA-Z0-9_-]{21}$/.test(id) 23 | bru.setVar('nanoid-test-id', null); 24 | expect(isValidNanoid).to.eql(true); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/inbuilt modules/tv4/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: tv4 3 | } 4 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/inbuilt modules/uuid/uuid.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: uuid 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{host}}/ping 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:pre-request { 14 | const { v4 } = require("uuid"); 15 | 16 | bru.setVar("uuid-test-id", v4()); 17 | } 18 | 19 | tests { 20 | test("uuid var", function() { 21 | const id = bru.getVar('uuid-test-id'); 22 | let isValidUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(id); 23 | bru.setVar('uuid-test-id', null); 24 | expect(isValidUuid).to.eql(true); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /packages/bruno-tests/collection/scripting/js/folder-collection script-tests pre.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: folder-collection script-tests pre 3 | type: http 4 | seq: 4 5 | } 6 | 7 | post { 8 | url: {{echo-host}} 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:pre-request { 14 | bru.setVar('should-test-collection-scripts', true); 15 | bru.setVar('should-test-folder-scripts', true); 16 | } 17 | -------------------------------------------------------------------------------- /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/string interpolation/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: string interpolation 3 | } 4 | 5 | vars:pre-request { 6 | folder_pre_var: folder_pre_var_value 7 | folder_pre_var_2: {{env.var1}} 8 | } 9 | -------------------------------------------------------------------------------- /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-tests/collection_level_oauth2/.gitignore: -------------------------------------------------------------------------------- 1 | !.env -------------------------------------------------------------------------------- /packages/bruno-tests/collection_level_oauth2/.nvmrc: -------------------------------------------------------------------------------- 1 | v18 -------------------------------------------------------------------------------- /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-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_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_level_oauth2/readme.md: -------------------------------------------------------------------------------- 1 | # bruno-tests collection 2 | 3 | API Collection to run sanity tests on Bruno CLI. 4 | -------------------------------------------------------------------------------- /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/.env: -------------------------------------------------------------------------------- 1 | PROC_ENV_VAR=woof -------------------------------------------------------------------------------- /packages/bruno-tests/collection_oauth2/.gitignore: -------------------------------------------------------------------------------- 1 | !.env -------------------------------------------------------------------------------- /packages/bruno-tests/collection_oauth2/.nvmrc: -------------------------------------------------------------------------------- 1 | v18 -------------------------------------------------------------------------------- /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-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_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-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-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-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-tests/collection_oauth2/bruno.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "name": "OAuth2 Demo", 4 | "type": "collection", 5 | "scripts": { 6 | "moduleWhitelist": [ 7 | "crypto" 8 | ], 9 | "filesystemAccess": { 10 | "allow": true 11 | } 12 | }, 13 | "clientCertificates": { 14 | "enabled": true, 15 | "certs": [] 16 | }, 17 | "presets": { 18 | "requestType": "http" 19 | } 20 | } -------------------------------------------------------------------------------- /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_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/file.json: -------------------------------------------------------------------------------- 1 | { 2 | "hello": "bruno" 3 | } 4 | -------------------------------------------------------------------------------- /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-tests/collection_oauth2/readme.md: -------------------------------------------------------------------------------- 1 | # bruno-tests collection 2 | 3 | API Collection to run sanity tests on Bruno CLI. 4 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-authorization_code/bruno.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "name": "keycloak-authorization_code", 4 | "type": "collection", 5 | "ignore": [ 6 | "node_modules", 7 | ".git" 8 | ] 9 | } -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-authorization_code/collection.bru: -------------------------------------------------------------------------------- 1 | auth { 2 | mode: oauth2 3 | } 4 | 5 | auth:oauth2 { 6 | grant_type: authorization_code 7 | callback_url: {{key-host}}/realms/bruno/account 8 | authorization_url: {{key-host}}/realms/bruno/protocol/openid-connect/auth 9 | access_token_url: {{key-host}}/realms/bruno/protocol/openid-connect/token 10 | refresh_token_url: 11 | client_id: account 12 | client_secret: {{client_secret}} 13 | scope: openid 14 | state: 15 | pkce: true 16 | credentials_placement: body 17 | credentials_id: credentials 18 | token_placement: header 19 | token_header_prefix: Bearer 20 | auto_fetch_token: true 21 | auto_refresh_token: false 22 | } 23 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-authorization_code/environments/oauth2.bru: -------------------------------------------------------------------------------- 1 | vars { 2 | key-host: http://localhost:8080 3 | } 4 | vars:secret [ 5 | client_secret 6 | ] 7 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-authorization_code/user_info_coll-auth.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: user_info_coll-auth 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{key-host}}/realms/bruno/protocol/openid-connect/userinfo 9 | body: none 10 | auth: inherit 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-authorization_code/user_info_custom.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: user_info_custom 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: {{key-host}}/realms/bruno/protocol/openid-connect/userinfo 9 | body: none 10 | auth: bearer 11 | } 12 | 13 | auth:bearer { 14 | token: {{$oauth2.credentials.access_token}} 15 | } 16 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-client-credentials/bruno.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "name": "keycloak-client-credentials", 4 | "type": "collection", 5 | "ignore": [ 6 | "node_modules", 7 | ".git" 8 | ] 9 | } -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-client-credentials/collection.bru: -------------------------------------------------------------------------------- 1 | auth { 2 | mode: oauth2 3 | } 4 | 5 | auth:oauth2 { 6 | grant_type: client_credentials 7 | access_token_url: {{key-host}}/realms/bruno/protocol/openid-connect/token 8 | refresh_token_url: 9 | client_id: account 10 | client_secret: {{client_secret}} 11 | scope: openid 12 | credentials_placement: body 13 | credentials_id: credentials 14 | token_placement: header 15 | token_header_prefix: Bearer 16 | auto_fetch_token: true 17 | auto_refresh_token: false 18 | } 19 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-client-credentials/environments/oauth2.bru: -------------------------------------------------------------------------------- 1 | vars { 2 | key-host: http://localhost:8080 3 | } 4 | vars:secret [ 5 | client_secret 6 | ] 7 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-client-credentials/user_info_coll-auth.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: user_info_coll-auth 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{key-host}}/realms/bruno/protocol/openid-connect/userinfo 9 | body: none 10 | auth: inherit 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-client-credentials/user_info_custom.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: user_info_custom 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: {{key-host}}/realms/bruno/protocol/openid-connect/userinfo 9 | body: none 10 | auth: bearer 11 | } 12 | 13 | auth:bearer { 14 | token: {{$oauth2.credentials.access_token}} 15 | } 16 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-client-credentials/user_info_request-auth.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: user_info_request-auth 3 | type: http 4 | seq: 3 5 | } 6 | 7 | get { 8 | url: {{key-host}}/realms/bruno/protocol/openid-connect/userinfo 9 | body: none 10 | auth: oauth2 11 | } 12 | 13 | auth:oauth2 { 14 | grant_type: client_credentials 15 | access_token_url: {{key-host}}/realms/bruno/protocol/openid-connect/token 16 | refresh_token_url: 17 | client_id: account 18 | client_secret: {{client_secret}}a 19 | scope: openid 20 | credentials_placement: body 21 | credentials_id: credentials 22 | token_placement: header 23 | token_header_prefix: Bearer 24 | auto_fetch_token: true 25 | auto_refresh_token: false 26 | } 27 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-password-credentials/bruno.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "name": "keycloak-password-credentials", 4 | "type": "collection", 5 | "ignore": [ 6 | "node_modules", 7 | ".git" 8 | ] 9 | } -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-password-credentials/collection.bru: -------------------------------------------------------------------------------- 1 | auth { 2 | mode: oauth2 3 | } 4 | 5 | auth:oauth2 { 6 | grant_type: password 7 | access_token_url: {{key-host}}/realms/bruno/protocol/openid-connect/token 8 | refresh_token_url: 9 | username: bruno 10 | password: bruno 11 | client_id: account 12 | client_secret: {{client_secret}} 13 | scope: openid 14 | credentials_placement: body 15 | credentials_id: credentials 16 | token_placement: header 17 | token_header_prefix: Bearer 18 | auto_fetch_token: true 19 | auto_refresh_token: false 20 | } 21 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-password-credentials/environments/oauth2.bru: -------------------------------------------------------------------------------- 1 | vars { 2 | key-host: http://localhost:8080 3 | } 4 | vars:secret [ 5 | client_secret 6 | ] 7 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-password-credentials/user_info_coll-auth.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: user_info_coll-auth 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: {{key-host}}/realms/bruno/protocol/openid-connect/userinfo 9 | body: none 10 | auth: inherit 11 | } 12 | -------------------------------------------------------------------------------- /packages/bruno-tests/keycloak-password-credentials/user_info_custom.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: user_info_custom 3 | type: http 4 | seq: 2 5 | } 6 | 7 | get { 8 | url: {{key-host}}/realms/bruno/protocol/openid-connect/userinfo 9 | body: none 10 | auth: bearer 11 | } 12 | 13 | auth:bearer { 14 | token: {{$oauth2.credentials.access_token}} 15 | } 16 | -------------------------------------------------------------------------------- /packages/bruno-tests/sandwich_exec/bruno.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "name": "sandwich_exec", 4 | "type": "collection", 5 | "ignore": [ 6 | "node_modules", 7 | ".git" 8 | ], 9 | "scripts": { 10 | "flow": "sandwich" 11 | } 12 | } -------------------------------------------------------------------------------- /packages/bruno-tests/sandwich_exec/collection.bru: -------------------------------------------------------------------------------- 1 | script:pre-request { 2 | console.log("collection pre"); 3 | } 4 | 5 | script:post-response { 6 | { 7 | console.log("collection post"); 8 | const sequence = bru.getVar('sequence') || []; 9 | sequence.push(1); 10 | bru.setVar('sequence', sequence); 11 | console.log("sequence", bru.getVar('sequence')); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/bruno-tests/sandwich_exec/folder/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: folder 3 | } 4 | 5 | script:pre-request { 6 | console.log("folder pre"); 7 | } 8 | 9 | script:post-response { 10 | { 11 | const sequence = bru.getVar('sequence') || []; 12 | sequence.push(2); 13 | bru.setVar('sequence', sequence); 14 | } 15 | console.log("folder post"); 16 | } 17 | -------------------------------------------------------------------------------- /packages/bruno-tests/sandwich_exec/folder/request.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: request 3 | type: http 4 | seq: 1 5 | } 6 | 7 | get { 8 | url: https://www.example.com 9 | body: none 10 | auth: none 11 | } 12 | 13 | script:pre-request { 14 | console.log("request pre"); 15 | } 16 | 17 | script:post-response { 18 | { 19 | console.log("request post"); 20 | 21 | const sequence = bru.getVar('sequence') || []; 22 | sequence.push(3); 23 | bru.setVar('sequence', sequence); 24 | } 25 | } 26 | 27 | tests { 28 | test("sandwich script execution is proper", function() { 29 | const sequence = bru.getVar('sequence'); 30 | bru.setVar('sequence', null); 31 | expect(sequence.toString()).to.equal([3,2,1].toString()); 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /packages/bruno-tests/sequential_exec/bruno.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "name": "sequential_exec", 4 | "type": "collection", 5 | "ignore": [ 6 | "node_modules", 7 | ".git" 8 | ], 9 | "scripts": { 10 | "flow": "sequential" 11 | } 12 | } -------------------------------------------------------------------------------- /packages/bruno-tests/sequential_exec/collection.bru: -------------------------------------------------------------------------------- 1 | script:pre-request { 2 | console.log("collection pre"); 3 | } 4 | 5 | script:post-response { 6 | { 7 | console.log("collection post"); 8 | const sequence = bru.getVar('sequence') || []; 9 | sequence.push(1); 10 | bru.setVar('sequence', sequence); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/bruno-tests/sequential_exec/folder/folder.bru: -------------------------------------------------------------------------------- 1 | meta { 2 | name: folder 3 | } 4 | 5 | script:pre-request { 6 | console.log("folder pre"); 7 | } 8 | 9 | script:post-response { 10 | { 11 | console.log("folder post"); 12 | const sequence = bru.getVar('sequence') || []; 13 | sequence.push(2); 14 | bru.setVar('sequence', sequence); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /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-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-tests/src/multipart/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const router = express.Router(); 3 | const formDataParser = require('./form-data-parser'); 4 | 5 | router.post('/mixed-content-types', (req, res) => { 6 | const parts = formDataParser.parse(req); 7 | return res.json(parts); 8 | }); 9 | 10 | module.exports = router; 11 | -------------------------------------------------------------------------------- /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/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/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-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-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-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-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-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/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/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/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-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-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/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-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-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-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 | -------------------------------------------------------------------------------- /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-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-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-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-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-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-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-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-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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /playwright/codegen.ts: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { startApp } = require('./electron.ts'); 3 | 4 | async function main() { 5 | const { app, context } = await startApp(); 6 | let outputFile = process.argv[2]?.trim(); 7 | if (outputFile && !/\.(ts|js)$/.test(outputFile)) { 8 | outputFile = path.join(__dirname, '../e2e-tests/', outputFile + '.spec.ts'); 9 | } 10 | await context._enableRecorder({ language: 'playwright-test', mode: 'recording', outputFile }); 11 | } 12 | 13 | main(); 14 | -------------------------------------------------------------------------------- /playwright/electron.ts: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { _electron: electron } = require('playwright'); 3 | 4 | const electronAppPath = path.join(__dirname, '../packages/bruno-electron'); 5 | 6 | exports.startApp = async () => { 7 | const app = await electron.launch({ args: [electronAppPath] }); 8 | const context = await app.context(); 9 | 10 | app.process().stdout.on('data', (data) => { 11 | process.stdout.write(data.toString().replace(/^(?=.)/gm, '[Electron] |')); 12 | }); 13 | app.process().stderr.on('data', (error) => { 14 | process.stderr.write(error.toString().replace(/^(?=.)/gm, '[Electron] |')); 15 | }); 16 | return { app, context }; 17 | }; 18 | --------------------------------------------------------------------------------