From 2b3e648fd9ed17fc3e69d55ed641ba7643cfa096 Mon Sep 17 00:00:00 2001 From: Adwait Aayush Date: Tue, 1 Sep 2026 19:34:28 +0530 Subject: [PATCH 1/2] fix(docs): resolve nested variables fully when show vars is on --- .../src/hooks/useVariableResolver.spec.tsx | 40 +++++++++++++++++++ .../src/hooks/useVariableResolver.tsx | 6 +-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx b/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx index 22b79ac1..9a3578e8 100644 --- a/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx +++ b/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx @@ -141,3 +141,43 @@ describe('lookup (variable hover card)', () => { expect(html).toContain('undefined'); }); }); + +const NestedProbe: React.FC = () => { + const r = useResolvedVariables(); + return ( +
+ {r.resolve('{{endpoint}}')} + {r.interpolate('{{endpoint}}')} +
+ ); +}; + +describe('nested variable resolution', () => { + const nested = { + request: { + variables: [ + { name: 'endpoint', value: '{{host}}/v1' }, + { name: 'host', value: 'https://api.test' } + ] + }, + config: { environments: [{ name: 'Dev', variables: [] }] } + } as unknown as typeof collection; + + it('follows a variable that points at another variable, for display and for interpolation', () => { + const store = createOpenCollectionStore(); + store.dispatch(setDocsCollection(nested)); + store.dispatch(setActiveEnv('Dev')); + store.dispatch(setShowVars(true)); + + const html = renderToStaticMarkup( + + + + + + ); + + expect(html).toContain('https://api.test/v1'); + expect(html).toContain('https://api.test/v1'); + }); +}); diff --git a/packages/bruno-api-docs/src/hooks/useVariableResolver.tsx b/packages/bruno-api-docs/src/hooks/useVariableResolver.tsx index e88b2224..f07b9d64 100644 --- a/packages/bruno-api-docs/src/hooks/useVariableResolver.tsx +++ b/packages/bruno-api-docs/src/hooks/useVariableResolver.tsx @@ -12,7 +12,7 @@ import { getItemUuid } from '@/utils/itemUtils'; import { mockDataFunctions, timeBasedDynamicVars } from '@/runner/utils/faker-functions'; import { buildScopedVariableModel, - resolveVariables, + resolveValueDeep, singleReferenceName, detectSpecialScope, isValidVariableName, @@ -95,7 +95,7 @@ const makeResolver = ( activeEnvName: string | null ): VariableResolver => { const isSecret = (name: string) => model.secretNames.has(name.trim()); - const interpolate = (raw: string) => resolveVariables(raw, model.values); + const interpolate = (raw: string) => resolveValueDeep(raw, model.values); return { showVars, activeEnvName, @@ -263,7 +263,7 @@ export const ItemVariableResolverProvider: React.FC<{ ); const interpolateWithSecrets = useCallback( - (raw: string) => resolveVariables(raw, model.fullValues), + (raw: string) => resolveValueDeep(raw, model.fullValues), [model] ); From 8e8ee8ccfd90d4c45b67b33b00392561c7e893eb Mon Sep 17 00:00:00 2001 From: Adwait Aayush Date: Fri, 4 Sep 2026 17:08:35 +0530 Subject: [PATCH 2/2] test(docs): cover nested variables when show vars is off --- .../src/hooks/useVariableResolver.spec.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx b/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx index 9a3578e8..3f9af104 100644 --- a/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx +++ b/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx @@ -180,4 +180,22 @@ describe('nested variable resolution', () => { expect(html).toContain('https://api.test/v1'); expect(html).toContain('https://api.test/v1'); }); + + it('gates resolve on showVars but never interpolate', () => { + const store = createOpenCollectionStore(); + store.dispatch(setDocsCollection(nested)); + store.dispatch(setActiveEnv('Dev')); + store.dispatch(setShowVars(false)); + + const html = renderToStaticMarkup( + + + + + + ); + + expect(html).toContain('{{endpoint}}'); + expect(html).toContain('https://api.test/v1'); + }); });