Skip to content
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

feat(middleware): support creation of standalone functions #229

Merged
merged 18 commits into from
Aug 13, 2024
Merged

Conversation

TheEdoRan
Copy link
Owner

Proposed changes

Code in this PR requires context to be an object, it extends it by default, and enables creation of standalone middleware functions via built-in experimental_createMiddleware utility.

Related issue(s) or discussion(s)

re #222

Copy link

vercel bot commented Aug 12, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
next-safe-action-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 13, 2024 10:51am
next-safe-action-website ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 13, 2024 10:51am

Copy link

@mcalhoun mcalhoun left a comment

Choose a reason for hiding this comment

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

Thanks for this work! I left a few comments on the deepMerge function (I've got a bunch of experience in this area and there are lots of foot guns! Also, maybe consider a series of unit tests for this function as it's REALLY easy to run into edge cases.

const k = key as keyof typeof obj2;
// eslint-disable-next-line
if (typeof obj2[k] === "object" && Object.hasOwn(obj1, k)) {
// @ts-expect-error

Choose a reason for hiding this comment

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

Consider handling arrays explicitly. If obj2[k] is an array, it might be better to replace obj1[k] with a copy of obj2[k] instead of treating it as an object for merging.

Choose a reason for hiding this comment

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

The check typeof obj2[k] === "object" will return true for null values, which could cause issues. Consider adding an explicit check to ensure obj2[k] is not null.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Thank you for reviewing the code. Would it be better to use lodash merge function in your opinion?

Choose a reason for hiding this comment

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

I definitely think using a 3rd-party library would be better, although I don't think lodash has been well-maintained recently? Maybe consider ramda?

Copy link
Owner Author

Choose a reason for hiding this comment

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

The thing is: ramda is published as a whole library, while lodash provides lodash.merge as a standalone package, which is obviously much smaller in size. deepmerge or deepmerge-ts also appear to be viable options. What do you think?

@@ -2,6 +2,22 @@ export const DEFAULT_SERVER_ERROR_MESSAGE = "Something went wrong while executin

export const isError = (error: unknown): error is Error => error instanceof Error;

export const deepMerge = (obj1: object, obj2: object) => {
for (const key of Object.keys(obj2)) {

Choose a reason for hiding this comment

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

To prevent prototype pollution attacks, consider adding a check to skip merging keys like proto, constructor, and prototype.

@@ -2,6 +2,22 @@ export const DEFAULT_SERVER_ERROR_MESSAGE = "Something went wrong while executin

export const isError = (error: unknown): error is Error => error instanceof Error;

export const deepMerge = (obj1: object, obj2: object) => {

Choose a reason for hiding this comment

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

Consider adding a validation to ensure that obj1 and obj2 are non-null objects. This will prevent issues when the function is called with non-object arguments.

@mcalhoun
Copy link

mcalhoun commented Aug 13, 2024 via email

@TheEdoRan
Copy link
Owner Author

TheEdoRan commented Aug 13, 2024

@mcalhoun I chose to use deepmerge-ts, which seems to be an up to date and more performant variant of deepmerge. Apparently, if you install the package as devDependency and import it in the code, tsup takes care of bundling the external library in the js output, which is nice.

Copy link

🎉 This PR is included in version 7.6.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants