Skip to content

Remove lodash #800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Remove lodash #800

wants to merge 5 commits into from

Conversation

ibroom
Copy link
Contributor

@ibroom ibroom commented Jul 2, 2025

Remove lodash from the form builder

Summary by CodeRabbit

  • Refactor

    • Replaced Lodash utility functions with native JavaScript methods and custom utilities across multiple components and libraries.
    • Added new native utility functions for deep cloning, debouncing, sorting, uniqueness, string formatting, and deep equality checks.
    • Updated internal array and object operations to use these native implementations, maintaining existing functionality.
  • Chores

    • Removed Lodash from dependencies.
    • Included the new utility library in the application’s assets for interface and build processes.

Remove lodash from the form builder
@ibroom ibroom requested a review from Arpanexe July 2, 2025 12:11
Copy link

coderabbitai bot commented Jul 2, 2025

Walkthrough

This update systematically removes all Lodash utility function dependencies across the codebase, replacing them with native JavaScript methods or custom helper functions. Several new utility methods are introduced within components or as a shared utility module. The widget configuration is updated to remove Lodash and include the new utility library. No changes are made to the core logic or exported entity signatures.

Changes

File(s) Change Summary
js/components/checkbox.js Replaces Lodash methods with native/custom implementations; adds sortBy, isEqual, and uniqueWith methods.
js/components/customButton.js Replaces Lodash's _.find and _.assign with native find and Object.assign.
js/components/file.js Replaces Lodash's _.map, _.some, _.sortBy with native methods; adds sortBy method.
js/components/image.js Replaces Lodash's _.map with native map in image click handler.
js/components/matrix.js Replaces Lodash methods with native/custom equivalents; adds toKebabCase and isEmpty methods.
js/components/number.js Replaces Lodash's _.isNaN with native isNaN.
js/components/password.js Replaces Lodash's _.forEach with native forEach in password generation logic.
js/components/radio.js Replaces Lodash's _.find and _.has with native find and property checks.
js/components/reorderList.js Replaces Lodash's _.cloneDeep with a new internal cloneDeep method.
js/components/wysiwyg.js Replaces Lodash methods with native/custom equivalents; adds toKebabCase, getNestedProperty, and setNestedProperty.
js/libs/builder.js Replaces all Lodash utility calls with native JavaScript equivalents.
js/libs/core.js Replaces Lodash utilities with native/custom methods; comments out emitEvent; custom debounce logic added.
js/libs/form.js Replaces all Lodash calls with native helper functions defined at the top of the file.
js/libs/templates.js Comments out compileTemplate and renderTemplate functions, disabling Handlebars template rendering.
js/libs/utils.js Adds new utility library with native implementations of common Lodash functions; exports globally and via CommonJS.
widget.json Removes Lodash from dependencies; adds js/libs/utils.js as an asset in interface and build sections.

Sequence Diagram(s)

sequenceDiagram
    participant Component
    participant Utils

    Note over Component,Utils: Example: Utility function usage after refactor

    Component->>Utils: call sortBy(array, iteratee)
    Utils-->>Component: returns sorted array

    Component->>Utils: call isEqual(a, b)
    Utils-->>Component: returns boolean

    Component->>Utils: call uniqWith(array, comparator)
    Utils-->>Component: returns unique array
Loading
sequenceDiagram
    participant App
    participant widget.json
    participant Lodash
    participant Utils

    App->>widget.json: Load dependencies
    widget.json--x Lodash: Lodash removed from assets
    widget.json-->>Utils: js/libs/utils.js added as asset
    App->>Utils: Use utility functions (e.g., sortBy, isEqual)
Loading

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-08T10_53_56_227Z-debug-0.log

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: `mapKeys` Utility Ignores Iteratee Return Value

The mapKeys utility function is incorrectly implemented. It calls the iteratee but ignores its return value, always returning an empty object instead of mapping object keys as intended by the original lodash method.

js/libs/form.js#L81-L89

function mapKeys(object, iteratee) {
const result = {};
for (const [key, value] of Object.entries(object)) {
iteratee(value, key);
}
return result;
}

Fix in Cursor


BugBot free trial expires on July 22, 2025
You have used $0.00 of your $1.00 spend limit so far. Manage your spend limit in the Cursor dashboard.

Was this report helpful? Give feedback by reacting with 👍 or 👎

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: 22

🔭 Outside diff range comments (3)
js/components/password.js (1)

126-130: Fix critical bug: Object.forEach() doesn't exist.

The change from _.forEach(this.rules, function(value)) to this.rules.forEach(function(value)) is incorrect. The rules property is an object, not an array, and objects don't have a forEach method. This will cause a runtime error.

-      this.rules.forEach(function(value) {
-        if (!value.test(password)) {
-          isValid = false;
-        }
-      });
+      Object.values(this.rules).forEach(function(value) {
+        if (!value.test(password)) {
+          isValid = false;
+        }
+      });

Alternatively, you could use Object.keys() and iterate over the keys:

-      this.rules.forEach(function(value) {
-        if (!value.test(password)) {
-          isValid = false;
-        }
-      });
+      Object.keys(this.rules).forEach(function(key) {
+        if (!this.rules[key].test(password)) {
+          isValid = false;
+        }
+      }.bind(this));
js/components/file.js (1)

107-135: Address var usage in multiple locations.

