lynx-framework
Version:
lynx is a NodeJS framework for Web Development, based on decorators and the async/await support.
316 lines (314 loc) • 18.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidateObject = exports.SchemaBuilder = void 0;
var Joi = require("joi");
var itErrors = require("./locale/joi_it");
/**
* SchemaBuilder for the Joi validator.
* It exposes some facility methods for some simple task,
* and it also allows a complete personalization of the final result.
*/
var SchemaBuilder = /** @class */ (function () {
function SchemaBuilder() {
this.keys = {};
}
/**
* Generate the final Joi Object Schema
*/
SchemaBuilder.prototype.build = function () {
return Joi.object().keys(this.keys);
};
/**
* General method, that can be used with the Joi functions
*/
SchemaBuilder.prototype.general = function (key, spec) {
this.keys[key] = spec;
this.lastKey = key;
return this;
};
/**
* Add an optional string to the Schema
* @param key the key
* @param min minimum length of the string
* @param max maximum length of the string
* @return the schema builder
*/
SchemaBuilder.prototype.stringOptional = function (key, min, max) {
var tmp = Joi.string();
if (min !== undefined) {
tmp = tmp.min(min);
}
else {
tmp = tmp.allow('');
}
if (max !== undefined) {
tmp = tmp.max(max);
}
this.keys[key] = tmp;
this.lastKey = key;
return this;
};
/**
* Add a required string to the Schema
* @param key the key
* @param min minimum length of the string
* @param max maximum length of the string
* @return the schema builder
*/
SchemaBuilder.prototype.string = function (key, min, max) {
this.stringOptional(key, min, max);
this.keys[key] = this.keys[key].required();
this.lastKey = key;
return this;
};
/**
* Add a required email to the Schema
* @param key the key
* @return the schema builder
*/
SchemaBuilder.prototype.email = function (key) {
this.keys[key] = Joi.string().email().required();
this.lastKey = key;
return this;
};
/**
* Add an optional email to the Schema
* @param key the key
* @return the schema builder
*/
SchemaBuilder.prototype.emailOptional = function (key) {
this.keys[key] = Joi.string().email();
this.lastKey = key;
return this;
};
/**
* Add a required password to the Schema.
* The password will be validated using the following regex:
* ^[0-9a-zA-Z\|\!\"\£\$\%\&\/\(\)\=\?\^\,\;\.\:\-\_\\\~]{6,}$
* @param key the key
* @return the schema builder
*/
SchemaBuilder.prototype.password = function (key) {
this.keys[key] = Joi.string()
.regex(/^[0-9a-zA-Z\|\!\"\£\$\%\&\/\(\)\=\?\^\,\;\.\:\-\_\\\~]{6,}$/)
.required();
return this;
};
/**
* Add an optional password to the Schema.
* The password will be validated using the following regex:
* ^[0-9a-zA-Z\|\!\"\£\$\%\&\/\(\)\=\?\^\,\;\.\:\-\_\\\~]{6,}$
* @param key the key
* @return the schema builder
*/
SchemaBuilder.prototype.passwordOptional = function (key) {
this.keys[key] = Joi.string().regex(/^[0-9a-zA-Z\|\!\"\£\$\%\&\/\(\)\=\?\^\,\;\.\:\-\_\\\~]{6,}$/);
return this;
};
/**
* Add an optional number to the Schema
* @param key the key
* @param min minimum value of the number
* @param max maximum value of the number
* @return the schema builder
*/
SchemaBuilder.prototype.numberOptional = function (key, min, max) {
var tmp = Joi.number();
if (min !== undefined) {
tmp = tmp.min(min);
}
if (max !== undefined) {
tmp = tmp.max(max);
}
this.keys[key] = tmp;
this.lastKey = key;
return this;
};
/**
* Add a required number to the Schema
* @param key the key
* @param min minimum value of the number
* @param max maximum value of the number
* @return the schema builder
*/
SchemaBuilder.prototype.number = function (key, min, max) {
this.numberOptional(key, min, max);
this.keys[key] = this.keys[key].required();
this.lastKey = key;
return this;
};
/**
* Add an optional integer number to the Schema
* @param key the key
* @param min minimum value of the number
* @param max maximum value of the number
* @return the schema builder
*/
SchemaBuilder.prototype.integerOptional = function (key, min, max) {
var tmp = Joi.number().integer();
if (min !== undefined) {
tmp = tmp.min(min);
}
if (max !== undefined) {
tmp = tmp.max(max);
}
this.keys[key] = tmp;
this.lastKey = key;
return this;
};
/**
* Add a required integer number to the Schema
* @param key the key
* @param min minimum value of the number
* @param max maximum value of the number
* @return the schema builder
*/
SchemaBuilder.prototype.integer = function (key, min, max) {
this.integerOptional(key, min, max);
this.keys[key] = this.keys[key].required();
this.lastKey = key;
return this;
};
/**
* Add an optional date to the Schema
* @param key the key
* @return the schema builder
*/
SchemaBuilder.prototype.dateOptional = function (key) {
this.keys[key] = Joi.date();
this.lastKey = key;
return this;
};
/**
* Add a required date to the Schema
* @param key the key
* @return the schema builder
*/
SchemaBuilder.prototype.date = function (key) {
this.keys[key] = Joi.date().required();
this.lastKey = key;
return this;
};
SchemaBuilder.prototype.arrayOfStrings = function (key) {
this.keys[key] = Joi.array().items(Joi.string());
this.lastKey = key;
return this;
};
SchemaBuilder.prototype.arrayOfStringsOptional = function (key) {
this.keys[key] = Joi.array().items(Joi.string());
this.lastKey = key;
return this;
};
/**
* Add the label to the last added key
* @param label the label to use in case of error
* @return the schema builder
*/
SchemaBuilder.prototype.withLabel = function (label) {
if (this.lastKey) {
this.keys[this.lastKey] = this.keys[this.lastKey].label(label);
}
return this;
};
return SchemaBuilder;
}());
exports.SchemaBuilder = SchemaBuilder;
/**
* This class is used to validate an object using a given schema.
* It is used by Lynx to automatically validate the body of any requests, using
* the Body decorator.
*/
var ValidateObject = /** @class */ (function () {
/**
* @param obj the object to validate
* @param schema the schema
* @param locales an array of available language. You can use the `req.acceptsLanguages()`
*/
function ValidateObject(obj, schema, locales) {
this._obj = obj;
this.schema = schema;
var options = null;
for (var _i = 0, locales_1 = locales; _i < locales_1.length; _i++) {
var locale = locales_1[_i];
if (locale.indexOf('en') != -1) {
break;
}
if (locale == 'it') {
options = {
language: itErrors.errors,
};
break;
}
}
this.validate(options);
}
ValidateObject.prototype.validate = function (options) {
this.valid = this.schema.validate(this._obj, options);
};
Object.defineProperty(ValidateObject.prototype, "isValid", {
/**
* Verify that the object respect the schema.
* @return true if the object is valid, false otherwise.
*/
get: function () {
return !this.valid.error;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ValidateObject.prototype, "obj", {
/**
* Unwrap the object (can be valid or not!)
* @return the unwrapped object
*/
get: function () {
return this._obj;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ValidateObject.prototype, "errors", {
/**
* Getter that returns an array of validation errors.
* @return an array of validation errors. It can not be null.
*/
get: function () {
var errors = [];
if (this.isValid) {
return errors;
}
if (this.valid.error) {
for (var _i = 0, _a = this.valid.error.details; _i < _a.length; _i++) {
var err = _a[_i];
errors.push({
name: err.context && err.context.key ? err.context.key : '',
message: err.message,
});
}
}
return errors;
},
enumerable: false,
configurable: true
});
Object.defineProperty(ValidateObject.prototype, "errorsMap", {
/**
* Getter that returns a map of errors. This prop contains the save information
* as the `errors` prop, but with a different format.
* @return a map or localized errors.
*/
get: function () {
var map = {};
for (var _i = 0, _a = this.errors; _i < _a.length; _i++) {
var err = _a[_i];
map[err.name] = err.message;
}
return map;
},
enumerable: false,
configurable: true
});
return ValidateObject;
}());
exports.ValidateObject = ValidateObject;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL2x5bngvdmFsaWRhdGUtb2JqZWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlCQUEyQjtBQUUzQiwwQ0FBNEM7QUFFNUM7Ozs7R0FJRztBQUNIO0lBR0k7UUFDSSxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQ7O09BRUc7SUFDSCw2QkFBSyxHQUFMO1FBQ0ksT0FBTyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCwrQkFBTyxHQUFQLFVBQVEsR0FBVyxFQUFFLElBQVM7UUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUM7UUFDbkIsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILHNDQUFjLEdBQWQsVUFBZSxHQUFXLEVBQUUsR0FBWSxFQUFFLEdBQVk7UUFDbEQsSUFBSSxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3ZCLElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRTtZQUNuQixHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUN0QjthQUFNO1lBQ0gsR0FBRyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDdkI7UUFDRCxJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUU7WUFDbkIsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDdEI7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUNyQixJQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQztRQUNuQixPQUFPLElBQUksQ0FBQztJ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