Skip to content

feat: add variable list APIs (bru.getVarList, bru.getEnvVarList, bru.getGlobalEnvVarList) - #7887

Closed
sanish-bruno wants to merge 21 commits into
usebruno:mainfrom
sanish-bruno:feat/variables-scripting-apis
Closed

feat: add variable list APIs (bru.getVarList, bru.getEnvVarList, bru.getGlobalEnvVarList)#7887
sanish-bruno wants to merge 21 commits into
usebruno:mainfrom
sanish-bruno:feat/variables-scripting-apis

Conversation

@sanish-bruno

@sanish-bruno sanish-bruno commented Apr 29, 2026

Copy link
Copy Markdown
Collaborator

JIRA

Summary

Adds variable list APIs to Bruno's scripting engine. Instead of namespace-style properties, these are getter methods that return arrays of {key, value} objects with domain-specific methods attached.

New APIs

Three getter methods on the bru scripting context:

  • bru.getVarList() — runtime variables
  • bru.getEnvVarList() — active collection environment variables
  • bru.getGlobalEnvVarList() — active global environment variables

Each returns an array (Array.isArray() is true) of {key, value} entries, so standard array methods (find, filter, map, forEach, length) work out of the box. Additionally, each array has these domain methods:

Method getVarList() getEnvVarList() getGlobalEnvVarList()
.get(key) Yes Yes Yes
.set(key, value) Yes Yes Yes
.has(key) Yes Yes Yes
.delete(key) Yes Yes No (TODO — UI sync)
.clear() Yes Yes No (TODO — UI sync)
.toObject() Yes Yes Yes

Usage examples

// Direct chaining
bru.getVarList().set('host', 'example.com');
bru.getVarList().get('host'); // 'example.com'

// Store reference for repeated use
const envVars = bru.getEnvVarList();
envVars.set('token', 'abc123');
envVars.has('token'); // true
envVars.toObject();   // { token: 'abc123', host: '...', ... }

// Array methods work natively
const envVars = bru.getEnvVarList();
envVars.filter(e => e.key.startsWith('test'));
envVars.find(e => e.key === 'host');
envVars.map(e => e.key);
envVars.length; // number of variables

Postman translator changes

Both the AST-based translator (postman-to-bruno-translator.js) and the regex fallback (postman-translations.js) have been updated.

Before (on main) → After (this PR)

Regex-based translator (postman-translations.js):

