You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.6 KiB

4 years ago
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Gajus Kuizinas @gajus
  4. */
  5. "use strict";
  6. const Ajv = require("ajv");
  7. const ajv = new Ajv({
  8. errorDataPath: "configuration",
  9. allErrors: true,
  10. verbose: true
  11. });
  12. require("ajv-keywords")(ajv, ["instanceof"]);
  13. require("../schemas/ajv.absolutePath")(ajv);
  14. const validateSchema = (schema, options) => {
  15. if (Array.isArray(options)) {
  16. const errors = options.map(options => validateObject(schema, options));
  17. errors.forEach((list, idx) => {
  18. const applyPrefix = err => {
  19. err.dataPath = `[${idx}]${err.dataPath}`;
  20. if (err.children) {
  21. err.children.forEach(applyPrefix);
  22. }
  23. };
  24. list.forEach(applyPrefix);
  25. });
  26. return errors.reduce((arr, items) => {
  27. return arr.concat(items);
  28. }, []);
  29. } else {
  30. return validateObject(schema, options);
  31. }
  32. };
  33. const validateObject = (schema, options) => {
  34. const validate = ajv.compile(schema);
  35. const valid = validate(options);
  36. return valid ? [] : filterErrors(validate.errors);
  37. };
  38. const filterErrors = errors => {
  39. let newErrors = [];
  40. for (const err of errors) {
  41. const dataPath = err.dataPath;
  42. let children = [];
  43. newErrors = newErrors.filter(oldError => {
  44. if (oldError.dataPath.includes(dataPath)) {
  45. if (oldError.children) {
  46. children = children.concat(oldError.children.slice(0));
  47. }
  48. oldError.children = undefined;
  49. children.push(oldError);
  50. return false;
  51. }
  52. return true;
  53. });
  54. if (children.length) {
  55. err.children = children;
  56. }
  57. newErrors.push(err);
  58. }
  59. return newErrors;
  60. };
  61. module.exports = validateSchema;