feat(cookies): add direct cookie access methods and update translations#7073
feat(cookies): add direct cookie access methods and update translations#7073sanish-bruno wants to merge 4 commits intousebruno:mainfrom
Conversation
- Introduced new methods for direct cookie access: `bru.cookies.get`, `bru.cookies.has`, and `bru.cookies.toObject`. - Updated translation mappings in `bruno-to-postman-translator` and `postman-to-bruno-translator` to support these new methods. - Enhanced tests to verify correct translation between `bru` and `pm` cookie methods, including mixed usage scenarios. - Updated `Bru` class to handle cookie access based on the current request URL.
WalkthroughAdds first-class direct cookie APIs across translators, runtime, QuickJS shim, and Bru core by introducing CookieList/PropertyList/ReadOnlyPropertyList, passing request URL into Bru, and expanding pm↔bru cookie translation mappings with tests for both directions. Changes
Sequence Diagram(s)sequenceDiagram
participant Script as Script (user code)
participant Translator as Converter (pm↔bru)
participant Bru as Bru instance
participant CookieList as CookieList
participant Jar as CookieJar / requests.cookies
Script->>Translator: translate cookie call (pm.cookies.get / bru.cookies.get)
Translator->>Bru: produce translated code referencing bru.cookies.get(name)
Script->>Bru: invoke bru.cookies.get(name)
Bru->>CookieList: CookieList.get(name) with interpolated requestUrl
CookieList->>Jar: getCookiesForUrl(requestUrl) / jar.getCookie(...)
Jar-->>CookieList: cookie(s)
CookieList-->>Bru: cookie value
Bru-->>Script: return value
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
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: 1
🤖 Fix all issues with AI agents
In `@packages/bruno-js/src/bru.js`:
- Around line 48-70: The get() method currently uses cookies.find(...) which
returns the first matching cookie while toObject() ends up with "last wins"
semantics; update get() (in the object containing get, has, toObject) to return
the last matching cookie for the interpolated this.requestUrl — e.g. use
Array.prototype.findLast (or iterate the cookies array in reverse) when
selecting cookie by key so get(name) and toObject() are consistent; keep the
existing interpolate(this.requestUrl) and getCookiesForUrl(url) usage and
preserve returning undefined when no url or no match.
🧹 Nitpick comments (2)
packages/bruno-js/src/runtime/vars-runtime.js (1)
40-40: 14 positional args toBruis getting unwieldy.The change itself is correct — passing
request?.urlaligns with the other runtime call sites. However, this constructor now takes 14 positional arguments withundefinedplaceholders for unused params. Consider moving to an options object in a follow-up to prevent ordering mistakes.packages/bruno-js/src/bru.js (1)
31-31: 14 positional constructor parameters — existing debt, but worth noting.This constructor keeps growing. A single options/config object would make call sites far more readable and resilient to parameter ordering bugs. I see this is pre-existing debt (flagged in
script-runtime.js:15-16), so not blocking.
- Added new cookie methods: `toString`, `clear`, `delete`, `one`, `all`, `idx`, `count`, `indexOf`, `find`, `filter`, `each`, `map`, and `reduce` to `bru.cookies`. - Refactored `Bru` class to utilize a new `CookieList` for cookie management, improving structure and readability. - Updated translation mappings in `bruno-to-postman-translator` and `postman-to-bruno-translator` to include new cookie methods. - Introduced `PropertyList` and `ReadOnlyPropertyList` classes for better data structure management. - Enhanced tests for comprehensive coverage of new cookie functionalities and their interactions.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/bruno-js/src/sandbox/quickjs/shims/bru.js`:
- Line 579: The wrapper for globalThis.bru.cookies.reduce always forwards acc
(which may be undefined) and thus breaks the no-initial-value semantics; change
the reduce wrapper around _allNative() so it forwards the call conditionally: if
the caller provided an initial accumulator (check arguments.length or presence
of a second arg) call _allNative().reduce(fn, acc), otherwise call
_allNative().reduce(fn) so the native behavior (use first element as initial or
throw on empty array) is preserved; update the function bound to
globalThis.bru.cookies.reduce accordingly.
🧹 Nitpick comments (7)
packages/bruno-js/src/readonly-property-list.js (2)
157-159:reduce()behaves differently from nativeArray.reducewhen called without an accumulator.
list.reduce(fn)passesundefinedas the initial value toArray.prototype.reduce, which differs from callingitems.reduce(fn)directly (native reduce without a second arg uses the first element as the initial accumulator and throws on empty arrays). If this is intentional to mirror Postman's PropertyList, it's fine — just worth a note.Optional: match native semantics
- reduce(fn, acc) { - return this._getItems().reduce(fn, acc); + reduce(fn, ...args) { + return this._getItems().reduce(fn, ...args); }
36-38: Dynamic mode:_dataSource()errors will bubble up unhandled.If a
dataSourcefunction throws, every read method will propagate the exception. This is likely fine for the cookie use case (wheregetCookiesForUrlis trusted internal code), but worth noting if this base class will be used more broadly.packages/bruno-js/src/cookie-list.js (1)
39-75: Write methods are clean — consistent null-URL guard pattern.Each method properly short-circuits on falsy URL with callback/Promise fallback. The
delete→removealias is straightforward.One small note: these public methods lack individual JSDoc (only the class-level doc lists them). Consider adding brief JSDoc per method. As per coding guidelines: "Add JSDoc comments to abstractions for additional details."
packages/bruno-js/src/property-list.js (2)
124-136:populate()andrepopulate()are identical implementations.Both methods assign
this._items = Array.isArray(items) ? [...items] : []. Since JS assignment is atomic, the "clear then populate" semantics ofrepopulatecollapse to the same operation. If this mirrors Postman's SDK surface, keeping both is fine for API compatibility, but a deduplication would be cleaner.Optional: deduplicate
populate(items) { this._assertStatic('populate'); this._items = Array.isArray(items) ? [...items] : []; } repopulate(items) { this._assertStatic('repopulate'); - this._items = Array.isArray(items) ? [...items] : []; + this.populate(items); }
66-76:insertAfter()silently appends whenafterisundefined, unlikeinsert()which handles it explicitly.
insert(item, before)explicitly checksbefore === undefinedand appends.insertAfter(item, after)doesn't — it falls through toindexOf(undefined) === -1→ append. The behavior is the same, but the intent is implicit. Consider adding an explicit guard for consistency, or documenting the fallback.packages/bruno-js/src/bru.js (1)
32-32: 14 positional constructor parameters is getting unwieldy.This isn't new to this PR, but adding
requestUrlas the 14th positional arg increases the risk of callers passing arguments in the wrong order. Consider consolidating into an options object in a follow-up.packages/bruno-js/src/sandbox/quickjs/shims/bru.js (1)
550-580: DuplicatecallWithCallbackdefinition — consider extracting to a shared helper.
callWithCallbackis defined identically both inside the block scope (Line 553) and in thejar()function (Line 585). This isn't a bug due to block scoping, but it's copy-pasted logic.
| globalThis.bru.cookies.filter = (fn) => _allNative().filter(fn); | ||
| globalThis.bru.cookies.find = (fn) => _allNative().find(fn); | ||
| globalThis.bru.cookies.map = (fn) => _allNative().map(fn); | ||
| globalThis.bru.cookies.reduce = (fn, acc) => _allNative().reduce(fn, acc); |
There was a problem hiding this comment.
reduce wrapper always passes acc, breaking no-initial-value semantics.
When a user calls bru.cookies.reduce(fn) without an initial accumulator, acc is undefined and _allNative().reduce(fn, undefined) is invoked. This differs from Array.prototype.reduce(fn) which uses the first element as the initial value. Result: unexpected coercion (e.g., "undefined" + ...).
Proposed fix
- globalThis.bru.cookies.reduce = (fn, acc) => _allNative().reduce(fn, acc);
+ globalThis.bru.cookies.reduce = (fn, ...rest) => rest.length ? _allNative().reduce(fn, rest[0]) : _allNative().reduce(fn);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| globalThis.bru.cookies.reduce = (fn, acc) => _allNative().reduce(fn, acc); | |
| globalThis.bru.cookies.reduce = (fn, ...rest) => rest.length ? _allNative().reduce(fn, rest[0]) : _allNative().reduce(fn); |
🤖 Prompt for AI Agents
In `@packages/bruno-js/src/sandbox/quickjs/shims/bru.js` at line 579, The wrapper
for globalThis.bru.cookies.reduce always forwards acc (which may be undefined)
and thus breaks the no-initial-value semantics; change the reduce wrapper around
_allNative() so it forwards the call conditionally: if the caller provided an
initial accumulator (check arguments.length or presence of a second arg) call
_allNative().reduce(fn, acc), otherwise call _allNative().reduce(fn) so the
native behavior (use first element as initial or throw on empty array) is
preserved; update the function bound to globalThis.bru.cookies.reduce
accordingly.
|
Glad to see a new cookies handling method. Anyway, don't forget to fix this before 9d3341e |
sure @ahamayeah59 #6679 the changes seems to be straight forward, will do my best to get it tested/reviewed and merged as soon as possible. |
Jira
Summary
Adds direct
bru.cookies.*access methods that mirror Postman'spm.cookiesAPI, allowing users to read, iterate, and manipulate cookies without going throughbru.cookies.jar().Previously, all cookie operations required explicitly creating a jar and passing URLs:
Now, users can work with cookies scoped to the current request URL directly:
Changes
New classes (
packages/bruno-js/src/)ReadOnlyPropertyList- Base collection class with read/search/iteration/transform methods. Supports both static mode (in-memory array) and dynamic mode (data source function).PropertyList(extendsReadOnlyPropertyList) - Adds mutation methods for static mode (headers, query params, etc.).CookieList(extendsReadOnlyPropertyList) - Cookie-specific collection using dynamic mode. Read methods delegate to the cookie jar via URL; write methods (add,upsert,remove,delete,clear) delegate async operations to the jar.New
bru.cookiesmethodsget(name),has(name, [value]),one(name),all(),count(),idx(n),indexOf(item),toObject(),toString()each(fn),find(fn),filter(fn),map(fn),reduce(fn, acc)add(obj),upsert(obj),remove(name),delete(name),clear()Updated files
bru.js- Replaced inline cookies object withnew CookieList(...), acceptsrequestUrlparametersandbox/quickjs/shims/bru.js- Exposed all new cookie methods to the QuickJS sandboxruntime/*.js- PassrequestUrltoBruconstructorpostman-translations.js- Added regex translations forpm.cookies.*direct access methodspostman-to-bruno-translator.js- Added AST translations forpm.cookies.*bruno-to-postman-translator.js- Added reverse translations forbru.cookies.*E2E tests (
packages/bruno-tests/collection/scripting/api/bru/cookies/)directGet.bru- Testsget()andhas()directReadMethods.bru- Testsone(),all(),count(),idx(),toObject(),toString()directIteration.bru- Testseach(),find(),filter(),map(),reduce()directWrite.bru- Testsadd(),upsert(),remove(),delete(),clear()Unit tests (
packages/bruno-js/tests/)readonly-property-list.spec.js- 119 lines covering all read/search/iteration methodsproperty-list.spec.js- 409 lines covering static-mode mutation methodscookie-list.spec.js- 294 lines covering async write delegation and jar integrationTest plan
npm run test --workspace=packages/bruno-jsnpm run test --workspace=packages/bruno-convertersbru run scripting/api/bru/cookies --env=Prod(42/42 pass)bru.cookies.get()works in pre-request/test scriptspm.cookies.get()and verify it translates correctlyContribution 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