index.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. const Ajv = require('ajv')
  2. module.exports = (obj={}, inSchema, outSchema) => {
  3. if (!inSchema) throw new ReferenceError('input schema not defined')
  4. const inValidate = (new Ajv()).compile(inSchema)
  5. let outValidate;
  6. if (outSchema){
  7. outSchema = {...outSchema}
  8. outSchema.additionalProperties = false
  9. outValidate = (new Ajv()).compile(outSchema)
  10. }
  11. return new Proxy(obj, {
  12. get(obj, prop){
  13. if (outValidate && !outValidate(obj)){
  14. if (outValidate.errors.find(({instancePath}) => instancePath.slice(1).startsWith(prop)) ||
  15. (outValidate.errors[0].keyword === 'additionalProperties' && outValidate.errors[0].params.additionalProperty === prop)){
  16. return;
  17. }
  18. }
  19. return obj[prop]
  20. },
  21. set(obj, prop, value){
  22. const newObject = {...obj, [prop]: value}
  23. if (!inValidate(newObject)){
  24. throw new TypeError(JSON.stringify([inValidate.errors, prop, value], null, 4))
  25. }
  26. obj[prop] = value
  27. }
  28. })
  29. }
  30. const schema = {
  31. type: "object",
  32. properties: {
  33. foo: {type: "integer"},
  34. bar: {type: "string"}
  35. },
  36. required: ["foo"],
  37. additionalProperties: false
  38. }
  39. const outSchema = {
  40. type: "object",
  41. properties: {
  42. foo: {type: "integer"},
  43. },
  44. required: ["foo"],
  45. additionalProperties: false
  46. }
  47. let validated = module.exports({}, schema, outSchema)
  48. validated.foo = 5;
  49. validated.bar = "string";
  50. console.log(validated.foo)
  51. console.log(validated.bar)
  52. console.log({...validated})
  53. //validated.bar = 100500;