Shadow Schema
Shadow Schema is functional schema that use Shadow Collections.
Example
1Example = new Mongo.Collection('example'); 2 3Example.schema({ 4 typed: function (value) { 5 if (_.isString(value)) { 6 return this.valid('is a string') 7 } else { 8 return this.invalid('must be a string') 9 } 10 }, 11 explicit: function (value) { 12 if (value === 'Jane') { 13 return this.valid('is Jane') 14 } else { 15 return this.invalid('must be Jane') 16 } 17 }, 18 generic: function (value) { 19 try { 20 //can be an array or {lat: Number, lng: Number} 21 var latLng = L.latLng(value); 22 if (_.isNumber(latLng.lat) && _.isNumber(latLng.lng)) { 23 return this.invalid('is Geo Location') 24 } else { 25 return this.invalid('must have both latitude and longitude') 26 } 27 } catch (e) { 28 return this.invalid('must be a valid GeoLocaton') 29 } 30 }, 31 descriptive: function (value) { 32 var email = someEmailValidator(value) //readme shortcut -_^ 33 if (email) { 34 if (email == 'gmail') { 35 return this.valid('is a Gmail email') 36 } else if (email == 'apple') { 37 return this.valid('is an Apple email') 38 } else { //and so on 39 return this.valid('is email') 40 } 41 } else { 42 return this.invalid('must be an email') //you would want to be more descriptive... 43 } 44 }, 45 'nested.properties': function (value) { 46 if (value) { //you may wish to type check booleans to save db space 47 return this.valid('is true') 48 } else { 49 return this.invalid('must be true') 50 } 51 }, 52 //other features, pass an object for more options 53 'with.default': { 54 validation: function () { //normal validations function 55 return this.valid('anything goes') 56 }, 57 default: 42 //this is not used in the schema, its just on option for other packages 58 }, 59 'auto.values': { 60 auto: function () { //run AFTER validations on insert/updates 61 if (Meteor.isServer) { //will run on client and then server if called from client 62 return new Date(); //good for createdAt values 63 } 64 } 65 } 66})
1var exampleId = Example.insert({ 2 typed: 'a string', 3 explicit: 'Joe', 4 generic: {lat: 60, lng: 60}, 5 descriptive: 'example@icloud.com' 6 nested = { 7 properties: true 8 } 9}); 10var example = Example.findOne(exampleId) 11 12example.$validate('typed'); 13//{valid: true, message: "is a string"} 14 15example.$validate('explicit'); 16//{valid: false, message: "must be Jane"} 17 18example.$validate('generic'); 19//{valid: true, message: "is Geo Location"} 20 21example.$validate('descriptive'); 22//{valid: true, message: "is an Apple email"} 23 24example.$validate('nested.properties'); 25//{valid: true, message: "is true"} 26 27 28example.$validate(); //returns an object with all the values