@ts-typed/validators 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +34 -11
- package/dist/br/index.d.ts +0 -1
- package/dist/br/index.d.ts.map +1 -1
- package/dist/br/index.js +1 -3
- package/dist/br/index.js.map +1 -1
- package/dist/global/credit-card.class.d.ts +20 -0
- package/dist/global/credit-card.class.d.ts.map +1 -0
- package/dist/global/credit-card.class.js +52 -0
- package/dist/global/credit-card.class.js.map +1 -0
- package/dist/global/email.class.d.ts +24 -0
- package/dist/global/email.class.d.ts.map +1 -0
- package/dist/global/email.class.js +42 -0
- package/dist/global/email.class.js.map +1 -0
- package/dist/global/full-name.class.d.ts.map +1 -0
- package/dist/global/full-name.class.js.map +1 -0
- package/dist/global/index.d.ts +4 -0
- package/dist/global/index.d.ts.map +1 -0
- package/dist/global/index.js +10 -0
- package/dist/global/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +8 -3
- package/dist/br/full-name.class.d.ts.map +0 -1
- package/dist/br/full-name.class.js.map +0 -1
- /package/dist/{br → global}/full-name.class.d.ts +0 -0
- /package/dist/{br → global}/full-name.class.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ All notable changes to `@ts-typed/validators` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.1.3] - 2026-10-19
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Bumped the `@ts-typed/compiler` dependency to `0.1.23` (generic call/construct validation now also covers inferred type arguments, not just explicit ones). No changes to this package's own code.
|
|
12
|
+
|
|
13
|
+
## [0.1.2] - 2026-10-18
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **`FullName` is no longer Brazil-specific.** Moved from `@ts-typed/validators/br` to a new `@ts-typed/validators/global` entry point (also re-exported from the package root). It no longer validates against `./br`'s exports — `require('@ts-typed/validators/br').FullName` is now `undefined`.
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- A new `@ts-typed/validators/global` entry point for validators meant for universal/international use, exporting `FullName`, `Email`, and `CreditCard`.
|
|
22
|
+
- `Email`: validates `local-part@domain.tld` pragmatically (not full RFC 5322) — local part allows letters/digits/`._%+-`, domain allows letters/digits/hyphens/dots, must end in a 2+ letter TLD. Adds `.localPart()`, `.domain()`, and `.redact()` (keeps the local part's first character, masks the rest, shows the domain in full: `"ana@example.com"` -> `"a**@example.com"`).
|
|
23
|
+
- `CreditCard`: validates a payment card number with the Luhn checksum (network-agnostic, works across card networks worldwide). Accepts spaces/hyphens as separators; the cleaned value must be 12-19 digits and pass the Luhn check. Adds `.numbers()`, `.masked()` (last 4 digits shown, rest masked in groups of 4: `"4532015112830366"` -> `"**** **** **** 0366"`), and `.redact()` (same as `.masked()`).
|
|
24
|
+
|
|
7
25
|
## [0.1.1] - 2026-10-18
|
|
8
26
|
|
|
9
27
|
### Added
|
package/README.md
CHANGED
|
@@ -7,28 +7,34 @@ npm install @ts-typed/validators
|
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
```ts
|
|
10
|
-
import { CPF } from '@ts-typed/validators
|
|
10
|
+
import { CPF } from '@ts-typed/validators/br';
|
|
11
|
+
import { Email } from '@ts-typed/validators/global';
|
|
11
12
|
|
|
12
13
|
export class CreateUserDto {
|
|
13
|
-
public readonly cpf!: CPF;
|
|
14
|
+
public readonly cpf!: CPF; // Brazil-specific
|
|
15
|
+
public readonly email!: Email; // global
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
class UserService {
|
|
17
19
|
public create(dto: CreateUserDto) {
|
|
18
|
-
console.log(dto.cpf);
|
|
19
|
-
console.log(dto.cpf.masked());
|
|
20
|
-
console.log(dto.
|
|
20
|
+
console.log(dto.cpf); // "12345678909" (or however the client sent it)
|
|
21
|
+
console.log(dto.cpf.masked()); // "123.456.789-09"
|
|
22
|
+
console.log(dto.email.domain()); // "example.com"
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
25
|
```
|
|
24
26
|
|
|
25
|
-
With `@ts-typed/compiler`'s build step,
|
|
27
|
+
With `@ts-typed/compiler`'s build step, a raw string crossing a typed boundary auto-constructs into a validated instance the moment it's assigned — no manual `new` anywhere in application code, and an invalid value throws before `create()` ever runs.
|
|
26
28
|
|
|
27
29
|
Each class behaves like a string everywhere it matters (`console.log`, template literals, `JSON.stringify`, every native `String.prototype` method), while adding its own validation and formatting methods. See [`@ts-typed/compiler`'s README](https://github.com/ts-typed/compiler#readme) for the full `ValueObject`/auto-construction mechanism this package builds on.
|
|
28
30
|
|
|
29
|
-
##
|
|
31
|
+
## Entry points
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
- `@ts-typed/validators/br` — Brazil-specific document validators.
|
|
34
|
+
- `@ts-typed/validators/global` — validators meant for universal/international use.
|
|
35
|
+
- `@ts-typed/validators` (the bare package root) re-exports everything from both.
|
|
36
|
+
|
|
37
|
+
## Validators (Brazil) — `@ts-typed/validators/br`
|
|
32
38
|
|
|
33
39
|
| Class | Document | Check digit | Accepts |
|
|
34
40
|
|---|---|---|---|
|
|
@@ -38,20 +44,37 @@ Import from `@ts-typed/validators` or `@ts-typed/validators/br` (same exports, e
|
|
|
38
44
|
| `CEP` | Postal code | Format only — no check digit exists | `"01310-100"` or `"01310100"` |
|
|
39
45
|
| `Placa` | Vehicle plate | Format only — no check digit exists | Legacy (`"ABC1234"`) or Mercosul (`"ABC1D23"`) |
|
|
40
46
|
| `CNH` | Driver's license number | Modulus 11 | `"03215478120"` |
|
|
41
|
-
| `FullName` | Full name (first + surname) | None — plausibility only | `"Ana Maria Silva Santos"` |
|
|
42
47
|
|
|
43
|
-
Every document class exposes `.numbers()` (the normalized, unformatted value) and, where there's a natural display format, `.masked()`. `CNH` has no standard formatted display form, so it only exposes `.numbers()`.
|
|
48
|
+
Every document class exposes `.numbers()` (the normalized, unformatted value) and, where there's a natural display format, `.masked()`. `CNH` has no standard formatted display form, so it only exposes `.numbers()`.
|
|
44
49
|
|
|
45
50
|
**`CEP` and `Placa` validate FORMAT only** — neither document type has a nationally standardized check digit, so these confirm shape (length/pattern), not that a specific number was actually issued.
|
|
46
51
|
|
|
52
|
+
## Validators (global) — `@ts-typed/validators/global`
|
|
53
|
+
|
|
54
|
+
| Class | What it validates | Notes |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `FullName` | A plausible full name (first + surname, any locale/script) | No check digit — plausibility only. `.firstName()`, `.lastName()`. |
|
|
57
|
+
| `Email` | `local-part@domain.tld` | Pragmatic format check, not full RFC 5322. `.localPart()`, `.domain()`. |
|
|
58
|
+
| `CreditCard` | A payment card number | Luhn checksum (network-agnostic). Accepts space/hyphen separators; 12-19 digits. `.numbers()`, `.masked()`. |
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { Email, CreditCard, FullName } from '@ts-typed/validators/global';
|
|
62
|
+
|
|
63
|
+
new Email('ana@example.com').domain(); // "example.com"
|
|
64
|
+
new CreditCard('4532 0151 1283 0366').masked(); // "**** **** **** 0366"
|
|
65
|
+
new FullName('Ana Maria Silva Santos').firstName(); // "Ana"
|
|
66
|
+
```
|
|
67
|
+
|
|
47
68
|
## Privacy masking (`.redact()`)
|
|
48
69
|
|
|
49
|
-
Every class —
|
|
70
|
+
Every class — in both `/br` and `/global` — exposes `.redact()`, for displaying a value in a context where the full value shouldn't be shown (logs, public listings, support tooling):
|
|
50
71
|
|
|
51
72
|
```ts
|
|
52
73
|
new CPF('123.456.789-09').redact(); // "***.456.789-**"
|
|
53
74
|
new CEP('12345-678').redact(); // "*****-678"
|
|
54
75
|
new FullName('Ana Maria Silva Santos').redact(); // "A** M**** S**** S*****"
|
|
76
|
+
new Email('ana@example.com').redact(); // "a**@example.com"
|
|
77
|
+
new CreditCard('4532015112830366').redact(); // "**** **** **** 0366"
|
|
55
78
|
```
|
|
56
79
|
|
|
57
80
|
Brazil has no single federal standard for this (there's an open legislative proposal asking for one, precisely because different institutions using different masks makes a number easier to reconstruct by cross-referencing). `CPF`'s format matches a real, documented state transparency-portal convention; the rest follow the same principle for consistency, not independent sourcing per document type. `CNPJ` identifies a legal entity, not a natural person, so LGPD's personal-data rules don't apply to it the way they do the others — its `.redact()` exists for API consistency, not because redacting a CNPJ is commonly required.
|
package/dist/br/index.d.ts
CHANGED
package/dist/br/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/br/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/br/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/br/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.CNH = exports.Placa = exports.CEP = exports.Nit = exports.Nis = exports.Pasep = exports.PIS = exports.CNPJ = exports.CPF = void 0;
|
|
4
4
|
var cpf_class_1 = require("./cpf.class");
|
|
5
5
|
Object.defineProperty(exports, "CPF", { enumerable: true, get: function () { return cpf_class_1.CPF; } });
|
|
6
6
|
var cnpj_class_1 = require("./cnpj.class");
|
|
@@ -16,6 +16,4 @@ var placa_class_1 = require("./placa.class");
|
|
|
16
16
|
Object.defineProperty(exports, "Placa", { enumerable: true, get: function () { return placa_class_1.Placa; } });
|
|
17
17
|
var cnh_class_1 = require("./cnh.class");
|
|
18
18
|
Object.defineProperty(exports, "CNH", { enumerable: true, get: function () { return cnh_class_1.CNH; } });
|
|
19
|
-
var full_name_class_1 = require("./full-name.class");
|
|
20
|
-
Object.defineProperty(exports, "FullName", { enumerable: true, get: function () { return full_name_class_1.FullName; } });
|
|
21
19
|
//# sourceMappingURL=index.js.map
|
package/dist/br/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/br/index.ts"],"names":[],"mappings":";;;AAAA,yCAAkC;AAAzB,gGAAA,GAAG,OAAA;AACZ,2CAAoC;AAA3B,kGAAA,IAAI,OAAA;AACb,yCAAmD;AAA1C,gGAAA,GAAG,OAAA;AAAE,kGAAA,KAAK,OAAA;AAAE,gGAAA,GAAG,OAAA;AAAE,gGAAA,GAAG,OAAA;AAC7B,yCAAkC;AAAzB,gGAAA,GAAG,OAAA;AACZ,6CAAsC;AAA7B,oGAAA,KAAK,OAAA;AACd,yCAAkC;AAAzB,gGAAA,GAAG,OAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/br/index.ts"],"names":[],"mappings":";;;AAAA,yCAAkC;AAAzB,gGAAA,GAAG,OAAA;AACZ,2CAAoC;AAA3B,kGAAA,IAAI,OAAA;AACb,yCAAmD;AAA1C,gGAAA,GAAG,OAAA;AAAE,kGAAA,KAAK,OAAA;AAAE,gGAAA,GAAG,OAAA;AAAE,gGAAA,GAAG,OAAA;AAC7B,yCAAkC;AAAzB,gGAAA,GAAG,OAAA;AACZ,6CAAsC;AAA7B,oGAAA,KAAK,OAAA;AACd,yCAAkC;AAAzB,gGAAA,GAAG,OAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ValueObject } from '@ts-typed/compiler';
|
|
2
|
+
/**
|
|
3
|
+
* A payment card number, validated with the Luhn checksum: a network-agnostic
|
|
4
|
+
* check used by card numbers worldwide. Separators (spaces or hyphens) are
|
|
5
|
+
* accepted; the cleaned value must be 12 to 19 digits and pass the Luhn check.
|
|
6
|
+
*/
|
|
7
|
+
export declare class CreditCard extends ValueObject {
|
|
8
|
+
constructor(raw: string);
|
|
9
|
+
protected isValid(raw: string): boolean;
|
|
10
|
+
/** Digits only, separators removed: `"4532 0151 1283 0366"` -> `"4532015112830366"`. */
|
|
11
|
+
numbers(): string;
|
|
12
|
+
/**
|
|
13
|
+
* Card display form: only the last 4 digits are shown, the rest masked, in
|
|
14
|
+
* groups of 4: `"4532015112830366"` -> `"**** **** **** 0366"`.
|
|
15
|
+
*/
|
|
16
|
+
masked(): string;
|
|
17
|
+
/** Card display is already a redaction by convention, so this is the same as `masked()`. */
|
|
18
|
+
redact(): string;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=credit-card.class.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credit-card.class.d.ts","sourceRoot":"","sources":["../../src/global/credit-card.class.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,WAAW;gBACtB,GAAG,EAAE,MAAM;IAI9B,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAKvC,wFAAwF;IACjF,OAAO,IAAI,MAAM;IAIxB;;;OAGG;IACI,MAAM,IAAI,MAAM;IAMvB,4FAA4F;IACrF,MAAM,IAAI,MAAM;CAGxB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CreditCard = void 0;
|
|
4
|
+
const compiler_1 = require("@ts-typed/compiler");
|
|
5
|
+
/**
|
|
6
|
+
* A payment card number, validated with the Luhn checksum: a network-agnostic
|
|
7
|
+
* check used by card numbers worldwide. Separators (spaces or hyphens) are
|
|
8
|
+
* accepted; the cleaned value must be 12 to 19 digits and pass the Luhn check.
|
|
9
|
+
*/
|
|
10
|
+
class CreditCard extends compiler_1.ValueObject {
|
|
11
|
+
constructor(raw) {
|
|
12
|
+
super(raw);
|
|
13
|
+
}
|
|
14
|
+
isValid(raw) {
|
|
15
|
+
const cleaned = raw.replace(/[\s-]/g, '');
|
|
16
|
+
return /^\d{12,19}$/.test(cleaned) && isValidLuhn(cleaned);
|
|
17
|
+
}
|
|
18
|
+
/** Digits only, separators removed: `"4532 0151 1283 0366"` -> `"4532015112830366"`. */
|
|
19
|
+
numbers() {
|
|
20
|
+
return this.toString().replace(/[\s-]/g, '');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Card display form: only the last 4 digits are shown, the rest masked, in
|
|
24
|
+
* groups of 4: `"4532015112830366"` -> `"**** **** **** 0366"`.
|
|
25
|
+
*/
|
|
26
|
+
masked() {
|
|
27
|
+
const digits = this.numbers();
|
|
28
|
+
const hidden = '*'.repeat(digits.length - 4).match(/.{1,4}/g) ?? [];
|
|
29
|
+
return [...hidden, digits.slice(-4)].join(' ');
|
|
30
|
+
}
|
|
31
|
+
/** Card display is already a redaction by convention, so this is the same as `masked()`. */
|
|
32
|
+
redact() {
|
|
33
|
+
return this.masked();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.CreditCard = CreditCard;
|
|
37
|
+
function isValidLuhn(digits) {
|
|
38
|
+
let sum = 0;
|
|
39
|
+
let shouldDouble = false;
|
|
40
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
41
|
+
let d = Number(digits[i]);
|
|
42
|
+
if (shouldDouble) {
|
|
43
|
+
d *= 2;
|
|
44
|
+
if (d > 9)
|
|
45
|
+
d -= 9;
|
|
46
|
+
}
|
|
47
|
+
sum += d;
|
|
48
|
+
shouldDouble = !shouldDouble;
|
|
49
|
+
}
|
|
50
|
+
return sum % 10 === 0;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=credit-card.class.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credit-card.class.js","sourceRoot":"","sources":["../../src/global/credit-card.class.ts"],"names":[],"mappings":";;;AAAA,iDAAiD;AAEjD;;;;GAIG;AACH,MAAa,UAAW,SAAQ,sBAAW;IACzC,YAAmB,GAAW;QAC5B,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IAES,OAAO,CAAC,GAAW;QAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC1C,OAAO,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED,wFAAwF;IACjF,OAAO;QACZ,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACI,MAAM;QACX,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACpE,OAAO,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,4FAA4F;IACrF,MAAM;QACX,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;CACF;AA7BD,gCA6BC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,YAAY,EAAE,CAAC;YACjB,CAAC,IAAI,CAAC,CAAC;YACP,IAAI,CAAC,GAAG,CAAC;gBAAE,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,GAAG,IAAI,CAAC,CAAC;QACT,YAAY,GAAG,CAAC,YAAY,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ValueObject } from '@ts-typed/compiler';
|
|
2
|
+
/**
|
|
3
|
+
* An email address, validated pragmatically rather than against the full
|
|
4
|
+
* RFC 5322 grammar: `local-part@domain.tld`. The local part allows letters,
|
|
5
|
+
* digits and `. _ % + -`; the domain allows letters, digits, hyphens and dots,
|
|
6
|
+
* and must end in a TLD of at least two letters. This matches the format
|
|
7
|
+
* checks most real-world systems apply.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Email extends ValueObject {
|
|
10
|
+
constructor(raw: string);
|
|
11
|
+
protected isValid(raw: string): boolean;
|
|
12
|
+
/** Everything before the `@`: `"ana@example.com"` -> `"ana"`. */
|
|
13
|
+
localPart(): string;
|
|
14
|
+
/** Everything after the `@`: `"ana@example.com"` -> `"example.com"`. */
|
|
15
|
+
domain(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Privacy-masked display form: the first character of the local part is
|
|
18
|
+
* kept, the rest of it is masked, and the domain is shown in full:
|
|
19
|
+
* `"ana@example.com"` -> `"a**@example.com"`. A one-character local part
|
|
20
|
+
* has nothing to mask, so it is shown as-is: `"j@example.com"`.
|
|
21
|
+
*/
|
|
22
|
+
redact(): string;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=email.class.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.class.d.ts","sourceRoot":"","sources":["../../src/global/email.class.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;;GAMG;AACH,qBAAa,KAAM,SAAQ,WAAW;gBACjB,GAAG,EAAE,MAAM;IAI9B,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIvC,iEAAiE;IAC1D,SAAS,IAAI,MAAM;IAK1B,wEAAwE;IACjE,MAAM,IAAI,MAAM;IAKvB;;;;;OAKG;IACI,MAAM,IAAI,MAAM;CAKxB"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Email = void 0;
|
|
4
|
+
const compiler_1 = require("@ts-typed/compiler");
|
|
5
|
+
/**
|
|
6
|
+
* An email address, validated pragmatically rather than against the full
|
|
7
|
+
* RFC 5322 grammar: `local-part@domain.tld`. The local part allows letters,
|
|
8
|
+
* digits and `. _ % + -`; the domain allows letters, digits, hyphens and dots,
|
|
9
|
+
* and must end in a TLD of at least two letters. This matches the format
|
|
10
|
+
* checks most real-world systems apply.
|
|
11
|
+
*/
|
|
12
|
+
class Email extends compiler_1.ValueObject {
|
|
13
|
+
constructor(raw) {
|
|
14
|
+
super(raw);
|
|
15
|
+
}
|
|
16
|
+
isValid(raw) {
|
|
17
|
+
return /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/.test(raw);
|
|
18
|
+
}
|
|
19
|
+
/** Everything before the `@`: `"ana@example.com"` -> `"ana"`. */
|
|
20
|
+
localPart() {
|
|
21
|
+
const value = this.toString();
|
|
22
|
+
return value.slice(0, value.indexOf('@'));
|
|
23
|
+
}
|
|
24
|
+
/** Everything after the `@`: `"ana@example.com"` -> `"example.com"`. */
|
|
25
|
+
domain() {
|
|
26
|
+
const value = this.toString();
|
|
27
|
+
return value.slice(value.indexOf('@') + 1);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Privacy-masked display form: the first character of the local part is
|
|
31
|
+
* kept, the rest of it is masked, and the domain is shown in full:
|
|
32
|
+
* `"ana@example.com"` -> `"a**@example.com"`. A one-character local part
|
|
33
|
+
* has nothing to mask, so it is shown as-is: `"j@example.com"`.
|
|
34
|
+
*/
|
|
35
|
+
redact() {
|
|
36
|
+
const local = this.localPart();
|
|
37
|
+
const masked = local.charAt(0) + '*'.repeat(Math.max(local.length - 1, 0));
|
|
38
|
+
return `${masked}@${this.domain()}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.Email = Email;
|
|
42
|
+
//# sourceMappingURL=email.class.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.class.js","sourceRoot":"","sources":["../../src/global/email.class.ts"],"names":[],"mappings":";;;AAAA,iDAAiD;AAEjD;;;;;;GAMG;AACH,MAAa,KAAM,SAAQ,sBAAW;IACpC,YAAmB,GAAW;QAC5B,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IAES,OAAO,CAAC,GAAW;QAC3B,OAAO,kDAAkD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtE,CAAC;IAED,iEAAiE;IAC1D,SAAS;QACd,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,wEAAwE;IACjE,MAAM;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED;;;;;OAKG;IACI,MAAM;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;IACtC,CAAC;CACF;AAhCD,sBAgCC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-name.class.d.ts","sourceRoot":"","sources":["../../src/global/full-name.class.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;GAKG;AACH,qBAAa,QAAS,SAAQ,WAAW;gBACpB,GAAG,EAAE,MAAM;IAI9B,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAKvC,6DAA6D;IACtD,SAAS,IAAI,MAAM;IAI1B,6FAA6F;IACtF,QAAQ,IAAI,MAAM;IAIzB;;;;;OAKG;IACI,MAAM,IAAI,MAAM;CAMxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"full-name.class.js","sourceRoot":"","sources":["../../src/global/full-name.class.ts"],"names":[],"mappings":";;;AAAA,iDAAiD;AAEjD;;;;;GAKG;AACH,MAAa,QAAS,SAAQ,sBAAW;IACvC,YAAmB,GAAW;QAC5B,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IAES,OAAO,CAAC,GAAW;QAC3B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,6DAA6D;IACtD,SAAS;QACd,OAAO,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,6FAA6F;IACtF,QAAQ;QACb,OAAO,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClE,CAAC;IAED;;;;;OAKG;IACI,MAAM;QACX,OAAO,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;aAC9B,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;aAC3D,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;CACF;AAhCD,4BAgCC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/global/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CreditCard = exports.Email = exports.FullName = void 0;
|
|
4
|
+
var full_name_class_1 = require("./full-name.class");
|
|
5
|
+
Object.defineProperty(exports, "FullName", { enumerable: true, get: function () { return full_name_class_1.FullName; } });
|
|
6
|
+
var email_class_1 = require("./email.class");
|
|
7
|
+
Object.defineProperty(exports, "Email", { enumerable: true, get: function () { return email_class_1.Email; } });
|
|
8
|
+
var credit_card_class_1 = require("./credit-card.class");
|
|
9
|
+
Object.defineProperty(exports, "CreditCard", { enumerable: true, get: function () { return credit_card_class_1.CreditCard; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/global/index.ts"],"names":[],"mappings":";;;AAAA,qDAA6C;AAApC,2GAAA,QAAQ,OAAA;AACjB,6CAAsC;AAA7B,oGAAA,KAAK,OAAA;AACd,yDAAiD;AAAxC,+GAAA,UAAU,OAAA"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./br"), exports);
|
|
18
|
+
__exportStar(require("./global"), exports);
|
|
18
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uCAAqB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uCAAqB;AACrB,2CAAyB"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ts-typed/validators",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"description": "Document/data validators built on @ts-typed/compiler's ValueObject
|
|
8
|
+
"description": "Document/data validators built on @ts-typed/compiler's ValueObject: locale-specific (Brazil) and global (Email, CreditCard, FullName) validators",
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
10
|
"engines": {
|
|
11
11
|
"node": ">=22"
|
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
"require": "./dist/br/index.js",
|
|
24
24
|
"default": "./dist/br/index.js"
|
|
25
25
|
},
|
|
26
|
+
"./global": {
|
|
27
|
+
"types": "./dist/global/index.d.ts",
|
|
28
|
+
"require": "./dist/global/index.js",
|
|
29
|
+
"default": "./dist/global/index.js"
|
|
30
|
+
},
|
|
26
31
|
"./package.json": "./package.json"
|
|
27
32
|
},
|
|
28
33
|
"files": [
|
|
@@ -38,7 +43,7 @@
|
|
|
38
43
|
"test": "npm run build && node --test --test-concurrency=1"
|
|
39
44
|
},
|
|
40
45
|
"dependencies": {
|
|
41
|
-
"@ts-typed/compiler": "0.1.
|
|
46
|
+
"@ts-typed/compiler": "0.1.23"
|
|
42
47
|
},
|
|
43
48
|
"peerDependencies": {
|
|
44
49
|
"typescript": ">=5.9 <6"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"full-name.class.d.ts","sourceRoot":"","sources":["../../src/br/full-name.class.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;GAKG;AACH,qBAAa,QAAS,SAAQ,WAAW;gBACpB,GAAG,EAAE,MAAM;IAI9B,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAKvC,6DAA6D;IACtD,SAAS,IAAI,MAAM;IAI1B,6FAA6F;IACtF,QAAQ,IAAI,MAAM;IAIzB;;;;;OAKG;IACI,MAAM,IAAI,MAAM;CAMxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"full-name.class.js","sourceRoot":"","sources":["../../src/br/full-name.class.ts"],"names":[],"mappings":";;;AAAA,iDAAiD;AAEjD;;;;;GAKG;AACH,MAAa,QAAS,SAAQ,sBAAW;IACvC,YAAmB,GAAW;QAC5B,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IAES,OAAO,CAAC,GAAW;QAC3B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,6DAA6D;IACtD,SAAS;QACd,OAAO,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,6FAA6F;IACtF,QAAQ;QACb,OAAO,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClE,CAAC;IAED;;;;;OAKG;IACI,MAAM;QACX,OAAO,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;aAC9B,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;aAC3D,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;CACF;AAhCD,4BAgCC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC"}
|
|
File without changes
|
|
File without changes
|