zynor 0.0.44
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/LICENSE +265 -0
- package/README.md +758 -0
- package/dist/index.cjs +71563 -0
- package/dist/index.d.ts +3078 -0
- package/dist/index.js +71563 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
# zynor
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/zynor)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](http://www.typescriptlang.org/)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
|
|
8
|
+
A comprehensive, promise-based DNS resolver library that aggregates multiple DNS-over-HTTPS (DoH) providers with advanced concurrency control, email validation, and flexible configuration. Built with TypeScript for maximum type safety and developer experience.
|
|
9
|
+
|
|
10
|
+
## 📋 Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Features](#-features)
|
|
13
|
+
- [Installation](#-installation)
|
|
14
|
+
- [Quick Start](#-quick-start)
|
|
15
|
+
- [DNS Providers](#-dns-providers)
|
|
16
|
+
- [Configuration](#-configuration)
|
|
17
|
+
- [API Reference](#-api-reference)
|
|
18
|
+
- [DNS Record Types](#-dns-record-types)
|
|
19
|
+
- [Email Validation](#email-validation)
|
|
20
|
+
- [TypeScript Support](#-typescript-support)
|
|
21
|
+
- [License](#-license)
|
|
22
|
+
|
|
23
|
+
## 🚀 Features
|
|
24
|
+
|
|
25
|
+
Zynor is designed to be the most comprehensive and reliable DNS resolution library for modern JavaScript applications. It combines multiple DNS-over-HTTPS providers with intelligent load balancing, advanced error handling, and extensive email validation capabilities to deliver enterprise-grade DNS resolution with exceptional performance and reliability.
|
|
26
|
+
|
|
27
|
+
- **🌐 Multiple DNS Providers**: Google DoH, Cloudflare DoH, Quad9 DoH, and Node.js native DNS
|
|
28
|
+
- **⚡ High Performance**: Concurrent requests with intelligent load balancing
|
|
29
|
+
- **🎯 Smart Provider Selection**: Automatic failover and random selection
|
|
30
|
+
- **🔧 Flexible Configuration**: Per-provider concurrency and rate limiting
|
|
31
|
+
- **📝 Full TypeScript Support**: Complete type definitions and IntelliSense
|
|
32
|
+
- **🌍 Cross-Platform**: Works with Node.js 18+, Deno, and Bun
|
|
33
|
+
- **📊 Complete DNS API**: All standard DNS record types supported
|
|
34
|
+
- **📧 Email Validation**: Comprehensive email domain validation and webmail detection
|
|
35
|
+
- **🛡️ Error Handling**: Robust error handling with detailed error information
|
|
36
|
+
- **🔄 Automatic Retry**: Built-in retry logic with exponential backoff
|
|
37
|
+
- **📈 Queue Management**: Advanced queue management with rate limiter
|
|
38
|
+
- **🎛️ Runtime Configuration**: Dynamic configuration updates without restart
|
|
39
|
+
|
|
40
|
+
## 📦 Installation
|
|
41
|
+
|
|
42
|
+
Zynor is available as an npm package and can be installed using any modern JavaScript package manager. The library is built with zero dependencies for maximum compatibility and minimal bundle size, making it perfect for both server-side applications and edge computing environments.
|
|
43
|
+
|
|
44
|
+
**Using npm:**
|
|
45
|
+
```bash
|
|
46
|
+
npm install zynor
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Using Yarn:**
|
|
50
|
+
```bash
|
|
51
|
+
yarn add zynor
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Using pnpm:**
|
|
55
|
+
```bash
|
|
56
|
+
pnpm add zynor
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Requirements:**
|
|
60
|
+
- Node.js 18.0.0 or higher
|
|
61
|
+
- TypeScript 4.5+ (for TypeScript projects)
|
|
62
|
+
- Modern JavaScript environment with Promise support
|
|
63
|
+
|
|
64
|
+
## 🚀 Quick Start
|
|
65
|
+
|
|
66
|
+
Get started with Zynor in seconds! The library offers two main approaches: standalone functions for simple DNS queries and the Zynor class for advanced configuration and control. Both approaches provide the same powerful DNS resolution capabilities with automatic provider selection and intelligent error handling.
|
|
67
|
+
|
|
68
|
+
### Standalone Functions (Recommended for Simple Use Cases)
|
|
69
|
+
|
|
70
|
+
Standalone functions provide the quickest way to perform DNS lookups with sensible defaults and automatic provider selection:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// Using standalone functions (recommended for simple use cases)
|
|
74
|
+
import { resolve4, resolveMx, resolveAny } from 'zynor';
|
|
75
|
+
|
|
76
|
+
// Resolve A records
|
|
77
|
+
const addresses = await resolve4('example.com');
|
|
78
|
+
console.log(addresses); // ['93.184.216.34']
|
|
79
|
+
|
|
80
|
+
// Resolve MX records
|
|
81
|
+
const mxRecords = await resolveMx('example.com');
|
|
82
|
+
console.log(mxRecords); // [{ priority: 10, exchange: 'mail.example.com' }]
|
|
83
|
+
|
|
84
|
+
// Resolve with specific provider
|
|
85
|
+
const googleResult = await resolve4('example.com', undefined, 'google');
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Zynor Class (For Advanced Configuration)
|
|
89
|
+
|
|
90
|
+
The Zynor class provides fine-grained control over DNS providers, concurrency limits, timeouts, and retry behavior:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// Using Zynor class (for advanced configuration)
|
|
94
|
+
import { Zynor } from 'zynor';
|
|
95
|
+
|
|
96
|
+
const dns = new Zynor({
|
|
97
|
+
google: { enabled: true, limit: { concurrency: 10 } },
|
|
98
|
+
cloudflare: { enabled: true, limit: { concurrency: 5 } }
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const addresses = await dns.resolve4('example.com');
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### CommonJS Support
|
|
105
|
+
|
|
106
|
+
Zynor fully supports CommonJS environments for maximum compatibility:
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
// CommonJS usage
|
|
110
|
+
const { resolve4, Zynor } = require('zynor');
|
|
111
|
+
|
|
112
|
+
const addresses = await resolve4('example.com');
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 🌐 DNS Providers
|
|
116
|
+
|
|
117
|
+
Zynor integrates with multiple DNS providers to ensure maximum reliability, performance, and flexibility. Each provider offers unique advantages and can be configured independently with custom settings for concurrency, timeouts, and retry behavior. The library automatically selects the best available provider or allows manual provider specification for specific use cases.
|
|
118
|
+
|
|
119
|
+
### Native Provider
|
|
120
|
+
|
|
121
|
+
The native provider leverages Node.js's built-in DNS resolution capabilities, providing seamless integration with system DNS settings and local network configurations.
|
|
122
|
+
|
|
123
|
+
- **Endpoint**: Node.js built-in `dns/promises` module
|
|
124
|
+
- **Features**: Supports all DNS methods including `lookup()`
|
|
125
|
+
- **Use Case**: Local/internal DNS resolution, system DNS settings
|
|
126
|
+
- **Advantages**: No external dependencies, respects system DNS configuration
|
|
127
|
+
- **Best For**: Internal networks, development environments, system-integrated applications
|
|
128
|
+
|
|
129
|
+
### Google DoH (DNS-over-HTTPS)
|
|
130
|
+
|
|
131
|
+
Google's public DNS service provides enterprise-grade DNS resolution with global infrastructure and comprehensive DNSSEC validation.
|
|
132
|
+
|
|
133
|
+
- **Endpoint**: `https://dns.google/resolve`
|
|
134
|
+
- **Features**: DNSSEC validation, high reliability, global anycast network
|
|
135
|
+
- **Use Case**: Public DNS resolution with Google's infrastructure
|
|
136
|
+
- **Advantages**: Global CDN, excellent uptime, DNSSEC support, comprehensive logging
|
|
137
|
+
- **Best For**: Production applications, global services, DNSSEC-required environments
|
|
138
|
+
|
|
139
|
+
### Cloudflare DoH (DNS-over-HTTPS)
|
|
140
|
+
|
|
141
|
+
Cloudflare's privacy-focused DNS service emphasizes user privacy with minimal logging and fast global resolution.
|
|
142
|
+
|
|
143
|
+
- **Endpoint**: `https://cloudflare-dns.com/dns-query`
|
|
144
|
+
- **Features**: Privacy-focused, minimal logging, malware protection
|
|
145
|
+
- **Use Case**: Privacy-conscious applications, consumer-facing services
|
|
146
|
+
- **Advantages**: Fast global network, strong privacy policy, built-in security features
|
|
147
|
+
- **Best For**: Privacy-sensitive applications, consumer products, GDPR-compliant services
|
|
148
|
+
|
|
149
|
+
### Quad9 DoH (DNS-over-HTTPS)
|
|
150
|
+
|
|
151
|
+
Quad9's security-focused DNS service provides threat intelligence and malware blocking while maintaining user privacy.
|
|
152
|
+
|
|
153
|
+
- **Endpoint**: `https://dns.quad9.net/dns-query`
|
|
154
|
+
- **Features**: Security-focused, threat blocking, privacy protection
|
|
155
|
+
- **Use Case**: Security-sensitive applications, enterprise environments
|
|
156
|
+
- **Advantages**: Malware blocking, threat intelligence, non-profit organization, no user tracking
|
|
157
|
+
- **Best For**: Security-critical applications, enterprise networks, threat-aware environments
|
|
158
|
+
|
|
159
|
+
## ⚙️ Configuration
|
|
160
|
+
|
|
161
|
+
Zynor provides extensive configuration options to fine-tune DNS resolution behavior according to your application's specific requirements. Each DNS provider can be configured independently with custom concurrency limits, rate limiting, timeouts, and retry policies. The configuration system supports both static initialization and dynamic runtime updates.
|
|
162
|
+
|
|
163
|
+
### Basic Configuration Example
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
const dns = new Zynor({
|
|
167
|
+
google: {
|
|
168
|
+
enabled: true,
|
|
169
|
+
limit: { concurrency: 10, rps: 100 },
|
|
170
|
+
timeout: 5000,
|
|
171
|
+
retries: 3
|
|
172
|
+
},
|
|
173
|
+
cloudflare: {
|
|
174
|
+
enabled: true,
|
|
175
|
+
limit: { concurrency: 5, rps: 50 }
|
|
176
|
+
},
|
|
177
|
+
quad9: { enabled: false },
|
|
178
|
+
native: { enabled: true }
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Configuration Options
|
|
183
|
+
|
|
184
|
+
- **enabled**: Enable or disable the provider (boolean)
|
|
185
|
+
- **limit.concurrency**: Maximum concurrent requests per provider (number)
|
|
186
|
+
- **limit.rps**: Requests per second rate limit (number)
|
|
187
|
+
- **timeout**: Request timeout in milliseconds (number)
|
|
188
|
+
- **retries**: Number of retry attempts on failure (number)
|
|
189
|
+
- **priority**: Provider selection priority (number, higher = preferred)
|
|
190
|
+
|
|
191
|
+
### Dynamic Configuration Updates
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// Update configuration at runtime
|
|
195
|
+
dns.setConfig('google', { enabled: false });
|
|
196
|
+
dns.setConfigs({ cloudflare: { limit: { concurrency: 15 } } });
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 📚 API Reference
|
|
200
|
+
|
|
201
|
+
The Zynor API is designed for simplicity and flexibility, offering both class-based and functional approaches to DNS resolution. All methods return strongly-typed promises and support optional provider selection, custom timeouts, and advanced configuration options.
|
|
202
|
+
|
|
203
|
+
### Zynor Class
|
|
204
|
+
|
|
205
|
+
The Zynor class provides a comprehensive DNS resolution interface with full configuration control and advanced features like provider management, concurrency control, and runtime configuration updates.
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const dns = new Zynor(config?: ZynorConfig);
|
|
209
|
+
|
|
210
|
+
// Basic DNS resolution methods
|
|
211
|
+
dns.resolve4(hostname: string): Promise<string[]> // IPv4 addresses
|
|
212
|
+
dns.resolve6(hostname: string): Promise<string[]> // IPv6 addresses
|
|
213
|
+
dns.resolveMx(hostname: string): Promise<MxRecord[]> // Mail exchange records
|
|
214
|
+
dns.resolveTxt(hostname: string): Promise<string[][]> // Text records
|
|
215
|
+
dns.resolveCname(hostname: string): Promise<string[]> // Canonical name records
|
|
216
|
+
dns.resolveNs(hostname: string): Promise<string[]> // Name server records
|
|
217
|
+
dns.resolveSoa(hostname: string): Promise<SoaRecord> // Start of Authority
|
|
218
|
+
dns.resolvePtr(ip: string): Promise<string[]> // Reverse DNS lookup
|
|
219
|
+
dns.resolveSrv(hostname: string): Promise<SrvRecord[]> // Service records
|
|
220
|
+
dns.resolveAny(hostname: string): Promise<AnyRecord[]> // All available records
|
|
221
|
+
|
|
222
|
+
// Configuration methods
|
|
223
|
+
dns.setConfig(provider: string, config: ProviderConfig): void
|
|
224
|
+
dns.setConfigs(configs: Partial<ZynorConfig>): void
|
|
225
|
+
|
|
226
|
+
// Email validation
|
|
227
|
+
dns.emailValidator: EmailValidator
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Standalone Functions
|
|
231
|
+
|
|
232
|
+
Standalone functions provide a lightweight alternative for simple DNS queries without the need for class instantiation. These functions use sensible defaults and automatic provider selection.
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { resolve4, resolveMx, resolveAny } from 'zynor';
|
|
236
|
+
|
|
237
|
+
// Use directly without creating a class instance
|
|
238
|
+
const addresses = await resolve4('example.com'); // Quick IPv4 resolution
|
|
239
|
+
const mxRecords = await resolveMx('example.com'); // Mail server lookup
|
|
240
|
+
const anyRecords = await resolveAny('example.com'); // Comprehensive DNS query
|
|
241
|
+
|
|
242
|
+
// With optional provider specification
|
|
243
|
+
const googleResult = await resolve4('example.com', undefined, 'google');
|
|
244
|
+
const cloudflareResult = await resolveMx('example.com', undefined, 'cloudflare');
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Method Parameters
|
|
248
|
+
|
|
249
|
+
Most DNS resolution methods accept the following parameters:
|
|
250
|
+
|
|
251
|
+
- **hostname/ip**: The domain name or IP address to resolve (string)
|
|
252
|
+
- **options**: Optional configuration object (varies by method)
|
|
253
|
+
- **provider**: Optional provider name for specific provider usage (string)
|
|
254
|
+
|
|
255
|
+
### Return Types
|
|
256
|
+
|
|
257
|
+
All methods return strongly-typed promises with comprehensive type definitions for maximum TypeScript compatibility and IntelliSense support.
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
### Email Validation
|
|
262
|
+
|
|
263
|
+
The Email Validation system provides comprehensive email address validation, domain analysis, and provider detection. It combines syntax validation, DNS lookups, and an extensive database of email providers to deliver accurate validation results with detailed metadata about the email address and its hosting provider.
|
|
264
|
+
|
|
265
|
+
#### `EmailValidator` Class
|
|
266
|
+
|
|
267
|
+
The EmailValidator class is the core component for email validation operations. It provides intelligent email analysis by checking syntax, validating domains through DNS resolution, detecting email providers, and identifying role-based addresses. The validator supports both basic and deep validation modes to accommodate different use cases and performance requirements.
|
|
268
|
+
|
|
269
|
+
##### `validate(email: string, deep?: boolean): Promise<EmailResponse>`
|
|
270
|
+
|
|
271
|
+
Performs comprehensive email validation and analysis, returning detailed information about the email address including provider detection, webmail availability, and role-based email identification.
|
|
272
|
+
|
|
273
|
+
**Parameters:**
|
|
274
|
+
- `email`: Email address to validate (string)
|
|
275
|
+
- `deep` (optional): Enable deep validation with additional DNS lookups and extended checks (default: false)
|
|
276
|
+
|
|
277
|
+
**Returns:** EmailResponse object with one of the following structures:
|
|
278
|
+
|
|
279
|
+
**Success Response Structure:**
|
|
280
|
+
```typescript
|
|
281
|
+
{
|
|
282
|
+
success: true,
|
|
283
|
+
data: {
|
|
284
|
+
provider: string, // Email provider name (e.g., "Gmail", "Outlook")
|
|
285
|
+
email: string, // Normalized email address
|
|
286
|
+
isFree: boolean, // Whether it's a free email provider domain
|
|
287
|
+
role: boolean, // Whether it's a role-based email (admin, support, etc.)
|
|
288
|
+
webmail?: string // Webmail URL if available
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**Error Response Structure:**
|
|
294
|
+
```typescript
|
|
295
|
+
{
|
|
296
|
+
success: false,
|
|
297
|
+
type: 'Syntax' | 'Rejected' | 'Invalid' | 'Disposable' | 'Error',
|
|
298
|
+
email: string,
|
|
299
|
+
role: boolean, // Whether it's a role-based email
|
|
300
|
+
message?: string // Detailed error message (only present for 'Error' type)
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
#### Basic Email Validation Examples
|
|
305
|
+
|
|
306
|
+
**Simple Validation:**
|
|
307
|
+
```typescript
|
|
308
|
+
import { Zynor } from 'zynor';
|
|
309
|
+
|
|
310
|
+
const validator = Zynor.emailValidator;
|
|
311
|
+
|
|
312
|
+
// Basic email validation
|
|
313
|
+
const result = await validator.validate('user@gmail.com');
|
|
314
|
+
if (result.success) {
|
|
315
|
+
console.log('✅ Valid email');
|
|
316
|
+
console.log('Provider:', result.data.provider); // "Gmail"
|
|
317
|
+
console.log('Webmail:', result.data.webmail); // "https://mail.google.com"
|
|
318
|
+
console.log('Role email:', result.data.role); // false
|
|
319
|
+
} else {
|
|
320
|
+
console.log('❌ Invalid email:', result.type);
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Deep Validation Mode:**
|
|
325
|
+
```typescript
|
|
326
|
+
// Enable deep validation for thorough analysis
|
|
327
|
+
const deepResult = await validator.validate('admin@company.com', true);
|
|
328
|
+
if (deepResult.success) {
|
|
329
|
+
console.log('Provider:', deepResult.data.provider);
|
|
330
|
+
console.log('Is role-based:', deepResult.data.role); // likely true for "admin"
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
#### Provider Detection Examples
|
|
335
|
+
|
|
336
|
+
**Major Email Providers:**
|
|
337
|
+
```typescript
|
|
338
|
+
// Gmail detection
|
|
339
|
+
const gmailResult = await validator.validate('john.doe@gmail.com');
|
|
340
|
+
console.log(gmailResult.data?.provider); // "Gmail"
|
|
341
|
+
|
|
342
|
+
// Outlook detection
|
|
343
|
+
const outlookResult = await validator.validate('jane@outlook.com');
|
|
344
|
+
console.log(outlookResult.data?.provider); // "Outlook"
|
|
345
|
+
|
|
346
|
+
// Yahoo detection
|
|
347
|
+
const yahooResult = await validator.validate('user@yahoo.com');
|
|
348
|
+
console.log(yahooResult.data?.provider); // "Yahoo"
|
|
349
|
+
|
|
350
|
+
// Corporate email detection
|
|
351
|
+
const corpResult = await validator.validate('employee@microsoft.com');
|
|
352
|
+
console.log(corpResult.data?.provider); // "Microsoft"
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
#### Role-Based Email Detection
|
|
356
|
+
|
|
357
|
+
**Identifying Role-Based Addresses:**
|
|
358
|
+
```typescript
|
|
359
|
+
// Common role-based emails
|
|
360
|
+
const roleEmails = [
|
|
361
|
+
'admin@company.com',
|
|
362
|
+
'support@service.com',
|
|
363
|
+
'info@business.org',
|
|
364
|
+
'sales@enterprise.net',
|
|
365
|
+
'noreply@platform.io'
|
|
366
|
+
];
|
|
367
|
+
|
|
368
|
+
for (const email of roleEmails) {
|
|
369
|
+
const result = await validator.validate(email);
|
|
370
|
+
if (result.success && result.data.role) {
|
|
371
|
+
console.log(`${email} is a role-based email`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
#### Webmail Detection and Access
|
|
377
|
+
|
|
378
|
+
**Webmail URL Extraction:**
|
|
379
|
+
```typescript
|
|
380
|
+
// Get webmail URLs for popular providers
|
|
381
|
+
const webmailEmails = [
|
|
382
|
+
'user@gmail.com', // https://mail.google.com
|
|
383
|
+
'user@outlook.com', // https://outlook.live.com
|
|
384
|
+
'user@yahoo.com', // https://mail.yahoo.com
|
|
385
|
+
'user@icloud.com' // https://www.icloud.com/mail
|
|
386
|
+
];
|
|
387
|
+
|
|
388
|
+
for (const email of webmailEmails) {
|
|
389
|
+
const result = await validator.validate(email);
|
|
390
|
+
if (result.success && result.data.webmail) {
|
|
391
|
+
console.log(`${email} -> ${result.data.webmail}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
#### Batch Email Validation
|
|
397
|
+
|
|
398
|
+
**Validating Multiple Emails:**
|
|
399
|
+
```typescript
|
|
400
|
+
async function validateEmailBatch(emails: string[]) {
|
|
401
|
+
const results = await Promise.allSettled(
|
|
402
|
+
emails.map(email => validator.validate(email))
|
|
403
|
+
);
|
|
404
|
+
|
|
405
|
+
return emails.map((email, index) => {
|
|
406
|
+
const result = results[index];
|
|
407
|
+
if (result.status === 'fulfilled' && result.value.success) {
|
|
408
|
+
return {
|
|
409
|
+
email,
|
|
410
|
+
valid: true,
|
|
411
|
+
provider: result.value.data.provider,
|
|
412
|
+
role: result.value.data.role,
|
|
413
|
+
webmail: result.value.data.webmail
|
|
414
|
+
};
|
|
415
|
+
} else {
|
|
416
|
+
return {
|
|
417
|
+
email,
|
|
418
|
+
valid: false,
|
|
419
|
+
error: result.status === 'fulfilled' ? result.value.type : 'validation_failed'
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Usage example
|
|
426
|
+
const emailList = [
|
|
427
|
+
'valid@gmail.com',
|
|
428
|
+
'invalid.email',
|
|
429
|
+
'admin@company.com',
|
|
430
|
+
'user@nonexistent-domain.xyz'
|
|
431
|
+
];
|
|
432
|
+
|
|
433
|
+
const batchResults = await validateEmailBatch(emailList);
|
|
434
|
+
console.log('Batch validation results:', batchResults);
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
#### Error Handling and Response Types
|
|
438
|
+
|
|
439
|
+
**Comprehensive Error Handling:**
|
|
440
|
+
```typescript
|
|
441
|
+
async function handleEmailValidation(email: string) {
|
|
442
|
+
try {
|
|
443
|
+
const result = await validator.validate(email);
|
|
444
|
+
|
|
445
|
+
if (result.success) {
|
|
446
|
+
return {
|
|
447
|
+
status: 'valid',
|
|
448
|
+
data: result.data
|
|
449
|
+
};
|
|
450
|
+
} else {
|
|
451
|
+
// Handle different error types
|
|
452
|
+
switch (result.type) {
|
|
453
|
+
case 'Syntax':
|
|
454
|
+
return { status: 'syntax_error', message: 'Invalid email format' };
|
|
455
|
+
case 'Invalid':
|
|
456
|
+
return { status: 'invalid_domain', message: 'Domain does not exist' };
|
|
457
|
+
case 'Rejected':
|
|
458
|
+
return { status: 'rejected', message: 'Email rejected by provider' };
|
|
459
|
+
case 'Disposable':
|
|
460
|
+
return { status: 'disposable', message: 'Disposable email address' };
|
|
461
|
+
case 'Error':
|
|
462
|
+
return { status: 'validation_error', message: result.message };
|
|
463
|
+
default:
|
|
464
|
+
return { status: 'unknown_error', message: 'Validation failed' };
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
} catch (error) {
|
|
468
|
+
return {
|
|
469
|
+
status: 'exception',
|
|
470
|
+
message: error instanceof Error ? error.message : 'Unexpected error'
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
// Usage
|
|
476
|
+
const validationResult = await handleEmailValidation('test@example.com');
|
|
477
|
+
console.log(validationResult);
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### Advanced Use Cases
|
|
481
|
+
|
|
482
|
+
**Email Domain Analysis:**
|
|
483
|
+
```typescript
|
|
484
|
+
async function analyzeEmailDomain(email: string) {
|
|
485
|
+
const result = await validator.validate(email, true); // Deep validation
|
|
486
|
+
|
|
487
|
+
if (result.success) {
|
|
488
|
+
const domain = email.split('@')[1];
|
|
489
|
+
return {
|
|
490
|
+
email: result.data.email,
|
|
491
|
+
domain,
|
|
492
|
+
provider: result.data.provider,
|
|
493
|
+
hasWebmail: !!result.data.webmail,
|
|
494
|
+
webmailUrl: result.data.webmail,
|
|
495
|
+
isRoleBased: result.data.role,
|
|
496
|
+
isPersonal: ['Gmail', 'Yahoo', 'Outlook', 'iCloud'].includes(result.data.provider),
|
|
497
|
+
isCorporate: !['Gmail', 'Yahoo', 'Outlook', 'iCloud'].includes(result.data.provider)
|
|
498
|
+
};
|
|
499
|
+
} else {
|
|
500
|
+
return {
|
|
501
|
+
email,
|
|
502
|
+
valid: false,
|
|
503
|
+
errorType: result.type,
|
|
504
|
+
errorMessage: result.message
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const analysis = await analyzeEmailDomain('ceo@apple.com');
|
|
510
|
+
console.log('Email analysis:', analysis);
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
#### Additional EmailValidator Methods
|
|
514
|
+
|
|
515
|
+
The EmailValidator class provides several utility methods for email validation and manipulation:
|
|
516
|
+
|
|
517
|
+
##### `isEmail(email: string): boolean`
|
|
518
|
+
|
|
519
|
+
Performs advanced email format validation with structural constraints.
|
|
520
|
+
|
|
521
|
+
**Validation Rules:**
|
|
522
|
+
- Maximum 35 characters for the local part
|
|
523
|
+
- Maximum 3 hyphens in the local part
|
|
524
|
+
- Maximum 3 dots in the local part
|
|
525
|
+
- Maximum 3 dots in the domain part
|
|
526
|
+
- Maximum 2 hyphens in the domain part
|
|
527
|
+
- Maximum 55 total characters in the email address
|
|
528
|
+
- Local part must be at least 2 characters
|
|
529
|
+
- Domain part must be at least 5 characters
|
|
530
|
+
|
|
531
|
+
**Example:**
|
|
532
|
+
```typescript
|
|
533
|
+
const validator = EmailValidator.create();
|
|
534
|
+
|
|
535
|
+
validator.isEmail("john.doe@example.com"); // true
|
|
536
|
+
validator.isEmail("x@y.com"); // false (domain too short)
|
|
537
|
+
validator.isEmail("toolong@d.c"); // false
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
##### `isFreeDomain(email_or_domain: string): boolean`
|
|
541
|
+
|
|
542
|
+
Checks if an email address or domain belongs to a free email provider (Gmail, Yahoo, Outlook, etc.).
|
|
543
|
+
|
|
544
|
+
**Example:**
|
|
545
|
+
```typescript
|
|
546
|
+
validator.isFreeDomain('person@yahoo.com'); // true
|
|
547
|
+
validator.isFreeDomain('gmail.com'); // true
|
|
548
|
+
validator.isFreeDomain('user@company.org'); // false
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
##### `isDisposable(email: string): boolean`
|
|
552
|
+
|
|
553
|
+
Checks if an email address is from a known disposable/temporary email provider.
|
|
554
|
+
|
|
555
|
+
**Example:**
|
|
556
|
+
```typescript
|
|
557
|
+
validator.isDisposable('test@mailinator.com'); // true
|
|
558
|
+
validator.isDisposable('john.doe@gmail.com'); // false
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
##### `isJson(input: string): string[] | null`
|
|
562
|
+
|
|
563
|
+
Validates if a string is a JSON array of valid email addresses.
|
|
564
|
+
|
|
565
|
+
**Returns:** Array of valid emails if successful, `null` otherwise.
|
|
566
|
+
|
|
567
|
+
**Example:**
|
|
568
|
+
```typescript
|
|
569
|
+
validator.isJson('["hello@site.com", "test@a.io"]');
|
|
570
|
+
// Returns: ["hello@site.com", "test@a.io"]
|
|
571
|
+
|
|
572
|
+
validator.isJson('["foo", 1, null]'); // Returns: null
|
|
573
|
+
validator.isJson('not json'); // Returns: null
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
##### `extractEmails(input: string[]): string[]`
|
|
577
|
+
|
|
578
|
+
Extracts valid email addresses from various input formats including:
|
|
579
|
+
- Plain email addresses
|
|
580
|
+
- Comma-separated values
|
|
581
|
+
- URL-encoded strings (automatically decoded)
|
|
582
|
+
- JSON arrays
|
|
583
|
+
|
|
584
|
+
**Example:**
|
|
585
|
+
```typescript
|
|
586
|
+
// Single email
|
|
587
|
+
validator.extractEmails(["user@example.com"]);
|
|
588
|
+
// Returns: ["user@example.com"]
|
|
589
|
+
|
|
590
|
+
// Comma-separated emails
|
|
591
|
+
validator.extractEmails(["user1@example.com,user2@example.com"]);
|
|
592
|
+
// Returns: ["user1@example.com", "user2@example.com"]
|
|
593
|
+
|
|
594
|
+
// URL-encoded
|
|
595
|
+
validator.extractEmails(["user%40example.com,test%40domain.com"]);
|
|
596
|
+
// Returns: ["user@example.com", "test@domain.com"]
|
|
597
|
+
|
|
598
|
+
// JSON array
|
|
599
|
+
validator.extractEmails(['["email1@test.com", "email2@test.com"]']);
|
|
600
|
+
// Returns: ["email1@test.com", "email2@test.com"]
|
|
601
|
+
|
|
602
|
+
// Mixed formats
|
|
603
|
+
validator.extractEmails([
|
|
604
|
+
"user@example.com",
|
|
605
|
+
"test@domain.com,admin@site.com",
|
|
606
|
+
'["json@email.com"]'
|
|
607
|
+
]);
|
|
608
|
+
// Returns: ["user@example.com", "test@domain.com", "admin@site.com", "json@email.com"]
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
##### `getProviderWebmailUrl(provider: ProviderName): string | null`
|
|
612
|
+
##### `getProviderWebmailUrl(provider: ProviderName, domainOrEmail: string): string | null`
|
|
613
|
+
##### `getProviderWebmailUrl(domainOrEmail: string): string | null`
|
|
614
|
+
|
|
615
|
+
Retrieves the webmail URL for a given email provider. Supports multiple overloaded signatures for flexibility.
|
|
616
|
+
|
|
617
|
+
**Parameters:**
|
|
618
|
+
- `provider` - Provider name (e.g., "Gmail", "Outlook") or domain/email
|
|
619
|
+
- `domainOrEmail` (optional) - Domain name or full email address
|
|
620
|
+
|
|
621
|
+
**Returns:** Webmail URL string if found, `null` otherwise.
|
|
622
|
+
|
|
623
|
+
**Example:**
|
|
624
|
+
```typescript
|
|
625
|
+
// Using provider name
|
|
626
|
+
validator.getProviderWebmailUrl('Gmail');
|
|
627
|
+
// Returns: "https://mail.google.com"
|
|
628
|
+
|
|
629
|
+
// Using domain
|
|
630
|
+
validator.getProviderWebmailUrl('outlook.com');
|
|
631
|
+
// Returns: "https://outlook.live.com"
|
|
632
|
+
|
|
633
|
+
// Using email address
|
|
634
|
+
validator.getProviderWebmailUrl('user@yahoo.com');
|
|
635
|
+
// Returns: "https://mail.yahoo.com"
|
|
636
|
+
|
|
637
|
+
// Using provider name with domain
|
|
638
|
+
validator.getProviderWebmailUrl('Gmail', 'google.com');
|
|
639
|
+
// Returns: "https://mail.google.com"
|
|
640
|
+
|
|
641
|
+
// Unknown provider
|
|
642
|
+
validator.getProviderWebmailUrl('unknown-provider.com');
|
|
643
|
+
// Returns: null
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
## 🗂️ DNS Record Types
|
|
647
|
+
|
|
648
|
+
Zynor supports all standard DNS record types with comprehensive parsing and type-safe return values. Each record type is optimized for specific use cases, from basic domain resolution to advanced service discovery and email routing. The library automatically handles record parsing and provides structured data objects for easy consumption.
|
|
649
|
+
|
|
650
|
+
| Record Type | Description | Use Cases | Return Type |
|
|
651
|
+
|-------------|-------------|-----------|-------------|
|
|
652
|
+
| **A** | IPv4 address records | Web hosting, basic domain resolution | `string[]` |
|
|
653
|
+
| **AAAA** | IPv6 address records | Modern networking, dual-stack configurations | `string[]` |
|
|
654
|
+
| **MX** | Mail exchange records | Email routing, mail server discovery | `MxRecord[]` |
|
|
655
|
+
| **TXT** | Text records | Domain verification, SPF, DKIM, configuration | `string[][]` |
|
|
656
|
+
| **CNAME** | Canonical name records | Domain aliases, CDN configuration | `string[]` |
|
|
657
|
+
| **NS** | Name server records | DNS delegation, authoritative servers | `string[]` |
|
|
658
|
+
| **SOA** | Start of Authority | Zone information, DNS administration | `SoaRecord` |
|
|
659
|
+
| **SRV** | Service records | Service discovery, load balancing | `SrvRecord[]` |
|
|
660
|
+
| **PTR** | Pointer records (reverse DNS) | IP to domain mapping, security verification | `string[]` |
|
|
661
|
+
| **CAA** | Certificate Authority Authorization | SSL certificate validation | `CaaRecord[]` |
|
|
662
|
+
| **NAPTR** | Name Authority Pointer | Complex service resolution | `NaptrRecord[]` |
|
|
663
|
+
| **TLSA** | Transport Layer Security Authentication | Certificate pinning, security | `TlsaRecord[]` |
|
|
664
|
+
| **ANY** | All available records | Comprehensive domain analysis | `AnyRecord[]` |
|
|
665
|
+
|
|
666
|
+
### Record Type Examples
|
|
667
|
+
|
|
668
|
+
```typescript
|
|
669
|
+
// A records - IPv4 addresses
|
|
670
|
+
const ipv4 = await resolve4('example.com');
|
|
671
|
+
// Returns: ['93.184.216.34']
|
|
672
|
+
|
|
673
|
+
// MX records - Mail servers with priority
|
|
674
|
+
const mailServers = await resolveMx('example.com');
|
|
675
|
+
// Returns: [{ priority: 10, exchange: 'mail.example.com' }]
|
|
676
|
+
|
|
677
|
+
// TXT records - Text data (SPF, DKIM, etc.)
|
|
678
|
+
const txtRecords = await resolveTxt('example.com');
|
|
679
|
+
// Returns: [['v=spf1 include:_spf.example.com ~all']]
|
|
680
|
+
|
|
681
|
+
// SRV records - Service discovery
|
|
682
|
+
const services = await resolveSrv('_sip._tcp.example.com');
|
|
683
|
+
// Returns: [{ priority: 10, weight: 5, port: 5060, name: 'sip.example.com' }]
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
## 🔷 TypeScript Support
|
|
689
|
+
|
|
690
|
+
Zynor is built with TypeScript from the ground up, providing comprehensive type definitions, full IntelliSense support, and compile-time type checking. The library exports all necessary types and interfaces, ensuring type safety across your entire DNS resolution workflow and eliminating runtime type errors.
|
|
691
|
+
|
|
692
|
+
### Complete Type Safety
|
|
693
|
+
|
|
694
|
+
```typescript
|
|
695
|
+
import { Zynor, MxRecord, SrvRecord, ProviderName } from 'zynor';
|
|
696
|
+
|
|
697
|
+
// Strongly typed results with full IntelliSense
|
|
698
|
+
const mxRecords: MxRecord[] = await resolveMx('example.com');
|
|
699
|
+
const srvRecords: SrvRecord[] = await resolveSrv('_sip._tcp.example.com');
|
|
700
|
+
|
|
701
|
+
// Type-safe provider names prevent typos
|
|
702
|
+
const provider: ProviderName = 'google';
|
|
703
|
+
const addresses = await resolve4('example.com', undefined, provider);
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
### Available Type Exports
|
|
707
|
+
|
|
708
|
+
```typescript
|
|
709
|
+
// Core types
|
|
710
|
+
import {
|
|
711
|
+
Zynor, // Main DNS class
|
|
712
|
+
ProviderName, // 'google' | 'cloudflare' | 'quad9' | 'native'
|
|
713
|
+
ZynorConfig, // Configuration interface
|
|
714
|
+
ProviderConfig, // Individual provider configuration
|
|
715
|
+
|
|
716
|
+
// DNS record types
|
|
717
|
+
MxRecord, // Mail exchange record
|
|
718
|
+
SrvRecord, // Service record
|
|
719
|
+
SoaRecord, // Start of Authority record
|
|
720
|
+
CaaRecord, // Certificate Authority Authorization
|
|
721
|
+
NaptrRecord, // Name Authority Pointer
|
|
722
|
+
TlsaRecord, // Transport Layer Security Authentication
|
|
723
|
+
AnyRecord, // Union of all record types
|
|
724
|
+
|
|
725
|
+
// Email validation types
|
|
726
|
+
EmailValidator, // Email validation class
|
|
727
|
+
EmailResponse, // Validation response type
|
|
728
|
+
EmailData, // Successful validation data
|
|
729
|
+
EmailError // Validation error type
|
|
730
|
+
} from 'zynor';
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
### Generic Type Support
|
|
734
|
+
|
|
735
|
+
```typescript
|
|
736
|
+
// Generic functions with type inference
|
|
737
|
+
const resolveWithType = async <T>(hostname: string, type: string): Promise<T> => {
|
|
738
|
+
// Type-safe resolution with custom return types
|
|
739
|
+
return await dns.resolveAny(hostname) as T;
|
|
740
|
+
};
|
|
741
|
+
|
|
742
|
+
// Usage with automatic type inference
|
|
743
|
+
const mxRecords = await resolveWithType<MxRecord[]>('example.com', 'MX');
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
## 📄 License
|
|
751
|
+
|
|
752
|
+
MIT License - see the [LICENSE](LICENSE) file for details.
|
|
753
|
+
|
|
754
|
+
---
|
|
755
|
+
|
|
756
|
+
**Made with ❤️ by [Yuniq Solutions Tech](https://yuniq.solutions)**
|
|
757
|
+
|
|
758
|
+
For more information, visit our [GitHub repository](https://github.com/yuniqsolutions/zynor) or check out our [documentation](https://github.com/yuniqsolutions/zynor#readme).
|