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: add 'rename' context-item #971

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

Conversation

fedeci
Copy link
Member

@fedeci fedeci commented Jan 2, 2021

Description

This allows to rename a property.

// req: { body: { name: 'foo' } } becomes 
// req: { body: { username: 'foo' } }
body('name').rename('username').isString()

// req: { body: { names: ['foo', 'bar'] } } throws
body('names.*').rename('username').isString()

// req: { body: { name: 'foo', surname: 'bar' } } throws
body(['name', 'surname']).rename('username')

// req: { body: { name: 'foo', surname: 'bar' } } throws
body('name').rename('surname')

Closes #785

To-do list

  • Work on returned errors
  • Wildcards?
  • Dotted property names (e.g. 1.0)
  • Context runner instance.path editing
  • Nested properties

  • I have added tests for what I changed.
  • This pull request is ready to merge.

Comment on lines 12 to 23
if (path !== this.newPath) {
if (context.fields.length !== 1) {
throw new Error('Cannot rename multiple fields.');
}
const field = context.fields[0];
if (field.includes('*') || this.newPath.includes('*')) {
throw new Error('Cannot use rename() with wildcards.');
}

if (_.get(req[location], this.newPath) !== undefined) {
throw new Error(`Cannot rename to req.${location}.${path} as it already exists.`);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

These errors are thrown at runtime, should we use context.addError() even if it is not a validation error?

@coveralls
Copy link

coveralls commented Jan 2, 2021

Coverage Status

Coverage remained the same at 100.0% when pulling db52eb4 on fedeci:rename-sanitizer into 0b0b6c8 on express-validator:master.

const newValue = instance.value;
if (contextItem instanceof Rename) {
// change instance path
instance.path = contextItem.newPath;
Copy link
Member Author

Choose a reason for hiding this comment

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

Is it correct to change instance.path?

Copy link
Member

Choose a reason for hiding this comment

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

I'll guess no because of the below:

setData(path: string, value: any, location: Location) {
const instance = this.dataMap.get(getDataMapKey(path, location));
if (!instance) {
throw new Error('Attempt to write data that did not pre-exist in context');
}

but we can always change behaviour.

And side comment, I'd just find it a bit more classy if we could use context's APIs instead of checking for the specific implementation of Rename here.

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.

ohey only 1.5 years later

Comment on lines +17 to +19
if (this.newPath.includes('*')) {
throw new Error('Cannot use rename() with wildcards.');
}
Copy link
Member

Choose a reason for hiding this comment

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

WDYT of moving this to the constructor/.rename()?

Just thinking that failing on server start might be a better developer experience than on request.

Comment on lines +21 to +22
if (_.get(req[location], this.newPath) !== undefined) {
throw new Error(`Cannot rename to req.${location}.${path} as it already exists.`);
Copy link
Member

Choose a reason for hiding this comment

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

I'm guessing that a client might, due to a bug, send more information than required and litter logs with 5XX errors (as I think it'll probably flow all the way to next()).

Perhaps it's best to remove this?

Comment on lines +25 to +26
_.set(req[location], this.newPath, value);
_.unset(req[location], path);
Copy link
Member

Choose a reason for hiding this comment

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

These should obey the dryRun option

import { Meta } from '../base';
import { Rename } from './rename';

it('the new path is identical to the old one', () => {
Copy link
Member

Choose a reason for hiding this comment

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

nitpicking, but I usually like to make test names read nicely with the it.
For example:

Suggested change
it('the new path is identical to the old one', () => {
it('does nothing when the new path is identical to the old one', () => {

const context = new ContextBuilder().setFields(['foo']).build();
const meta: Meta = { req: {}, location: 'body', path: 'foo' };

expect(new Rename('foo').run(context, 'value', meta)).resolves;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
expect(new Rename('foo').run(context, 'value', meta)).resolves;
await expect(new Rename('foo').run(context, 'value', meta)).resolves;

though I'm afraid that .resolves might not be asserting anything 🤔

const newValue = instance.value;
if (contextItem instanceof Rename) {
// change instance path
instance.path = contextItem.newPath;
Copy link
Member

Choose a reason for hiding this comment

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

I'll guess no because of the below:

setData(path: string, value: any, location: Location) {
const instance = this.dataMap.get(getDataMapKey(path, location));
if (!instance) {
throw new Error('Attempt to write data that did not pre-exist in context');
}

but we can always change behaviour.

And side comment, I'd just find it a bit more classy if we could use context's APIs instead of checking for the specific implementation of Rename here.

@gustavohenke gustavohenke force-pushed the master branch 2 times, most recently from 3177f64 to 6e160b1 Compare April 7, 2023 12:26
@gustavohenke gustavohenke removed this from the v7.0.0 milestone Apr 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request] Ability to rename parameters
3 participants