Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bmi3-schema-validator

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bmi3-schema-validator - npm Package Compare versions

Comparing version 1.0.3 to 1.1.0

57

lib/classes/Validator.js

@@ -10,3 +10,4 @@ const typesMap = new Map([

[ Array, 'an Array' ],
[ NaN, 'a NaN' ]
[ NaN, 'a NaN' ],
[ Function, 'a Function' ]
]);

@@ -23,6 +24,7 @@

class Validator {
constructor(schema, strict = false) {
constructor(schema, strict = false, def = false) {
this.schema = schema;
this.types = typesMap;
this.strict = strict;
this.default = def;
}

@@ -35,2 +37,17 @@

/**
* Поле — тип, или что-то сложнее?
* @param {Mixed} property поле
* @return {Boolean} результат проверки типа. Будет true, если тип один из спика, или если он валидатор, или если он конструктор
*/
isType(property) {
return this.types.has(property) || (typeof property === 'function');
}
getTypeName(property) {
const name = this.types.get(property);
if (name) return name;
return property.name;
}
/**
* Определяет, является узел схемы плоским или нет

@@ -41,3 +58,3 @@ * @param {Mixed} property узел для провеки

isFlat(property, recursive = false) {
if (this.types.has(property)) {
if (this.isType(property)) {
return {

@@ -53,4 +70,4 @@ required: false,

}
if (property.hasOwnProperty('type') && this.types.has(property.type)) {
return {
if (property.hasOwnProperty('type') && this.isType(property.type)) {
const flat = {
type: property.type,

@@ -63,3 +80,7 @@ required: !!property.required,

exclude: property.exclude || null
};
}
if (property.hasOwnProperty('default')) {
flat.default = property.default
}
return flat;
}

@@ -152,3 +173,2 @@ if (Array.isArray(property)) {

if (isRequiredExclude) required = isRequiredExclude;
if (required) {

@@ -159,2 +179,6 @@ if (type !== null && type !== undefined) {

} else if (value === undefined) {
if (this.default && options.hasOwnProperty('default')) {
// Это хак, дальше в коде на основе этого мы зададим default в свойство
return false;
}
return true;

@@ -190,5 +214,12 @@ }

if (type === Boolean) return typeof value === 'boolean';
if (type === Function) return typeof value === 'function';
if (type === Date) return value instanceof Date;
if (type === Object) return value instanceof Object;
if (type === Array) return Array.isArray(value);
if (typeof type === 'function') {
if (type.isValidator) {
return type(value, level, options);
}
return value instanceof type;
}
// Такие правила

@@ -237,2 +268,10 @@ if (isNaN(type)) return typeof value !== 'number';

}
if (this.default && !isValid && flat.hasOwnProperty('default')) {
if (typeof flat.default === 'function') {
level[key] = flat.default();
} else {
level[key] = flat.default;
}
isValid = true;
}
if (!isValid) {

@@ -242,5 +281,5 @@ const isInclude = (flat.include ? ` Required properties: ${flat.include.join(', ')};` : ``);

const isEnum = (flat.enum ? ` Property is enumerable [${flat.enum.join(', ')}];` : ``);
let isRequired = (flat.required ? ` Property is required; Type of property should be ${this.types.get(flat.type)};` : ` Type of property should be ${this.types.get(flat.type)};`);
let isRequired = (flat.required ? ` Property is required; Type of property should be ${this.getTypeName(flat.type)};` : ` Type of property should be ${this.getTypeName(flat.type)};`);
if (Array.isArray(schema)) {
isRequired = (flat.required ? ` Property is required; Type of property should be an Array of ${this.types.get(flat.type)};` : ` Type of property should be an Array of ${this.types.get(flat.type)};`);
isRequired = (flat.required ? ` Property is required; Type of property should be an Array of ${this.getTypeName(flat.type)};` : ` Type of property should be an Array of ${this.getTypeName(flat.type)};`);
}

@@ -247,0 +286,0 @@ const isRequiredInclude = (flat.requiredExclude ? ` Property is required if object level include ${flat.requiredInclude}` : ``);

2

package.json
{
"name": "bmi3-schema-validator",
"version": "1.0.3",
"version": "1.1.0",
"description": "Simple validation library for bmi3 interpreter",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -100,3 +100,4 @@ # bmi3-schema-validator

[ Array, 'an Array' ],
[ NaN, 'a NaN' ]
[ NaN, 'a NaN' ],
[ Function, 'a Function' ]
]);

@@ -153,6 +154,64 @@ ```

## Расширение валидации
## Расширение функционала
Если вы хотите добавить дополнительную логику в ваш валидатор, можно просто применить простое наследование:
### Экземпляр класса
Вы можете указать любую функцию-конструктор в качестве типа. По умолчанию валидатор проверит соответствие через `instanceof`, так что для экземпляров наследников конструктора валидация тоже будет проходить:
```javascript
class User {
constructor(name, lastname) {
this.name = name;
this.lastname = lastname;
}
}
const validator = new Validator({
user: {
type: User,
required: true
},
orderId: {
type: Number,
required: true
}
});
validator.validateSync({
user: new User('Вася', 'Петров'),
orderId: 12
});
```
### Тип-валидатор
Иногда валидировать по тому, является поле наследником класса или нет — недостаточно, тогда можно реализовать тип-валидатор. Это просто функция, для которой мы дополнительно задаем поле `isValidator` как true.
Допустим нам нужно, чтобы у User всегда было задано поле name:
```javascript
function UserType(value, level, options) {
return value instanceof User && value.name && typeof value.name === 'string';
}
```
В `level` лежит тот узел, который мы сейчас рассматриваем — т. е. текущее поле в окружении соседних.
```javascript
{
sublevel: {
age: Number,
gender: {
type: String,
enum: ['male', 'female']
},
hair: String
},
name: String
}
Для `name` это будет `sublevel`, а для `age` — `gender` и `hair`, т. е. это тот объект или подобъект, поле которого сейчас проверяется.
```
В `options` будут лежать модификаторы, для узла, такие как `required` и т. п.
### Наследование
Допустим этого не достаточно и вы хотите добавить дополнительную логику в валидатор, можно просто применить простое наследование нового валидатора от старого:
```javascript
class MyValidator extends Validator {

@@ -173,3 +232,43 @@ validateSync(level, schema, depth = 0, path = '', buffer = []) {

## Значения по-умолчанию
Третьим параметром в конструктор можно передать флаг «Проверяй модификатор `default` и наполняй проверяемый объект».
Т. е. если поставить его в `true` или записать `validator.default = true` при проверке будет происходить подстановка значений из модификатора `default`, если валидация не прошла или поля вообще нет.
Пример:
```javascript
const validator = Validator({
name: {
type: String,
default: 'Нет имени'
},
card: {
type: Number,
default: 12345,
required: true
},
date: {
type: Date,
default: Date
}
}, false, true) // Третий параметр, поставили validator.default в true
const data = {
card: 1
}
validator.validateSync(data);
/**
* data.name —> "Нет имени"
* data.number -> 1
* data.date —> Date()
*/
```
Обратите внимание, что если в качестве значения по-умолчанию передать функцию, будет записан её результат
## Лицензия
MIT. Никакие гарантии на библиотеку не распространяются, она предоставляется как есть.

@@ -59,1 +59,71 @@ /*global test expect */

});
const defaultSchema = {
name: {
type: String,
default: 'Петя'
},
card: {
type: Number,
default: 12345,
required: true
},
date: {
type: Date,
default: Date
}
}
test('Валиданя с default', () => {
const validator = new Validator(defaultSchema, false, true);
const data = {
card: 1
}
validator.validateSync(data);
expect(data).toEqual({
name: 'Петя',
card: 1,
date: Date()
});
});
test('Валиданя с default', () => {
const validator = new Validator(defaultSchema, false, true);
const data = {}
validator.validateSync(data);
expect(data).toEqual({
name: 'Петя',
card: 12345,
date: Date()
});
});
test('Валидная схема c типом-классом', () => {
function A() { this.hello = 'world' }
const validator = new Validator({
a: {
required: true,
type: A
}
});
expect(validator.validateSync({ a: new A() })).toBe(undefined);
});
test('Валидная схема c типом-функцией', () => {
function A(prop) { this.hello = prop || 'world' }
function B(value) {
return value && value.hello === 'world'
}
B.isValidator = true;
const validator = new Validator({
a: {
required: true,
type: B
},
b: {
required: true,
type: NaN
}
});
expect(validator.validateSync({ a: new A(), b: 'Привет' })).toBe(undefined);
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc