validno 0.1.8 → 0.1.10

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.
@@ -121,6 +121,7 @@ function checkRules(key, value, requirements, inputObj) {
121
121
  return result;
122
122
  }
123
123
  const rules = requirements.rules;
124
+ const title = requirements.title || key;
124
125
  const allResults = [];
125
126
  const allRulesKeys = Object.keys(rules);
126
127
  let i = 0;
@@ -133,6 +134,17 @@ function checkRules(key, value, requirements, inputObj) {
133
134
  const func = rulesFunctions[ruleName];
134
135
  const args = rules[ruleName];
135
136
  const result = func(key, value, args, { schema: this.schema, input: inputObj });
137
+ if (requirements.customMessage && typeof requirements.customMessage === 'function') {
138
+ result.details = requirements.customMessage({
139
+ keyword: ruleName,
140
+ value: value,
141
+ key: key,
142
+ title: title,
143
+ reqs: requirements,
144
+ schema: this.schema,
145
+ rules: rules,
146
+ });
147
+ }
136
148
  allResults.push(result);
137
149
  i++;
138
150
  }
package/dist/checkType.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { ErrorKeywords } from "./constants/details.js";
1
2
  import _validations from "./utils/validations.js";
2
3
  const getErrorDetails = (key, expectedType, receivedValue) => {
3
4
  let receivedType = '';
@@ -32,7 +33,7 @@ const checkTypeMultiple = (key, value, requirements, keyName = key) => {
32
33
  const check = checkType(key, value, requirementsRe);
33
34
  if (check[0].passed === true) {
34
35
  result.passed = true;
35
- result.details = 'Passed';
36
+ result.details = 'OK';
36
37
  return result;
37
38
  }
38
39
  i++;
@@ -41,8 +42,10 @@ const checkTypeMultiple = (key, value, requirements, keyName = key) => {
41
42
  };
42
43
  const checkType = (key, value, requirements, keyName = key) => {
43
44
  const isNotNull = value !== null;
45
+ const keyTitle = 'title' in requirements ? requirements.title : keyName;
46
+ const hasCustomMessage = requirements.customMessage && typeof requirements.customMessage === 'function';
44
47
  if (value === undefined && requirements.required) {
45
- return [{ key: keyName, passed: false, details: `Key ${keyName} is missing` }];
48
+ return [{ key: keyName, passed: false, details: `Значение "${keyName}" отсутствует` }];
46
49
  }
47
50
  let result = [];
48
51
  if (Array.isArray(requirements.type)) {
@@ -52,16 +55,28 @@ const checkType = (key, value, requirements, keyName = key) => {
52
55
  result.push({
53
56
  key: keyName,
54
57
  passed: true,
55
- details: 'Passed'
58
+ details: 'OK'
56
59
  });
57
60
  return result;
58
61
  }
62
+ const customErrDetails = hasCustomMessage ?
63
+ requirements.customMessage({
64
+ keyword: ErrorKeywords.Type,
65
+ value: value,
66
+ key: keyName,
67
+ title: keyTitle,
68
+ reqs: requirements,
69
+ schema: null
70
+ }) :
71
+ null;
72
+ const baseErrDetails = getErrorDetails(keyName, requirements.type, value);
73
+ const getDetails = (isOK) => isOK ? 'OK' : customErrDetails || baseErrDetails;
59
74
  switch (requirements.type) {
60
75
  case 'any':
61
76
  result.push({
62
77
  key: keyName,
63
78
  passed: true,
64
- details: 'Passed'
79
+ details: 'OK'
65
80
  });
66
81
  break;
67
82
  case Number:
@@ -69,7 +84,7 @@ const checkType = (key, value, requirements, keyName = key) => {
69
84
  result.push({
70
85
  key: keyName,
71
86
  passed: isNumber,
72
- details: isNumber ? 'Passed' : getErrorDetails(keyName, requirements.type, value)
87
+ details: getDetails(isNumber)
73
88
  });
74
89
  break;
75
90
  case String:
@@ -77,17 +92,17 @@ const checkType = (key, value, requirements, keyName = key) => {
77
92
  result.push({
78
93
  key: keyName,
79
94
  passed: isString,
80
- details: isString ? 'Passed' : getErrorDetails(keyName, requirements.type, value)
95
+ details: getDetails(isString)
81
96
  });
82
97
  break;
83
98
  case Date:
84
99
  const isDate = isNotNull && value.constructor === Date;
85
100
  const isValid = isDate && !isNaN(value.getTime());
86
- const errorMsg = isValid ? getErrorDetails(keyName, requirements.type, value) : 'Дата невалидна';
101
+ const errorMsg = isValid ? getDetails(isDate) : 'Дата невалидна';
87
102
  result.push({
88
103
  key: keyName,
89
104
  passed: isDate && isValid,
90
- details: isDate && isValid ? 'Passed' : errorMsg
105
+ details: isDate && isValid ? 'OK' : errorMsg
91
106
  });
92
107
  break;
93
108
  case Boolean:
@@ -95,7 +110,7 @@ const checkType = (key, value, requirements, keyName = key) => {
95
110
  result.push({
96
111
  key: keyName,
97
112
  passed: isBoolean,
98
- details: isBoolean ? 'Passed' : getErrorDetails(keyName, requirements.type, value)
113
+ details: isBoolean ? 'OK' : getDetails(isBoolean)
99
114
  });
100
115
  break;
101
116
  case Array:
@@ -104,7 +119,7 @@ const checkType = (key, value, requirements, keyName = key) => {
104
119
  result.push({
105
120
  key: keyName,
106
121
  passed: false,
107
- details: getErrorDetails(keyName, requirements.type, value)
122
+ details: getDetails(isArray)
108
123
  });
109
124
  break;
110
125
  }
@@ -123,7 +138,7 @@ const checkType = (key, value, requirements, keyName = key) => {
123
138
  result.push({
124
139
  key: keyName,
125
140
  passed: isOk,
126
- details: isOk ? 'Passed' : !isEachChecked.passed ? isEachChecked.details : getErrorDetails(keyName, requirements.type, value)
141
+ details: isOk ? 'OK' : !isEachChecked.passed ? isEachChecked.details : getDetails(isOk)
127
142
  });
128
143
  break;
129
144
  case Object:
@@ -131,7 +146,7 @@ const checkType = (key, value, requirements, keyName = key) => {
131
146
  result.push({
132
147
  key: keyName,
133
148
  passed: isObject,
134
- details: isObject ? 'Passed' : getErrorDetails(keyName, requirements.type, value)
149
+ details: isObject ? 'OK' : getDetails(isObject)
135
150
  });
136
151
  break;
137
152
  case RegExp:
@@ -139,7 +154,7 @@ const checkType = (key, value, requirements, keyName = key) => {
139
154
  result.push({
140
155
  key: keyName,
141
156
  passed: isRegex,
142
- details: isRegex ? 'Passed' : getErrorDetails(keyName, requirements.type, value)
157
+ details: isRegex ? 'OK' : getDetails(isRegex)
143
158
  });
144
159
  break;
145
160
  case null:
@@ -147,7 +162,7 @@ const checkType = (key, value, requirements, keyName = key) => {
147
162
  result.push({
148
163
  key: keyName,
149
164
  passed: isNull,
150
- details: isNull ? 'Passed' : getErrorDetails(keyName, requirements.type, value)
165
+ details: isNull ? 'OK' : getDetails(isNull)
151
166
  });
152
167
  break;
153
168
  default:
@@ -0,0 +1,6 @@
1
+ export var ErrorKeywords;
2
+ (function (ErrorKeywords) {
3
+ ErrorKeywords["Missing"] = "missing";
4
+ ErrorKeywords["Type"] = "type";
5
+ ErrorKeywords["Rule"] = "rule";
6
+ })(ErrorKeywords || (ErrorKeywords = {}));
package/dist/dev.js ADDED
@@ -0,0 +1,63 @@
1
+ import { Schema } from "./Schema.js";
2
+ const schema = new Schema({
3
+ wrongType: {
4
+ type: Number,
5
+ required: true,
6
+ title: 'Не по типу',
7
+ customMessage: (input) => {
8
+ return 'wrong type 1 msg ' + input.keyword;
9
+ }
10
+ },
11
+ missingKey: {
12
+ type: Date,
13
+ required: true,
14
+ title: 'Отсутствующий',
15
+ customMessage: (input) => {
16
+ return 'missing msg ' + input.keyword;
17
+ }
18
+ },
19
+ wrongRule1: {
20
+ type: String,
21
+ required: true,
22
+ title: 'Wrong Rule #1',
23
+ rules: {
24
+ is: 'xxx'
25
+ },
26
+ customMessage: (input) => {
27
+ return 'wrong rule #1 msg ' + input.keyword;
28
+ }
29
+ },
30
+ wrongRule2: {
31
+ type: String,
32
+ required: true,
33
+ title: 'Wrong Rule #2',
34
+ rules: {
35
+ lengthMin: 999
36
+ },
37
+ customMessage: (input) => {
38
+ return 'wrong rule #2 msg ' + input.keyword;
39
+ }
40
+ },
41
+ wrongRule3: {
42
+ type: String,
43
+ required: true,
44
+ title: 'Wrong Rule #3',
45
+ rules: {
46
+ lengthMax: 1
47
+ },
48
+ customMessage: (input) => {
49
+ const { keyword, value, key, title, reqs, schema, rules } = input;
50
+ if (keyword === 'lengthMax') {
51
+ return `Значение ${value} недопустимо для поля ${title}. Минимальная длина ${rules.lengthMax} символов`;
52
+ }
53
+ return 'Проверьте значение, кажется, что-то не в порядке';
54
+ }
55
+ },
56
+ });
57
+ const obj = {
58
+ wrongType: 'String',
59
+ wrongRule1: 'qwertyuiop',
60
+ wrongRule2: 'asdfghjkl',
61
+ wrongRule3: 'zxcvbnmasd'
62
+ };
63
+ console.log('finalResult', schema.validate(obj));
package/dist/validate.js CHANGED
@@ -3,6 +3,7 @@ import checkType from "./checkType.js";
3
3
  import _errors from "./utils/errors.js";
4
4
  import _validations from "./utils/validations.js";
5
5
  import { defaultSchemaKeys } from "./Schema.js";
6
+ import { ErrorKeywords } from "./constants/details.js";
6
7
  export const getResultDefaults = () => {
7
8
  return {
8
9
  ok: null,
@@ -11,9 +12,7 @@ export const getResultDefaults = () => {
11
12
  passed: [],
12
13
  errors: [],
13
14
  byKeys: {},
14
- byTitles: {},
15
15
  errorsByKeys: {},
16
- errorsByTitles: {}
17
16
  };
18
17
  };
19
18
  const checkIsNested = (obj) => {
@@ -34,9 +33,7 @@ export const mergeResults = (resultsOld, resultsNew) => {
34
33
  output.missed = [...resultsOld.missed, ...resultsNew.missed];
35
34
  output.passed = [...resultsOld.passed, ...resultsNew.passed];
36
35
  output.byKeys = Object.assign(Object.assign({}, resultsOld.byKeys), resultsNew.byKeys);
37
- output.byTitles = Object.assign(Object.assign({}, resultsOld.byTitles), resultsNew.byTitles);
38
36
  output.errorsByKeys = Object.assign(Object.assign({}, resultsOld.errorsByKeys), resultsNew.errorsByKeys);
39
- output.errorsByTitles = Object.assign(Object.assign({}, resultsOld.errorsByTitles), resultsNew.errorsByTitles);
40
37
  return output;
41
38
  };
42
39
  export function handleReqKey(key, data, reqs, deepKey = key) {
@@ -51,13 +48,11 @@ export function handleReqKey(key, data, reqs, deepKey = key) {
51
48
  results.missed.push(deepKey);
52
49
  results.failed.push(deepKey);
53
50
  results.byKeys[deepKey] = false;
54
- results.byTitles[keyTitle] = false;
55
51
  return results;
56
52
  }
57
53
  if (hasNested) {
58
54
  const nestedReqKeys = Object.keys(reqs);
59
55
  results.byKeys[deepKey] = true;
60
- results.byTitles[keyTitle] = true;
61
56
  let i = 0;
62
57
  while (i < nestedReqKeys.length) {
63
58
  const reqKeyI = nestedReqKeys[i];
@@ -71,7 +66,12 @@ export function handleReqKey(key, data, reqs, deepKey = key) {
71
66
  let errMsg = _errors.getMissingError(deepKey);
72
67
  if (reqs.customMessage && typeof reqs.customMessage === 'function') {
73
68
  errMsg = reqs.customMessage({
74
- value: data[key], key: deepKey, title: keyTitle, reqs: reqs, schema: this.schema
69
+ keyword: ErrorKeywords.Missing,
70
+ value: data[key],
71
+ key: deepKey,
72
+ title: keyTitle,
73
+ reqs: reqs,
74
+ schema: this.schema
75
75
  });
76
76
  }
77
77
  missedCheck.push(false);
@@ -79,9 +79,6 @@ export function handleReqKey(key, data, reqs, deepKey = key) {
79
79
  results.failed.push(deepKey);
80
80
  results.errors.push(errMsg);
81
81
  results.byKeys[deepKey] = false;
82
- results.byTitles[keyTitle] = false;
83
- results.errorsByKeys[deepKey] = [errMsg];
84
- results.errorsByTitles[keyTitle] = [errMsg];
85
82
  return results;
86
83
  }
87
84
  const typeCheck = checkType(key, data[key], reqs, deepKey);
@@ -97,11 +94,8 @@ export function handleReqKey(key, data, reqs, deepKey = key) {
97
94
  ruleCheck.details.forEach((el) => {
98
95
  if (deepKey in results.errorsByKeys)
99
96
  results.errorsByKeys[deepKey] = [];
100
- if (deepKey in results.errorsByTitles)
101
- results.errorsByTitles[keyTitle] = [];
102
97
  results.errors.push(el);
103
98
  results.errorsByKeys[deepKey] = ['1'];
104
- results.errorsByTitles[keyTitle] = ['1'];
105
99
  });
106
100
  }
107
101
  if (missedCheck.length)
@@ -115,21 +109,18 @@ export function handleReqKey(key, data, reqs, deepKey = key) {
115
109
  results.errorsByKeys[deepKey] = [
116
110
  ...results.errors
117
111
  ];
118
- results.errorsByTitles[keyTitle] = [
119
- ...results.errors
120
- ];
121
112
  results.byKeys[deepKey] = (missedCheck.length + typeChecked.length + rulesChecked.length) === 0;
122
- results.byTitles[keyTitle] = (missedCheck.length + typeChecked.length + rulesChecked.length) === 0;
123
113
  return results;
124
114
  }
125
- const isCheckNeeded = (key, hasLimits, onlyKeys) => {
115
+ const checkIfValidationIsNeeded = (key, hasLimits, onlyKeys) => {
126
116
  return !hasLimits || (key === onlyKeys || Array.isArray(onlyKeys) && (onlyKeys === null || onlyKeys === void 0 ? void 0 : onlyKeys.includes(key)));
127
117
  };
128
118
  function validate(schema, data, onlyKeys) {
129
119
  let results = getResultDefaults();
130
120
  const areKeysLimited = (Array.isArray(onlyKeys) && onlyKeys.length > 0) || (typeof onlyKeys === 'string' && onlyKeys.length > 0);
131
121
  for (const [key, reqs] of Object.entries(schema.schema)) {
132
- if (isCheckNeeded(key, areKeysLimited, onlyKeys)) {
122
+ const isValidationRequired = checkIfValidationIsNeeded(key, areKeysLimited, onlyKeys);
123
+ if (isValidationRequired) {
133
124
  const keyResult = handleReqKey.call(this, key, data, reqs);
134
125
  results = mergeResults(results, keyResult);
135
126
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "validno",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/src/Schema.ts DELETED
@@ -1,46 +0,0 @@
1
- import validate from "./validate.js"
2
-
3
- export type TSchemaItem = {
4
- required: boolean,
5
- type: any,
6
- eachType?: any,
7
- rules?: {},
8
- title?: string,
9
- customMessage?: Function
10
- }
11
-
12
- export type TSchemaInput = {
13
- [key: string]: TSchemaItem | TSchemaInput
14
- }
15
-
16
- export const enum ESchemaFields {
17
- Required = 'required',
18
- Type = 'type',
19
- EachType = 'eachType',
20
- Rules = 'rules',
21
- Title = 'title',
22
- CustomMessage = 'customMessage'
23
- }
24
-
25
- export const defaultSchemaKeys = [
26
- ESchemaFields.Required,
27
- ESchemaFields.Type,
28
- ESchemaFields.EachType,
29
- ESchemaFields.Rules,
30
- ESchemaFields.Title,
31
- ESchemaFields.CustomMessage
32
- ]
33
-
34
- export type TSchema = TSchemaInput
35
-
36
- export class Schema {
37
- schema: TSchema
38
-
39
- constructor(inputSchema: TSchema) {
40
- this.schema = inputSchema
41
- }
42
-
43
- validate(data: any, keys?: string | string[]) {
44
- return validate.call(this, this, data, keys)
45
- }
46
- }
package/src/checkRules.ts DELETED
@@ -1,181 +0,0 @@
1
- import { TSchema, TSchemaItem } from "./Schema.js";
2
- import _validations from "./utils/validations.js"
3
-
4
- export type TRule = {[key: string]: any}
5
-
6
- type TLengths = string | Array<any>
7
-
8
- export const rulesParams = {
9
- lengthMin: {
10
- allowedTypes: [String]
11
- }
12
- }
13
-
14
- const ensureRuleHasCorrectType = (value: any, allowedTypes: any[]) => {
15
- const isInAllowedList = allowedTypes.some(TYPE => {
16
- const getType = (el: any) => Object.prototype.toString.call(el)
17
- return getType(new TYPE()) == getType(value)
18
- })
19
-
20
- return isInAllowedList
21
- }
22
-
23
- const rulesFunctions: any = {
24
- custom: (key: string, val: any, func: Function, extra: {schema: TSchema, input: {[key: string]: any}}) => {
25
- return func(val, extra)
26
- },
27
- isEmail: (key: string, val: any) => {
28
- return {
29
- result: _validations.isEmail(val),
30
- details: `Значение должно соответствовать формату name@email.ru`
31
- }
32
- },
33
- is: (key: string, val: any, equalTo: any) => {
34
- return {
35
- result: _validations.is(val, equalTo),
36
- details: `Значение должно быть "${equalTo}"`
37
- }
38
- },
39
- isNot: (key: string, val: any, notEqualTo: any) => {
40
- return {
41
- result: _validations.isNot(val, notEqualTo),
42
- details: `Значение "${notEqualTo}" недопустимо`
43
- }
44
- },
45
- min: (key: string, val: number, min: number) => {
46
- return {
47
- result: _validations.isNumberGte(val, min),
48
- details: "Значение не может быть меньше " + min
49
- }
50
- },
51
- max: (key: string, val: number, max: number) => {
52
- return {
53
- result: _validations.isNumberLte(val, max),
54
- details: "Значение не может быть больше " + max
55
- }
56
- },
57
- minMax: (key: string, val: number, minMax: [min: number, max: number]) => {
58
- const [min, max] = minMax
59
- return {
60
- result: _validations.isNumberGte(val, min) && _validations.isNumberLte(val, max),
61
- details: `Значение должно быть в пределах ${min}-${max}`
62
- }
63
- },
64
- length: (key: string, val: TLengths, length: number) => {
65
- return {
66
- result: _validations.lengthIs(val, length),
67
- details: "Количество символов должно быть равным " + length
68
- }
69
- },
70
- lengthNot: (key: string, val: TLengths, lengthNot: number) => {
71
- return {
72
- result: _validations.lengthNot(val, lengthNot),
73
- details: "Количество символов не должно быть равным " + lengthNot
74
- }
75
- },
76
- lengthMinMax: (key: string, val: TLengths, minMax: [min: number, max: number]) => {
77
- const [min, max] = minMax
78
-
79
- return {
80
- result: _validations.lengthMin(val, min) && _validations.lengthMax(val, max),
81
- details: `Длина должна быть от ${min} до ${max} символов`
82
- }
83
- },
84
- lengthMin: (key: string, val: TLengths, min: number) => {
85
- ensureRuleHasCorrectType(val, rulesParams['lengthMin'].allowedTypes)
86
-
87
- return {
88
- result: _validations.lengthMin(val, min),
89
- details: `Длина не может быть меньше ${min} символов`
90
- }
91
- },
92
- lengthMax: (key: string, val: TLengths, max: number) => {
93
- return {
94
- result: _validations.lengthMax(val, max),
95
- details: `Длина не может быть больше ${max} символов`
96
- }
97
- },
98
- regex: (key: string, val: any, regex: RegExp) => {
99
- return {
100
- result: _validations.regexTested(val, regex),
101
- details: "Значение не соответствует допустимому формату"
102
- }
103
- },
104
- enum: (key: string, value: any, allowedList: any[]) => {
105
- const output = {
106
- result: true,
107
- details: ''
108
- }
109
-
110
- if (!Array.isArray(value)) {
111
- const isCorrect = allowedList.includes(value)
112
- output.result = isCorrect,
113
- output.details = isCorrect ? '' : `Значение "${value}" недопустимо`
114
- } else {
115
- const incorrectValues: any[] = []
116
- value.forEach((v: any) => !allowedList.includes(v) ? incorrectValues.push(v): {})
117
- const isCorrect = incorrectValues.length === 0
118
-
119
- output.result = isCorrect,
120
- output.details = isCorrect ? '' : `Значения недопустимы: "${incorrectValues.join(', ')}"`
121
- }
122
-
123
- return output
124
- }
125
- };
126
-
127
- type TRulesResult = {
128
- ok: boolean,
129
- details: string[]
130
- }
131
-
132
- function checkRules (this: any, key: string, value: any, requirements: TSchemaItem, inputObj: any) {
133
- const result: TRulesResult = {
134
- ok: true,
135
- details: []
136
- };
137
-
138
- // Значение отсутствует, но НЕ является обязательным
139
- if (requirements.required !== true && value === undefined) return result
140
-
141
- // Для этого ключа нет правил
142
- if (!requirements || !requirements.rules || !Object.keys(requirements.rules).length) {
143
- return result
144
- }
145
-
146
- const rules: TRule = requirements.rules
147
-
148
- const allResults = []
149
- const allRulesKeys = Object.keys(rules)
150
-
151
- let i = 0;
152
- while (i < allRulesKeys.length) {
153
- const ruleName = allRulesKeys[i]
154
-
155
- // Если правило, указанное для ключа, отсутствует в списке доступных
156
- if (ruleName in rulesFunctions === false) {
157
- i++
158
- continue
159
- }
160
-
161
- const func = rulesFunctions[ruleName]
162
- const args = rules[ruleName]
163
-
164
- const result = func(key, value, args, {schema: this.schema, input: inputObj})
165
- allResults.push(result)
166
-
167
- i++;
168
- }
169
-
170
- // If key has failed rules checks
171
- const failedResults = allResults.filter(el => el.result === false)
172
-
173
- if (failedResults.length) {
174
- result.ok = false
175
- result.details = failedResults.map(el => el.details)
176
- }
177
-
178
- return result;
179
- };
180
-
181
- export default checkRules