Multiple var declarations should be replaced with const to follow modern JavaScript practices and the Google JavaScript Style Guide.

     loadFileData: function() {
-      var $vm = this;
-      var isFileDataLoaded = false;
+      const $vm = this;
+      let isFileDataLoaded = false;
       // ... rest of method

       }).then(function(files) {
-        var newFiles = files.map(function(file) {
+        const newFiles = files.map(function(file) {
js/libs/core.js (1)

224-937: Comprehensive testing plan needed for core refactoring.

This extensive Lodash removal affects critical form builder functionality and requires thorough testing.

Essential test areas:

  1. Debounce functionality: Input handling, timing accuracy
  2. Object property merging: Component configuration inheritance
  3. Array operations: Option processing, deduplication, filtering
  4. Field matching: Name synchronisation, duplicate detection
  5. Deep cloning: Form data preservation, nested object handling

Suggested test approach:

  • Unit tests for each utility replacement
  • Integration tests for form field creation and configuration
  • End-to-end tests for multi-step form scenarios

The scope of changes warrants extensive regression testing to ensure no functionality is broken.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8be60cc and 91ce56b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (16)
  • js/components/checkbox.js (4 hunks)
  • js/components/customButton.js (1 hunks)
  • js/components/file.js (3 hunks)
  • js/components/image.js (1 hunks)
  • js/components/matrix.js (8 hunks)
  • js/components/number.js (1 hunks)
  • js/components/password.js (1 hunks)
  • js/components/radio.js (1 hunks)
  • js/components/reorderList.js (3 hunks)
  • js/components/wysiwyg.js (4 hunks)
  • js/libs/builder.js (18 hunks)
  • js/libs/core.js (22 hunks)
  • js/libs/form.js (27 hunks)
  • js/libs/templates.js (1 hunks)
  • js/libs/utils.js (1 hunks)
  • widget.json (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.js`: Review the JavaScript code against the Google JavaScript style guide ...

**/*.js: Review the JavaScript code against the Google JavaScript style guide and point out any mismatches. Ensure all code is fully documented. Suggest a testing plan to ensure code is adequately tested. Suggest unit tests. Avoid integration tests.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • js/libs/templates.js
  • js/components/number.js
  • js/components/customButton.js
  • js/components/password.js
  • js/components/image.js
  • js/components/radio.js
  • js/components/reorderList.js
  • js/components/checkbox.js
  • js/components/matrix.js
  • js/components/wysiwyg.js
  • js/components/file.js
  • js/libs/core.js
  • js/libs/utils.js
  • js/libs/builder.js
  • js/libs/form.js
🧬 Code Graph Analysis (1)
js/libs/core.js (2)
js/libs/builder.js (3)
  • field (1155-1155)
  • currentMultiStepForm (1133-1133)
  • currentMultiStepForm (1179-1179)
js/libs/form.js (9)
  • field (298-298)
  • currentMultiStepForm (283-283)
  • currentMultiStepForm (900-900)
  • currentMultiStepForm (1086-1086)
  • currentMultiStepForm (1415-1415)
  • currentMultiStepForm (2006-2006)
  • currentMultiStepForm (2046-2046)
  • currentMultiStepForm (2065-2065)
  • currentMultiStepForm (2087-2087)
🪛 Biome (1.9.4)
js/components/customButton.js

[error] 33-33: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 34-34: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

js/components/radio.js

[error] 58-60: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

js/components/reorderList.js

[error] 117-117: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 119-119: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

js/components/checkbox.js

[error] 53-57: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 60-62: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 112-112: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 113-113: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 135-135: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 143-143: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 144-144: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 148-148: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 165-165: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 166-166: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 169-171: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 182-182: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 228-230: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

js/components/matrix.js

[error] 63-63: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 97-97: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 177-177: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 178-180: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 182-182: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 246-246: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 249-249: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 258-260: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 313-313: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 314-316: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

js/components/wysiwyg.js

[error] 42-42: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 74-74: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 86-86: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 87-87: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 88-92: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 125-125: Template literals are preferred over string concatenation.

Unsafe fix: Use a template literal.

(lint/style/useTemplate)


[error] 249-249: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)

js/components/file.js

[error] 97-97: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 98-98: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 108-108: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 109-109: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 128-132: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

js/libs/core.js

[error] 49-49: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 50-50: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 143-143: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 147-147: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 225-237: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 226-226: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 229-229: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 230-230: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 318-320: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 435-435: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 429-429: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 430-433: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 637-639: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 674-676: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 692-697: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 699-709: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 701-701: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 815-815: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 818-818: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 925-925: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

js/libs/utils.js

[error] 34-34: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)


[error] 26-26: Use Array.isArray() instead of instanceof Array.

instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.

(lint/suspicious/useIsArray)


[error] 117-117: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

js/libs/builder.js

[error] 265-267: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 672-678: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 680-686: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 696-696: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 700-700: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 793-795: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 977-977: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 978-978: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 979-979: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 981-981: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 982-982: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 985-985: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 986-986: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 987-987: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 1024-1027: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 1254-1256: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 1282-1284: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

js/libs/form.js

[error] 134-134: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 137-137: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 138-138: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 139-142: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 143-143: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 454-454: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 513-513: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 519-519: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 538-538: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 1443-1443: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 1633-1639: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 1656-1656: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 2157-2160: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 2163-2163: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 2168-2168: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 2173-2173: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 2175-2175: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 2166-2166: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 2220-2220: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 2409-2409: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Unsafe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)


[error] 2409-2409: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 2447-2447: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: Cursor BugBot
🔇 Additional comments (34)
js/libs/utils.js (2)

53-69: LGTM! Excellent debounce implementation.

The debounce function correctly handles both immediate and delayed execution patterns, with proper cleanup and context preservation.


142-157: Use safer property checking method.

The has function should use Object.hasOwnProperty.call() instead of accessing hasOwnProperty directly from the object.

 function has(obj, path) {
   if (!obj || typeof obj !== 'object') return false;
 
   const keys = path.split('.');
   let current = obj;
 
   for (const key of keys) {
-    if (current === null || current === undefined || !Object.prototype.hasOwnProperty.call(current, key)) {
+    if (current === null || current === undefined || !Object.hasOwnProperty(current, key)) {
       return false;
     }
 
     current = current[key];
   }
 
   return true;
 }

Likely an incorrect or invalid review comment.

js/components/number.js (1)

82-82: Replacement of _.isNaN with isNaN is safe in this context

No other occurrences of _.isNaN were found in the codebase. Since value is the result of parseFloat(), it will always be a number (or NaN), so isNaN(value) behaves identically to _.isNaN(value) here. You may optionally use Number.isNaN(value) for stricter NaN-only checks, but it isn’t required to maintain correctness.

widget.json (1)

35-35: Approved removal of lodash — new utils.js usage verified

  • Searched for any remaining lodash references with rg lodash and rg "_.[\w]+" across .js files; no lodash imports or usage found in application code.
  • The only matches are internal identifiers in vendor libraries, which are unaffected by this change.
  • Adding js/libs/utils.js to both interface and build assets and removing the lodash dependency is correct and complete.
js/libs/templates.js (1)

76-78: Ignore removal of unused template helpers

A scan of the entire codebase found no references to compileTemplate or renderTemplate outside their commented definitions in js/libs/templates.js. Commenting them out introduces no breaking changes, so you can safely leave them removed.

Likely an incorrect or invalid review comment.

js/components/image.js (1)

317-319: Excellent lodash replacement with native method.

The replacement of _.map with native Array.prototype.map is correct and maintains identical functionality whilst removing the lodash dependency.

js/components/file.js (1)

54-60: Excellent native method replacements for lodash utilities.

The replacements are correct:

  • Array.map() properly replaces _.map
  • Array.some() properly replaces _.some

These native methods provide identical functionality whilst removing lodash dependencies.

js/components/matrix.js (4)

66-76: Well-implemented kebab-case conversion helper.

The toKebabCase method correctly handles camelCase to kebab-case conversion and provides appropriate documentation.


78-89: Solid isEmpty implementation with comprehensive type checking.

The isEmpty method handles all the necessary edge cases (null, undefined, empty strings, arrays, and objects) with clear logic.


157-159: Excellent native JavaScript replacements for Lodash methods.

The refactoring successfully replaces Lodash utilities with native equivalents:

  • Array.prototype.forEach instead of _.forEach
  • Object.keys().forEach instead of _.forIn
  • Array.prototype.findIndex instead of _.findIndex
  • Object.prototype.hasOwnProperty.call instead of _.has
  • Custom isEmpty method instead of _.isEmpty

The logic remains intact and the implementations are correct.

Also applies to: 169-196


245-265: Consistent and correct native method usage throughout.

All remaining Lodash replacements follow the same pattern:

  • Native find and every methods
  • Proper use of Object.prototype.hasOwnProperty.call
  • Consistent forEach patterns

The refactoring maintains the original functionality whilst removing external dependencies.

Also applies to: 289-297, 312-321, 335-337

js/components/checkbox.js (5)

104-120: Well-implemented sortBy method with proper immutability.

The sortBy implementation correctly:

  • Uses slice() to avoid mutating the original array
  • Implements proper comparison logic
  • Handles edge cases with consistent return values

122-156: Robust deep equality implementation with comprehensive type checking.

The isEqual method properly handles:

  • Primitive type equality
  • Null/undefined checks
  • Array deep comparison with recursion
  • Object deep comparison with property validation
  • Proper use of Object.prototype.hasOwnProperty.call

The recursive implementation is correct and will handle nested structures appropriately.


158-179: Correct uniqueWith implementation using comparator function.

The method properly:

  • Creates a new result array
  • Uses some() to check for duplicates
  • Correctly applies the comparator function with proper context
  • Maintains functional programming principles

53-57: Effective usage of custom sortBy method.

The sortBy method is used correctly to maintain checkbox option order based on their index positions in the options array.

Also applies to: 185-189


228-230: Proper native JavaScript replacements.

Good use of native find() method with Object.prototype.hasOwnProperty.call for safe property checking.

js/components/wysiwyg.js (4)

54-64: Clean toKebabCase implementation.

The method correctly handles the conversion from various formats to kebab-case with proper regex patterns and method chaining.


66-76: Excellent getNestedProperty implementation.

The method properly uses reduce() to safely traverse nested object properties and handles missing properties gracefully.


78-95: Solid setNestedProperty implementation with object creation.

The method correctly:

  • Splits the path into keys
  • Creates intermediate objects as needed
  • Sets the final property value
  • Uses proper functional programming patterns

248-257: Proper usage of native forEach and helper methods.

The code correctly:

  • Uses native forEach instead of Lodash
  • Applies the custom getNestedProperty and setNestedProperty methods
  • Maintains the original plugin configuration logic
js/libs/core.js (6)

48-68: Excellent native JavaScript replacements for category processing.

The refactoring successfully replaces Lodash methods with native equivalents:

  • Object.keys().forEach() instead of _.forIn
  • Array.prototype.find() instead of _.find

The logic is preserved and the implementation is more performant without external dependencies.


224-237: Well-implemented custom debounce function.

The debounce implementation correctly:

  • Uses closure to maintain timeout state
  • Handles context and arguments properly
  • Clears previous timeouts appropriately
  • Applies the function with correct timing

This is a solid replacement for _.debounce.


340-400: Proper use of Object.assign for property merging.

The native Object.assign() correctly replaces _.assign() functionality whilst maintaining the original merge behaviour for component properties.

Also applies to: 435-439


924-937: Effective custom debounced field matching implementation.

The _matchFields method properly:

  • Uses custom debounce with appropriate delay
  • Maintains context with closure
  • Handles field name synchronisation correctly
  • Checks for duplicate fields in multi-step forms

The refactoring preserves the original functionality whilst removing Lodash dependency.


692-709: Correct native array method usage.

The code properly replaces Lodash array utilities with native methods:

  • Array.prototype.map() instead of _.map
  • Array.prototype.filter() instead of _.filter and _.compact
  • Proper handling of falsy value filtering

The spread operator with Set for deduplication is a modern, efficient approach.

Also applies to: 1321-1346


870-871: Evaluate deep-cloning approach in js/libs/core.js

The current use of

this.localSelectedFieldOptions = JSON.parse(JSON.stringify(this.selectedFieldOptions));
this.localFieldOptions         = JSON.parse(JSON.stringify(this.fieldOptions));

fails for Dates, functions, undefined values or circular references.

Consider instead:

  • Use the built-in structured cloning API where available (modern browsers, Node 17+):
    this.localSelectedFieldOptions = structuredClone(this.selectedFieldOptions);
    this.localFieldOptions         = structuredClone(this.fieldOptions);
  • Provide a fallback or polyfill for environments without structuredClone, or use a lightweight deep-clone utility.
  • Verify your target runtime support and test edge cases (e.g. circular structures, special object types).

[js/libs/core.js#L870–871]

js/libs/builder.js (4)

43-43: Well done on replacing _.compact with native filter(Boolean)!

This is a clean and idiomatic JavaScript replacement that maintains the same functionality.

Also applies to: 422-422


123-143: Good replacement of _.assign with Object.assign.

The native Object.assign is the standard way to merge objects in modern JavaScript.


696-696: Excellent use of Set for array uniqueness!

Using [...new Set()] is a modern and efficient way to get unique values, replacing _.uniq.


977-992: Good conversion from lodash to native loops.

The nested loop structure correctly handles the attribute processing.

Consider using more modern iteration methods:

-for (var i = 0; i < $allElements.length; i++) {
-  var el = $allElements[i];
+for (const el of $allElements) {
   var $el = $(el);

-  for (var j = 0; j < el.attributes.length; j++) {
-    var attr = el.attributes[j];
+  for (const attr of el.attributes) {
js/libs/form.js (4)

15-153: Good approach to replacing lodash with native JavaScript helpers!

The helper functions are well-implemented and maintain compatibility with the lodash API. This keeps the codebase maintainable while removing the external dependency.


52-67: Well-implemented get function for nested property access.

The implementation correctly handles edge cases and follows the lodash API, including support for both string paths with dots and array paths.


451-470: Verify the usage of mapKeys here.

Given that the mapKeys implementation is broken (see previous comment), this code might not be working as intended. The current usage suggests you're only iterating over the object, not transforming keys.

Consider replacing with a clearer approach:

-mapKeys(Fliplet.Navigate.query, function(value, key) {
+Object.entries(Fliplet.Navigate.query).forEach(function([key, value]) {
   if (key === field.defaultValueKey) {
     field.rowOptions.forEach(function(row) {
       var val = row.id ? row.id : row.label;

       if (!has(matrixValue, val)) {
         matrixValue[val] = value;
       }
     });
   } else if (key.includes(field.defaultValueKey)) {
     var regex = /\[(.*)\]/g;
     var match = key.split(regex).filter(r => r !== '');

     if (match.length > 1) {
       matrixValue[match[1]] = value;
     } else {
       matrixValue = value;
     }
   }
 });

1861-1861: Good use of Object.values() for native object value extraction.

This is the standard way to get object values in modern JavaScript, replacing lodash's _.values.

@@ -716,7 +721,7 @@ Fliplet().then(function() {
payload: payload
});
} else if (!hooksDeleted) {
if (_.isEqual(columns.sort(), ds.columns.sort())) {
if (JSON.stringify(columns.sort()) === JSON.stringify(ds.columns.sort())) {
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider a more efficient array comparison method.

While JSON.stringify works for comparing arrays, it can be inefficient for large datasets and doesn't handle all edge cases (e.g., different object property orders).

Consider using a dedicated array comparison function:

-if (JSON.stringify(columns.sort()) === JSON.stringify(ds.columns.sort())) {
+if (columns.length === ds.columns.length && columns.sort().every((val, index) => val === ds.columns.sort()[index])) {
   return; // no need to update
 }

Or extract to a utility function:

function arraysEqual(a, b) {
  if (a.length !== b.length) return false;
  const sortedA = [...a].sort();
  const sortedB = [...b].sort();
  return sortedA.every((val, index) => val === sortedB[index]);
}
🤖 Prompt for AI Agents
In js/libs/builder.js at line 724, replace the current array comparison using
JSON.stringify with a more efficient and reliable method. Implement a utility
function that first checks array lengths, sorts copies of both arrays, and then
compares elements one by one for equality. Use this function to compare the
columns arrays instead of stringifying them.

Comment on lines +81 to +89
function mapKeys(object, iteratee) {
const result = {};

for (const [key, value] of Object.entries(object)) {
iteratee(value, key);
}

return result;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: The mapKeys function is incorrectly implemented.

The function only calls the iteratee but doesn't create a new object with mapped keys. This will break any code relying on this function.

The current implementation doesn't map keys or return a transformed object. Here's the correct implementation:

 function mapKeys(object, iteratee) {
   const result = {};

   for (const [key, value] of Object.entries(object)) {
-    iteratee(value, key);
+    const newKey = iteratee(value, key);
+    result[newKey] = value;
   }

   return result;
 }

However, looking at the usage in line 451, it seems the code doesn't actually need the mapped object - it's just iterating. Consider if mapKeys is the right function here, or if a simple Object.entries().forEach() would be clearer.

📝 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.

Suggested change
function mapKeys(object, iteratee) {
const result = {};
for (const [key, value] of Object.entries(object)) {
iteratee(value, key);
}
return result;
}
function mapKeys(object, iteratee) {
const result = {};
for (const [key, value] of Object.entries(object)) {
const newKey = iteratee(value, key);
result[newKey] = value;
}
return result;
}
🤖 Prompt for AI Agents
In js/libs/form.js around lines 81 to 89, the mapKeys function currently calls
the iteratee but does not build or return a new object with transformed keys,
which breaks its intended functionality. To fix this, modify the function to
create a new result object where each key is replaced by the value returned from
the iteratee, and return this new object. Alternatively, if the usage at line
451 only requires iteration without mapping, replace the mapKeys call with
Object.entries().forEach() for clarity and correctness.

Comment on lines +134 to +149
var timeout;

return function() {
var context = this;
var args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;

clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider using let instead of var in the debounce function.

While var works here, using let would be more consistent with modern JavaScript practices.

 function debounce(func, wait, immediate) {
-  var timeout;
+  let timeout;

   return function() {
-    var context = this;
-    var args = arguments;
-    var later = function() {
+    const context = this;
+    const args = arguments;
+    const later = function() {
       timeout = null;
       if (!immediate) func.apply(context, args);
     };
-    var callNow = immediate && !timeout;
+    const callNow = immediate && !timeout;

     clearTimeout(timeout);
     timeout = setTimeout(later, wait);
     if (callNow) func.apply(context, args);
   };
 }
📝 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.

Suggested change
var timeout;
return function() {
var context = this;
var args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
function debounce(func, wait, immediate) {
let timeout;
return function() {
const context = this;
const args = arguments;
const later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 134-134: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 137-137: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 138-138: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 139-142: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 143-143: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

🤖 Prompt for AI Agents
In js/libs/form.js between lines 134 and 149, replace the declaration of the
variable 'timeout' from 'var' to 'let' to align with modern JavaScript practices
and improve code clarity and block scoping.

var ordered = _.sortBy(this.value, function(val) {
return _.findIndex($vm.options, function(option) {
var ordered = this.sortBy(this.value, function(val) {
return $vm.options.findIndex(function(option) {
Copy link
Contributor

@Arpanexe Arpanexe Jul 7, 2025

Choose a reason for hiding this comment

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

@armine-fliplet Could you please confirm if this change will work? I assume $vm.options doesn’t have a findIndex function unless it is string or Array.

Copy link
Contributor

Choose a reason for hiding this comment

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

@Arpanexe type of $vm.options is Array

return (option.id || option.label) === val;
});
});

// Get all options label in array format
var allOptions = _.map(this.options, function(option) {
var allOptions = this.options.map(function(option) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@armine-fliplet Same with map function

Copy link
Contributor

Choose a reason for hiding this comment

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

@Arpanexe type of $vm.options is Array

@armine-fliplet armine-fliplet self-requested a review July 8, 2025 08:42
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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: 6

🔭 Outside diff range comments (1)
js/libs/core.js (1)

149-170: Excellent Lodash replacements with minor style improvements needed.

The replacements are correct:

  • Object.keys().forEach() properly replaces _.forIn
  • String.prototype.includes() correctly replaces _.includes
  • Object.prototype.hasOwnProperty.call() is good practice for safe property checking

Consider updating variable declarations from var to const:

-                Object.keys(Fliplet.Navigate.query).forEach(function(key) {
-                var value = Fliplet.Navigate.query[key];
+                Object.keys(Fliplet.Navigate.query).forEach(function(key) {
+                const value = Fliplet.Navigate.query[key];
♻️ Duplicate comments (2)
js/libs/core.js (2)

22-37: Remove duplicate JSDoc documentation.

The JSDoc comment for emitEvent is duplicated. Remove the first occurrence (lines 22-27) since the function is commented out with proper explanation.


436-446: Object.assign replacement is correct, but address variable declarations.

The replacement of _.assignIn with Object.assign is correct. Update variable declarations from var to const:

-      var baseComponent = components[componentName];
-      var pickedProps = {
+      const baseComponent = components[componentName];
+      const pickedProps = {

Note: The parameter reassignment issue on line 442 was already flagged in previous reviews.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91ce56b and 4129347.

📒 Files selected for processing (1)
  • js/libs/core.js (22 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.js`: Review the JavaScript code against the Google JavaScript style guide ...

**/*.js: Review the JavaScript code against the Google JavaScript style guide and point out any mismatches. Ensure all code is fully documented. Suggest a testing plan to ensure code is adequately tested. Suggest unit tests. Avoid integration tests.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • js/libs/core.js
🧬 Code Graph Analysis (1)
js/libs/core.js (2)
js/libs/builder.js (3)
  • field (1155-1155)
  • currentMultiStepForm (1133-1133)
  • currentMultiStepForm (1179-1179)
js/libs/form.js (9)
  • field (298-298)
  • currentMultiStepForm (283-283)
  • currentMultiStepForm (900-900)
  • currentMultiStepForm (1086-1086)
  • currentMultiStepForm (1415-1415)
  • currentMultiStepForm (2006-2006)
  • currentMultiStepForm (2046-2046)
  • currentMultiStepForm (2065-2065)
  • currentMultiStepForm (2087-2087)
🪛 Biome (1.9.4)
js/libs/core.js

[error] 56-56: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 57-57: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 150-150: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 154-154: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 232-244: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 233-233: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'let' instead.

(lint/style/noVar)


[error] 236-236: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 237-237: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 325-327: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 442-442: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)


[error] 436-436: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 437-440: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 644-646: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 681-683: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 699-704: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 706-716: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 708-708: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 822-822: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 825-825: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)


[error] 932-932: Use let or const instead of var.

A variable declared with var is accessible in the whole body of the function. Thus, the variable can be accessed before its initialization and outside the block where it is declared.
See MDN web docs for more details.
Unsafe fix: Use 'const' instead.

(lint/style/noVar)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (4)
js/libs/core.js (4)

58-60: LGTM: Correct Lodash replacement.

The replacement of _.find with native Array.prototype.find is correct and maintains the same functionality.


727-850: LGTM: Consistent Object.assign replacements.

All Object.assign(this.errors, {...}) calls correctly replace _.assignIn functionality. The error handling logic is preserved and the syntax is clean.


877-878: JSON cloning replacement is adequate for this use case.

The JSON.parse(JSON.stringify()) replacement for _.cloneDeep works well for basic object cloning of field options. Note that this approach has limitations (doesn't handle functions, dates, undefined, Symbol) but is sufficient for the current data structure.


1328-1353: LGTM: Clean array processing implementation.

The use of native split(), map(), and filter() methods for processing option strings is correct and efficient. The string parsing logic properly handles both simple options and label/ID pairs.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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: 4

♻️ Duplicate comments (2)
js/libs/utils.js (2)

115-133: Avoid parameter reassignment in assignIn

Static analysis still flags target reassignment. Use a local variable instead to comply with Google style and maintain clarity.

-function assignIn(target, ...sources) {
-  if (!target || typeof target !== 'object') {
-    target = {};
-  }
+function assignIn(target, ...sources) {
+  const result = (target && typeof target === 'object') ? target : {};
 
   sources.forEach(source => {
     if (source && typeof source === 'object') {
       Object.keys(source).forEach(key => {
         if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
-          target[key] = assignIn(target[key] || {}, source[key]);
+          result[key] = assignIn(result[key] || {}, source[key]);
         } else {
-          target[key] = source[key];
+          result[key] = source[key];
         }
       });
     }
   });
 
-  return target;
+  return result;
 }

1-4: Extend file-level JSDoc per Google style

The header lacks @fileoverview, examples, and explicit author/version tags previously requested.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4129347 and d0b867c.

📒 Files selected for processing (1)
  • js/libs/utils.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.js`: Review the JavaScript code against the Google JavaScript style guide ...

**/*.js: Review the JavaScript code against the Google JavaScript style guide and point out any mismatches. Ensure all code is fully documented. Suggest a testing plan to ensure code is adequately tested. Suggest unit tests. Avoid integration tests.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • js/libs/utils.js
🪛 Biome (1.9.4)
js/libs/utils.js

[error] 117-117: Reassigning a function parameter is confusing.

The parameter is declared here:

Use a local variable instead.

(lint/style/noParameterAssign)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (1)
js/libs/utils.js (1)

90-96: isEmpty does not respect Maps, Sets, Numbers or Booleans

_.isEmpty(new Map()) → true, but this implementation returns false.
Also primitives like 0 or false should return true according to Lodash. Please align or update documentation.

Comment on lines +53 to +69
function debounce(func, wait, immediate) {
let timeout;

return function executedFunction(...args) {
const later = () => {
timeout = null;
if (!immediate) func.apply(this, args);
};

const callNow = immediate && !timeout;

clearTimeout(timeout);
timeout = setTimeout(later, wait);

if (callNow) func.apply(this, args);
};
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

debounce leaks this & arguments context

Inside the returned arrow (later) this is lexically bound to the outer scope, not to the original call site, which breaks the common Lodash contract. Use a normal function and forward both this and args explicitly.

🤖 Prompt for AI Agents
In js/libs/utils.js around lines 53 to 69, the debounce function uses an arrow
function for 'later', causing 'this' to be lexically bound and not preserving
the original call context. Replace the arrow function 'later' with a normal
function expression and explicitly forward 'this' and 'args' to 'func.apply' to
correctly preserve the calling context and arguments.

Comment on lines +176 to +186
function uniqWith(array, comparator) {
const result = [];

for (const item of array) {
if (!result.some(existing => comparator(existing, item))) {
result.push(item);
}
}

return result;
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

uniqWith is O(n²); warn for large inputs

For large arrays this quadratic scan may be a bottleneck. Consider hashing comparator keys or using a Set when comparator is equality.

🤖 Prompt for AI Agents
In js/libs/utils.js around lines 176 to 186, the uniqWith function has O(n²)
complexity due to nested iteration with the comparator. To fix this, optimize
for large inputs by checking if the comparator is simple equality and, if so,
use a Set to track seen items for O(n) performance. Otherwise, consider hashing
keys derived from the comparator to reduce redundant comparisons and improve
efficiency.

armine-fliplet and others added 2 commits July 8, 2025 14:50
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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: 7

♻️ Duplicate comments (3)
js/libs/utils.js (3)

194-204: Performance concern: O(n²) complexity for large arrays.

The uniqWith function has quadratic time complexity due to the nested iteration. For large arrays, this could become a performance bottleneck.

Consider optimising for large inputs by checking if the comparator is simple equality and using a Set for O(n) performance, or implement a more efficient algorithm for custom comparators.


278-293: Avoid global namespace pollution.

The code blindly overwrites window.FlipletUtils without checking if it already exists, which could clobber existing utilities.

 // Make utilities available globally for browser usage
 if (typeof window !== 'undefined') {
-  window.FlipletUtils = {
+  window.FlipletUtils = Object.assign(window.FlipletUtils || {}, {
     cloneDeep,
     debounce,
     kebabCase,
     isEmpty,
     compact,
     assignIn,
     has,
     uniq,
     uniqWith,
     sortBy,
     isEqual
-  };
+  });
 }

1-4: Enhance file-level documentation.

The current documentation is basic. Consider adding more comprehensive JSDoc comments following the Google JavaScript style guide.

 /**
  * Utility functions to replace lodash dependencies
  * These functions provide native JavaScript alternatives to commonly used lodash methods
+ * 
+ * @fileoverview Native JavaScript utility functions replacing Lodash dependencies
+ * @version 1.0.0
+ * @author Fliplet
  */
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0b867c and c93aa40.

📒 Files selected for processing (1)
  • js/libs/utils.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.js`: Review the JavaScript code against the Google JavaScript style guide ...

**/*.js: Review the JavaScript code against the Google JavaScript style guide and point out any mismatches. Ensure all code is fully documented. Suggest a testing plan to ensure code is adequately tested. Suggest unit tests. Avoid integration tests.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • js/libs/utils.js
🪛 GitHub Check: Linting
js/libs/utils.js

[failure] 47-47:
Expected blank line before this statement


[failure] 42-42:
Do not nest ternary expressions


[failure] 38-38:
Expected blank line before this statement


[failure] 37-37:
Expected blank line before this statement


[failure] 6-6:
Missing JSDoc for parameter 'cache'

🪛 GitHub Actions: Run ESLint on Pull Requests
js/libs/utils.js

[error] 6-6: ESLint: Missing JSDoc for parameter 'cache' (valid-jsdoc)

Comment on lines +261 to +293
// Export utilities for use in other files
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
cloneDeep,
debounce,
kebabCase,
isEmpty,
compact,
assignIn,
has,
uniq,
uniqWith,
sortBy,
isEqual
};
}

// Make utilities available globally for browser usage
if (typeof window !== 'undefined') {
window.FlipletUtils = {
cloneDeep,
debounce,
kebabCase,
isEmpty,
compact,
assignIn,
has,
uniq,
uniqWith,
sortBy,
isEqual
};
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

🛠️ Refactor suggestion

Suggest comprehensive unit testing plan.

This utility library requires thorough testing to ensure compatibility with lodash replacements. Consider implementing unit tests covering:

  • Edge cases for each function (null, undefined, empty values)
  • Circular reference handling in cloneDeep
  • Performance testing for uniqWith with large datasets
  • Cross-browser compatibility testing
  • Type validation and error handling

Would you like me to generate a comprehensive test suite for these utilities?

🤖 Prompt for AI Agents
In js/libs/utils.js around lines 261 to 293, the utility functions are exported
for both Node.js and browser environments but lack comprehensive unit tests. To
fix this, create a detailed test suite that covers edge cases such as null,
undefined, and empty inputs for each function, tests cloneDeep's handling of
circular references, evaluates uniqWith's performance on large datasets,
verifies cross-browser compatibility, and checks type validation and error
handling to ensure robustness and compatibility with lodash replacements.

Comment on lines +160 to +175
function has(obj, path) {
if (!obj || typeof obj !== 'object') return false;

const keys = path.split('.');
let current = obj;

for (const key of keys) {
if (current === null || current === undefined || !Object.prototype.hasOwnProperty.call(current, key)) {
return false;
}

current = current[key];
}

return true;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add input validation for the path parameter.

The function assumes path is a string but doesn't validate this assumption, which could lead to runtime errors.

 function has(obj, path) {
   if (!obj || typeof obj !== 'object') return false;
+  if (typeof path !== 'string') return false;
 
   const keys = path.split('.');
📝 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.

Suggested change
function has(obj, path) {
if (!obj || typeof obj !== 'object') return false;
const keys = path.split('.');
let current = obj;
for (const key of keys) {
if (current === null || current === undefined || !Object.prototype.hasOwnProperty.call(current, key)) {
return false;
}
current = current[key];
}
return true;
}
function has(obj, path) {
if (!obj || typeof obj !== 'object') return false;
if (typeof path !== 'string') return false;
const keys = path.split('.');
let current = obj;
for (const key of keys) {
if (current === null || current === undefined || !Object.prototype.hasOwnProperty.call(current, key)) {
return false;
}
current = current[key];
}
return true;
}
🤖 Prompt for AI Agents
In js/libs/utils.js around lines 160 to 175, the has function assumes the path
parameter is a string but does not validate it, which can cause runtime errors
if a non-string is passed. Add input validation at the start of the function to
check if path is a string; if not, return false immediately to prevent errors
from calling split on a non-string.

* @param {*} obj - Object to clone
* @returns {*} Cloned object
*/
function cloneDeep(obj, cache = new WeakMap()) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add missing JSDoc parameter documentation.

The cache parameter is missing from the JSDoc documentation, which is causing linting failures.

 /**
  * Deep clone an object using structuredClone or JSON fallback
  * Replacement for _.cloneDeep()
  * @param {*} obj - Object to clone
+ * @param {WeakMap} cache - Internal cache for circular reference tracking
  * @returns {*} Cloned object
  */
📝 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.

Suggested change
function cloneDeep(obj, cache = new WeakMap()) {
/**
* Deep clone an object using structuredClone or JSON fallback
* Replacement for _.cloneDeep()
* @param {*} obj - Object to clone
* @param {WeakMap} cache - Internal cache for circular reference tracking
* @returns {*} Cloned object
*/
function cloneDeep(obj, cache = new WeakMap()) {
// …rest of implementation…
}
🤖 Prompt for AI Agents
In js/libs/utils.js at line 12, the JSDoc comment for the cloneDeep function is
missing documentation for the cache parameter. Add a @param tag for cache in the
JSDoc block, describing it as a WeakMap used to cache objects during cloning to
handle circular references. This will resolve the linting failure related to
missing parameter documentation.

Comment on lines +213 to +227
function sortBy(array, iteratee) {
const getValue = typeof iteratee === 'function'
? iteratee
: item => item[iteratee];

return [...array].sort((a, b) => {
const aVal = getValue(a);
const bVal = getValue(b);

if (aVal < bVal) return -1;
if (aVal > bVal) return 1;

return 0;
});
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider handling edge cases in sortBy function.

The function doesn't handle cases where the iteratee function might return undefined or null values, which could lead to unexpected sorting behaviour.

   return [...array].sort((a, b) => {
     const aVal = getValue(a);
     const bVal = getValue(b);
+    
+    // Handle undefined/null values
+    if (aVal == null && bVal == null) return 0;
+    if (aVal == null) return 1;
+    if (bVal == null) return -1;
 
     if (aVal < bVal) return -1;
     if (aVal > bVal) return 1;
📝 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.

Suggested change
function sortBy(array, iteratee) {
const getValue = typeof iteratee === 'function'
? iteratee
: item => item[iteratee];
return [...array].sort((a, b) => {
const aVal = getValue(a);
const bVal = getValue(b);
if (aVal < bVal) return -1;
if (aVal > bVal) return 1;
return 0;
});
}
function sortBy(array, iteratee) {
const getValue = typeof iteratee === 'function'
? iteratee
: item => item[iteratee];
return [...array].sort((a, b) => {
const aVal = getValue(a);
const bVal = getValue(b);
// Handle undefined/null values
if (aVal == null && bVal == null) return 0;
if (aVal == null) return 1;
if (bVal == null) return -1;
if (aVal < bVal) return -1;
if (aVal > bVal) return 1;
return 0;
});
}
🤖 Prompt for AI Agents
In js/libs/utils.js around lines 213 to 227, the sortBy function does not handle
cases where the iteratee returns undefined or null, which can cause unexpected
sorting results. Update the comparison logic to explicitly check for undefined
or null values for aVal and bVal, and define a consistent ordering for these
cases (e.g., treat undefined/null as greater or lesser than any valid value).
This will ensure the sort behaves predictably even when some items have missing
or null properties.

Comment on lines +37 to +38
cache.set(obj, result);
return result;
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Fix formatting issues for better readability.

Static analysis indicates missing blank lines before these statements, which improves code readability.

   if (Array.isArray(obj)) {
     const result = obj.map(item => cloneDeep(item, cache));
+
     cache.set(obj, result);
+
     return result;
   }
📝 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.

Suggested change
cache.set(obj, result);
return result;
if (Array.isArray(obj)) {
const result = obj.map(item => cloneDeep(item, cache));
cache.set(obj, result);
return result;
}
🧰 Tools
🪛 GitHub Check: Linting

[failure] 38-38:
Expected blank line before this statement


[failure] 37-37:
Expected blank line before this statement

🤖 Prompt for AI Agents
In js/libs/utils.js around lines 37 to 38, add a blank line before the
statements "cache.set(obj, result);" and "return result;" to improve code
readability and adhere to formatting standards.

Comment on lines +42 to +46
const cloned = obj instanceof Map
? new Map()
: obj instanceof Set
? new Set()
: {};
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Simplify nested ternary expressions for better readability.

The nested ternary operators make the code harder to read and are flagged by static analysis.

   if (typeof obj === 'object') {
-    const cloned = obj instanceof Map
-      ? new Map()
-      : obj instanceof Set
-        ? new Set()
-        : {};
+    let cloned;
+    if (obj instanceof Map) {
+      cloned = new Map();
+    } else if (obj instanceof Set) {
+      cloned = new Set();
+    } else {
+      cloned = {};
+    }
     cache.set(obj, cloned);
📝 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.

Suggested change
const cloned = obj instanceof Map
? new Map()
: obj instanceof Set
? new Set()
: {};
if (typeof obj === 'object') {
let cloned;
if (obj instanceof Map) {
cloned = new Map();
} else if (obj instanceof Set) {
cloned = new Set();
} else {
cloned = {};
}
cache.set(obj, cloned);
🧰 Tools
🪛 GitHub Check: Linting

[failure] 42-42:
Do not nest ternary expressions

🤖 Prompt for AI Agents
In js/libs/utils.js around lines 42 to 46, the nested ternary expression used to
initialize the cloned variable reduces code readability. Refactor this by
replacing the nested ternary with a clearer if-else or switch statement that
explicitly checks if obj is an instance of Map or Set and assigns the
appropriate new instance, otherwise defaults to an empty object. This will
improve readability and satisfy static analysis checks.

: obj instanceof Set
? new Set()
: {};
cache.set(obj, cloned);
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Add blank line before statement for consistency.

Static analysis indicates a missing blank line before this statement.

     cache.set(obj, cloned);
+
     for (const key in obj) {
📝 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.

Suggested change
cache.set(obj, cloned);
cache.set(obj, cloned);
for (const key in obj) {
🧰 Tools
🪛 GitHub Check: Linting

[failure] 47-47:
Expected blank line before this statement

🤖 Prompt for AI Agents
In js/libs/utils.js at line 47, add a blank line before the statement
"cache.set(obj, cloned);" to maintain consistent code formatting and satisfy
static analysis requirements.

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