Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Rename field with wildcard support#1215

Open
anasshakil wants to merge 4 commits intoexpress-validator:masterfrom
anasshakil:master
Open

Rename field with wildcard support#1215
anasshakil wants to merge 4 commits intoexpress-validator:masterfrom
anasshakil:master

Conversation

@anasshakil
Copy link

@anasshakil anasshakil commented Feb 21, 2023

Description

This allows to rename fields using rename context item.

Example

app.post(
  "/user",
  // Promise
  body("search").rename(async (value) => {
    // do some asynchronous task
    if (value.includes("@")) {
      return "email";
    } else if (value.includes("#")) {
      return "tag";
    }
    return null;
  }),
  // Basic
  check("search")
    .rename((value) => {
      if (value.includes("+")) {
        return "phone";
      }
      return undefined;
    })
    .withMessage("An error occurred"),
  // wildcard field with short-circuiting `string`
  body("user.*.addresses.home").rename("accounts.*.users.*.addresses.billing.street"),
  (req, res) => {
    // Handle the request
    const data = matchedData(req);
    res.json(data);
  }
);

Request Body

{
    "search": "[email protected]",
    "user": [
        {
            "addresses": {
                "home":  "billing address street"
            }
        }
    ]
}

Output

{
  "email": "[email protected]",
   "accounts": [
        {
            "users": [
                {
                    "addresses": {
                        "billing": {
                            "street": "billing address street"
                        }
                    }
                }
            ]
        }
    ]
}

closes #785

To-do list

  • Wildcard support

  • I have added tests for what I changed.

  • This pull request is ready to merge.

@anasshakil anasshakil closed this Feb 21, 2023
@anasshakil anasshakil reopened this Feb 21, 2023
@coveralls
Copy link

coveralls commented Feb 22, 2023

Coverage Status

Coverage: 99.263% (-0.7%) from 100.0% when pulling 5d4dafc on anasshakil:master into eba0cfe on express-validator:master.

Comment on lines +23 to +24
if (typeof actualResult === 'string') {
context.renameFieldInstance(actualResult, meta);
Copy link
Member

Choose a reason for hiding this comment

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

May I ask why you thought of making use of the custom validators?

Changing the meaning of the return of a custom validator will be quite disruptive for everybody, and is certainly a breaking change.

Perhaps a new function in the chain would be a better idea?

Copy link
Author

@anasshakil anasshakil Feb 22, 2023

Choose a reason for hiding this comment

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

We ran into a problem where we needed to rename the search field on the bases of the input. I thought of the custom validator as a solution because it solves both of the requirements. To avoid the breaking change, we can accept the return type of an object containing a field, for example { express_rename: 'foo' }.

Comment on lines +116 to +121
if (this.fields.length !== 1) {
throw new Error('Attempt to rename multiple fields.');
}
if (/\.|\*/g.test(originalPath)) {
throw new Error('Attempt to rename a wildcard field');
}
Copy link
Member

Choose a reason for hiding this comment

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

Nice thinking here. I suppose that the callback should be able to handle the name to give to a field though -- as it has access to the full original path.

Copy link
Author

Choose a reason for hiding this comment

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

I had some success on renaming wildcard paths but need to do more work for wildcard support

- Wildcard support
- Test cases added for wildcard and non-wildcard field rename
@anasshakil anasshakil changed the title Rename field using custom validator Rename field with wildcard support Feb 27, 2023
Copy link
Member

@gustavohenke gustavohenke left a comment

Choose a reason for hiding this comment

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

General question: should the old property be removed when renaming the item?

renameFieldInstance will work for setting the new property with the same value as the old field instance, but it won't touch the old one.

// Avoids e.g. undefined values being set on the request if it didn't have the key initially.
const reqValue = path !== '' ? _.get(req[location], path) : req[location];
if (!options.dryRun && reqValue !== instance.value) {
path !== '' ? _.set(req[location], path, newValue) : _.set(req, location, newValue);
}

* @param evaluator the custom evaluator based on the `CustomValidator`
* @returns the current validation chain
*/
rename(evaluator: CustomValidator): Return;
Copy link
Member

Choose a reason for hiding this comment

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

Nice, this is better!
A few comments here though:

  1. This shouldn't stay in the Validators interface. ContextHandler sounds more like it.
  2. Let's add a type specific for the rename callback, so that CustomValidator can evolve independently from the rename functionality.
  3. WDYT of accepting a string value too, which works as a shortcut? For example, rename('banana') automatically renames that field to banana.

import { ContextItem } from './context-item';

export class RenameFieldContextItem implements ContextItem {
message: any;
Copy link
Member

Choose a reason for hiding this comment

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

When you move rename out of Validators, I think that this won't be necessary anymore

export class RenameFieldContextItem implements ContextItem {
message: any;

constructor(private readonly evaluator: CustomValidator, private readonly negated: boolean) {}
Copy link
Member

Choose a reason for hiding this comment

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

Ditto for negated

- Shifted  rename functionality to context handler
@anasshakil anasshakil requested a review from gustavohenke March 9, 2023 11:25
@gustavohenke gustavohenke force-pushed the master branch 2 times, most recently from 3177f64 to 6e160b1 Compare April 7, 2023 12:26
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.

[Feature Request] Ability to rename parameters

3 participants