fix: preserve i18n and versions in filter method#900
fix: preserve i18n and versions in filter method#900mateo-leal wants to merge 3 commits intoWFCD:masterfrom
Conversation
📝 WalkthroughWalkthrough
Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 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.
Pull request overview
This PR fixes metadata loss when using Items.filter() and Items.map() by ensuring the returned arrays retain the i18n and versions data that the Items wrapper provides.
Changes:
- Preserve
versionson arrays returned fromfilter()andmap(). - Preserve
i18non arrays returned fromfilter()andmap(), and narrowi18nto only matched items forfilter(). - Add tests to validate
i18n/versionspreservation and i18n narrowing behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| test/index.spec.mjs | Adds regression tests for i18n/versions preservation across filter()/map() and correct i18n narrowing on filtered results. |
| index.mjs | Updates ESM Items.filter()/map() to carry i18n/versions onto returned arrays (and filter i18n entries). |
| index.js | Mirrors the same filter()/map() metadata preservation behavior for the CJS build. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
test/index.spec.mjs (1)
335-343: Avoid hard-codeduniqueNametest fixtures.Line 336 can become stale when data files update, causing flaky failures. Prefer selecting a target from loaded test data.
Suggested patch
- const targetUniqueName = '/Lotus/Types/Friendly/Pets/ZanukaPets/ZanukaPetParts/ZanukaPetPartHeadB'; const items = await wrapConstr({ category: ['Pets'], i18n: ['es'] }); + const targetUniqueName = items[0]?.uniqueName; + assert.ok(targetUniqueName, 'should have at least one pet item'); const filtered = items.filter((i) => i.uniqueName === targetUniqueName);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@test/index.spec.mjs` around lines 335 - 343, The test uses a hard-coded uniqueName (targetUniqueName) which can become stale; instead pick a target from the loaded items returned by wrapConstr so the fixture is stable—e.g., select a candidate from the items array (like items[0] or items.find(...) ensuring it has an i18n entry), then use that item's uniqueName as the target, and adjust the subsequent assertions to reference the dynamically selected uniqueName and filtered result (functions/locals to edit: wrapConstr, items, filtered, targetUniqueName).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@index.js`:
- Around line 183-184: The map metadata assignment always sets a.i18n even when
this.i18n is undefined; change it to match the filter behavior by only assigning
a.i18n when the source i18n is present (e.g., check this.i18n !== undefined or
truthiness before setting a.i18n = this.i18n) while leaving a.versions
assignment as-is; update the assignment in the block that references variable a
and this.i18n so the property is not added with an explicit undefined value.
In `@index.mjs`:
- Around line 182-183: The assignment a.i18n = this.i18n sets an explicit
undefined property when i18n is disabled; mirror the guard used in filter by
only assigning a.i18n when this.i18n is present (truthy/non-null), e.g. wrap the
assignment in the same conditional used for filter so that when i18n is off the
property is not created; update the code around the a.i18n assignment (where a
and this.i18n are referenced alongside a.versions) to use that guard.
---
Nitpick comments:
In `@test/index.spec.mjs`:
- Around line 335-343: The test uses a hard-coded uniqueName (targetUniqueName)
which can become stale; instead pick a target from the loaded items returned by
wrapConstr so the fixture is stable—e.g., select a candidate from the items
array (like items[0] or items.find(...) ensuring it has an i18n entry), then use
that item's uniqueName as the target, and adjust the subsequent assertions to
reference the dynamically selected uniqueName and filtered result
(functions/locals to edit: wrapConstr, items, filtered, targetUniqueName).
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: cf9eb6de-cc46-4367-bb0c-84168cb2390e
📒 Files selected for processing (3)
index.jsindex.mjstest/index.spec.mjs
There was a problem hiding this comment.
🧹 Nitpick comments (1)
index.js (1)
161-169: Align overriddenfilter/mapcallback behavior with native Array semantics.Both overrides currently call callbacks as
fn(el)only. Native Array methods pass(element, index, array)and supportthisArgfor consistency. While current usages in the codebase don't rely on these parameters, implementing full parity would prevent unexpected behavior if callbacks are written expecting standard Array semantics.Proposed parity refactor
- filter(fn) { + filter(fn, thisArg) { const A = []; const filteredNames = this.i18n ? new Set() : null; - for (const el of this) { - if (fn(el)) { + for (let i = 0; i < this.length; i++) { + const el = this[i]; + if (fn.call(thisArg, el, i, this)) { A.push(el); if (filteredNames) filteredNames.add(el.uniqueName); } } @@ - map(fn) { + map(fn, thisArg) { const a = []; - for (const el of this) a.push(fn(el)); + for (let i = 0; i < this.length; i++) { + a.push(fn.call(thisArg, this[i], i, this)); + } if (this.i18n) a.i18n = this.i18n; a.versions = this.versions; return a; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@index.js` around lines 161 - 169, The custom Collection.prototype.filter currently calls the callback as fn(el) which diverges from native Array semantics; update filter (and the similar map override) to accept an optional thisArg parameter and invoke the callback with fn.call(thisArg, el, i, this) (or equivalent) so the callback receives (element, index, array) and honors thisArg; keep the existing logic that updates filteredNames/adds to A but pass the current index variable (i) and the collection reference (this) into the callback invocation to maintain full parity with native Array.filter/Array.map.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@index.js`:
- Around line 161-169: The custom Collection.prototype.filter currently calls
the callback as fn(el) which diverges from native Array semantics; update filter
(and the similar map override) to accept an optional thisArg parameter and
invoke the callback with fn.call(thisArg, el, i, this) (or equivalent) so the
callback receives (element, index, array) and honors thisArg; keep the existing
logic that updates filteredNames/adds to A but pass the current index variable
(i) and the collection reference (this) into the callback invocation to maintain
full parity with native Array.filter/Array.map.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c7f3e5ca-49a3-4bd5-aa02-87b2ff026372
📒 Files selected for processing (3)
index.jsindex.mjstest/index.spec.mjs
✅ Files skipped from review due to trivial changes (1)
- test/index.spec.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
- index.mjs
What did you fix?
Using .filter function now keeps the i18n object
Reproduction steps
Evidence/screenshot/link to line
Considerations
Summary by CodeRabbit
Enhancements
Tests