-
-
Save sivakumar-kailasam/46a149198ecaad34d31d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
var get = Ember.get; | |
var keys = Ember.keys; | |
var isNone = Ember.isNone; | |
/** | |
* Computed Property Macro returns computed property that evaluates to result of validation. | |
* | |
* It accepts rules hash which property name as keys and validation functions as values. | |
* | |
* ```javascript | |
* var controller = Ember.Controller.extend({ | |
* name: null, | |
* date: null, | |
* validation: validation({ | |
* name: function(value) { | |
* return validation.required(value); | |
* }, | |
* date: function(date) { | |
* return validation.date(date); | |
* } | |
* }) | |
* }); | |
* ``` | |
* | |
* Result of validation is an object with the following signature | |
* | |
* { | |
* <propertyName>: { | |
* isPassed: <boolean>, | |
* error: <string> // error that was returned as a result of failed validation | |
* value: <mixed> // value that was validated | |
* } | |
* ... | |
* } | |
* | |
* @param {Object} rules | |
* @returns {Ember.ComputedProperty} | |
*/ | |
function validation(rules) { | |
// create array of dependent keys | |
var dependentKeys = keys(rules); | |
var isPassedKeys = keys(rules).map(function (propName) { | |
return '%@.%@'.fmt(propName, 'isPassed'); | |
}); | |
var ValidationResponse = Ember.ObjectProxy.extend(Ember.PromiseProxyMixin, { | |
isPassed: Ember.computed.and.apply(this, isPassedKeys), | |
isFailed: Ember.computed.not('isPassed') | |
}); | |
function buildValidationPromise() { | |
var _this = this; | |
var promises = {}; | |
keys(rules).forEach(function (propName) { | |
var callback = rules[propName]; | |
var value = get(_this, propName); | |
// coerce the return values into being a promise | |
promises[propName] = new Ember.RSVP.Promise(function (resolve) { | |
resolve(callback.call(_this, value)); | |
}); | |
}); | |
function updateIsValidating(value) { | |
return function (result) { | |
_this.set('isValidating', value); | |
return result; | |
}; | |
} | |
function transform(response) { | |
keys(response).forEach(function (propName) { | |
var result = response[propName]; | |
// TODO: does need to read the return value to figure out if tests? | |
response[propName] = { | |
isPassed: get(result, 'state') === 'fulfilled', | |
error: get(result, 'state') === 'rejected' ? get(result, 'reason') : null, | |
value: get(_this, propName) | |
}; | |
}); | |
return response; | |
} | |
return ValidationResponse.create({ | |
promise: Ember.RSVP.hashSettled(promises).then(transform).finally(updateIsValidating(false)), | |
target: this, | |
isValidating: true | |
}); | |
} | |
return applyComputed(dependentKeys, buildValidationPromise); | |
} | |
function applyComputed(dependentKeys, callback) { | |
return Ember.computed.apply(this, [].concat(dependentKeys, [callback])); | |
} | |
var requiredRegex = /([^\s])/; | |
var urlRegex = /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i; | |
var emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; | |
var dateISORegex = /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/; | |
var numberRegex = /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/; | |
var slugRegex = /^[0-9a-zA-Z-_]+$/; | |
var required = makeFormat(requiredRegex, "Must not be empty."); | |
var url = makeFormat(urlRegex, "Must be a url and start with http://"); | |
var email = makeFormat(emailRegex, "Must be an email address"); | |
var dateISO = makeFormat(dateISORegex, "Must be in date ISO makeFormat"); | |
var number = makeFormat(numberRegex, "Must be a number"); | |
var slug = makeFormat(slugRegex, "May contain only numbers, letters, dash or underscore."); | |
function date(value, message) { | |
if (isNone(message)) { | |
message = "Must be a valid date."; | |
} | |
var passed = !/Invalid|NaN/.test(new Date(value).toString()); | |
if (passed) { | |
return value; | |
} | |
throw message; | |
} | |
export function makeFormat(regex, defaultMessage) { | |
return function(value, message) { | |
if (isNone(message)) { | |
message = defaultMessage; | |
} | |
if (!isNone(value) && regex.test(value)) { | |
return value; | |
} | |
throw message; | |
}; | |
} | |
validation.required = required; | |
validation.url = url; | |
validation.email = email; | |
validation.dateISO = dateISO; | |
validation.number = number; | |
validation.slug = slug; | |
validation.date = date; | |
export default validation; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment