matched-data.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.matchedData = matchedData;
  4. const _ = require("lodash");
  5. const base_1 = require("./base");
  6. /**
  7. * Extracts data validated or sanitized from the request, and builds an object with them.
  8. *
  9. * @param req the express request object
  10. * @param options
  11. * @returns an object of data that's been validated or sanitized in the passed request
  12. */
  13. function matchedData(req, options = {}) {
  14. const internalReq = req;
  15. const fieldExtractor = createFieldExtractor(options.includeOptionals !== true);
  16. const validityFilter = createValidityFilter(options.onlyValidData);
  17. const locationFilter = createLocationFilter(options.locations);
  18. return _(internalReq[base_1.contextsKey])
  19. .flatMap(fieldExtractor)
  20. .filter(validityFilter)
  21. .map(field => field.instance)
  22. .filter(locationFilter)
  23. .reduce((state, instance) => _.set(state, instance.path, instance.value), {});
  24. }
  25. function createFieldExtractor(removeOptionals) {
  26. return (context) => {
  27. const instances = context.getData({ requiredOnly: removeOptionals });
  28. return instances.map((instance) => ({ instance, context }));
  29. };
  30. }
  31. function createValidityFilter(onlyValidData = true) {
  32. return !onlyValidData
  33. ? () => true
  34. : (field) => {
  35. const hasError = field.context.errors.some(error => error.type === 'field' &&
  36. error.location === field.instance.location &&
  37. error.path === field.instance.path);
  38. return !hasError;
  39. };
  40. }
  41. function createLocationFilter(locations = []) {
  42. // No locations mean all locations
  43. const allLocations = locations.length === 0;
  44. return allLocations ? () => true : (field) => locations.includes(field.location);
  45. }