@kklab/fortress-validator 1.0.10 → 1.0.12
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 -1
- package/dist/FieldValidator.d.ts +23 -2
- package/dist/index.js +269 -171
- package/dist/index.umd.js +1 -1
- package/dist/rules/httpOrHttps.d.ts +3 -0
- package/dist/rules/ip.d.ts +6 -0
- package/dist/rules/ipv4.d.ts +6 -0
- package/dist/rules/ipv6.d.ts +6 -0
- package/dist/rules/notContainsAll.d.ts +2 -2
- package/dist/rules/notContainsAny.d.ts +2 -2
- package/dist/rules/protocol.d.ts +6 -0
- package/dist/rules/stringNotContainsAll.d.ts +2 -2
- package/dist/rules/stringNotContainsAny.d.ts +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -92,9 +92,13 @@ const result = validator
|
|
|
92
92
|
| `fileMaxSize` | Passes if the field's value is not greater than the specified maximum file size. |
|
|
93
93
|
| `fileMinSize` | Passes if the field's value is at least the specified minimum file size. |
|
|
94
94
|
| `fileSize` | Passes if the field's value matches the specified file size. |
|
|
95
|
-
| `http` | Passes if the field's value starts with "http://"
|
|
95
|
+
| `http` | Passes if the field's value starts with "http://". |
|
|
96
|
+
| `httpOrHttps` | Passes if the field's value starts with "http://" or "https://". |
|
|
96
97
|
| `https` | Passes if the field's value starts with "https://". |
|
|
97
98
|
| `integer` | Passes if the field's value is an integer. |
|
|
99
|
+
| `ip` | Passes if the field's value is a valid IP address. |
|
|
100
|
+
| `ipv4` | Passes if the field's value is a valid IPv4 address. |
|
|
101
|
+
| `ipv6` | Passes if the field's value is a valid IPv6 address. |
|
|
98
102
|
| `iso8601` | Passes if the field's value is a valid ISO 8601 date. |
|
|
99
103
|
| `json` | Passes if the field's value is a valid JSON string. |
|
|
100
104
|
| `jsonSchema` | Passes if the field's value matches the specified JSON schema. |
|
|
@@ -111,6 +115,7 @@ const result = validator
|
|
|
111
115
|
| `number` | Passes if the field's value is a number. |
|
|
112
116
|
| `numeric` | Passes if the field's value contains only numeric characters. |
|
|
113
117
|
| `oneOf` | Passes if the field's value is one of the specified values. |
|
|
118
|
+
| `protocol` | Passes if the field's value starts with the specified protocol. |
|
|
114
119
|
| `regex` | Passes if the field's value matches the specified regular expression. |
|
|
115
120
|
| `required` | Passes if the field's value is not empty. |
|
|
116
121
|
| `requiredWhen` | Passes if the field's value is not empty when the specified condition is true. |
|
package/dist/FieldValidator.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ declare class FieldValidator {
|
|
|
9
9
|
private ruleFunctions;
|
|
10
10
|
private conditions;
|
|
11
11
|
private shouldSkip;
|
|
12
|
+
private appliedProtocols;
|
|
12
13
|
constructor({ name, locale, fallbackLocale, locales, rules, }: FieldValidatorArguments);
|
|
13
14
|
get formattedName(): string;
|
|
14
15
|
get messages(): Messages;
|
|
@@ -141,17 +142,33 @@ declare class FieldValidator {
|
|
|
141
142
|
*/
|
|
142
143
|
fileSize(size: number): this;
|
|
143
144
|
/**
|
|
144
|
-
* Passes if the field's value starts with "http://"
|
|
145
|
+
* Passes if the field's value starts with the "http://" protocol.
|
|
145
146
|
*/
|
|
146
147
|
http(): this;
|
|
147
148
|
/**
|
|
148
|
-
* Passes if the field's value starts with "https://".
|
|
149
|
+
* Passes if the field's value starts with the "http://" or "https://" protocols.
|
|
150
|
+
*/
|
|
151
|
+
httpOrHttps(): this;
|
|
152
|
+
/**
|
|
153
|
+
* Passes if the field's value starts with the "https://" protocol.
|
|
149
154
|
*/
|
|
150
155
|
https(): this;
|
|
151
156
|
/**
|
|
152
157
|
* Passes if the field's value is an integer.
|
|
153
158
|
*/
|
|
154
159
|
integer(): this;
|
|
160
|
+
/**
|
|
161
|
+
* Passes if the field's value is a valid IP address.
|
|
162
|
+
*/
|
|
163
|
+
ip(): this;
|
|
164
|
+
/**
|
|
165
|
+
* Passes if the field's value is a valid IPv4 address.
|
|
166
|
+
*/
|
|
167
|
+
ipv4(): this;
|
|
168
|
+
/**
|
|
169
|
+
* Passes if the field's value is a valid IPv6 address.
|
|
170
|
+
*/
|
|
171
|
+
ipv6(): this;
|
|
155
172
|
/**
|
|
156
173
|
* Passes if the field's value is a valid ISO 8601 date.
|
|
157
174
|
*/
|
|
@@ -204,6 +221,10 @@ declare class FieldValidator {
|
|
|
204
221
|
* Passes if the field's value is not one of the specified values.
|
|
205
222
|
*/
|
|
206
223
|
notOneOf(values: string[]): this;
|
|
224
|
+
/**
|
|
225
|
+
* Passes if the field's value starts with the specified protocol.
|
|
226
|
+
*/
|
|
227
|
+
protocol(protocol: string | string[]): this;
|
|
207
228
|
/**
|
|
208
229
|
* Passes if the field's value is a number.
|
|
209
230
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,27 +1,31 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
const
|
|
1
|
+
var q = Object.defineProperty;
|
|
2
|
+
var O = (t, e, r) => e in t ? q(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
|
|
3
|
+
var o = (t, e, r) => (O(t, typeof e != "symbol" ? e + "" : e, r), r);
|
|
4
|
+
const A = (t) => {
|
|
5
|
+
const e = ",、;:!?。()《》「」『』【】〔〕", r = "\\x20-\\x7E", s = new RegExp(`\\s*([${e}])`, "gu"), l = new RegExp(`([${e}])\\s*([${r}])`, "gu"), u = new RegExp(`([^${r}${e}])([${r}])`, "gu"), _ = new RegExp(`([${r}])([^${r}${e}])`, "gu");
|
|
6
|
+
return t.replace(s, "$1").replace(l, "$1$2").replace(u, "$1 $2").replace(_, "$1 $2").replace(/ +/g, " ");
|
|
7
|
+
}, n = (t, e = 0) => new Intl.NumberFormat(void 0, {
|
|
5
8
|
minimumFractionDigits: e,
|
|
6
9
|
maximumFractionDigits: e
|
|
7
|
-
}).format(t),
|
|
8
|
-
class
|
|
10
|
+
}).format(t), M = (t) => Object.prototype.toString.call(t).toLowerCase().slice(8, -1), a = (t) => t == null || t === "" || Array.isArray(t) && t.length < 1, i = (t) => `"${t}"`;
|
|
11
|
+
class k {
|
|
9
12
|
constructor({
|
|
10
13
|
name: e,
|
|
11
14
|
locale: r,
|
|
12
|
-
fallbackLocale:
|
|
13
|
-
locales:
|
|
15
|
+
fallbackLocale: s,
|
|
16
|
+
locales: l,
|
|
14
17
|
rules: u
|
|
15
18
|
}) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
this
|
|
19
|
+
o(this, "name");
|
|
20
|
+
o(this, "locale");
|
|
21
|
+
o(this, "fallbackLocale");
|
|
22
|
+
o(this, "locales");
|
|
23
|
+
o(this, "rules");
|
|
24
|
+
o(this, "ruleFunctions", {});
|
|
25
|
+
o(this, "conditions", {});
|
|
26
|
+
o(this, "shouldSkip", !1);
|
|
27
|
+
o(this, "appliedProtocols", {});
|
|
28
|
+
this.name = e, this.locale = r, this.fallbackLocale = s, this.locales = l, this.rules = u;
|
|
25
29
|
}
|
|
26
30
|
get formattedName() {
|
|
27
31
|
return this.name.toLowerCase();
|
|
@@ -50,31 +54,31 @@ class C {
|
|
|
50
54
|
return this.rules[e];
|
|
51
55
|
}
|
|
52
56
|
buildRuleFunction(e, r) {
|
|
53
|
-
return (
|
|
54
|
-
if (s
|
|
57
|
+
return (s) => {
|
|
58
|
+
if (a(s) && !this.mandatoryRules.includes(e))
|
|
55
59
|
return !0;
|
|
56
|
-
const
|
|
57
|
-
return typeof
|
|
60
|
+
const l = this.getRule(e)(r)(s);
|
|
61
|
+
return typeof l == "string" ? l : l === !0 ? !0 : this.buildRuleFunctionMessage(e, r, s);
|
|
58
62
|
};
|
|
59
63
|
}
|
|
60
|
-
buildRuleFunctionMessage(e, r,
|
|
61
|
-
const
|
|
62
|
-
if (typeof
|
|
63
|
-
const u =
|
|
64
|
-
if (!(u in
|
|
64
|
+
buildRuleFunctionMessage(e, r, s) {
|
|
65
|
+
const l = this.getMessage(e)(this.formattedName, r);
|
|
66
|
+
if (typeof l == "object") {
|
|
67
|
+
const u = M(s);
|
|
68
|
+
if (!(u in l))
|
|
65
69
|
throw new Error(`The message for the "${e}" rule of the "${u}" type is missing.`);
|
|
66
|
-
return
|
|
70
|
+
return A(l[u]);
|
|
67
71
|
}
|
|
68
|
-
return
|
|
72
|
+
return A(l);
|
|
69
73
|
}
|
|
70
74
|
pushRuleFunction(e, r) {
|
|
71
75
|
if (e in this.conditions && !this.conditions[e])
|
|
72
76
|
return this;
|
|
73
|
-
const
|
|
74
|
-
return this.ruleFunctions
|
|
77
|
+
const s = this.buildRuleFunction(e, r);
|
|
78
|
+
return this.ruleFunctions[e] = s, this;
|
|
75
79
|
}
|
|
76
80
|
getRuleFunctions() {
|
|
77
|
-
return this.ruleFunctions;
|
|
81
|
+
return Object.values(this.ruleFunctions);
|
|
78
82
|
}
|
|
79
83
|
/**
|
|
80
84
|
* Collects the rule functions.
|
|
@@ -88,10 +92,11 @@ class C {
|
|
|
88
92
|
validate(e) {
|
|
89
93
|
if (this.shouldSkip)
|
|
90
94
|
return !0;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
const r = this.getRuleFunctions();
|
|
96
|
+
for (const s of r) {
|
|
97
|
+
const l = s(e);
|
|
98
|
+
if (typeof l == "string")
|
|
99
|
+
return l;
|
|
95
100
|
}
|
|
96
101
|
return !0;
|
|
97
102
|
}
|
|
@@ -110,8 +115,8 @@ class C {
|
|
|
110
115
|
/**
|
|
111
116
|
* Passes if the field's value is a date that occurs after the specified date.
|
|
112
117
|
*/
|
|
113
|
-
after(e, r,
|
|
114
|
-
return this.apply(this.after.name, { date: e, format: r, displayFormat:
|
|
118
|
+
after(e, r, s, l = !0) {
|
|
119
|
+
return this.apply(this.after.name, { date: e, format: r, displayFormat: s, strict: l });
|
|
115
120
|
}
|
|
116
121
|
/**
|
|
117
122
|
* Passes if the field's value contains only letters.
|
|
@@ -152,8 +157,8 @@ class C {
|
|
|
152
157
|
/**
|
|
153
158
|
* Passes if the field's value is a date that occurs before the specified date.
|
|
154
159
|
*/
|
|
155
|
-
before(e, r,
|
|
156
|
-
return this.apply(this.before.name, { date: e, format: r, displayFormat:
|
|
160
|
+
before(e, r, s, l = !0) {
|
|
161
|
+
return this.apply(this.before.name, { date: e, format: r, displayFormat: s, strict: l });
|
|
157
162
|
}
|
|
158
163
|
/**
|
|
159
164
|
* Passes if the field's value is between the specified minimum and maximum values.
|
|
@@ -264,16 +269,22 @@ class C {
|
|
|
264
269
|
return this.apply(this.fileSize.name, { size: e });
|
|
265
270
|
}
|
|
266
271
|
/**
|
|
267
|
-
* Passes if the field's value starts with "http://"
|
|
272
|
+
* Passes if the field's value starts with the "http://" protocol.
|
|
268
273
|
*/
|
|
269
274
|
http() {
|
|
270
|
-
return this.apply(this.http.name);
|
|
275
|
+
return this.appliedProtocols[this.http.name] = !0, this.apply(this.http.name);
|
|
271
276
|
}
|
|
272
277
|
/**
|
|
273
|
-
* Passes if the field's value starts with "https://".
|
|
278
|
+
* Passes if the field's value starts with the "http://" or "https://" protocols.
|
|
279
|
+
*/
|
|
280
|
+
httpOrHttps() {
|
|
281
|
+
return this.appliedProtocols[this.http.name] = !0, this.appliedProtocols[this.https.name] = !0, this.apply(this.httpOrHttps.name);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Passes if the field's value starts with the "https://" protocol.
|
|
274
285
|
*/
|
|
275
286
|
https() {
|
|
276
|
-
return this.apply(this.https.name);
|
|
287
|
+
return this.appliedProtocols[this.https.name] = !0, this.apply(this.https.name);
|
|
277
288
|
}
|
|
278
289
|
/**
|
|
279
290
|
* Passes if the field's value is an integer.
|
|
@@ -281,6 +292,27 @@ class C {
|
|
|
281
292
|
integer() {
|
|
282
293
|
return this.apply(this.integer.name);
|
|
283
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Passes if the field's value is a valid IP address.
|
|
297
|
+
*/
|
|
298
|
+
ip() {
|
|
299
|
+
const e = Object.keys(this.appliedProtocols).length > 0;
|
|
300
|
+
return this.apply(this.ip.name, { includeProtocol: e });
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Passes if the field's value is a valid IPv4 address.
|
|
304
|
+
*/
|
|
305
|
+
ipv4() {
|
|
306
|
+
const e = Object.keys(this.appliedProtocols).length > 0;
|
|
307
|
+
return this.apply(this.ipv4.name, { includeProtocol: e });
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Passes if the field's value is a valid IPv6 address.
|
|
311
|
+
*/
|
|
312
|
+
ipv6() {
|
|
313
|
+
const e = Object.keys(this.appliedProtocols).length > 0;
|
|
314
|
+
return this.apply(this.ipv6.name, { includeProtocol: e });
|
|
315
|
+
}
|
|
284
316
|
/**
|
|
285
317
|
* Passes if the field's value is a valid ISO 8601 date.
|
|
286
318
|
*/
|
|
@@ -359,6 +391,13 @@ class C {
|
|
|
359
391
|
notOneOf(e) {
|
|
360
392
|
return this.apply(this.notOneOf.name, { values: e });
|
|
361
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Passes if the field's value starts with the specified protocol.
|
|
396
|
+
*/
|
|
397
|
+
protocol(e) {
|
|
398
|
+
const r = Array.isArray(e) ? e : [e];
|
|
399
|
+
return r.forEach((s) => this.appliedProtocols[s] = !0), this.apply(this.protocol.name, { values: r });
|
|
400
|
+
}
|
|
362
401
|
/**
|
|
363
402
|
* Passes if the field's value is a number.
|
|
364
403
|
*/
|
|
@@ -492,7 +531,7 @@ class C {
|
|
|
492
531
|
return typeof e == "object" ? (this.conditions = e, this) : (e || (this.shouldSkip = !0), this);
|
|
493
532
|
}
|
|
494
533
|
}
|
|
495
|
-
const
|
|
534
|
+
const E = {
|
|
496
535
|
accepted: (t) => `The ${t} field must be accepted.`,
|
|
497
536
|
alpha: (t) => `The ${t} field must only contain letters.`,
|
|
498
537
|
alphaDash: (t) => `The ${t} field must only contain letters, numbers, dashes and underscores.`,
|
|
@@ -501,24 +540,24 @@ const _ = {
|
|
|
501
540
|
array: (t) => `The ${t} field must be an array.`,
|
|
502
541
|
ascii: (t) => `The ${t} field must only contain ASCII characters and symbols.`,
|
|
503
542
|
between: (t, e) => {
|
|
504
|
-
const { min: r, max:
|
|
543
|
+
const { min: r, max: s } = e;
|
|
505
544
|
return {
|
|
506
|
-
number: `The ${t} field must be between ${n(r)} and ${n(
|
|
507
|
-
array: `The ${t} field must contain items where each item is between ${n(r)} and ${n(
|
|
545
|
+
number: `The ${t} field must be between ${n(r)} and ${n(s)}.`,
|
|
546
|
+
array: `The ${t} field must contain items where each item is between ${n(r)} and ${n(s)}.`
|
|
508
547
|
};
|
|
509
548
|
},
|
|
510
549
|
betweenLength: (t, e) => {
|
|
511
|
-
const { min: r, max:
|
|
512
|
-
return `The ${t} field must be between ${n(r)} and ${n(
|
|
550
|
+
const { min: r, max: s } = e;
|
|
551
|
+
return `The ${t} field must be between ${n(r)} and ${n(s)} items.`;
|
|
513
552
|
},
|
|
514
553
|
boolean: (t) => `The ${t} field must be a boolean value.`,
|
|
515
554
|
containsAll: (t, e) => {
|
|
516
555
|
const { values: r } = e;
|
|
517
|
-
return `The ${t} field must contain all of the following values: ${r.join(", ")}.`;
|
|
556
|
+
return `The ${t} field must contain all of the following values: ${r.map(i).join(", ")}.`;
|
|
518
557
|
},
|
|
519
558
|
containsAny: (t, e) => {
|
|
520
559
|
const { values: r } = e;
|
|
521
|
-
return `The ${t} field must contain at least one of the following values: ${r.join(", ")}.`;
|
|
560
|
+
return `The ${t} field must contain at least one of the following values: ${r.map(i).join(", ")}.`;
|
|
522
561
|
},
|
|
523
562
|
declined: (t) => `The ${t} field must be declined.`,
|
|
524
563
|
different: (t, e) => {
|
|
@@ -538,10 +577,10 @@ const _ = {
|
|
|
538
577
|
},
|
|
539
578
|
file: (t) => `The ${t} field must be a file.`,
|
|
540
579
|
fileBetweenSize: (t, e) => {
|
|
541
|
-
const { min: r, max:
|
|
580
|
+
const { min: r, max: s } = e;
|
|
542
581
|
return {
|
|
543
|
-
file: `The ${t} field must be between ${n(r)} and ${n(
|
|
544
|
-
array: `The ${t} field must contain items where each item is between ${n(r)} and ${n(
|
|
582
|
+
file: `The ${t} field must be between ${n(r)} and ${n(s)} kilobytes.`,
|
|
583
|
+
array: `The ${t} field must contain items where each item is between ${n(r)} and ${n(s)} kilobytes.`
|
|
545
584
|
};
|
|
546
585
|
},
|
|
547
586
|
fileMaxSize: (t, e) => {
|
|
@@ -565,9 +604,13 @@ const _ = {
|
|
|
565
604
|
array: `The ${t} field must contain items where each item is ${n(r)} kilobytes.`
|
|
566
605
|
};
|
|
567
606
|
},
|
|
568
|
-
http: (t) => `The ${t} field must start with
|
|
569
|
-
|
|
607
|
+
http: (t) => `The ${t} field must start with the "http://" protocol.`,
|
|
608
|
+
httpOrHttps: (t) => `The ${t} field must start with the "http://" or "https://" protocols.`,
|
|
609
|
+
https: (t) => `The ${t} field must start with the "https://" protocol.`,
|
|
570
610
|
integer: (t) => `The ${t} field must be an integer.`,
|
|
611
|
+
ip: (t) => `The ${t} field must be a valid IP address.`,
|
|
612
|
+
ipv4: (t) => `The ${t} field must be a valid IPv4 address.`,
|
|
613
|
+
ipv6: (t) => `The ${t} field must be a valid IPv6 address.`,
|
|
571
614
|
json: (t) => `The ${t} field must be a valid JSON string.`,
|
|
572
615
|
length: (t, e) => {
|
|
573
616
|
const { length: r } = e;
|
|
@@ -598,11 +641,11 @@ const _ = {
|
|
|
598
641
|
},
|
|
599
642
|
notContainsAll: (t, e) => {
|
|
600
643
|
const { values: r } = e;
|
|
601
|
-
return `The ${t} field must not contain all of the following values together: ${r.join(", ")}.`;
|
|
644
|
+
return `The ${t} field must not contain all of the following values together: ${r.map(i).join(", ")}.`;
|
|
602
645
|
},
|
|
603
646
|
notContainsAny: (t, e) => {
|
|
604
647
|
const { values: r } = e;
|
|
605
|
-
return `The ${t} field must not contain any of the following values: ${r.join(", ")}.`;
|
|
648
|
+
return `The ${t} field must not contain any of the following values: ${r.map(i).join(", ")}.`;
|
|
606
649
|
},
|
|
607
650
|
notEquals: (t, e) => {
|
|
608
651
|
const { value: r } = e;
|
|
@@ -610,13 +653,21 @@ const _ = {
|
|
|
610
653
|
},
|
|
611
654
|
notOneOf: (t, e) => {
|
|
612
655
|
const { values: r } = e;
|
|
613
|
-
return `The ${t} field must not be one of the following values: ${r.join(", ")}.`;
|
|
656
|
+
return `The ${t} field must not be one of the following values: ${r.map(i).join(", ")}.`;
|
|
614
657
|
},
|
|
615
658
|
number: (t) => `The ${t} field must be a number.`,
|
|
616
659
|
numeric: (t) => `The ${t} field must be a number.`,
|
|
617
660
|
oneOf: (t, e) => {
|
|
618
661
|
const { values: r } = e;
|
|
619
|
-
return `The ${t} field must be one of the following values: ${r.join(", ")}.`;
|
|
662
|
+
return `The ${t} field must be one of the following values: ${r.map(i).join(", ")}.`;
|
|
663
|
+
},
|
|
664
|
+
protocol: (t, e) => {
|
|
665
|
+
const { values: r } = e;
|
|
666
|
+
if (r.length === 1) {
|
|
667
|
+
const [s] = r;
|
|
668
|
+
return `The ${t} field must start with the "${s}://" protocol.`;
|
|
669
|
+
}
|
|
670
|
+
return `The ${t} field must start with one of the following protocols: ${r.map((s) => `${s}://`).map(i).join(", ")}.`;
|
|
620
671
|
},
|
|
621
672
|
regex: (t) => `The ${t} field must match the required format.`,
|
|
622
673
|
required: (t) => `The ${t} field is required.`,
|
|
@@ -637,19 +688,19 @@ const _ = {
|
|
|
637
688
|
},
|
|
638
689
|
string: (t) => `The ${t} field must be a string.`,
|
|
639
690
|
stringBetweenLength: (t, e) => {
|
|
640
|
-
const { min: r, max:
|
|
691
|
+
const { min: r, max: s } = e;
|
|
641
692
|
return {
|
|
642
|
-
string: `The ${t} field must be between ${n(r)} and ${n(
|
|
643
|
-
array: `The ${t} field must contain items where each item is between ${n(r)} and ${n(
|
|
693
|
+
string: `The ${t} field must be between ${n(r)} and ${n(s)} characters.`,
|
|
694
|
+
array: `The ${t} field must contain items where each item is between ${n(r)} and ${n(s)} characters.`
|
|
644
695
|
};
|
|
645
696
|
},
|
|
646
697
|
stringContainsAll: (t, e) => {
|
|
647
698
|
const { values: r } = e;
|
|
648
|
-
return `The ${t} field must contain all of the following text: ${r.join(", ")}.`;
|
|
699
|
+
return `The ${t} field must contain all of the following text: ${r.map(i).join(", ")}.`;
|
|
649
700
|
},
|
|
650
701
|
stringContainsAny: (t, e) => {
|
|
651
702
|
const { values: r } = e;
|
|
652
|
-
return `The ${t} field must contain at least one of the following text: ${r.join(", ")}.`;
|
|
703
|
+
return `The ${t} field must contain at least one of the following text: ${r.map(i).join(", ")}.`;
|
|
653
704
|
},
|
|
654
705
|
stringLength: (t, e) => {
|
|
655
706
|
const { length: r } = e;
|
|
@@ -674,42 +725,42 @@ const _ = {
|
|
|
674
725
|
},
|
|
675
726
|
stringNotContainsAll: (t, e) => {
|
|
676
727
|
const { values: r } = e;
|
|
677
|
-
return `The ${t} field must not contain all of the following text together: ${r.join(", ")}.`;
|
|
728
|
+
return `The ${t} field must not contain all of the following text together: ${r.map(i).join(", ")}.`;
|
|
678
729
|
},
|
|
679
730
|
stringNotContainsAny: (t, e) => {
|
|
680
731
|
const { values: r } = e;
|
|
681
|
-
return `The ${t} field must not contain any of the following text: ${r.join(", ")}.`;
|
|
732
|
+
return `The ${t} field must not contain any of the following text: ${r.map(i).join(", ")}.`;
|
|
682
733
|
},
|
|
683
734
|
unique: (t) => `The ${t} field has already been taken.`,
|
|
684
735
|
uppercase: (t) => `The ${t} field must be uppercase.`,
|
|
685
736
|
url: (t) => `The ${t} field must be a valid URL.`
|
|
686
|
-
},
|
|
737
|
+
}, B = {
|
|
687
738
|
accepted: () => "此欄位必須被同意",
|
|
688
739
|
alpha: () => "此欄位只能包含字母",
|
|
689
740
|
alphaDash: () => "此欄位只能包含字母、數字、連接號和底線",
|
|
690
741
|
alphaDashDot: () => "此欄位只能包含字母、數字、連接號、底線和點",
|
|
691
742
|
alphaNum: () => "此欄位只能包含字母和數字",
|
|
692
743
|
array: () => "此欄位必須是一個陣列",
|
|
693
|
-
ascii: () => "此欄位只能包含ASCII字元和符號",
|
|
744
|
+
ascii: () => "此欄位只能包含 ASCII 字元和符號",
|
|
694
745
|
between: (t, e) => {
|
|
695
|
-
const { min: r, max:
|
|
746
|
+
const { min: r, max: s } = e;
|
|
696
747
|
return {
|
|
697
|
-
number: `此欄位必須介於${n(r)}到${n(
|
|
698
|
-
array: `此欄位中的每個項目都必須介於${n(r)}到${n(
|
|
748
|
+
number: `此欄位必須介於${n(r)}到${n(s)}`,
|
|
749
|
+
array: `此欄位中的每個項目都必須介於${n(r)}到${n(s)}`
|
|
699
750
|
};
|
|
700
751
|
},
|
|
701
752
|
betweenLength: (t, e) => {
|
|
702
|
-
const { min: r, max:
|
|
703
|
-
return `此欄位必須介於${n(r)}到${n(
|
|
753
|
+
const { min: r, max: s } = e;
|
|
754
|
+
return `此欄位必須介於${n(r)}到${n(s)}個項目之間`;
|
|
704
755
|
},
|
|
705
756
|
boolean: () => "此欄位必須是一個布林值",
|
|
706
757
|
containsAll: (t, e) => {
|
|
707
758
|
const { values: r } = e;
|
|
708
|
-
return `此欄位必須包含以下所有項目:${r.join(", ")}`;
|
|
759
|
+
return `此欄位必須包含以下所有項目:${r.map(i).join(", ")}`;
|
|
709
760
|
},
|
|
710
761
|
containsAny: (t, e) => {
|
|
711
762
|
const { values: r } = e;
|
|
712
|
-
return `此欄位必須包含以下其中一個項目:${r.join(", ")}`;
|
|
763
|
+
return `此欄位必須包含以下其中一個項目:${r.map(i).join(", ")}`;
|
|
713
764
|
},
|
|
714
765
|
declined: () => "此欄位必須被拒絕",
|
|
715
766
|
different: (t, e) => {
|
|
@@ -729,10 +780,10 @@ const _ = {
|
|
|
729
780
|
},
|
|
730
781
|
file: () => "此欄位必須是檔案",
|
|
731
782
|
fileBetweenSize: (t, e) => {
|
|
732
|
-
const { min: r, max:
|
|
783
|
+
const { min: r, max: s } = e;
|
|
733
784
|
return {
|
|
734
|
-
file: `此欄位必須介於${n(r)}到${n(
|
|
735
|
-
array: `此欄位中的每個項目都必須介於${n(r)}到${n(
|
|
785
|
+
file: `此欄位必須介於${n(r)}到${n(s)} KB 之間`,
|
|
786
|
+
array: `此欄位中的每個項目都必須介於${n(r)}到${n(s)} KB 之間`
|
|
736
787
|
};
|
|
737
788
|
},
|
|
738
789
|
fileMaxSize: (t, e) => {
|
|
@@ -756,9 +807,13 @@ const _ = {
|
|
|
756
807
|
array: `此欄位中的每個項目都必須是${n(r)} KB`
|
|
757
808
|
};
|
|
758
809
|
},
|
|
759
|
-
http: () =>
|
|
760
|
-
|
|
810
|
+
http: () => '此欄位必須以 "http://" 協議開頭',
|
|
811
|
+
httpOrHttps: () => '此欄位必須以 "http://" 或 "https://" 協議開頭',
|
|
812
|
+
https: () => '此欄位必須以 "https://" 協議開頭',
|
|
761
813
|
integer: () => "此欄位必須是整數",
|
|
814
|
+
ip: () => "此欄位必須是有效的 IP 位址",
|
|
815
|
+
ipv4: () => "此欄位必須是有效的 IPv4 位址",
|
|
816
|
+
ipv6: () => "此欄位必須是有效的 IPv6 位址",
|
|
762
817
|
json: () => "此欄位必須是有效的 JSON 字串",
|
|
763
818
|
length: (t, e) => {
|
|
764
819
|
const { length: r } = e;
|
|
@@ -789,11 +844,11 @@ const _ = {
|
|
|
789
844
|
},
|
|
790
845
|
notContainsAll: (t, e) => {
|
|
791
846
|
const { values: r } = e;
|
|
792
|
-
return `此欄位不能同時包含以下所有值:${r.join(", ")}`;
|
|
847
|
+
return `此欄位不能同時包含以下所有值:${r.map(i).join(", ")}`;
|
|
793
848
|
},
|
|
794
849
|
notContainsAny: (t, e) => {
|
|
795
850
|
const { values: r } = e;
|
|
796
|
-
return `此欄位不能包含以下任何值:${r.join(", ")}`;
|
|
851
|
+
return `此欄位不能包含以下任何值:${r.map(i).join(", ")}`;
|
|
797
852
|
},
|
|
798
853
|
notEquals: (t, e) => {
|
|
799
854
|
const { value: r } = e;
|
|
@@ -801,13 +856,21 @@ const _ = {
|
|
|
801
856
|
},
|
|
802
857
|
notOneOf: (t, e) => {
|
|
803
858
|
const { values: r } = e;
|
|
804
|
-
return `此欄位不能是以下任何值:${r.join(", ")}`;
|
|
859
|
+
return `此欄位不能是以下任何值:${r.map(i).join(", ")}`;
|
|
805
860
|
},
|
|
806
861
|
number: () => "此欄位必須是數字",
|
|
807
862
|
numeric: () => "此欄位必須是數字",
|
|
808
863
|
oneOf: (t, e) => {
|
|
809
864
|
const { values: r } = e;
|
|
810
|
-
return
|
|
865
|
+
return `此欄位必須是以下其中一個值:${r.map(i).join(", ")}`;
|
|
866
|
+
},
|
|
867
|
+
protocol: (t, e) => {
|
|
868
|
+
const { values: r } = e;
|
|
869
|
+
if (r.length === 1) {
|
|
870
|
+
const [s] = r;
|
|
871
|
+
return `此欄位必須以 "${s}://" 協議開頭`;
|
|
872
|
+
}
|
|
873
|
+
return `此欄位必須以以下其中一個協議開頭:${r.map((s) => `${s}://`).map(i).join(", ")}`;
|
|
811
874
|
},
|
|
812
875
|
regex: () => "此欄位必須符合所需的格式",
|
|
813
876
|
required: () => "此欄位為必填",
|
|
@@ -828,19 +891,19 @@ const _ = {
|
|
|
828
891
|
},
|
|
829
892
|
string: () => "此欄位必須是字串",
|
|
830
893
|
stringBetweenLength: (t, e) => {
|
|
831
|
-
const { min: r, max:
|
|
894
|
+
const { min: r, max: s } = e;
|
|
832
895
|
return {
|
|
833
|
-
string: `此欄位必須介於${n(r)}到${n(
|
|
834
|
-
array: `此欄位中的每個項目都必須介於${n(r)}到${n(
|
|
896
|
+
string: `此欄位必須介於${n(r)}到${n(s)}個字元之間`,
|
|
897
|
+
array: `此欄位中的每個項目都必須介於${n(r)}到${n(s)}個字元之間`
|
|
835
898
|
};
|
|
836
899
|
},
|
|
837
900
|
stringContainsAll: (t, e) => {
|
|
838
901
|
const { values: r } = e;
|
|
839
|
-
return `此欄位必須包含以下所有文字:${r.join(", ")}`;
|
|
902
|
+
return `此欄位必須包含以下所有文字:${r.map(i).join(", ")}`;
|
|
840
903
|
},
|
|
841
904
|
stringContainsAny: (t, e) => {
|
|
842
905
|
const { values: r } = e;
|
|
843
|
-
return `此欄位必須包含以下其中一個文字:${r.join(", ")}`;
|
|
906
|
+
return `此欄位必須包含以下其中一個文字:${r.map(i).join(", ")}`;
|
|
844
907
|
},
|
|
845
908
|
stringLength: (t, e) => {
|
|
846
909
|
const { length: r } = e;
|
|
@@ -865,111 +928,146 @@ const _ = {
|
|
|
865
928
|
},
|
|
866
929
|
stringNotContainsAll: (t, e) => {
|
|
867
930
|
const { values: r } = e;
|
|
868
|
-
return `此欄位不能同時包含以下所有文字:${r.join(", ")}`;
|
|
931
|
+
return `此欄位不能同時包含以下所有文字:${r.map(i).join(", ")}`;
|
|
869
932
|
},
|
|
870
933
|
stringNotContainsAny: (t, e) => {
|
|
871
934
|
const { values: r } = e;
|
|
872
|
-
return `此欄位不能包含以下任何文字:${r.join(", ")}`;
|
|
935
|
+
return `此欄位不能包含以下任何文字:${r.map(i).join(", ")}`;
|
|
873
936
|
},
|
|
874
937
|
unique: () => "此欄位已經存在",
|
|
875
938
|
uppercase: () => "此欄位必須是大寫",
|
|
876
|
-
url: () => "
|
|
877
|
-
},
|
|
878
|
-
en:
|
|
879
|
-
"zh-TW":
|
|
880
|
-
},
|
|
881
|
-
if (
|
|
939
|
+
url: () => "此欄位必須是有效的 URL"
|
|
940
|
+
}, D = {
|
|
941
|
+
en: E,
|
|
942
|
+
"zh-TW": B
|
|
943
|
+
}, P = () => (t) => a(t) ? !1 : ["y", "yes", "on", "1", "true"].includes(String(t).toLowerCase()), N = () => (t) => a(t) ? !1 : /^[a-zA-Z]+$/.test(String(t)), W = () => (t) => a(t) ? !1 : /^[a-zA-Z0-9-_]+$/.test(String(t)), I = () => (t) => a(t) ? !1 : /^[a-zA-Z0-9-_.]+$/.test(String(t)), Z = () => (t) => a(t) ? !1 : /^[a-zA-Z0-9]+$/.test(String(t)), K = () => (t) => Array.isArray(t), H = () => (t) => a(t) ? !1 : /^[\x20-\x7E]+$/.test(String(t)), h = ({ max: t }) => (e) => a(e) ? !1 : typeof e == "number" ? e <= t : Array.isArray(e) ? e.every((r) => h({ max: t })(r)) : !1, c = ({ min: t }) => (e) => a(e) ? !1 : typeof e == "number" ? e >= t : Array.isArray(e) ? e.every((r) => c({ min: t })(r)) : !1, U = ({ min: t, max: e }) => (r) => a(r) ? !1 : c({ min: t })(r) && h({ max: e })(r), T = ({ length: t }) => (e) => a(e) ? !1 : Array.isArray(e) ? e.length <= t : !1, v = ({ length: t }) => (e) => a(e) ? !1 : Array.isArray(e) ? e.length >= t : !1, J = ({ min: t, max: e }) => (r) => a(r) ? !1 : v({ length: t })(r) && T({ length: e })(r), V = () => (t) => a(t) ? !1 : typeof t == "boolean", w = ({ values: t }) => (e) => a(e) ? !1 : Array.isArray(e) ? t.every((r) => e.includes(r)) : !1, R = ({ values: t }) => (e) => a(e) ? !1 : Array.isArray(e) ? t.some((r) => e.includes(r)) : !1, G = () => (t) => a(t) ? !1 : ["n", "no", "off", "0", "false"].includes(String(t).toLowerCase()), Q = ({ value: t }) => (e) => a(e) ? !1 : e !== t, X = () => (t) => a(t) ? !1 : Array.isArray(t) ? new Set(t).size === t.length : !0, Y = () => (t) => a(t) ? !1 : /^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(String(t)), ee = () => (t) => a(t) ? !1 : /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(String(t)), te = ({ value: t }) => (e) => a(e) ? !1 : String(e).endsWith(t), re = ({ value: t }) => (e) => e === t, ne = () => (t) => t instanceof File, f = ({ size: t }) => (e) => a(e) ? !1 : e instanceof File ? e.size <= t * 1024 : Array.isArray(e) ? e.every((r) => f({ size: t })(r)) : !1, m = ({ size: t }) => (e) => a(e) ? !1 : e instanceof File ? e.size >= t * 1024 : Array.isArray(e) ? e.every((r) => m({ size: t })(r)) : !1, se = ({ min: t, max: e }) => (r) => a(r) ? !1 : m({ size: t })(r) && f({ size: e })(r), L = ({ size: t }) => (e) => {
|
|
944
|
+
if (a(e))
|
|
882
945
|
return !1;
|
|
883
946
|
if (e instanceof File) {
|
|
884
|
-
const r = t * 1024,
|
|
885
|
-
return e.size >= r && e.size <
|
|
947
|
+
const r = t * 1024, s = (t + 1) * 1024;
|
|
948
|
+
return e.size >= r && e.size < s;
|
|
886
949
|
}
|
|
887
|
-
return Array.isArray(e) ? e.every((r) =>
|
|
888
|
-
},
|
|
889
|
-
if (
|
|
950
|
+
return Array.isArray(e) ? e.every((r) => L({ size: t })(r)) : !1;
|
|
951
|
+
}, S = ({ value: t }) => (e) => a(e) ? !1 : String(e).startsWith(t), g = ({ values: t }) => (e) => a(e) ? !1 : t.map((r) => `${r}://`).some((r) => S({ value: r })(e)), x = () => (t) => a(t) ? !1 : g({ values: ["http"] })(t), z = () => (t) => a(t) ? !1 : g({ values: ["https"] })(t), ae = () => (t) => a(t) ? !1 : x()(t) || z()(t), y = () => (t) => a(t) ? !1 : typeof t == "number", ie = () => (t) => a(t) ? !1 : y()(t) && Number.isInteger(t), p = ({ includeProtocol: t } = {}) => (e) => {
|
|
952
|
+
if (a(e))
|
|
953
|
+
return !1;
|
|
954
|
+
if (t)
|
|
955
|
+
try {
|
|
956
|
+
const { host: r } = new URL(String(e));
|
|
957
|
+
return p({})(r);
|
|
958
|
+
} catch {
|
|
959
|
+
return !1;
|
|
960
|
+
}
|
|
961
|
+
return /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(:\d+)?$/.test(String(e));
|
|
962
|
+
}, d = ({ includeProtocol: t } = {}) => (e) => {
|
|
963
|
+
if (a(e))
|
|
964
|
+
return !1;
|
|
965
|
+
if (t)
|
|
966
|
+
try {
|
|
967
|
+
const { host: r } = new URL(String(e));
|
|
968
|
+
return d({})(r);
|
|
969
|
+
} catch {
|
|
970
|
+
return !1;
|
|
971
|
+
}
|
|
972
|
+
return /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/.test(String(e));
|
|
973
|
+
}, le = ({ includeProtocol: t } = {}) => (e) => a(e) ? !1 : p({ includeProtocol: t })(e) || d({ includeProtocol: t })(e), oe = () => (t) => {
|
|
974
|
+
if (a(t))
|
|
890
975
|
return !1;
|
|
891
976
|
try {
|
|
892
977
|
return JSON.parse(String(t)), !0;
|
|
893
978
|
} catch {
|
|
894
979
|
return !1;
|
|
895
980
|
}
|
|
896
|
-
},
|
|
897
|
-
if (
|
|
981
|
+
}, ue = ({ length: t }) => (e) => a(e) ? !1 : Array.isArray(e) ? e.length === t : !1, he = () => (t) => a(t) ? !1 : String(t) === String(t).toLowerCase(), ce = ({ values: t }) => (e) => a(e) ? !1 : Array.isArray(e) ? !t.every((r) => e.includes(r)) : !1, fe = ({ values: t }) => (e) => a(e) ? !1 : Array.isArray(e) ? !t.some((r) => e.includes(r)) : !1, me = ({ value: t }) => (e) => e !== t, ge = ({ values: t }) => (e) => a(e) ? !1 : !t.includes(e), F = () => (t) => typeof t == "string", ye = () => (t) => a(t) ? !1 : F()(t) ? /^-?\d+(\.\d+)?$/.test(String(t)) : y()(t), pe = ({ values: t }) => (e) => a(e) ? !1 : t.includes(e), de = ({ expression: t }) => (e) => {
|
|
982
|
+
if (a(e))
|
|
898
983
|
return !1;
|
|
899
984
|
if (!(t instanceof RegExp))
|
|
900
985
|
throw new TypeError("The expression provided is not a valid RegExp.");
|
|
901
986
|
return t.test(String(e));
|
|
902
|
-
},
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
987
|
+
}, $e = () => (t) => !a(t), be = ({ value: t }) => (e) => a(e) ? !1 : Array.isArray(e) ? e.every((r) => r === t) : e === t, C = ({ size: t }) => (e) => a(e) ? !1 : typeof e == "number" ? e === t : Array.isArray(e) ? e.every((r) => C({ size: t })(r)) : !1, $ = ({ length: t }) => (e) => a(e) ? !1 : typeof e == "string" ? e.length <= t : Array.isArray(e) ? e.every((r) => $({ length: t })(r)) : !1, b = ({ length: t }) => (e) => a(e) ? !1 : typeof e == "string" ? e.length >= t : Array.isArray(e) ? e.every((r) => b({ length: t })(r)) : !1, Ae = ({ min: t, max: e }) => (r) => a(r) ? !1 : b({ length: t })(r) && $({ length: e })(r), j = ({ length: t }) => (e) => a(e) ? !1 : typeof e == "string" ? e.length === t : Array.isArray(e) ? e.every((r) => j({ length: t })(r)) : !1, we = ({ values: t }) => (e) => a(e) ? !1 : typeof e == "string" ? !t.every((r) => e.includes(r)) : !1, Re = ({ values: t }) => (e) => a(e) ? !1 : typeof e == "string" ? !t.some((r) => e.includes(r)) : !1, Te = ({ values: t, ignored: e = [] }) => (r) => a(r) ? !1 : (Array.isArray(e) ? e : [e]).some((s) => s === r) ? !0 : !t.some((s) => s === r), ve = () => (t) => a(t) ? !1 : String(t) === String(t).toUpperCase(), Le = () => (t) => {
|
|
988
|
+
if (a(t))
|
|
989
|
+
return !1;
|
|
990
|
+
try {
|
|
991
|
+
return new URL(String(t)), !0;
|
|
992
|
+
} catch {
|
|
993
|
+
return !1;
|
|
994
|
+
}
|
|
995
|
+
}, Se = {
|
|
996
|
+
accepted: P,
|
|
997
|
+
alpha: N,
|
|
998
|
+
alphaDash: W,
|
|
999
|
+
alphaDashDot: I,
|
|
1000
|
+
alphaNum: Z,
|
|
1001
|
+
array: K,
|
|
1002
|
+
ascii: H,
|
|
1003
|
+
between: U,
|
|
1004
|
+
betweenLength: J,
|
|
1005
|
+
boolean: V,
|
|
1006
|
+
containsAll: w,
|
|
1007
|
+
containsAny: R,
|
|
1008
|
+
declined: G,
|
|
1009
|
+
different: Q,
|
|
1010
|
+
distinct: X,
|
|
1011
|
+
domain: Y,
|
|
1012
|
+
email: ee,
|
|
1013
|
+
endsWith: te,
|
|
1014
|
+
equals: re,
|
|
1015
|
+
file: ne,
|
|
1016
|
+
fileBetweenSize: se,
|
|
924
1017
|
fileMaxSize: f,
|
|
925
1018
|
fileMinSize: m,
|
|
926
|
-
fileSize:
|
|
927
|
-
http:
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1019
|
+
fileSize: L,
|
|
1020
|
+
http: x,
|
|
1021
|
+
httpOrHttps: ae,
|
|
1022
|
+
https: z,
|
|
1023
|
+
integer: ie,
|
|
1024
|
+
ip: le,
|
|
1025
|
+
ipv4: p,
|
|
1026
|
+
ipv6: d,
|
|
1027
|
+
json: oe,
|
|
1028
|
+
length: ue,
|
|
1029
|
+
lowercase: he,
|
|
933
1030
|
max: h,
|
|
934
|
-
maxLength:
|
|
1031
|
+
maxLength: T,
|
|
935
1032
|
min: c,
|
|
936
|
-
minLength:
|
|
937
|
-
notContainsAll:
|
|
938
|
-
notContainsAny:
|
|
939
|
-
notEquals:
|
|
940
|
-
notOneOf:
|
|
941
|
-
number:
|
|
942
|
-
numeric:
|
|
943
|
-
oneOf:
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1033
|
+
minLength: v,
|
|
1034
|
+
notContainsAll: ce,
|
|
1035
|
+
notContainsAny: fe,
|
|
1036
|
+
notEquals: me,
|
|
1037
|
+
notOneOf: ge,
|
|
1038
|
+
number: y,
|
|
1039
|
+
numeric: ye,
|
|
1040
|
+
oneOf: pe,
|
|
1041
|
+
protocol: g,
|
|
1042
|
+
regex: de,
|
|
1043
|
+
required: $e,
|
|
1044
|
+
same: be,
|
|
1045
|
+
size: C,
|
|
1046
|
+
startsWith: S,
|
|
1047
|
+
string: F,
|
|
1048
|
+
stringBetweenLength: Ae,
|
|
1049
|
+
stringContainsAll: w,
|
|
1050
|
+
stringContainsAny: R,
|
|
1051
|
+
stringLength: j,
|
|
1052
|
+
stringMaxLength: $,
|
|
1053
|
+
stringMinLength: b,
|
|
1054
|
+
stringNotContainsAll: we,
|
|
1055
|
+
stringNotContainsAny: Re,
|
|
1056
|
+
unique: Te,
|
|
1057
|
+
uppercase: ve,
|
|
1058
|
+
url: Le
|
|
961
1059
|
};
|
|
962
|
-
class
|
|
1060
|
+
class ze {
|
|
963
1061
|
constructor({
|
|
964
1062
|
fallbackLocale: e,
|
|
965
1063
|
locale: r,
|
|
966
|
-
plugins:
|
|
1064
|
+
plugins: s
|
|
967
1065
|
} = {}) {
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
this.registerLocales(
|
|
1066
|
+
o(this, "locale", "en");
|
|
1067
|
+
o(this, "fallbackLocale", "en");
|
|
1068
|
+
o(this, "locales", {});
|
|
1069
|
+
o(this, "rules", {});
|
|
1070
|
+
this.registerLocales(D), this.registerRules(Se), e && this.setFallbackLocale(e), r && this.setLocale(r), s && s.forEach((l) => this.registerPlugin(l));
|
|
973
1071
|
}
|
|
974
1072
|
getLocale() {
|
|
975
1073
|
return this.locale;
|
|
@@ -988,7 +1086,7 @@ class we {
|
|
|
988
1086
|
return this.fallbackLocale = e, this;
|
|
989
1087
|
}
|
|
990
1088
|
defineField(e) {
|
|
991
|
-
return new
|
|
1089
|
+
return new k({
|
|
992
1090
|
name: e,
|
|
993
1091
|
locale: this.locale,
|
|
994
1092
|
fallbackLocale: this.fallbackLocale,
|
|
@@ -998,7 +1096,7 @@ class we {
|
|
|
998
1096
|
}
|
|
999
1097
|
registerLocales(e) {
|
|
1000
1098
|
return this.locales = Object.keys(e).reduce(
|
|
1001
|
-
(r,
|
|
1099
|
+
(r, s) => (r[s] = { ...this.locales[s], ...e[s] }, r),
|
|
1002
1100
|
{ ...this.locales }
|
|
1003
1101
|
), this;
|
|
1004
1102
|
}
|
|
@@ -1012,6 +1110,6 @@ class we {
|
|
|
1012
1110
|
}
|
|
1013
1111
|
}
|
|
1014
1112
|
export {
|
|
1015
|
-
|
|
1016
|
-
|
|
1113
|
+
k as FieldValidator,
|
|
1114
|
+
ze as FormValidator
|
|
1017
1115
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(u,l){typeof exports=="object"&&typeof module<"u"?l(exports):typeof define=="function"&&define.amd?define(["exports"],l):(u=typeof globalThis<"u"?globalThis:u||self,l(u.Fortress={}))})(this,function(u){"use strict";var me=Object.defineProperty;var ge=(u,l,n)=>l in u?me(u,l,{enumerable:!0,configurable:!0,writable:!0,value:n}):u[l]=n;var o=(u,l,n)=>(ge(u,typeof l!="symbol"?l+"":l,n),n);const l=t=>t.replace(/([^\x20-\x7E])([\x20-\x7E])/gu,"$1 $2").replace(/([\x20-\x7E])([^\x20-\x7E])/gu,"$1 $2").replace(/ +/g," "),n=(t,e=0)=>new Intl.NumberFormat(void 0,{minimumFractionDigits:e,maximumFractionDigits:e}).format(t),z=t=>Object.prototype.toString.call(t).toLowerCase().slice(8,-1),s=t=>t==null||t===""||Array.isArray(t)&&t.length<1;class b{constructor({name:e,locale:r,fallbackLocale:i,locales:a,rules:h}){o(this,"name");o(this,"locale");o(this,"fallbackLocale");o(this,"locales");o(this,"rules");o(this,"ruleFunctions",[]);o(this,"conditions",{});o(this,"shouldSkip",!1);this.name=e,this.locale=r,this.fallbackLocale=i,this.locales=a,this.rules=h}get formattedName(){return this.name.toLowerCase()}get messages(){return this.locales[this.locale]||{}}get fallbackMessages(){return this.locales[this.fallbackLocale]||{}}get mandatoryRules(){return[this.required.name,this.string.name,this.array.name,this.equals.name,this.notEquals.name]}getMessage(e){return this.messages[e]||this.fallbackMessages[e]||(r=>`The ${r} field is invalid.`)}getRule(e){if(!(e in this.rules))throw new Error(`The "${e}" rule is not registered.`);return this.rules[e]}buildRuleFunction(e,r){return i=>{if(s(i)&&!this.mandatoryRules.includes(e))return!0;const a=this.getRule(e)(r)(i);return typeof a=="string"?a:a===!0?!0:this.buildRuleFunctionMessage(e,r,i)}}buildRuleFunctionMessage(e,r,i){const a=this.getMessage(e)(this.formattedName,r);if(typeof a=="object"){const h=z(i);if(!(h in a))throw new Error(`The message for the "${e}" rule of the "${h}" type is missing.`);return l(a[h])}return l(a)}pushRuleFunction(e,r){if(e in this.conditions&&!this.conditions[e])return this;const i=this.buildRuleFunction(e,r);return this.ruleFunctions.push(i),this}getRuleFunctions(){return this.ruleFunctions}collect(){return this.shouldSkip?[]:this.getRuleFunctions()}validate(e){if(this.shouldSkip)return!0;for(const r of this.ruleFunctions){const i=r(e);if(typeof i=="string")return i}return!0}apply(e,r={}){return this.pushRuleFunction(e,r)}accepted(){return this.apply(this.accepted.name)}after(e,r,i,a=!0){return this.apply(this.after.name,{date:e,format:r,displayFormat:i,strict:a})}alpha(){return this.apply(this.alpha.name)}alphaDash(){return this.apply(this.alphaDash.name)}alphaDashDot(){return this.apply(this.alphaDashDot.name)}alphaNum(){return this.apply(this.alphaNum.name)}array(){return this.apply(this.array.name)}ascii(){return this.apply(this.ascii.name)}before(e,r,i,a=!0){return this.apply(this.before.name,{date:e,format:r,displayFormat:i,strict:a})}between(e,r){return this.apply(this.between.name,{min:e,max:r})}betweenLength(e,r){return this.apply(this.betweenLength.name,{min:e,max:r})}boolean(){return this.apply(this.boolean.name)}containsAll(e){return this.apply(this.containsAll.name,{values:e})}containsAny(e){return this.apply(this.containsAny.name,{values:e})}date(e,r=!0){return this.apply(this.date.name,{format:e,strict:r})}declined(){return this.apply(this.declined.name)}different(e,r){return this.apply(this.different.name,{field:e,value:r})}distinct(){return this.apply(this.distinct.name)}domain(){return this.apply(this.domain.name)}email(){return this.apply(this.email.name)}endsWith(e){return this.apply(this.endsWith.name,{value:e})}equals(e){return this.apply(this.equals.name,{value:e})}file(){return this.apply(this.file.name)}fileBetweenSize(e,r){return this.apply(this.fileBetweenSize.name,{min:e,max:r})}fileMaxSize(e){return this.apply(this.fileMaxSize.name,{size:e})}fileMinSize(e){return this.apply(this.fileMinSize.name,{size:e})}fileSize(e){return this.apply(this.fileSize.name,{size:e})}http(){return this.apply(this.http.name)}https(){return this.apply(this.https.name)}integer(){return this.apply(this.integer.name)}iso8601(){return this.apply(this.iso8601.name)}json(){return this.apply(this.json.name)}jsonSchema(e){return this.apply(this.jsonSchema.name,{schema:e,locale:this.locale,field:this.name})}length(e){return this.apply(this.length.name,{length:e})}lowercase(){return this.apply(this.lowercase.name)}max(e){return this.apply(this.max.name,{max:e})}maxLength(e){return this.apply(this.maxLength.name,{length:e})}min(e){return this.apply(this.min.name,{min:e})}minLength(e){return this.apply(this.minLength.name,{length:e})}notContainsAll(e){return this.apply(this.notContainsAll.name,{values:e})}notContainsAny(e){return this.apply(this.notContainsAny.name,{values:e})}notEquals(e){return this.apply(this.notEquals.name,{value:e})}notOneOf(e){return this.apply(this.notOneOf.name,{values:e})}number(){return this.apply(this.number.name)}numeric(){return this.apply(this.numeric.name)}oneOf(e){return this.apply(this.oneOf.name,{values:e})}regex(e){return this.apply(this.regex.name,{expression:e})}required(){return this.apply(this.required.name)}requiredWhen(e){return this.when({required:e}).required()}same(e,r){return this.apply(this.same.name,{field:e,value:r})}size(e){return this.apply(this.size.name,{size:e})}startsWith(e){return this.apply(this.startsWith.name,{value:e})}string(){return this.apply(this.string.name)}stringBetweenLength(e,r){return this.apply(this.stringBetweenLength.name,{min:e,max:r})}stringContainsAll(e){return this.apply(this.stringContainsAll.name,{values:e})}stringContainsAny(e){return this.apply(this.stringContainsAny.name,{values:e})}stringLength(e){return this.apply(this.stringLength.name,{length:e})}stringMaxLength(e){return this.apply(this.stringMaxLength.name,{length:e})}stringMinLength(e){return this.apply(this.stringMinLength.name,{length:e})}stringNotContainsAll(e){return this.apply(this.stringNotContainsAll.name,{values:e})}stringNotContainsAny(e){return this.apply(this.stringNotContainsAny.name,{values:e})}unique(e,r=[]){return this.apply(this.unique.name,{values:e,ignored:r})}uppercase(){return this.apply(this.uppercase.name)}url(){return this.apply(this.url.name)}when(e){return typeof e=="object"?(this.conditions=e,this):(e||(this.shouldSkip=!0),this)}}const C={en:{accepted:t=>`The ${t} field must be accepted.`,alpha:t=>`The ${t} field must only contain letters.`,alphaDash:t=>`The ${t} field must only contain letters, numbers, dashes and underscores.`,alphaDashDot:t=>`The ${t} field must only contain letters, numbers, dashes, underscores and dots.`,alphaNum:t=>`The ${t} field must only contain letters and numbers.`,array:t=>`The ${t} field must be an array.`,ascii:t=>`The ${t} field must only contain ASCII characters and symbols.`,between:(t,e)=>{const{min:r,max:i}=e;return{number:`The ${t} field must be between ${n(r)} and ${n(i)}.`,array:`The ${t} field must contain items where each item is between ${n(r)} and ${n(i)}.`}},betweenLength:(t,e)=>{const{min:r,max:i}=e;return`The ${t} field must be between ${n(r)} and ${n(i)} items.`},boolean:t=>`The ${t} field must be a boolean value.`,containsAll:(t,e)=>{const{values:r}=e;return`The ${t} field must contain all of the following values: ${r.join(", ")}.`},containsAny:(t,e)=>{const{values:r}=e;return`The ${t} field must contain at least one of the following values: ${r.join(", ")}.`},declined:t=>`The ${t} field must be declined.`,different:(t,e)=>{const{field:r}=e;return`The ${t} and ${r} fields must be different.`},distinct:t=>`The ${t} field must not contain duplicate values.`,domain:t=>`The ${t} field must be a valid domain.`,email:t=>`The ${t} field must be a valid email address.`,endsWith:(t,e)=>{const{value:r}=e;return`The ${t} field must end with ${r}.`},equals:(t,e)=>{const{value:r}=e;return`The ${t} field must be equal to ${r}.`},file:t=>`The ${t} field must be a file.`,fileBetweenSize:(t,e)=>{const{min:r,max:i}=e;return{file:`The ${t} field must be between ${n(r)} and ${n(i)} kilobytes.`,array:`The ${t} field must contain items where each item is between ${n(r)} and ${n(i)} kilobytes.`}},fileMaxSize:(t,e)=>{const{size:r}=e;return{file:`The ${t} field must not be greater than ${n(r)} kilobytes.`,array:`The ${t} field must contain items where each item is not greater than ${n(r)} kilobytes.`}},fileMinSize:(t,e)=>{const{size:r}=e;return{file:`The ${t} field must be at least ${n(r)} kilobytes.`,array:`The ${t} field must contain items where each item is at least ${n(r)} kilobytes.`}},fileSize:(t,e)=>{const{size:r}=e;return{file:`The ${t} field must be ${n(r)} kilobytes.`,array:`The ${t} field must contain items where each item is ${n(r)} kilobytes.`}},http:t=>`The ${t} field must start with either "http://" or "https://".`,https:t=>`The ${t} field must start with "http://".`,integer:t=>`The ${t} field must be an integer.`,json:t=>`The ${t} field must be a valid JSON string.`,length:(t,e)=>{const{length:r}=e;return`The ${t} field must be ${n(r)} items.`},lowercase:t=>`The ${t} field must be lowercase.`,max:(t,e)=>{const{max:r}=e;return{number:`The ${t} field must not be greater than ${n(r)}.`,array:`The ${t} field must contain items where each item is not greater than ${n(r)}.`}},maxLength:(t,e)=>{const{length:r}=e;return`The ${t} field must not be greater than ${n(r)} items.`},min:(t,e)=>{const{min:r}=e;return{number:`The ${t} field must be at least ${n(r)}.`,array:`The ${t} field must contain items where each item is at least ${n(r)}.`}},minLength:(t,e)=>{const{length:r}=e;return`The ${t} field must be at least ${n(r)} items.`},notContainsAll:(t,e)=>{const{values:r}=e;return`The ${t} field must not contain all of the following values together: ${r.join(", ")}.`},notContainsAny:(t,e)=>{const{values:r}=e;return`The ${t} field must not contain any of the following values: ${r.join(", ")}.`},notEquals:(t,e)=>{const{value:r}=e;return`The ${t} field must not be equal to ${r}.`},notOneOf:(t,e)=>{const{values:r}=e;return`The ${t} field must not be one of the following values: ${r.join(", ")}.`},number:t=>`The ${t} field must be a number.`,numeric:t=>`The ${t} field must be a number.`,oneOf:(t,e)=>{const{values:r}=e;return`The ${t} field must be one of the following values: ${r.join(", ")}.`},regex:t=>`The ${t} field must match the required format.`,required:t=>`The ${t} field is required.`,same:(t,e)=>{const{field:r}=e;return`The ${t} and ${r} fields must match.`},size:(t,e)=>{const{size:r}=e;return{number:`The ${t} field must be ${n(r)}.`,array:`The ${t} field must contain items where each item is ${n(r)}.`}},startsWith:(t,e)=>{const{value:r}=e;return`The ${t} field must start with ${r}.`},string:t=>`The ${t} field must be a string.`,stringBetweenLength:(t,e)=>{const{min:r,max:i}=e;return{string:`The ${t} field must be between ${n(r)} and ${n(i)} characters.`,array:`The ${t} field must contain items where each item is between ${n(r)} and ${n(i)} characters.`}},stringContainsAll:(t,e)=>{const{values:r}=e;return`The ${t} field must contain all of the following text: ${r.join(", ")}.`},stringContainsAny:(t,e)=>{const{values:r}=e;return`The ${t} field must contain at least one of the following text: ${r.join(", ")}.`},stringLength:(t,e)=>{const{length:r}=e;return{string:`The ${t} field must be ${n(r)} characters.`,array:`The ${t} field must contain items where each item is ${n(r)} characters.`}},stringMaxLength:(t,e)=>{const{length:r}=e;return{string:`The ${t} field must not be greater than ${n(r)} characters.`,array:`The ${t} field must contain items where each item is not greater than ${n(r)} characters.`}},stringMinLength:(t,e)=>{const{length:r}=e;return{string:`The ${t} field must be at least ${n(r)} characters.`,array:`The ${t} field must contain items where each item is at least ${n(r)} characters.`}},stringNotContainsAll:(t,e)=>{const{values:r}=e;return`The ${t} field must not contain all of the following text together: ${r.join(", ")}.`},stringNotContainsAny:(t,e)=>{const{values:r}=e;return`The ${t} field must not contain any of the following text: ${r.join(", ")}.`},unique:t=>`The ${t} field has already been taken.`,uppercase:t=>`The ${t} field must be uppercase.`,url:t=>`The ${t} field must be a valid URL.`},"zh-TW":{accepted:()=>"此欄位必須被同意",alpha:()=>"此欄位只能包含字母",alphaDash:()=>"此欄位只能包含字母、數字、連接號和底線",alphaDashDot:()=>"此欄位只能包含字母、數字、連接號、底線和點",alphaNum:()=>"此欄位只能包含字母和數字",array:()=>"此欄位必須是一個陣列",ascii:()=>"此欄位只能包含ASCII字元和符號",between:(t,e)=>{const{min:r,max:i}=e;return{number:`此欄位必須介於${n(r)}到${n(i)}`,array:`此欄位中的每個項目都必須介於${n(r)}到${n(i)}`}},betweenLength:(t,e)=>{const{min:r,max:i}=e;return`此欄位必須介於${n(r)}到${n(i)}個項目之間`},boolean:()=>"此欄位必須是一個布林值",containsAll:(t,e)=>{const{values:r}=e;return`此欄位必須包含以下所有項目:${r.join(", ")}`},containsAny:(t,e)=>{const{values:r}=e;return`此欄位必須包含以下其中一個項目:${r.join(", ")}`},declined:()=>"此欄位必須被拒絕",different:(t,e)=>{const{field:r}=e;return`此欄位必須和${r}欄位不同`},distinct:()=>"此欄位不能包含重複的值",domain:()=>"此欄位必須是有效的網域",email:()=>"此欄位必須是有效的電子郵件地址",endsWith:(t,e)=>{const{value:r}=e;return`此欄位必須以${r}結尾`},equals:(t,e)=>{const{value:r}=e;return`此欄位必須是${r}`},file:()=>"此欄位必須是檔案",fileBetweenSize:(t,e)=>{const{min:r,max:i}=e;return{file:`此欄位必須介於${n(r)}到${n(i)} KB之間`,array:`此欄位中的每個項目都必須介於${n(r)}到${n(i)} KB之間`}},fileMaxSize:(t,e)=>{const{size:r}=e;return{file:`此欄位不能大於${n(r)} KB`,array:`此欄位中的每個項目都不能大於${n(r)} KB`}},fileMinSize:(t,e)=>{const{size:r}=e;return{file:`此欄位不能小於${n(r)} KB`,array:`此欄位中的每個項目都不能小於${n(r)} KB`}},fileSize:(t,e)=>{const{size:r}=e;return{file:`此欄位必須是${n(r)} KB`,array:`此欄位中的每個項目都必須是${n(r)} KB`}},http:()=>"此欄位必須以 http:// 或 https:// 開頭",https:()=>"此欄位必須以 https:// 開頭",integer:()=>"此欄位必須是整數",json:()=>"此欄位必須是有效的 JSON 字串",length:(t,e)=>{const{length:r}=e;return`此欄位必須包含${n(r)}個項目`},lowercase:()=>"此欄位必須是小寫",max:(t,e)=>{const{max:r}=e;return{number:`此欄位不能大於${n(r)}`,array:`此欄位中的每個項目都不能大於${n(r)}`}},maxLength:(t,e)=>{const{length:r}=e;return`此欄位不能大於${n(r)}個項目`},min:(t,e)=>{const{min:r}=e;return{number:`此欄位不能小於${n(r)}`,array:`此欄位中的每個項目都不能小於${n(r)}`}},minLength:(t,e)=>{const{length:r}=e;return`此欄位不能小於${n(r)}個項目`},notContainsAll:(t,e)=>{const{values:r}=e;return`此欄位不能同時包含以下所有值:${r.join(", ")}`},notContainsAny:(t,e)=>{const{values:r}=e;return`此欄位不能包含以下任何值:${r.join(", ")}`},notEquals:(t,e)=>{const{value:r}=e;return`此欄位不能是${r}`},notOneOf:(t,e)=>{const{values:r}=e;return`此欄位不能是以下任何值:${r.join(", ")}`},number:()=>"此欄位必須是數字",numeric:()=>"此欄位必須是數字",oneOf:(t,e)=>{const{values:r}=e;return`此欄位必須是以下任何值:${r.join(", ")}`},regex:()=>"此欄位必須符合所需的格式",required:()=>"此欄位為必填",same:(t,e)=>{const{field:r}=e;return`此欄位必須與${r}欄位相同`},size:(t,e)=>{const{size:r}=e;return{number:`此欄位必須是${n(r)}`,array:`此欄位中的每個項目都必須是${n(r)}`}},startsWith:(t,e)=>{const{value:r}=e;return`此欄位必須以${r}開頭`},string:()=>"此欄位必須是字串",stringBetweenLength:(t,e)=>{const{min:r,max:i}=e;return{string:`此欄位必須介於${n(r)}到${n(i)}個字元之間`,array:`此欄位中的每個項目都必須介於${n(r)}到${n(i)}個字元之間`}},stringContainsAll:(t,e)=>{const{values:r}=e;return`此欄位必須包含以下所有文字:${r.join(", ")}`},stringContainsAny:(t,e)=>{const{values:r}=e;return`此欄位必須包含以下其中一個文字:${r.join(", ")}`},stringLength:(t,e)=>{const{length:r}=e;return{string:`此欄位必須是${n(r)}個字元`,array:`此欄位中的每個項目都必須是${n(r)}個字元`}},stringMaxLength:(t,e)=>{const{length:r}=e;return{string:`此欄位不能大於${n(r)}個字元`,array:`此欄位中的每個項目都不能大於${n(r)}個字元`}},stringMinLength:(t,e)=>{const{length:r}=e;return{string:`此欄位不能小於${n(r)}個字元`,array:`此欄位中的每個項目都不能小於${n(r)}個字元`}},stringNotContainsAll:(t,e)=>{const{values:r}=e;return`此欄位不能同時包含以下所有文字:${r.join(", ")}`},stringNotContainsAny:(t,e)=>{const{values:r}=e;return`此欄位不能包含以下任何文字:${r.join(", ")}`},unique:()=>"此欄位已經存在",uppercase:()=>"此欄位必須是大寫",url:()=>"此欄位必須是有效的網址"}},_=()=>t=>s(t)?!1:["y","yes","on","1","true"].includes(String(t).toLowerCase()),j=()=>t=>s(t)?!1:/^[a-zA-Z]+$/.test(String(t)),q=()=>t=>s(t)?!1:/^[a-zA-Z0-9-_]+$/.test(String(t)),M=()=>t=>s(t)?!1:/^[a-zA-Z0-9-_.]+$/.test(String(t)),F=()=>t=>s(t)?!1:/^[a-zA-Z0-9]+$/.test(String(t)),k=()=>t=>Array.isArray(t),O=()=>t=>s(t)?!1:/^[\x20-\x7E]+$/.test(String(t)),c=({max:t})=>e=>s(e)?!1:typeof e=="number"?e<=t:Array.isArray(e)?e.every(r=>c({max:t})(r)):!1,m=({min:t})=>e=>s(e)?!1:typeof e=="number"?e>=t:Array.isArray(e)?e.every(r=>m({min:t})(r)):!1,B=({min:t,max:e})=>r=>s(r)?!1:m({min:t})(r)&&c({max:e})(r),A=({length:t})=>e=>s(e)?!1:Array.isArray(e)?e.length<=t:!1,w=({length:t})=>e=>s(e)?!1:Array.isArray(e)?e.length>=t:!1,D=({min:t,max:e})=>r=>s(r)?!1:w({length:t})(r)&&A({length:e})(r),E=()=>t=>s(t)?!1:typeof t=="boolean",T=({values:t})=>e=>s(e)?!1:Array.isArray(e)?t.every(r=>e.includes(r)):!1,R=({values:t})=>e=>s(e)?!1:Array.isArray(e)?t.some(r=>e.includes(r)):!1,W=()=>t=>s(t)?!1:["n","no","off","0","false"].includes(String(t).toLowerCase()),N=({value:t})=>e=>s(e)?!1:e!==t,Z=()=>t=>s(t)?!1:Array.isArray(t)?new Set(t).size===t.length:!0,K=()=>t=>s(t)?!1:/^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(String(t)),I=()=>t=>s(t)?!1:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(String(t)),V=({value:t})=>e=>s(e)?!1:String(e).endsWith(t),J=({value:t})=>e=>e===t,P=()=>t=>t instanceof File,g=({size:t})=>e=>s(e)?!1:e instanceof File?e.size<=t*1024:Array.isArray(e)?e.every(r=>g({size:t})(r)):!1,y=({size:t})=>e=>s(e)?!1:e instanceof File?e.size>=t*1024:Array.isArray(e)?e.every(r=>y({size:t})(r)):!1,U=({min:t,max:e})=>r=>s(r)?!1:y({size:t})(r)&&g({size:e})(r),L=({size:t})=>e=>{if(s(e))return!1;if(e instanceof File){const r=t*1024,i=(t+1)*1024;return e.size>=r&&e.size<i}return Array.isArray(e)?e.every(r=>L({size:t})(r)):!1},f=({value:t})=>e=>s(e)?!1:String(e).startsWith(t),G=()=>t=>s(t)?!1:f({value:"http://"})(t)||f({value:"https://"})(t),H=()=>t=>s(t)?!1:f({value:"https://"})(t),d=()=>t=>s(t)?!1:typeof t=="number",Q=()=>t=>s(t)?!1:d()(t)&&Number.isInteger(t),X=()=>t=>{if(s(t))return!1;try{return JSON.parse(String(t)),!0}catch{return!1}},Y=({length:t})=>e=>s(e)?!1:Array.isArray(e)?e.length===t:!1,ee=()=>t=>s(t)?!1:String(t)===String(t).toLowerCase(),te=({values:t})=>e=>s(e)?!1:Array.isArray(e)?!t.every(r=>e.includes(r)):!1,re=({values:t})=>e=>s(e)?!1:Array.isArray(e)?!t.some(r=>e.includes(r)):!1,ne=({value:t})=>e=>e!==t,se=({values:t})=>e=>s(e)?!1:!t.includes(e),v=()=>t=>typeof t=="string",ie=()=>t=>s(t)?!1:v()(t)?/^-?\d+(\.\d+)?$/.test(String(t)):d()(t),ae=({values:t})=>e=>s(e)?!1:t.includes(e),le=({expression:t})=>e=>{if(s(e))return!1;if(!(t instanceof RegExp))throw new TypeError("The expression provided is not a valid RegExp.");return t.test(String(e))},ue=()=>t=>!s(t),oe=({value:t})=>e=>s(e)?!1:Array.isArray(e)?e.every(r=>r===t):e===t,S=({size:t})=>e=>s(e)?!1:typeof e=="number"?e===t:Array.isArray(e)?e.every(r=>S({size:t})(r)):!1,$=({length:t})=>e=>s(e)?!1:typeof e=="string"?e.length<=t:Array.isArray(e)?e.every(r=>$({length:t})(r)):!1,p=({length:t})=>e=>s(e)?!1:typeof e=="string"?e.length>=t:Array.isArray(e)?e.every(r=>p({length:t})(r)):!1,he=({min:t,max:e})=>r=>s(r)?!1:p({length:t})(r)&&$({length:e})(r),x=({length:t})=>e=>s(e)?!1:typeof e=="string"?e.length===t:Array.isArray(e)?e.every(r=>x({length:t})(r)):!1,fe={accepted:_,alpha:j,alphaDash:q,alphaDashDot:M,alphaNum:F,array:k,ascii:O,between:B,betweenLength:D,boolean:E,containsAll:T,containsAny:R,declined:W,different:N,distinct:Z,domain:K,email:I,endsWith:V,equals:J,file:P,fileBetweenSize:U,fileMaxSize:g,fileMinSize:y,fileSize:L,http:G,https:H,integer:Q,json:X,length:Y,lowercase:ee,max:c,maxLength:A,min:m,minLength:w,notContainsAll:te,notContainsAny:re,notEquals:ne,notOneOf:se,number:d,numeric:ie,oneOf:ae,regex:le,required:ue,same:oe,size:S,startsWith:f,string:v,stringBetweenLength:he,stringContainsAll:T,stringContainsAny:R,stringLength:x,stringMaxLength:$,stringMinLength:p,stringNotContainsAll:({values:t})=>e=>s(e)?!1:typeof e=="string"?!t.every(r=>e.includes(r)):!1,stringNotContainsAny:({values:t})=>e=>s(e)?!1:typeof e=="string"?!t.some(r=>e.includes(r)):!1,unique:({values:t,ignored:e=[]})=>r=>s(r)?!1:(Array.isArray(e)?e:[e]).some(i=>i===r)?!0:!t.some(i=>i===r),uppercase:()=>t=>s(t)?!1:String(t)===String(t).toUpperCase(),url:()=>t=>s(t)?!1:/^(https?):\/\/[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}.*$/.test(String(t))};class ce{constructor({fallbackLocale:e,locale:r,plugins:i}={}){o(this,"locale","en");o(this,"fallbackLocale","en");o(this,"locales",{});o(this,"rules",{});this.registerLocales(C),this.registerRules(fe),e&&this.setFallbackLocale(e),r&&this.setLocale(r),i&&i.forEach(a=>this.registerPlugin(a))}getLocale(){return this.locale}getFallbackLocale(){return this.fallbackLocale}setLocale(e){if(!(e in this.locales))throw new Error(`The "${e}" locale is not registered.`);return this.locale=e,this}setFallbackLocale(e){if(!(e in this.locales))throw new Error(`The "${e}" fallback locale is not registered.`);return this.fallbackLocale=e,this}defineField(e){return new b({name:e,locale:this.locale,fallbackLocale:this.fallbackLocale,locales:this.locales,rules:this.rules})}registerLocales(e){return this.locales=Object.keys(e).reduce((r,i)=>(r[i]={...this.locales[i],...e[i]},r),{...this.locales}),this}registerRules(e){return this.rules={...this.rules,...e},this}registerPlugin(e){if(!e||!e.locales||!e.rules)throw new Error('The plugin must have "locales" and "rules" properties.');return this.registerLocales(e.locales).registerRules(e.rules)}}u.FieldValidator=b,u.FormValidator=ce,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(h,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(h=typeof globalThis<"u"?globalThis:h||self,o(h.Fortress={}))})(this,function(h){"use strict";var Ae=Object.defineProperty;var we=(h,o,n)=>o in h?Ae(h,o,{enumerable:!0,configurable:!0,writable:!0,value:n}):h[o]=n;var u=(h,o,n)=>(we(h,typeof o!="symbol"?o+"":o,n),n);const o=t=>{const e=",、;:!?。()《》「」『』【】〔〕",r="\\x20-\\x7E",s=new RegExp(`\\s*([${e}])`,"gu"),l=new RegExp(`([${e}])\\s*([${r}])`,"gu"),f=new RegExp(`([^${r}${e}])([${r}])`,"gu"),be=new RegExp(`([${r}])([^${r}${e}])`,"gu");return t.replace(s,"$1").replace(l,"$1$2").replace(f,"$1 $2").replace(be,"$1 $2").replace(/ +/g," ")},n=(t,e=0)=>new Intl.NumberFormat(void 0,{minimumFractionDigits:e,maximumFractionDigits:e}).format(t),O=t=>Object.prototype.toString.call(t).toLowerCase().slice(8,-1),a=t=>t==null||t===""||Array.isArray(t)&&t.length<1,i=t=>`"${t}"`;class R{constructor({name:e,locale:r,fallbackLocale:s,locales:l,rules:f}){u(this,"name");u(this,"locale");u(this,"fallbackLocale");u(this,"locales");u(this,"rules");u(this,"ruleFunctions",{});u(this,"conditions",{});u(this,"shouldSkip",!1);u(this,"appliedProtocols",{});this.name=e,this.locale=r,this.fallbackLocale=s,this.locales=l,this.rules=f}get formattedName(){return this.name.toLowerCase()}get messages(){return this.locales[this.locale]||{}}get fallbackMessages(){return this.locales[this.fallbackLocale]||{}}get mandatoryRules(){return[this.required.name,this.string.name,this.array.name,this.equals.name,this.notEquals.name]}getMessage(e){return this.messages[e]||this.fallbackMessages[e]||(r=>`The ${r} field is invalid.`)}getRule(e){if(!(e in this.rules))throw new Error(`The "${e}" rule is not registered.`);return this.rules[e]}buildRuleFunction(e,r){return s=>{if(a(s)&&!this.mandatoryRules.includes(e))return!0;const l=this.getRule(e)(r)(s);return typeof l=="string"?l:l===!0?!0:this.buildRuleFunctionMessage(e,r,s)}}buildRuleFunctionMessage(e,r,s){const l=this.getMessage(e)(this.formattedName,r);if(typeof l=="object"){const f=O(s);if(!(f in l))throw new Error(`The message for the "${e}" rule of the "${f}" type is missing.`);return o(l[f])}return o(l)}pushRuleFunction(e,r){if(e in this.conditions&&!this.conditions[e])return this;const s=this.buildRuleFunction(e,r);return this.ruleFunctions[e]=s,this}getRuleFunctions(){return Object.values(this.ruleFunctions)}collect(){return this.shouldSkip?[]:this.getRuleFunctions()}validate(e){if(this.shouldSkip)return!0;const r=this.getRuleFunctions();for(const s of r){const l=s(e);if(typeof l=="string")return l}return!0}apply(e,r={}){return this.pushRuleFunction(e,r)}accepted(){return this.apply(this.accepted.name)}after(e,r,s,l=!0){return this.apply(this.after.name,{date:e,format:r,displayFormat:s,strict:l})}alpha(){return this.apply(this.alpha.name)}alphaDash(){return this.apply(this.alphaDash.name)}alphaDashDot(){return this.apply(this.alphaDashDot.name)}alphaNum(){return this.apply(this.alphaNum.name)}array(){return this.apply(this.array.name)}ascii(){return this.apply(this.ascii.name)}before(e,r,s,l=!0){return this.apply(this.before.name,{date:e,format:r,displayFormat:s,strict:l})}between(e,r){return this.apply(this.between.name,{min:e,max:r})}betweenLength(e,r){return this.apply(this.betweenLength.name,{min:e,max:r})}boolean(){return this.apply(this.boolean.name)}containsAll(e){return this.apply(this.containsAll.name,{values:e})}containsAny(e){return this.apply(this.containsAny.name,{values:e})}date(e,r=!0){return this.apply(this.date.name,{format:e,strict:r})}declined(){return this.apply(this.declined.name)}different(e,r){return this.apply(this.different.name,{field:e,value:r})}distinct(){return this.apply(this.distinct.name)}domain(){return this.apply(this.domain.name)}email(){return this.apply(this.email.name)}endsWith(e){return this.apply(this.endsWith.name,{value:e})}equals(e){return this.apply(this.equals.name,{value:e})}file(){return this.apply(this.file.name)}fileBetweenSize(e,r){return this.apply(this.fileBetweenSize.name,{min:e,max:r})}fileMaxSize(e){return this.apply(this.fileMaxSize.name,{size:e})}fileMinSize(e){return this.apply(this.fileMinSize.name,{size:e})}fileSize(e){return this.apply(this.fileSize.name,{size:e})}http(){return this.appliedProtocols[this.http.name]=!0,this.apply(this.http.name)}httpOrHttps(){return this.appliedProtocols[this.http.name]=!0,this.appliedProtocols[this.https.name]=!0,this.apply(this.httpOrHttps.name)}https(){return this.appliedProtocols[this.https.name]=!0,this.apply(this.https.name)}integer(){return this.apply(this.integer.name)}ip(){const e=Object.keys(this.appliedProtocols).length>0;return this.apply(this.ip.name,{includeProtocol:e})}ipv4(){const e=Object.keys(this.appliedProtocols).length>0;return this.apply(this.ipv4.name,{includeProtocol:e})}ipv6(){const e=Object.keys(this.appliedProtocols).length>0;return this.apply(this.ipv6.name,{includeProtocol:e})}iso8601(){return this.apply(this.iso8601.name)}json(){return this.apply(this.json.name)}jsonSchema(e){return this.apply(this.jsonSchema.name,{schema:e,locale:this.locale,field:this.name})}length(e){return this.apply(this.length.name,{length:e})}lowercase(){return this.apply(this.lowercase.name)}max(e){return this.apply(this.max.name,{max:e})}maxLength(e){return this.apply(this.maxLength.name,{length:e})}min(e){return this.apply(this.min.name,{min:e})}minLength(e){return this.apply(this.minLength.name,{length:e})}notContainsAll(e){return this.apply(this.notContainsAll.name,{values:e})}notContainsAny(e){return this.apply(this.notContainsAny.name,{values:e})}notEquals(e){return this.apply(this.notEquals.name,{value:e})}notOneOf(e){return this.apply(this.notOneOf.name,{values:e})}protocol(e){const r=Array.isArray(e)?e:[e];return r.forEach(s=>this.appliedProtocols[s]=!0),this.apply(this.protocol.name,{values:r})}number(){return this.apply(this.number.name)}numeric(){return this.apply(this.numeric.name)}oneOf(e){return this.apply(this.oneOf.name,{values:e})}regex(e){return this.apply(this.regex.name,{expression:e})}required(){return this.apply(this.required.name)}requiredWhen(e){return this.when({required:e}).required()}same(e,r){return this.apply(this.same.name,{field:e,value:r})}size(e){return this.apply(this.size.name,{size:e})}startsWith(e){return this.apply(this.startsWith.name,{value:e})}string(){return this.apply(this.string.name)}stringBetweenLength(e,r){return this.apply(this.stringBetweenLength.name,{min:e,max:r})}stringContainsAll(e){return this.apply(this.stringContainsAll.name,{values:e})}stringContainsAny(e){return this.apply(this.stringContainsAny.name,{values:e})}stringLength(e){return this.apply(this.stringLength.name,{length:e})}stringMaxLength(e){return this.apply(this.stringMaxLength.name,{length:e})}stringMinLength(e){return this.apply(this.stringMinLength.name,{length:e})}stringNotContainsAll(e){return this.apply(this.stringNotContainsAll.name,{values:e})}stringNotContainsAny(e){return this.apply(this.stringNotContainsAny.name,{values:e})}unique(e,r=[]){return this.apply(this.unique.name,{values:e,ignored:r})}uppercase(){return this.apply(this.uppercase.name)}url(){return this.apply(this.url.name)}when(e){return typeof e=="object"?(this.conditions=e,this):(e||(this.shouldSkip=!0),this)}}const M={en:{accepted:t=>`The ${t} field must be accepted.`,alpha:t=>`The ${t} field must only contain letters.`,alphaDash:t=>`The ${t} field must only contain letters, numbers, dashes and underscores.`,alphaDashDot:t=>`The ${t} field must only contain letters, numbers, dashes, underscores and dots.`,alphaNum:t=>`The ${t} field must only contain letters and numbers.`,array:t=>`The ${t} field must be an array.`,ascii:t=>`The ${t} field must only contain ASCII characters and symbols.`,between:(t,e)=>{const{min:r,max:s}=e;return{number:`The ${t} field must be between ${n(r)} and ${n(s)}.`,array:`The ${t} field must contain items where each item is between ${n(r)} and ${n(s)}.`}},betweenLength:(t,e)=>{const{min:r,max:s}=e;return`The ${t} field must be between ${n(r)} and ${n(s)} items.`},boolean:t=>`The ${t} field must be a boolean value.`,containsAll:(t,e)=>{const{values:r}=e;return`The ${t} field must contain all of the following values: ${r.map(i).join(", ")}.`},containsAny:(t,e)=>{const{values:r}=e;return`The ${t} field must contain at least one of the following values: ${r.map(i).join(", ")}.`},declined:t=>`The ${t} field must be declined.`,different:(t,e)=>{const{field:r}=e;return`The ${t} and ${r} fields must be different.`},distinct:t=>`The ${t} field must not contain duplicate values.`,domain:t=>`The ${t} field must be a valid domain.`,email:t=>`The ${t} field must be a valid email address.`,endsWith:(t,e)=>{const{value:r}=e;return`The ${t} field must end with ${r}.`},equals:(t,e)=>{const{value:r}=e;return`The ${t} field must be equal to ${r}.`},file:t=>`The ${t} field must be a file.`,fileBetweenSize:(t,e)=>{const{min:r,max:s}=e;return{file:`The ${t} field must be between ${n(r)} and ${n(s)} kilobytes.`,array:`The ${t} field must contain items where each item is between ${n(r)} and ${n(s)} kilobytes.`}},fileMaxSize:(t,e)=>{const{size:r}=e;return{file:`The ${t} field must not be greater than ${n(r)} kilobytes.`,array:`The ${t} field must contain items where each item is not greater than ${n(r)} kilobytes.`}},fileMinSize:(t,e)=>{const{size:r}=e;return{file:`The ${t} field must be at least ${n(r)} kilobytes.`,array:`The ${t} field must contain items where each item is at least ${n(r)} kilobytes.`}},fileSize:(t,e)=>{const{size:r}=e;return{file:`The ${t} field must be ${n(r)} kilobytes.`,array:`The ${t} field must contain items where each item is ${n(r)} kilobytes.`}},http:t=>`The ${t} field must start with the "http://" protocol.`,httpOrHttps:t=>`The ${t} field must start with the "http://" or "https://" protocols.`,https:t=>`The ${t} field must start with the "https://" protocol.`,integer:t=>`The ${t} field must be an integer.`,ip:t=>`The ${t} field must be a valid IP address.`,ipv4:t=>`The ${t} field must be a valid IPv4 address.`,ipv6:t=>`The ${t} field must be a valid IPv6 address.`,json:t=>`The ${t} field must be a valid JSON string.`,length:(t,e)=>{const{length:r}=e;return`The ${t} field must be ${n(r)} items.`},lowercase:t=>`The ${t} field must be lowercase.`,max:(t,e)=>{const{max:r}=e;return{number:`The ${t} field must not be greater than ${n(r)}.`,array:`The ${t} field must contain items where each item is not greater than ${n(r)}.`}},maxLength:(t,e)=>{const{length:r}=e;return`The ${t} field must not be greater than ${n(r)} items.`},min:(t,e)=>{const{min:r}=e;return{number:`The ${t} field must be at least ${n(r)}.`,array:`The ${t} field must contain items where each item is at least ${n(r)}.`}},minLength:(t,e)=>{const{length:r}=e;return`The ${t} field must be at least ${n(r)} items.`},notContainsAll:(t,e)=>{const{values:r}=e;return`The ${t} field must not contain all of the following values together: ${r.map(i).join(", ")}.`},notContainsAny:(t,e)=>{const{values:r}=e;return`The ${t} field must not contain any of the following values: ${r.map(i).join(", ")}.`},notEquals:(t,e)=>{const{value:r}=e;return`The ${t} field must not be equal to ${r}.`},notOneOf:(t,e)=>{const{values:r}=e;return`The ${t} field must not be one of the following values: ${r.map(i).join(", ")}.`},number:t=>`The ${t} field must be a number.`,numeric:t=>`The ${t} field must be a number.`,oneOf:(t,e)=>{const{values:r}=e;return`The ${t} field must be one of the following values: ${r.map(i).join(", ")}.`},protocol:(t,e)=>{const{values:r}=e;if(r.length===1){const[s]=r;return`The ${t} field must start with the "${s}://" protocol.`}return`The ${t} field must start with one of the following protocols: ${r.map(s=>`${s}://`).map(i).join(", ")}.`},regex:t=>`The ${t} field must match the required format.`,required:t=>`The ${t} field is required.`,same:(t,e)=>{const{field:r}=e;return`The ${t} and ${r} fields must match.`},size:(t,e)=>{const{size:r}=e;return{number:`The ${t} field must be ${n(r)}.`,array:`The ${t} field must contain items where each item is ${n(r)}.`}},startsWith:(t,e)=>{const{value:r}=e;return`The ${t} field must start with ${r}.`},string:t=>`The ${t} field must be a string.`,stringBetweenLength:(t,e)=>{const{min:r,max:s}=e;return{string:`The ${t} field must be between ${n(r)} and ${n(s)} characters.`,array:`The ${t} field must contain items where each item is between ${n(r)} and ${n(s)} characters.`}},stringContainsAll:(t,e)=>{const{values:r}=e;return`The ${t} field must contain all of the following text: ${r.map(i).join(", ")}.`},stringContainsAny:(t,e)=>{const{values:r}=e;return`The ${t} field must contain at least one of the following text: ${r.map(i).join(", ")}.`},stringLength:(t,e)=>{const{length:r}=e;return{string:`The ${t} field must be ${n(r)} characters.`,array:`The ${t} field must contain items where each item is ${n(r)} characters.`}},stringMaxLength:(t,e)=>{const{length:r}=e;return{string:`The ${t} field must not be greater than ${n(r)} characters.`,array:`The ${t} field must contain items where each item is not greater than ${n(r)} characters.`}},stringMinLength:(t,e)=>{const{length:r}=e;return{string:`The ${t} field must be at least ${n(r)} characters.`,array:`The ${t} field must contain items where each item is at least ${n(r)} characters.`}},stringNotContainsAll:(t,e)=>{const{values:r}=e;return`The ${t} field must not contain all of the following text together: ${r.map(i).join(", ")}.`},stringNotContainsAny:(t,e)=>{const{values:r}=e;return`The ${t} field must not contain any of the following text: ${r.map(i).join(", ")}.`},unique:t=>`The ${t} field has already been taken.`,uppercase:t=>`The ${t} field must be uppercase.`,url:t=>`The ${t} field must be a valid URL.`},"zh-TW":{accepted:()=>"此欄位必須被同意",alpha:()=>"此欄位只能包含字母",alphaDash:()=>"此欄位只能包含字母、數字、連接號和底線",alphaDashDot:()=>"此欄位只能包含字母、數字、連接號、底線和點",alphaNum:()=>"此欄位只能包含字母和數字",array:()=>"此欄位必須是一個陣列",ascii:()=>"此欄位只能包含 ASCII 字元和符號",between:(t,e)=>{const{min:r,max:s}=e;return{number:`此欄位必須介於${n(r)}到${n(s)}`,array:`此欄位中的每個項目都必須介於${n(r)}到${n(s)}`}},betweenLength:(t,e)=>{const{min:r,max:s}=e;return`此欄位必須介於${n(r)}到${n(s)}個項目之間`},boolean:()=>"此欄位必須是一個布林值",containsAll:(t,e)=>{const{values:r}=e;return`此欄位必須包含以下所有項目:${r.map(i).join(", ")}`},containsAny:(t,e)=>{const{values:r}=e;return`此欄位必須包含以下其中一個項目:${r.map(i).join(", ")}`},declined:()=>"此欄位必須被拒絕",different:(t,e)=>{const{field:r}=e;return`此欄位必須和${r}欄位不同`},distinct:()=>"此欄位不能包含重複的值",domain:()=>"此欄位必須是有效的網域",email:()=>"此欄位必須是有效的電子郵件地址",endsWith:(t,e)=>{const{value:r}=e;return`此欄位必須以${r}結尾`},equals:(t,e)=>{const{value:r}=e;return`此欄位必須是${r}`},file:()=>"此欄位必須是檔案",fileBetweenSize:(t,e)=>{const{min:r,max:s}=e;return{file:`此欄位必須介於${n(r)}到${n(s)} KB 之間`,array:`此欄位中的每個項目都必須介於${n(r)}到${n(s)} KB 之間`}},fileMaxSize:(t,e)=>{const{size:r}=e;return{file:`此欄位不能大於${n(r)} KB`,array:`此欄位中的每個項目都不能大於${n(r)} KB`}},fileMinSize:(t,e)=>{const{size:r}=e;return{file:`此欄位不能小於${n(r)} KB`,array:`此欄位中的每個項目都不能小於${n(r)} KB`}},fileSize:(t,e)=>{const{size:r}=e;return{file:`此欄位必須是${n(r)} KB`,array:`此欄位中的每個項目都必須是${n(r)} KB`}},http:()=>'此欄位必須以 "http://" 協議開頭',httpOrHttps:()=>'此欄位必須以 "http://" 或 "https://" 協議開頭',https:()=>'此欄位必須以 "https://" 協議開頭',integer:()=>"此欄位必須是整數",ip:()=>"此欄位必須是有效的 IP 位址",ipv4:()=>"此欄位必須是有效的 IPv4 位址",ipv6:()=>"此欄位必須是有效的 IPv6 位址",json:()=>"此欄位必須是有效的 JSON 字串",length:(t,e)=>{const{length:r}=e;return`此欄位必須包含${n(r)}個項目`},lowercase:()=>"此欄位必須是小寫",max:(t,e)=>{const{max:r}=e;return{number:`此欄位不能大於${n(r)}`,array:`此欄位中的每個項目都不能大於${n(r)}`}},maxLength:(t,e)=>{const{length:r}=e;return`此欄位不能大於${n(r)}個項目`},min:(t,e)=>{const{min:r}=e;return{number:`此欄位不能小於${n(r)}`,array:`此欄位中的每個項目都不能小於${n(r)}`}},minLength:(t,e)=>{const{length:r}=e;return`此欄位不能小於${n(r)}個項目`},notContainsAll:(t,e)=>{const{values:r}=e;return`此欄位不能同時包含以下所有值:${r.map(i).join(", ")}`},notContainsAny:(t,e)=>{const{values:r}=e;return`此欄位不能包含以下任何值:${r.map(i).join(", ")}`},notEquals:(t,e)=>{const{value:r}=e;return`此欄位不能是${r}`},notOneOf:(t,e)=>{const{values:r}=e;return`此欄位不能是以下任何值:${r.map(i).join(", ")}`},number:()=>"此欄位必須是數字",numeric:()=>"此欄位必須是數字",oneOf:(t,e)=>{const{values:r}=e;return`此欄位必須是以下其中一個值:${r.map(i).join(", ")}`},protocol:(t,e)=>{const{values:r}=e;if(r.length===1){const[s]=r;return`此欄位必須以 "${s}://" 協議開頭`}return`此欄位必須以以下其中一個協議開頭:${r.map(s=>`${s}://`).map(i).join(", ")}`},regex:()=>"此欄位必須符合所需的格式",required:()=>"此欄位為必填",same:(t,e)=>{const{field:r}=e;return`此欄位必須與${r}欄位相同`},size:(t,e)=>{const{size:r}=e;return{number:`此欄位必須是${n(r)}`,array:`此欄位中的每個項目都必須是${n(r)}`}},startsWith:(t,e)=>{const{value:r}=e;return`此欄位必須以${r}開頭`},string:()=>"此欄位必須是字串",stringBetweenLength:(t,e)=>{const{min:r,max:s}=e;return{string:`此欄位必須介於${n(r)}到${n(s)}個字元之間`,array:`此欄位中的每個項目都必須介於${n(r)}到${n(s)}個字元之間`}},stringContainsAll:(t,e)=>{const{values:r}=e;return`此欄位必須包含以下所有文字:${r.map(i).join(", ")}`},stringContainsAny:(t,e)=>{const{values:r}=e;return`此欄位必須包含以下其中一個文字:${r.map(i).join(", ")}`},stringLength:(t,e)=>{const{length:r}=e;return{string:`此欄位必須是${n(r)}個字元`,array:`此欄位中的每個項目都必須是${n(r)}個字元`}},stringMaxLength:(t,e)=>{const{length:r}=e;return{string:`此欄位不能大於${n(r)}個字元`,array:`此欄位中的每個項目都不能大於${n(r)}個字元`}},stringMinLength:(t,e)=>{const{length:r}=e;return{string:`此欄位不能小於${n(r)}個字元`,array:`此欄位中的每個項目都不能小於${n(r)}個字元`}},stringNotContainsAll:(t,e)=>{const{values:r}=e;return`此欄位不能同時包含以下所有文字:${r.map(i).join(", ")}`},stringNotContainsAny:(t,e)=>{const{values:r}=e;return`此欄位不能包含以下任何文字:${r.map(i).join(", ")}`},unique:()=>"此欄位已經存在",uppercase:()=>"此欄位必須是大寫",url:()=>"此欄位必須是有效的 URL"}},k=()=>t=>a(t)?!1:["y","yes","on","1","true"].includes(String(t).toLowerCase()),E=()=>t=>a(t)?!1:/^[a-zA-Z]+$/.test(String(t)),B=()=>t=>a(t)?!1:/^[a-zA-Z0-9-_]+$/.test(String(t)),D=()=>t=>a(t)?!1:/^[a-zA-Z0-9-_.]+$/.test(String(t)),N=()=>t=>a(t)?!1:/^[a-zA-Z0-9]+$/.test(String(t)),P=()=>t=>Array.isArray(t),W=()=>t=>a(t)?!1:/^[\x20-\x7E]+$/.test(String(t)),c=({max:t})=>e=>a(e)?!1:typeof e=="number"?e<=t:Array.isArray(e)?e.every(r=>c({max:t})(r)):!1,m=({min:t})=>e=>a(e)?!1:typeof e=="number"?e>=t:Array.isArray(e)?e.every(r=>m({min:t})(r)):!1,I=({min:t,max:e})=>r=>a(r)?!1:m({min:t})(r)&&c({max:e})(r),T=({length:t})=>e=>a(e)?!1:Array.isArray(e)?e.length<=t:!1,v=({length:t})=>e=>a(e)?!1:Array.isArray(e)?e.length>=t:!1,Z=({min:t,max:e})=>r=>a(r)?!1:v({length:t})(r)&&T({length:e})(r),K=()=>t=>a(t)?!1:typeof t=="boolean",L=({values:t})=>e=>a(e)?!1:Array.isArray(e)?t.every(r=>e.includes(r)):!1,S=({values:t})=>e=>a(e)?!1:Array.isArray(e)?t.some(r=>e.includes(r)):!1,H=()=>t=>a(t)?!1:["n","no","off","0","false"].includes(String(t).toLowerCase()),U=({value:t})=>e=>a(e)?!1:e!==t,V=()=>t=>a(t)?!1:Array.isArray(t)?new Set(t).size===t.length:!0,J=()=>t=>a(t)?!1:/^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(String(t)),G=()=>t=>a(t)?!1:/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(String(t)),Q=({value:t})=>e=>a(e)?!1:String(e).endsWith(t),X=({value:t})=>e=>e===t,Y=()=>t=>t instanceof File,g=({size:t})=>e=>a(e)?!1:e instanceof File?e.size<=t*1024:Array.isArray(e)?e.every(r=>g({size:t})(r)):!1,d=({size:t})=>e=>a(e)?!1:e instanceof File?e.size>=t*1024:Array.isArray(e)?e.every(r=>d({size:t})(r)):!1,ee=({min:t,max:e})=>r=>a(r)?!1:d({size:t})(r)&&g({size:e})(r),x=({size:t})=>e=>{if(a(e))return!1;if(e instanceof File){const r=t*1024,s=(t+1)*1024;return e.size>=r&&e.size<s}return Array.isArray(e)?e.every(r=>x({size:t})(r)):!1},z=({value:t})=>e=>a(e)?!1:String(e).startsWith(t),y=({values:t})=>e=>a(e)?!1:t.map(r=>`${r}://`).some(r=>z({value:r})(e)),F=()=>t=>a(t)?!1:y({values:["http"]})(t),C=()=>t=>a(t)?!1:y({values:["https"]})(t),te=()=>t=>a(t)?!1:F()(t)||C()(t),p=()=>t=>a(t)?!1:typeof t=="number",re=()=>t=>a(t)?!1:p()(t)&&Number.isInteger(t),$=({includeProtocol:t}={})=>e=>{if(a(e))return!1;if(t)try{const{host:r}=new URL(String(e));return $({})(r)}catch{return!1}return/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(:\d+)?$/.test(String(e))},b=({includeProtocol:t}={})=>e=>{if(a(e))return!1;if(t)try{const{host:r}=new URL(String(e));return b({})(r)}catch{return!1}return/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/.test(String(e))},ne=({includeProtocol:t}={})=>e=>a(e)?!1:$({includeProtocol:t})(e)||b({includeProtocol:t})(e),se=()=>t=>{if(a(t))return!1;try{return JSON.parse(String(t)),!0}catch{return!1}},ae=({length:t})=>e=>a(e)?!1:Array.isArray(e)?e.length===t:!1,ie=()=>t=>a(t)?!1:String(t)===String(t).toLowerCase(),le=({values:t})=>e=>a(e)?!1:Array.isArray(e)?!t.every(r=>e.includes(r)):!1,oe=({values:t})=>e=>a(e)?!1:Array.isArray(e)?!t.some(r=>e.includes(r)):!1,ue=({value:t})=>e=>e!==t,he=({values:t})=>e=>a(e)?!1:!t.includes(e),j=()=>t=>typeof t=="string",fe=()=>t=>a(t)?!1:j()(t)?/^-?\d+(\.\d+)?$/.test(String(t)):p()(t),ce=({values:t})=>e=>a(e)?!1:t.includes(e),me=({expression:t})=>e=>{if(a(e))return!1;if(!(t instanceof RegExp))throw new TypeError("The expression provided is not a valid RegExp.");return t.test(String(e))},ge=()=>t=>!a(t),de=({value:t})=>e=>a(e)?!1:Array.isArray(e)?e.every(r=>r===t):e===t,_=({size:t})=>e=>a(e)?!1:typeof e=="number"?e===t:Array.isArray(e)?e.every(r=>_({size:t})(r)):!1,A=({length:t})=>e=>a(e)?!1:typeof e=="string"?e.length<=t:Array.isArray(e)?e.every(r=>A({length:t})(r)):!1,w=({length:t})=>e=>a(e)?!1:typeof e=="string"?e.length>=t:Array.isArray(e)?e.every(r=>w({length:t})(r)):!1,ye=({min:t,max:e})=>r=>a(r)?!1:w({length:t})(r)&&A({length:e})(r),q=({length:t})=>e=>a(e)?!1:typeof e=="string"?e.length===t:Array.isArray(e)?e.every(r=>q({length:t})(r)):!1,pe={accepted:k,alpha:E,alphaDash:B,alphaDashDot:D,alphaNum:N,array:P,ascii:W,between:I,betweenLength:Z,boolean:K,containsAll:L,containsAny:S,declined:H,different:U,distinct:V,domain:J,email:G,endsWith:Q,equals:X,file:Y,fileBetweenSize:ee,fileMaxSize:g,fileMinSize:d,fileSize:x,http:F,httpOrHttps:te,https:C,integer:re,ip:ne,ipv4:$,ipv6:b,json:se,length:ae,lowercase:ie,max:c,maxLength:T,min:m,minLength:v,notContainsAll:le,notContainsAny:oe,notEquals:ue,notOneOf:he,number:p,numeric:fe,oneOf:ce,protocol:y,regex:me,required:ge,same:de,size:_,startsWith:z,string:j,stringBetweenLength:ye,stringContainsAll:L,stringContainsAny:S,stringLength:q,stringMaxLength:A,stringMinLength:w,stringNotContainsAll:({values:t})=>e=>a(e)?!1:typeof e=="string"?!t.every(r=>e.includes(r)):!1,stringNotContainsAny:({values:t})=>e=>a(e)?!1:typeof e=="string"?!t.some(r=>e.includes(r)):!1,unique:({values:t,ignored:e=[]})=>r=>a(r)?!1:(Array.isArray(e)?e:[e]).some(s=>s===r)?!0:!t.some(s=>s===r),uppercase:()=>t=>a(t)?!1:String(t)===String(t).toUpperCase(),url:()=>t=>{if(a(t))return!1;try{return new URL(String(t)),!0}catch{return!1}}};class $e{constructor({fallbackLocale:e,locale:r,plugins:s}={}){u(this,"locale","en");u(this,"fallbackLocale","en");u(this,"locales",{});u(this,"rules",{});this.registerLocales(M),this.registerRules(pe),e&&this.setFallbackLocale(e),r&&this.setLocale(r),s&&s.forEach(l=>this.registerPlugin(l))}getLocale(){return this.locale}getFallbackLocale(){return this.fallbackLocale}setLocale(e){if(!(e in this.locales))throw new Error(`The "${e}" locale is not registered.`);return this.locale=e,this}setFallbackLocale(e){if(!(e in this.locales))throw new Error(`The "${e}" fallback locale is not registered.`);return this.fallbackLocale=e,this}defineField(e){return new R({name:e,locale:this.locale,fallbackLocale:this.fallbackLocale,locales:this.locales,rules:this.rules})}registerLocales(e){return this.locales=Object.keys(e).reduce((r,s)=>(r[s]={...this.locales[s],...e[s]},r),{...this.locales}),this}registerRules(e){return this.rules={...this.rules,...e},this}registerPlugin(e){if(!e||!e.locales||!e.rules)throw new Error('The plugin must have "locales" and "rules" properties.');return this.registerLocales(e.locales).registerRules(e.rules)}}h.FieldValidator=R,h.FormValidator=$e,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})});
|
|
@@ -2,5 +2,5 @@ import { Rule, RuleArguments } from '@kklab/fortress-validator-types';
|
|
|
2
2
|
export interface NotContainsAllRuleArguments extends RuleArguments {
|
|
3
3
|
values: unknown[];
|
|
4
4
|
}
|
|
5
|
-
declare const
|
|
6
|
-
export default
|
|
5
|
+
declare const notContainsAllRule: Rule<NotContainsAllRuleArguments>;
|
|
6
|
+
export default notContainsAllRule;
|
|
@@ -2,5 +2,5 @@ import { Rule, RuleArguments } from '@kklab/fortress-validator-types';
|
|
|
2
2
|
export interface NotContainsAnyRuleArguments extends RuleArguments {
|
|
3
3
|
values: unknown[];
|
|
4
4
|
}
|
|
5
|
-
declare const
|
|
6
|
-
export default
|
|
5
|
+
declare const notContainsAnyRule: Rule<NotContainsAnyRuleArguments>;
|
|
6
|
+
export default notContainsAnyRule;
|
|
@@ -2,5 +2,5 @@ import { Rule, RuleArguments } from '@kklab/fortress-validator-types';
|
|
|
2
2
|
export interface StringNotContainsAllRuleArguments extends RuleArguments {
|
|
3
3
|
values: string[];
|
|
4
4
|
}
|
|
5
|
-
declare const
|
|
6
|
-
export default
|
|
5
|
+
declare const stringNotContainsAllRule: Rule<StringNotContainsAllRuleArguments>;
|
|
6
|
+
export default stringNotContainsAllRule;
|
|
@@ -2,5 +2,5 @@ import { Rule, RuleArguments } from '@kklab/fortress-validator-types';
|
|
|
2
2
|
export interface StringNotContainsAnyRuleArguments extends RuleArguments {
|
|
3
3
|
values: string[];
|
|
4
4
|
}
|
|
5
|
-
declare const
|
|
6
|
-
export default
|
|
5
|
+
declare const stringNotContainsAnyRule: Rule<StringNotContainsAnyRuleArguments>;
|
|
6
|
+
export default stringNotContainsAnyRule;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kklab/fortress-validator",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.12",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"release": "npm run test && npm run build && npm publish --access public"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@kklab/fortress-validator-utils": "^1.0.
|
|
17
|
+
"@kklab/fortress-validator-utils": "^1.0.3"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@kklab/fortress-validator-plugin-date": "^1.0.4",
|