Skip to content

Conversation

@kingston
Copy link
Collaborator

@kingston kingston commented Jan 15, 2025

Summary by CodeRabbit

Based on the comprehensive summary of changes, here are the release notes:

  • New Features

    • Created a new @halfdomelabs/utils package to centralize utility functions across the codebase
    • Introduced a new sync library for synchronizing codebase from Baseplate definitions
  • Dependency Updates

    • Replaced lodash and ramda libraries with es-toolkit in multiple packages
    • Added @halfdomelabs/utils as a workspace dependency across various projects
  • Performance Improvements

    • Streamlined utility functions and reduced external library dependencies
    • Simplified object merging and sorting operations using native JavaScript methods
  • Refactoring

    • Updated import statements and utility function usage across multiple packages
    • Consolidated merging and sorting logic into a centralized utils package
  • Licensing

    • Added a new software license agreement for the Baseplate code generator

@linear
Copy link

linear bot commented Jan 15, 2025

@changeset-bot
Copy link

changeset-bot bot commented Jan 15, 2025

🦋 Changeset detected

Latest commit: d1e6478

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@halfdomelabs/utils Patch
@halfdomelabs/project-builder-server Patch
@halfdomelabs/project-builder-lib Patch
@halfdomelabs/project-builder-web Patch
@halfdomelabs/fastify-generators Patch
@halfdomelabs/react-generators Patch
@halfdomelabs/core-generators Patch
@halfdomelabs/project-builder-cli Patch
@halfdomelabs/project-builder-common Patch
@halfdomelabs/project-builder-test Patch
@halfdomelabs/baseplate-plugin-storage Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Jan 15, 2025

Walkthrough

A comprehensive refactoring effort has been undertaken to replace utility libraries like Ramda and Lodash with a new @halfdomelabs/utils package and es-toolkit. This initiative involves creating a new utility package, removing dependencies on existing libraries, and updating import statements and function calls across multiple packages. The changes aim to streamline dependencies, improve code maintainability, and leverage more modern JavaScript utility functions.

Changes

File/Package Change Summary
@halfdomelabs/utils New utility package created with utility functions like safeMerge, safeMergeAll, and other object manipulation methods
Multiple Packages Removed dependencies: lodash, ramda, @types/lodash, @types/ramda
Multiple Packages Added dependencies: @halfdomelabs/utils, es-toolkit
Multiple Source Files Replaced library-specific utility functions with native JavaScript methods or es-toolkit equivalents

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant Utils as @halfdomelabs/utils
    participant EsTk as es-toolkit
    participant Project as Project Packages

    Dev->>Utils: Create new utility package
    Utils->>EsTk: Leverage es-toolkit functions
    Project->>Utils: Import utility functions
    Project->>EsTk: Import additional utility functions
    Project->>Project: Replace Ramda/Lodash calls
Loading

The sequence diagram illustrates the transition from multiple utility libraries to a centralized utility package with supplementary support from es-toolkit, demonstrating how the refactoring simplifies dependency management and utility function usage across the project.

Finishing Touches

  • 📝 Generate Docstrings (Beta)

🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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

@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: 3

🧹 Nitpick comments (7)
packages/project-builder-web/src/pages/apps/new.page.tsx (1)

Line range hint 1-1: Overall Migration Assessment

The migration from lodash to es-toolkit is largely consistent and well-executed across all files. Key observations:

  1. Syntax adaptations are consistent (e.g., array syntax for iteratees)
  2. Most functionality is preserved
  3. One potential behavioral change in AdminSectionsForm.tsx where the sorting criteria were modified

Consider documenting these syntax differences between lodash and es-toolkit in your team's migration guide to help other developers with similar migrations.

packages/fastify-generators/src/writers/pothos/args.ts (1)

84-87: Consider adding type assertion for argMap.

The safeMergeAllWithOptions return type might need explicit typing to ensure type safety with the subsequent mapValues operation.

-  const argMap = safeMergeAllWithOptions(argOutputs);
+  const argMap = safeMergeAllWithOptions(argOutputs) as Record<string, PothosArgOutput>;
packages/project-builder-lib/src/references/deserialize-schema.ts (1)

76-77: Consider using native JavaScript features where possible.

For simple path access, consider using optional chaining and nullish coalescing instead of the compatibility get/set functions. This could improve performance and reduce dependency on compatibility layers.

Example for the parent path access:

-const parentId = parentPath
-  ? (get(data, parentPath) as string)
-  : undefined;
+const parentId = parentPath
+  ? data?.[(parentPath as string[])[0]]?.[(parentPath as string[])[1]] as string
+  : undefined;

Note: Only apply this optimization for simple paths where the structure is known. For dynamic deep paths, continue using get/set.

Also applies to: 89-91, 102-102

packages/project-builder-web/src/pages/data/models/_hooks/useModelForm.ts (1)

178-183: Consider simplifying the sort criteria.

The sorting implementation is correct but can be simplified since you're only sorting by a single field.

-            draftConfig.models = sortBy(
-              [
-                ...draftConfig.models.filter((m) => m.id !== updatedModel.id),
-                updatedModel,
-              ],
-              [(m) => m.name],
-            );
+            draftConfig.models = sortBy(
+              [
+                ...draftConfig.models.filter((m) => m.id !== updatedModel.id),
+                updatedModel,
+              ],
+              (m) => m.name,
+            );
packages/fastify-generators/src/generators/core/fastify-server/index.ts (1)

183-197: Consider simplifying the plugin ordering logic.

While the implementation is correct, the switch statement could be simplified using a mapping object for better maintainability.

+            const PRIORITY_MAP = {
+              EARLY: 0,
+              MIDDLE: 1,
+              END: 2,
+            };
+
             const orderedPlugins = sortBy(plugins, [
-              (plugin) => {
-                switch (plugin.orderPriority) {
-                  case 'EARLY': {
-                    return 0;
-                  }
-                  case 'END': {
-                    return 2;
-                  }
-                  default: {
-                    return 1;
-                  }
-                }
-              },
+              (plugin) => PRIORITY_MAP[plugin.orderPriority ?? 'MIDDLE'],
             ]);
packages/core-generators/src/writers/typescript/imports.ts (1)

300-303: Consider adding error handling for merge conflicts.

The safeMergeAllWithOptions is used with allowEqualValues: true, which might silently ignore merge conflicts. Consider adding explicit error handling for cases where values differ.

packages/core-generators/src/writers/typescript/source-file.ts (1)

614-620: LGTM! Array flattening uses native JavaScript API.

Good use of native flat() method. However, consider making the comment more descriptive:

-    ].flat(/* The depth is always 2 */ 2);
+    ].flat(/* Flatten nested arrays: [[...], [...]] -> [...] */ 2);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Lite

📥 Commits

Reviewing files that changed from the base of the PR and between 9988200 and d1e6478.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (74)
  • .changeset/fuzzy-experts-exercise.md (1 hunks)
  • .changeset/thin-radios-pretend.md (1 hunks)
  • packages/core-generators/package.json (1 hunks)
  • packages/core-generators/src/generators/node/typescript/index.ts (2 hunks)
  • packages/core-generators/src/writers/typescript/code-entries.ts (2 hunks)
  • packages/core-generators/src/writers/typescript/import-order.ts (1 hunks)
  • packages/core-generators/src/writers/typescript/import-order.unit.test.ts (2 hunks)
  • packages/core-generators/src/writers/typescript/imports.ts (5 hunks)
  • packages/core-generators/src/writers/typescript/source-file.ts (8 hunks)
  • packages/fastify-generators/package.json (1 hunks)
  • packages/fastify-generators/src/generators/core/app-module/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/config-service/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/fastify-server/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/core/request-service-context/index.ts (3 hunks)
  • packages/fastify-generators/src/generators/core/root-module/index.ts (3 hunks)
  • packages/fastify-generators/src/generators/core/service-context/index.ts (4 hunks)
  • packages/fastify-generators/src/generators/pothos/pothos-enums-file/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/pothos/pothos-types-file/index.ts (2 hunks)
  • packages/fastify-generators/src/generators/prisma/_shared/crud-method/data-method.ts (4 hunks)
  • packages/fastify-generators/src/generators/prisma/embedded-relation-transformer/index.ts (1 hunks)
  • packages/fastify-generators/src/writers/pothos/args.ts (2 hunks)
  • packages/fastify-generators/src/writers/prisma-schema/schema.ts (2 hunks)
  • packages/project-builder-lib/package.json (1 hunks)
  • packages/project-builder-lib/src/compiler/app-compiler-spec.ts (1 hunks)
  • packages/project-builder-lib/src/parser/index.ts (4 hunks)
  • packages/project-builder-lib/src/plugins/imports/loader.ts (3 hunks)
  • packages/project-builder-lib/src/references/deserialize-schema.ts (7 hunks)
  • packages/project-builder-lib/src/references/fix-ref-deletions.ts (5 hunks)
  • packages/project-builder-lib/src/references/ref-builder.ts (7 hunks)
  • packages/project-builder-lib/src/references/serialize-schema.ts (2 hunks)
  • packages/project-builder-lib/src/tools/model-merger/index.ts (3 hunks)
  • packages/project-builder-lib/src/utils/merge.ts (2 hunks)
  • packages/project-builder-lib/src/web/hooks/useResettableForm.ts (3 hunks)
  • packages/project-builder-server/package.json (1 hunks)
  • packages/project-builder-server/src/compiler/backend/fastify.ts (1 hunks)
  • packages/project-builder-server/src/compiler/backend/feature.ts (1 hunks)
  • packages/project-builder-server/src/compiler/web/index.ts (1 hunks)
  • packages/project-builder-web/package.json (0 hunks)
  • packages/project-builder-web/src/app/AppLayout/AppBreadcrumbs.tsx (2 hunks)
  • packages/project-builder-web/src/pages/apps/AppsLayout.page.tsx (1 hunks)
  • packages/project-builder-web/src/pages/apps/edit/admin/AdminEditSectionForm.tsx (2 hunks)
  • packages/project-builder-web/src/pages/apps/edit/admin/AdminSectionsForm.tsx (2 hunks)
  • packages/project-builder-web/src/pages/apps/list.page.tsx (1 hunks)
  • packages/project-builder-web/src/pages/apps/new.page.tsx (2 hunks)
  • packages/project-builder-web/src/pages/data/_layout.tsx (2 hunks)
  • packages/project-builder-web/src/pages/data/enums/EnumsSidebarList.tsx (2 hunks)
  • packages/project-builder-web/src/pages/data/enums/hooks/useEnumForm.tsx (2 hunks)
  • packages/project-builder-web/src/pages/data/models/_components/ModelsSidebarList.tsx (2 hunks)
  • packages/project-builder-web/src/pages/data/models/_hooks/useModelForm.ts (2 hunks)
  • packages/project-builder-web/src/pages/settings/components/FeatureForm.tsx (2 hunks)
  • packages/project-builder-web/src/pages/settings/project-settings.tsx (2 hunks)
  • packages/react-generators/package.json (1 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-edit/index.ts (1 hunks)
  • packages/react-generators/src/generators/admin/admin-crud-embedded-form/index.ts (1 hunks)
  • packages/react-generators/src/generators/apollo/react-apollo/index.ts (2 hunks)
  • packages/react-generators/src/generators/core/_utils/render-routes.ts (2 hunks)
  • packages/react-generators/src/generators/core/react-config/index.ts (2 hunks)
  • packages/react-generators/src/writers/graphql/index.ts (3 hunks)
  • packages/utils/.gitignore (1 hunks)
  • packages/utils/.prettierignore (1 hunks)
  • packages/utils/LICENSE (1 hunks)
  • packages/utils/README.md (1 hunks)
  • packages/utils/eslint.config.js (1 hunks)
  • packages/utils/package.json (1 hunks)
  • packages/utils/prettier.config.js (1 hunks)
  • packages/utils/src/index.ts (1 hunks)
  • packages/utils/src/objects/index.ts (1 hunks)
  • packages/utils/src/objects/safe-merge.ts (2 hunks)
  • packages/utils/src/objects/safe-merge.unit.test.ts (1 hunks)
  • packages/utils/tsconfig.build.json (1 hunks)
  • packages/utils/tsconfig.json (1 hunks)
  • packages/utils/vitest.config.ts (1 hunks)
  • tests/simple/packages/backend/baseplate/.clean/package.json (0 hunks)
  • tests/simple/packages/backend/package.json (0 hunks)
💤 Files with no reviewable changes (3)
  • tests/simple/packages/backend/baseplate/.clean/package.json
  • tests/simple/packages/backend/package.json
  • packages/project-builder-web/package.json
✅ Files skipped from review due to trivial changes (19)
  • packages/utils/src/objects/index.ts
  • packages/utils/eslint.config.js
  • packages/utils/.prettierignore
  • packages/utils/vitest.config.ts
  • packages/utils/prettier.config.js
  • packages/project-builder-server/src/compiler/backend/fastify.ts
  • packages/utils/.gitignore
  • packages/utils/tsconfig.json
  • .changeset/fuzzy-experts-exercise.md
  • packages/utils/tsconfig.build.json
  • packages/utils/package.json
  • packages/react-generators/src/generators/apollo/react-apollo/index.ts
  • packages/utils/LICENSE
  • packages/react-generators/src/generators/admin/admin-crud-embedded-form/index.ts
  • .changeset/thin-radios-pretend.md
  • packages/utils/README.md
  • packages/project-builder-server/src/compiler/web/index.ts
  • packages/utils/src/index.ts
  • packages/fastify-generators/src/generators/prisma/embedded-relation-transformer/index.ts
🔇 Additional comments (69)
packages/project-builder-web/src/pages/settings/project-settings.tsx (2)

12-12: LGTM! Import change aligns with refactoring goals.

The replacement of lodash's pick with es-toolkit's pick is consistent with the PR objectives.


Line range hint 31-35: Verify es-toolkit's pick behavior matches lodash.

The implementation looks correct, but let's ensure es-toolkit's pick function handles edge cases (undefined/null values) similarly to lodash's implementation.

Run this script to find other usages and verify consistent behavior:

packages/project-builder-lib/src/utils/merge.ts (1)

1-1: Verify compatibility of mergeWith from es-toolkit

You've replaced R.mergeWith from Ramda with mergeWith from es-toolkit. Ensure that mergeWith from es-toolkit provides the same deep merging capabilities and handles customizer functions as expected.

Please review the mergeWith implementation in es-toolkit to confirm it aligns with your intended merge behavior.

packages/core-generators/src/writers/typescript/import-order.unit.test.ts (1)

34-34: Replace toReversed() with supported array reversal method

Same issue as above. Ensure consistent use of array reversal methods for compatibility.

packages/project-builder-lib/src/references/serialize-schema.ts (2)

10-12: Type constraint enhancement improves type safety.

The addition of extends Record<string, unknown> constraint to TValue ensures that the function only accepts object types, preventing potential runtime errors.


3-3: Verify es-toolkit/compat functions maintain lodash compatibility.

The migration from lodash to es-toolkit/compat functions (get, set, unset) appears correct. However, let's verify that the behavior remains identical, especially for edge cases.

Also applies to: 17-17, 20-20, 25-25, 34-34

✅ Verification successful

es-toolkit/compat functions maintain lodash compatibility ✓

The verification of test files shows comprehensive coverage of edge cases and complex scenarios, including:

  • Nested property access
  • Optional references
  • Parent-child relationships
  • Error handling

The functions are used consistently across the codebase in critical serialization/deserialization operations, demonstrating equivalent behavior to lodash.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any tests that verify the behavior of these utility functions
rg -l "test.*serialize.*schema" --type ts

Length of output: 43


Script:

#!/bin/bash
# Find the exact file and nearby tests
fd "serialize-schema" --type f

# Look for usage patterns of get/set/unset from es-toolkit
rg "from 'es-toolkit/compat'" -B1 -A1 --type ts

# Search for test files in the project-builder-lib
fd "test" --type f --extension ts --extension spec --extension test packages/project-builder-lib/

# Look for actual usage of these functions
rg "(?:get|set|unset)\(" --type ts -A 2 packages/project-builder-lib/src/references/

Length of output: 8510


Script:

#!/bin/bash
# Check the test files for verification of edge cases
rg -A 5 "describe|it\(" packages/project-builder-lib/src/references/serialize-schema.unit.test.ts
rg -A 5 "describe|it\(" packages/project-builder-lib/src/references/deserialize-schema.unit.test.ts

# Look for any imports of lodash in tests for comparison
rg "lodash" packages/project-builder-lib/src/references/

Length of output: 3034

packages/project-builder-lib/src/web/hooks/useResettableForm.ts (1)

4-4: Verify deep comparison behavior of es-toolkit's isEqual.

The replacement of lodash's isEqual with es-toolkit's version is used for comparing form values. This is critical for form state management and needs careful verification.

Also applies to: 29-29, 41-41

packages/project-builder-web/src/pages/apps/AppsLayout.page.tsx (1)

10-10: Note API difference in es-toolkit's sortBy implementation.

The migration from lodash's sortBy to es-toolkit's version required changing the syntax to use an array of key functions. While functionally equivalent, the implementation is different:

  • Lodash: _.sortBy(apps, (m) => m.name)
  • es-toolkit: sortBy(apps, [(app) => app.name])

Also applies to: 17-17

✅ Verification successful

Migration to es-toolkit's sortBy is complete and consistent

All instances in the codebase follow the new array-based key function pattern required by es-toolkit's sortBy implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other sortBy usage patterns to ensure consistent migration
rg "sortBy.*=>" --type ts

Length of output: 1196

packages/react-generators/src/generators/core/_utils/render-routes.ts (1)

4-4: Verify grouping behavior with edge cases.

The migration from lodash's groupBy to es-toolkit's version handles route grouping. Critical to verify:

  1. Null/undefined layout key handling
  2. 'no-layout' default behavior
  3. Empty groups handling

Also applies to: 13-15

✅ Verification successful

Grouping behavior verified, implementation is correct

The es-toolkit groupBy implementation properly handles all edge cases:

  • Null/undefined layout keys default to 'no-layout' via nullish coalescing
  • Missing layouts are validated with clear error messages
  • Empty groups are handled naturally by the grouping operation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for tests verifying route grouping behavior
rg -A 5 "test.*routes.*group" --type test

# Check for other groupBy usage patterns
rg "groupBy.*=>" --type ts

Length of output: 896


Script:

#!/bin/bash
# Find route grouping implementation
ast-grep --pattern 'groupBy($array, $fn)' packages/react-generators/src/generators/core/_utils/render-routes.ts

# Search for layout key handling
rg -A 5 "layout.*key" packages/react-generators/src/generators/core/_utils/render-routes.ts

Length of output: 517

packages/project-builder-web/src/pages/apps/list.page.tsx (1)

6-6: LGTM! Note the array syntax for iteratees.

The migration from lodash to es-toolkit looks good. Note that es-toolkit's sortBy expects an array of iteratees, hence the [(app) => app.name] syntax.

Also applies to: 14-14

packages/project-builder-web/src/pages/apps/edit/admin/AdminSectionsForm.tsx (1)

6-6: Verify if removing feature-based sorting was intentional.

The previous implementation sorted by both feature and name properties, but the new implementation only sorts by name. This changes the display order of sections.

If you want to maintain the same sorting behavior, consider:

-  const sortedSections = sortBy(appConfig.sections ?? [], [
-    (section) => section.name,
-  ]);
+  const sortedSections = sortBy(appConfig.sections ?? [], [
+    (section) => section.feature,
+    (section) => section.name,
+  ]);

Also applies to: 25-27

✅ Verification successful

Sorting by name only appears to be an intentional improvement

The simplified sorting by name is a reasonable change as:

  • No other instances of feature-based section sorting were found in the codebase
  • Single-property sorting provides a more predictable and consistent user experience
  • The feature property might be optional, making name-based sorting more reliable
🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find section type definition
ast-grep --pattern 'type Section = {
  $$$
}'

# Find interface definitions related to sections
ast-grep --pattern 'interface $_ {
  $$$
  section$_: $_
  $$$
}'

# Look for similar sortBy usage patterns
rg "sortBy.*section" -A 2 -B 2

# Check if there are any test files related to section sorting
fd "test|spec" | rg -i "section.*sort"

Length of output: 753


Script:

#!/bin/bash
# Look for type definitions with 'section' in broader context
ast-grep --pattern 'type $_ = {
  feature?: $_
  name: $_
  $$$
}'

# Look for documentation about sections
rg -i "section" README.md || true
rg -i "section" docs/ || true

# Find any config schema files
fd "schema.json|config.json" | xargs cat

# Look for feature-based grouping or sorting
rg "feature.*section" -A 2 -B 2

Length of output: 5760

packages/project-builder-web/src/pages/data/_layout.tsx (1)

5-5: LGTM! Clean migration to es-toolkit.

The migration from lodash's maxBy to es-toolkit's maxBy maintains identical functionality while reducing dependencies.

Also applies to: 18-18

packages/project-builder-web/src/pages/apps/new.page.tsx (1)

17-17: LGTM! Note the explicit iteratee function syntax.

The migration from lodash to es-toolkit looks good. Note that while lodash allowed the shorthand string syntax 'name', es-toolkit requires an explicit iteratee function (app) => app.name.

Also applies to: 45-45

packages/utils/src/objects/safe-merge.ts (3)

1-8: LGTM! Clean interface design with good documentation.

The MergeOptions interface is well-documented and the imports from es-toolkit align with the PR's objective of replacing lodash/ramda.


55-66: LGTM! Good backward compatibility.

The safeMergeAll function maintains the original API while leveraging the new implementation, making it easier for consumers to migrate.


49-50: Validate array input before flattening.

The flat() operation assumes the input array contains valid elements. Consider adding validation to handle potential edge cases.

packages/project-builder-server/src/compiler/backend/feature.ts (1)

12-12: LGTM! Clean import update.

The import statement has been correctly updated to use the new @halfdomelabs/utils package, aligning with the PR's objective of centralizing utility functions.

packages/fastify-generators/src/writers/pothos/args.ts (1)

4-5: LGTM! Clean utility function migration.

The imports have been correctly updated to use @halfdomelabs/utils and es-toolkit, aligning with the PR's objective.

packages/project-builder-lib/src/compiler/app-compiler-spec.ts (1)

3-4: LGTM! Clean import update.

The import statement has been correctly updated to use the new @halfdomelabs/utils package, maintaining the same functionality while aligning with the PR's objective.

packages/fastify-generators/src/generators/pothos/pothos-enums-file/index.ts (1)

14-14: LGTM! Correct usage of es-toolkit's sortBy.

The replacement of Ramda's sortBy with es-toolkit's version is done correctly. The iteratee function is properly wrapped in an array as required by es-toolkit's API.

Also applies to: 77-77

packages/core-generators/src/writers/typescript/import-order.ts (1)

111-120: Verify browser/node.js compatibility for Array.prototype.toSorted.

While the native implementation is more efficient, Array.prototype.toSorted() is an ES2023 feature that might not be supported in all target environments.

Run this script to check the minimum Node.js version in package.json and verify compatibility:

✅ Verification successful

Array.prototype.toSorted() usage is compatible with the codebase requirements

The codebase requires Node.js ^20.0.0 which fully supports this ES2023 feature.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check Node.js version requirements and verify toSorted support
# Note: toSorted requires Node.js >= 20.0.0

# Check engines field in package.json
jq -r '.engines.node' package.json

# Check if any transpilation/polyfill is configured
fd -e js -e json -e yaml -e yml babel

Length of output: 82

packages/project-builder-web/src/pages/data/models/_components/ModelsSidebarList.tsx (1)

11-11: LGTM! Consistent usage of es-toolkit's sortBy.

The replacement of lodash's sortBy with es-toolkit's version maintains the same functionality and follows the consistent pattern across the codebase.

Also applies to: 35-35

packages/project-builder-web/src/pages/data/enums/EnumsSidebarList.tsx (1)

11-11: LGTM! Consistent usage of es-toolkit's sortBy.

The replacement of lodash's sortBy with es-toolkit's version maintains the same functionality and follows the consistent pattern across the codebase.

Also applies to: 35-35

packages/fastify-generators/src/generators/core/app-module/index.ts (1)

10-10: LGTM! Clean replacement of Ramda's mapObjIndexed.

The replacement of R.mapObjIndexed with mapValues from es-toolkit maintains the same functionality while reducing external dependencies.

Also applies to: 78-80

packages/fastify-generators/src/writers/prisma-schema/schema.ts (1)

1-1: LGTM! Clean replacement of Ramda's sortBy.

The replacement of R.sortBy with sortBy from es-toolkit maintains the same sorting behavior while reducing external dependencies.

Also applies to: 128-128

packages/fastify-generators/src/generators/pothos/pothos-types-file/index.ts (1)

13-13: LGTM! Clean replacement of Ramda's sortBy with improved readability.

The replacement of R.sortBy with sortBy from es-toolkit maintains the same sorting behavior while making the category ordering logic more explicit and easier to understand.

Also applies to: 83-90

packages/project-builder-lib/src/references/deserialize-schema.ts (1)

3-4: LGTM! Clean replacement of lodash utilities.

The replacements maintain the same functionality while reducing external dependencies:

  • groupBy, keyBy, uniq from es-toolkit core
  • get, set from es-toolkit/compat for path-based operations
packages/project-builder-lib/src/references/fix-ref-deletions.ts (2)

3-4: LGTM! Good separation of imports.

The separation between es-toolkit and es-toolkit/compat imports is correct. The compat imports (get, groupBy, set) are for older browser compatibility, while sortBy is from the main package.


53-53: Verify the behavior of replaced utility functions.

The replacements look correct, but let's verify that the es-toolkit functions maintain the same behavior as their lodash counterparts, especially for:

  1. get/set with nested paths
  2. groupBy with object arrays
  3. sortBy with descending order (-o.idx)

Also applies to: 70-70, 83-83, 87-87, 92-92, 115-117, 121-123

✅ Verification successful

The es-toolkit utility functions maintain lodash-compatible behavior

The codebase shows consistent usage of es-toolkit utilities that matches lodash patterns:

  • get/set handle nested paths correctly (e.g., form error access)
  • groupBy works with object arrays as expected (e.g., entity grouping)
  • sortBy supports both simple keys and complex sorting with descending order
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for tests that verify the behavior of these utility functions
rg -A 5 "describe.*('(get|set|groupBy|sortBy)" 

Length of output: 149


Script:

#!/bin/bash
# Search for test files
rg -l "describe.*['\"].*?(get|set|groupBy|sortBy)" 

# Search for actual usage patterns of these utilities
rg -A 2 "import.*\{.*(get|set|groupBy|sortBy).*\}" 

# Search for specific usage patterns
ast-grep --pattern 'get($_, $_)'
ast-grep --pattern 'set($_, $_, $_)'
ast-grep --pattern 'groupBy($_, $_)'
ast-grep --pattern 'sortBy($_, $_)'

Length of output: 51611

packages/react-generators/src/generators/core/react-config/index.ts (1)

95-97: Verify the sorting behavior remains consistent.

The replacement of Ramda's sortBy with es-toolkit's sortBy looks correct for sorting config entries by key name. However, let's verify that no config entries are using special characters that might sort differently.

✅ Verification successful

Sorting behavior verified as consistent

The replacement is safe as the config entries use standard environment variable style naming (e.g., 'VITE_ENVIRONMENT'), and both implementations use standard string comparison for sorting.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for config entry definitions to verify key naming patterns
rg -A 5 "configEntries.*=.*{" 

Length of output: 133


Script:

#!/bin/bash
# Search for configEntries variable declarations and assignments
ast-grep --pattern 'const configEntries = $_'

# Search for config entries with properly escaped regex
rg -A 5 'configEntries\s*=\s*\{' 

# Also search for any direct assignments to configEntries
rg -A 5 'configEntries\[[^]]+\]\s*=' 

Length of output: 628


Script:

#!/bin/bash
# Find ConfigEntry type definition
ast-grep --pattern 'type ConfigEntry = $_'
ast-grep --pattern 'interface ConfigEntry $_'

# Find how configEntryMap is populated
rg -B 5 -A 5 'configEntryMap' packages/react-generators/src/generators/core/react-config/index.ts

# Look for any key validation or constraints
rg -l 'validateConfigKey|validateKey|isValidKey' packages/react-generators/

Length of output: 1529

packages/project-builder-web/src/pages/settings/components/FeatureForm.tsx (1)

105-105: LGTM! Simple and correct usage of sortBy.

The replacement of lodash's sortBy with es-toolkit's sortBy is straightforward and correct. The sorting by feature name will maintain the same behavior.

packages/project-builder-lib/src/plugins/imports/loader.ts (2)

1-1: LGTM! Clean import of utility functions.

The import of keyBy and mapValues from es-toolkit is clean and follows the project's new direction of using es-toolkit instead of lodash.


42-42: Verify the behavior of keyBy and mapValues in plugin initialization.

The replacements look correct, but let's verify that the es-toolkit functions maintain the same behavior as their lodash counterparts, especially in the critical plugin initialization logic:

  1. keyBy should maintain unique keys
  2. mapValues should handle undefined values correctly

Also applies to: 45-45, 133-133

✅ Verification successful

The es-toolkit replacements for keyBy and mapValues are safe to use

The unit tests demonstrate that:

  • Plugin IDs are properly handled as unique keys
  • Dependencies and implementations are correctly mapped and passed between plugins
  • The initialization order is maintained as expected
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for tests that verify plugin initialization
rg -A 5 "describe.*('plugin.*initialization" 

# Search for edge cases in plugin module definitions
ast-grep --pattern 'const $module = {
  exports: $$$,
  dependencies: $$$
}'

Length of output: 224


Script:

#!/bin/bash
# Search for test files related to plugins
fd -e test.ts -e spec.ts -e test.js -e spec.js | grep -i "plugin"

# Search for keyBy usage in plugin-related files
rg "keyBy.*plugin" -A 3

# Search for mapValues usage in plugin-related files
rg "mapValues.*plugin" -A 3

# Search for plugin module type definitions or interfaces
ast-grep --pattern 'interface PluginModule {
  $$$
}'

Length of output: 1308


Script:

#!/bin/bash
# Check the unit test contents
cat "packages/project-builder-lib/src/plugins/imports/loader.unit.test.ts"

# Look for error handling around plugin IDs
rg "duplicate.*plugin|invalid.*plugin" -A 3

# Search for plugin module type definition
ast-grep --pattern 'type PluginModule = {
  $$$
}'

