ru.coon 3.0.58 → 3.0.60

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/.husky/pre-commit CHANGED
File without changes
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # Version 3.0.60, [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/b3ba3aeb89954b8e1650cb40e052a4509b4809fb)
2
+ * ## Fixes
3
+ * <span style='color:red'>fix validator, util.getByPath</span> ([608e70], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/608e7096603a0ed31656b0f45686bab7a4ee302b))
4
+
5
+ * update: CHANGELOG.md ([e42a2a], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/e42a2a6fb8b511ba174ab5060fc84c683a046945))
6
+
7
+ # Version 3.0.59, [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/065a134b1f6c6211d56ef758b127778d5e104faa)
8
+ * Копирование в буфер обмена без использования дополнительного окна prompt. Related to NEVA-990 ([41cd4e], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/41cd4ed4fdb7088d10df1eac44964c5aadae4646))
9
+ * add Coon.validator singleton class ([a402d0], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/a402d0829e81d7f4297fba2af9b628a4528533c1))
10
+ * upd ([61e613], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/61e6137120af2b8a95c0d7918a85afe2aa3d0456))
11
+ * upd ([0258f1], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/0258f199b5928da341e6549f5589390f1fa87bcd))
12
+ * add validator ([0ca7d7], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/0ca7d719f4715af1845f0b4385333271db2438bb))
13
+ * update: CHANGELOG.md ([5969de], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/5969de159690ff30bc5194f8fe83a4d1d7507dd0))
14
+
1
15
  # Version 3.0.58, [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/9f4087fb2aba17d56ea49774ac21340c1b414307)
2
16
  * update: CHANGELOG.md ([fcea34], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/fcea34f891b7acc6a0b73200d9b6d7b60c383f46))
3
17
 
@@ -8,7 +22,13 @@
8
22
  * ## Features
9
23
  * <span style='color:green'>feat: add forceShowHeader</span> ([7ce368], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/7ce368898a1809f08aaa8331af2bdef4f40366da))
10
24
 
25
+ * update: CHANGELOG.md ([8108ae], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/8108ae12826ada676cd8598e0c1ba8ce067fa32e))
26
+
27
+ # Version 3.0.57, [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/28be9d312317e10260c5d784cf2eb09e83a30140)
11
28
  * HT-14299: изменение вида несохраненных изменений в вертикальных табах ([590315], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/59031554ed302eabdc194e916e44c3a8a3c77371))
29
+ * update: CHANGELOG.md ([62c8b4], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/62c8b40173f540191ba7eeb9aad48dae93dd5f57))
30
+
31
+ # Version 3.0.56, [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/74308acb16cf13c9793236b74d8fd025bd632cab)
12
32
  * HT-14580: повторный вход при завершении сессии ([66c811], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/66c81121345e02ec436a9ec3308db087030a25ac))
13
33
  * update: CHANGELOG.md ([0cd2cb], [link](http://gitlab-dbr.sigma-it.local/dbr/ru.coon/-/commit/0cd2cb99bbdcdf6d8cf83c29c744dd0f02daa497))
14
34
 
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "ru.coon"
5
5
  },
6
6
  "description": "",
7
- "version": "3.0.58",
7
+ "version": "3.0.60",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+http://gitlab-dbr.sigma-it.local/dbr/ru.coon"
@@ -0,0 +1,17 @@
1
+ Ext.define('Coon.common.AbstractPlugin', {
2
+ extend: 'Ext.AbstractPlugin',
3
+
4
+ constructor(config) {
5
+ Ext.apply(this, config || {});
6
+
7
+ if (Array.isArray(this.validConfig)) {
8
+ const state = Coon.validator.isObjectValid(this.pluginConfig.properties, this.validConfig);
9
+ if (!state.valid) {
10
+ console.error(`Invalid configuration for plugin ${this.pluginConfig.name}:\n${state.errors}`);
11
+ }
12
+ this.pluginConfig.validity = state;
13
+ }
14
+
15
+ this.callParent([config]);
16
+ },
17
+ });
File without changes
File without changes
@@ -868,6 +868,11 @@ Ext.define('Coon.report.component.ReportPanel', {
868
868
  }
869
869
  config[prefix + 'type'] = plugin[ns.$uiElement].xtype || plugin[ns.$xtype];
870
870
  config[ns.$sortSequence] = plugin[ns.$sortSequence] || null;
871
+ config.pluginConfig = {
872
+ properties: Object.assign({}, config),
873
+ type,
874
+ name: prefix + 'type',
875
+ };
871
876
  return config;
872
877
  });
