JavaScript модуль для работы со схемой данных
|
|
2 недель назад | |
|---|---|---|
| .husky | 3 недель назад | |
| dist | 2 недель назад | |
| src | 2 недель назад | |
| .c8rc | 3 недель назад | |
| .commitlintrc | 3 недель назад | |
| .editorconfig | 3 недель назад | |
| .gitignore | 3 недель назад | |
| .mocharc.json | 3 недель назад | |
| .prettierrc | 3 недель назад | |
| LICENSE | 3 недель назад | |
| README.md | 3 недель назад | |
| build-cjs.js | 3 недель назад | |
| eslint.config.js | 3 недель назад | |
| package.json | 3 недель назад | |
| tsconfig.json | 3 недель назад |
JavaScript модуль для работы со схемой данных.
npm install @e22m4u/js-data-schema
Модуль поддерживает ESM и CommonJS стандарты.
ESM
import {DataValidator} from '@e22m4u/js-data-schema';
CommonJS
const {DataValidator} = require('@e22m4u/js-data-schema');
Схема данных позволяет указать допустимый тип значения, схему элементов массива и схему свойств объекта. Схему можно использовать для проверки входящих данных или для преобразования данных к формату схемы.
Свойства схемы:
type тип данных (допускает пустые значения);items схема элементов массива, фабрика или имя
схемы;properties схема свойств объекта, фабрика или имя
схемы;required исключает пустые значения;default значение по умолчанию или фабрика;Параметр type определяет тип данных. При определении
типа можно использовать константу или название типа в виде строки.
Константы проверяются редакторами кода, что позволяет избежать опечаток
при вводе типа.
| константа | значение |
|---|---|
DataType.ANY |
"any" |
DataType.STRING |
"string" |
DataType.NUMBER |
"number" |
DataType.BOOLEAN |
"boolean" |
DataType.ARRAY |
"array" |
DataType.OBJECT |
"object" |
Параметр items позволяет указать схему для элементов
массива. Параметр можно использовать только если явно указан тип
array. В примере ниже схема массива включает описание его
элементов, которые должны соответствовать числовому типу.
{
type: DataType.ARRAY, // тип данных
items: {
type: DataType.NUMBER // тип элементов
}
}
// [-1, 0, 1, undefined, null]
Так как типы допускают пустые
значения, рекомендуется использовать параметр required
в определении схемы элемента, чтобы исключить такие значения из состава
массива.
{
type: DataType.ARRAY,
items: {
type: DataType.NUMBER,
required: true // исключает undefined, null и 0
}
}
// [-1, 1]
Параметр properties позволяет указать схему каждого
свойства объекта. Параметр можно использовать, только если явно указан
тип object. В примере ниже используется схема объекта с
двумя свойствами.
{
type: DataType.OBJECT, // тип данных
properties: {
name: {
type: DataType.STRING // тип свойства "name"
},
age: {
type: DataType.NUMBER // тип свойства "age"
}
}
}
// {
// "name": "John",
// "age": 27
// }
Значения свойств могут быть обязательными. Для этого используется
параметр required в схеме соответствующего свойства. Если
параметр указан, то пустые значения будут
вызывать ошибку при проверке свойства.
{
type: DataType.OBJECT,
properties: {
name: {
type: DataType.STRING,
required: true // исключает undefined, null и ""
},
age: {
type: DataType.NUMBER,
required: true // исключает undefined, null и 0
}
}
}
Так как по умолчанию все типы допускают пустые значения, параметр
required может быть полезен для явного их запрета при
проверке данных. Параметр можно использовать там, где указывается тип
данных.
{
type: DataType.STRING, // тип данных
required: true // исключает пустые значения
}
// "foo", "bar" ...
Значение по умолчанию можно указать в параметре default.
Указанное значение будет использовано, если исходное значение оказалось
пустым. Если значение параметра является
объектом или массивом, то итоговые данных получат его копию.
{
type: DataType.STRING, // тип данных
default: 'N/A' // значение по умолчанию
}
Модуль экспортирует сервис DataValidator, с помощью
которого выполняется проверка соответствия данных указанной схеме.
Пример ниже демонстрирует создание экземпляра сервиса и проверку
примитивных значений.
import {DataValidator, DataType} from '@e22m4u/js-data-schema';
const validator = new DataValidator();
const numberSchema = {type: DataType.NUMBER};
// OK
validator.validate(10, numberSchema);
validator.validate(0, numberSchema);
validator.validate(undefined, numberSchema);
validator.validate(null, numberSchema);
// выбросит DataValidationError
validator.validate('str', numberSchema);
validator.validate(true, numberSchema);
validator.validate([1, 2, 3], numberSchema);
validator.validate({foo: 'bar'}, numberSchema);
Каждый тип данных имеет собственный набор пустых значений, которые являются
допустимыми при проверке соответствующего типа. Чтобы исключить такие
значения применяется параметр required.
import {DataValidator, DataType} from '@e22m4u/js-data-schema';
const validator = new DataValidator();
const requiredNumberSchema = {
type: DataType.NUMBER,
required: true // исключает пустые значения
};
// OK
validator.validate(10, requiredNumberSchema);
validator.validate(-10, requiredNumberSchema);
// выбросит DataValidationError
validator.validate(0, requiredNumberSchema);
validator.validate(undefined, requiredNumberSchema);
validator.validate(null, requiredNumberSchema);
Сервис DataParser спроектирован для приведения данных в
соответствие указанной схеме. Приведение выполняется с учетом возможных
ошибок пользовательского ввода. К примеру, если схема ожидает число, но
входящие данные содержат другие символы, то будет выброшена ошибка.
import {DataParser, DataType} from '@e22m4u/js-data-schema';
const parser = new DataParser();
parser.parse('10', {type: DataType.NUMBER}); // 10
parser.parse('10.5', {type: DataType.NUMBER}); // 10.5
parser.parse('10abc', {type: DataType.NUMBER}); // DataParsingError
Массивы и объекты могут быть представлены в виде JSON. Метод
parse поддерживает данный формат и выполняет проверку
разобранного значения. К примеру, если элементы массива не соответствуют
определению схемы, то будет выброшена ошибка.
import {DataParser, DataType} from '@e22m4u/js-data-schema';
const parser = new DataParser();
const numberListSchema = {
type: DataType.ARRAY,
items: {
type: DataType.NUMBER,
required: true, // исключает undefined, null и 0
},
};
parser.parse('[1, 2, 3]', numberListSchema); // [1, 2, 3]
parser.parse('[1, 2, null]', numberListSchema); // DataParsingError
Если при разборе данных значение оказалось пустым, то при наличии параметра
default используется значение по умолчанию. Значение
данного параметра должно соответствовать схеме.
import {DataParser, DataType} from '@e22m4u/js-data-schema';
const parser = new DataParser();
const schema = {
type: DataType.NUMBER,
default: 0,
};
parser.parse('10', schema); // 10
parser.parse(undefined, schema); // 0
parser.parse('N/A', schema); // DataParsingError
Модуль экспортирует сервисы для проверки и парсинга данных. Каждый
сервис позволяет регистрировать схемы данных по уникальному имени
методом defineSchema.
import {DataValidator, DataParser, DataType} from '@e22m4u/js-data-service';
const validator = new DataValidator();
const parser = new DataParser();
const schema = {
type: DataType.ARRAY,
items: {
type: DataType.STRING,
required: true,
},
};
validator.defineSchema({name: 'mySchema', schema});
parser.defineSchema({name: 'mySchema', schema});
Регистрация схем может выполняться централизованно через реестр. Этого можно добиться используя сервис-контейнер, который выступает в роли точки входа.
import {ServiceContainer} from '@e22m4u/js-service';
import {
DataType,
DataParser,
DataValidator,
DataSchemaRegistry,
} from '@e22m4u/js-data-service';
const app = new ServiceContainer();
const registry = app.get(DataSchemaRegistry);
registry.defineSchema({
name: 'mySchema',
schema: {
type: DataType.ARRAY,
items: {
type: DataType.STRING,
required: true,
},
},
});
const validator = app.get(DataValidator);
const parser = app.get(DataParser);
В примере выше оба сервиса используют общий реестр и знают о
зарегистрированной схеме mySchema, что избавляет от
необходимости синхронизации между сервисами данного модуля.
Зарегистрированное имя схемы можно использовать вместо объекта схемы. Пример ниже демонстрирует проверку данных с помощью именованной схемы.
validator.defineSchema({
name: 'stringList',
schema: {
type: DataType.STRING,
required: true,
},
});
validator.validate(['a', 'b', 'c'], 'mySchema'); // OK
validator.validate(['a', 'b', 10], 'mySchema'); // DataValidationError
Зарегистрированные имена можно встраивать в другие схемы. Ниже приводится пример разбора JSON строки с использованием именованной схемы внутри схемы массива.
parser.defineSchema({
name: 'user', // имя схемы
schema: {
type: DataType.OBJECT,
properties: {
name: {
type: DataType.STRING,
required: true,
},
age: {
type: DataType.NUMBER,
default: 0,
},
},
},
});
const jsonData = `[{"name": "John","age": 35},{"name": "Tommy"}]`;
const users = parser.parse(jsonData, {
type: DataType.ARRAY,
items: 'user', // <= именованная схема
});
console.log(users);
// [
// {
// name: 'John',
// age: 35
// },
// {
// name: 'Tommy',
// age: 0
// }
// ]
Если именованная схема описывает объект, то допускается передача
имени схемы в параметр properties, что позволяет
переопределить остальные параметры зарегистрированной схемы.
validator.validate(data, {
type: DataType.OBJECT,
properties: 'user', // имя схема вместо схемы свойств
required: true, // переопределение параметра схемы "user"
});
Разные типы данных имеют свои наборы пустых значений. Эти наборы
используются для определения наличия полезной нагрузки в значении
свойства. Например, параметр required исключает пустые
значения при проверке данных.
| тип данных | пустые значения |
|---|---|
DataType.ANY |
значения остальных типов |
DataType.STRING |
undefined, null, "" |
DataType.NUMBER |
undefined, null, 0 |
DataType.BOOLEAN |
undefined, null |
DataType.ARRAY |
undefined, null, [] |
DataType.OBJECT |
undefined, null, {} |
Управление этими наборами осуществляется через специальный сервис, который предоставляет модуль @e22m4u/js-empty-values (не требует установки).
npm run test
MIT