glib-web 4.1.2 → 4.1.3

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.
@@ -8,7 +8,7 @@
8
8
  <template v-if="values.length > 0">
9
9
  <input type="hidden" v-for="(value, index) in values" :value="value" :key="index" :name="fieldName" />
10
10
  </template>
11
- <input v-else type="hidden" :name="fieldName" :value="null" />
11
+ <input v-else type="hidden" :name="fieldName" :value="spec.uncheckValue" />
12
12
  </div>
13
13
  </template>
14
14
 
@@ -1,4 +1,5 @@
1
1
  import { vueApp } from "../../store";
2
+ import { ValidationFactory } from "../validation";
2
3
 
3
4
  export default {
4
5
  methods: {
@@ -24,26 +25,9 @@ export default {
24
25
  $validation(rules) {
25
26
  var augmentedRules = rules || [];
26
27
  Utils.type.ifObject(this.spec.validation, val => {
27
- Utils.type.ifObject(val.required, spec => {
28
- const validationFunc = (v) => {
29
- if (!Utils.type.isNotNull(v)) return spec.message;
30
- if (Array.isArray(v) && v.length <= 0) return spec.message;
31
- if (Utils.type.isString(v) && v.length <= 0) return spec.message;
32
-
33
-
34
- return true;
35
- };
36
- augmentedRules = augmentedRules.concat([validationFunc]);
37
- });
38
- Utils.type.ifObject(val.format, spec => {
39
- augmentedRules = augmentedRules.concat([
40
- v => {
41
- if (v && !v.toString().match(spec.regex)) {
42
- return spec.message;
43
- }
44
- return true;
45
- }
46
- ]);
28
+ Object.keys(val).forEach((key) => {
29
+ const validator = ValidationFactory.getValidator(key, val[key]);
30
+ augmentedRules = augmentedRules.concat([validator.build.bind(validator)]);
47
31
  });
48
32
  });
49
33
  return augmentedRules;
@@ -0,0 +1,179 @@
1
+ class AbstractValidator {
2
+ constructor(validationOptions) {
3
+ this.validationOptions = validationOptions;
4
+ }
5
+
6
+ build(model) {
7
+ return true;
8
+ }
9
+
10
+ isAllowBlank() {
11
+ return !!this.validationOptions.allow_blank || !!this.validationOptions.allow_nil;
12
+ }
13
+ }
14
+
15
+ function isPresent(value) {
16
+ if (value == undefined) return false;
17
+ if (value == null) return false;
18
+ if (Array.isArray(value) && value.length <= 0) return false;
19
+ if (typeof value == 'string' && value.length <= 0) return false;
20
+ if (typeof value == 'object' && Object.keys(value).length <= 0) return false;
21
+
22
+ return true;
23
+ }
24
+
25
+ class PresenceValidator extends AbstractValidator {
26
+ build(model) {
27
+ return isPresent(model) ? true : this.validationOptions.message;
28
+ }
29
+ }
30
+ class RequiredValidator extends PresenceValidator { }
31
+
32
+ class AbsenceValidator extends AbstractValidator {
33
+ build(model) {
34
+ return !isPresent(model) ? true : this.validationOptions.message;
35
+ }
36
+ }
37
+
38
+ class AcceptanceValidator extends AbstractValidator {
39
+ build(model) {
40
+ if (this.isAllowBlank() && !isPresent(model)) return true;
41
+
42
+ const { accept } = this.validationOptions;
43
+ return accept.includes(model) ? true : this.validationOptions.message;
44
+ }
45
+ }
46
+
47
+ class NumericalityValidator extends AbstractValidator {
48
+ build(model) {
49
+ if (this.isAllowBlank() && !isPresent(model)) return true;
50
+
51
+ let result = true;
52
+ ['greater_than', 'greater_than_or_equal_to', 'equal_to', 'less_than', 'less_than_or_equal_to', 'other_than', 'odd', 'even'].forEach((key) => {
53
+ let count = this.validationOptions[key];
54
+ if (!isPresent(count)) return;
55
+ if (this.validate(key, count, model)) return;
56
+
57
+ result = this.errorMessage(key, count);
58
+ });
59
+
60
+ return result;
61
+ }
62
+
63
+ validate(key, count, value) {
64
+ const obj = {
65
+ 'greater_than': () => count < value,
66
+ 'greater_than_or_equal_to': () => count <= value,
67
+ 'equal_to': () => count == value,
68
+ 'less_than': () => count > value,
69
+ 'less_than_or_equal_to': () => count >= value,
70
+ 'other_than': () => count != value,
71
+ 'in': () => count.includes(value),
72
+ 'odd': () => value % 2 == 1,
73
+ 'even': () => value % 2 == 0
74
+ };
75
+
76
+ return obj[key]();
77
+ }
78
+
79
+ errorMessage(key, count) {
80
+ const message = this.validationOptions.message;
81
+ if (typeof message == 'string') return message;
82
+
83
+ return message[key].replace('%{count}', count);
84
+ }
85
+ }
86
+
87
+ class FormatValidator extends AbstractValidator {
88
+ build(model) {
89
+ if (this.isAllowBlank() && !isPresent(model)) return true;
90
+
91
+ const regex = this.validationOptions.with || this.validationOptions.without || this.validationOptions.regex;
92
+ let match = !!(model || '').match(regex);
93
+ match = this.isInverse() ? !match : match;
94
+
95
+ return match ? true : this.validationOptions.message;
96
+ }
97
+
98
+ isInverse() {
99
+ return !!this.validationOptions.without;
100
+ }
101
+ }
102
+
103
+ class InclusionValidator extends AbstractValidator {
104
+ build(model) {
105
+ if (this.isAllowBlank() && !isPresent(model)) return true;
106
+
107
+ const within = this.validationOptions.in || this.validationOptions.within;
108
+
109
+ return within.includes(model) ? true : this.validationOptions.message;
110
+ }
111
+ }
112
+
113
+ class ExclusionValidator extends AbstractValidator {
114
+ build(model) {
115
+ if (this.isAllowBlank() && !isPresent(model)) return true;
116
+
117
+ const within = this.validationOptions.in || this.validationOptions.within;
118
+
119
+ return !within.includes(model) ? true : this.validationOptions.message;
120
+ }
121
+ }
122
+
123
+ class LengthValidator extends AbsenceValidator {
124
+ build(model) {
125
+ model ||= '';
126
+ if (this.isAllowBlank() && !isPresent(model)) return true;
127
+
128
+ const { minimum, maximum } = this.validationOptions;
129
+ let result;
130
+ if (isPresent(minimum)) {
131
+ result = model.length > minimum ? true : this.errorMessage('too_short', minimum);
132
+ }
133
+ if (result !== true) return result;
134
+ if (isPresent(maximum)) {
135
+ result = model.length < maximum ? true : this.errorMessage('too_long', maximum);
136
+ }
137
+ if (result !== true) return result;
138
+ if (isPresent(this.validationOptions.is)) {
139
+ result = model.length === this.validationOptions.is ? true : this.errorMessage('wrong_length', this.validationOptions.is);
140
+ }
141
+ if (result !== true) return result;
142
+ if (isPresent(this.validationOptions.in)) {
143
+ result = (model.length >= this.validationOptions.is || model.length <= this.validatorOptions.is) ? true : this.errorMessage('wrong_length', this.validationOptions.in);
144
+ }
145
+
146
+ return result;
147
+ }
148
+
149
+ errorMessage(key, count) {
150
+ const message = this.validationOptions.message;
151
+ const singular = count <= 1;
152
+ if (typeof message == 'string') {
153
+ return message.replace('%{count}', count);
154
+ }
155
+
156
+ return message[key][singular ? 'one' : 'other'].replace('%{count}', count);
157
+ }
158
+ }
159
+
160
+ const clsMap = {
161
+ 'absence': AbsenceValidator,
162
+ 'presence': PresenceValidator,
163
+ 'required': RequiredValidator,
164
+ 'acceptance': AcceptanceValidator,
165
+ 'numericality': NumericalityValidator,
166
+ 'format': FormatValidator,
167
+ 'inclusion': InclusionValidator,
168
+ 'exclusion': ExclusionValidator,
169
+ 'length': LengthValidator
170
+ };
171
+
172
+ class ValidationFactory {
173
+ static getValidator(validatorName, validatorOptions) {
174
+ return new clsMap[validatorName](validatorOptions);
175
+ }
176
+ }
177
+
178
+ export { ValidationFactory }
179
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glib-web",
3
- "version": "4.1.2",
3
+ "version": "4.1.3",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {