feat: add certs and proxy config to bru.sendRequest API#6988
feat: add certs and proxy config to bru.sendRequest API#6988bijin-bruno merged 6 commits intousebruno:mainfrom
certs and proxy config to bru.sendRequest API#6988Conversation
WalkthroughBuilds and threads a certsAndProxyConfig through CLI/Electron request preparation, exposes a createSendRequest factory (preserving default sendRequest), updates Bru to accept and use certsAndProxyConfig for creating sendRequest, updates runtimes/tests, and adds autocomplete hints for Changes
Sequence DiagramsequenceDiagram
participant CLI_Electron as Electron/CLI
participant CertUtils as cert-utils (buildCertsAndProxyConfig)
participant Interpolator as interpolateObject
participant Request as Request
participant Runtime as Runtime/Bru
participant CreateSR as createSendRequest
participant Axios as axios
CLI_Electron->>CertUtils: buildCertsAndProxyConfig(collection..., request...)
CertUtils->>Interpolator: interpolate client certs & proxy using vars
CertUtils-->>CLI_Electron: certsAndProxyConfig
CLI_Electron->>Request: attach certsAndProxyConfig
CLI_Electron->>Runtime: new Bru(..., certsAndProxyConfig)
Runtime->>CreateSR: createSendRequest(certsAndProxyConfig)
CreateSR-->>Runtime: configured sendRequest
Runtime->>CreateSR: sendRequest(requestConfig, [callback])
CreateSR->>CreateSR: compute http/https agents
CreateSR->>Axios: perform HTTP request (with agents)
Axios-->>CreateSR: response / error
CreateSR-->>Runtime: resolve/reject or invoke callback
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@packages/bruno-electron/src/ipc/network/cert-utils.js`:
- Line 4: buildCertsAndProxyConfig is redundantly calling transformProxyConfig
before passing proxy settings to getHttpHttpsAgents which also transforms them;
remove the transformProxyConfig invocation inside buildCertsAndProxyConfig and
pass the raw proxy config object returned from getSystemProxy (or the
intermediate variable currently being transformed) directly into
getHttpHttpsAgents so that transformProxyConfig is only applied once by
getHttpHttpsAgents; update any references to the transformed variable name (in
buildCertsAndProxyConfig) accordingly and ensure getHttpHttpsAgents continues to
accept and transform the raw config.
In `@packages/bruno-requests/src/scripting/send-request.spec.ts`:
- Around line 100-116: The tests call createSendRequest with a partial config;
update them to use a complete SendRequestConfig by creating a shared baseConfig
object that includes collectionPath (string) and a full options object
(ConfigOptions with noproxy, shouldVerifyTls, etc.), then spread/extend that
baseConfig per test (e.g., for proxy-specific cases) before passing it into
createSendRequest; adjust all test cases that currently pass partial configs
(including the one invoking createSendRequest and other occurrences) to
reference this baseConfig so tests mirror realistic usage of createSendRequest.
In `@packages/bruno-requests/src/scripting/send-request.ts`:
- Around line 22-33: The createSendRequest function currently passes a
possibly-relative requestConfig.url to getHttpHttpsAgents, breaking proxy/cert
matching; change it to compute an absolute requestUrl by resolving
requestConfig.url against requestConfig.baseURL (or mergedConfig.baseURL) when
url is a string but not an absolute URL, e.g. if url starts with '/' or lacks
protocol prepend the baseURL before calling getHttpHttpsAgents; then pass that
derived requestUrl to getHttpHttpsAgents and continue using mergedConfig for the
Axios request so hostname/protocol and cert matching work correctly (update
references to requestUrl, mergedConfig, requestConfig.url and getHttpHttpsAgents
accordingly).
| test('should apply agents from config', async () => { | ||
| const mockHttpAgent = { name: 'httpAgent' }; | ||
| const mockHttpsAgent = { name: 'httpsAgent' }; | ||
| mockGetHttpHttpsAgents.mockResolvedValue({ | ||
| httpAgent: mockHttpAgent, | ||
| httpsAgent: mockHttpsAgent | ||
| }); | ||
| const mockResponse = { data: 'test' }; | ||
| mockAxios.mockResolvedValue(mockResponse); | ||
|
|
||
| const customSendRequest = createSendRequest({ proxyConfig: {} }); | ||
| await customSendRequest({ url: 'https://example.com' }); | ||
|
|
||
| expect(mockGetHttpHttpsAgents).toHaveBeenCalledWith({ | ||
| proxyConfig: {}, | ||
| requestUrl: 'https://example.com' | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find SendRequestConfig definition
fd "send-request" -type f | grep -E "\.(ts|js)$" | grep -v spec | head -10Repository: usebruno/bruno
Length of output: 228
🏁 Script executed:
#!/bin/bash
# Look for SendRequestConfig type/interface definition
rg -n "interface SendRequestConfig|type SendRequestConfig" --type tsRepository: usebruno/bruno
Length of output: 185
🏁 Script executed:
#!/bin/bash
# Examine the send-request.spec.ts test file
fd "send-request.spec.ts" -type fRepository: usebruno/bruno
Length of output: 228
🏁 Script executed:
#!/bin/bash
# Find GetHttpHttpsAgentsParams definition
rg -n "interface GetHttpHttpsAgentsParams|type GetHttpHttpsAgentsParams" -A 10Repository: usebruno/bruno
Length of output: 961
🏁 Script executed:
#!/bin/bash
# Find and read the send-request.spec.ts file
fd "send-request.spec.ts" -exec wc -l {} \;Repository: usebruno/bruno
Length of output: 244
🏁 Script executed:
#!/bin/bash
# Read the send-request.spec.ts file
fd "send-request.spec.ts" -exec cat -n {} \;Repository: usebruno/bruno
Length of output: 288
🏁 Script executed:
#!/bin/bash
# Find the test file path and read it
find . -name "send-request.spec.ts" -type fRepository: usebruno/bruno
Length of output: 118
🏁 Script executed:
#!/bin/bash
# Read the test file
cat packages/bruno-requests/src/scripting/send-request.spec.ts | head -160Repository: usebruno/bruno
Length of output: 5133
🏁 Script executed:
#!/bin/bash
# Read the send-request.ts file to see the createSendRequest function signature
cat packages/bruno-requests/src/scripting/send-request.tsRepository: usebruno/bruno
Length of output: 2496
🏁 Script executed:
#!/bin/bash
# Check tsconfig setup for test files
find . -name "tsconfig*.json" | head -5 | xargs -I {} sh -c 'echo "=== {} ===" && cat {}'Repository: usebruno/bruno
Length of output: 3880
🏁 Script executed:
#!/bin/bash
# Check if jest config includes TypeScript
find . -name "jest.config.*" -o -name "jest.setup.*" | head -3 | xargs -I {} sh -c 'echo "=== {} ===" && cat {}'Repository: usebruno/bruno
Length of output: 1561
🏁 Script executed:
#!/bin/bash
# Check if there's a build/test command that includes type checking
rg -n "typeCheck|noEmit|skipLibCheck" jest.config.* tsconfig* 2>/dev/null | head -20Repository: usebruno/bruno
Length of output: 40
🏁 Script executed:
#!/bin/bash
# Check if bruno-requests has a specific jest config
find ./packages/bruno-requests -name "jest.config.*" -o -name "babel.config.*"Repository: usebruno/bruno
Length of output: 140
🏁 Script executed:
#!/bin/bash
# Check bruno-requests tsconfig to see if .spec.ts files are included in type checking
cat ./packages/bruno-requests/tsconfig.json 2>/dev/null || echo "No tsconfig found"Repository: usebruno/bruno
Length of output: 615
🏁 Script executed:
#!/bin/bash
# Check the jest.config.js for bruno-requests to understand test setup
cat ./packages/bruno-requests/jest.config.jsRepository: usebruno/bruno
Length of output: 420
🏁 Script executed:
#!/bin/bash
# Search for proxyConfig usage in the codebase to understand the actual config shape
rg -n "proxyConfig" packages/bruno-requests/src --type ts | head -20Repository: usebruno/bruno
Length of output: 2246
🏁 Script executed:
#!/bin/bash
# Verify the exact property name by looking at how getHttpHttpsAgents is actually called
rg -B 5 -A 5 "getHttpHttpsAgents\(" packages/bruno-requests/src/scripting/send-request.tsRepository: usebruno/bruno
Length of output: 439
🏁 Script executed:
#!/bin/bash
# Check what ProxyConfig interface looks like
rg -n "type ProxyConfig|interface ProxyConfig" packages/bruno-requests/src -A 5Repository: usebruno/bruno
Length of output: 1055
🏁 Script executed:
#!/bin/bash
# Search for actual usages of createSendRequest to see what config is passed in real code
rg -n "createSendRequest\(" packages/bruno-requests/src --type ts -A 2 | grep -v "spec.ts"Repository: usebruno/bruno
Length of output: 307
🏁 Script executed:
#!/bin/bash
# Look for how SendRequestConfig is actually constructed and used
rg -n "SendRequestConfig" packages/bruno-requests/src -B 2 -A 2Repository: usebruno/bruno
Length of output: 1311
🏁 Script executed:
#!/bin/bash
# Verify what's in ConfigOptions to understand the full picture
rg -n "type ConfigOptions|interface ConfigOptions" packages/bruno-requests/src -A 10 | head -30Repository: usebruno/bruno
Length of output: 983
🏁 Script executed:
#!/bin/bash
# Check if the test actually runs successfully with current config
cd packages/bruno-requests && npm test -- send-request.spec.ts --listTests 2>&1 | head -20Repository: usebruno/bruno
Length of output: 478
🏁 Script executed:
#!/bin/bash
# Double-check if createSendRequest spreads config to getHttpHttpsAgents
cat packages/bruno-requests/src/scripting/send-request.ts | sed -n '22,40p'Repository: usebruno/bruno
Length of output: 858
🏁 Script executed:
#!/bin/bash
# Check what the test is actually passing to getHttpHttpsAgents
rg -A 10 "should apply agents from config" packages/bruno-requests/src/scripting/send-request.spec.ts | head -20Repository: usebruno/bruno
Length of output: 494
Use a complete SendRequestConfig in tests instead of partial config objects.
The test passes only { proxyConfig: {} } to createSendRequest(), but SendRequestConfig requires collectionPath (string) and options (ConfigOptions with noproxy, shouldVerifyTls, etc.). While test files aren't type-checked, the incomplete config doesn't reflect realistic usage and makes tests less meaningful. Extract a shared base config with all required fields and extend it per test to improve clarity and maintainability.
Suggested pattern
+const baseConfig = {
+ collectionPath: '/tmp',
+ options: {
+ noproxy: false,
+ shouldVerifyTls: true,
+ shouldUseCustomCaCertificate: false,
+ shouldKeepDefaultCaCertificates: true
+ }
+};
@@
- const customSendRequest = createSendRequest({ proxyConfig: {} });
+ const customSendRequest = createSendRequest({ ...baseConfig });Also applies to: lines 134–139, 149–153
🤖 Prompt for AI Agents
In `@packages/bruno-requests/src/scripting/send-request.spec.ts` around lines 100
- 116, The tests call createSendRequest with a partial config; update them to
use a complete SendRequestConfig by creating a shared baseConfig object that
includes collectionPath (string) and a full options object (ConfigOptions with
noproxy, shouldVerifyTls, etc.), then spread/extend that baseConfig per test
(e.g., for proxy-specific cases) before passing it into createSendRequest;
adjust all test cases that currently pass partial configs (including the one
invoking createSendRequest and other occurrences) to reference this baseConfig
so tests mirror realistic usage of createSendRequest.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/bruno-cli/src/runner/run-single-request.js`:
- Around line 171-175: sendRequestInterpolationOptions currently only passes
envVars, runtimeVariables, and processEnvVars so proxy/cert paths that use other
variable scopes won't interpolate; update the sendRequestInterpolationOptions
object in run-single-request.js to also include collectionVariables,
folderVariables, requestVariables, globalEnvironmentVariables, and
promptVariables (the same scopes used by buildCertsAndProxyConfig in
cert-utils.js) so those variables are available during interpolation.
🧹 Nitpick comments (1)
packages/bruno-cli/src/runner/run-single-request.js (1)
168-193: RedundantgetSystemProxy()calls – consider reusing the result.
getSystemProxy()is called here at line 170, and again at lines 333, 380, and 527. Since system proxy configuration doesn't change during request execution, you could reusesystemProxyConfigfrom line 170 instead of calling it multiple times.♻️ Suggested refactor – reuse systemProxyConfig
Move the
getSystemProxy()call earlier (before line 168) and reusesystemProxyConfigat lines 333, 380, and 527:- const systemProxy = await getSystemProxy(); + const systemProxy = systemProxyConfig;Apply similar changes at lines 380 and 527.
| const cliOptions = getOptions(); | ||
| const systemProxyConfig = await getSystemProxy(); | ||
| const sendRequestInterpolationOptions = { | ||
| envVars: envVariables, |
There was a problem hiding this comment.
include globalEnvVars for cli
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When bru.sendRequest is called with a plain URL string instead of a
config object, the function now normalizes it to { url: string } before
processing. This fixes the case where spreading a string created an
invalid config object.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…onfig
Interpolate environment variables in clientCertificates and proxy
configuration for bru.sendRequest API, enabling use of variables like
{{CERT_PATH}} or {{PROXY_HOST}} in certificate paths and proxy settings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add interpolateObject to electron's interpolate-string.js using buildCombinedVars pattern (matches CLI implementation) - Simplify cert-utils.js by using interpolateObject instead of manual field-by-field interpolation - Add interpolation for clientCertificates and proxy config in CLI's run-single-request.js for bru.sendRequest Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add globalEnvVars, collectionVariables, folderVariables, requestVariables to sendRequestInterpolationOptions for complete variable support - Use cached system proxy instead of redundant getSystemProxy() call - Remove duplicate getOptions() call Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
da2bdbe to
d906393
Compare
Only load CA certificates when shouldVerifyTls is true, since they are not used for validation when TLS verification is disabled. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
jira
Description
Contribution Checklist:
Note: Keeping the PR small and focused helps make it easier to review and merge. If you have multiple changes you want to make, please consider submitting them as separate pull requests.
Publishing to New Package Managers
Please see here for more information.
Summary by CodeRabbit
New Features
Tests
Public API