Skip to content

Commit 25a3029

Browse files
committed
email and url now accept empty strings (but not white space).
1 parent 1e69d3c commit 25a3029

File tree

7 files changed

+65
-61
lines changed

7 files changed

+65
-61
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
Nothing yet.
1111

12+
## [1.0.1] - 2025-04-28
13+
14+
### Fixed
15+
16+
- `email` and `url` now accept empty strings (but not white space).
17+
1218
## [1.0.0] - 2025-04-21
1319

1420
### Added
1521

1622
- Implemented Validator, message formatting and validation rules.
1723

18-
[unreleased]: https://github.com/Logitar/js/compare/v1.0.0...HEAD
24+
[unreleased]: https://github.com/Logitar/js/compare/v1.0.1...HEAD
25+
[1.0.1]: https://github.com/Logitar/js/compare/v1.0.0...v1.0.1
1926
[1.0.0]: https://github.com/Logitar/js/releases/tag/v1.0.0

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "logitar-validation",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "JavaScript validation library distributed by Logitar.",
55
"keywords": [
66
"logitar",
@@ -40,4 +40,4 @@
4040
"dependencies": {
4141
"logitar-js": "^1.0.1"
4242
}
43-
}
43+
}

src/rules/__tests__/email.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ describe("email", () => {
1616
expect(outcome.message).toBe("The arguments must be undefined, or a valid email address validation regular expression.");
1717
});
1818

19-
it.concurrent("should return invalid when the value is not a valid email address", () => {
20-
const outcome = email("aa@@bb..cc") as RuleExecutionOutcome;
19+
test.each([" ", "aa@@bb..cc"])("should return invalid when the value is not a valid email address", (value) => {
20+
const outcome = email(value) as RuleExecutionOutcome;
2121
expect(outcome.severity).toBe("error");
2222
expect(outcome.message).toBe("{{name}} must be a valid email address.");
2323
});
2424

25-
it.concurrent("should return valid when the value is a valid email address", () => {
26-
const outcome = email("test@example.com") as RuleExecutionOutcome;
25+
test.each(["", "test@example.com"])("should return valid when the value is a valid email address", (value) => {
26+
const outcome = email(value) as RuleExecutionOutcome;
2727
expect(outcome.severity).toBe("information");
2828
expect(outcome.message).toBeUndefined();
2929
});

src/rules/__tests__/url.spec.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,9 @@ describe("url", () => {
1010
expect(outcome.message).toBe("{{name}} must be a string.");
1111
});
1212

13-
test.each(["", " "])("should return invalid when the value is empty or white-space", (value) => {
13+
test.each([" ", "invalid-url"])("should return invalid when the value is not a valid URL", (value) => {
1414
const outcome = url(value) as RuleExecutionOutcome;
1515
expect(outcome.severity).toBe("error");
16-
expect(outcome.message).toBe("{{name}} cannot be an empty string.");
17-
});
18-
19-
it.concurrent("should return invalid when the value is not a valid URL", () => {
20-
const outcome = url("invalid-url") as RuleExecutionOutcome;
21-
expect(outcome.severity).toBe("error");
2216
expect(outcome.message).toBe("{{name}} must be a valid URL.");
2317
});
2418

@@ -37,6 +31,7 @@ describe("url", () => {
3731
});
3832

3933
test.each([
34+
["", undefined],
4035
["http://example.com", undefined],
4136
["http://example.com", "http,https"],
4237
["http://example.com", "http;https"],

src/rules/email.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,23 @@ const email: ValidationRule = (value: unknown, args: unknown): RuleExecutionOutc
1414
return { severity: "error", message: "{{name}} must be a string." };
1515
}
1616

17-
let isArgsValid: boolean = true;
18-
let regex: RegExp;
19-
if (typeof args === "string" || args instanceof RegExp) {
20-
regex = new RegExp(args);
21-
} else {
22-
regex = new RegExp(defaultRegex);
23-
if (typeof args !== "undefined" && typeof args !== "boolean") {
24-
isArgsValid = false;
17+
if (value.length > 0) {
18+
let isArgsValid: boolean = true;
19+
let regex: RegExp;
20+
if (typeof args === "string" || args instanceof RegExp) {
21+
regex = new RegExp(args);
22+
} else {
23+
regex = new RegExp(defaultRegex);
24+
if (typeof args !== "undefined" && typeof args !== "boolean") {
25+
isArgsValid = false;
26+
}
2527
}
26-
}
2728

28-
if (!regex.test(value)) {
29-
return { severity: "error", message: "{{name}} must be a valid email address." };
30-
} else if (!isArgsValid) {
31-
return { severity: "warning", message: "The arguments must be undefined, or a valid email address validation regular expression." };
29+
if (!regex.test(value)) {
30+
return { severity: "error", message: "{{name}} must be a valid email address." };
31+
} else if (!isArgsValid) {
32+
return { severity: "warning", message: "The arguments must be undefined, or a valid email address validation regular expression." };
33+
}
3234
}
3335

3436
return { severity: "information" };

src/rules/url.ts

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { stringUtils } from "logitar-js";
22

33
import type { RuleExecutionOutcome, ValidationRule } from "../types";
44

5-
const { isNullOrWhiteSpace, trimEnd } = stringUtils;
5+
const { trimEnd } = stringUtils;
66

77
/**
88
* Format a protocol string to be used in a set.
@@ -22,43 +22,43 @@ function format(protocol: string): string {
2222
const url: ValidationRule = (value: unknown, args: unknown): RuleExecutionOutcome => {
2323
if (typeof value !== "string") {
2424
return { severity: "error", message: "{{name}} must be a string." };
25-
} else if (isNullOrWhiteSpace(value)) {
26-
return { severity: "error", message: "{{name}} cannot be an empty string." };
2725
}
2826

29-
let isArgsValid: boolean = true;
30-
const protocols: Set<string> = new Set(["http", "https"]);
31-
if (typeof args !== "undefined") {
32-
let values: string[] = [];
33-
if (typeof args === "string") {
34-
values = args.split(/[,;\|]/);
35-
} else if (Array.isArray(args)) {
36-
values = args;
27+
if (value.length > 0) {
28+
let isArgsValid: boolean = true;
29+
const protocols: Set<string> = new Set(["http", "https"]);
30+
if (typeof args !== "undefined") {
31+
let values: string[] = [];
32+
if (typeof args === "string") {
33+
values = args.split(/[,;\|]/);
34+
} else if (Array.isArray(args)) {
35+
values = args;
36+
}
37+
if (values.length === 0) {
38+
isArgsValid = false;
39+
} else {
40+
values.forEach((value) => protocols.add(format(value)));
41+
}
3742
}
38-
if (values.length === 0) {
39-
isArgsValid = false;
40-
} else {
41-
values.forEach((value) => protocols.add(format(value)));
42-
}
43-
}
4443

45-
let url: URL;
46-
try {
47-
url = new URL(value.trim());
48-
} catch (_) {
49-
return { severity: "error", message: "{{name}} must be a valid URL." };
50-
}
44+
let url: URL;
45+
try {
46+
url = new URL(value.trim());
47+
} catch (_) {
48+
return { severity: "error", message: "{{name}} must be a valid URL." };
49+
}
5150

52-
if (!protocols.has(format(url.protocol))) {
53-
return { severity: "error", message: `{{name}} must be an URL with one of the following protocols: ${[...protocols].join(", ")}.` };
54-
}
51+
if (!protocols.has(format(url.protocol))) {
52+
return { severity: "error", message: `{{name}} must be an URL with one of the following protocols: ${[...protocols].join(", ")}.` };
53+
}
5554

56-
if (!isArgsValid) {
57-
return {
58-
severity: "warning",
59-
message:
60-
"The arguments must be undefined, a string containing the allowed protocols separated by commas, semicolons or pipes, or an array of allowed protocols.",
61-
};
55+
if (!isArgsValid) {
56+
return {
57+
severity: "warning",
58+
message:
59+
"The arguments must be undefined, a string containing the allowed protocols separated by commas, semicolons or pipes, or an array of allowed protocols.",
60+
};
61+
}
6262
}
6363

6464
return { severity: "information" };

0 commit comments

Comments
 (0)