UNPKG

web3-domain-resolver

Version:

Web3 Library that enable with just one function to resolve domains on multiple web3 providers such as ENS, UnstoppableDomains and Freename

135 lines (134 loc) 5.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NameTools = void 0; const resolved_resource_type_1 = require("../resolvers/types/resolved-resource-type"); const name_tools_types_1 = require("./name-tools.types"); const punycode = require("punycode"); class NameTools { static mapName(domainOrTld) { if (!domainOrTld) { return undefined; } const detailedName = this.getDetailedName(domainOrTld); if (!detailedName) { return undefined; } //portions let tld = null; let tldAsciiName = null; let secondLevelDomain = null; let secondLevelDomainAsciiName = null; if (detailedName.type === name_tools_types_1.NameType.TLD) { tld = domainOrTld; tldAsciiName = detailedName.asciiName; } else if (detailedName.type === name_tools_types_1.NameType.SECOND_LEVEL_DOMAIN || detailedName.type === name_tools_types_1.NameType.SUB_DOMAINED_DOMAIN) { const nameSplitted = detailedName.name.split("."); const asciiNameSplitted = detailedName.asciiName.split("."); if (nameSplitted.length === 2 && asciiNameSplitted.length === 2) { tld = nameSplitted[nameSplitted.length - 1]; secondLevelDomain = nameSplitted[nameSplitted.length - 2]; tldAsciiName = asciiNameSplitted[asciiNameSplitted.length - 1]; secondLevelDomainAsciiName = asciiNameSplitted[asciiNameSplitted.length - 2]; } } return { domain: secondLevelDomainAsciiName, fullname: domainOrTld, tld: tldAsciiName, type: detailedName.type, }; } static getItemTypeFromString(name) { if (name.includes(".")) { const splitted = name.split("."); const cleanSplitted = splitted.filter(s => s !== ""); if (cleanSplitted.length === 2) { return name_tools_types_1.NameType.SECOND_LEVEL_DOMAIN; } else if (cleanSplitted.length === 1) { return name_tools_types_1.NameType.TLD; } else if (cleanSplitted.length > 2) { return name_tools_types_1.NameType.SUB_DOMAINED_DOMAIN; } } return name_tools_types_1.NameType.TLD; } static getDetailedName(name) { let foundError = false; const errors = []; //We need the ascii string to avoid detecting emoji and other unicode characters as invalid const asciiString = punycode.toASCII(name); //Check if the search input contains forbidden characters const isSearchStringAllowable = this.isNameAllowed(asciiString); if (!isSearchStringAllowable?.isAllowable) { errors.push("INVALID_NAME"); foundError = true; } //Check if the search input name has a repeated dot (es. app..cryptotld) const dotCount = asciiString.split(".").length - 1; if (dotCount > 1) { errors.push("REPETED_DOT"); foundError = true; } if (!foundError) { let asciiName = asciiString; const itemType = this.getItemTypeFromString(asciiString); if (itemType == name_tools_types_1.NameType.SUB_DOMAINED_DOMAIN) { //The search input name is a sub domained domain (es. freename.app.cryptotld) errors.push("SUB_DOMAINS_NOT_ALLOWED"); } else { if (itemType == name_tools_types_1.NameType.TLD) { //remove the "." from the start of the tld (es .freename becomes freename) if (name.includes(".")) { name = name.replace(/\./g, ""); asciiName = asciiName.replace(/\./g, ""); } } return { asciiName, name, type: itemType, }; } } } static isNameAllowed(name) { //Check if search string contains only allowed characters const allowedCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-."; let invalidCharacters = []; let isAllowable = true; let dotsOnly = true; for (let i = 0; i < name.length; i++) { const char = name.charAt(i); if (allowedCharacters.indexOf(char) === -1) { invalidCharacters.push(char); isAllowable = false; } if (char !== ".") { dotsOnly = false; } } if (dotsOnly) { invalidCharacters = ["."]; isAllowable = false; } return { isAllowable, invalidCharacters, }; } static getResolvedResourceType(type) { switch (type) { case name_tools_types_1.NameType.TLD: return resolved_resource_type_1.ResolvedResourceType.TLD; case name_tools_types_1.NameType.SECOND_LEVEL_DOMAIN: return resolved_resource_type_1.ResolvedResourceType.SECOND_LEVEL_DOMAIN; default: return resolved_resource_type_1.ResolvedResourceType.UNTYPED; } } } exports.NameTools = NameTools;