Skip to content

Commit

Permalink
Implemented separated matched data for different locaitons
Browse files Browse the repository at this point in the history
  • Loading branch information
villamide committed Oct 13, 2017
1 parent 5f84536 commit 67927e4
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 6 deletions.
21 changes: 19 additions & 2 deletions README.md
Expand Up @@ -180,7 +180,24 @@ These methods are all available via `require('express-validator/filter')`.

### `matchedData(req[, options])`
- `req`: the express request object.
- `options` *(optional)*: an object of options. Defaults to `{ onlyValidData: true }`
- `options` *(optional)*: an object of options. Defaults to `{ onlyValidData: true }`.
- `onlyValidData: (Boolean)` If true, `matchedData` will return only the validated fields.
- `locations: Array` String array containing the matched data from the fields you want returned.
```js
// Example
const req = {
query: { foo: '123', bar: 'abc' },
body: { baz: '234' }
};
check(['foo', 'bar', 'baz']).isInt()(req, {}, () => {}).then(() => {
const bodyData = matchedData(req, { locations: ['body'] });
const queryData = matchedData(req, { locations: ['query'] });
const allData = matchedData(req);
console.log(bodyData) // { baz: 234 }
console.log(queryData) // { foo: 123 }
console.log(all) // { foo: 123, baz: 234 }
});
```
> *Returns:* an object of data validated by the `check` APIs.
Extracts data validated by the `check` APIs from the request and builds
Expand Down Expand Up @@ -380,7 +397,7 @@ The key will be the name of the sanitizer, while the value is the sanitization f
The Legacy Validation Chain instances provides further functionality than the one provided by the base [Validation Chain](#validation-chain-api) objects.
It also differs in that the legacy one is not a middleware *per se*.

Any custom validator specified in the middleware will be made available
Any custom validator specified in the middleware will be made available
in instances of this validation chain.

Additionally, the following validators are also available:
Expand Down
15 changes: 13 additions & 2 deletions filter/matched-data.js
@@ -1,17 +1,28 @@
const _ = require('lodash');
const selectFields = require('../check/select-fields');

module.exports = (req, { onlyValidData = true } = {}) => {
module.exports = (req, options = {}) => {
let onlyValidData = options.onlyValidData === undefined ? true : options.onlyValidData
let customLocations = options.locations === undefined ? false : options.locations
if (customLocations && !Array.isArray(customLocations)) {
throw new Error('returnLocations must be an Array')
}

const validityFilter = !onlyValidData ? () => true : field => {
return !req._validationErrors.find(error =>
error.param === field.path &&
error.location === field.location
);
};

const locationsFilter = !customLocations ? () => true : v => {
return customLocations.indexOf(v.location) !== -1
}

return _(req._validationContexts)
.flatMap(context => selectFields(req, context))
.filter(validityFilter)
.filter(locationsFilter)
.reduce((state, field) => _.set(state, field.path, field.value), {})
.valueOf();
};
};
57 changes: 55 additions & 2 deletions filter/matched-data.spec.js
Expand Up @@ -31,7 +31,7 @@ describe('filter: matchedData', () => {
});
});

describe('when { onlyValidData: false } flag is passed', () => {
describe('when { options.onlyValidData: false } flag is passed', () => {
it('returns object with all data validated in the request', () => {
const req = {
query: { foo: '123', bar: 'abc', baz: 'def' }
Expand Down Expand Up @@ -65,4 +65,57 @@ describe('filter: matchedData', () => {
});
});
});
});

describe('when { options.locations = [] } flag is passed', () => {
it('returns object with the specified location in the array', () => {
const req = {
query: { foo: '123', bar: 'abc' },
body: { baz: '234' }
};

return check(['foo', 'bar', 'baz']).isInt()(req, {}, () => {}).then(() => {
const data = matchedData(req, { locations: ['body'] });

expect(data).to.eql({
baz: '234'
});
});
});

it('returns object with the specified location in the array', () => {
const req = {
query: { foo: '123', bar: 'abc' },
body: { baz: '234' }
};

return check(['foo', 'bar', 'baz']).isInt()(req, {}, () => {}).then(() => {
const data = matchedData(req, { locations: ['body', 'query'] });

expect(data).to.eql({
foo: '123',
baz: '234'
});
});
});

it('returns object with the specified location in the array', () => {
const req = {
query: { foo: '123', bar: 'abc' },
body: { baz: '234' }
};

return check(['foo', 'bar', 'baz']).isInt()(req, {}, () => {}).then(() => {
const data = matchedData(req, {
onlyValidData: false,
locations: ['body', 'query']
});

expect(data).to.eql({
foo: '123',
bar: 'abc',
baz: '234'
});
});
});
});
});

0 comments on commit 67927e4

Please sign in to comment.