Skip to content

fix: Replace instanceof Array with Array.isArray()#10222

Closed
Moumouls wants to merge 3 commits intoparse-community:alphafrom
Moumouls:moumouls/fix-instance-of-array
Closed

fix: Replace instanceof Array with Array.isArray()#10222
Moumouls wants to merge 3 commits intoparse-community:alphafrom
Moumouls:moumouls/fix-instance-of-array

Conversation

@Moumouls
Copy link
Member

@Moumouls Moumouls commented Mar 16, 2026

Pull Request

Issue

instanceof Array is not realm safe, so in test frameworks like Jest or in advanced parse-server setup, many queries and parse-server features can break.

Approach

Replacing instanceof Array with Array.isArray() which is realm safe, and official MDN recommendation

Added an eslint rule to prevent futur problem related to this kind of issue

Tasks

  • Add tests
  • Add changes to documentation (guides, repository pages, code comments)
  • Add security check
  • Add new Parse Error codes to Parse JS SDK

Summary by CodeRabbit

  • Bug Fixes

    • Improved array type detection across the codebase for better cross-realm compatibility
  • Tests

    • Added tests for cross-realm array handling in query validation and storage operations
  • Chores

    • Updated ESLint configuration to enforce consistent array detection methods

@parse-github-assistant
Copy link

I will reformat the title to use the proper commit message syntax.

@parse-github-assistant parse-github-assistant bot changed the title fix: instance of array is too brittle, replacing in favor of Array.is… fix: Instance of array is too brittle, replacing in favor of Array.is… Mar 16, 2026
@parse-github-assistant
Copy link

parse-github-assistant bot commented Mar 16, 2026

🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review.

Tip

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

Note

Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect.

Caution

Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement.

@Moumouls Moumouls changed the title fix: Instance of array is too brittle, replacing in favor of Array.is… fix: replace instanceof Array with Array.isArray() Mar 16, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

This PR replaces uses of instanceof Array with Array.isArray() across the codebase and tests for cross-realm safety, and adds an ESLint rule to forbid instanceof Array with a message recommending Array.isArray().

Changes

Cohort / File(s) Summary
ESLint config files
eslint.config.js, spec/eslint.config.js, types/eslint.config.mjs
Added no-restricted-syntax rule to forbid instanceof Array and recommend Array.isArray() (selector: BinaryExpression[operator='instanceof'][right.name='Array']).
Tests — Database & Query
spec/DatabaseController.spec.js, spec/ParseAPI.spec.js, spec/rest.spec.js
Replaced instanceof Array checks with Array.isArray(); added three DatabaseController tests using vm.runInNewContext to verify cross-realm arrays for $or, $and, and $nor.
Tests & helpers
spec/MongoStorageAdapter.spec.js, spec/helper.js
Updated assertions and helper normalization to use Array.isArray() instead of instanceof Array.
Controllers
src/Controllers/DatabaseController.js, src/Controllers/FilesController.js, src/Controllers/LiveQueryController.js, src/Controllers/SchemaController.js
Replaced array type checks with Array.isArray() in validation, update handling, constructor/config parsing, and object-type detection.
Storage adapters
src/Adapters/Storage/Mongo/MongoTransform.js, src/Adapters/Storage/Postgres/PostgresStorageAdapter.js
Replaced instanceof Array checks with Array.isArray() in transformation, constraint handling, geo-query, and update logic.
Config & query utilities
src/Config.js, src/RestQuery.js, src/GraphQL/transformers/query.js
Switched to Array.isArray() for configuration validation and query/constraint array checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title accurately summarizes the main change: replacing instanceof Array with Array.isArray() across the codebase for realm-safety.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@parseplatformorg
Copy link
Contributor

parseplatformorg commented Mar 16, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@parse-github-assistant
Copy link

I will reformat the title to use the proper commit message syntax.

@parse-github-assistant parse-github-assistant bot changed the title fix: replace instanceof Array with Array.isArray() fix: Replace instanceof Array with Array.isArray() Mar 16, 2026
@parse-github-assistant
Copy link

I will reformat the title to use the proper commit message syntax.

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

❌ Patch coverage is 92.30769% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.18%. Comparing base (e5e1f5b) to head (7364e2c).
⚠️ Report is 5 commits behind head on alpha.

Files with missing lines Patch % Lines
src/Adapters/Storage/Mongo/MongoTransform.js 94.44% 1 Missing ⚠️
src/Controllers/DatabaseController.js 83.33% 1 Missing ⚠️
src/GraphQL/transformers/query.js 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            alpha   #10222      +/-   ##
==========================================
- Coverage   92.18%   92.18%   -0.01%     
==========================================
  Files         192      192              
  Lines       16307    16307              
  Branches      199      199              
==========================================
- Hits        15033    15032       -1     
- Misses       1253     1254       +1     
  Partials       21       21              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
spec/DatabaseController.spec.js (1)

60-85: Refactor these new tests to use async/await instead of done callbacks.

The three cross-realm array tests (lines 60, 69, 78) are solid, but they use the done callback pattern. New tests in this suite should use async/await to align with the established promise-based pattern.

Refactoring pattern
-    it('should accept cross-realm arrays for $or', done => {
+    it('should accept cross-realm arrays for $or', async () => {
       const query = {
         $or: vm.runInNewContext('[{ a: 1 }, { b: 2 }]'),
       };
       expect(Array.isArray(query.$or)).toBe(true);
       expect(() => validateQuery(query)).not.toThrow();
-      done();
     });

-    it('should accept cross-realm arrays for $and', done => {
+    it('should accept cross-realm arrays for $and', async () => {
       const query = {
         $and: vm.runInNewContext('[{ a: 1 }, { b: 2 }]'),
       };
       expect(Array.isArray(query.$and)).toBe(true);
       expect(() => validateQuery(query)).not.toThrow();
-      done();
     });

-    it('should accept cross-realm arrays for $nor', done => {
+    it('should accept cross-realm arrays for $nor', async () => {
       const query = {
         $nor: vm.runInNewContext('[{ a: 1 }]'),
       };
       expect(Array.isArray(query.$nor)).toBe(true);
       expect(() => validateQuery(query)).not.toThrow();
-      done();
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@spec/DatabaseController.spec.js` around lines 60 - 85, Convert the three
tests that currently use the done callback into async functions: change each
it(..., done => { ... done(); }) to it(..., async () => { ... }) and remove the
done parameter and final done() call; keep the existing bodies
(vm.runInNewContext('[...]'), Array.isArray assertions, and the expect(() =>
validateQuery(...)).not.toThrow() checks) unchanged so they remain synchronous
but use the async/await test style; apply this to the tests referencing $or,
$and, and $nor and the usages of vm.runInNewContext and validateQuery.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Controllers/DatabaseController.js`:
- Around line 134-152: The three forEach callbacks iterating query.$or,
query.$and, and query.$nor currently use expression-bodied arrow functions that
implicitly return the result of validateQuery; change them to block-bodied
callbacks that call validateQuery without returning (e.g., replace value =>
validateQuery(...) with value => { validateQuery(...); }) for each occurrence so
the linter rule lint/suspicious/useIterableCallbackReturn is satisfied and
behavior is unchanged.

---

Nitpick comments:
In `@spec/DatabaseController.spec.js`:
- Around line 60-85: Convert the three tests that currently use the done
callback into async functions: change each it(..., done => { ... done(); }) to
it(..., async () => { ... }) and remove the done parameter and final done()
call; keep the existing bodies (vm.runInNewContext('[...]'), Array.isArray
assertions, and the expect(() => validateQuery(...)).not.toThrow() checks)
unchanged so they remain synchronous but use the async/await test style; apply
this to the tests referencing $or, $and, and $nor and the usages of
vm.runInNewContext and validateQuery.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f64eb102-16ef-4bf9-8802-25bbe234df7d

📥 Commits

Reviewing files that changed from the base of the PR and between 9667fd7 and f297dbd.

📒 Files selected for processing (17)
  • eslint.config.js
  • spec/DatabaseController.spec.js
  • spec/MongoStorageAdapter.spec.js
  • spec/ParseAPI.spec.js
  • spec/eslint.config.js
  • spec/helper.js
  • spec/rest.spec.js
  • src/Adapters/Storage/Mongo/MongoTransform.js
  • src/Adapters/Storage/Postgres/PostgresStorageAdapter.js
  • src/Config.js
  • src/Controllers/DatabaseController.js
  • src/Controllers/FilesController.js
  • src/Controllers/LiveQueryController.js
  • src/Controllers/SchemaController.js
  • src/GraphQL/transformers/query.js
  • src/RestQuery.js
  • types/eslint.config.mjs

@mtrezza mtrezza changed the title fix: Replace instanceof Array with Array.isArray() fix: Replace instanceof Array with Array.isArray() Mar 16, 2026
Copy link
Member

@mtrezza mtrezza left a comment

Choose a reason for hiding this comment

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

This PR fix is too narrow. The issue stems from the fact that instanceof is not realm-safe, regardless of which type it compares to. So we should remove all occurrences of instanceof throughout the codebase. I would prefer a more structured approach. Introducing helper functions would be a better approach, especially as some of the realm-safe alternatives are more complex. Use the existing Utils.js and add isDate(), isRegex(), etc. It seems that Node.js is moving towards providing safe alternatives, but for example Date.isDate() is still in proposal stage it seems.

@mtrezza
Copy link
Member

mtrezza commented Mar 16, 2026

Superseded by #10225, which covers all instanceof types.

@mtrezza mtrezza closed this Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants