(data)
| 52 | |
| 53 | // Map an RDAP response into the same field names whoiser exposes, so pick() works uniformly |
| 54 | const rdapToWhoiserShape = (data) => { |
| 55 | if (!data || data.errorCode || data.objectClassName === 'error') return null; |
| 56 | const events = data.events || []; |
| 57 | const evt = (a) => events.find((e) => e.eventAction === a)?.eventDate; |
| 58 | const registrar = (data.entities || []).find((e) => (e.roles || []).includes('registrar')); |
| 59 | const ianaId = registrar?.publicIds?.find((p) => /iana/i.test(p.type))?.identifier; |
| 60 | const registrarUrlEntry = registrar?.links?.find((l) => l.rel === 'about' || l.rel === 'related'); |
| 61 | return { |
| 62 | 'Domain Name': data.ldhName, |
| 63 | 'Created Date': evt('registration'), |
| 64 | 'Updated Date': evt('last changed') || evt('last update of RDAP database'), |
| 65 | 'Expiry Date': evt('expiration'), |
| 66 | 'Registry Domain ID': data.handle, |
| 67 | Registrar: vcardFn(registrar?.vcardArray), |
| 68 | 'Registrar IANA ID': ianaId, |
| 69 | 'Registrar URL': registrarUrlEntry?.href, |
| 70 | 'Domain Status': data.status, |
| 71 | 'Name Server': (data.nameservers || []).map((n) => n.ldhName).filter(Boolean), |
| 72 | DNSSEC: data.secureDNS?.delegationSigned ? 'signed' : 'unsigned', |
| 73 | }; |
| 74 | }; |
| 75 | |
| 76 | // Last-resort lookup via rdap.org (a meta-resolver that bootstraps the right RDAP server) |
| 77 | const fetchRdapFallback = async (domain) => { |
no test coverage detected