Skip to content

Commit 214bc1e

Browse files
committed
feat: implement new phone regexp property
1 parent 7c28c48 commit 214bc1e

File tree

6 files changed

+36
-17
lines changed

6 files changed

+36
-17
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 1.4.0
2+
- Add `RegExp` property in phone validation rule
3+
14
## 1.3.0
25
- Add missing `VineNotSameAsRule` implementation
36
- Implement `VineRegexRule` validation rule

lib/src/contracts/schema.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ abstract interface class VineString implements VineSchema, BasicSchema<VineStrin
112112
/// ```dart
113113
/// vine.string().phone(message: 'The value must be a valid phone number');
114114
/// ```
115-
VineString phone({String? message});
115+
VineString phone({RegExp? match, String? message});
116116

117117
/// Check if the string is an IP address [version] the IP address version [message] the error message to display
118118
/// ```dart

lib/src/rules/string_rule.dart

+20-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:vine/src/contracts/schema.dart';
44
import 'package:vine/src/contracts/vine.dart';
55
import 'package:vine/src/helper.dart';
66

7-
final regex = RegExp(r'^\+?[0-9]{1,4}[-.\s]?[0-9]{1,4}[-.\s]?[0-9]{4,10}$');
7+
final europeanPhoneRegex = RegExp(r'^\+?[0-9]{1,4}[-.\s]?[0-9]{1,4}[-.\s]?[0-9]{4,10}$');
88

99
final class VineStringRule implements VineRule {
1010
final String? message;
@@ -93,13 +93,15 @@ final class VineEmailRule implements VineRule {
9393
}
9494

9595
final class VinePhoneRule implements VineRule {
96+
final RegExp? regex;
9697
final String? message;
9798

98-
const VinePhoneRule(this.message);
99+
const VinePhoneRule(this.regex, this.message);
99100

100101
@override
101102
void handle(VineValidationContext ctx, FieldContext field) {
102-
if (field.value case String value when !regex.hasMatch(value)) {
103+
final currentRegexp = regex ?? europeanPhoneRegex;
104+
if (field.value case String value when !currentRegexp.hasMatch(value)) {
103105
final error = ctx.errorReporter.format('phone', field, message, {});
104106
ctx.errorReporter.report('phone', [...field.customKeys, field.name], error);
105107
}
@@ -161,16 +163,18 @@ final class VineUrlRule implements VineRule {
161163
final bool allowUnderscores;
162164
final String? message;
163165

164-
const VineUrlRule(this.protocols, this.requireTld, this.requireProtocol, this.allowUnderscores, this.message);
166+
const VineUrlRule(
167+
this.protocols, this.requireTld, this.requireProtocol, this.allowUnderscores, this.message);
165168

166169
@override
167170
void handle(VineValidationContext ctx, FieldContext field) {
168-
if (field.value case String value when !value.isURL({
169-
'protocols': protocols,
170-
'requireTld': requireTld,
171-
'requireProtocol': requireProtocol,
172-
'allowUnderscores': allowUnderscores,
173-
})) {
171+
if (field.value case String value
172+
when !value.isURL({
173+
'protocols': protocols,
174+
'requireTld': requireTld,
175+
'requireProtocol': requireProtocol,
176+
'allowUnderscores': allowUnderscores,
177+
})) {
174178
final error = ctx.errorReporter.format('url', field, message, {});
175179
ctx.errorReporter.report('url', [...field.customKeys, field.name], error);
176180
}
@@ -214,7 +218,8 @@ final class VineStartWithRule implements VineRule {
214218
@override
215219
void handle(VineValidationContext ctx, FieldContext field) {
216220
if (field.value case String value when !value.startsWith(attemptedValue)) {
217-
final error = ctx.errorReporter.format('startWith', field, message, {'value': attemptedValue});
221+
final error =
222+
ctx.errorReporter.format('startWith', field, message, {'value': attemptedValue});
218223
ctx.errorReporter.report('startWith', [...field.customKeys, field.name], error);
219224
}
220225
}
@@ -248,13 +253,15 @@ final class VineConfirmedRule implements VineRule {
248253
final hasKey = ctx.data.containsKey(confirmedKey);
249254

250255
if (!hasKey) {
251-
final error = ctx.errorReporter.format('missingProperty', field, message, {'field': confirmedKey});
256+
final error =
257+
ctx.errorReporter.format('missingProperty', field, message, {'field': confirmedKey});
252258
ctx.errorReporter.report('missingProperty', [...field.customKeys, field.name], error);
253259
}
254260

255261
final currentValue = ctx.data[confirmedKey];
256262
if ((field.value as String) != currentValue) {
257-
final error = ctx.errorReporter.format('confirmed', field, message, {'attemptedName': confirmedKey});
263+
final error =
264+
ctx.errorReporter.format('confirmed', field, message, {'attemptedName': confirmedKey});
258265
ctx.errorReporter.report('confirmed', [...field.customKeys, field.name], error);
259266
}
260267

lib/src/schema/string_schema.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ final class VineStringSchema extends RuleParser implements VineString {
3030
}
3131

3232
@override
33-
VineString phone({String? message}) {
34-
super.addRule(VinePhoneRule(message));
33+
VineString phone({RegExp? match, String? message}) {
34+
super.addRule(VinePhoneRule(match, message));
3535
return this;
3636
}
3737

pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: vine
22
description: Vine is a robust, typed validation library for Dart/Flutter, designed to simplify and secure data management in applications
3-
version: 1.3.0
3+
version: 1.4.0
44
repository: https://github.com/LeadcodeDev/vine
55

66
platforms:

test/rules/string_test.dart

+9
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@ void main() {
9494
expect(() => validator.validate(payload), throwsA(isA<ValidationException>()));
9595
});
9696

97+
test('valid custom phone regexp', () {
98+
final payload = {'phone': '1230025900'};
99+
final validator = vine.compile(vine.object({
100+
'phone': vine.string().phone(match: RegExp(r'^\d{10}$')),
101+
}));
102+
103+
expect(() => validator.validate(payload), returnsNormally);
104+
});
105+
97106
test('valid ipAddress IPv4', () {
98107
final payload = {'ip': '192.168.1.1'};
99108
final validator = vine.compile(vine.object({

0 commit comments

Comments
 (0)