Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Validation {
- constructor(data) {
- this._data = data;
- this._valid = true;
- this._skip = false; // Flag to skip validation until next .expect() or .go()
- this._errors = []; // Store errors here
- this._keys = []; // Store invalid keys here
- }
- // Store checked value in this._value for chained checking
- _get() {
- if (typeof this._data[this._key] !== 'undefined') return this._data[this._key];
- let parts = this._key.split('.'),
- value = this._data;
- for (let i = 0; i < parts.length; i++) {
- try {
- value = value[parts[i]];
- } catch(e) {
- return void 0;
- }
- if (typeof value === 'undefined') return void 0;
- }
- return value;
- }
- // Push error object into this._errors
- _add(message) {
- this._errors.push({ path: this._key, message: message });
- this._keys.push(this._key);
- if (this._valid) this._valid = false;
- return this;
- }
- // Helper to find out if a particular key has already been invalidated
- _already() {
- return this._keys.indexOf(this._key) !== -1;
- }
- // Start validation chain for a key, store key in this._key
- expect(key) {
- if ([ 'string', 'number', 'boolean' ].indexOf(typeof key) === -1)
- throw new Error('Validation key in .expect() must be a either a string, a number, or a boolean');
- if (this._already()) {
- this._skip = true;
- return this;
- }
- this._skip = false;
- this._optional = false;
- this._nullable = false;
- this._key = key;
- this._value = this._get();
- return this;
- }
- present(message) {
- if (this._skip) return this;
- if (this._already()) return this;
- if (typeof this._key === 'undefined') throw new Error('Must call .expect() before .present()');
- if (this._optional) throw new Error('Cannot call .present() after .optional()');
- if (typeof message === 'undefined') message = 'This is a required parameter';
- if (typeof this._value === 'undefined') this._add(message);
- return this;
- }
- string(message) {
- if (this._skip) return this;
- if (this._already()) return this;
- if (typeof this._key === 'undefined') throw new Error('Must call .expect() before .string()');
- if (this._optional && typeof this._value === 'undefined') return this;
- if (this._nullable && this._value === null) return this;
- if (typeof message === 'undefined') message = 'The parameter must be a string';
- if (typeof this._value !== 'string') this._add(message);
- return this;
- }
- go(handler) {
- if (typeof handler !== 'function') throw new Error('Handler in .go() must be a function');
- if (!this._valid) {
- let error = new Error('Validation Error');
- error.name = 'ValidationError';
- error.errors = this._errors;
- return process.nextTick(handler, error);
- }
- process.nextTick(handler);
- }
- }
- const validate = data => new Validation(data);
- validate({ name: { last: 'foo' }})
- .expect('name.first').present().string() // Duplicate this line ~2000 times for error
- .go(console.log);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement