npm package: @neivi/iqx-lookup-typescript
Description: IQX Lookup API client for TypeScript/JavaScript
Author: Neivi IT
Latest version: 0.2.1

# @neivi/iqx-lookup-typescript

TypeScript/JavaScript client for the [IQX Lookup API](https://iqxlookup.neivi.es) -- 11 validation and lookup endpoints with full type safety.

## Installation

```bash
npm install @neivi/iqx-lookup-typescript
```

## Quick Start

```typescript
import { IqxLookup } from '@neivi/iqx-lookup-typescript';

const client = new IqxLookup({ apiKey: 'ALk-your-api-key' });

// Validate an email
const email = await client.validateEmail('user@example.com');
console.log(email.validFormat, email.disposableEmail);

// Geolocate an IP
const geo = await client.geolocateIp('8.8.8.8');
console.log(geo.countryName, geo.cityName);

// Validate an IBAN
const iban = await client.validateIban('DE89370400440532013000');
console.log(iban.valid, iban.bankCode, iban.bicValid);
```

## API Reference

| Method | Parameters | Returns |
|--------|-----------|---------|
| `validateEmail(address)` | email address | `EmailValidationResult` |
| `validatePhone(number, countryCode?)` | phone number, optional country | `PhoneValidationResult` |
| `geolocateIp(ip?)` | IPv4/IPv6 address (omit for caller's IP) | `IpGeolocation` |
| `validateVat(countryCode, number)` | EU country code, VAT number | `VatValidationResult` |
| `parseUserAgent(ua?)` | User-Agent string (omit for caller's UA) | `UserAgentResult` |
| `validateIban(iban)` | IBAN string | `IbanValidationResult` |
| `validateBic(bic)` | BIC/SWIFT code | `BicValidationResult` |
| `lookupDns(domain, types?)` | domain, optional record type filter | `DnsLookupResult` |
| `checkSsl(domain)` | domain name | `SslCertificateResult` |
| `analyzePassword(password)` | password string | `PasswordStrengthResult` |
| `validateCreditCard(cardNumber)` | card number | `CreditCardValidationResult` |

### `validateEmail(address: string): Promise<EmailValidationResult>`

Validates an email address. Returns format validity, MX/A record presence, role address detection, disposable email detection, and free email provider detection.

### `validatePhone(number: string, countryCode?: string): Promise<PhoneValidationResult>`

Validates a phone number. Returns E.164 formatting, carrier info, phone type, location, and timezone data. The optional `countryCode` parameter helps parse numbers without an international prefix.

### `geolocateIp(ip?: string): Promise<IpGeolocation>`

Geolocates an IP address. When called without arguments, geolocates the caller's IP. Returns country, region, city, coordinates, timezone, and EU membership.

### `validateVat(countryCode: string, number: string): Promise<VatValidationResult>`

Validates a European VAT number against the VIES service. Returns validity, registered name, and address.

### `parseUserAgent(ua?: string): Promise<UserAgentResult>`

Parses a user-agent string. When called without arguments, parses the caller's user-agent. Returns browser, OS, and device information.

### `validateIban(iban: string): Promise<IbanValidationResult>`

Validates an IBAN (International Bank Account Number). Returns validity, country code, bank code, branch code, check digit, account number, BIC, and BIC validity.

### `validateBic(bic: string): Promise<BicValidationResult>`

Validates a BIC/SWIFT code. Returns validity, bank code, country code, location code, and branch code.

### `lookupDns(domain: string, types?: string): Promise<DnsLookupResult>`

Looks up DNS records for a domain. The optional `types` parameter filters by record type (e.g., `"MX"`). Returns the domain, an array of DNS records, and security analysis (SPF, DMARC, DNSSEC).

### `checkSsl(domain: string): Promise<SslCertificateResult>`

Checks the SSL/TLS certificate for a domain. Returns issuer, subject, validity dates (`validFrom`/`validTo`), days until expiry, protocol, serial number, grade, warnings, signature algorithm, SANs, cipher suite, and chain length.

### `analyzePassword(password: string): Promise<PasswordStrengthResult>`

Analyzes password strength. Returns score (0-4), crack time (seconds and display), guesses, warning, improvement suggestions, and breach information.

### `validateCreditCard(cardNumber: string): Promise<CreditCardValidationResult>`

Validates a credit card number using the Luhn algorithm. Returns validity, card brand, last four digits, card type, issuing bank, card country, card category, and Luhn check result.

### `rateLimitInfo: RateLimitInfo | null`

Returns the rate limit information from the most recent API response, or `null` if no request has been made yet.

## Configuration

```typescript
const client = new IqxLookup({
  apiKey: 'ALk-your-api-key',
});
```

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `string` | -- | API key for authentication (required) |
| `baseUrl` | `string` | `https://api.iqxlookup.neivi.es` | API base URL |
| `timeout` | `number` | `10000` | Request timeout in milliseconds |

The base URL is resolved with priority: **explicit parameter > `LOOKUP_BASE_URL` env var > default**. Useful for local development:

```bash
export LOOKUP_BASE_URL=http://localhost:8081
```

## Rate Limiting

Rate limit information is available after every API call via `client.rateLimitInfo`:

```typescript
const result = await client.validateEmail('user@example.com');
const limits = client.rateLimitInfo;
if (limits) {
  console.log(`${limits.remaining}/${limits.limit} requests remaining`);
  console.log(`Resets at ${new Date(limits.reset * 1000)}`);
}
```

## Error Handling

All errors extend `IqxLookupError`, which provides `statusCode` and `errorMessage` properties.

```typescript
import {
  IqxLookup,
  IqxLookupError,
  UnauthorizedError,
  ForbiddenError,
  RateLimitError,
  NotFoundError,
  ServiceUnavailableError,
} from '@neivi/iqx-lookup-typescript';

const client = new IqxLookup({ apiKey: 'ALk-your-api-key' });

try {
  const result = await client.validateEmail('user@example.com');
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
    console.log(`Limit: ${error.limit}, Remaining: ${error.remaining}`);
  } else if (error instanceof UnauthorizedError) {
    console.log('Invalid API key');
  } else if (error instanceof ForbiddenError) {
    console.log('Access denied');
  } else if (error instanceof NotFoundError) {
    console.log('Resource not found');
  } else if (error instanceof ServiceUnavailableError) {
    console.log('Service temporarily unavailable');
  } else if (error instanceof IqxLookupError) {
    console.log(`API error ${error.statusCode}: ${error.errorMessage}`);
  }
}
```

| Error Class | HTTP Status | Extra Properties |
|---|---|---|
| `UnauthorizedError` | 401 | |
| `ForbiddenError` | 403 | |
| `NotFoundError` | 404 | |
| `RateLimitError` | 429 | `retryAfter`, `limit`, `remaining`, `reset` |
| `ServiceUnavailableError` | 503 | |
| `IqxLookupError` | any | `statusCode`, `errorMessage` |

## Testing

```bash
npm test
```

## Requirements

- Node.js 18+ (uses native `fetch`)
- Zero runtime dependencies

## License

Apache-2.0