@e22m4u/js-repository 0.6.5 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -532
- package/dist/cjs/index.cjs +125 -1140
- package/package.json +4 -4
- package/src/adapter/adapter.d.ts +2 -4
- package/src/adapter/adapter.js +2 -6
- package/src/adapter/adapter.spec.js +3 -15
- package/src/adapter/builtin/memory-adapter.js +41 -12
- package/src/adapter/builtin/memory-adapter.spec.js +47 -0
- package/src/adapter/decorator/index.d.ts +0 -2
- package/src/adapter/decorator/index.js +0 -2
- package/src/definition/model/index.d.ts +0 -2
- package/src/definition/model/index.js +0 -2
- package/src/definition/model/properties/index.d.ts +0 -2
- package/src/definition/model/properties/index.js +0 -2
- package/src/definition/model/properties/properties-definition-validator.js +0 -169
- package/src/definition/model/properties/properties-definition-validator.spec.js +0 -162
- package/src/definition/model/properties/property-definition.d.ts +1 -5
- package/src/utils/index.d.ts +0 -4
- package/src/utils/index.js +0 -4
- package/src/utils/model-name-to-model-key.js +0 -4
- package/src/utils/model-name-to-model-key.spec.js +0 -23
- package/tsconfig.json +2 -2
- package/src/adapter/decorator/data-transformation-decorator.d.ts +0 -14
- package/src/adapter/decorator/data-transformation-decorator.js +0 -54
- package/src/adapter/decorator/data-transformation-decorator.spec.js +0 -193
- package/src/adapter/decorator/data-validation-decorator.d.ts +0 -14
- package/src/adapter/decorator/data-validation-decorator.js +0 -54
- package/src/adapter/decorator/data-validation-decorator.spec.js +0 -105
- package/src/definition/model/model-data-transformer.d.ts +0 -16
- package/src/definition/model/model-data-transformer.js +0 -170
- package/src/definition/model/model-data-transformer.spec.js +0 -2312
- package/src/definition/model/model-data-validator.d.ts +0 -16
- package/src/definition/model/model-data-validator.js +0 -318
- package/src/definition/model/model-data-validator.spec.js +0 -4528
- package/src/definition/model/properties/property-transformer/builtin/index.d.ts +0 -3
- package/src/definition/model/properties/property-transformer/builtin/index.js +0 -3
- package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.d.ts +0 -6
- package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.js +0 -19
- package/src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.spec.js +0 -39
- package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.d.ts +0 -6
- package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.js +0 -19
- package/src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.spec.js +0 -39
- package/src/definition/model/properties/property-transformer/builtin/trim-transformer.d.ts +0 -6
- package/src/definition/model/properties/property-transformer/builtin/trim-transformer.js +0 -19
- package/src/definition/model/properties/property-transformer/builtin/trim-transformer.spec.js +0 -39
- package/src/definition/model/properties/property-transformer/index.d.ts +0 -2
- package/src/definition/model/properties/property-transformer/index.js +0 -2
- package/src/definition/model/properties/property-transformer/property-transformer-registry.d.ts +0 -29
- package/src/definition/model/properties/property-transformer/property-transformer-registry.js +0 -76
- package/src/definition/model/properties/property-transformer/property-transformer-registry.spec.js +0 -133
- package/src/definition/model/properties/property-transformer/property-transformer.d.ts +0 -27
- package/src/definition/model/properties/property-transformer/property-transformer.js +0 -1
- package/src/definition/model/properties/property-validator/builtin/index.d.ts +0 -3
- package/src/definition/model/properties/property-validator/builtin/index.js +0 -3
- package/src/definition/model/properties/property-validator/builtin/max-length-validator.d.ts +0 -6
- package/src/definition/model/properties/property-validator/builtin/max-length-validator.js +0 -28
- package/src/definition/model/properties/property-validator/builtin/max-length-validator.spec.js +0 -100
- package/src/definition/model/properties/property-validator/builtin/min-length-validator.d.ts +0 -6
- package/src/definition/model/properties/property-validator/builtin/min-length-validator.js +0 -28
- package/src/definition/model/properties/property-validator/builtin/min-length-validator.spec.js +0 -100
- package/src/definition/model/properties/property-validator/builtin/regexp-validator.d.ts +0 -6
- package/src/definition/model/properties/property-validator/builtin/regexp-validator.js +0 -30
- package/src/definition/model/properties/property-validator/builtin/regexp-validator.spec.js +0 -102
- package/src/definition/model/properties/property-validator/index.d.ts +0 -2
- package/src/definition/model/properties/property-validator/index.js +0 -2
- package/src/definition/model/properties/property-validator/property-validator-registry.d.ts +0 -29
- package/src/definition/model/properties/property-validator/property-validator-registry.js +0 -76
- package/src/definition/model/properties/property-validator/property-validator-registry.spec.js +0 -132
- package/src/definition/model/properties/property-validator/property-validator.d.ts +0 -25
- package/src/definition/model/properties/property-validator/property-validator.js +0 -1
- package/src/utils/get-ctor-name.d.ts +0 -6
- package/src/utils/get-ctor-name.js +0 -11
- package/src/utils/get-ctor-name.spec.js +0 -17
- package/src/utils/get-decorator-target-type.d.ts +0 -27
- package/src/utils/get-decorator-target-type.js +0 -63
- package/src/utils/get-decorator-target-type.spec.js +0 -80
- package/src/utils/is-ctor.d.ts +0 -8
- package/src/utils/is-ctor.js +0 -11
- package/src/utils/is-ctor.spec.js +0 -26
- package/src/utils/transform-promise.d.ts +0 -13
- package/src/utils/transform-promise.js +0 -15
- package/src/utils/transform-promise.spec.js +0 -19
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {ModelData} from '../../types.js';
|
|
2
|
-
import {Service} from '@e22m4u/js-service';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Model data validator.
|
|
6
|
-
*/
|
|
7
|
-
export declare class ModelDataValidator extends Service {
|
|
8
|
-
/**
|
|
9
|
-
* Validate.
|
|
10
|
-
*
|
|
11
|
-
* @param modelName
|
|
12
|
-
* @param modelData
|
|
13
|
-
* @param isPartial
|
|
14
|
-
*/
|
|
15
|
-
validate(modelName: string, modelData: ModelData, isPartial?: boolean): void;
|
|
16
|
-
}
|
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
import {Service} from '@e22m4u/js-service';
|
|
2
|
-
import {DataType} from './properties/index.js';
|
|
3
|
-
import {getCtorName} from '../../utils/index.js';
|
|
4
|
-
import {isPlainObject} from '../../utils/index.js';
|
|
5
|
-
import {EmptyValuesService} from '@e22m4u/js-empty-values';
|
|
6
|
-
import {InvalidArgumentError} from '../../errors/index.js';
|
|
7
|
-
import {PropertyValidatorRegistry} from './properties/index.js';
|
|
8
|
-
import {ModelDefinitionUtils} from './model-definition-utils.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Model data validator.
|
|
12
|
-
*/
|
|
13
|
-
export class ModelDataValidator extends Service {
|
|
14
|
-
/**
|
|
15
|
-
* Validate.
|
|
16
|
-
*
|
|
17
|
-
* @param {string} modelName
|
|
18
|
-
* @param {object} modelData
|
|
19
|
-
* @param {boolean} isPartial
|
|
20
|
-
* @returns {undefined}
|
|
21
|
-
*/
|
|
22
|
-
validate(modelName, modelData, isPartial = false) {
|
|
23
|
-
if (!isPlainObject(modelData))
|
|
24
|
-
throw new InvalidArgumentError(
|
|
25
|
-
'The data of the model %v should be an Object, but %v was given.',
|
|
26
|
-
modelName,
|
|
27
|
-
modelData,
|
|
28
|
-
);
|
|
29
|
-
const propDefs =
|
|
30
|
-
this.getService(
|
|
31
|
-
ModelDefinitionUtils,
|
|
32
|
-
).getPropertiesDefinitionInBaseModelHierarchy(modelName);
|
|
33
|
-
const propNames = Object.keys(isPartial ? modelData : propDefs);
|
|
34
|
-
propNames.forEach(propName => {
|
|
35
|
-
const propDef = propDefs[propName];
|
|
36
|
-
if (!propDef) return;
|
|
37
|
-
this._validatePropertyValue(
|
|
38
|
-
modelName,
|
|
39
|
-
propName,
|
|
40
|
-
propDef,
|
|
41
|
-
modelData[propName],
|
|
42
|
-
);
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Validate property value.
|
|
48
|
-
*
|
|
49
|
-
* @param {string} modelName
|
|
50
|
-
* @param {string} propName
|
|
51
|
-
* @param {string|object} propDef
|
|
52
|
-
* @param {*} propValue
|
|
53
|
-
* @returns {undefined}
|
|
54
|
-
*/
|
|
55
|
-
_validatePropertyValue(modelName, propName, propDef, propValue) {
|
|
56
|
-
const propType =
|
|
57
|
-
this.getService(ModelDefinitionUtils).getDataTypeFromPropertyDefinition(
|
|
58
|
-
propDef,
|
|
59
|
-
);
|
|
60
|
-
const isEmpty = this.getService(EmptyValuesService).isEmptyByType(
|
|
61
|
-
propType,
|
|
62
|
-
propValue,
|
|
63
|
-
);
|
|
64
|
-
if (isEmpty) {
|
|
65
|
-
// skips validation
|
|
66
|
-
// for an empty value
|
|
67
|
-
const isRequired =
|
|
68
|
-
typeof propDef === 'string' ? false : Boolean(propDef.required);
|
|
69
|
-
if (!isRequired) return;
|
|
70
|
-
// a required property should
|
|
71
|
-
// not have an empty value
|
|
72
|
-
throw new InvalidArgumentError(
|
|
73
|
-
'The property %v of the model %v is required, but %v was given.',
|
|
74
|
-
propName,
|
|
75
|
-
modelName,
|
|
76
|
-
propValue,
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
// проверка соответствия типа значения
|
|
80
|
-
this._validateValueByPropertyType(modelName, propName, propDef, propValue);
|
|
81
|
-
// проверка значения валидаторами
|
|
82
|
-
this._validateValueByPropertyValidators(
|
|
83
|
-
modelName,
|
|
84
|
-
propName,
|
|
85
|
-
propDef,
|
|
86
|
-
propValue,
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Validate value by property type.
|
|
92
|
-
*
|
|
93
|
-
* @param {string} modelName
|
|
94
|
-
* @param {string} propName
|
|
95
|
-
* @param {string|object} propDef
|
|
96
|
-
* @param {*} propValue
|
|
97
|
-
* @param {boolean} isArrayValue
|
|
98
|
-
* @returns {undefined}
|
|
99
|
-
*/
|
|
100
|
-
_validateValueByPropertyType(
|
|
101
|
-
modelName,
|
|
102
|
-
propName,
|
|
103
|
-
propDef,
|
|
104
|
-
propValue,
|
|
105
|
-
isArrayValue = false,
|
|
106
|
-
) {
|
|
107
|
-
let expectingType;
|
|
108
|
-
if (isArrayValue) {
|
|
109
|
-
if (typeof propDef === 'object') {
|
|
110
|
-
expectingType = propDef.itemType ?? DataType.ANY;
|
|
111
|
-
} else {
|
|
112
|
-
expectingType = DataType.ANY;
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
115
|
-
expectingType = typeof propDef !== 'string' ? propDef.type : propDef;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const createError = expected => {
|
|
119
|
-
const pattern = isArrayValue
|
|
120
|
-
? 'The array property %v of the model %v must have %s element, but %s was given.'
|
|
121
|
-
: 'The property %v of the model %v must have %s, but %s was given.';
|
|
122
|
-
const ctorName = getCtorName(propValue);
|
|
123
|
-
const givenStr = ctorName ?? typeof propValue;
|
|
124
|
-
return new InvalidArgumentError(
|
|
125
|
-
pattern,
|
|
126
|
-
propName,
|
|
127
|
-
modelName,
|
|
128
|
-
expected,
|
|
129
|
-
givenStr,
|
|
130
|
-
);
|
|
131
|
-
};
|
|
132
|
-
switch (expectingType) {
|
|
133
|
-
// STRING
|
|
134
|
-
case DataType.STRING:
|
|
135
|
-
if (typeof propValue !== 'string') throw createError('a String');
|
|
136
|
-
break;
|
|
137
|
-
// NUMBER
|
|
138
|
-
case DataType.NUMBER:
|
|
139
|
-
if (typeof propValue !== 'number') throw createError('a Number');
|
|
140
|
-
break;
|
|
141
|
-
// BOOLEAN
|
|
142
|
-
case DataType.BOOLEAN:
|
|
143
|
-
if (typeof propValue !== 'boolean') throw createError('a Boolean');
|
|
144
|
-
break;
|
|
145
|
-
// ARRAY
|
|
146
|
-
case DataType.ARRAY:
|
|
147
|
-
if (!Array.isArray(propValue)) throw createError('an Array');
|
|
148
|
-
propValue.forEach(value =>
|
|
149
|
-
this._validateValueByPropertyType(
|
|
150
|
-
modelName,
|
|
151
|
-
propName,
|
|
152
|
-
propDef,
|
|
153
|
-
value,
|
|
154
|
-
true,
|
|
155
|
-
),
|
|
156
|
-
);
|
|
157
|
-
break;
|
|
158
|
-
// OBJECT
|
|
159
|
-
case DataType.OBJECT: {
|
|
160
|
-
if (!isPlainObject(propValue)) throw createError('an Object');
|
|
161
|
-
if (typeof propDef === 'object') {
|
|
162
|
-
const modelOptionField = isArrayValue ? 'itemModel' : 'model';
|
|
163
|
-
const modelOptionValue = propDef[modelOptionField];
|
|
164
|
-
if (modelOptionValue) this.validate(modelOptionValue, propValue);
|
|
165
|
-
}
|
|
166
|
-
break;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Validate value by property validators.
|
|
173
|
-
*
|
|
174
|
-
* @param {string} modelName
|
|
175
|
-
* @param {string} propName
|
|
176
|
-
* @param {string|object} propDef
|
|
177
|
-
* @param {*} propValue
|
|
178
|
-
* @returns {undefined}
|
|
179
|
-
*/
|
|
180
|
-
_validateValueByPropertyValidators(modelName, propName, propDef, propValue) {
|
|
181
|
-
if (typeof propDef === 'string' || propDef.validate == null) return;
|
|
182
|
-
const validateDef = propDef.validate;
|
|
183
|
-
const validatorRegistry = this.getService(PropertyValidatorRegistry);
|
|
184
|
-
const createError = validatorName => {
|
|
185
|
-
if (validatorName) {
|
|
186
|
-
return new InvalidArgumentError(
|
|
187
|
-
'The property %v of the model %v has the invalid value %v ' +
|
|
188
|
-
'that caught by the property validator %v.',
|
|
189
|
-
propName,
|
|
190
|
-
modelName,
|
|
191
|
-
propValue,
|
|
192
|
-
validatorName,
|
|
193
|
-
);
|
|
194
|
-
} else {
|
|
195
|
-
return new InvalidArgumentError(
|
|
196
|
-
'The property %v of the model %v has the invalid value %v ' +
|
|
197
|
-
'that caught by a property validator.',
|
|
198
|
-
propName,
|
|
199
|
-
modelName,
|
|
200
|
-
propValue,
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
// объявление функции для проверки значения
|
|
205
|
-
// с помощью указанного валидатора
|
|
206
|
-
const validateBy = (validatorOrName, validatorOptions = undefined) => {
|
|
207
|
-
let validatorName, validatorFn;
|
|
208
|
-
// если первый аргумент является строкой, то строка
|
|
209
|
-
// воспринимается как название зарегистрированного
|
|
210
|
-
// валидатора
|
|
211
|
-
if (typeof validatorOrName === 'string') {
|
|
212
|
-
validatorName = validatorOrName;
|
|
213
|
-
validatorFn = validatorRegistry.getValidator(validatorName);
|
|
214
|
-
}
|
|
215
|
-
// если первый аргумент является функцией,
|
|
216
|
-
// то функция воспринимается как валидатор
|
|
217
|
-
else if (typeof validatorOrName === 'function') {
|
|
218
|
-
validatorName =
|
|
219
|
-
validatorOrName.name && validatorOrName.name !== 'validate'
|
|
220
|
-
? validatorOrName.name
|
|
221
|
-
: undefined;
|
|
222
|
-
validatorFn = validatorOrName;
|
|
223
|
-
}
|
|
224
|
-
// если первый аргумент не является строкой
|
|
225
|
-
// и функцией, то выбрасывается ошибка
|
|
226
|
-
else {
|
|
227
|
-
throw new InvalidArgumentError(
|
|
228
|
-
'Validator must be a non-empty String or ' +
|
|
229
|
-
'a Function, but %v was given.',
|
|
230
|
-
validatorOrName,
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
const context = {validatorName, modelName, propName};
|
|
234
|
-
const valid = validatorFn(propValue, validatorOptions, context);
|
|
235
|
-
// если валидатор возвращает Promise,
|
|
236
|
-
// то выбрасывается ошибка
|
|
237
|
-
if (valid instanceof Promise) {
|
|
238
|
-
if (validatorName) {
|
|
239
|
-
throw new InvalidArgumentError(
|
|
240
|
-
'Asynchronous property validators are not supported, ' +
|
|
241
|
-
'but the property %v of the model %v has the property ' +
|
|
242
|
-
'validator %v that returns a Promise.',
|
|
243
|
-
propName,
|
|
244
|
-
modelName,
|
|
245
|
-
validatorName,
|
|
246
|
-
);
|
|
247
|
-
} else {
|
|
248
|
-
throw new InvalidArgumentError(
|
|
249
|
-
'Asynchronous property validators are not supported, ' +
|
|
250
|
-
'but the property %v of the model %v has a property ' +
|
|
251
|
-
'validator that returns a Promise.',
|
|
252
|
-
propName,
|
|
253
|
-
modelName,
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
// если валидатор вернул значение отличное
|
|
258
|
-
// от true, то выбрасывается ошибка
|
|
259
|
-
else if (valid !== true) {
|
|
260
|
-
throw createError(validatorName);
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
// если значением опции "validate" является строка,
|
|
264
|
-
// то строка воспринимается как название валидатора
|
|
265
|
-
if (validateDef && typeof validateDef === 'string') {
|
|
266
|
-
validateBy(validateDef);
|
|
267
|
-
}
|
|
268
|
-
// если значение опции "validate" является функция,
|
|
269
|
-
// то функция воспринимается как валидатор
|
|
270
|
-
else if (validateDef && typeof validateDef === 'function') {
|
|
271
|
-
validateBy(validateDef);
|
|
272
|
-
}
|
|
273
|
-
// если значение опции "validate" является массив, то каждый
|
|
274
|
-
// элемент массива воспринимается как название валидатора
|
|
275
|
-
// или функция-валидатор
|
|
276
|
-
else if (Array.isArray(validateDef)) {
|
|
277
|
-
validateDef.forEach(validatorOrName => {
|
|
278
|
-
if (
|
|
279
|
-
!validatorOrName ||
|
|
280
|
-
(typeof validatorOrName !== 'string' &&
|
|
281
|
-
typeof validatorOrName !== 'function')
|
|
282
|
-
) {
|
|
283
|
-
throw new InvalidArgumentError(
|
|
284
|
-
'The provided option "validate" for the property %v in the model %v ' +
|
|
285
|
-
'has an Array value that should contain validator names or validator ' +
|
|
286
|
-
'functions, but %v was given.',
|
|
287
|
-
propName,
|
|
288
|
-
modelName,
|
|
289
|
-
validatorOrName,
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
validateBy(validatorOrName);
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
// если значение опции "validate" является объектом,
|
|
296
|
-
// то ключи объекта воспринимаются как названия валидаторов,
|
|
297
|
-
// а их значения аргументами
|
|
298
|
-
else if (validateDef !== null && typeof validateDef === 'object') {
|
|
299
|
-
Object.keys(validateDef).forEach(validatorName => {
|
|
300
|
-
const validatorOptions = validateDef[validatorName];
|
|
301
|
-
validateBy(validatorName, validatorOptions);
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
// если значение опции "validate" не является строкой,
|
|
305
|
-
// функцией и массивом, то выбрасывается ошибка
|
|
306
|
-
else {
|
|
307
|
-
throw new InvalidArgumentError(
|
|
308
|
-
'The provided option "validate" for the property %v in the model %v ' +
|
|
309
|
-
'should be either a validator name, a validator function, an array ' +
|
|
310
|
-
'of validator names or functions, or an object mapping validator ' +
|
|
311
|
-
'names to their arguments, but %v was given.',
|
|
312
|
-
propName,
|
|
313
|
-
modelName,
|
|
314
|
-
validateDef,
|
|
315
|
-
);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|