873
878
  },
@@ -57,6 +57,7 @@ Ext.define('Coon.report.component.reportpanel.ReportGrid', {
57
57
  try {
58
58
  this.addPlugin(plugin);
59
59
  } catch (e) {
60
+ console.error('plugin error', e);
60
61
  pluginErrors.push(e.message);
61
62
  }
62
63
  });
@@ -2,7 +2,7 @@ Ext.define('Coon.report.util', {
2
2
  singleton: true,
3
3
 
4
4
  validateReportConfig(config) {
5
- return Coon.util.isObjectValid(config, [
5
+ return Coon.validator.isObjectValid(config, [
6
6
  {path: 'reportDescription', valid: 'string, required'},
7
7
  {path: 'reportId', valid: 'string, required'},
8
8
  {path: 'SQLText', valid: 'string, required'},
@@ -10,17 +10,17 @@ Ext.define('Coon.report.util', {
10
10
  path: 'fields',
11
11
  valid: 'array',
12
12
  rules: [
13
- {path: '[].description', valid: 'string, required'},
14
- {path: '[].reportFieldCd', valid: 'string, required'},
15
- {path: '[].visibleSwitch', valid: 'boolean'},
16
- {path: '[].reportFieldTypeLookup', valid: 'uppercase, required'},
13
+ {path: 'description', valid: 'string, required'},
14
+ {path: 'reportFieldCd', valid: 'string, required'},
15
+ {path: 'visibleSwitch', valid: 'boolean'},
16
+ {path: 'reportFieldTypeLookup', valid: 'uppercase, required'},
17
17
  {
18
- path: '[].properties',
18
+ path: 'properties',
19
19
  valid: 'array',
20
20
  rules: [
21
- {path: '[].sequenceNumber', valid: 'number'},
22
- {path: '[].key', valid: 'type.string'},
23
- {path: '[].value', valid: '!type.undefined'}
21
+ {path: 'sequenceNumber', valid: 'number'},
22
+ {path: 'key', valid: 'type.string'},
23
+ {path: 'value', valid: '!type.undefined'}
24
24
  ],
25
25
  }
26
26
  ],
@@ -29,40 +29,40 @@ Ext.define('Coon.report.util', {
29
29
  path: 'plugins',
30
30
  valid: 'array',
31
31
  rules: [
32
- {path: '[].xtype', valid: 'string, required'},
33
- {path: '[].type', valid: 'string, required'},
34
- {path: '[].uiElement', valid: 'string, required'},
35
- {path: '[].jsonProperties', valid: 'string, required'},
36
- {path: '[].sequenceNumber', valid: 'number, required'},
37
- {path: '[].sortSequence', valid: 'number, required'}
32
+ {path: 'xtype', valid: 'string, required'},
33
+ {path: 'type', valid: 'string, required'},
34
+ {path: 'uiElement', valid: 'string, required'},
35
+ {path: 'jsonProperties', valid: 'string, required'},
36
+ {path: 'sequenceNumber', valid: 'number, required'},
37
+ {path: 'sortSequence', valid: 'number, required'}
38
38
  ],
39
39
  },
40
40
  {
41
41
  path: 'properties',
42
42
  valid: 'array',
43
43
  rules: [
44
- {path: '[].key', valid: 'string, required'},
45
- {path: '[].value', valid: 'string, required'},
46
- {path: '[].sequenceNumber', valid: 'string, required'}
44
+ {path: 'key', valid: 'string, required'},
45
+ {path: 'value', valid: 'string, required'},
46
+ {path: 'sequenceNumber', valid: 'string, required'}
47
47
  ],
48
48
  },
49
49
  {
50
50
  path: 'parameters',
51
51
  valid: 'array',
52
52
  rules: [
53
- {path: '[].requiredSwitch', valid: 'boolean'},
54
- {path: '[].visibleSwitch', valid: 'boolean'},
55
- {path: '[].notUsedInSQLSwitch', valid: 'boolean'},
56
- {path: '[].description', valid: 'string, required'},
57
- {path: '[].reportParameterCd', valid: 'string, required'},
58
- {path: '[].reportParameterTypeLookup', valid: 'string, required, uppercase'},
53
+ {path: 'requiredSwitch', valid: 'boolean'},
54
+ {path: 'visibleSwitch', valid: 'boolean'},
55
+ {path: 'notUsedInSQLSwitch', valid: 'boolean'},
56
+ {path: 'description', valid: 'string, required'},
57
+ {path: 'reportParameterCd', valid: 'string, required'},
58
+ {path: 'reportParameterTypeLookup', valid: 'string, required, uppercase'},
59
59
  {
60
- path: '[].properties',
60
+ path: 'properties',
61
61
  valid: 'array',
62
62
  rules: [
63
- {path: '[].key', valid: 'string, required'},
64
- {path: '[].value', valid: 'string, required'},
65
- {path: '[].sequenceNumber', valid: 'number'}
63
+ {path: 'key', valid: 'string, required'},
64
+ {path: 'value', valid: 'string, required'},
65
+ {path: 'sequenceNumber', valid: 'number'}
66
66
  ],
67
67
  }
68
68
  ],
@@ -9,6 +9,9 @@ Ext.define('Coon.uielement.component.UiCustomPanel', {
9
9
  'Coon.uielement.component.UiCustomPanelTraceWindow'
10
10
  ],
11
11
  controller: 'UiCustomController',
12
+ mixins: [
13
+ 'Coon.validator.mixin'
14
+ ],
12
15
 
13
16
  keyMap: {
14
17
  'Ctrl+Shift+Alt+F8': {
@@ -75,6 +78,9 @@ Ext.define('Coon.uielement.component.UiCustomPanel', {
75
78
  },
76
79
 
77
80
  forceShowHeader(_, title) {
81
+ if (this.assert.is_string_required(title).invalid) {
82
+ return;
83
+ }
78
84
  if (typeof title !== 'string' || !title) {
79
85
  return;
80
86
  }
package/src/util.js CHANGED
@@ -73,19 +73,17 @@ Ext.define('Coon.util', {
73
73
  }
74
74
  return path.reduce((acc, pathProp) => {
75
75
  if (acc) {
76
+ if (pathProp.startsWith('[') && pathProp.endsWith(']')) {
77
+ pathProp = pathProp.slice(1, -1) || 0;
78
+ if (Number.isInteger(parseInt(pathProp))) {
79
+ acc = acc[parseInt(pathProp)];
80
+ return acc;
81
+ }
82
+ }
76
83
  if (Ext.isObject(acc)) {
77
84
  acc = acc[pathProp];
78
85
  return acc;
79
86
  }
80
- if (Array.isArray(acc)) {
81
- if (pathProp.startsWith('[') && pathProp.endsWith(']')) {
82
- pathProp = pathProp.slice(1, -1) || 0;
83
- if (Number.isInteger(parseInt(pathProp))) {
84
- acc = acc[parseInt(pathProp)];
85
- return acc;
86
- }
87
- }
88
- }
89
87
  } else {
90
88
  path = [];
91
89
  acc = defaultValue;
@@ -210,7 +208,7 @@ Ext.define('Coon.util', {
210
208
  const bAcc = acc;
211
209
  acc = this.safeCall(fn, acc);
212
210
  if (debug) {
213
- // eslint-disable-next-line no-console
211
+ // eslint-disable-next-line no-console
214
212
  console.debug(`\n \x1b[36m\x1b[4m BEFORE: \x1b[0m ${fn.toString()}`);
215
213
  // eslint-disable-next-line no-console
216
214
  console.dir(bAcc, {depth: debug.depth || 5});
@@ -228,7 +226,22 @@ Ext.define('Coon.util', {
228
226
  return acc;
229
227
  },
230
228
 
231
- copyToClipboard(copiedData) {
229
+ getHtaEl() {
230
+ const textArea = document.createElement('textarea');
231
+ textArea.style.position = 'fixed';
232
+ textArea.style.top = 0;
233
+ textArea.style.left = 0;
234
+ textArea.style.width = '2em';
235
+ textArea.style.height = '2em';
236
+ textArea.style.padding = 0;
237
+ textArea.style.border = 'none';
238
+ textArea.style.outline = 'none';
239
+ textArea.style.boxShadow = 'none';
240
+ textArea.style.background = 'transparent';
241
+ return textArea;
242
+ },
243
+
244
+ copyToClipboard(copiedData, successText = 'Скопировано успешно') {
232
245
  try {
233
246
  if (!Ext.browser.is.Firefox && navigator && navigator.clipboard) {
234
247
  navigator.permissions.query({name: 'clipboard-write'}).then((result) => {
@@ -243,13 +256,14 @@ Ext.define('Coon.util', {
243
256
  if (window.clipboardData && window.clipboardData.setData) {
244
257
  window.clipboardData.setData('text', copiedData);
245
258
  }
246
- if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
247
- const hiddenTextArea = this.getHtaEl();
248
- hiddenTextArea.value = copiedData;
249
- hiddenTextArea.focus();
250
- hiddenTextArea.select();
251
- return document.execCommand('copy');
252
- }
259
+ const hiddenTextArea = this.getHtaEl();
260
+ hiddenTextArea.value = copiedData;
261
+ document.body.appendChild(hiddenTextArea);
262
+ hiddenTextArea.focus();
263
+ hiddenTextArea.select();
264
+ document.execCommand('copy');
265
+ document.body.removeChild(hiddenTextArea);
266
+ Ext.toast({html: successText, cls: ['toast-success']});
253
267
  } catch (ex) {
254
268
  return prompt('Copy to clipboard: Ctrl+C, Enter', copiedData);
255
269
  }
@@ -369,106 +383,6 @@ Ext.define('Coon.util', {
369
383
  return acc;
370
384
  },
371
385
 
372
- /**
373
- *
374
- * @param {Object} obj
375
- * @param {Array} rules
376
- * @example
377
- * rules: [
378
- * {path: 'a.b.c', valid: 'string,nonempty,length.-.30,', msg: 'invalid string'}
379
- * ]
380
- */
381
- isObjectValid(obj, rules) {
382
- const getValid = (valid) => {
383
- if (typeof valid === 'string') {
384
- return valid.split(',').map((el) => el.trim());
385
- }
386
- if (Array.isArray(valid)) {
387
- return valid;
388
- }
389
- };
390
- const checkValidity = (validProps, value) => validProps.find((prop) => {
391
- const [name, ...args] = prop.split('.');
392
- if (typeof validators[name] === 'function') {
393
- return !(
394
- validators[name](value, ...args)
395
- );
396
- }
397
- });
398
- // validators
399
- const validators = {
400
- empty: (v) => Ext.isEmpty(v),
401
- required: (v) => !Ext.isEmpty(v),
402
- uppercase: (v) => typeof v === 'string' && v.toUpperCase() === v,
403
- lowercase: (v) => typeof v === 'string' && v.toLowerCase() === v,
404
- true: (v) => v === true,
405
- false: (v) => v === false,
406
- allowblank: (v) => true,
407
- type: (v, expectedType) => {
408
- if (expectedType === 'null') {
409
- return v === null;
410
- }
411
- if (expectedType === 'array') {
412
- return Array.isArray(v);
413
- }
414
- if (expectedType === 'object') {
415
- return Ext.isObject(v);
416
- }
417
- return typeof v === expectedType;
418
- },
419
- not: (name, ...args) => {
420
- if (typeof validators[name] !== 'function') {
421
- throw new Error(`validator [${name}] is not exist!`);
422
- }
423
- return (v, ...args) => validators[name](v, ...args);
424
- },
425
- };
426
- validators['!type'] = (v, typename) => !validators.type(v, typename);
427
- validators.string = (v) => validators.type(v, 'string');
428
- validators.array = (v) => validators.type(v, 'array');
429
- validators.boolean = (v) => validators.type(v, 'boolean');
430
- validators.number = (v) => validators.type(v, 'number');
431
- validators.object = (v) => validators.type(v, 'object');
432
- // EOF validators
433
- const getErrors = (obj, rules) => {
434
- const errors = Coon.util.filterMap(rules, (rule) => {
435
- if (!rule.path) {
436
- return;
437
- }
438
- const value = Coon.util.getByPath(obj, rule.path);
439
- const validTags = getValid(rule.valid) || [];
440
- let subErrors;
441
- let isInvalid = typeof valid === 'function' ?
442
- validTags(value) :
443
- checkValidity(validTags, value);
444
- if (
445
- !Ext.isEmpty(value) &&
446
- !isInvalid &&
447
- Array.isArray(rule.rules) &&
448
- rule.rules.length
449
- ) {
450
- const subResult = getErrors(value, rule.rules);
451
- if (!subResult.valid) {
452
- isInvalid = false;
453
- subErrors = subResult.errors.join('\n');
454
- }
455
- }
456
- if (isInvalid) {
457
- rule.msg = rule.msg || `[by path: ${rule.path}], value [${value}] is invalid`;
458
- if (subErrors) {
459
- rule.msg = rule.msg + '\n' + subErrors;
460
- }
461
- return rule.msg;
462
- }
463
- });
464
- return {
465
- valid: !errors.length,
466
- errors,
467
- };
468
- };
469
- return getErrors(obj, rules);
470
- },
471
-
472
386
  getAllCommandsList() {
473
387
  if (Coon.util.locals.getAllCommandsList) {
474
388
  return Coon.util.locals.getAllCommandsList;
@@ -665,10 +579,10 @@ Ext.define('Coon.util', {
665
579
 
666
580
  getInstanceIdProperties(instance) {
667
581
  if (instance.id ||
668
- instance.xtype ||
669
- instance.ptype ||
670
- instance.$className ||
671
- Ext.isObject(instance.initialConfig)
582
+ instance.xtype ||
583
+ instance.ptype ||
584
+ instance.$className ||
585
+ Ext.isObject(instance.initialConfig)
672
586
  ) {
673
587
  return Object.assign(
674
588
  {},
@@ -756,6 +670,7 @@ Ext.define('Coon.util', {
756
670
  }
757
671
  }
758
672
  }
673
+
759
674
  return detectCycle(data);
760
675
  },
761
676
 
package/src/util.scss ADDED
@@ -0,0 +1,4 @@
1
+ .x-window.toast-success {
2
+ border: 1px solid green !important;
3
+ border-radius: 2px !important;
4
+ }
@@ -0,0 +1,184 @@
1
+ Ext.define('Coon.validator', {
2
+ singleton: true,
3
+
4
+ alternateClassName: 'Coon.v',
5
+
6
+ constructor() {
7
+ const validators = {
8
+ empty: (v) => Ext.isEmpty(v),
9
+ notempty: (v) => !Ext.isEmpty(v),
10
+ required: (v) => !Ext.isEmpty(v),
11
+ uppercase: (v) => typeof v === 'string' && v.toUpperCase() === v,
12
+ lowercase: (v) => typeof v === 'string' && v.toLowerCase() === v,
13
+ true: (v) => v === true,
14
+ false: (v) => v === false,
15
+ allowblank: (v) => true,
16
+ type: (v, expectedType) => {
17
+ if (expectedType === 'null') {
18
+ return v === null;
19
+ }
20
+ if (expectedType === 'array') {
21
+ return Array.isArray(v);
22
+ }
23
+ if (expectedType === 'object') {
24
+ return Ext.isObject(v);
25
+ }
26
+ return typeof v === expectedType;
27
+ },
28
+ not: (name, ...args) => {
29
+ if (typeof validators[name] !== 'function') {
30
+ throw new Error(`validator [${name}] is not exist!`);
31
+ }
32
+ return (v, ...args) => validators[name](v, ...args);
33
+ },
34
+ };
35
+ validators['!type'] = (v, typename) => !validators.type(v, typename);
36
+ validators.string = (v) => validators.type(v, 'string');
37
+ validators.array = (v) => validators.type(v, 'array');
38
+ validators.boolean = (v) => validators.type(v, 'boolean');
39
+ validators.number = (v) => validators.type(v, 'number');
40
+ validators.object = (v) => validators.type(v, 'object');
41
+ this.addValidator = (name, validator, override) => {
42
+ if (!validators[name] || override) {
43
+ validators[name] = validator;
44
+ }
45
+ };
46
+ this.getValidator = (name) => validators[name];
47
+ this.getValidators = () => validators;
48
+ },
49
+
50
+
51
+ /**
52
+ *
53
+ * @param {Object} obj
54
+ * @param {Array} rules
55
+ * @example
56
+ * rules: [
57
+ * {path: 'a.b.c', valid: 'string,nonempty,length.-.30,', msg: 'invalid string'}
58
+ * ]
59
+ */
60
+ isObjectValid(obj, rules) {
61
+ if (!Ext.isObject(obj)) {
62
+ return {
63
+ valid: false,
64
+ errors: ['object is not valid'],
65
+ };
66
+ }
67
+ const getValid = (valid) => {
68
+ if (typeof valid === 'string') {
69
+ return valid.split(',').map((el) => el.trim());
70
+ }
71
+ if (Array.isArray(valid)) {
72
+ return valid;
73
+ }
74
+ };
75
+ const checkValidity = (validProps, value) => validProps.find((prop) => {
76
+ const [name, ...args] = prop.split('.');
77
+ if (typeof validators[name] === 'function') {
78
+ return validators[name](value, ...args);
79
+ } else {
80
+ console.error(`validator [${name}] is not exist!`);
81
+ return false;
82
+ }
83
+ });
84
+ const validators = this.getValidators();
85
+ const getErrors = (src, rules) => {
86
+ if (Array.isArray(src)) {
87
+ for (const el of src) {
88
+ const state = getErrors(el, rules);
89
+ if (!state.valid) {
90
+ return state;
91
+ }
92
+ }
93
+ return {valid: true, errors: []};
94
+ }
95
+ const errors = Coon.util.filterMap(rules, (rule) => {
96
+ let errorMessage = '';
97
+ if (!rule.path) {
98
+ return;
99
+ }
100
+ const value = Coon.util.getByPath(src, rule.path);
101
+ const validTags = getValid(rule.valid) || [];
102
+ let subResult;
103
+ const isValid = checkValidity(validTags, value);
104
+ if (
105
+ isValid &&
106
+ Array.isArray(rule.rules) &&
107
+ rule.rules.length
108
+ ) {
109
+ subResult = getErrors(value, rule.rules);
110
+ }
111
+ if (!isValid) {
112
+ errorMessage += rule.msg ||
113
+ `The property on the path "${rule.path}" with the value ${value} is invalid, validity check: ${rule.valid}`;
114
+ }
115
+ if (subResult && !subResult.valid) {
116
+ errorMessage += '\n---\n ' + subResult.errors.join('\n ');
117
+ }
118
+ return errorMessage || false;
119
+ });
120
+ return {
121
+ valid: !errors.length,
122
+ errors,
123
+ };
124
+ };
125
+ return getErrors(obj, rules);
126
+ },
127
+
128
+ }, function() {
129
+ this.assert = new Proxy(this, {
130
+ get: function(target, name) {
131
+ if (!name.startsWith('is_')) {
132
+ return target[name];
133
+ }
134
+ const tokens = name.slice(3)
135
+ .split('_')
136
+ .map((name) => {
137
+ if (!Coon.validator.getValidator(name)) {
138
+ return {name};
139
+ }
140
+ return {
141
+ fn: (tested) => {
142
+ if (tested.invalid) {
143
+ return tested;
144
+ }
145
+ const isValid = Coon.validator.getValidator(name).call(this, tested.value);
146
+ tested.invalid = !isValid;
147
+ tested.steps.push({[name]: isValid});
148
+ return tested;
149
+ },
150
+ name,
151
+ };
152
+ });
153
+ if (tokens.find(({fn}) => !fn)) {
154
+ return () => {
155
+ const tested = {steps: []};
156
+ tokens.filter(({fn}) => !fn)
157
+ .map(({name}) => name)
158
+ .forEach((name) => {
159
+ tested.steps.push({[name]: `validator not found`});
160
+ });
161
+ tested.invalid = true;
162
+ return tested;
163
+ };
164
+ }
165
+ if (tokens.length === 0) {
166
+ return (tested) => {
167
+ tested.valid = true;
168
+ return tested;
169
+ };
170
+ }
171
+ return (value) => Coon.util.chained(
172
+ tokens.map((el) => el.fn),
173
+ {value, steps: []}
174
+ );
175
+ },
176
+ });
177
+ });
178
+
179
+ Ext.define('Coon.validator.mixin', {
180
+ constructor(validator) {
181
+ this.assert = Coon.validator.assert;
182
+ this.callParent(arguments);
183
+ },
184
+ });
package/src/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  Ext.define('Coon.version', {
2
2
  singleton: true,
3
- number: '3.0.58',
3
+ number: '3.0.60',
4
4
  });