@indodev/toolkit 0.3.0 → 0.3.2
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/dist/{compare-BIodyGn7.d.cts → compare-CZadJMGl.d.cts} +1 -1
- package/dist/{compare-BIodyGn7.d.ts → compare-CZadJMGl.d.ts} +1 -1
- package/dist/email-validator/index.cjs +83 -0
- package/dist/email-validator/index.cjs.map +1 -0
- package/dist/email-validator/index.d.cts +13 -0
- package/dist/email-validator/index.d.ts +13 -0
- package/dist/email-validator/index.js +76 -0
- package/dist/email-validator/index.js.map +1 -0
- package/dist/email-validator-R9L5unIw.d.cts +120 -0
- package/dist/email-validator-R9L5unIw.d.ts +120 -0
- package/dist/index.cjs +148 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -107
- package/dist/index.d.ts +5 -107
- package/dist/index.js +144 -1
- package/dist/index.js.map +1 -1
- package/dist/npwp/index.cjs +95 -0
- package/dist/npwp/index.cjs.map +1 -0
- package/dist/npwp/index.d.cts +76 -0
- package/dist/npwp/index.d.ts +76 -0
- package/dist/npwp/index.js +90 -0
- package/dist/npwp/index.js.map +1 -0
- package/dist/plate/index.cjs +99 -0
- package/dist/plate/index.cjs.map +1 -0
- package/dist/plate/index.d.cts +8 -0
- package/dist/plate/index.d.ts +8 -0
- package/dist/plate/index.js +94 -0
- package/dist/plate/index.js.map +1 -0
- package/dist/text/index.d.cts +1 -1
- package/dist/text/index.d.ts +1 -1
- package/dist/types-i5e6R0AS.d.cts +39 -0
- package/dist/types-i5e6R0AS.d.ts +39 -0
- package/dist/utils-DDVlOusI.d.cts +30 -0
- package/dist/utils-DDVlOusI.d.ts +30 -0
- package/dist/vin/index.cjs +84 -0
- package/dist/vin/index.cjs.map +1 -0
- package/dist/vin/index.d.cts +39 -0
- package/dist/vin/index.d.ts +39 -0
- package/dist/vin/index.js +74 -0
- package/dist/vin/index.js.map +1 -0
- package/package.json +21 -1
|
@@ -988,4 +988,4 @@ declare function compareStrings(str1: string, str2: string, options?: CompareOpt
|
|
|
988
988
|
*/
|
|
989
989
|
declare function similarity(str1: string, str2: string): number;
|
|
990
990
|
|
|
991
|
-
export { type CompareOptions as C, type ExtractOptions as E, type SlugifyOptions as S, type TitleCaseOptions as T, toSentenceCase as a, sanitize as b, capitalize as c, contractAbbreviation as d, expandAbbreviation as e,
|
|
991
|
+
export { type CompareOptions as C, type ExtractOptions as E, type SlugifyOptions as S, type TitleCaseOptions as T, toSentenceCase as a, sanitize as b, capitalize as c, contractAbbreviation as d, expandAbbreviation as e, truncate as f, extractWords as g, removeStopwords as h, toFormal as i, isAlay as j, compareStrings as k, similarity as l, type SanitizeOptions as m, normalizeWhitespace as n, type TruncateOptions as o, profanityFilter as p, removeAccents as r, slugify as s, toTitleCase as t };
|
|
@@ -988,4 +988,4 @@ declare function compareStrings(str1: string, str2: string, options?: CompareOpt
|
|
|
988
988
|
*/
|
|
989
989
|
declare function similarity(str1: string, str2: string): number;
|
|
990
990
|
|
|
991
|
-
export { type CompareOptions as C, type ExtractOptions as E, type SlugifyOptions as S, type TitleCaseOptions as T, toSentenceCase as a, sanitize as b, capitalize as c, contractAbbreviation as d, expandAbbreviation as e,
|
|
991
|
+
export { type CompareOptions as C, type ExtractOptions as E, type SlugifyOptions as S, type TitleCaseOptions as T, toSentenceCase as a, sanitize as b, capitalize as c, contractAbbreviation as d, expandAbbreviation as e, truncate as f, extractWords as g, removeStopwords as h, toFormal as i, isAlay as j, compareStrings as k, similarity as l, type SanitizeOptions as m, normalizeWhitespace as n, type TruncateOptions as o, profanityFilter as p, removeAccents as r, slugify as s, toTitleCase as t };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/email-validator/constants.ts
|
|
4
|
+
var EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?)*$/;
|
|
5
|
+
var DISPOSABLE_DOMAINS = [
|
|
6
|
+
"mailinator.com",
|
|
7
|
+
"10minutemail.com",
|
|
8
|
+
"temp-mail.org",
|
|
9
|
+
"guerrillamail.com"
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
// src/email-validator/email-validator.ts
|
|
13
|
+
var COMMON_PROVIDERS = ["gmail.com", "yahoo.com", "outlook.com", "hotmail.com", "icloud.com"];
|
|
14
|
+
var MAX_EMAIL_LENGTH = 254;
|
|
15
|
+
function validateEmail(email, options) {
|
|
16
|
+
if (!email || typeof email !== "string") {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const trimmedEmail = email.trim().toLowerCase();
|
|
20
|
+
if (trimmedEmail.length > MAX_EMAIL_LENGTH) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const parts = trimmedEmail.split("@");
|
|
24
|
+
if (parts.length !== 2) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const [username, domain] = parts;
|
|
28
|
+
if (!username || !domain) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
if (username.length > 64) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
if (username.includes("..") || username.startsWith(".") || username.endsWith(".") || domain.startsWith(".") || domain.endsWith(".") || domain.includes("..")) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (!EMAIL_REGEX.test(trimmedEmail)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (options?.blockDisposable) {
|
|
41
|
+
if (DISPOSABLE_DOMAINS.includes(domain)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
function getEmailInfo(email) {
|
|
48
|
+
if (!validateEmail(email)) return null;
|
|
49
|
+
const [username, domain] = email.trim().toLowerCase().split("@");
|
|
50
|
+
return {
|
|
51
|
+
username,
|
|
52
|
+
domain,
|
|
53
|
+
isCommonProvider: COMMON_PROVIDERS.includes(domain),
|
|
54
|
+
isDisposable: DISPOSABLE_DOMAINS.includes(domain)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function maskEmail(email, options) {
|
|
58
|
+
if (!validateEmail(email)) return email;
|
|
59
|
+
const { visibleStart = 1, visibleEnd = 1, maskChar = "*" } = options || {};
|
|
60
|
+
const [username, domain] = email.split("@");
|
|
61
|
+
if (username.length <= 3) {
|
|
62
|
+
return `${username[0]}${maskChar.repeat(3)}@${domain}`;
|
|
63
|
+
}
|
|
64
|
+
const maskedLength = username.length - (visibleStart + visibleEnd);
|
|
65
|
+
if (maskedLength <= 0) {
|
|
66
|
+
return `${username[0]}${maskChar.repeat(3)}@${domain}`;
|
|
67
|
+
}
|
|
68
|
+
const start = username.slice(0, visibleStart);
|
|
69
|
+
const end = username.slice(username.length - visibleEnd);
|
|
70
|
+
return `${start}${maskChar.repeat(maskedLength)}${end}@${domain}`;
|
|
71
|
+
}
|
|
72
|
+
function normalizeEmail(email) {
|
|
73
|
+
return email.trim().toLowerCase();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
exports.DISPOSABLE_DOMAINS = DISPOSABLE_DOMAINS;
|
|
77
|
+
exports.EMAIL_REGEX = EMAIL_REGEX;
|
|
78
|
+
exports.getEmailInfo = getEmailInfo;
|
|
79
|
+
exports.maskEmail = maskEmail;
|
|
80
|
+
exports.normalizeEmail = normalizeEmail;
|
|
81
|
+
exports.validateEmail = validateEmail;
|
|
82
|
+
//# sourceMappingURL=index.cjs.map
|
|
83
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/email-validator/constants.ts","../../src/email-validator/email-validator.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Regular expression for standard email validation.\n * Optimized for RFC 5322 compliance.\n */\nexport const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?)*$/;\n\n/**\n * Common disposable email domains to block if needed.\n */\nexport const DISPOSABLE_DOMAINS = [\n 'mailinator.com',\n '10minutemail.com',\n 'temp-mail.org',\n 'guerrillamail.com',\n];\n","import { EMAIL_REGEX, DISPOSABLE_DOMAINS } from './constants';\nimport type { EmailValidationOptions, EmailMaskOptions, EmailInfo } from './types';\n\n/**\n * List of common global email providers.\n */\nconst COMMON_PROVIDERS = ['gmail.com', 'yahoo.com', 'outlook.com', 'hotmail.com', 'icloud.com'];\n\n/**\n * The maximum length of an email address according to RFC 5321.\n */\nconst MAX_EMAIL_LENGTH = 254;\n\n/**\n * Validates if a string is a properly formatted email address based on RFC 5322.\n * \n * Performs checks for:\n * - Proper email format (regex).\n * - RFC specific rules (no double dots, username length < 64).\n * - Maximum total length (254 characters).\n * - Optional: disposable email detection.\n * \n * @param email - The email string to validate.\n * @param options - Optional validation configuration.\n * @returns `true` if valid, `false` otherwise.\n * \n * @example\n * ```typescript\n * import { validateEmail } from '@indodev/toolkit/email-validator';\n * \n * validateEmail('user@example.com'); // true\n * validateEmail('invalid-email'); // false\n * validateEmail('spam@mailinator.com', { blockDisposable: true }); // false\n * ```\n */\nexport function validateEmail(email: string, options?: EmailValidationOptions): boolean {\n if (!email || typeof email !== 'string') {\n return false;\n }\n\n const trimmedEmail = email.trim().toLowerCase();\n\n if (trimmedEmail.length > MAX_EMAIL_LENGTH) {\n return false;\n }\n\n const parts = trimmedEmail.split('@');\n if (parts.length !== 2) {\n return false;\n }\n\n const [username, domain] = parts;\n\n if (!username || !domain) {\n return false;\n }\n\n if (username.length > 64) {\n return false;\n }\n\n if (\n username.includes('..') ||\n username.startsWith('.') ||\n username.endsWith('.') ||\n domain.startsWith('.') ||\n domain.endsWith('.') ||\n domain.includes('..')\n ) {\n return false;\n }\n\n if (!EMAIL_REGEX.test(trimmedEmail)) {\n return false;\n }\n\n if (options?.blockDisposable) {\n if (DISPOSABLE_DOMAINS.includes(domain)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Parses an email address to extract useful metadata.\n * \n * @param email - The email address to parse.\n * @returns `EmailInfo` object containing details or `null` if the email is invalid.\n * \n * @example\n * ```typescript\n * import { getEmailInfo } from '@indodev/toolkit/email-validator';\n * \n * const info = getEmailInfo('adam@gmail.com');\n * // { username: 'adam', domain: 'gmail.com', isCommonProvider: true, isDisposable: false }\n * ```\n */\nexport function getEmailInfo(email: string): EmailInfo | null {\n if (!validateEmail(email)) return null;\n\n const [username, domain] = email.trim().toLowerCase().split('@');\n\n return {\n username,\n domain,\n isCommonProvider: COMMON_PROVIDERS.includes(domain),\n isDisposable: DISPOSABLE_DOMAINS.includes(domain),\n };\n}\n\n/**\n * Masks the username portion of an email for privacy protection.\n * \n * Falls back to a standard mask if the username is too short to respect visibleStart/visibleEnd.\n * \n * @param email - The email address to mask.\n * @param options - Optional masking configuration.\n * @returns Masked email string or original if invalid.\n * \n * @example\n * ```typescript\n * import { maskEmail } from '@indodev/toolkit/email-validator';\n * \n * maskEmail('user@example.com'); // 'u**r@example.com'\n * maskEmail('user@example.com', { maskChar: '#' }); // 'u##r@example.com'\n * ```\n */\nexport function maskEmail(email: string, options?: EmailMaskOptions): string {\n if (!validateEmail(email)) return email;\n\n const { visibleStart = 1, visibleEnd = 1, maskChar = '*' } = options || {};\n const [username, domain] = email.split('@');\n\n // Fallback for very short usernames\n if (username.length <= 3) {\n return `${username[0]}${maskChar.repeat(3)}@${domain}`;\n }\n\n // Calculate masked length\n const maskedLength = username.length - (visibleStart + visibleEnd);\n\n // If the result of masking would be empty or negative, use fallback\n if (maskedLength <= 0) {\n return `${username[0]}${maskChar.repeat(3)}@${domain}`;\n }\n\n const start = username.slice(0, visibleStart);\n const end = username.slice(username.length - visibleEnd);\n\n return `${start}${maskChar.repeat(maskedLength)}${end}@${domain}`;\n}\n\n/**\n * Normalizes an email address by trimming whitespace and converting to lowercase.\n * \n * @param email - The email to normalize.\n * @returns Normalized email string.\n * \n * @example\n * ```typescript\n * import { normalizeEmail } from '@indodev/toolkit/email-validator';\n * \n * normalizeEmail(' USER@Example.COM '); // 'user@example.com'\n * ```\n */\nexport function normalizeEmail(email: string): string {\n return email.trim().toLowerCase();\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { c as EmailInfo, b as EmailMaskOptions, E as EmailValidationOptions, a as EmailValidationResult, g as getEmailInfo, m as maskEmail, n as normalizeEmail, v as validateEmail } from '../email-validator-R9L5unIw.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Regular expression for standard email validation.
|
|
5
|
+
* Optimized for RFC 5322 compliance.
|
|
6
|
+
*/
|
|
7
|
+
declare const EMAIL_REGEX: RegExp;
|
|
8
|
+
/**
|
|
9
|
+
* Common disposable email domains to block if needed.
|
|
10
|
+
*/
|
|
11
|
+
declare const DISPOSABLE_DOMAINS: string[];
|
|
12
|
+
|
|
13
|
+
export { DISPOSABLE_DOMAINS, EMAIL_REGEX };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { c as EmailInfo, b as EmailMaskOptions, E as EmailValidationOptions, a as EmailValidationResult, g as getEmailInfo, m as maskEmail, n as normalizeEmail, v as validateEmail } from '../email-validator-R9L5unIw.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Regular expression for standard email validation.
|
|
5
|
+
* Optimized for RFC 5322 compliance.
|
|
6
|
+
*/
|
|
7
|
+
declare const EMAIL_REGEX: RegExp;
|
|
8
|
+
/**
|
|
9
|
+
* Common disposable email domains to block if needed.
|
|
10
|
+
*/
|
|
11
|
+
declare const DISPOSABLE_DOMAINS: string[];
|
|
12
|
+
|
|
13
|
+
export { DISPOSABLE_DOMAINS, EMAIL_REGEX };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// src/email-validator/constants.ts
|
|
2
|
+
var EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?)*$/;
|
|
3
|
+
var DISPOSABLE_DOMAINS = [
|
|
4
|
+
"mailinator.com",
|
|
5
|
+
"10minutemail.com",
|
|
6
|
+
"temp-mail.org",
|
|
7
|
+
"guerrillamail.com"
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
// src/email-validator/email-validator.ts
|
|
11
|
+
var COMMON_PROVIDERS = ["gmail.com", "yahoo.com", "outlook.com", "hotmail.com", "icloud.com"];
|
|
12
|
+
var MAX_EMAIL_LENGTH = 254;
|
|
13
|
+
function validateEmail(email, options) {
|
|
14
|
+
if (!email || typeof email !== "string") {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const trimmedEmail = email.trim().toLowerCase();
|
|
18
|
+
if (trimmedEmail.length > MAX_EMAIL_LENGTH) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const parts = trimmedEmail.split("@");
|
|
22
|
+
if (parts.length !== 2) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const [username, domain] = parts;
|
|
26
|
+
if (!username || !domain) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
if (username.length > 64) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
if (username.includes("..") || username.startsWith(".") || username.endsWith(".") || domain.startsWith(".") || domain.endsWith(".") || domain.includes("..")) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (!EMAIL_REGEX.test(trimmedEmail)) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (options?.blockDisposable) {
|
|
39
|
+
if (DISPOSABLE_DOMAINS.includes(domain)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
function getEmailInfo(email) {
|
|
46
|
+
if (!validateEmail(email)) return null;
|
|
47
|
+
const [username, domain] = email.trim().toLowerCase().split("@");
|
|
48
|
+
return {
|
|
49
|
+
username,
|
|
50
|
+
domain,
|
|
51
|
+
isCommonProvider: COMMON_PROVIDERS.includes(domain),
|
|
52
|
+
isDisposable: DISPOSABLE_DOMAINS.includes(domain)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function maskEmail(email, options) {
|
|
56
|
+
if (!validateEmail(email)) return email;
|
|
57
|
+
const { visibleStart = 1, visibleEnd = 1, maskChar = "*" } = options || {};
|
|
58
|
+
const [username, domain] = email.split("@");
|
|
59
|
+
if (username.length <= 3) {
|
|
60
|
+
return `${username[0]}${maskChar.repeat(3)}@${domain}`;
|
|
61
|
+
}
|
|
62
|
+
const maskedLength = username.length - (visibleStart + visibleEnd);
|
|
63
|
+
if (maskedLength <= 0) {
|
|
64
|
+
return `${username[0]}${maskChar.repeat(3)}@${domain}`;
|
|
65
|
+
}
|
|
66
|
+
const start = username.slice(0, visibleStart);
|
|
67
|
+
const end = username.slice(username.length - visibleEnd);
|
|
68
|
+
return `${start}${maskChar.repeat(maskedLength)}${end}@${domain}`;
|
|
69
|
+
}
|
|
70
|
+
function normalizeEmail(email) {
|
|
71
|
+
return email.trim().toLowerCase();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { DISPOSABLE_DOMAINS, EMAIL_REGEX, getEmailInfo, maskEmail, normalizeEmail, validateEmail };
|
|
75
|
+
//# sourceMappingURL=index.js.map
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/email-validator/constants.ts","../../src/email-validator/email-validator.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Regular expression for standard email validation.\n * Optimized for RFC 5322 compliance.\n */\nexport const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?)*$/;\n\n/**\n * Common disposable email domains to block if needed.\n */\nexport const DISPOSABLE_DOMAINS = [\n 'mailinator.com',\n '10minutemail.com',\n 'temp-mail.org',\n 'guerrillamail.com',\n];\n","import { EMAIL_REGEX, DISPOSABLE_DOMAINS } from './constants';\nimport type { EmailValidationOptions, EmailMaskOptions, EmailInfo } from './types';\n\n/**\n * List of common global email providers.\n */\nconst COMMON_PROVIDERS = ['gmail.com', 'yahoo.com', 'outlook.com', 'hotmail.com', 'icloud.com'];\n\n/**\n * The maximum length of an email address according to RFC 5321.\n */\nconst MAX_EMAIL_LENGTH = 254;\n\n/**\n * Validates if a string is a properly formatted email address based on RFC 5322.\n * \n * Performs checks for:\n * - Proper email format (regex).\n * - RFC specific rules (no double dots, username length < 64).\n * - Maximum total length (254 characters).\n * - Optional: disposable email detection.\n * \n * @param email - The email string to validate.\n * @param options - Optional validation configuration.\n * @returns `true` if valid, `false` otherwise.\n * \n * @example\n * ```typescript\n * import { validateEmail } from '@indodev/toolkit/email-validator';\n * \n * validateEmail('user@example.com'); // true\n * validateEmail('invalid-email'); // false\n * validateEmail('spam@mailinator.com', { blockDisposable: true }); // false\n * ```\n */\nexport function validateEmail(email: string, options?: EmailValidationOptions): boolean {\n if (!email || typeof email !== 'string') {\n return false;\n }\n\n const trimmedEmail = email.trim().toLowerCase();\n\n if (trimmedEmail.length > MAX_EMAIL_LENGTH) {\n return false;\n }\n\n const parts = trimmedEmail.split('@');\n if (parts.length !== 2) {\n return false;\n }\n\n const [username, domain] = parts;\n\n if (!username || !domain) {\n return false;\n }\n\n if (username.length > 64) {\n return false;\n }\n\n if (\n username.includes('..') ||\n username.startsWith('.') ||\n username.endsWith('.') ||\n domain.startsWith('.') ||\n domain.endsWith('.') ||\n domain.includes('..')\n ) {\n return false;\n }\n\n if (!EMAIL_REGEX.test(trimmedEmail)) {\n return false;\n }\n\n if (options?.blockDisposable) {\n if (DISPOSABLE_DOMAINS.includes(domain)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Parses an email address to extract useful metadata.\n * \n * @param email - The email address to parse.\n * @returns `EmailInfo` object containing details or `null` if the email is invalid.\n * \n * @example\n * ```typescript\n * import { getEmailInfo } from '@indodev/toolkit/email-validator';\n * \n * const info = getEmailInfo('adam@gmail.com');\n * // { username: 'adam', domain: 'gmail.com', isCommonProvider: true, isDisposable: false }\n * ```\n */\nexport function getEmailInfo(email: string): EmailInfo | null {\n if (!validateEmail(email)) return null;\n\n const [username, domain] = email.trim().toLowerCase().split('@');\n\n return {\n username,\n domain,\n isCommonProvider: COMMON_PROVIDERS.includes(domain),\n isDisposable: DISPOSABLE_DOMAINS.includes(domain),\n };\n}\n\n/**\n * Masks the username portion of an email for privacy protection.\n * \n * Falls back to a standard mask if the username is too short to respect visibleStart/visibleEnd.\n * \n * @param email - The email address to mask.\n * @param options - Optional masking configuration.\n * @returns Masked email string or original if invalid.\n * \n * @example\n * ```typescript\n * import { maskEmail } from '@indodev/toolkit/email-validator';\n * \n * maskEmail('user@example.com'); // 'u**r@example.com'\n * maskEmail('user@example.com', { maskChar: '#' }); // 'u##r@example.com'\n * ```\n */\nexport function maskEmail(email: string, options?: EmailMaskOptions): string {\n if (!validateEmail(email)) return email;\n\n const { visibleStart = 1, visibleEnd = 1, maskChar = '*' } = options || {};\n const [username, domain] = email.split('@');\n\n // Fallback for very short usernames\n if (username.length <= 3) {\n return `${username[0]}${maskChar.repeat(3)}@${domain}`;\n }\n\n // Calculate masked length\n const maskedLength = username.length - (visibleStart + visibleEnd);\n\n // If the result of masking would be empty or negative, use fallback\n if (maskedLength <= 0) {\n return `${username[0]}${maskChar.repeat(3)}@${domain}`;\n }\n\n const start = username.slice(0, visibleStart);\n const end = username.slice(username.length - visibleEnd);\n\n return `${start}${maskChar.repeat(maskedLength)}${end}@${domain}`;\n}\n\n/**\n * Normalizes an email address by trimming whitespace and converting to lowercase.\n * \n * @param email - The email to normalize.\n * @returns Normalized email string.\n * \n * @example\n * ```typescript\n * import { normalizeEmail } from '@indodev/toolkit/email-validator';\n * \n * normalizeEmail(' USER@Example.COM '); // 'user@example.com'\n * ```\n */\nexport function normalizeEmail(email: string): string {\n return email.trim().toLowerCase();\n}\n"]}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email validation options.
|
|
3
|
+
*/
|
|
4
|
+
interface EmailValidationOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Whether to block known disposable email domains.
|
|
7
|
+
* @default false
|
|
8
|
+
*/
|
|
9
|
+
blockDisposable?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detailed email validation result.
|
|
13
|
+
*/
|
|
14
|
+
interface EmailValidationResult {
|
|
15
|
+
isValid: boolean;
|
|
16
|
+
domain?: string;
|
|
17
|
+
isDisposable?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options for email masking.
|
|
21
|
+
*/
|
|
22
|
+
interface EmailMaskOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Number of characters to keep visible at the start of the username.
|
|
25
|
+
* @default 1
|
|
26
|
+
*/
|
|
27
|
+
visibleStart?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Number of characters to keep visible at the end of the username.
|
|
30
|
+
* @default 1
|
|
31
|
+
*/
|
|
32
|
+
visibleEnd?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Character used for masking.
|
|
35
|
+
* @default '*'
|
|
36
|
+
*/
|
|
37
|
+
maskChar?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Detailed email information.
|
|
41
|
+
*/
|
|
42
|
+
interface EmailInfo {
|
|
43
|
+
username: string;
|
|
44
|
+
domain: string;
|
|
45
|
+
isCommonProvider: boolean;
|
|
46
|
+
isDisposable: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validates if a string is a properly formatted email address based on RFC 5322.
|
|
51
|
+
*
|
|
52
|
+
* Performs checks for:
|
|
53
|
+
* - Proper email format (regex).
|
|
54
|
+
* - RFC specific rules (no double dots, username length < 64).
|
|
55
|
+
* - Maximum total length (254 characters).
|
|
56
|
+
* - Optional: disposable email detection.
|
|
57
|
+
*
|
|
58
|
+
* @param email - The email string to validate.
|
|
59
|
+
* @param options - Optional validation configuration.
|
|
60
|
+
* @returns `true` if valid, `false` otherwise.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* import { validateEmail } from '@indodev/toolkit/email-validator';
|
|
65
|
+
*
|
|
66
|
+
* validateEmail('user@example.com'); // true
|
|
67
|
+
* validateEmail('invalid-email'); // false
|
|
68
|
+
* validateEmail('spam@mailinator.com', { blockDisposable: true }); // false
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
declare function validateEmail(email: string, options?: EmailValidationOptions): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Parses an email address to extract useful metadata.
|
|
74
|
+
*
|
|
75
|
+
* @param email - The email address to parse.
|
|
76
|
+
* @returns `EmailInfo` object containing details or `null` if the email is invalid.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* import { getEmailInfo } from '@indodev/toolkit/email-validator';
|
|
81
|
+
*
|
|
82
|
+
* const info = getEmailInfo('adam@gmail.com');
|
|
83
|
+
* // { username: 'adam', domain: 'gmail.com', isCommonProvider: true, isDisposable: false }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
declare function getEmailInfo(email: string): EmailInfo | null;
|
|
87
|
+
/**
|
|
88
|
+
* Masks the username portion of an email for privacy protection.
|
|
89
|
+
*
|
|
90
|
+
* Falls back to a standard mask if the username is too short to respect visibleStart/visibleEnd.
|
|
91
|
+
*
|
|
92
|
+
* @param email - The email address to mask.
|
|
93
|
+
* @param options - Optional masking configuration.
|
|
94
|
+
* @returns Masked email string or original if invalid.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* import { maskEmail } from '@indodev/toolkit/email-validator';
|
|
99
|
+
*
|
|
100
|
+
* maskEmail('user@example.com'); // 'u**r@example.com'
|
|
101
|
+
* maskEmail('user@example.com', { maskChar: '#' }); // 'u##r@example.com'
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
declare function maskEmail(email: string, options?: EmailMaskOptions): string;
|
|
105
|
+
/**
|
|
106
|
+
* Normalizes an email address by trimming whitespace and converting to lowercase.
|
|
107
|
+
*
|
|
108
|
+
* @param email - The email to normalize.
|
|
109
|
+
* @returns Normalized email string.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* import { normalizeEmail } from '@indodev/toolkit/email-validator';
|
|
114
|
+
*
|
|
115
|
+
* normalizeEmail(' USER@Example.COM '); // 'user@example.com'
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
declare function normalizeEmail(email: string): string;
|
|
119
|
+
|
|
120
|
+
export { type EmailValidationOptions as E, type EmailValidationResult as a, type EmailMaskOptions as b, type EmailInfo as c, getEmailInfo as g, maskEmail as m, normalizeEmail as n, validateEmail as v };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email validation options.
|
|
3
|
+
*/
|
|
4
|
+
interface EmailValidationOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Whether to block known disposable email domains.
|
|
7
|
+
* @default false
|
|
8
|
+
*/
|
|
9
|
+
blockDisposable?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detailed email validation result.
|
|
13
|
+
*/
|
|
14
|
+
interface EmailValidationResult {
|
|
15
|
+
isValid: boolean;
|
|
16
|
+
domain?: string;
|
|
17
|
+
isDisposable?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options for email masking.
|
|
21
|
+
*/
|
|
22
|
+
interface EmailMaskOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Number of characters to keep visible at the start of the username.
|
|
25
|
+
* @default 1
|
|
26
|
+
*/
|
|
27
|
+
visibleStart?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Number of characters to keep visible at the end of the username.
|
|
30
|
+
* @default 1
|
|
31
|
+
*/
|
|
32
|
+
visibleEnd?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Character used for masking.
|
|
35
|
+
* @default '*'
|
|
36
|
+
*/
|
|
37
|
+
maskChar?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Detailed email information.
|
|
41
|
+
*/
|
|
42
|
+
interface EmailInfo {
|
|
43
|
+
username: string;
|
|
44
|
+
domain: string;
|
|
45
|
+
isCommonProvider: boolean;
|
|
46
|
+
isDisposable: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validates if a string is a properly formatted email address based on RFC 5322.
|
|
51
|
+
*
|
|
52
|
+
* Performs checks for:
|
|
53
|
+
* - Proper email format (regex).
|
|
54
|
+
* - RFC specific rules (no double dots, username length < 64).
|
|
55
|
+
* - Maximum total length (254 characters).
|
|
56
|
+
* - Optional: disposable email detection.
|
|
57
|
+
*
|
|
58
|
+
* @param email - The email string to validate.
|
|
59
|
+
* @param options - Optional validation configuration.
|
|
60
|
+
* @returns `true` if valid, `false` otherwise.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* import { validateEmail } from '@indodev/toolkit/email-validator';
|
|
65
|
+
*
|
|
66
|
+
* validateEmail('user@example.com'); // true
|
|
67
|
+
* validateEmail('invalid-email'); // false
|
|
68
|
+
* validateEmail('spam@mailinator.com', { blockDisposable: true }); // false
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
declare function validateEmail(email: string, options?: EmailValidationOptions): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Parses an email address to extract useful metadata.
|
|
74
|
+
*
|
|
75
|
+
* @param email - The email address to parse.
|
|
76
|
+
* @returns `EmailInfo` object containing details or `null` if the email is invalid.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* import { getEmailInfo } from '@indodev/toolkit/email-validator';
|
|
81
|
+
*
|
|
82
|
+
* const info = getEmailInfo('adam@gmail.com');
|
|
83
|
+
* // { username: 'adam', domain: 'gmail.com', isCommonProvider: true, isDisposable: false }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
declare function getEmailInfo(email: string): EmailInfo | null;
|
|
87
|
+
/**
|
|
88
|
+
* Masks the username portion of an email for privacy protection.
|
|
89
|
+
*
|
|
90
|
+
* Falls back to a standard mask if the username is too short to respect visibleStart/visibleEnd.
|
|
91
|
+
*
|
|
92
|
+
* @param email - The email address to mask.
|
|
93
|
+
* @param options - Optional masking configuration.
|
|
94
|
+
* @returns Masked email string or original if invalid.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* import { maskEmail } from '@indodev/toolkit/email-validator';
|
|
99
|
+
*
|
|
100
|
+
* maskEmail('user@example.com'); // 'u**r@example.com'
|
|
101
|
+
* maskEmail('user@example.com', { maskChar: '#' }); // 'u##r@example.com'
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
declare function maskEmail(email: string, options?: EmailMaskOptions): string;
|
|
105
|
+
/**
|
|
106
|
+
* Normalizes an email address by trimming whitespace and converting to lowercase.
|
|
107
|
+
*
|
|
108
|
+
* @param email - The email to normalize.
|
|
109
|
+
* @returns Normalized email string.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* import { normalizeEmail } from '@indodev/toolkit/email-validator';
|
|
114
|
+
*
|
|
115
|
+
* normalizeEmail(' USER@Example.COM '); // 'user@example.com'
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
declare function normalizeEmail(email: string): string;
|
|
119
|
+
|
|
120
|
+
export { type EmailValidationOptions as E, type EmailValidationResult as a, type EmailMaskOptions as b, type EmailInfo as c, getEmailInfo as g, maskEmail as m, normalizeEmail as n, validateEmail as v };
|
package/dist/index.cjs
CHANGED
|
@@ -1181,6 +1181,149 @@ function formatPlate(plate) {
|
|
|
1181
1181
|
return `${match[1]} ${match[2]} ${match[3]}`;
|
|
1182
1182
|
}
|
|
1183
1183
|
|
|
1184
|
+
// src/vin/constants.ts
|
|
1185
|
+
var VIN_LENGTH = 17;
|
|
1186
|
+
var VIN_CHECK_DIGIT_INDEX = 8;
|
|
1187
|
+
var VIN_MODULUS = 11;
|
|
1188
|
+
var VIN_CHECK_DIGIT_X = "X";
|
|
1189
|
+
var VIN_WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2];
|
|
1190
|
+
var VIN_CHAR_VALUES = {
|
|
1191
|
+
"0": 0,
|
|
1192
|
+
"1": 1,
|
|
1193
|
+
"2": 2,
|
|
1194
|
+
"3": 3,
|
|
1195
|
+
"4": 4,
|
|
1196
|
+
"5": 5,
|
|
1197
|
+
"6": 6,
|
|
1198
|
+
"7": 7,
|
|
1199
|
+
"8": 8,
|
|
1200
|
+
"9": 9,
|
|
1201
|
+
"A": 1,
|
|
1202
|
+
"B": 2,
|
|
1203
|
+
"C": 3,
|
|
1204
|
+
"D": 4,
|
|
1205
|
+
"E": 5,
|
|
1206
|
+
"F": 6,
|
|
1207
|
+
"G": 7,
|
|
1208
|
+
"H": 8,
|
|
1209
|
+
"J": 1,
|
|
1210
|
+
"K": 2,
|
|
1211
|
+
"L": 3,
|
|
1212
|
+
"M": 4,
|
|
1213
|
+
"N": 5,
|
|
1214
|
+
"P": 7,
|
|
1215
|
+
"R": 9,
|
|
1216
|
+
"S": 2,
|
|
1217
|
+
"T": 3,
|
|
1218
|
+
"U": 4,
|
|
1219
|
+
"V": 5,
|
|
1220
|
+
"W": 6,
|
|
1221
|
+
"X": 7,
|
|
1222
|
+
"Y": 8,
|
|
1223
|
+
"Z": 9
|
|
1224
|
+
};
|
|
1225
|
+
var EXCLUDED_VIN_CHARS = ["I", "O", "Q"];
|
|
1226
|
+
|
|
1227
|
+
// src/vin/validate.ts
|
|
1228
|
+
function validateVIN(vin) {
|
|
1229
|
+
if (!vin || vin.length !== VIN_LENGTH) {
|
|
1230
|
+
return false;
|
|
1231
|
+
}
|
|
1232
|
+
const normalizedVIN = vin.toUpperCase();
|
|
1233
|
+
for (const char of EXCLUDED_VIN_CHARS) {
|
|
1234
|
+
if (normalizedVIN.includes(char)) {
|
|
1235
|
+
return false;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
let sum = 0;
|
|
1239
|
+
for (let i = 0; i < VIN_LENGTH; i++) {
|
|
1240
|
+
const char = normalizedVIN[i];
|
|
1241
|
+
const weight = VIN_WEIGHTS[i];
|
|
1242
|
+
const val = VIN_CHAR_VALUES[char];
|
|
1243
|
+
if (val === void 0) {
|
|
1244
|
+
return false;
|
|
1245
|
+
}
|
|
1246
|
+
sum += val * weight;
|
|
1247
|
+
}
|
|
1248
|
+
const checkDigitValue = sum % VIN_MODULUS;
|
|
1249
|
+
const expectedCheckDigit = checkDigitValue === 10 ? VIN_CHECK_DIGIT_X : checkDigitValue.toString();
|
|
1250
|
+
const actualCheckDigit = normalizedVIN[VIN_CHECK_DIGIT_INDEX];
|
|
1251
|
+
return actualCheckDigit === expectedCheckDigit;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
// src/email-validator/constants.ts
|
|
1255
|
+
var EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,253}[a-zA-Z0-9])?)*$/;
|
|
1256
|
+
var DISPOSABLE_DOMAINS = [
|
|
1257
|
+
"mailinator.com",
|
|
1258
|
+
"10minutemail.com",
|
|
1259
|
+
"temp-mail.org",
|
|
1260
|
+
"guerrillamail.com"
|
|
1261
|
+
];
|
|
1262
|
+
|
|
1263
|
+
// src/email-validator/email-validator.ts
|
|
1264
|
+
var COMMON_PROVIDERS = ["gmail.com", "yahoo.com", "outlook.com", "hotmail.com", "icloud.com"];
|
|
1265
|
+
var MAX_EMAIL_LENGTH = 254;
|
|
1266
|
+
function validateEmail(email, options) {
|
|
1267
|
+
if (!email || typeof email !== "string") {
|
|
1268
|
+
return false;
|
|
1269
|
+
}
|
|
1270
|
+
const trimmedEmail = email.trim().toLowerCase();
|
|
1271
|
+
if (trimmedEmail.length > MAX_EMAIL_LENGTH) {
|
|
1272
|
+
return false;
|
|
1273
|
+
}
|
|
1274
|
+
const parts = trimmedEmail.split("@");
|
|
1275
|
+
if (parts.length !== 2) {
|
|
1276
|
+
return false;
|
|
1277
|
+
}
|
|
1278
|
+
const [username, domain] = parts;
|
|
1279
|
+
if (!username || !domain) {
|
|
1280
|
+
return false;
|
|
1281
|
+
}
|
|
1282
|
+
if (username.length > 64) {
|
|
1283
|
+
return false;
|
|
1284
|
+
}
|
|
1285
|
+
if (username.includes("..") || username.startsWith(".") || username.endsWith(".") || domain.startsWith(".") || domain.endsWith(".") || domain.includes("..")) {
|
|
1286
|
+
return false;
|
|
1287
|
+
}
|
|
1288
|
+
if (!EMAIL_REGEX.test(trimmedEmail)) {
|
|
1289
|
+
return false;
|
|
1290
|
+
}
|
|
1291
|
+
if (options?.blockDisposable) {
|
|
1292
|
+
if (DISPOSABLE_DOMAINS.includes(domain)) {
|
|
1293
|
+
return false;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
return true;
|
|
1297
|
+
}
|
|
1298
|
+
function getEmailInfo(email) {
|
|
1299
|
+
if (!validateEmail(email)) return null;
|
|
1300
|
+
const [username, domain] = email.trim().toLowerCase().split("@");
|
|
1301
|
+
return {
|
|
1302
|
+
username,
|
|
1303
|
+
domain,
|
|
1304
|
+
isCommonProvider: COMMON_PROVIDERS.includes(domain),
|
|
1305
|
+
isDisposable: DISPOSABLE_DOMAINS.includes(domain)
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
function maskEmail(email, options) {
|
|
1309
|
+
if (!validateEmail(email)) return email;
|
|
1310
|
+
const { visibleStart = 1, visibleEnd = 1, maskChar = "*" } = options || {};
|
|
1311
|
+
const [username, domain] = email.split("@");
|
|
1312
|
+
if (username.length <= 3) {
|
|
1313
|
+
return `${username[0]}${maskChar.repeat(3)}@${domain}`;
|
|
1314
|
+
}
|
|
1315
|
+
const maskedLength = username.length - (visibleStart + visibleEnd);
|
|
1316
|
+
if (maskedLength <= 0) {
|
|
1317
|
+
return `${username[0]}${maskChar.repeat(3)}@${domain}`;
|
|
1318
|
+
}
|
|
1319
|
+
const start = username.slice(0, visibleStart);
|
|
1320
|
+
const end = username.slice(username.length - visibleEnd);
|
|
1321
|
+
return `${start}${maskChar.repeat(maskedLength)}${end}@${domain}`;
|
|
1322
|
+
}
|
|
1323
|
+
function normalizeEmail(email) {
|
|
1324
|
+
return email.trim().toLowerCase();
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1184
1327
|
// src/currency/format.ts
|
|
1185
1328
|
function formatRupiah(amount, options) {
|
|
1186
1329
|
const {
|
|
@@ -3159,6 +3302,7 @@ exports.generateSmsLink = generateSmsLink;
|
|
|
3159
3302
|
exports.generateTelLink = generateTelLink;
|
|
3160
3303
|
exports.generateWALink = generateWALink;
|
|
3161
3304
|
exports.getAge = getAge;
|
|
3305
|
+
exports.getEmailInfo = getEmailInfo;
|
|
3162
3306
|
exports.getOperator = getOperator;
|
|
3163
3307
|
exports.getRegionFromPlate = getRegionFromPlate;
|
|
3164
3308
|
exports.isAlay = isAlay;
|
|
@@ -3167,9 +3311,11 @@ exports.isMobileNumber = isMobileNumber;
|
|
|
3167
3311
|
exports.isProvider = isProvider;
|
|
3168
3312
|
exports.isValidForBirthDate = isValidForBirthDate;
|
|
3169
3313
|
exports.isValidForGender = isValidForGender;
|
|
3314
|
+
exports.maskEmail = maskEmail;
|
|
3170
3315
|
exports.maskNIK = maskNIK;
|
|
3171
3316
|
exports.maskNPWP = maskNPWP;
|
|
3172
3317
|
exports.maskPhoneNumber = maskPhoneNumber;
|
|
3318
|
+
exports.normalizeEmail = normalizeEmail;
|
|
3173
3319
|
exports.normalizeWhitespace = normalizeWhitespace;
|
|
3174
3320
|
exports.parseNIK = parseNIK;
|
|
3175
3321
|
exports.parseNPWP = parseNPWP;
|
|
@@ -3190,9 +3336,11 @@ exports.toSentenceCase = toSentenceCase;
|
|
|
3190
3336
|
exports.toTitleCase = toTitleCase;
|
|
3191
3337
|
exports.toWords = toWords;
|
|
3192
3338
|
exports.truncate = truncate;
|
|
3339
|
+
exports.validateEmail = validateEmail;
|
|
3193
3340
|
exports.validateNIK = validateNIK;
|
|
3194
3341
|
exports.validateNPWP = validateNPWP;
|
|
3195
3342
|
exports.validatePhoneNumber = validatePhoneNumber;
|
|
3196
3343
|
exports.validatePlate = validatePlate;
|
|
3344
|
+
exports.validateVIN = validateVIN;
|
|
3197
3345
|
//# sourceMappingURL=index.cjs.map
|
|
3198
3346
|
//# sourceMappingURL=index.cjs.map
|