# Search for validation functions
rg "validate.*plugin|check.*plugin" -A 3

Length of output: 3373

packages/project-builder-web/src/pages/data/enums/hooks/useEnumForm.tsx (1)

119-126: Verify the sorting behavior remains consistent.

The transition from lodash's sortBy to es-toolkit's sortBy looks correct. However, ensure that the new sorting implementation maintains the same order as before, especially since es-toolkit's sortBy expects an array of functions while lodash's version accepted a direct function.

✅ Verification successful

Sorting implementation is correctly migrated and consistent

The codebase shows a complete migration to es-toolkit's sortBy with consistent usage patterns. The enum sorting by name property is implemented uniformly across all enum-related components, maintaining consistent behavior.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any other instances of lodash's sortBy to ensure consistent migration
rg "_.sortBy|lodash.*sortBy" -A 3

Length of output: 35


Script:

#!/bin/bash
# Search for any sortBy imports or usage with broader patterns
echo "=== Searching for sortBy imports ==="
rg "import.*sortBy|from.*sortBy" -A 1

echo -e "\n=== Searching for sortBy function calls ==="
rg "sortBy\(" -A 2

echo -e "\n=== Checking the specific file history ==="
git log -p packages/project-builder-web/src/pages/data/enums/hooks/useEnumForm.tsx | rg -A 5 -B 5 "sortBy"

Length of output: 11513

packages/project-builder-lib/src/tools/model-merger/index.ts (2)

Line range hint 150-154: Ensure consistent array comparison behavior.

The transition to es-toolkit's isEqual for comparing primaryKeyFieldRefs arrays looks correct. However, verify that the array comparison behavior remains consistent, especially for arrays containing complex objects or when order matters.

Consider adding unit tests specifically for array comparison scenarios to ensure the behavior remains consistent across different types of primary key configurations.


63-63: Verify deep equality comparison behavior.

The transition from lodash's isEqual to es-toolkit's isEqual looks correct. However, ensure that es-toolkit's implementation handles deep object comparison similarly to lodash's version, as this is critical for detecting field changes.

✅ Verification successful

Transition to es-toolkit's isEqual is complete and correct

The codebase shows consistent usage of es-toolkit's isEqual (v1.31.0) for deep object comparison across multiple components, including complex nested structures, arrays, and objects, confirming its suitability as a replacement for lodash's isEqual.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining instances of lodash's isEqual
rg "_.isEqual|lodash.*isEqual" -A 3

Length of output: 37


Script:

#!/bin/bash
# Find imports and usages of isEqual
rg "import.*isEqual|isEqual\(" -A 2

# Look for es-toolkit package in dependencies
fd package.json --exec grep -A 5 "es-toolkit"

# Find the actual implementation if available
ast-grep --pattern 'function isEqual($_) { $$$ }'

Length of output: 5332

packages/fastify-generators/src/generators/core/config-service/index.ts (1)

130-133: Verify config entries remain consistently ordered.

The transition from Ramda's sortBy to es-toolkit's sortBy looks correct. The sorting affects both the configuration object and the generated environment files, so ensure that:

  1. The order remains consistent across all generated files
  2. The array-based sorting criteria [(entry) => entry[0]] maintains the same behavior as before
✅ Verification successful

Config entries sorting remains consistent across the codebase

The transition to es-toolkit's sortBy is complete and consistent. The array-based sorting criteria [(entry) => entry[0]] maintains the same behavior, ensuring consistent ordering across all generated files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining instances of Ramda's sortBy
rg "R.sortBy|ramda.*sortBy" -A 3

Length of output: 34


Script:

#!/bin/bash
# Check for any sorting-related imports and implementations
echo "=== Checking imports ==="
rg "import.*sort.*from" -g "*.ts" -g "*.js"

echo -e "\n=== Checking config-related files ==="
fd "config" -e ts -e js --exec rg -l "sort"

echo -e "\n=== Checking test files for sorting assertions ==="
fd "test|spec" -e ts -e js --exec rg -l "sort.*config|config.*sort"

echo -e "\n=== Examining the config service implementation ==="
ast-grep --pattern 'sortBy($$$)'

Length of output: 11589

packages/fastify-generators/src/generators/core/request-service-context/index.ts (2)

137-139: Ensure consistent passthrough mapping behavior.

The transition to es-toolkit's mapValues for context passthroughs looks correct. However, verify that:

  1. The callback function receives parameters in the same order
  2. The mapping behavior remains consistent for all passthrough scenarios

Consider adding unit tests to verify the mapping behavior, especially for edge cases where the order of parameters might affect the outcome.


125-125: Verify context field mapping behavior.

The transition from Ramda's mapObjIndexed to es-toolkit's mapValues for context fields looks correct. However, ensure that the mapping maintains the same behavior, especially regarding the order of parameters and access to keys.

✅ Verification successful

Mapping behavior transition verified successfully

The transition from mapObjIndexed to mapValues is correct. The parameter order and mapping behavior are consistent across multiple generator modules, and the mapper function doesn't require key access.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining instances of Ramda's mapObjIndexed
rg "R.mapObjIndexed|ramda.*mapObjIndexed" -A 3

Length of output: 48


Script:

#!/bin/bash
# Get the complete context of the mapping operation
ast-grep --pattern 'mapValues(contextFields, $_)' -A 5 -B 5

# Look for test files related to request-service-context
fd "request-service-context.*test" --type f --exec cat {}

# Check for mapValues implementation or usage patterns
rg "mapValues.*type" -A 2 -B 2

Length of output: 6847

packages/project-builder-web/src/pages/data/models/_hooks/useModelForm.ts (1)

19-19: LGTM! Import change aligns with the refactoring goal.

The change from lodash to es-toolkit's sortBy function aligns with the PR objective.

packages/fastify-generators/src/generators/core/service-context/index.ts (2)

17-17: LGTM! Import change aligns with the refactoring goal.

The change from ramda to es-toolkit's mapValues function aligns with the PR objective.


109-109: LGTM! Correct usage of mapValues.

The mapValues function is correctly used to replace ramda's mapObjIndexed while maintaining the same functionality.

Also applies to: 125-125

packages/fastify-generators/src/generators/core/root-module/index.ts (2)

16-17: LGTM! Import changes align with the refactoring goal.

