@mikkelscheike/email-provider-links 2.7.1 β†’ 2.8.0

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/README.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  πŸ”’ **Modern email provider detection library with enhanced TypeScript support and enterprise security**
4
4
 
5
- A robust TypeScript library providing direct links to **93 email providers** (178 domains) with **concurrent DNS resolution**, **optimized performance**, **comprehensive email validation**, and advanced security features for login and password reset flows.
5
+ A robust TypeScript library providing direct links to **93 email providers** (180 domains) with **concurrent DNS resolution**, **optimized performance**, **comprehensive email validation**, and advanced security features for login and password reset flows.
6
+
7
+ ## πŸš€ Try it out
8
+
9
+ **[Live Demo](https://demo.mikkelscheike.com)** - Test the library with any email address and see it in action!
6
10
 
7
11
  ## ✨ New in Version 2.7.0
8
12
 
@@ -13,12 +17,13 @@ A robust TypeScript library providing direct links to **93 email providers** (17
13
17
  - πŸ›‘οΈ **Improved Security**: Enhanced cryptographic integrity verification
14
18
  - ⚑ **Better Performance**: Optimized concurrent DNS with smart caching
15
19
  - 🎯 **Developer Experience**: Enhanced error messages and debugging information
20
+ - πŸ“Š **Development Mode**: Memory usage tracking when NODE_ENV=development
16
21
 
17
22
  ## ✨ Core Features
18
23
 
19
- - πŸš€ **Fast & Lightweight**: Zero dependencies, ultra-low memory (~0.39MB initial, ~0.02MB per 1000 ops)
24
+ - πŸš€ **Fast & Lightweight**: Zero dependencies, ultra-low memory (~0.08MB initial, ~0.03MB per 1000 ops)
20
25
  - πŸ“§ **93 Email Providers**: Gmail, Outlook, Yahoo, ProtonMail, iCloud, and many more
21
- - 🌐 **178 Domains Supported**: Comprehensive international coverage
26
+ - 🌐 **207 Domains Supported**: Comprehensive international coverage
22
27
  - 🌍 **Full IDN Support**: International domain names with RFC compliance and Punycode
23
28
  - βœ… **Advanced Email Validation**: International email validation with detailed error reporting
24
29
  - 🏒 **Business Domain Detection**: DNS-based detection for custom domains (Google Workspace, Microsoft 365, etc.)
@@ -31,7 +36,7 @@ A robust TypeScript library providing direct links to **93 email providers** (17
31
36
  - πŸ”„ **Email Alias Detection**: Normalize Gmail dots, plus addressing, and provider-specific aliases
32
37
  - πŸ›‘οΈ **Fraud Prevention**: Detect duplicate accounts through email alias manipulation
33
38
  - πŸ“¦ **Batch Processing**: Efficiently process multiple emails with deduplication
34
- - πŸ§ͺ **Thoroughly Tested**: 396 tests with comprehensive code coverage
39
+ - πŸ§ͺ **Thoroughly Tested**: 424 tests with 93.16% code coverage
35
40
 
36
41
  ## Installation
37
42
 
@@ -54,83 +59,9 @@ Fully compatible with the latest Node.js 24.x! The library is tested on:
54
59
  - Node.js 22.x (Current)
55
60
  - **Node.js 24.x (Latest)** - Full support with latest features
56
61
 
57
- ## Quick Start
58
-
59
- **One function handles everything** - consumer emails, business domains, and unknown providers:
60
-
61
- ```typescript
62
- import { getEmailProvider } from '@mikkelscheike/email-provider-links';
63
-
64
- // Works for ANY email address - the only function you need
65
- const result = await getEmailProvider('user@gmail.com');
66
- console.log(result.loginUrl); // "https://mail.google.com/mail/"
67
- console.log(result.provider?.companyProvider); // "Gmail"
68
-
69
- // Automatically detects business domains too
70
- const business = await getEmailProvider('user@mycompany.com');
71
- console.log(business.provider?.companyProvider); // "Google Workspace" (if detected)
72
-
73
- // Gracefully handles unknown providers
74
- const unknown = await getEmailProvider('user@unknown.com');
75
- console.log(unknown.loginUrl); // null
76
- ```
77
-
78
- ## Enhanced Email Validation
79
-
80
- **New in 2.7.0**: Comprehensive email validation with international support:
81
-
82
- ```typescript
83
- import { validateEmailAddress, validateInternationalEmail } from '@mikkelscheike/email-provider-links';
84
-
85
- // Enhanced validation with detailed error reporting
86
- const result = validateEmailAddress('user@example.com');
87
- if (result.isValid) {
88
- console.log('Valid email:', result.normalizedEmail);
89
- } else {
90
- console.log('Error:', result.error?.message);
91
- console.log('Error code:', result.error?.code);
92
- }
93
-
94
- // International domain validation
95
- const intlResult = validateInternationalEmail('user@mΓΌnchen.de');
96
- if (!intlResult) {
97
- console.log('Valid international email');
98
- } else {
99
- console.log('Validation error:', intlResult.message);
100
- }
101
- ```
102
-
103
- ## Batch Processing
104
-
105
- **New in 2.7.0**: Process multiple emails efficiently with deduplication:
106
-
107
- ```typescript
108
- import { batchProcessEmails } from '@mikkelscheike/email-provider-links';
109
-
110
- const emails = [
111
- 'user@gmail.com',
112
- 'u.s.e.r+work@gmail.com', // Alias of the first email
113
- 'test@yahoo.com',
114
- 'invalid-email'
115
- ];
116
-
117
- const results = batchProcessEmails(emails, {
118
- includeProviderInfo: true,
119
- normalizeEmails: true,
120
- deduplicateAliases: true
121
- });
122
-
123
- results.forEach(result => {
124
- console.log(`${result.email}: ${result.isValid ? 'Valid' : 'Invalid'}`);
125
- if (result.isDuplicate) {
126
- console.log(' πŸ”„ Duplicate detected');
127
- }
128
- });
129
- ```
130
-
131
62
  ## Supported Providers
132
63
 
133
- **πŸ“Š Current Coverage: 93 providers supporting 178 domains**
64
+ **πŸ“Š Current Coverage: 93 providers supporting 207 domains**
134
65
 
135
66
  **Consumer Email Providers:**
136
67
  - **Gmail** (2 domains): gmail.com, googlemail.com
@@ -301,73 +232,36 @@ console.log(domain); // 'example.com'
301
232
 
302
233
  </details>
303
234
 
304
- ## TypeScript Support
305
-
306
- Full TypeScript support with comprehensive interfaces:
307
-
308
- ```typescript
309
- interface EmailProviderResult {
310
- provider: EmailProvider | null;
311
- email: string;
312
- loginUrl: string | null;
313
- detectionMethod?: 'domain_match' | 'mx_record' | 'txt_record' | 'both' | 'proxy_detected';
314
- proxyService?: string;
315
- error?: {
316
- type: 'INVALID_EMAIL' | 'DNS_TIMEOUT' | 'RATE_LIMITED' | 'UNKNOWN_DOMAIN' |
317
- 'NETWORK_ERROR' | 'IDN_VALIDATION_ERROR';
318
- message: string;
319
- retryAfter?: number; // seconds until retry allowed (for rate limiting)
320
- idnError?: string; // specific IDN validation error message
321
- };
322
- }
323
-
324
- interface ConfigConstants {
325
- DEFAULT_DNS_TIMEOUT: number; // 5000ms
326
- MAX_DNS_REQUESTS_PER_MINUTE: number; // 10 requests
327
- SUPPORTED_PROVIDERS_COUNT: number; // 93 providers
328
- SUPPORTED_DOMAINS_COUNT: number; // 178 domains
329
- }
330
- ```
331
-
332
- ## πŸ›‘οΈ Security Features
235
+ ## Performance and Detection System
333
236
 
334
- This package implements **enterprise-grade security** to protect against malicious redirects and supply chain attacks:
237
+ For detailed performance metrics and information about the detection system, refer to [Performance and Detection System](docs/PERFORMANCE.md).
335
238
 
336
- ### βœ… Multi-Layer Protection
239
+ ### Development Mode Features
337
240
 
338
- - **HTTPS-Only Enforcement**: All provider URLs must use HTTPS protocol
339
- - **Domain Allowlisting**: Only pre-approved domains are allowed (93+ verified providers)
340
- - **Malicious Pattern Detection**: Blocks IP addresses, URL shorteners, suspicious TLDs
341
- - **Path Traversal Prevention**: Detects and blocks `../` and encoded variants
342
- - **JavaScript Injection Protection**: Prevents `javascript:`, `data:`, and script injections
343
- - **File Integrity Verification**: SHA-256 hash verification for provider database
241
+ When `NODE_ENV` is set to 'development', the library provides additional insights:
344
242
 
345
- ### πŸ”’ Attack Prevention
346
-
347
- Protects against common attack vectors:
348
- - ❌ **URL Injection**: Blocked by strict allowlisting
349
- - ❌ **Typosquatting**: Blocked by domain validation
350
- - ❌ **URL Shorteners**: Blocked by pattern detection
351
- - ❌ **Protocol Downgrade**: Blocked by HTTPS enforcement
352
- - ❌ **Path Traversal**: Blocked by path validation
353
- - ❌ **Script Injection**: Blocked by content validation
354
- - ❌ **Supply Chain Attacks**: Blocked by integrity verification
243
+ ```typescript
244
+ // Memory usage is automatically logged:
245
+ // πŸš€ Current memory usage: 0.08 MB
246
+ ```
355
247
 
356
- ### πŸ§ͺ Security Testing
248
+ ### Memory Management
357
249
 
358
- - **396 comprehensive tests** covering all functionality and edge cases
359
- - **92+ dedicated security tests** covering all attack vectors
360
- - **Automated security validation** in CI/CD pipeline
361
- - **Regular security audits** of provider database
250
+ The library implements careful memory management:
251
+ - Initial load: ~0.08MB heap usage
252
+ - Batch operations: ~0.03MB per 1000 operations
253
+ - Maximum load: < 25MB even under heavy concurrent operations
254
+ - Automatic garbage collection hints
255
+ - Memory usage logging in development mode
362
256
 
363
- ## Performance Benchmarks
257
+ ### Performance Benchmarks
364
258
 
365
259
  This package is designed to be extremely memory efficient and fast:
366
260
 
367
- - **Provider loading**: ~0.39MB heap usage, <0.5ms
368
- - **Email lookups**: ~0.02MB heap usage per 100 operations
369
- - **Concurrent DNS**: ~0.03MB heap usage, ~110ms for 10 lookups
370
- - **Large scale (1000 ops)**: ~0.02MB heap usage, <3ms total
261
+ - **Provider loading**: ~0.08MB heap usage, ~0.5ms
262
+ - **Email lookups**: ~0.03MB heap usage per 100 operations
263
+ - **Concurrent DNS**: ~0.03MB heap usage, ~27ms for 10 lookups
264
+ - **Large scale (1000 ops)**: ~0.03MB heap usage, ~1.1ms total
371
265
  - **International validation**: <1ms for complex IDN domains
372
266
 
373
267
  To run benchmarks locally:
@@ -375,19 +269,11 @@ To run benchmarks locally:
375
269
  npm run benchmark
376
270
  ```
377
271
 
378
- ## Examples
379
-
380
- Run the modern example to see all features in action:
381
-
382
- ```bash
383
- npx tsx examples/modern-example.ts
384
- ```
385
-
386
272
  ## Contributing
387
273
 
388
274
  We welcome contributions! See [CONTRIBUTING.md](docs/CONTRIBUTING.md) for guidelines on adding new email providers.
389
275
 
390
- **Quality Assurance**: This project maintains high standards with 396 comprehensive tests achieving excellent code coverage.
276
+ **Quality Assurance**: This project maintains high standards with 424 comprehensive tests achieving 93.16% code coverage (96.46% function coverage).
391
277
  **Security Note**: All new providers undergo security validation and must pass our allowlist verification.
392
278
 
393
279
  ## Security
@@ -400,4 +286,4 @@ MIT License - see [LICENSE](LICENSE) file for details.
400
286
 
401
287
  ---
402
288
 
403
- **Zero dependencies β€’ TypeScript-first β€’ Production ready β€’ International support**
289
+ **Zero dependencies β€’ TypeScript-first β€’ Production ready β€’ International support**
package/dist/api.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  */
7
7
  export interface EmailProvider {
8
8
  companyProvider: string;
9
- loginUrl: string;
9
+ loginUrl: string | null;
10
10
  domains: string[];
11
11
  customDomainDetection?: {
12
12
  mxPatterns?: string[];
package/dist/api.js CHANGED
@@ -215,9 +215,9 @@ function getEmailProviderSync(email) {
215
215
  }
216
216
  };
217
217
  }
218
- // Load providers and find matching domain
219
- const { providers } = (0, loader_1.loadProviders)();
220
- const provider = providers.find(p => p.domains?.some(d => d.toLowerCase() === domain));
218
+ // Use cached providers and domain map for efficient lookup
219
+ const { domainMap } = (0, loader_1.loadProviders)();
220
+ const provider = domainMap.get(domain);
221
221
  const result = {
222
222
  provider: provider || null,
223
223
  email,
@@ -4,7 +4,7 @@
4
4
  * Implements parallel MX/TXT record lookups for 2x faster business domain detection.
5
5
  * Uses Promise.allSettled for fault tolerance and intelligent result merging.
6
6
  */
7
- import { EmailProvider } from './index';
7
+ import { EmailProvider } from './api';
8
8
  /**
9
9
  * Configuration for concurrent DNS detection
10
10
  */
@@ -27,9 +27,9 @@ const path_1 = require("path");
27
27
  */
28
28
  const KNOWN_GOOD_HASHES = {
29
29
  // SHA-256 hash of the legitimate emailproviders.json
30
- 'emailproviders.json': 'f77814bf0537019c6f38bf2744ae21640f04a2d39cb67c5116f6e03160c9486f',
30
+ 'emailproviders.json': 'bdd4fe7d32a8760db2c2a2fcc9d2c07b32cc309f17eb6fd6c57753de0b5d623d',
31
31
  // You can add hashes for other critical files
32
- 'package.json': '67927e7e27636b55dc1fee5e34f16bbbf721a33103b0bc94c3c42923e2325cef'
32
+ 'package.json': '86b76c6907a39775d96677b6d76719c8de6cadd256945134195513101beef489'
33
33
  };
34
34
  /**
35
35
  * Calculates SHA-256 hash of a file or string content
package/dist/loader.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Handles loading email provider data with performance optimizations.
5
5
  */
6
- import { EmailProvider } from './index';
6
+ import { EmailProvider } from './api';
7
7
  /**
8
8
  * Loading statistics for performance monitoring
9
9
  */
package/dist/loader.js CHANGED
@@ -30,8 +30,8 @@ const DEFAULT_CONFIG = {
30
30
  */
31
31
  function convertProviderToEmailProvider(compressedProvider) {
32
32
  const provider = {
33
- companyProvider: compressedProvider.name,
34
- loginUrl: compressedProvider.url,
33
+ companyProvider: compressedProvider.companyProvider,
34
+ loginUrl: compressedProvider.loginUrl || null,
35
35
  domains: compressedProvider.domains || []
36
36
  };
37
37
  // Convert DNS detection patterns
@@ -92,6 +92,10 @@ function loadProvidersInternal(config = {}) {
92
92
  console.log(`⚑ Loading completed in ${loadTime}ms`);
93
93
  console.log(`πŸ“Š Stats: ${providers.length} providers, ${domainCount} domains`);
94
94
  }
95
+ if (process.env.NODE_ENV === 'development') {
96
+ const memoryUsageInMB = process.memoryUsage().heapUsed / 1024 / 1024;
97
+ console.log(`πŸš€ Current memory usage: ${memoryUsageInMB.toFixed(2)} MB`);
98
+ }
95
99
  return {
96
100
  providers,
97
101
  stats: loadingStats
package/dist/schema.d.ts CHANGED
@@ -12,9 +12,9 @@ export interface Provider {
12
12
  /** Provider ID (short identifier) */
13
13
  id: string;
14
14
  /** Provider display name */
15
- name: string;
16
- /** Login/webmail URL */
17
- url: string;
15
+ companyProvider: string;
16
+ /** Login/webmail URL (or null if not available) */
17
+ loginUrl: string | null;
18
18
  /** Email domains (omitted if empty) */
19
19
  domains?: string[];
20
20
  /** DNS detection patterns (flattened) */
package/dist/schema.js CHANGED
@@ -51,14 +51,11 @@ function validateProvider(provider) {
51
51
  if (!provider.id || typeof provider.id !== 'string') {
52
52
  errors.push('Provider ID is required and must be a string');
53
53
  }
54
- if (!provider.name || typeof provider.name !== 'string') {
55
- errors.push('Provider name is required and must be a string');
54
+ if (!provider.companyProvider || typeof provider.companyProvider !== 'string') {
55
+ errors.push('Company provider is required and must be a string');
56
56
  }
57
- if (!provider.url || typeof provider.url !== 'string') {
58
- errors.push('Provider URL is required and must be a string');
59
- }
60
- else if (!provider.url.startsWith('https://')) {
61
- errors.push('Provider URL must use HTTPS');
57
+ if (provider.loginUrl !== null && (typeof provider.loginUrl !== 'string' || !provider.loginUrl.startsWith('https://'))) {
58
+ errors.push('Login URL must be null or a string starting with HTTPS');
62
59
  }
63
60
  if (provider.domains && !Array.isArray(provider.domains)) {
64
61
  errors.push('Domains must be an array');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mikkelscheike/email-provider-links",
3
- "version": "2.7.1",
4
- "description": "TypeScript library for email provider detection with 93 providers (178 domains), concurrent DNS resolution, optimized performance, 91.75% test coverage, and enterprise security for login and password reset flows",
3
+ "version": "2.8.0",
4
+ "description": "TypeScript library for email provider detection with 93 providers (207 domains), concurrent DNS resolution, optimized performance, 91.75% test coverage, and enterprise security for login and password reset flows",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
@@ -62,17 +62,17 @@
62
62
  "access": "public"
63
63
  },
64
64
  "devDependencies": {
65
- "@jest/globals": "^30.0.2",
65
+ "@jest/globals": "^30.0.3",
66
66
  "@semantic-release/commit-analyzer": "^13.0.1",
67
67
  "@semantic-release/exec": "^7.1.0",
68
68
  "@semantic-release/git": "^10.0.1",
69
69
  "@semantic-release/github": "^11.0.3",
70
- "@semantic-release/npm": "^12.0.1",
70
+ "@semantic-release/npm": "^12.0.2",
71
71
  "@semantic-release/release-notes-generator": "^14.0.3",
72
72
  "@types/jest": "^30.0.0",
73
- "@types/node": "^24.0.3",
73
+ "@types/node": "^24.0.4",
74
74
  "conventional-changelog-conventionalcommits": "^9.0.0",
75
- "jest": "^30.0.2",
75
+ "jest": "^30.0.3",
76
76
  "semantic-release": "^24.2.5",
77
77
  "ts-jest": "^29.4.0",
78
78
  "tsx": "^4.20.3",