@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.
Files changed (41) hide show
  1. package/dist/{compare-BIodyGn7.d.cts → compare-CZadJMGl.d.cts} +1 -1
  2. package/dist/{compare-BIodyGn7.d.ts → compare-CZadJMGl.d.ts} +1 -1
  3. package/dist/email-validator/index.cjs +83 -0
  4. package/dist/email-validator/index.cjs.map +1 -0
  5. package/dist/email-validator/index.d.cts +13 -0
  6. package/dist/email-validator/index.d.ts +13 -0
  7. package/dist/email-validator/index.js +76 -0
  8. package/dist/email-validator/index.js.map +1 -0
  9. package/dist/email-validator-R9L5unIw.d.cts +120 -0
  10. package/dist/email-validator-R9L5unIw.d.ts +120 -0
  11. package/dist/index.cjs +148 -0
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +5 -107
  14. package/dist/index.d.ts +5 -107
  15. package/dist/index.js +144 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/npwp/index.cjs +95 -0
  18. package/dist/npwp/index.cjs.map +1 -0
  19. package/dist/npwp/index.d.cts +76 -0
  20. package/dist/npwp/index.d.ts +76 -0
  21. package/dist/npwp/index.js +90 -0
  22. package/dist/npwp/index.js.map +1 -0
  23. package/dist/plate/index.cjs +99 -0
  24. package/dist/plate/index.cjs.map +1 -0
  25. package/dist/plate/index.d.cts +8 -0
  26. package/dist/plate/index.d.ts +8 -0
  27. package/dist/plate/index.js +94 -0
  28. package/dist/plate/index.js.map +1 -0
  29. package/dist/text/index.d.cts +1 -1
  30. package/dist/text/index.d.ts +1 -1
  31. package/dist/types-i5e6R0AS.d.cts +39 -0
  32. package/dist/types-i5e6R0AS.d.ts +39 -0
  33. package/dist/utils-DDVlOusI.d.cts +30 -0
  34. package/dist/utils-DDVlOusI.d.ts +30 -0
  35. package/dist/vin/index.cjs +84 -0
  36. package/dist/vin/index.cjs.map +1 -0
  37. package/dist/vin/index.d.cts +39 -0
  38. package/dist/vin/index.d.ts +39 -0
  39. package/dist/vin/index.js +74 -0
  40. package/dist/vin/index.js.map +1 -0
  41. 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, removeStopwords as f, toFormal as g, truncate as h, isAlay as i, extractWords 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 };
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, removeStopwords as f, toFormal as g, truncate as h, isAlay as i, extractWords 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 };
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