The changes to use es-toolkit and @halfdomelabs/utils align with the PR objective.


156-157: LGTM! Correct usage of new utility functions.

The implementation correctly uses:

  • mapValues for transforming expressions
  • safeMergeAllWithOptions for merging field configurations

Also applies to: 199-199

packages/fastify-generators/src/generators/core/fastify-server/index.ts (1)

17-17: LGTM! Import change aligns with the refactoring goal.

The change from ramda to es-toolkit's sortBy function aligns with the PR objective.

packages/react-generators/src/writers/graphql/index.ts (1)

1-1: LGTM! Clean replacement of lodash's isEqual with es-toolkit.

The migration from lodash to es-toolkit for the isEqual function is clean and maintains the same functionality.

Also applies to: 200-200, 314-314

packages/project-builder-lib/src/parser/index.ts (1)

3-4: LGTM! Clean replacement of ramda utilities with modern alternatives.

The migration from ramda to es-toolkit and @halfdomelabs/utils is well-executed:

  • cloneDeep replaces ramda's deep clone
  • keyBy replaces ramda's indexBy
  • safeMerge provides safe merging capabilities

Also applies to: 40-40, 128-128

packages/core-generators/src/generators/node/typescript/index.ts (1)

10-10: LGTM! Clean replacement of ramda's mergeAll.

The migration from ramda's mergeAll to @halfdomelabs/utils' safeMergeAll for merging tsconfig.json sections is clean and maintains the same functionality.

Also applies to: 312-312

packages/core-generators/src/writers/typescript/imports.ts (1)

3-4: LGTM! Clean replacement of ramda's array operations with native alternatives.

The migration from ramda to native array methods and es-toolkit utilities is well-executed:

  • Native flatMap replaces ramda's flatten
  • uniq from es-toolkit for duplicate filtering

Also applies to: 278-280, 288-290

packages/react-generators/src/generators/admin/admin-crud-edit/index.ts (1)

160-161: Great use of native Object.fromEntries!

Good replacement of lodash's zipObject with the native Object.fromEntries. This change reduces external dependencies while maintaining the same functionality.

packages/fastify-generators/src/generators/prisma/_shared/crud-method/data-method.ts (2)

Line range hint 13-14: Well-organized imports from es-toolkit!

Good separation of imports between core es-toolkit and compat modules. Using specific imports helps with tree-shaking.


Line range hint 153-159: Good choice using safeMergeAllWithOptions!

The replacement of Ramda's mergeAll with safeMergeAllWithOptions provides better control over the merge behavior and maintains type safety.

packages/core-generators/src/writers/typescript/code-entries.ts (1)

55-71: Excellent use of native array methods with es-toolkit's uniq!

The changes improve code readability and maintainability by:

  • Using native flat() method for array flattening
  • Maintaining consistent method chaining
  • Leveraging uniq from es-toolkit for efficient deduplication
packages/project-builder-lib/src/references/ref-builder.ts (2)

Line range hint 431-435: Good use of es-toolkit's set!

Clean replacement of lodash's set utility while maintaining the same functionality for updating nested object properties.


Line range hint 598-637: Verify the entity reference resolution logic.

This is a critical section handling entity references and name resolution. While the replacement of lodash utilities with es-toolkit's keyBy and pull is good, please ensure:

  1. The entity resolution loop behaves correctly with the new pull implementation
  2. Edge cases are handled properly (e.g., circular references)
  3. Error messages are still accurate
✅ Verification successful

Entity reference resolution logic verified successfully

The implementation is robust and safe:

  • Circular references are prevented by design through type constraints and validation
  • The entity resolution loop has proper termination conditions
  • The pull operation is used correctly to maintain the integrity of the pending entities list
  • Error handling is comprehensive with specific error messages
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for potential circular references in entity definitions
ast-grep --pattern 'class $_ {
  $$$
  addEntity($_, $_) {
    $$$
    addEntity($_, $_)
    $$$
  }
  $$$
}'

Length of output: 111


Script:

#!/bin/bash
# Check the implementation and usage of pull function
rg "pull\(" -A 3 -B 3

# Look for entity resolution patterns and error handling
ast-grep --pattern 'throw new Error(`Could not resolve $$$`)'

# Check for nameRefPath usage
rg "nameRefPath" -A 2 -B 2

Length of output: 5631

packages/react-generators/package.json (1)

39-39: LGTM! Dependency changes align with refactoring goals.

The addition of es-toolkit and removal of lodash/ramda aligns with the PR's objective of standardizing utility functions.

packages/fastify-generators/package.json (1)

39-42: LGTM! Consistent dependency updates across packages.

The addition of @halfdomelabs/utils and es-toolkit, along with the removal of ramda, maintains consistency with the refactoring effort across packages.

packages/project-builder-lib/package.json (1)

42-42: LGTM! Completes the dependency standardization across packages.

The addition of @halfdomelabs/utils and es-toolkit completes the standardization of utility functions across all packages.

packages/core-generators/package.json (1)

40-40: LGTM! Dependencies updated correctly.

The changes align with the PR objectives by replacing ramda with @halfdomelabs/utils.

packages/project-builder-server/package.json (1)

45-45: LGTM! Dependencies updated correctly.

The addition of @halfdomelabs/utils aligns with the PR objectives.

packages/project-builder-web/src/app/AppLayout/AppBreadcrumbs.tsx (1)

5-5: LGTM! Verify the sorting behavior remains unchanged.

The replacement of lodash's orderBy with es-toolkit's orderBy maintains the same function signature and should provide identical sorting behavior.

Let's verify that es-toolkit's orderBy maintains the same behavior as lodash:

Also applies to: 37-37

✅ Verification successful

✓ Sorting behavior verified

The migration from lodash to es-toolkit's orderBy is complete and correct. The usage pattern is consistent, and no lodash orderBy imports remain in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that es-toolkit's orderBy is used consistently across the codebase
# and that there are no remaining lodash orderBy imports

# Check for any remaining lodash orderBy imports
rg -l "import.*\{.*orderBy.*\}.*from ['\"](lodash|lodash-es)['\"]"

# Check for consistent usage pattern of es-toolkit's orderBy
rg "orderBy\((.*?),.*\[['\"]\w+['\"]],.*\[['\"]asc['\"]]\)" -A 1

