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.
Files changed (151) hide show
  1. package/.env.example +52 -0
  2. package/Dockerfile +15 -0
  3. package/LICENSE +21 -0
  4. package/README.md +426 -0
  5. package/SECURITY.md +252 -0
  6. package/dist/config.d.ts +25 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +117 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/fallbacks/index.d.ts +6 -0
  11. package/dist/fallbacks/index.d.ts.map +1 -0
  12. package/dist/fallbacks/index.js +14 -0
  13. package/dist/fallbacks/index.js.map +1 -0
  14. package/dist/fallbacks/rdap.d.ts +18 -0
  15. package/dist/fallbacks/rdap.d.ts.map +1 -0
  16. package/dist/fallbacks/rdap.js +339 -0
  17. package/dist/fallbacks/rdap.js.map +1 -0
  18. package/dist/fallbacks/whois.d.ts +27 -0
  19. package/dist/fallbacks/whois.d.ts.map +1 -0
  20. package/dist/fallbacks/whois.js +219 -0
  21. package/dist/fallbacks/whois.js.map +1 -0
  22. package/dist/registrars/base.d.ts +89 -0
  23. package/dist/registrars/base.d.ts.map +1 -0
  24. package/dist/registrars/base.js +203 -0
  25. package/dist/registrars/base.js.map +1 -0
  26. package/dist/registrars/index.d.ts +7 -0
  27. package/dist/registrars/index.d.ts.map +1 -0
  28. package/dist/registrars/index.js +15 -0
  29. package/dist/registrars/index.js.map +1 -0
  30. package/dist/registrars/namecheap.d.ts +69 -0
  31. package/dist/registrars/namecheap.d.ts.map +1 -0
  32. package/dist/registrars/namecheap.js +307 -0
  33. package/dist/registrars/namecheap.js.map +1 -0
  34. package/dist/registrars/porkbun.d.ts +63 -0
  35. package/dist/registrars/porkbun.d.ts.map +1 -0
  36. package/dist/registrars/porkbun.js +299 -0
  37. package/dist/registrars/porkbun.js.map +1 -0
  38. package/dist/server.d.ts +19 -0
  39. package/dist/server.d.ts.map +1 -0
  40. package/dist/server.js +209 -0
  41. package/dist/server.js.map +1 -0
  42. package/dist/services/domain-search.d.ts +40 -0
  43. package/dist/services/domain-search.d.ts.map +1 -0
  44. package/dist/services/domain-search.js +438 -0
  45. package/dist/services/domain-search.js.map +1 -0
  46. package/dist/services/index.d.ts +5 -0
  47. package/dist/services/index.d.ts.map +1 -0
  48. package/dist/services/index.js +11 -0
  49. package/dist/services/index.js.map +1 -0
  50. package/dist/tools/bulk_search.d.ts +72 -0
  51. package/dist/tools/bulk_search.d.ts.map +1 -0
  52. package/dist/tools/bulk_search.js +108 -0
  53. package/dist/tools/bulk_search.js.map +1 -0
  54. package/dist/tools/check_socials.d.ts +71 -0
  55. package/dist/tools/check_socials.d.ts.map +1 -0
  56. package/dist/tools/check_socials.js +357 -0
  57. package/dist/tools/check_socials.js.map +1 -0
  58. package/dist/tools/compare_registrars.d.ts +80 -0
  59. package/dist/tools/compare_registrars.d.ts.map +1 -0
  60. package/dist/tools/compare_registrars.js +116 -0
  61. package/dist/tools/compare_registrars.js.map +1 -0
  62. package/dist/tools/index.d.ts +10 -0
  63. package/dist/tools/index.d.ts.map +1 -0
  64. package/dist/tools/index.js +31 -0
  65. package/dist/tools/index.js.map +1 -0
  66. package/dist/tools/search_domain.d.ts +61 -0
  67. package/dist/tools/search_domain.d.ts.map +1 -0
  68. package/dist/tools/search_domain.js +81 -0
  69. package/dist/tools/search_domain.js.map +1 -0
  70. package/dist/tools/suggest_domains.d.ts +82 -0
  71. package/dist/tools/suggest_domains.d.ts.map +1 -0
  72. package/dist/tools/suggest_domains.js +227 -0
  73. package/dist/tools/suggest_domains.js.map +1 -0
  74. package/dist/tools/tld_info.d.ts +56 -0
  75. package/dist/tools/tld_info.d.ts.map +1 -0
  76. package/dist/tools/tld_info.js +273 -0
  77. package/dist/tools/tld_info.js.map +1 -0
  78. package/dist/types.d.ts +193 -0
  79. package/dist/types.d.ts.map +1 -0
  80. package/dist/types.js +9 -0
  81. package/dist/types.js.map +1 -0
  82. package/dist/utils/cache.d.ts +81 -0
  83. package/dist/utils/cache.d.ts.map +1 -0
  84. package/dist/utils/cache.js +192 -0
  85. package/dist/utils/cache.js.map +1 -0
  86. package/dist/utils/errors.d.ts +87 -0
  87. package/dist/utils/errors.d.ts.map +1 -0
  88. package/dist/utils/errors.js +191 -0
  89. package/dist/utils/errors.js.map +1 -0
  90. package/dist/utils/index.d.ts +8 -0
  91. package/dist/utils/index.d.ts.map +1 -0
  92. package/dist/utils/index.js +24 -0
  93. package/dist/utils/index.js.map +1 -0
  94. package/dist/utils/logger.d.ts +27 -0
  95. package/dist/utils/logger.d.ts.map +1 -0
  96. package/dist/utils/logger.js +132 -0
  97. package/dist/utils/logger.js.map +1 -0
  98. package/dist/utils/premium-analyzer.d.ts +33 -0
  99. package/dist/utils/premium-analyzer.d.ts.map +1 -0
  100. package/dist/utils/premium-analyzer.js +273 -0
  101. package/dist/utils/premium-analyzer.js.map +1 -0
  102. package/dist/utils/validators.d.ts +53 -0
  103. package/dist/utils/validators.d.ts.map +1 -0
  104. package/dist/utils/validators.js +159 -0
  105. package/dist/utils/validators.js.map +1 -0
  106. package/docs/marketing/devto-post.md +135 -0
  107. package/docs/marketing/hackernews.md +42 -0
  108. package/docs/marketing/producthunt.md +109 -0
  109. package/docs/marketing/reddit-post.md +59 -0
  110. package/docs/marketing/twitter-thread.md +105 -0
  111. package/examples/bulk-search-50-domains.ts +131 -0
  112. package/examples/cli-interactive.ts +280 -0
  113. package/examples/compare-registrars.ts +78 -0
  114. package/examples/search-single-domain.ts +54 -0
  115. package/examples/suggest-names.ts +110 -0
  116. package/glama.json +6 -0
  117. package/jest.config.js +35 -0
  118. package/package.json +62 -0
  119. package/smithery.yaml +36 -0
  120. package/src/config.ts +121 -0
  121. package/src/fallbacks/index.ts +6 -0
  122. package/src/fallbacks/rdap.ts +407 -0
  123. package/src/fallbacks/whois.ts +250 -0
  124. package/src/registrars/base.ts +264 -0
  125. package/src/registrars/index.ts +7 -0
  126. package/src/registrars/namecheap.ts +378 -0
  127. package/src/registrars/porkbun.ts +380 -0
  128. package/src/server.ts +276 -0
  129. package/src/services/domain-search.ts +567 -0
  130. package/src/services/index.ts +9 -0
  131. package/src/tools/bulk_search.ts +142 -0
  132. package/src/tools/check_socials.ts +467 -0
  133. package/src/tools/compare_registrars.ts +162 -0
  134. package/src/tools/index.ts +45 -0
  135. package/src/tools/search_domain.ts +93 -0
  136. package/src/tools/suggest_domains.ts +284 -0
  137. package/src/tools/tld_info.ts +294 -0
  138. package/src/types.ts +289 -0
  139. package/src/utils/cache.ts +238 -0
  140. package/src/utils/errors.ts +262 -0
  141. package/src/utils/index.ts +8 -0
  142. package/src/utils/logger.ts +162 -0
  143. package/src/utils/premium-analyzer.ts +303 -0
  144. package/src/utils/validators.ts +193 -0
  145. package/tests/premium-analyzer.test.ts +310 -0
  146. package/tests/unit/cache.test.ts +123 -0
  147. package/tests/unit/errors.test.ts +190 -0
  148. package/tests/unit/tld-info.test.ts +62 -0
  149. package/tests/unit/tools.test.ts +200 -0
  150. package/tests/unit/validators.test.ts +146 -0
  151. package/tsconfig.json +25 -0
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * Structured JSON Logger with Secret Masking.
4
+ *
5
+ * - Outputs JSON for easy parsing
6
+ * - Masks API keys and secrets automatically
7
+ * - Includes request IDs for tracing
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.logger = void 0;
11
+ exports.generateRequestId = generateRequestId;
12
+ exports.setRequestId = setRequestId;
13
+ exports.clearRequestId = clearRequestId;
14
+ const config_js_1 = require("../config.js");
15
+ /**
16
+ * Patterns that look like API keys or secrets.
17
+ * These will be masked in log output.
18
+ */
19
+ const SECRET_PATTERNS = [
20
+ // Long alphanumeric strings (likely API keys)
21
+ /\b[a-zA-Z0-9]{32,}\b/g,
22
+ // Patterns that look like secrets
23
+ /(?:api[_-]?key|secret|password|token)[\s:="']+[^\s"']+/gi,
24
+ ];
25
+ /**
26
+ * Mask sensitive data in a value.
27
+ */
28
+ function maskSecrets(value) {
29
+ if (typeof value === 'string') {
30
+ let masked = value;
31
+ for (const pattern of SECRET_PATTERNS) {
32
+ masked = masked.replace(pattern, '[REDACTED]');
33
+ }
34
+ return masked;
35
+ }
36
+ if (Array.isArray(value)) {
37
+ return value.map(maskSecrets);
38
+ }
39
+ if (value && typeof value === 'object') {
40
+ const maskedObj = {};
41
+ for (const [key, val] of Object.entries(value)) {
42
+ // Always mask keys that look like secrets
43
+ const lowerKey = key.toLowerCase();
44
+ if (lowerKey.includes('secret') ||
45
+ lowerKey.includes('password') ||
46
+ lowerKey.includes('apikey') ||
47
+ lowerKey.includes('api_key') ||
48
+ lowerKey.includes('token')) {
49
+ maskedObj[key] = '[REDACTED]';
50
+ }
51
+ else {
52
+ maskedObj[key] = maskSecrets(val);
53
+ }
54
+ }
55
+ return maskedObj;
56
+ }
57
+ return value;
58
+ }
59
+ /**
60
+ * Log level priority for filtering.
61
+ */
62
+ const LOG_LEVELS = {
63
+ debug: 0,
64
+ info: 1,
65
+ warn: 2,
66
+ error: 3,
67
+ };
68
+ /**
69
+ * Should this level be logged?
70
+ */
71
+ function shouldLog(level) {
72
+ return LOG_LEVELS[level] >= LOG_LEVELS[config_js_1.config.logLevel];
73
+ }
74
+ /**
75
+ * Generate a unique request ID.
76
+ */
77
+ function generateRequestId() {
78
+ return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
79
+ }
80
+ /**
81
+ * Current request context (for tracing).
82
+ */
83
+ let currentRequestId;
84
+ function setRequestId(id) {
85
+ currentRequestId = id;
86
+ }
87
+ function clearRequestId() {
88
+ currentRequestId = undefined;
89
+ }
90
+ /**
91
+ * Core logging function.
92
+ */
93
+ function log(level, message, data) {
94
+ if (!shouldLog(level))
95
+ return;
96
+ const entry = {
97
+ timestamp: new Date().toISOString(),
98
+ level,
99
+ message,
100
+ };
101
+ if (currentRequestId) {
102
+ entry.request_id = currentRequestId;
103
+ }
104
+ // Add and mask additional data
105
+ if (data) {
106
+ const masked = maskSecrets(data);
107
+ Object.assign(entry, masked);
108
+ }
109
+ // Output to stderr (MCP servers use stdout for protocol)
110
+ console.error(JSON.stringify(entry));
111
+ }
112
+ /**
113
+ * Logger instance with convenience methods.
114
+ */
115
+ exports.logger = {
116
+ debug: (message, data) => log('debug', message, data),
117
+ info: (message, data) => log('info', message, data),
118
+ warn: (message, data) => log('warn', message, data),
119
+ error: (message, data) => log('error', message, data),
120
+ /**
121
+ * Log an error with stack trace.
122
+ */
123
+ logError: (message, error, data) => {
124
+ log('error', message, {
125
+ ...data,
126
+ error_name: error.name,
127
+ error_message: error.message,
128
+ error_stack: error.stack,
129
+ });
130
+ },
131
+ };
132
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAoFH,8CAEC;AAOD,oCAEC;AAED,wCAEC;AAjGD,4CAAsC;AAYtC;;;GAGG;AACH,MAAM,eAAe,GAAG;IACtB,8CAA8C;IAC9C,uBAAuB;IACvB,kCAAkC;IAClC,0DAA0D;CAC3D,CAAC;AAEF;;GAEG;AACH,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;YACtC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,SAAS,GAA4B,EAAE,CAAC;QAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,0CAA0C;YAC1C,MAAM,QAAQ,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YACnC,IACE,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC3B,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAC7B,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAC3B,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAC5B,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAC1B,CAAC;gBACD,SAAS,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,GAA6B;IAC3C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF;;GAEG;AACH,SAAS,SAAS,CAAC,KAAe;IAChC,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,kBAAM,CAAC,QAAQ,CAAC,CAAC;AAC1D,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB;IAC/B,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACpF,CAAC;AAED;;GAEG;AACH,IAAI,gBAAoC,CAAC;AAEzC,SAAgB,YAAY,CAAC,EAAU;IACrC,gBAAgB,GAAG,EAAE,CAAC;AACxB,CAAC;AAED,SAAgB,cAAc;IAC5B,gBAAgB,GAAG,SAAS,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAS,GAAG,CACV,KAAe,EACf,OAAe,EACf,IAA8B;IAE9B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE,OAAO;IAE9B,MAAM,KAAK,GAAa;QACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK;QACL,OAAO;KACR,CAAC;IAEF,IAAI,gBAAgB,EAAE,CAAC;QACrB,KAAK,CAAC,UAAU,GAAG,gBAAgB,CAAC;IACtC,CAAC;IAED,+BAA+B;IAC/B,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAA4B,CAAC;QAC5D,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,yDAAyD;IACzD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACU,QAAA,MAAM,GAAG;IACpB,KAAK,EAAE,CAAC,OAAe,EAAE,IAA8B,EAAE,EAAE,CACzD,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;IAC7B,IAAI,EAAE,CAAC,OAAe,EAAE,IAA8B,EAAE,EAAE,CACxD,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;IAC5B,IAAI,EAAE,CAAC,OAAe,EAAE,IAA8B,EAAE,EAAE,CACxD,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;IAC5B,KAAK,EAAE,CAAC,OAAe,EAAE,IAA8B,EAAE,EAAE,CACzD,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;IAE7B;;OAEG;IACH,QAAQ,EAAE,CAAC,OAAe,EAAE,KAAY,EAAE,IAA8B,EAAE,EAAE;QAC1E,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE;YACpB,GAAG,IAAI;YACP,UAAU,EAAE,KAAK,CAAC,IAAI;YACtB,aAAa,EAAE,KAAK,CAAC,OAAO;YAC5B,WAAW,EAAE,KAAK,CAAC,KAAK;SACzB,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Premium Domain Analyzer.
3
+ *
4
+ * Analyzes WHY a domain is premium and provides actionable insights.
5
+ * Premium domains are typically short, dictionary words, or popular keywords.
6
+ */
7
+ import type { DomainResult } from '../types.js';
8
+ /**
9
+ * Analyze why a domain might be premium.
10
+ */
11
+ export declare function analyzePremiumReason(domain: string): string[];
12
+ /**
13
+ * Generate detailed premium insights for a domain result.
14
+ */
15
+ export declare function generatePremiumInsight(result: DomainResult): string | null;
16
+ /**
17
+ * Suggest alternatives when a domain is premium.
18
+ */
19
+ export declare function suggestPremiumAlternatives(domain: string): string[];
20
+ /**
21
+ * Calculate a quality score for a domain result.
22
+ * Score factors:
23
+ * - Price competitiveness (vs standard pricing)
24
+ * - WHOIS privacy included
25
+ * - Renewal price reasonableness
26
+ * - Premium status (negative factor)
27
+ */
28
+ export declare function calculateDomainScore(result: DomainResult): number;
29
+ /**
30
+ * Generate insights summary for multiple premium domains.
31
+ */
32
+ export declare function generatePremiumSummary(results: DomainResult[]): string[];
33
+ //# sourceMappingURL=premium-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"premium-analyzer.d.ts","sourceRoot":"","sources":["../../src/utils/premium-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA2ChD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAgD7D;AAyBD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAgC1E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA8BnE;AAMD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAwCjE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CA+CxE"}
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ /**
3
+ * Premium Domain Analyzer.
4
+ *
5
+ * Analyzes WHY a domain is premium and provides actionable insights.
6
+ * Premium domains are typically short, dictionary words, or popular keywords.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.analyzePremiumReason = analyzePremiumReason;
10
+ exports.generatePremiumInsight = generatePremiumInsight;
11
+ exports.suggestPremiumAlternatives = suggestPremiumAlternatives;
12
+ exports.calculateDomainScore = calculateDomainScore;
13
+ exports.generatePremiumSummary = generatePremiumSummary;
14
+ // ═══════════════════════════════════════════════════════════════════════════
15
+ // Premium Reason Detection
16
+ // ═══════════════════════════════════════════════════════════════════════════
17
+ /**
18
+ * Common dictionary words that command premium prices.
19
+ * Based on analysis of premium domain sales.
20
+ */
21
+ const PREMIUM_KEYWORDS = new Set([
22
+ // Tech
23
+ 'ai', 'app', 'api', 'cloud', 'data', 'dev', 'tech', 'code', 'web', 'net',
24
+ 'cyber', 'crypto', 'nft', 'meta', 'virtual', 'digital', 'smart', 'auto',
25
+ // Business
26
+ 'buy', 'sell', 'shop', 'store', 'pay', 'cash', 'bank', 'money', 'invest',
27
+ 'trade', 'market', 'biz', 'pro', 'corp', 'inc', 'llc', 'hq', 'hub',
28
+ // Health/Life
29
+ 'health', 'fit', 'life', 'care', 'med', 'doc', 'bio', 'eco', 'green',
30
+ // Media
31
+ 'tv', 'fm', 'news', 'media', 'live', 'stream', 'video', 'music', 'art',
32
+ // Generic valuable
33
+ 'best', 'top', 'prime', 'elite', 'ultra', 'super', 'mega', 'max', 'plus',
34
+ 'one', 'first', 'go', 'get', 'my', 'the', 'now', 'new', 'next', 'hot',
35
+ ]);
36
+ /**
37
+ * TLDs known for having many premium domains.
38
+ */
39
+ const PREMIUM_HEAVY_TLDS = new Set([
40
+ 'io', 'ai', 'co', 'app', 'dev', 'xyz', 'club', 'online', 'site', 'tech',
41
+ ]);
42
+ /**
43
+ * Numeric patterns that are often premium.
44
+ */
45
+ const PREMIUM_NUMBER_PATTERNS = [
46
+ /^\d{1,3}$/, // 1-3 digit numbers (1, 99, 123)
47
+ /^(\d)\1+$/, // Repeating digits (111, 888)
48
+ /^12345?$/, // Sequential (123, 1234)
49
+ /^2[0-9]{3}$/, // Years (2024, 2025)
50
+ ];
51
+ /**
52
+ * Analyze why a domain might be premium.
53
+ */
54
+ function analyzePremiumReason(domain) {
55
+ const reasons = [];
56
+ const name = domain.split('.')[0].toLowerCase();
57
+ const tld = domain.split('.').pop().toLowerCase();
58
+ // Length-based premium
59
+ if (name.length === 1) {
60
+ reasons.push('Single character domain (extremely rare)');
61
+ }
62
+ else if (name.length === 2) {
63
+ reasons.push('Two-character domain (very rare)');
64
+ }
65
+ else if (name.length === 3) {
66
+ reasons.push('Three-character domain (short and memorable)');
67
+ }
68
+ else if (name.length === 4) {
69
+ reasons.push('Four-character domain (concise)');
70
+ }
71
+ // Dictionary word check
72
+ if (PREMIUM_KEYWORDS.has(name)) {
73
+ reasons.push(`Popular keyword "${name}"`);
74
+ }
75
+ // Numeric patterns
76
+ for (const pattern of PREMIUM_NUMBER_PATTERNS) {
77
+ if (pattern.test(name)) {
78
+ reasons.push('Valuable numeric pattern');
79
+ break;
80
+ }
81
+ }
82
+ // All letters same (aaa, bbb)
83
+ if (/^(.)\1+$/.test(name) && name.length <= 4) {
84
+ reasons.push('Repeating character pattern');
85
+ }
86
+ // Premium-heavy TLD
87
+ if (PREMIUM_HEAVY_TLDS.has(tld)) {
88
+ reasons.push(`High-demand .${tld} extension`);
89
+ }
90
+ // Acronym-style (all caps letters, 2-4 chars)
91
+ if (/^[a-z]{2,4}$/.test(name) && name.toUpperCase() === name.toUpperCase()) {
92
+ const couldBeAcronym = name.length <= 4 && !PREMIUM_KEYWORDS.has(name);
93
+ if (couldBeAcronym && reasons.length === 0) {
94
+ reasons.push('Potential acronym/initials');
95
+ }
96
+ }
97
+ return reasons;
98
+ }
99
+ // ═══════════════════════════════════════════════════════════════════════════
100
+ // Premium Insights Generation
101
+ // ═══════════════════════════════════════════════════════════════════════════
102
+ /**
103
+ * Standard TLD pricing for comparison (approximate first-year prices).
104
+ */
105
+ const STANDARD_TLD_PRICES = {
106
+ com: 10,
107
+ net: 12,
108
+ org: 12,
109
+ io: 40,
110
+ co: 25,
111
+ dev: 12,
112
+ app: 14,
113
+ ai: 80,
114
+ xyz: 3,
115
+ me: 8,
116
+ info: 5,
117
+ tech: 8,
118
+ cloud: 10,
119
+ };
120
+ /**
121
+ * Generate detailed premium insights for a domain result.
122
+ */
123
+ function generatePremiumInsight(result) {
124
+ if (!result.premium || !result.available) {
125
+ return null;
126
+ }
127
+ const domain = result.domain;
128
+ const tld = domain.split('.').pop();
129
+ const reasons = analyzePremiumReason(domain);
130
+ const standardPrice = STANDARD_TLD_PRICES[tld] || 15;
131
+ const parts = [];
132
+ // Price markup insight
133
+ if (result.price_first_year !== null) {
134
+ const markup = result.price_first_year / standardPrice;
135
+ if (markup >= 100) {
136
+ parts.push(`💎 ${domain} is priced at $${result.price_first_year} (${Math.round(markup)}x standard .${tld} pricing)`);
137
+ }
138
+ else if (markup >= 10) {
139
+ parts.push(`💰 ${domain} is priced at $${result.price_first_year} (${Math.round(markup)}x standard pricing)`);
140
+ }
141
+ else {
142
+ parts.push(`⚠️ ${domain} is a premium domain at $${result.price_first_year}`);
143
+ }
144
+ }
145
+ else {
146
+ parts.push(`⚠️ ${domain} is marked as premium (price varies)`);
147
+ }
148
+ // Why it's premium
149
+ if (reasons.length > 0) {
150
+ parts.push(`Why premium: ${reasons.join(', ')}`);
151
+ }
152
+ return parts.join(' — ');
153
+ }
154
+ /**
155
+ * Suggest alternatives when a domain is premium.
156
+ */
157
+ function suggestPremiumAlternatives(domain) {
158
+ const name = domain.split('.')[0];
159
+ const tld = domain.split('.').pop();
160
+ const suggestions = [];
161
+ // Prefix/suffix variations
162
+ const prefixes = ['get', 'try', 'use', 'my', 'the', 'go'];
163
+ const suffixes = ['app', 'hq', 'io', 'now', 'hub', 'labs'];
164
+ // Add a prefix
165
+ const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];
166
+ suggestions.push(`${prefix}${name}.${tld}`);
167
+ // Add a suffix
168
+ const suffix = suffixes[Math.floor(Math.random() * suffixes.length)];
169
+ suggestions.push(`${name}${suffix}.${tld}`);
170
+ // Try alternative TLDs (cheaper ones)
171
+ const cheaperTlds = ['co', 'dev', 'app', 'me', 'xyz'].filter(t => t !== tld);
172
+ if (cheaperTlds.length > 0) {
173
+ suggestions.push(`${name}.${cheaperTlds[0]}`);
174
+ }
175
+ // Double the last letter (creative variation)
176
+ if (name.length >= 3) {
177
+ const doubled = name + name[name.length - 1];
178
+ suggestions.push(`${doubled}.${tld}`);
179
+ }
180
+ return suggestions.slice(0, 3); // Max 3 suggestions
181
+ }
182
+ // ═══════════════════════════════════════════════════════════════════════════
183
+ // Domain Score Calculation
184
+ // ═══════════════════════════════════════════════════════════════════════════
185
+ /**
186
+ * Calculate a quality score for a domain result.
187
+ * Score factors:
188
+ * - Price competitiveness (vs standard pricing)
189
+ * - WHOIS privacy included
190
+ * - Renewal price reasonableness
191
+ * - Premium status (negative factor)
192
+ */
193
+ function calculateDomainScore(result) {
194
+ if (!result.available)
195
+ return 0;
196
+ let score = 5; // Base score
197
+ const tld = result.domain.split('.').pop();
198
+ const standardPrice = STANDARD_TLD_PRICES[tld] || 15;
199
+ // Price factor (0-3 points)
200
+ if (result.price_first_year !== null) {
201
+ const priceRatio = result.price_first_year / standardPrice;
202
+ if (priceRatio <= 0.5)
203
+ score += 3; // Great deal
204
+ else if (priceRatio <= 1.0)
205
+ score += 2; // Good price
206
+ else if (priceRatio <= 2.0)
207
+ score += 1; // Fair
208
+ else if (priceRatio > 5)
209
+ score -= 2; // Expensive
210
+ }
211
+ // Privacy included (+1 point)
212
+ if (result.privacy_included) {
213
+ score += 1;
214
+ }
215
+ // Renewal price check (+1 point if reasonable)
216
+ if (result.price_renewal !== null && result.price_first_year !== null) {
217
+ const renewalRatio = result.price_renewal / result.price_first_year;
218
+ if (renewalRatio <= 1.5)
219
+ score += 1; // Renewal is reasonable
220
+ }
221
+ // Premium penalty (-1 point)
222
+ if (result.premium) {
223
+ score -= 1;
224
+ }
225
+ // TLD popularity bonus
226
+ if (['com', 'io', 'dev', 'app', 'co'].includes(tld)) {
227
+ score += 0.5;
228
+ }
229
+ // Clamp to 0-10
230
+ return Math.max(0, Math.min(10, Math.round(score * 10) / 10));
231
+ }
232
+ /**
233
+ * Generate insights summary for multiple premium domains.
234
+ */
235
+ function generatePremiumSummary(results) {
236
+ const premiums = results.filter(r => r.premium && r.available);
237
+ if (premiums.length === 0)
238
+ return [];
239
+ const insights = [];
240
+ // Count by reason
241
+ const allReasons = premiums.flatMap(r => analyzePremiumReason(r.domain));
242
+ const reasonCounts = allReasons.reduce((acc, reason) => {
243
+ acc[reason] = (acc[reason] || 0) + 1;
244
+ return acc;
245
+ }, {});
246
+ // Most common reason
247
+ const topReason = Object.entries(reasonCounts)
248
+ .sort((a, b) => b[1] - a[1])[0];
249
+ if (topReason) {
250
+ insights.push(`💎 Premium domains detected: ${topReason[0]}`);
251
+ }
252
+ // Total premium price vs standard
253
+ const totalPremiumCost = premiums
254
+ .filter(p => p.price_first_year !== null)
255
+ .reduce((sum, p) => sum + (p.price_first_year || 0), 0);
256
+ const totalStandardCost = premiums
257
+ .reduce((sum, p) => {
258
+ const tld = p.domain.split('.').pop();
259
+ return sum + (STANDARD_TLD_PRICES[tld] || 15);
260
+ }, 0);
261
+ if (totalPremiumCost > 0 && totalPremiumCost > totalStandardCost * 2) {
262
+ insights.push(`💡 Premium pricing is ${Math.round(totalPremiumCost / totalStandardCost)}x standard — consider name variations`);
263
+ }
264
+ // Suggest alternatives if all are premium
265
+ if (premiums.length === results.filter(r => r.available).length && premiums.length > 0) {
266
+ const alternatives = suggestPremiumAlternatives(premiums[0].domain);
267
+ if (alternatives.length > 0) {
268
+ insights.push(`💡 Try: ${alternatives.join(', ')}`);
269
+ }
270
+ }
271
+ return insights;
272
+ }
273
+ //# sourceMappingURL=premium-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"premium-analyzer.js","sourceRoot":"","sources":["../../src/utils/premium-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Domain Name Validators.
3
+ *
4
+ * Validates domain names, TLDs, and other inputs.
5
+ * Provides user-friendly error messages.
6
+ */
7
+ /**
8
+ * Validate and normalize a domain name (without TLD).
9
+ *
10
+ * @param name - The domain name to validate
11
+ * @returns Normalized domain name (lowercase)
12
+ * @throws InvalidDomainError if invalid
13
+ */
14
+ export declare function validateDomainName(name: string): string;
15
+ /**
16
+ * Validate a TLD.
17
+ *
18
+ * @param tld - The TLD to validate (with or without leading dot)
19
+ * @returns Normalized TLD (lowercase, no dot)
20
+ * @throws UnsupportedTldError if invalid or not allowed
21
+ */
22
+ export declare function validateTld(tld: string): string;
23
+ /**
24
+ * Parse a full domain name into name and TLD.
25
+ *
26
+ * @param fullDomain - Full domain like "example.com" or "sub.example.co.uk"
27
+ * @returns Object with name and tld
28
+ * @throws InvalidDomainError if parsing fails
29
+ */
30
+ export declare function parseDomain(fullDomain: string): {
31
+ name: string;
32
+ tld: string;
33
+ };
34
+ /**
35
+ * Validate an array of TLDs.
36
+ *
37
+ * @param tlds - Array of TLDs to validate
38
+ * @returns Array of normalized TLDs
39
+ */
40
+ export declare function validateTlds(tlds: string[]): string[];
41
+ /**
42
+ * Check if a string looks like a full domain (has a dot).
43
+ */
44
+ export declare function isFullDomain(input: string): boolean;
45
+ /**
46
+ * Build a full domain from name and TLD.
47
+ */
48
+ export declare function buildDomain(name: string, tld: string): string;
49
+ /**
50
+ * Validate registrar name.
51
+ */
52
+ export declare function validateRegistrar(registrar: string): string;
53
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0BH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyCvD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA4B/C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAsB7E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAOrD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAW3D"}