Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@dollarshaveclub/ember-validations
Advanced tools
npm install
bower install
ember build
The builds will be in the dist/
directory.
If you are using
ember-cli
you can add
ember-validations
to your package.json
:
"devDependencies": {
...
"ember-validations": "~ 2.0.0"
}
You may want to be more precise with your version locking.
We will continue to build EmberValidations
to the DockYard build
server until ember-cli
is officially recommended by Ember. You can
select a build version from:
http://builds.dockyard.com for use in
Bower.
If it is a bug please open an issue on GitHub.
You need to mixin EmberValidations
into any Ember.Object
you want to add
validations to:
import Ember from 'ember';
import EmberValidations from 'ember-validations';
export default Ember.Controller.extend(EmberValidations);
You define your validations as a JSON object. They should be added to
the controller that represents the model in question.
The keys in the object should map to properties. If you pass a
JSON object as the value this will be seen as validation rules to apply
to the property. If you pass true
then the property itself will be
seen as a validatable object.
import Ember from 'ember';
import EmberValidations from 'ember-validations';
export default Ember.Controller.extend(EmberValidations, {
validations: {
'model.firstName': {
presence: true,
length: { minimum: 5 }
},
'model.age': {
numericality: true
},
'model.profile': true
}
});
Though not yet explicitly part of the API, you can also add validators to nested objects:
import Ember from 'ember';
import EmberValidations from 'ember-validations';
export default Ember.Component.extend(EmberValidations, {
validations: {
'user.firstName': {
presence: true,
length: { minimum: 5 }
}
}
});
This is useful for things like Components which don't act as proxies, but again, until this is officially built into the project, YMMV.
Note: If you override the init function, you must call _super()
import Ember from 'ember';
import EmberValidations from 'ember-validations';
export default Ember.Controller.extend(EmberValidations, {
init: function() {
// this call is necessary, don't forget it!
this._super.apply(this, arguments);
// Your init code...
}
});
Validates the property has a value that is null
, undefined
, or ''
true
- Passing just true
will activate validation and use default messagemessage
- Any string you wish to be the error message. Overrides i18n
.// Examples
absence: true
absence: { message: 'must be blank' }
By default the values '1'
, 1
, and true
are the acceptable values
true
- Passing just true
will activate validation and use default messagemessage
- Any string you wish to be the error message. Overrides i18n
.accept
- the value for acceptance// Examples
acceptance: true
acceptance: { message: 'you must accept', accept: 'yes' }
Expects a propertyConfirmation
to have the same value as
property
. The validation must be applied to the property
, not the propertyConfirmation
(otherwise it would expect a propertyConfirmationConfirmation
).
true
- Passing just true
will activate validation and use default messagemessage
- Any string you wish to be the error message. Overrides i18n
.// Examples
confirmation: true
confirmation: { message: 'you must confirm' }
A list of values that are not allowed
message
- Any string you wish to be the error message. Overrides i18n
.allowBlank
- If true
skips validation if value is emptyin
- An array of values that are excludedrange
- an array with the first element as the lower bound the and second element as the upper bound. Any value that falls within the range will be considered excluded// Examples
exclusion: { in: ['Yellow', 'Black', 'Red'] }
exclusion: { range: [5, 10], allowBlank: true, message: 'cannot be between 5 and 10' }
A regular expression to test with the value
message
- Any string you wish to be the error message. Overrides i18n
.allowBlank
- If true
skips validation if value is emptywith
- The regular expression to test with// Examples
format: { with: /^([a-zA-Z]|\d)+$/, allowBlank: true, message: 'must be letters and numbers only' }
A list of the only values allowed
message
- Any string you wish to be the error message. Overrides i18n
.allowBlank
- If true
skips validation if value is emptyin
- An array of values that are allowedrange
- an array with the first element as the lower bound the and
second element as the upper bound. Only values that fall within the range will be considered allowed// Examples
inclusion: { in: ['Yellow', 'Black', 'Red'] }
inclusion: { range: [5, 10], allowBlank: true, message: 'must be between 5 and 10' }
Define the lengths that are allowed
number
- Alias for is
array
- Will expand to minimum
and maximum
. First element is the lower bound, second element is the upper bound.allowBlank
- If true
skips validation if value is emptyminimum
- The minimum length of the value allowedmaximum
- The maximum length of the value allowedis
- The exact length of the value allowedtokenizer
- A function that should return a object that responds to length
tooShort
- the message used when the minimum
validation fails. Overrides i18n
tooLong
- the message used when the maximum
validation fails. Overrides i18n
wrongLength
- the message used when the is
validation fails. Overrides i18n
// Examples
length: 5
length: [3, 5]
length: { is: 10, allowBlank: true }
length: { minimum: 3, maximum: 5, messages: { tooShort: 'should be more than 3 characters', tooLong: 'should be less than 5 characters' } }
length: { is: 5, tokenizer: function(value) { return value.split(''); } }
Will ensure the value is a number
true
- Passing just true
will activate validation and use default messageallowBlank
- If true
skips validation if value is emptyonlyInteger
- Will only allow integersgreaterThan
- Ensures the value is greater thangreaterThanOrEqualTo
- Ensures the value is greater than or equal toequalTo
- Ensures the value is equal tolessThan
- Ensures the value is less thanlessThanOrEqualTo
- Ensures the value is less than or equal toodd
- Ensures the value is oddeven
- Ensures the value is evennumericality
- Message used when value failes to be a number. Overrides i18n
onlyInteger
- Message used when value failes to be an integer. Overrides i18n
greaterThan
- Message used when value failes to be greater than. Overrides i18n
greaterThanOrEqualTo
- Message used when value failes to be greater than or equal to. Overrides i18n
equalTo
- Message used when value failes to be equal to. Overrides i18n
lessThan
- Message used when value failes to be less than. Overrides i18n
lessThanOrEqualTo
- Message used when value failes to be less than or equal to. Overrides i18n
odd
- Message used when value failes to be odd. Overrides i18n
even
- Message used when value failes to be even. Overrides i18n
// Examples
numericality: true
numericality: { messages: { numericality: 'must be a number' } }
numericality: { odd: true, messages: { odd: 'must be an odd number' } }
numericality: { onlyInteger: true, greaterThan: 5, lessThanOrEqualTo : 10 }
Validates the property has a value that is not null
, undefined
, or ''
true
- Passing just true
will activate validation and use default messagemessage
- Any string you wish to be the error message. Overrides i18n
.// Examples
presence: true
presence: { message: 'must not be blank' }
Not yet implemented.
Each validator can take an if
or an unless
in its options
hash.
The value of the conditional can be an inline function, a string that
represents a property on the object, or a string that represents a
function on the object. The result should be a boolean.
note that if
is considered a keyword in IE8 and so you should put it
in quotes
// function form
'model.firstName': {
presence: {
'if': function(object, validator) {
return true;
}
}
}
// string form
// if 'canValidate' is a function on the object it will be called
// if 'canValidate' is a property object.get('canValidate') will be called
'model.firstName': {
presence: {
unless: 'canValidate'
}
}
You can place your custom validators into
my-app/app/validators/{local,remote}/<name>
:
import Base from 'ember-validations/validators/base';
export default Base.extend({
// ...
});
It is recommended that you separate between local
and remote
validators. However, if you wish you can place your validator into
my-app/app/validators/<name>
. However, any similarly named validator
in local/
or remote/
has a higher lookup presedence over those in
validators/
.
The "native" validators that come with ember-validations
have the
lowest lookup priority.
You can add your validators to the global object:
EmberValidations.validators.local.<ClassName> =
EmberValidations.validators.Base.extend({
// ...
});
To create a new validator you need to override the call
function. When
the validator is run its call
function is what handles determining if
the validator is valid or not. Call has access to this.model
,
this.property
. If the validation fails you must push the failing
message onto the validator's this.validationErrors
array. A simple example of a
validator could be:
import Base from 'ember-validations/validators/base';
import Ember from 'ember';
export default Base.extend({
call: function() {
if (Ember.isBlank(this.model.get(this.property))) {
this.validationErrors.pushObject("cannot be blank");
}
}
});
You may want to create a more complex validator that can observer for
changes on multiple properties. You should override the init
function
to accomplish this:
import Base from 'ember-validations/validators/base';
import Ember from 'ember';
export default Base.extend({
init: function() {
// this call is necessary, don't forget it!
this._super();
this.dependentValidationKeys.pushObject(this.options.alsoWatch);
},
call: function() {
if (Ember.isBlank(this.model.get(this.property))) {
this.validationErrors.pushObject("cannot be blank");
}
}
});
The init
function is given access to the this.options
wich is simply
a POJO of the options passed to the validator.
dependentValidationKeys
is the collection of paths relative to
this.model
that will be observed for changes. If any changes occur on
any given path the validator will automatically trigger.
If you want to create validators inline you can use the
validator
function that is part of the ember-validations
export:
import EmberValidations, { validator } from 'ember-validations';
User.create({
validations: {
'model.name': {
inline: validator(function() {
if (this.model.get('canNotDoSomething')) {
return "you can't do this!"
}
})
}
}
});
Inside the validator
function you have access to this.model
which is
a reference to the model. You must return an error message that will
be attached to the errors array for the property it is created on.
Return nothing for the validator to pass.
Alternatively if the property doesn't have any additional validations you can use a more concise syntax:
User.create({
validations: {
'model.name': EmberValidations.validator(function() {
if (this.model.get('canNotDoSomething')) {
return "you can't do this!"
}
})
}
});
Validations will automatically run when the object is created and when
each property changes. isValid
states bubble up and help define the
direct parent's validation state. isInvalid
is also available for convenience.
If you want to force all validations to run simply call .validate()
on the object. isValid
will be set to true
or false
. All validations are run as deferred objects, so the validations will
not be completed when validate
is done. So validate
returns a promise, call then
with a function containing the code you want to run after the validations have successfully
completed.
user.validate().then(function() {
// all validations pass
user.get('isValid'); // true
}).catch(function() {
// any validations fail
user.get('isValid'); // false
}).finally(function() {
// all validations complete
// regardless of isValid state
user.get('isValid'); // true || false
});
After mixing in EmberValidations
into your object it will now have a
.validationErrors
object. All validation error messages will be placed in there
for the corresponding property. Errors messages will always be an array.
import Ember from 'ember';
import EmberValidations from 'ember-validations';
export default Ember.Object.extend(EmberValidations, {
validations: {
'model.firstName': { presence: true }
}
});
import User from 'my-app/models/user';
user = User.create();
user.validate().then(null, function() {
user.get('isValid'); // false
user.get('validationErrors.firstName'); // ["can't be blank"]
user.set('firstName', 'Brian');
user.validate().then(function() {
user.get('isValid'); // true
user.get('validationErrors.firstName'); // []
})
})
For Ember Validations to work with Ember QUnit,
you must define all your validations in the needs
property of the moduleFor
call. This will ensure Ember QUnit's isolated container will be able to locate
the validations during testing.
import { test, moduleFor } from 'ember-qunit';
moduleFor('controller:user/edit', 'UserEditController', {
needs: ['service:validations',
'ember-validations@validator:local/presence',
'ember-validations@validator:local/length',
'validator:local/name',
'validator:local/email'
]
});
test('Controller Test', function() { ... });
Where UserEditController
uses the built-in presence
and length
validators,
and the locally defined name
and email
validators.
To test whether your Ember validations are working correctly, you can use the test helpers:
testValidPropertyValues(propertyName, values [, context ])
testInvalidPropertyValues(propertyName, values [, context ])
propertyName
(String): the property that you are validating.values
(Array): an array of property values to check.context
(function) optional: if specified, this function will be
called with the object under test as an argument. See example below.import { test, moduleFor } from 'ember-qunit';
import {
testValidPropertyValues,
testInvalidPropertyValues
} from '../../helpers/validate-properties';
moduleFor('controller:user', 'UserController', {
needs: ['ember-validations@validator:local/presence',
'ember-validations@validator:local/length'
]
});
testValidPropertyValues('firstName', ['Winston', '12345']);
testInvalidPropertyValues('firstName', ['abc', '', null, undefined]);
If a property's validation relies on another property, you can pass a context to the test helper:
testValidPropertyValues('lastName', ['Dog', '12345'], function(subject) {
subject.set('firstName', 'Boomer');
});
testValidPropertyValues('lastName', ['', null, undefined], function(subject) {
subject.set('firstName', null);
});
When you use ember-i18n your Ember.I18n.translations
object should contain the following keys under the errors
key:
Ember.I18n.translations = {
errors: {
inclusion: "is not included in the list",
exclusion: "is reserved",
invalid: "is invalid",
confirmation: "doesn't match {{attribute}}",
accepted: "must be accepted",
empty: "can't be empty",
blank: "can't be blank",
present: "must be blank",
tooLong: "is too long (maximum is {{count}} characters)",
tooShort: "is too short (minimum is {{count}} characters)",
wrongLength: "is the wrong length (should be {{count}} characters)",
notANumber: "is not a number",
notAnInteger: "must be an integer",
greaterThan: "must be greater than {{count}}",
greaterThanOrEqualTo: "must be greater than or equal to {{count}}",
equalTo: "must be equal to {{count}}",
lessThan: "must be less than {{count}}",
lessThanOrEqualTo: "must be less than or equal to {{count}}",
otherThan: "must be other than {{count}}",
odd: "must be odd",
even: "must be even"
}
}
We are very thankful for the many contributors
This library follows Semantic Versioning
Please do! We are always looking to improve this library. Please see our Contribution Guidelines on how to properly submit issues and pull requests.
DockYard, LLC © 2013
FAQs
Validations for Ember Objects
The npm package @dollarshaveclub/ember-validations receives a total of 0 weekly downloads. As such, @dollarshaveclub/ember-validations popularity was classified as not popular.
We found that @dollarshaveclub/ember-validations demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.