@stacksjs/whois 0.64.6 → 0.66.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/dist/constants.d.ts +3 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.js +161 -2
- package/dist/index.js.map +96 -6
- package/dist/types.d.ts +93 -0
- package/dist/utils.d.ts +7 -0
- package/package.json +9 -12
- package/src/constants.ts +325 -0
- package/src/index.ts +69 -171
- package/src/types.ts +97 -0
- package/src/utils.ts +22 -0
- package/src/parameters.ts +0 -4
- package/src/servers.ts +0 -318
- package/src/test.ts +0 -5
package/src/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import type { SocksClientOptions } from 'socks'
|
|
2
|
+
import type { ProxyData, WhoIsOptions, WhoIsResponse } from './types'
|
|
1
3
|
import Net from 'node:net'
|
|
4
|
+
import { log } from '@stacksjs/logging'
|
|
2
5
|
import fetch from 'node-fetch'
|
|
3
|
-
import type { SocksClientOptions } from 'socks'
|
|
4
6
|
import { SocksClient } from 'socks'
|
|
5
|
-
import PARAMETERS from './
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
const IANA_CHK_URL = 'https://www.iana.org/whois?q='
|
|
7
|
+
import { IANA_CHK_URL, PARAMETERS, SERVERS } from './constants'
|
|
8
|
+
import { ProxyType } from './types'
|
|
9
|
+
import { shallowCopy } from './utils'
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Find the WhoIs server for the TLD from IANA WhoIs service. The TLD is be searched and the HTML response is parsed to extract the WhoIs server
|
|
@@ -13,43 +14,24 @@ const IANA_CHK_URL = 'https://www.iana.org/whois?q='
|
|
|
13
14
|
* @param tld TLD of the domain
|
|
14
15
|
* @returns WhoIs server which hosts the information for the domains of the TLD
|
|
15
16
|
*/
|
|
16
|
-
async function findWhoIsServer(tld: string): Promise<string> {
|
|
17
|
+
export async function findWhoIsServer(tld: string): Promise<string> {
|
|
17
18
|
const chkURL = IANA_CHK_URL + tld
|
|
18
19
|
|
|
19
20
|
try {
|
|
20
21
|
const res = await fetch(chkURL)
|
|
21
22
|
if (res.ok) {
|
|
22
23
|
const body = await res.text()
|
|
23
|
-
const server = body.match(/whois:\s+(
|
|
24
|
-
if (server?.[1])
|
|
24
|
+
const server = body.match(/whois:\s+(\S+)/)
|
|
25
|
+
if (server?.[1])
|
|
26
|
+
return server[1]
|
|
25
27
|
}
|
|
26
|
-
}
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
27
30
|
console.error('Error in getting WhoIs server data from IANA', err)
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
return ''
|
|
31
34
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Copy an Object with its values
|
|
34
|
-
*
|
|
35
|
-
* @param obj Object which needs to be copied
|
|
36
|
-
* @returns A copy of the object
|
|
37
|
-
*/
|
|
38
|
-
function shallowCopy<T>(obj: T): T {
|
|
39
|
-
if (Array.isArray(obj)) {
|
|
40
|
-
return obj.slice() as T // Clone the array
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (typeof obj === 'object' && obj !== null) {
|
|
44
|
-
const copy: any = {}
|
|
45
|
-
for (const key in obj) {
|
|
46
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) copy[key] = shallowCopy(obj[key])
|
|
47
|
-
}
|
|
48
|
-
return copy as T
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return obj // For primitive values, return as is
|
|
52
|
-
}
|
|
53
35
|
|
|
54
36
|
/**
|
|
55
37
|
* Get whois server of the tld from servers list
|
|
@@ -57,7 +39,9 @@ function shallowCopy<T>(obj: T): T {
|
|
|
57
39
|
* @param tld TLD of the domain
|
|
58
40
|
* @returns WhoIs server which hosts the information for the domains of the TLD
|
|
59
41
|
*/
|
|
60
|
-
function getWhoIsServer(tld: keyof typeof SERVERS): string | undefined {
|
|
42
|
+
export function getWhoIsServer(tld: keyof typeof SERVERS): string | undefined {
|
|
43
|
+
if (tld === 'com')
|
|
44
|
+
return 'whois.verisign-grs.com'
|
|
61
45
|
return SERVERS[tld]
|
|
62
46
|
}
|
|
63
47
|
|
|
@@ -69,134 +53,23 @@ function getWhoIsServer(tld: keyof typeof SERVERS): string | undefined {
|
|
|
69
53
|
* @param domain Domain name
|
|
70
54
|
* @returns TLD
|
|
71
55
|
*/
|
|
72
|
-
function getTLD(domain: string): keyof typeof SERVERS {
|
|
73
|
-
|
|
74
|
-
let
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (domainData.length < 2) break
|
|
79
|
-
|
|
80
|
-
const tldCheck = domainData.slice(1).join('.') as keyof typeof SERVERS
|
|
81
|
-
const server = SERVERS[tldCheck]
|
|
82
|
-
if (server) {
|
|
83
|
-
tld = tldCheck
|
|
84
|
-
break
|
|
56
|
+
export function getTLD(domain: string): keyof typeof SERVERS {
|
|
57
|
+
const domainParts = domain.split('.')
|
|
58
|
+
for (let i = domainParts.length - 1; i > 0; i--) {
|
|
59
|
+
const possibleTLD = domainParts.slice(i).join('.') as keyof typeof SERVERS
|
|
60
|
+
if (SERVERS[possibleTLD]) {
|
|
61
|
+
return possibleTLD
|
|
85
62
|
}
|
|
86
|
-
domainStr = tldCheck
|
|
87
63
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
console.debug('TLD is not found in server list. Returning last element after split as TLD!')
|
|
92
|
-
|
|
93
|
-
const domainData = domain.split('.')
|
|
94
|
-
return domainData[domainData.length - 1] as keyof typeof SERVERS
|
|
64
|
+
// If no match found in SERVERS, return the last part
|
|
65
|
+
return domainParts[domainParts.length - 1] as keyof typeof SERVERS
|
|
95
66
|
}
|
|
96
67
|
|
|
97
68
|
// get whois query parameters if exist on parameters.json for whois server
|
|
98
|
-
function getParameters(server: string): string | undefined {
|
|
69
|
+
export function getParameters(server: string): string | undefined {
|
|
99
70
|
return (PARAMETERS as { [key: string]: string })[server]
|
|
100
71
|
}
|
|
101
72
|
|
|
102
|
-
/**
|
|
103
|
-
* Type of the proxy. Either SOCKS4 or SOCKS5
|
|
104
|
-
* @enum
|
|
105
|
-
*/
|
|
106
|
-
export enum ProxyType {
|
|
107
|
-
/**
|
|
108
|
-
* SOCKS4 type of proxy
|
|
109
|
-
*/
|
|
110
|
-
SOCKS4 = 0,
|
|
111
|
-
/**
|
|
112
|
-
* SOCKS5 type of proxy
|
|
113
|
-
*/
|
|
114
|
-
SOCKS5 = 1,
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Proxy related data
|
|
119
|
-
* @interface
|
|
120
|
-
*
|
|
121
|
-
*/
|
|
122
|
-
export interface ProxyData {
|
|
123
|
-
/**
|
|
124
|
-
* Proxy IP
|
|
125
|
-
*/
|
|
126
|
-
ip: string
|
|
127
|
-
/**
|
|
128
|
-
* Proxy port
|
|
129
|
-
*/
|
|
130
|
-
port: number
|
|
131
|
-
/**
|
|
132
|
-
* Username to connect to the proxy
|
|
133
|
-
*/
|
|
134
|
-
username?: string | null
|
|
135
|
-
/**
|
|
136
|
-
* Password to connect to the proxy
|
|
137
|
-
*/
|
|
138
|
-
password?: string | null
|
|
139
|
-
/**
|
|
140
|
-
* {@link ProxyType}
|
|
141
|
-
*/
|
|
142
|
-
type: ProxyType
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* WhoIs options
|
|
147
|
-
* @interface
|
|
148
|
-
*/
|
|
149
|
-
export interface WhoIsOptions {
|
|
150
|
-
/**
|
|
151
|
-
* TLD of the domain. If the {@link tld} is not provided (or null), then it will be automatically determined as to the given domain name
|
|
152
|
-
*/
|
|
153
|
-
tld?: string | null
|
|
154
|
-
/**
|
|
155
|
-
* The encoding type used for WhoIs server and response. By default UTF-8 is used.
|
|
156
|
-
*/
|
|
157
|
-
encoding?: string | null
|
|
158
|
-
|
|
159
|
-
/** {@link ProxyData} */
|
|
160
|
-
proxy?: ProxyData | null
|
|
161
|
-
/**
|
|
162
|
-
* The WhoIs server to collect data from. If not provided, the server will automatically determined using the {@link tld}
|
|
163
|
-
*/
|
|
164
|
-
server?: string | null
|
|
165
|
-
/**
|
|
166
|
-
* The port of the WhoIs server. By default, port 43 is used.
|
|
167
|
-
*/
|
|
168
|
-
serverPort?: number | null
|
|
169
|
-
/**
|
|
170
|
-
* Which data needs to be extracted/parsed from the WhoIs response.
|
|
171
|
-
* An object can be passed which contains keys of the fields of the WhoIs response.
|
|
172
|
-
* A copy of the provided object will be returned with the values filled for the provided keys.
|
|
173
|
-
*
|
|
174
|
-
* The keys can have default value of empty string. However, if the WhoIs response has multiple values for the same field (eg: 'Domain Status'),
|
|
175
|
-
* then all the values can be collected by providing a default value of an Array([]).
|
|
176
|
-
*
|
|
177
|
-
* Following example shows an object used to collect 'Domain Name', 'Domain Status' (multiple values) and 'Registrar' from WhoIs response
|
|
178
|
-
*
|
|
179
|
-
* @example {'Domain Name': '', 'Domain Status': [], 'Registrar': ''}
|
|
180
|
-
*/
|
|
181
|
-
parseData?: object | null
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Response returned from whois function. Contains the raw text from WhoIs server and parsed/fornatted WhoIs data (if parsed is true)
|
|
186
|
-
*
|
|
187
|
-
* @interface
|
|
188
|
-
*/
|
|
189
|
-
export interface WhoIsResponse {
|
|
190
|
-
/**
|
|
191
|
-
* Raw text response from WhoIs server
|
|
192
|
-
*/
|
|
193
|
-
_raw: string
|
|
194
|
-
/**
|
|
195
|
-
* Parsed/Formatted key-value pairs of the response (if parsed is true)
|
|
196
|
-
*/
|
|
197
|
-
parsedData: any | null
|
|
198
|
-
}
|
|
199
|
-
|
|
200
73
|
/**
|
|
201
74
|
* Parse collected raw WhoIs data
|
|
202
75
|
*
|
|
@@ -220,22 +93,26 @@ export class WhoIsParser {
|
|
|
220
93
|
if (letter === '\n' || (lastLetter === ':' && letter === ' ')) {
|
|
221
94
|
if (lastStr.trim() in outputData) {
|
|
222
95
|
lastField = lastStr.trim()
|
|
223
|
-
}
|
|
96
|
+
}
|
|
97
|
+
else if (lastField !== null) {
|
|
224
98
|
const x = lastStr.trim()
|
|
225
99
|
if (x !== '') {
|
|
226
100
|
const obj = outputData[lastField]
|
|
227
|
-
if (Array.isArray(obj))
|
|
101
|
+
if (Array.isArray(obj))
|
|
102
|
+
obj.push(x)
|
|
228
103
|
else outputData[lastField] = x
|
|
229
104
|
|
|
230
105
|
lastField = null
|
|
231
106
|
}
|
|
232
107
|
}
|
|
233
108
|
lastStr = ''
|
|
234
|
-
}
|
|
109
|
+
}
|
|
110
|
+
else if (letter !== ':') {
|
|
235
111
|
lastStr = lastStr + letter
|
|
236
112
|
}
|
|
237
113
|
lastLetter = letter as string
|
|
238
|
-
if (lastStr === 'Record maintained by' || lastStr === '>>>')
|
|
114
|
+
if (lastStr === 'Record maintained by' || lastStr === '>>>')
|
|
115
|
+
break
|
|
239
116
|
}
|
|
240
117
|
|
|
241
118
|
return outputData
|
|
@@ -256,7 +133,7 @@ export class WhoIsParser {
|
|
|
256
133
|
'Updated Date': '',
|
|
257
134
|
'Registry Expiry Date': '',
|
|
258
135
|
'Domain Status': [],
|
|
259
|
-
Registrar: '',
|
|
136
|
+
'Registrar': '',
|
|
260
137
|
}
|
|
261
138
|
}
|
|
262
139
|
|
|
@@ -293,7 +170,8 @@ export async function tcpWhois(
|
|
|
293
170
|
return new Promise((resolve, reject) => {
|
|
294
171
|
try {
|
|
295
172
|
socket.connect({ port, host: server }, () => {
|
|
296
|
-
if (queryOptions !== '')
|
|
173
|
+
if (queryOptions !== '')
|
|
174
|
+
socket.write(encoder.encode(`${queryOptions} ${domain}\r\n`))
|
|
297
175
|
else socket.write(encoder.encode(`${domain}\r\n`))
|
|
298
176
|
})
|
|
299
177
|
|
|
@@ -304,7 +182,8 @@ export async function tcpWhois(
|
|
|
304
182
|
socket.on('error', (error) => {
|
|
305
183
|
reject(error)
|
|
306
184
|
})
|
|
307
|
-
}
|
|
185
|
+
}
|
|
186
|
+
catch (e) {
|
|
308
187
|
reject(e)
|
|
309
188
|
}
|
|
310
189
|
})
|
|
@@ -334,12 +213,15 @@ export async function tcpWhois(
|
|
|
334
213
|
SocksClient.createConnection(options, (err, info) => {
|
|
335
214
|
if (err) {
|
|
336
215
|
reject(err)
|
|
337
|
-
}
|
|
338
|
-
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
if (!info)
|
|
219
|
+
reject(new Error('No socket info received!'))
|
|
339
220
|
|
|
340
221
|
if (queryOptions !== '') {
|
|
341
222
|
info?.socket.write(encoder.encode(`${queryOptions} ${domain}\r\n`))
|
|
342
|
-
}
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
343
225
|
info?.socket.write(encoder.encode(`${domain}\r\n`))
|
|
344
226
|
}
|
|
345
227
|
|
|
@@ -354,7 +236,7 @@ export async function tcpWhois(
|
|
|
354
236
|
}
|
|
355
237
|
|
|
356
238
|
/**
|
|
357
|
-
* Collect WhoIs data for the mentioned {@link domain}. Parse the
|
|
239
|
+
* Collect WhoIs data for the mentioned {@link domain}. Parse the received response if {@link parse} is true, accordingly.
|
|
358
240
|
*
|
|
359
241
|
* @param domain Domain name
|
|
360
242
|
* @param parse Whether the raw text needs to be parsed/formatted or not
|
|
@@ -375,7 +257,8 @@ export async function whois(
|
|
|
375
257
|
if (!options) {
|
|
376
258
|
tld = getTLD(domain)
|
|
377
259
|
proxy = null
|
|
378
|
-
}
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
379
262
|
tld = options.tld ? options.tld : getTLD(domain)
|
|
380
263
|
encoding = options.encoding ? options.encoding : 'utf-8'
|
|
381
264
|
proxy = options.proxy ? options.proxy : null
|
|
@@ -386,16 +269,16 @@ export async function whois(
|
|
|
386
269
|
if (server === '') {
|
|
387
270
|
let serverData = getWhoIsServer(tld as keyof typeof SERVERS)
|
|
388
271
|
if (!serverData) {
|
|
389
|
-
|
|
272
|
+
log.debug(`No WhoIs server found for TLD: ${tld}! Attempting IANA WhoIs database for server!`)
|
|
390
273
|
serverData = await findWhoIsServer(tld)
|
|
391
274
|
if (!serverData) {
|
|
392
|
-
|
|
275
|
+
log.debug('WhoIs server could not be found!')
|
|
393
276
|
return {
|
|
394
277
|
_raw: '',
|
|
395
278
|
parsedData: null,
|
|
396
279
|
}
|
|
397
280
|
}
|
|
398
|
-
|
|
281
|
+
log.debug(`WhoIs sever found for ${tld}: ${server}`)
|
|
399
282
|
}
|
|
400
283
|
|
|
401
284
|
server = serverData
|
|
@@ -405,7 +288,9 @@ export async function whois(
|
|
|
405
288
|
const queryOptions = qOptions || ''
|
|
406
289
|
|
|
407
290
|
try {
|
|
291
|
+
log.debug(`Attempting WHOIS lookup for ${domain} on server ${server}`)
|
|
408
292
|
const rawData = await tcpWhois(domain, queryOptions, server, port, encoding, proxy)
|
|
293
|
+
log.debug(`Raw WHOIS data received:`, rawData)
|
|
409
294
|
if (!parse) {
|
|
410
295
|
const parsedData = WhoIsParser.parseData(rawData, null)
|
|
411
296
|
return {
|
|
@@ -415,7 +300,8 @@ export async function whois(
|
|
|
415
300
|
}
|
|
416
301
|
|
|
417
302
|
let outputData: any | null = null
|
|
418
|
-
if (options?.parseData)
|
|
303
|
+
if (options?.parseData)
|
|
304
|
+
outputData = shallowCopy(options.parseData)
|
|
419
305
|
|
|
420
306
|
try {
|
|
421
307
|
const parsedData = WhoIsParser.parseData(rawData, outputData)
|
|
@@ -423,14 +309,17 @@ export async function whois(
|
|
|
423
309
|
_raw: rawData,
|
|
424
310
|
parsedData,
|
|
425
311
|
}
|
|
426
|
-
}
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
427
314
|
console.error('Error in parsing WhoIs data!', err)
|
|
428
315
|
return {
|
|
429
316
|
_raw: rawData,
|
|
430
317
|
parsedData: null,
|
|
431
318
|
}
|
|
432
319
|
}
|
|
433
|
-
}
|
|
320
|
+
}
|
|
321
|
+
catch (err: any) {
|
|
322
|
+
log.debug(`Error in WHOIS lookup for ${domain} on server ${server}`, err)
|
|
434
323
|
return {
|
|
435
324
|
_raw: '',
|
|
436
325
|
parsedData: null,
|
|
@@ -439,6 +328,7 @@ export async function whois(
|
|
|
439
328
|
}
|
|
440
329
|
|
|
441
330
|
export function lookup(domain: string, options: WhoIsOptions | null = null): Promise<WhoIsResponse> {
|
|
331
|
+
log.debug(`Lookup called for ${domain}`)
|
|
442
332
|
return whois(domain, true, options)
|
|
443
333
|
}
|
|
444
334
|
|
|
@@ -464,7 +354,8 @@ export async function batchWhois(
|
|
|
464
354
|
let response: WhoIsResponse[] = []
|
|
465
355
|
|
|
466
356
|
if (parallel) {
|
|
467
|
-
if (threads > domains.length)
|
|
357
|
+
if (threads > domains.length)
|
|
358
|
+
threads = domains.length
|
|
468
359
|
|
|
469
360
|
for (let i = 0; i < domains.length; i += threads) {
|
|
470
361
|
const batch = domains.slice(i, i + threads)
|
|
@@ -474,7 +365,8 @@ export async function batchWhois(
|
|
|
474
365
|
}),
|
|
475
366
|
)
|
|
476
367
|
}
|
|
477
|
-
}
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
478
370
|
for (let i = 0; i < domains.length; i++) {
|
|
479
371
|
const res = await whois(domains[i] as string, parse, options)
|
|
480
372
|
response.push(res)
|
|
@@ -483,3 +375,9 @@ export async function batchWhois(
|
|
|
483
375
|
|
|
484
376
|
return response
|
|
485
377
|
}
|
|
378
|
+
|
|
379
|
+
export * from './constants'
|
|
380
|
+
export * from './types'
|
|
381
|
+
|
|
382
|
+
export { SocksClient } from 'socks'
|
|
383
|
+
export type { SocksClientOptions } from 'socks'
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response returned from whois function. Contains the raw text from WhoIs server and parsed/fornatted WhoIs data (if parsed is true)
|
|
3
|
+
*
|
|
4
|
+
* @interface
|
|
5
|
+
*/
|
|
6
|
+
export interface WhoIsResponse {
|
|
7
|
+
/**
|
|
8
|
+
* Raw text response from WhoIs server
|
|
9
|
+
*/
|
|
10
|
+
_raw: string
|
|
11
|
+
/**
|
|
12
|
+
* Parsed/Formatted key-value pairs of the response (if parsed is true)
|
|
13
|
+
*/
|
|
14
|
+
parsedData: any | null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Type of the proxy. Either SOCKS4 or SOCKS5
|
|
19
|
+
* @enum
|
|
20
|
+
*/
|
|
21
|
+
export enum ProxyType {
|
|
22
|
+
/**
|
|
23
|
+
* SOCKS4 type of proxy
|
|
24
|
+
*/
|
|
25
|
+
SOCKS4 = 0,
|
|
26
|
+
/**
|
|
27
|
+
* SOCKS5 type of proxy
|
|
28
|
+
*/
|
|
29
|
+
SOCKS5 = 1,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Proxy related data
|
|
34
|
+
* @interface
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
export interface ProxyData {
|
|
38
|
+
/**
|
|
39
|
+
* Proxy IP
|
|
40
|
+
*/
|
|
41
|
+
ip: string
|
|
42
|
+
/**
|
|
43
|
+
* Proxy port
|
|
44
|
+
*/
|
|
45
|
+
port: number
|
|
46
|
+
/**
|
|
47
|
+
* Username to connect to the proxy
|
|
48
|
+
*/
|
|
49
|
+
username?: string | null
|
|
50
|
+
/**
|
|
51
|
+
* Password to connect to the proxy
|
|
52
|
+
*/
|
|
53
|
+
password?: string | null
|
|
54
|
+
/**
|
|
55
|
+
* {@link ProxyType}
|
|
56
|
+
*/
|
|
57
|
+
type: ProxyType
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* WhoIs options
|
|
62
|
+
* @interface
|
|
63
|
+
*/
|
|
64
|
+
export interface WhoIsOptions {
|
|
65
|
+
/**
|
|
66
|
+
* TLD of the domain. If the {@link tld} is not provided (or null), then it will be automatically determined as to the given domain name
|
|
67
|
+
*/
|
|
68
|
+
tld?: string | null
|
|
69
|
+
/**
|
|
70
|
+
* The encoding type used for WhoIs server and response. By default UTF-8 is used.
|
|
71
|
+
*/
|
|
72
|
+
encoding?: string | null
|
|
73
|
+
|
|
74
|
+
/** {@link ProxyData} */
|
|
75
|
+
proxy?: ProxyData | null
|
|
76
|
+
/**
|
|
77
|
+
* The WhoIs server to collect data from. If not provided, the server will automatically determined using the {@link tld}
|
|
78
|
+
*/
|
|
79
|
+
server?: string | null
|
|
80
|
+
/**
|
|
81
|
+
* The port of the WhoIs server. By default, port 43 is used.
|
|
82
|
+
*/
|
|
83
|
+
serverPort?: number | null
|
|
84
|
+
/**
|
|
85
|
+
* Which data needs to be extracted/parsed from the WhoIs response.
|
|
86
|
+
* An object can be passed which contains keys of the fields of the WhoIs response.
|
|
87
|
+
* A copy of the provided object will be returned with the values filled for the provided keys.
|
|
88
|
+
*
|
|
89
|
+
* The keys can have default value of empty string. However, if the WhoIs response has multiple values for the same field (eg: 'Domain Status'),
|
|
90
|
+
* then all the values can be collected by providing a default value of an Array([]).
|
|
91
|
+
*
|
|
92
|
+
* Following example shows an object used to collect 'Domain Name', 'Domain Status' (multiple values) and 'Registrar' from WhoIs response
|
|
93
|
+
*
|
|
94
|
+
* @example {'Domain Name': '', 'Domain Status': [], 'Registrar': ''}
|
|
95
|
+
*/
|
|
96
|
+
parseData?: object | null
|
|
97
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy an Object with its values
|
|
3
|
+
*
|
|
4
|
+
* @param obj Object which needs to be copied
|
|
5
|
+
* @returns A copy of the object
|
|
6
|
+
*/
|
|
7
|
+
export function shallowCopy<T>(obj: T): T {
|
|
8
|
+
if (Array.isArray(obj)) {
|
|
9
|
+
return obj.slice() as T // Clone the array
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (typeof obj === 'object' && obj !== null) {
|
|
13
|
+
const copy: any = {}
|
|
14
|
+
for (const key in obj) {
|
|
15
|
+
if (Object.prototype.hasOwnProperty.call(obj, key))
|
|
16
|
+
copy[key] = shallowCopy(obj[key])
|
|
17
|
+
}
|
|
18
|
+
return copy as T
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return obj // For primitive values, return as is
|
|
22
|
+
}
|
package/src/parameters.ts
DELETED