Length of output: 344

packages/project-builder-web/src/pages/apps/edit/admin/AdminEditSectionForm.tsx (1)

20-20: LGTM! Note the different usage pattern for es-toolkit's sortBy.

The replacement of lodash's sortBy with es-toolkit's sortBy requires a slight modification in usage pattern. The new pattern using an iteratee function (section) => section.name is more type-safe than the string shorthand 'name'.

Let's verify the consistent usage of es-toolkit's sortBy across the codebase:

Also applies to: 76-83

✅ Verification successful

Verified: es-toolkit's sortBy usage is consistent across the codebase

All instances of sortBy have been migrated from lodash to es-toolkit and follow the new pattern using array-wrapped arrow functions. No remaining lodash sortBy imports found.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that es-toolkit's sortBy is used consistently with the new pattern
# and that there are no remaining lodash sortBy imports

# Check for any remaining lodash sortBy imports
rg -l "import.*\{.*sortBy.*\}.*from ['\"](lodash|lodash-es)['\"]"

# Check for consistent usage pattern of es-toolkit's sortBy
rg "sortBy\((.*?),.*\[(.*?) =>.*\]" -A 1

Length of output: 1810

packages/core-generators/src/writers/typescript/source-file.ts (7)

12-12: LGTM! Import changes align with refactoring goals.

The addition of mapValues and uniqWith from 'es-toolkit' successfully replaces the removed Ramda imports.


Line range hint 140-160: LGTM! Constructor refactoring maintains functionality.

The replacement of Ramda's mapObjIndexed with mapValues from es-toolkit preserves the original logic while aligning with the refactoring goals.


164-175: LGTM! Data structure initialization uses native JavaScript API.

The replacement of Ramda's fromPairs with native Object.fromEntries is a good choice as it:

  • Reduces external dependencies
  • Uses well-supported native JavaScript API
  • Maintains the same functionality

345-380: LGTM! Consistent refactoring of map operations.

The replacement of Ramda's mapObjIndexed with mapValues is consistently applied across all code entry transformations while maintaining type safety and error handling.


629-632: LGTM! Import string handling is clean and concise.

The simplified approach to handling import strings improves readability while maintaining the same functionality.


641-641: LGTM! Import flattening uses native array methods.

Good use of native flatMap for flattening import arrays.


652-653: LGTM! Header block deduplication uses es-toolkit.

The replacement of Ramda's uniq with es-toolkit's uniqWith maintains the same deduplication logic with the custom comparison function.

}
if (typeof a === 'object' && typeof b === 'object') {
return R.mergeWith(deepMergeRightUniq, a, b);
return mergeWith(a, b, deepMergeRightUniq);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix array handling in deepMergeRightUniq function

The check typeof a === 'object' && typeof b === 'object' includes arrays because arrays are objects in JavaScript. This means that when both a and b are arrays, the array-specific merge logic might be bypassed, leading to incorrect behavior.

To ensure arrays are handled properly, move the array check before the object check.

Apply this diff to correct the logic:

 export function deepMergeRightUniq(a: unknown, b: unknown): unknown {
   if (a == null) {
     return b;
   }
   if (b == null) {
     return a;
   }
+  if (Array.isArray(a) && Array.isArray(b)) {
+    return [...new Set([...(a as unknown[]), ...(b as unknown[])])];
+  }
   if (typeof a === 'object' && typeof b === 'object') {
     return mergeWith(a, b, deepMergeRightUniq);
   }
-  if (Array.isArray(a) && Array.isArray(b)) {
-    return [...new Set([...(a as unknown[]), ...(b as unknown[])])];
-  }
 
   return b;
 }
📝 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
return mergeWith(a, b, deepMergeRightUniq);
export function deepMergeRightUniq(a: unknown, b: unknown): unknown {
if (a == null) {
return b;
}
if (b == null) {
return a;
}
if (Array.isArray(a) && Array.isArray(b)) {
return [...new Set([...(a as unknown[]), ...(b as unknown[])])];
}
if (typeof a === 'object' && typeof b === 'object') {
return mergeWith(a, b, deepMergeRightUniq);
}
return b;
}

'./',
]);
expect(sortByImportOrder(R.reverse(input), {})).toEqual([
expect(sortByImportOrder(input.toReversed(), {})).toEqual([
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace toReversed() with supported array reversal method

The method toReversed() is part of a newer ECMAScript proposal and may not be supported in all environments, potentially causing runtime errors.

Replace input.toReversed() with input.slice().reverse() to ensure compatibility:

 expect(sortByImportOrder(input, {})).toEqual([
   'fs',
   'chalk',
   '../foo',
   './bar',
   './',
 ]);
-expect(sortByImportOrder(input.toReversed(), {})).toEqual([
+expect(sortByImportOrder(input.slice().reverse(), {})).toEqual([
   'fs',
   'chalk',
   '../foo',
   './bar',
   './',
 ]);
📝 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
expect(sortByImportOrder(input.toReversed(), {})).toEqual([
expect(sortByImportOrder(input.slice().reverse(), {})).toEqual([

it('throws an error when keys overlap', () => {
const items = [{ a: 1 }, { b: 2 }, { b: 3 }];
expect(() => safeMergeAll(...items)).toThrowError(
expect(() => safeMergeAll(items)).toThrowError(
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the function call to safeMergeAll

In this test case, safeMergeAll is called with an array argument, but the function expects individual objects as arguments (spread syntax). Passing the array directly may lead to unexpected behavior.

Adjust the function call to spread the items:

 const items = [{ a: 1 }, { b: 2 }, { b: 3 }];
-expect(() => safeMergeAll(items)).toThrowError(
+expect(() => safeMergeAll(...items)).toThrowError(
   'Cannot merge key b because it already exists.',
 );
📝 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
expect(() => safeMergeAll(items)).toThrowError(
expect(() => safeMergeAll(...items)).toThrowError(

@kingston kingston merged commit 6a317cc into main Jan 15, 2025
6 checks passed
@kingston kingston deleted the kingston/eng-548-create-new-utils-package-to-better-share-utility-functions branch January 15, 2025 18:50
@github-actions github-actions bot mentioned this pull request Jan 17, 2025
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.

2 participants