domain-search-mcp 1.0.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/.env.example +52 -0
- package/Dockerfile +15 -0
- package/LICENSE +21 -0
- package/README.md +426 -0
- package/SECURITY.md +252 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +117 -0
- package/dist/config.js.map +1 -0
- package/dist/fallbacks/index.d.ts +6 -0
- package/dist/fallbacks/index.d.ts.map +1 -0
- package/dist/fallbacks/index.js +14 -0
- package/dist/fallbacks/index.js.map +1 -0
- package/dist/fallbacks/rdap.d.ts +18 -0
- package/dist/fallbacks/rdap.d.ts.map +1 -0
- package/dist/fallbacks/rdap.js +339 -0
- package/dist/fallbacks/rdap.js.map +1 -0
- package/dist/fallbacks/whois.d.ts +27 -0
- package/dist/fallbacks/whois.d.ts.map +1 -0
- package/dist/fallbacks/whois.js +219 -0
- package/dist/fallbacks/whois.js.map +1 -0
- package/dist/registrars/base.d.ts +89 -0
- package/dist/registrars/base.d.ts.map +1 -0
- package/dist/registrars/base.js +203 -0
- package/dist/registrars/base.js.map +1 -0
- package/dist/registrars/index.d.ts +7 -0
- package/dist/registrars/index.d.ts.map +1 -0
- package/dist/registrars/index.js +15 -0
- package/dist/registrars/index.js.map +1 -0
- package/dist/registrars/namecheap.d.ts +69 -0
- package/dist/registrars/namecheap.d.ts.map +1 -0
- package/dist/registrars/namecheap.js +307 -0
- package/dist/registrars/namecheap.js.map +1 -0
- package/dist/registrars/porkbun.d.ts +63 -0
- package/dist/registrars/porkbun.d.ts.map +1 -0
- package/dist/registrars/porkbun.js +299 -0
- package/dist/registrars/porkbun.js.map +1 -0
- package/dist/server.d.ts +19 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +209 -0
- package/dist/server.js.map +1 -0
- package/dist/services/domain-search.d.ts +40 -0
- package/dist/services/domain-search.d.ts.map +1 -0
- package/dist/services/domain-search.js +438 -0
- package/dist/services/domain-search.js.map +1 -0
- package/dist/services/index.d.ts +5 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +11 -0
- package/dist/services/index.js.map +1 -0
- package/dist/tools/bulk_search.d.ts +72 -0
- package/dist/tools/bulk_search.d.ts.map +1 -0
- package/dist/tools/bulk_search.js +108 -0
- package/dist/tools/bulk_search.js.map +1 -0
- package/dist/tools/check_socials.d.ts +71 -0
- package/dist/tools/check_socials.d.ts.map +1 -0
- package/dist/tools/check_socials.js +357 -0
- package/dist/tools/check_socials.js.map +1 -0
- package/dist/tools/compare_registrars.d.ts +80 -0
- package/dist/tools/compare_registrars.d.ts.map +1 -0
- package/dist/tools/compare_registrars.js +116 -0
- package/dist/tools/compare_registrars.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +31 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/search_domain.d.ts +61 -0
- package/dist/tools/search_domain.d.ts.map +1 -0
- package/dist/tools/search_domain.js +81 -0
- package/dist/tools/search_domain.js.map +1 -0
- package/dist/tools/suggest_domains.d.ts +82 -0
- package/dist/tools/suggest_domains.d.ts.map +1 -0
- package/dist/tools/suggest_domains.js +227 -0
- package/dist/tools/suggest_domains.js.map +1 -0
- package/dist/tools/tld_info.d.ts +56 -0
- package/dist/tools/tld_info.d.ts.map +1 -0
- package/dist/tools/tld_info.js +273 -0
- package/dist/tools/tld_info.js.map +1 -0
- package/dist/types.d.ts +193 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cache.d.ts +81 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +192 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/errors.d.ts +87 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +191 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +24 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +27 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +132 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/premium-analyzer.d.ts +33 -0
- package/dist/utils/premium-analyzer.d.ts.map +1 -0
- package/dist/utils/premium-analyzer.js +273 -0
- package/dist/utils/premium-analyzer.js.map +1 -0
- package/dist/utils/validators.d.ts +53 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +159 -0
- package/dist/utils/validators.js.map +1 -0
- package/docs/marketing/devto-post.md +135 -0
- package/docs/marketing/hackernews.md +42 -0
- package/docs/marketing/producthunt.md +109 -0
- package/docs/marketing/reddit-post.md +59 -0
- package/docs/marketing/twitter-thread.md +105 -0
- package/examples/bulk-search-50-domains.ts +131 -0
- package/examples/cli-interactive.ts +280 -0
- package/examples/compare-registrars.ts +78 -0
- package/examples/search-single-domain.ts +54 -0
- package/examples/suggest-names.ts +110 -0
- package/glama.json +6 -0
- package/jest.config.js +35 -0
- package/package.json +62 -0
- package/smithery.yaml +36 -0
- package/src/config.ts +121 -0
- package/src/fallbacks/index.ts +6 -0
- package/src/fallbacks/rdap.ts +407 -0
- package/src/fallbacks/whois.ts +250 -0
- package/src/registrars/base.ts +264 -0
- package/src/registrars/index.ts +7 -0
- package/src/registrars/namecheap.ts +378 -0
- package/src/registrars/porkbun.ts +380 -0
- package/src/server.ts +276 -0
- package/src/services/domain-search.ts +567 -0
- package/src/services/index.ts +9 -0
- package/src/tools/bulk_search.ts +142 -0
- package/src/tools/check_socials.ts +467 -0
- package/src/tools/compare_registrars.ts +162 -0
- package/src/tools/index.ts +45 -0
- package/src/tools/search_domain.ts +93 -0
- package/src/tools/suggest_domains.ts +284 -0
- package/src/tools/tld_info.ts +294 -0
- package/src/types.ts +289 -0
- package/src/utils/cache.ts +238 -0
- package/src/utils/errors.ts +262 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/logger.ts +162 -0
- package/src/utils/premium-analyzer.ts +303 -0
- package/src/utils/validators.ts +193 -0
- package/tests/premium-analyzer.test.ts +310 -0
- package/tests/unit/cache.test.ts +123 -0
- package/tests/unit/errors.test.ts +190 -0
- package/tests/unit/tld-info.test.ts +62 -0
- package/tests/unit/tools.test.ts +200 -0
- package/tests/unit/validators.test.ts +146 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Registrar Adapter.
|
|
3
|
+
*
|
|
4
|
+
* Abstract class that all registrar adapters extend.
|
|
5
|
+
* Provides common functionality:
|
|
6
|
+
* - Rate limiting (token bucket)
|
|
7
|
+
* - Retry with exponential backoff
|
|
8
|
+
* - Error handling and logging
|
|
9
|
+
*/
|
|
10
|
+
import type { DomainResult, TLDInfo } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Token bucket rate limiter.
|
|
13
|
+
*/
|
|
14
|
+
export declare class RateLimiter {
|
|
15
|
+
private tokens;
|
|
16
|
+
private readonly maxTokens;
|
|
17
|
+
private readonly refillRate;
|
|
18
|
+
private lastRefill;
|
|
19
|
+
constructor(maxPerMinute?: number);
|
|
20
|
+
/**
|
|
21
|
+
* Try to consume a token. Returns true if successful.
|
|
22
|
+
*/
|
|
23
|
+
tryConsume(): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Wait until a token is available.
|
|
26
|
+
*/
|
|
27
|
+
waitForToken(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Refill tokens based on elapsed time.
|
|
30
|
+
*/
|
|
31
|
+
private refill;
|
|
32
|
+
/**
|
|
33
|
+
* Get seconds until next token is available.
|
|
34
|
+
*/
|
|
35
|
+
getWaitSeconds(): number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Abstract base class for registrar adapters.
|
|
39
|
+
*/
|
|
40
|
+
export declare abstract class RegistrarAdapter {
|
|
41
|
+
/** Human-readable name of the registrar */
|
|
42
|
+
abstract readonly name: string;
|
|
43
|
+
/** Identifier used in results */
|
|
44
|
+
abstract readonly id: string;
|
|
45
|
+
/** Rate limiter for this registrar */
|
|
46
|
+
protected readonly rateLimiter: RateLimiter;
|
|
47
|
+
/** Max retry attempts */
|
|
48
|
+
protected readonly maxRetries: number;
|
|
49
|
+
/** Base delay for exponential backoff (ms) */
|
|
50
|
+
protected readonly baseDelayMs: number;
|
|
51
|
+
/** Request timeout (ms) */
|
|
52
|
+
protected readonly timeoutMs: number;
|
|
53
|
+
constructor(requestsPerMinute?: number);
|
|
54
|
+
/**
|
|
55
|
+
* Check domain availability and get pricing.
|
|
56
|
+
* This is the main method each adapter must implement.
|
|
57
|
+
*/
|
|
58
|
+
abstract search(domain: string, tld: string): Promise<DomainResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Get information about a TLD.
|
|
61
|
+
* Optional - not all registrars provide this.
|
|
62
|
+
*/
|
|
63
|
+
abstract getTldInfo(tld: string): Promise<TLDInfo | null>;
|
|
64
|
+
/**
|
|
65
|
+
* Check if this adapter is enabled (has required credentials).
|
|
66
|
+
*/
|
|
67
|
+
abstract isEnabled(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Execute a function with rate limiting.
|
|
70
|
+
*/
|
|
71
|
+
protected rateLimitedCall<T>(fn: () => Promise<T>): Promise<T>;
|
|
72
|
+
/**
|
|
73
|
+
* Execute with retry and exponential backoff.
|
|
74
|
+
*/
|
|
75
|
+
protected retryWithBackoff<T>(fn: () => Promise<T>, operation: string): Promise<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Create a timeout wrapper for a promise.
|
|
78
|
+
*/
|
|
79
|
+
protected withTimeout<T>(promise: Promise<T>, operation: string, timeoutMs?: number): Promise<T>;
|
|
80
|
+
/**
|
|
81
|
+
* Log an error with context.
|
|
82
|
+
*/
|
|
83
|
+
protected logError(error: Error, context?: Record<string, unknown>): void;
|
|
84
|
+
/**
|
|
85
|
+
* Create a standardized DomainResult.
|
|
86
|
+
*/
|
|
87
|
+
protected createResult(domain: string, tld: string, data: Partial<DomainResult>): DomainResult;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/registrars/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAUzD;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,UAAU,CAAS;gBAEf,YAAY,GAAE,MAAW;IAOrC;;OAEG;IACH,UAAU,IAAI,OAAO;IAWrB;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAQnC;;OAEG;IACH,OAAO,CAAC,MAAM;IASd;;OAEG;IACH,cAAc,IAAI,MAAM;CAKzB;AASD;;GAEG;AACH,8BAAsB,gBAAgB;IACpC,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAE7B,sCAAsC;IACtC,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAE5C,yBAAyB;IACzB,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAK;IAE1C,8CAA8C;IAC9C,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAQ;IAE9C,2BAA2B;IAC3B,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAS;gBAEjC,iBAAiB,GAAE,MAAW;IAI1C;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAEnE;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAEzD;;OAEG;IACH,QAAQ,CAAC,SAAS,IAAI,OAAO;IAE7B;;OAEG;cACa,eAAe,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAgBpE;;OAEG;cACa,gBAAgB,CAAC,CAAC,EAChC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,CAAC,CAAC;IA6Cb;;OAEG;IACH,SAAS,CAAC,WAAW,CAAC,CAAC,EACrB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAuB,GACjC,OAAO,CAAC,CAAC,CAAC;IAkBb;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAOzE;;OAEG;IACH,SAAS,CAAC,YAAY,CACpB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,GAC1B,YAAY;CAkBhB"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Base Registrar Adapter.
|
|
4
|
+
*
|
|
5
|
+
* Abstract class that all registrar adapters extend.
|
|
6
|
+
* Provides common functionality:
|
|
7
|
+
* - Rate limiting (token bucket)
|
|
8
|
+
* - Retry with exponential backoff
|
|
9
|
+
* - Error handling and logging
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.RegistrarAdapter = exports.RateLimiter = void 0;
|
|
13
|
+
const logger_js_1 = require("../utils/logger.js");
|
|
14
|
+
const errors_js_1 = require("../utils/errors.js");
|
|
15
|
+
const config_js_1 = require("../config.js");
|
|
16
|
+
/**
|
|
17
|
+
* Token bucket rate limiter.
|
|
18
|
+
*/
|
|
19
|
+
class RateLimiter {
|
|
20
|
+
tokens;
|
|
21
|
+
maxTokens;
|
|
22
|
+
refillRate; // tokens per second
|
|
23
|
+
lastRefill;
|
|
24
|
+
constructor(maxPerMinute = 60) {
|
|
25
|
+
this.maxTokens = maxPerMinute;
|
|
26
|
+
this.tokens = maxPerMinute;
|
|
27
|
+
this.refillRate = maxPerMinute / 60; // Convert to per-second
|
|
28
|
+
this.lastRefill = Date.now();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Try to consume a token. Returns true if successful.
|
|
32
|
+
*/
|
|
33
|
+
tryConsume() {
|
|
34
|
+
this.refill();
|
|
35
|
+
if (this.tokens >= 1) {
|
|
36
|
+
this.tokens -= 1;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Wait until a token is available.
|
|
43
|
+
*/
|
|
44
|
+
async waitForToken() {
|
|
45
|
+
while (!this.tryConsume()) {
|
|
46
|
+
// Calculate wait time for next token
|
|
47
|
+
const waitMs = Math.ceil(1000 / this.refillRate);
|
|
48
|
+
await sleep(waitMs);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Refill tokens based on elapsed time.
|
|
53
|
+
*/
|
|
54
|
+
refill() {
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
const elapsed = (now - this.lastRefill) / 1000;
|
|
57
|
+
const refillAmount = elapsed * this.refillRate;
|
|
58
|
+
this.tokens = Math.min(this.maxTokens, this.tokens + refillAmount);
|
|
59
|
+
this.lastRefill = now;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get seconds until next token is available.
|
|
63
|
+
*/
|
|
64
|
+
getWaitSeconds() {
|
|
65
|
+
if (this.tokens >= 1)
|
|
66
|
+
return 0;
|
|
67
|
+
const neededTokens = 1 - this.tokens;
|
|
68
|
+
return Math.ceil(neededTokens / this.refillRate);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.RateLimiter = RateLimiter;
|
|
72
|
+
/**
|
|
73
|
+
* Sleep helper.
|
|
74
|
+
*/
|
|
75
|
+
function sleep(ms) {
|
|
76
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Abstract base class for registrar adapters.
|
|
80
|
+
*/
|
|
81
|
+
class RegistrarAdapter {
|
|
82
|
+
/** Rate limiter for this registrar */
|
|
83
|
+
rateLimiter;
|
|
84
|
+
/** Max retry attempts */
|
|
85
|
+
maxRetries = 3;
|
|
86
|
+
/** Base delay for exponential backoff (ms) */
|
|
87
|
+
baseDelayMs = 2000;
|
|
88
|
+
/** Request timeout (ms) */
|
|
89
|
+
timeoutMs = 10000;
|
|
90
|
+
constructor(requestsPerMinute = 60) {
|
|
91
|
+
this.rateLimiter = new RateLimiter(requestsPerMinute);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Execute a function with rate limiting.
|
|
95
|
+
*/
|
|
96
|
+
async rateLimitedCall(fn) {
|
|
97
|
+
// Check if we should even try (dry run mode)
|
|
98
|
+
if (config_js_1.config.dryRun) {
|
|
99
|
+
throw new errors_js_1.RegistrarApiError(this.name, 'Dry run mode - no API calls made');
|
|
100
|
+
}
|
|
101
|
+
// Wait for rate limit
|
|
102
|
+
const waitSeconds = this.rateLimiter.getWaitSeconds();
|
|
103
|
+
if (waitSeconds > 0) {
|
|
104
|
+
logger_js_1.logger.debug(`Rate limiting: waiting ${waitSeconds}s for ${this.name}`);
|
|
105
|
+
}
|
|
106
|
+
await this.rateLimiter.waitForToken();
|
|
107
|
+
return fn();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Execute with retry and exponential backoff.
|
|
111
|
+
*/
|
|
112
|
+
async retryWithBackoff(fn, operation) {
|
|
113
|
+
let lastError;
|
|
114
|
+
for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
|
|
115
|
+
try {
|
|
116
|
+
return await this.rateLimitedCall(fn);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
120
|
+
// Check if we should retry
|
|
121
|
+
const wrapped = (0, errors_js_1.wrapError)(error);
|
|
122
|
+
if (!wrapped.retryable) {
|
|
123
|
+
throw wrapped;
|
|
124
|
+
}
|
|
125
|
+
// Check if it's a rate limit error with retry-after
|
|
126
|
+
if (error instanceof errors_js_1.RateLimitError && error.retryAfter) {
|
|
127
|
+
const waitMs = error.retryAfter - Date.now();
|
|
128
|
+
if (waitMs > 0 && waitMs < 60000) {
|
|
129
|
+
logger_js_1.logger.info(`Rate limited, waiting ${waitMs}ms`, {
|
|
130
|
+
registrar: this.name,
|
|
131
|
+
attempt,
|
|
132
|
+
});
|
|
133
|
+
await sleep(waitMs);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Exponential backoff
|
|
138
|
+
if (attempt < this.maxRetries) {
|
|
139
|
+
const delay = this.baseDelayMs * Math.pow(2, attempt - 1);
|
|
140
|
+
logger_js_1.logger.warn(`Retry ${attempt}/${this.maxRetries} for ${operation}`, {
|
|
141
|
+
registrar: this.name,
|
|
142
|
+
delay_ms: delay,
|
|
143
|
+
error: lastError.message,
|
|
144
|
+
});
|
|
145
|
+
await sleep(delay);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// All retries failed
|
|
150
|
+
throw lastError || new Error(`Failed after ${this.maxRetries} retries`);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create a timeout wrapper for a promise.
|
|
154
|
+
*/
|
|
155
|
+
withTimeout(promise, operation, timeoutMs = this.timeoutMs) {
|
|
156
|
+
return new Promise((resolve, reject) => {
|
|
157
|
+
const timer = setTimeout(() => {
|
|
158
|
+
reject(new errors_js_1.TimeoutError(operation, timeoutMs));
|
|
159
|
+
}, timeoutMs);
|
|
160
|
+
promise
|
|
161
|
+
.then((result) => {
|
|
162
|
+
clearTimeout(timer);
|
|
163
|
+
resolve(result);
|
|
164
|
+
})
|
|
165
|
+
.catch((error) => {
|
|
166
|
+
clearTimeout(timer);
|
|
167
|
+
reject(error);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Log an error with context.
|
|
173
|
+
*/
|
|
174
|
+
logError(error, context) {
|
|
175
|
+
logger_js_1.logger.logError(`${this.name} error`, error, {
|
|
176
|
+
registrar: this.id,
|
|
177
|
+
...context,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Create a standardized DomainResult.
|
|
182
|
+
*/
|
|
183
|
+
createResult(domain, tld, data) {
|
|
184
|
+
return {
|
|
185
|
+
domain: `${domain}.${tld}`,
|
|
186
|
+
available: data.available ?? false,
|
|
187
|
+
premium: data.premium ?? false,
|
|
188
|
+
price_first_year: data.price_first_year ?? null,
|
|
189
|
+
price_renewal: data.price_renewal ?? null,
|
|
190
|
+
currency: data.currency ?? 'USD',
|
|
191
|
+
privacy_included: data.privacy_included ?? false,
|
|
192
|
+
transfer_price: data.transfer_price ?? null,
|
|
193
|
+
registrar: this.id,
|
|
194
|
+
source: data.source ?? `${this.id}_api`,
|
|
195
|
+
checked_at: new Date().toISOString(),
|
|
196
|
+
premium_reason: data.premium_reason,
|
|
197
|
+
tld_restrictions: data.tld_restrictions,
|
|
198
|
+
score: data.score,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
exports.RegistrarAdapter = RegistrarAdapter;
|
|
203
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/registrars/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/registrars/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Registrar Exports.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.namecheapAdapter = exports.NamecheapAdapter = exports.porkbunAdapter = exports.PorkbunAdapter = exports.RegistrarAdapter = void 0;
|
|
7
|
+
var base_js_1 = require("./base.js");
|
|
8
|
+
Object.defineProperty(exports, "RegistrarAdapter", { enumerable: true, get: function () { return base_js_1.RegistrarAdapter; } });
|
|
9
|
+
var porkbun_js_1 = require("./porkbun.js");
|
|
10
|
+
Object.defineProperty(exports, "PorkbunAdapter", { enumerable: true, get: function () { return porkbun_js_1.PorkbunAdapter; } });
|
|
11
|
+
Object.defineProperty(exports, "porkbunAdapter", { enumerable: true, get: function () { return porkbun_js_1.porkbunAdapter; } });
|
|
12
|
+
var namecheap_js_1 = require("./namecheap.js");
|
|
13
|
+
Object.defineProperty(exports, "NamecheapAdapter", { enumerable: true, get: function () { return namecheap_js_1.NamecheapAdapter; } });
|
|
14
|
+
Object.defineProperty(exports, "namecheapAdapter", { enumerable: true, get: function () { return namecheap_js_1.namecheapAdapter; } });
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/registrars/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AACzB,2CAA8D;AAArD,4GAAA,cAAc,OAAA;AAAE,4GAAA,cAAc,OAAA;AACvC,+CAAoE;AAA3D,gHAAA,gBAAgB,OAAA;AAAE,gHAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Namecheap Registrar Adapter.
|
|
3
|
+
*
|
|
4
|
+
* Namecheap uses an XML-based API.
|
|
5
|
+
* API Docs: https://www.namecheap.com/support/api/intro/
|
|
6
|
+
*
|
|
7
|
+
* Note: Namecheap requires IP whitelisting for API access.
|
|
8
|
+
*/
|
|
9
|
+
import { RegistrarAdapter } from './base.js';
|
|
10
|
+
import type { DomainResult, TLDInfo } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Namecheap adapter implementation.
|
|
13
|
+
*/
|
|
14
|
+
export declare class NamecheapAdapter extends RegistrarAdapter {
|
|
15
|
+
readonly name = "Namecheap";
|
|
16
|
+
readonly id = "namecheap";
|
|
17
|
+
private readonly client;
|
|
18
|
+
private readonly apiKey?;
|
|
19
|
+
private readonly apiUser?;
|
|
20
|
+
private readonly useSandbox;
|
|
21
|
+
constructor();
|
|
22
|
+
/**
|
|
23
|
+
* Check if Namecheap API is enabled.
|
|
24
|
+
*/
|
|
25
|
+
isEnabled(): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Search for domain availability.
|
|
28
|
+
*/
|
|
29
|
+
search(domain: string, tld: string): Promise<DomainResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Parse the check response XML.
|
|
32
|
+
* SECURITY: Validates parsed result with Zod schema.
|
|
33
|
+
*/
|
|
34
|
+
private parseCheckResponse;
|
|
35
|
+
/**
|
|
36
|
+
* Get TLD information.
|
|
37
|
+
*/
|
|
38
|
+
getTldInfo(tld: string): Promise<TLDInfo | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Get client IP for API requests.
|
|
41
|
+
* Namecheap requires this for all API calls.
|
|
42
|
+
*
|
|
43
|
+
* SECURITY: We no longer call external services (ipify.org) to get IP.
|
|
44
|
+
* The IP must be configured via NAMECHEAP_CLIENT_IP environment variable.
|
|
45
|
+
* This prevents unintended IP disclosure to third parties.
|
|
46
|
+
*/
|
|
47
|
+
private getClientIp;
|
|
48
|
+
/**
|
|
49
|
+
* Handle API errors with user-friendly messages.
|
|
50
|
+
*/
|
|
51
|
+
private handleApiError;
|
|
52
|
+
/**
|
|
53
|
+
* Get typical use case for a TLD.
|
|
54
|
+
*/
|
|
55
|
+
private getTldUseCase;
|
|
56
|
+
/**
|
|
57
|
+
* Get TLD popularity rating.
|
|
58
|
+
*/
|
|
59
|
+
private getTldPopularity;
|
|
60
|
+
/**
|
|
61
|
+
* Get TLD category.
|
|
62
|
+
*/
|
|
63
|
+
private getTldCategory;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Singleton instance.
|
|
67
|
+
*/
|
|
68
|
+
export declare const namecheapAdapter: NamecheapAdapter;
|
|
69
|
+
//# sourceMappingURL=namecheap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namecheap.d.ts","sourceRoot":"","sources":["../../src/registrars/namecheap.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA4FzD;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB;IACpD,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,EAAE,eAAe;IAE1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;;IAkBrC;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA0ChE;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA6C1B;;OAEG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAmBtD;;;;;;;OAOG;IACH,OAAO,CAAC,WAAW;IAwBnB;;OAEG;IACH,OAAO,CAAC,cAAc;IAyCtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACH,OAAO,CAAC,cAAc;CAUvB;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
|