rdap
v0.0.14
Published
Modern RDAP client and server with RFC compliance, bootstrap service, and h3 integration
Maintainers
Readme
rdap 🌐
A modern RDAP (Registration Data Access Protocol) client and server implementation following ICANN standards.
✨ Features
- 🎯 Full support for all RDAP query types:
- 🌐 Domain names (including IDN support)
- 🔍 IP addresses (IPv4 and IPv6)
- 🔢 Autonomous System Numbers (ASN)
- 🌍 Nameservers
- 👤 Entity handles and object tags
- 📦 Built-in IANA bootstrap files with option to fetch latest data
- ⚡️ Real-time bootstrap data retrieval
- 🔄 Proper Accept header usage for RDAP responses
- 🛡️ Comprehensive error handling with detailed error types
- 📝 Full TypeScript support with strict type definitions
- 🚀 Minimal dependencies and small footprint
- 🔒 Secure access support (HTTPS and authentication)
- 📄 Pagination support for large responses
- 🧩 Functional programming approach - pure functions only
- 🚀 Built-in RDAP server with h3 integration
- 🔄 Server supports custom data providers and proxying
📥 Installation
# Using npm
npm install rdap
# Using yarn
yarn add rdap
# Using pnpm
pnpm add rdap🚀 Basic Usage
import {
queryRDAP,
queryDomain,
queryIP,
queryASN,
queryNameserver,
queryEntity,
queryHelp,
createRdapServer,
} from "rdap";
// Query domain information
const domainInfo = await queryDomain("example.com");
// Returns: RdapDomain with nameservers, status, events, etc.
// Query IP information (IPv4)
const ipv4Info = await queryIP("8.8.8.8");
// Returns: RdapIpNetwork with network information, entities, etc.
// Query IP information (IPv6)
const ipv6Info = await queryIP("2001:db8::1");
// Returns: RdapIpNetwork with network information, entities, etc.
// Query ASN information
const asnInfo = await queryASN("15169");
// Returns: RdapAutnum with ASN details, network range, etc.
// Query nameserver information
const nsInfo = await queryNameserver("ns1.example.com");
// Returns: RdapNameserver with nameserver details, status, etc.
// Query entity information
const entityInfo = await queryEntity("GOGL");
// Returns: RdapEntity with entity details, roles, etc.
// Query help information
const helpInfo = await queryHelp();
// Returns: RdapHelp with RDAP server capabilities and reverse search properties
// Generic query with options
const data = await queryRDAP("example.com", {
baseUrl: "https://custom-rdap-server.com",
type: "domain", // Explicitly specify query type
fetchOptions: {
headers: {
Authorization: "Bearer your-token",
},
},
});
// All convenience functions also support options
const domainWithCustomServer = await queryDomain("example.com", {
baseUrl: "https://custom-rdap-server.com",
fetchOptions: {},
});
const nameserverWithType = await queryNameserver("ns1.example.com", {
type: "nameserver", // Explicitly specify nameserver query
});
// Create and start RDAP server
const server = createRdapServer();
server.serve(8080);
console.log("RDAP Server running on http://localhost:8080");🔧 Advanced Usage
🚀 RDAP Server
Basic Server
import { createRdapServer, createRdapHandler } from "rdap/server";
// Create and start RDAP server
const server = createRdapServer();
server.serve(8080);
// RDAP Server running on http://localhost:8080
// Available endpoints:
// GET /help - Server help
// GET /domain/example.com - Domain info
// GET /ip/8.8.8.8 - IP info
// GET /autnum/15169 - ASN info
// GET /nameserver/ns1.example.com - Nameserver info
// GET /entity/ABC123-EXAMPLE - Entity infoServer with Custom Base URL
const server = createRdapServer({
baseUrl: "https://rdap.arin.net/registry",
});
server.serve(8080);Server with Custom Data Provider
const server = createRdapServer({
dataProvider: async (query, type) => {
console.log(`${type}: ${query}`);
// Return custom data
return {
objectClassName: type,
handle: `MOCK_${query}`,
};
},
});
server.serve(8080);Using Handler Directly
import { createApp } from "h3";
const handler = createRdapHandler({
baseUrl: "https://rdap.example.com",
});
const app = createApp();
app.use(handler);
// Start with your own server setup🛠️ Using Custom RDAP Servers (Client)
import { queryRDAP } from "rdap";
// Use a custom RDAP server
const domainInfo = await queryRDAP("example.com", {
baseUrl: "https://rdap.nic.example",
});
// Use custom headers and authentication
const domainInfo = await queryRDAP("example.com", {
fetchOptions: {
headers: {
Authorization: "Bearer your-token",
},
},
});🔍 Type Detection and Validation
import { getQueryType, getBootstrapType, isDomain, isAsn } from "rdap";
// Detect query type automatically
const queryType = getQueryType("example.com"); // "domain"
const queryType = getQueryType("8.8.8.8"); // "ip"
const queryType = getQueryType("15169"); // "autnum"
// Get bootstrap type for server discovery
const bootstrapType = getBootstrapType("example.com"); // "dns"
const bootstrapType = getBootstrapType("8.8.8.8"); // "ipv4"
const bootstrapType = getBootstrapType("15169"); // "asn"
// Validate input types
console.log(isDomain("example.com")); // true
console.log(isAsn("AS15169")); // true
console.log(isAsn("15169")); // true🔄 Working with Bootstrap Data
import { findBootstrapServer, getBootstrapMetadata } from "rdap";
// Find appropriate RDAP server for a query
const serverUrl = await findBootstrapServer("dns", "example.com");
console.log(serverUrl); // "https://rdap.verisign.com"
const serverUrl = await findBootstrapServer("ipv4", "8.8.8.8");
console.log(serverUrl); // "https://rdap.arin.net"
// Get bootstrap metadata for offline usage
const metadata = await getBootstrapMetadata("ipv4");
console.log(metadata.servers); // Available IPv4 RDAP servers
// Force refresh bootstrap data
const freshMetadata = await getBootstrapMetadata("dns", true);⚠️ Error Handling
import { queryRDAP } from "rdap";
try {
const data = await queryRDAP("nonexistent-domain.example");
} catch (error) {
console.error(`RDAP query failed: ${error.message}`);
// Common error types:
if (error.message.includes("not found")) {
// Handle 404 errors
}
if (error.message.includes("rate limit")) {
// Handle 429 errors
}
if (error.message.includes("authentication failed")) {
// Handle 401/403 errors
}
}📚 API Reference
🔍 Query Functions
queryRDAP<T = RdapResponse>(query: string, options?: RdapOptions): Promise<T>
Generic RDAP query function with full configuration options.
Parameters:
query- The query string (domain, IP, ASN, entity handle, etc.)options- Optional configuration objectbaseUrl?- Custom RDAP server URLtype?- Explicit query type (overrides auto-detection)fetchOptions?- Fetch API options (headers, auth, etc.)
Returns:
- Promise resolving to the RDAP response
queryDomain<T = RdapDomain>(domain: string, options?: RdapOptions): Promise<T>
Query domain information with optional configuration.
queryIP<T = RdapIpNetwork>(ip: string, options?: RdapOptions): Promise<T>
Query IP network information with optional configuration.
queryASN<T = RdapAutnum>(asn: string, options?: RdapOptions): Promise<T>
Query autonomous system information with optional configuration.
queryNameserver<T = RdapNameserver>(nameserver: string, options?: RdapOptions): Promise<T>
Query nameserver information with optional configuration.
queryEntity<T = RdapEntity>(handle: string, options?: RdapOptions): Promise<T>
Query entity information with optional configuration.
queryHelp<T = RdapHelp>(options?: RdapOptions): Promise<T>
Query RDAP help information from the server. Returns server capabilities, conformance levels, and reverse search properties.
🚀 Server Functions
createRdapServer(options?: RdapServerOptions): { handler: EventHandlerWithFetch, serve: (port?: number) => void }
Create a complete RDAP server with convenience wrapper.
Parameters:
options- Optional server configuration objectbaseUrl?- Custom RDAP server URL to proxy requests todataProvider?- Custom data handler for local responsesauthorize?- Authorization function for requestsfetchOptions?- Custom fetch options for proxied requestsresolvePath?- Custom path resolver function
Returns:
- Object with
handlerandserve(port)method
createRdapHandler(options?: RdapServerOptions): EventHandlerWithFetch
Create an RDAP handler that can be used with h3 or other web frameworks.
Parameters: Same as createRdapServer
Returns:
- Event handler that can be used with h3 apps
🔧 Utility Functions
getQueryType(query: string): RdapQueryType
Automatically detect the type of query based on input format.
Returns: "domain" | "nameserver" | "entity" | "ip" | "autnum" | "help"
getBootstrapType(query: string): RdapBootstrapType
Get the bootstrap type for server discovery.
Returns: "asn" | "dns" | "ipv4" | "ipv6" | "object-tags"
isDomain(value: string): boolean
Check if a string is a valid domain name.
isAsn(value: string): boolean
Check if a string is a valid ASN (supports both "AS15169" and "15169" formats).
formatAsn(value: string): string
Format ASN value to remove "AS" prefix if present.
convertToAscii(domain: string): string
Convert internationalized domain name (IDN) to ASCII format.
bootstrapTypeToQueryType(type: RdapBootstrapType, queryType?: RdapQueryType): RdapQueryType
Convert bootstrap type to query type. Optionally accepts explicit query type to override default mapping.
findBootstrapServer(type: RdapBootstrapType, query: string): Promise<string>
Find appropriate RDAP server for a given query type and query string.
Returns: Promise resolving to the RDAP server URL
getBootstrapMetadata(type: RdapBootstrapType, fetch?: boolean): Promise<RdapBootstrapMetadata>
Get bootstrap metadata for RDAP server discovery. Supports offline usage with cached data.
Parameters:
type- Bootstrap type ("asn" | "dns" | "ipv4" | "ipv6" | "object-tags")fetch- Force refresh bootstrap data from IANA (default: false)
Returns: Promise resolving to bootstrap metadata with server listings
getServerUrl(query: string, type?: RdapQueryType, options?: RdapOptions): Promise<string>
Build complete RDAP query URL with automatic server discovery.
Returns: Promise resolving to the full RDAP query URL
📋 Types
RdapOptions
Configuration options for RDAP queries:
interface RdapOptions {
baseUrl?: string; // Custom RDAP server URL
type?: RdapQueryType; // Explicit query type (overrides auto-detection)
fetchOptions?: RequestInit; // Fetch API options (headers, auth, etc.)
}Response Types
RdapDomain- Domain information responseRdapIpNetwork- IP network information responseRdapAutnum- Autonomous system information responseRdapNameserver- Nameserver information responseRdapEntity- Entity information responseRdapHelp- Help and server capabilities responseRdapErrorResponse- Error response
📖 Standards Compliance
This implementation strictly follows these RDAP-related standards:
- 📘 RFC 7480 - HTTP Usage in RDAP
- 🔒 RFC 7481 - Security Services for RDAP
- 🔍 RFC 7482 - RDAP Query Format
- 📋 RFC 7483 - RDAP JSON Responses
- 🔄 RFC 8056 - EPP and RDAP Status Mapping
- ✅ ICANN RDAP Response Profile
✅ Specification Compliance Features
- HTTP Method: Uses GET for all RDAP queries as required by RFC 7482
- Content Negotiation: Sends
Accept: application/rdap+jsonheader - User-Agent: Includes proper client identification
- URL Structure: Follows
{baseUrl}/{queryType}/{query}pattern - Error Handling: Implements comprehensive HTTP status code handling
- Help Support: Provides
queryHelp()for server capability discovery - Bootstrap Service: Uses IANA official bootstrap data for server discovery