Postman Before (main) After (this PR)
pm.environment.get( bru.getEnvVar( bru.getEnvVarList().get(
pm.environment.set( bru.setEnvVar( bru.getEnvVarList().set(
pm.environment.has(…) bru.getEnvVar(…) !== undefined && bru.getEnvVar(…) !== null bru.getEnvVarList().has(
pm.environment.unset( (not translated) bru.getEnvVarList().delete(
pm.environment.toObject( bru.getAllEnvVars( bru.getEnvVarList().toObject(
pm.environment.clear( bru.deleteAllEnvVars( bru.getEnvVarList().clear(
pm.environment.name bru.getEnvName() bru.getEnvName()
pm.variables.get( bru.getVar( bru.getVarList().get(
pm.variables.set( bru.setVar( bru.getVarList().set(
pm.variables.has( (not translated) bru.getVarList().has(
pm.variables.unset( (not translated) bru.getVarList().delete(
pm.variables.toObject( bru.getAllVars( bru.getVarList().toObject(
pm.variables.clear( (not translated) bru.getVarList().clear(
pm.globals.get( bru.getGlobalEnvVar( bru.getGlobalEnvVarList().get(
pm.globals.set( bru.setGlobalEnvVar( bru.getGlobalEnvVarList().set(
pm.globals.has( (not translated) bru.getGlobalEnvVarList().has(
pm.globals.toObject( bru.getAllGlobalEnvVars( bru.getGlobalEnvVarList().toObject(
postman.setEnvironmentVariable( bru.setEnvVar( bru.getEnvVarList().set(
postman.getEnvironmentVariable( bru.getEnvVar( bru.getEnvVarList().get(
postman.clearEnvironmentVariable( bru.deleteEnvVar( bru.getEnvVarList().delete(

AST-based translator (postman-to-bruno-translator.js):

Same mappings as above (including pm.environment.namebru.getEnvName()), plus:

  • Removed complex pm.environment.has transformation (was expanding to bru.getEnvVar(…) !== undefined && bru.getEnvVar(…) !== null) — now a simple 1:1 mapping
  • Removed complex pm.globals.has transformation (same pattern) — now a simple 1:1 mapping

Bruno → Postman translator (bruno-to-postman-translator.js)

Added reverse translations for the new getter-based APIs:

Bruno Postman
bru.getVarList().get("key") pm.variables.get("key")
bru.getVarList().set("key", "val") pm.variables.set("key", "val")
bru.getVarList().has("key") pm.variables.has("key")
bru.getVarList().delete("key") pm.variables.unset("key")
bru.getVarList().toObject() pm.variables.toObject()
bru.getVarList().clear() pm.variables.clear()
bru.getEnvVarList().get("key") pm.environment.get("key")
bru.getEnvVarList().set("key", "val") pm.environment.set("key", "val")
bru.getEnvVarList().has("key") pm.environment.has("key")
bru.getEnvVarList().delete("key") pm.environment.unset("key")
bru.getEnvVarList().toObject() pm.environment.toObject()
bru.getEnvVarList().clear() pm.environment.clear()
bru.getGlobalEnvVarList().get("key") pm.globals.get("key")
bru.getGlobalEnvVarList().set("key", "val") pm.globals.set("key", "val")
bru.getGlobalEnvVarList().has("key") pm.globals.has("key")
bru.getGlobalEnvVarList().toObject() pm.globals.toObject()

Legacy methods (bru.getEnvVar, bru.setVar, etc.) continue to be translated as before.

Note: Alias-based translations are not currently supported in the Bruno → Postman translator. Only direct call expressions are translated. For example:

// ✅ Translated — direct call expression
bru.getEnvVarList().get("host");        // → pm.environment.get("host")
bru.getVarList().set("key", "value");   // → pm.variables.set("key", "value")

// ❌ NOT translated — aliased to a variable first
const envVars = bru.getEnvVarList();
envVars.get("host");                    // stays as-is (envVars.get("host"))

This is consistent with the existing translator behavior — it does not resolve variable aliases for Bruno APIs.

New standalone method

  • bru.getGlobalEnvName() — returns the name of the active global environment. Added for consistency with the existing bru.getEnvName() method. Available in both sandboxes.

Implementation

  • VariableList extends Array (packages/bruno-js/src/variable-list.js) — entries are {key, value} objects stored as array elements. Symbol.species set to Array so filter/map return plain arrays. Wraps existing plain { key: value } objects and syncs mutations bidirectionally for backward compatibility
  • Bru class uses # private fields for the three VariableList instances, exposed only via getVarList(), getEnvVarList(), getGlobalEnvVarList() getter methods
  • Backward compatible — all existing bru.getVar(), bru.setEnvVar(), etc. methods remain unchanged and operate on the same underlying objects
  • QuickJS sandbox — bridge objects wired via createPropertyListBridge. Getter functions build a real array from _getEntries() with domain methods attached, so Array.isArray() and native array methods work in both sandboxes
  • filterKeys — internal keys like __name__ are excluded from the array but preserved in the backing object
  • Autocomplete — added bru.getVarList().*, bru.getEnvVarList().*, bru.getGlobalEnvVarList().* hints

Test coverage

  • Unit tests (packages/bruno-js/tests/variable-list.spec.js) — array behavior, CRUD, filterKeys, cross-path mutation visibility, custom validators
  • CLI test cases (packages/bruno-tests/collection/scripting/api/bru/getVarList/, getEnvVarList/, getGlobalEnvVarList/) — set/get, has, delete, clear, toObject, array-behavior
  • E2E Playwright tests (tests/scripting/bru-api/getVarList/, getEnvVarList/, getGlobalEnvVarList/) — dual-sandbox (developer + safe mode) verification
  • Postman → Bruno converter tests updated across 13 test files to match new translation targets
  • Bruno → Postman converter tests: new globals.test.js + additions to variables.test.js and environment.test.js

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have read the contribution guidelines.

@coderabbitai

coderabbitai Bot commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Replaces flat Postman variable helpers with namespaced Bruno APIs (bru.environment.*, bru.variables.*, bru.globals.*), adds VariableList, exposes VM property-list bridges, updates translator mappings and many translator tests, and removes bespoke AST expansions for has() checks.

Changes

Postman translation + runtime rename

Layer / File(s) Summary
VariableList implementation & tests
packages/bruno-js/src/variable-list.js, packages/bruno-js/tests/variable-list.spec.js
Adds VariableList class (get/has/toObject/set/unset/clear, filterKeys, key validation, interpolation) and comprehensive Jest tests validating behavior.
Bru runtime wiring & collection metadata
packages/bruno-js/src/bru.js, packages/bruno-app/src/utils/collections/index.js
Instantiates this.variables, this.environment, this.globals as VariableList wrappers, adds getGlobalEnvName(), exposes enumerable name getters, and includes __name__ on global env payload.
VM shim & bridge
packages/bruno-js/src/sandbox/quickjs/shims/bru.js, packages/bruno-js/src/sandbox/quickjs/utils/property-list-bridge.js
Exposes bridged bru.variables, bru.environment, bru.globals with synchronous read/write methods; adds syncWriteMethods support; wires VM name getters to runtime getters.
Translator mappings
packages/bruno-converters/src/postman/postman-translations.js, packages/bruno-converters/src/utils/postman-to-bruno-translator.js
Rewrites pm.environment/pm.variables/pm.globals translations to bru.environment.*, bru.variables.*, bru.globals.*; remaps deprecated Postman env helpers; removes bespoke AST has() expansions.
Translator tests
packages/bruno-converters/tests/postman/postman-translations/*, packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/*
Update expected translation outputs across many test suites to reference the new namespaced Bruno APIs.
Editor hints
packages/bruno-app/src/utils/codemirror/autocomplete.js
Adds CodeMirror autocomplete entries for bru.environment, bru.variables, and bru.globals (including name).

Sequence Diagram(s)

sequenceDiagram
  participant PM as Postman Script
  participant Translator as Postman→Bruno Translator
  participant VM as QuickJS VM (bru shim)
  participant Runtime as Bru Runtime (VariableList)
  PM->>Translator: Parse pm.* calls
  Translator->>VM: Emit namespaced calls (bru.environment.get/set/has, bru.variables.*, bru.globals.*)
  VM->>Runtime: Bridge call (sync read/write via property-list bridge)
  Runtime->>Runtime: VariableList.get/set/unset/clear (interpolate/validate/persist)
  Runtime-->>VM: Return values (or undefined for sync writes)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

size/XXL

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno
  • sid-bruno

Poem

🌱 Namespaced variables step into view,
bru.environment, bru.variables, bru.globals too.
Bridges hum, VariableList keeps order tight,
Translators updated, tests match the light,
A tidier runtime — devs sleep well tonight ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title mentions 'bru.getVarList, bru.getEnvVarList, bru.getGlobalEnvVarList' but the actual implementation introduces 'bru.variables, bru.environment, bru.globals' as the primary APIs. Update the title to reflect the actual API names: 'feat: add namespaced variable APIs (bru.variables, bru.environment, bru.globals)' or similar.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sanish-bruno sanish-bruno changed the title Feat/variables scripting apis feat: add PropertyList-based variable scoping APIs (bru.variables, bru.environment, bru.globals) Apr 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/bruno-js/tests/variable-list.spec.js (1)

53-60: Add regression coverage for reserved keys (__proto__, etc.).

Given VariableList#set now centralizes writes, this suite should include a blocking-case test for dangerous prototype keys to prevent future regressions.

Suggested test addition
     test('set() allows valid key characters', () => {
       list.set('my-var_name.v2', 'ok');
       expect(vars['my-var_name.v2']).toBe('ok');
     });
+
+    test('set() rejects reserved prototype keys', () => {
+      expect(() => list.set('__proto__', 'x')).toThrow('not allowed');
+      expect(() => list.set('prototype', 'x')).toThrow('not allowed');
+      expect(() => list.set('constructor', 'x')).toThrow('not allowed');
+    });
As per coding guidelines: `Add tests for any new functionality or meaningful changes. If code is added, removed, or significantly modified, corresponding tests should be updated or created.` and `Cover both the "happy path" and the realistically problematic paths.`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-js/tests/variable-list.spec.js` around lines 53 - 60, The test
suite is missing regression coverage for dangerous reserved prototype keys; add
tests in packages/bruno-js/tests/variable-list.spec.js that exercise
VariableList#set to ensure it rejects reserved keys such as "__proto__",
"constructor" (and similar prototype-polluting names) by throwing the same
validation error used for invalid characters; follow the existing test style
(see tests 'set() validates key format' and 'set() allows valid key characters')
and assert that calling list.set('__proto__', 'x') and list.set('constructor',
'x') throws the expected error to prevent prototype pollution regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bruno-js/src/variable-list.js`:
- Line 3: The variableNameRegex and the set() logic currently allow
meta-reserved keys (e.g., "__proto__", "prototype", "constructor") which enables
prototype-pollution; update validation so the regex or the set() validator
explicitly rejects those reserved property names before assigning into the
internal object. Concretely, add a guard in the set method(s) referenced (around
the blocks at the locations matching variableNameRegex and the set
implementations) that returns or throws when key matches
/^__proto__$|^prototype$|^constructor$/ or when key is not matched by the
tightened variableNameRegex, and apply the same guard to the other
set/assignment sites noted (the blocks corresponding to lines 71-76 and 103-113)
to ensure all writes block prototype-related keys.

In `@packages/bruno-js/tests/variable-list.spec.js`:
- Around line 127-130: Rename the test titled 'has() still checks filtered keys
via dataSource' to reflect that filtered keys are not visible to has(); update
the test title string (the argument to the test() call) for the test that calls
list.has('__name__') and list.has('host') to something like "has() respects
filtered keys and returns false for filtered entries" so the description matches
the assertions in the test.

---

Nitpick comments:
In `@packages/bruno-js/tests/variable-list.spec.js`:
- Around line 53-60: The test suite is missing regression coverage for dangerous
reserved prototype keys; add tests in
packages/bruno-js/tests/variable-list.spec.js that exercise VariableList#set to
ensure it rejects reserved keys such as "__proto__", "constructor" (and similar
prototype-polluting names) by throwing the same validation error used for
invalid characters; follow the existing test style (see tests 'set() validates
key format' and 'set() allows valid key characters') and assert that calling
list.set('__proto__', 'x') and list.set('constructor', 'x') throws the expected
error to prevent prototype pollution regressions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f2e37527-b140-46e2-a75e-82235836b8ae

📥 Commits

Reviewing files that changed from the base of the PR and between 13a9f9b and 4622ad1.

📒 Files selected for processing (20)
  • packages/bruno-converters/src/postman/postman-translations.js
  • packages/bruno-converters/src/utils/postman-to-bruno-translator.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-comments.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-edge-cases.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-variables.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/combined.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/environment.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/legacy-tests-syntax.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/multiline-syntax.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/postman-references.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/response.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/testing-framework.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/variable-chaining.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/variables.test.js
  • packages/bruno-js/src/bru.js
  • packages/bruno-js/src/sandbox/quickjs/shims/bru.js
  • packages/bruno-js/src/sandbox/quickjs/utils/property-list-bridge.js
  • packages/bruno-js/src/variable-list.js
  • packages/bruno-js/tests/variable-list.spec.js

@@ -0,0 +1,117 @@
const PropertyList = require('./property-list');

const variableNameRegex = /^[\w-.]*$/;

@coderabbitai coderabbitai Bot Apr 29, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Block reserved keys to prevent prototype-pollution behavior.

set() currently permits keys like __proto__ (and related meta-keys), which can mutate object prototype behavior when writing into plain objects. This is a security/correctness risk in scripting inputs.

Proposed fix
 const PropertyList = require('./property-list');
 
 const variableNameRegex = /^[\w-.]*$/;
+const reservedVariableKeys = new Set(['__proto__', 'prototype', 'constructor']);
@@
   set(key, value, options) {
-    if (!key) {
+    if (typeof key !== 'string' || key.length === 0) {
       throw new Error('Creating a variable without specifying a name is not allowed.');
     }
     this.#validateKey(key);
     this._variablesObj[key] = value;
@@
   `#validateKey`(key) {
+    if (reservedVariableKeys.has(key)) {
+      throw new Error(`Variable name: "${key}" is not allowed.`);
+    }
     if (this._validateKeyFn) {
       this._validateKeyFn(key);
       return;
     }

Also applies to: 71-76, 103-113

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-js/src/variable-list.js` at line 3, The variableNameRegex and
the set() logic currently allow meta-reserved keys (e.g., "__proto__",
"prototype", "constructor") which enables prototype-pollution; update validation
so the regex or the set() validator explicitly rejects those reserved property
names before assigning into the internal object. Concretely, add a guard in the
set method(s) referenced (around the blocks at the locations matching
variableNameRegex and the set implementations) that returns or throws when key
matches /^__proto__$|^prototype$|^constructor$/ or when key is not matched by
the tightened variableNameRegex, and apply the same guard to the other
set/assignment sites noted (the blocks corresponding to lines 71-76 and 103-113)
to ensure all writes block prototype-related keys.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it feels like over-engineering, it is less likely to happen in a real world, scenario, it is more like a foot shot

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sanish-bruno Fair point — prototype pollution is a meaningful concern primarily when processing untrusted external input (e.g., a server parsing user-submitted JSON). In Bruno's desktop scripting context, the user writing bru.variables.set('__proto__', ...) is only shooting their own foot, not anyone else's. Happy to drop this suggestion.

( ˘︹˘ )
( づ🐇づ


🧠 Learnings used
Learnt from: naman-bruno
Repo: usebruno/bruno PR: 6407
File: packages/bruno-app/src/components/Environments/ConfirmCloseEnvironment/index.js:5-41
Timestamp: 2025-12-17T21:41:24.730Z
Learning: Do not suggest PropTypes validation for React components in the Bruno codebase. The project does not use PropTypes, so reviews should avoid proposing PropTypes and rely on the existing typing/validation approach (e.g., TypeScript or alternative runtime checks) if applicable. This guideline applies broadly to all JavaScript/JSX components in the repo.

Comment thread packages/bruno-js/tests/variable-list.spec.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/bruno-js/src/variable-list.js`:
- Around line 80-82: The unset method in VariableList unconditionally deletes
keys and should respect the same filter used by clear; update unset(key) so it
first checks the filterKeys set (the same logic used by clear) and return
without deleting if key is one of the filtered entries (e.g., "__name__");
reference the unset method and the existing filterKeys/clear logic in
variable-list.js and mirror that guard so protected keys are not removed from
this._variablesObj.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 274ff697-697b-4970-80ae-9e9d30256594

📥 Commits

Reviewing files that changed from the base of the PR and between 0e4080f and 191bb55.

📒 Files selected for processing (3)
  • packages/bruno-js/src/bru.js
  • packages/bruno-js/src/variable-list.js
  • packages/bruno-js/tests/variable-list.spec.js
✅ Files skipped from review due to trivial changes (1)
  • packages/bruno-js/tests/variable-list.spec.js

Comment thread packages/bruno-js/src/variable-list.js Outdated
@sanish-bruno
sanish-bruno force-pushed the feat/variables-scripting-apis branch from 191bb55 to ec21268 Compare May 12, 2026 10:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/bruno-converters/src/postman/postman-translations.js (1)

52-59: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Remove legacy duplicate mappings that overwrite new PropertyList APIs.

Lines 52-59 define legacy mappings for pm.globals.* and pm.environment.* / pm.variables.* that duplicate and overwrite the new PropertyList-based mappings at lines 27-28, 32, 13-14, 23. JavaScript objects keep only the last value for duplicate keys, so the new bru.globals.get/set/toObject, bru.environment.toObject/clear, and bru.variables.toObject mappings are silently discarded. The translator will emit legacy helpers instead of the new namespaced APIs.

🐛 Proposed fix

Remove the duplicate legacy mappings:

   'pm\\.response\\.responseTime': 'res.getResponseTime()',
-  'pm\\.globals\\.set\\(': 'bru.setGlobalEnvVar(',
-  'pm\\.globals\\.get\\(': 'bru.getGlobalEnvVar(',
   // 'pm\\.globals\\.unset\\(': 'bru.deleteGlobalEnvVar(',
-  'pm\\.globals\\.toObject\\(': 'bru.getAllGlobalEnvVars(',
   // 'pm\\.globals\\.clear\\(': 'bru.deleteAllGlobalEnvVars(',
-  'pm\\.environment\\.toObject\\(': 'bru.getAllEnvVars(',
-  'pm\\.environment\\.clear\\(': 'bru.deleteAllEnvVars(',
-  'pm\\.variables\\.toObject\\(': 'bru.getAllVars(',
   // Request header PropertyList methods
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bruno-converters/src/postman/postman-translations.js` around lines
52 - 59, The object contains legacy duplicate keys (e.g.,
'pm\\.globals\\.set\\(', 'pm\\.globals\\.get\\(', 'pm\\.globals\\.toObject\\(',
'pm\\.environment\\.toObject\\(', 'pm\\.environment\\.clear\\(',
'pm\\.variables\\.toObject\\(') that overwrite the intended PropertyList-based
mappings (such as bru.globals.get/set/toObject, bru.environment.toObject/clear,
bru.variables.toObject) causing the translator to emit legacy helpers; remove
these legacy duplicate mappings from the mapping object so the new namespaced
APIs (bru.globals.*, bru.environment.*, bru.variables.*) defined earlier remain
effective and are not overwritten.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/bruno-js/src/sandbox/quickjs/utils/property-list-bridge.js`:
- Line 108: Remove the extraneous blank line in
packages/bruno-js/src/sandbox/quickjs/utils/property-list-bridge.js that
violates the "no multiple blank lines" ESLint rule—locate the extra empty line
around line 108 in the property-list-bridge module and delete it so there is at
most one consecutive blank line, then run lint to confirm the rule is satisfied.

---

Outside diff comments:
In `@packages/bruno-converters/src/postman/postman-translations.js`:
- Around line 52-59: The object contains legacy duplicate keys (e.g.,
'pm\\.globals\\.set\\(', 'pm\\.globals\\.get\\(', 'pm\\.globals\\.toObject\\(',
'pm\\.environment\\.toObject\\(', 'pm\\.environment\\.clear\\(',
'pm\\.variables\\.toObject\\(') that overwrite the intended PropertyList-based
mappings (such as bru.globals.get/set/toObject, bru.environment.toObject/clear,
bru.variables.toObject) causing the translator to emit legacy helpers; remove
these legacy duplicate mappings from the mapping object so the new namespaced
APIs (bru.globals.*, bru.environment.*, bru.variables.*) defined earlier remain
effective and are not overwritten.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e1bf7429-23c5-4063-a6aa-9ef3cfb921b0

📥 Commits

Reviewing files that changed from the base of the PR and between 191bb55 and ec21268.

📒 Files selected for processing (21)
  • packages/bruno-app/src/utils/collections/index.js
  • packages/bruno-converters/src/postman/postman-translations.js
  • packages/bruno-converters/src/utils/postman-to-bruno-translator.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-comments.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-edge-cases.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-variables.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/combined.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/environment.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/legacy-tests-syntax.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/multiline-syntax.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/postman-references.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/response.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/testing-framework.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/variable-chaining.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/variables.test.js
  • packages/bruno-js/src/bru.js
  • packages/bruno-js/src/sandbox/quickjs/shims/bru.js
  • packages/bruno-js/src/sandbox/quickjs/utils/property-list-bridge.js
  • packages/bruno-js/src/variable-list.js
  • packages/bruno-js/tests/variable-list.spec.js
✅ Files skipped from review due to trivial changes (5)
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/request.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/multiline-syntax.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/variable-chaining.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/testing-framework.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/variables.test.js
🚧 Files skipped from review as they are similar to previous changes (12)
  • packages/bruno-app/src/utils/collections/index.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-variables.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-edge-cases.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/postman-comments.spec.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/legacy-tests-syntax.test.js
  • packages/bruno-js/src/bru.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/postman-references.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/response.test.js
  • packages/bruno-converters/src/utils/postman-to-bruno-translator.js
  • packages/bruno-js/src/sandbox/quickjs/shims/bru.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/combined.test.js
  • packages/bruno-converters/tests/postman/postman-translations/transpiler-tests/environment.test.js

Comment thread packages/bruno-js/src/sandbox/quickjs/utils/property-list-bridge.js Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
packages/bruno-js/src/variable-list.js (2)

94-96: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

unset bypasses filterKeys, unlike clear.

clear() correctly preserves filterKeys entries (e.g., __name__), but unset deletes unconditionally. Calling bru.environment.unset('__name__') would silently remove the environment name from the backing object, breaking environment.name and getEnvName() for the rest of the request lifecycle.

🛡️ Proposed fix
 unset(key) {
+  if (this._filterKeys.includes(key)) return;
   delete this._variablesObj[key];
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bruno-js/src/variable-list.js` around lines 94 - 96, The unset
method deletes keys unconditionally causing protected keys in filterKeys (e.g.,
"__name__") to be removed; change unset in the VariableList class (method unset)
to mirror clear's behavior by skipping deletion for any key present in
this.filterKeys (or the same internal mechanism clear uses) so protected entries
in this._variablesObj are preserved and environment.name/getEnvName remain
stable for the request lifecycle.

1-1: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Block reserved keys to prevent prototype-pollution behavior.

The validation logic still permits keys like __proto__, prototype, and constructor, which can mutate object prototype behavior when writing into this._variablesObj. This is a security and correctness risk when user scripts supply variable names.

🛡️ Proposed fix
 const variableNameRegex = /^[\w-.]*$/;
+const reservedVariableKeys = new Set(['__proto__', 'prototype', 'constructor']);

 /**
@@
   `#validateKey`(key) {
+    if (reservedVariableKeys.has(key)) {
+      throw new Error(`Variable name: "${key}" is not allowed.`);
+    }
     if (this._validateKeyFn) {
       this._validateKeyFn(key);
       return;

Also applies to: 82-88, 111-122

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bruno-js/src/variable-list.js` at line 1, The current
variableNameRegex allows dangerous keys (e.g. "__proto__", "prototype",
"constructor") that can cause prototype pollution when written into
this._variablesObj; update the validation used around variableNameRegex and any
functions that write into this._variablesObj to explicitly reject a blacklist of
reserved property names (at minimum "__proto__", "prototype", "constructor")
rather than relying solely on the regex, return/throw a validation error for
those names, and ensure every code path that sets variables (the places
currently using variableNameRegex and the assignment sites to
this._variablesObj) performs this blacklist check before assignment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/bruno-app/src/utils/codemirror/autocomplete.js`:
- Around line 149-169: The autocomplete list for the new scoped namespaces
('bru.variables', 'bru.environment', 'bru.globals') is missing the full set of
PropertyList methods; update the entries for these symbols in
packages/bruno-app/src/utils/codemirror/autocomplete.js to include the broader
PropertyList API (e.g., one, all, idx, count, indexOf, each, map, filter, find,
reduce, toJSON, toString) so the hint surface matches the runtime API for each
of 'bru.variables', 'bru.environment', and 'bru.globals'.

---

Duplicate comments:
In `@packages/bruno-js/src/variable-list.js`:
- Around line 94-96: The unset method deletes keys unconditionally causing
protected keys in filterKeys (e.g., "__name__") to be removed; change unset in
the VariableList class (method unset) to mirror clear's behavior by skipping
deletion for any key present in this.filterKeys (or the same internal mechanism
clear uses) so protected entries in this._variablesObj are preserved and
environment.name/getEnvName remain stable for the request lifecycle.
- Line 1: The current variableNameRegex allows dangerous keys (e.g. "__proto__",
"prototype", "constructor") that can cause prototype pollution when written into
this._variablesObj; update the validation used around variableNameRegex and any
functions that write into this._variablesObj to explicitly reject a blacklist of
reserved property names (at minimum "__proto__", "prototype", "constructor")
rather than relying solely on the regex, return/throw a validation error for
those names, and ensure every code path that sets variables (the places
currently using variableNameRegex and the assignment sites to
this._variablesObj) performs this blacklist check before assignment.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 497b8a92-b524-4a88-a0c9-9e1be4fc4fea

📥 Commits

Reviewing files that changed from the base of the PR and between ec21268 and 19967e6.

📒 Files selected for processing (4)
  • packages/bruno-app/src/utils/codemirror/autocomplete.js
  • packages/bruno-js/src/sandbox/quickjs/shims/bru.js
  • packages/bruno-js/src/variable-list.js
  • packages/bruno-js/tests/variable-list.spec.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-js/src/sandbox/quickjs/shims/bru.js

Comment thread packages/bruno-app/src/utils/codemirror/autocomplete.js Outdated
@sanish-bruno sanish-bruno changed the title feat: add PropertyList-based variable scoping APIs (bru.variables, bru.environment, bru.globals) feat: add variable scoping APIs (bru.variables, bru.environment, bru.globals) May 12, 2026
@sanish-bruno sanish-bruno changed the title feat: add variable scoping APIs (bru.variables, bru.environment, bru.globals) feat: add variable list APIs (bru.getVarList, bru.getEnvVarList, bru.getGlobalEnvVarList) May 19, 2026
…and bru.variables methods

This commit modifies the translation logic to replace deprecated Postman API calls with updated bru methods for environment and variable management. The changes include updating method names in both the translation files and the corresponding test cases to ensure consistency and correctness in the translation process.
…slations and implementation

This commit comments out the globals.unset and globals.clear methods in the Postman translations and the Bru class implementation, marking them as TODOs to be re-enabled once the UI sync issue is resolved. This change ensures that the code remains functional while addressing the current limitations in the UI.
This commit updates the order of sync read methods in the bru.js shims for variables, environment, and globals to ensure a consistent structure across the code. The changes enhance readability and maintainability without altering functionality.
This commit introduces a new method `getGlobalEnvName` in the Bru class to retrieve the global environment name. Additionally, it updates the Bru shims to expose this method and define a property for the global environment name, enhancing the accessibility of environment information within the application.
…nment variable handling

This commit removes the onSet callback from the VariableList class, streamlining the variable setting process. Additionally, it simplifies the environment variable management in the Bru class by eliminating unnecessary logic related to persistent variables, enhancing code clarity and maintainability.
This commit adds new autocomplete suggestions for `bru.variables`, `bru.environment`, and `bru.globals` methods, enriching the developer experience. Additionally, it refactors the VariableList class to remove inheritance from PropertyList, simplifying its structure and enhancing the API with methods like `has` and `toObject`, which now exclude filtered keys. Tests are updated to reflect these changes and ensure functionality.
…List

This commit introduces checks in the `set` and `unset` methods of the VariableList class to prevent modification of reserved internal variable names. If a user attempts to set or unset a filtered key, an error is thrown, enhancing the integrity of the variable management system. Corresponding tests are added to ensure the new behavior is correctly implemented.
This commit removes outdated legacy translations from the Postman translations file, which were duplicate keys that conflicted with the namespaced bru.globals, bru.environment, and bru.variables mappings. This change enhances clarity and prevents potential overwrites in the translation logic.
This commit updates the `has` method in the VariableList class to optionally check for a matching value in addition to the key. Corresponding tests are added to verify the new functionality, ensuring accurate behavior when checking for both key existence and value equality.
…tionality

This commit updates the syncWriteMethods in the bru.globals implementation to include 'unset' and 'clear', allowing for more comprehensive manipulation of global variables. This change enhances the flexibility of the global environment management within the application.
…rage

This commit updates the VariableList class to internally manage variables as an array of { key, value } entries, allowing for more flexible input handling. It modifies the constructor to accept either a plain object or an array, and introduces synchronization methods to maintain compatibility with legacy object structures. The `get`, `has`, `set`, `unset`, and `clear` methods are updated to work with the new internal structure, enhancing the overall functionality and maintainability of the variable management system.
…ement

This commit introduces significant changes to the Bru class and VariableList, including the encapsulation of variable lists as private properties. The methods for managing variables have been updated to use `delete` instead of `unset`, aligning with modern JavaScript practices. New methods `getVarList`, `getEnvVarList`, and `getGlobalEnvVarList` are added to provide access to these private lists. Additionally, the autocomplete suggestions have been updated to reflect these changes, improving the developer experience. Corresponding tests are added to ensure the new functionality works as expected.
…ru.getVarList APIs

This commit introduces new test specifications for the bru.getEnvVarList, bru.getGlobalEnvVarList, and bru.getVarList APIs, ensuring that all tests pass in both developer and safe modes. Additionally, it includes initial user data configurations in JSON format for collection security and user preferences, enhancing the testing framework's robustness.
…Prod' instead of 'Local'

This commit modifies the test specifications for the bru.getEnvVarList, bru.getGlobalEnvVarList, and bru.getVarList APIs to select the 'Prod' environment instead of 'Local' in both developer and safe modes. This change ensures that the tests are aligned with production settings, enhancing the accuracy of the testing framework.
…ement

This commit refactors the VariableList class to extend Array, allowing it to leverage standard array methods directly. It updates the constructor to handle input more flexibly, including filtering out specified keys. The internal methods for managing entries are modified to utilize array methods, improving performance and maintainability. Additionally, new tests are added to verify the array behavior and ensure that the class functions correctly with the updated structure.
…vVarList, and bru.getVarList APIs

This commit introduces new test files for the bru.getEnvVarList, bru.getGlobalEnvVarList, and bru.getVarList APIs, focusing on validating array behavior. The tests ensure that the returned variable lists are arrays, have the correct length, and contain expected key-value object structures. Additionally, it verifies filtering and mapping functionalities, enhancing the robustness of the testing framework.
… integration

This commit introduces the _getEntries method in the VariableList class, which returns a plain array copy of its entries for compatibility with the QuickJS bridge. Additionally, the bru shims are updated to include _getEntries in the syncReadObjectMethods, ensuring that the new method is accessible in the global context. This enhancement improves the interoperability of the VariableList with the QuickJS environment.
…methods

This commit refactors the Postman translation logic to replace direct calls to bru.environment, bru.variables, and bru.globals with the new bru.getEnvVarList(), bru.getVarList(), and bru.getGlobalEnvVarList() methods. This change enhances consistency and aligns with the updated variable management structure, ensuring that all references to environment and variable access are correctly routed through the new API methods. Additionally, corresponding tests are updated to reflect these changes, improving the overall robustness of the translation framework.
…EnvVarList methods

This commit enhances the Postman translation framework by implementing additional translations for the bru.getVarList() and bru.getEnvVarList() methods, allowing for comprehensive handling of variable access patterns. New tests are added to validate the translations for get, set, has, delete, toObject, and clear methods, ensuring robust functionality and consistency across the variable management system.
@sanish-bruno
sanish-bruno force-pushed the feat/variables-scripting-apis branch from 165d040 to 5a7d4fc Compare May 19, 2026 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant