85 lines
2.1 KiB
JavaScript
85 lines
2.1 KiB
JavaScript
![]() |
const punycode = require('punycode')
|
||
|
const sldMap = require('./data/sldMap.json')
|
||
|
const ccTldMap = require('./data/ccTldMap.json')
|
||
|
|
||
|
module.exports = function isValidDomain (value, opts) {
|
||
|
if (typeof value !== 'string') return false
|
||
|
if (!(opts instanceof Object)) opts = {}
|
||
|
value = value.toLowerCase()
|
||
|
|
||
|
if (value.endsWith('.')) {
|
||
|
value = value.slice(0, value.length - 1)
|
||
|
}
|
||
|
|
||
|
if (opts.allowUnicode) {
|
||
|
value = punycode.toASCII(value)
|
||
|
}
|
||
|
|
||
|
if (value.length > 253) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
const validChars = /^([\u0E00-\u0E7Fa-z0-9-._*]+)$/g
|
||
|
if (!validChars.test(value)) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
if (opts.topLevel) {
|
||
|
if (ccTldMap[value.replace(/\.$/, '')]) {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const sldRegex = /(.*)\.(([\u0E00-\u0E7Fa-z0-9]+)(\.[a-z0-9]+))/
|
||
|
const matches = value.match(sldRegex)
|
||
|
let tld = null
|
||
|
let labels = null
|
||
|
if (matches && matches.length > 2) {
|
||
|
if (sldMap[matches[2]]) {
|
||
|
tld = matches[2]
|
||
|
labels = matches[1].split('.')
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!labels) {
|
||
|
labels = value.split('.')
|
||
|
if (labels.length <= 1) return false
|
||
|
|
||
|
tld = labels.pop()
|
||
|
const tldRegex = /^(?:xn--)?(?!^\d+$)[\u0E00-\u0E7Fa-z0-9]+$/gi
|
||
|
|
||
|
if (!tldRegex.test(tld)) return false
|
||
|
}
|
||
|
|
||
|
if (opts.subdomain === false && labels.length > 1) return false
|
||
|
|
||
|
const isValid = labels.every(function (label, index) {
|
||
|
if (opts.wildcard && index === 0 && label === '*' && labels.length > 1) {
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
let validLabelChars = /^([\u0E00-\u0E7Fa-zA-Z0-9-_]+)$/g
|
||
|
if (index === labels.length - 1) {
|
||
|
validLabelChars = /^([\u0E00-\u0E7Fa-zA-Z0-9-]+)$/g
|
||
|
}
|
||
|
|
||
|
// https://github.com/miguelmota/is-valid-domain/issues/22
|
||
|
const doubleDashCount = (label.match(/--(--)?/g) || []).length
|
||
|
const xnDashCount = (label.match(/xn--/g) || []).length
|
||
|
if (index === labels.length - 1 && doubleDashCount !== xnDashCount) {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
const isValid = (
|
||
|
validLabelChars.test(label) &&
|
||
|
label.length < 64 &&
|
||
|
!label.startsWith('-') &&
|
||
|
!label.endsWith('-')
|
||
|
)
|
||
|
|
||
|
return isValid
|
||
|
})
|
||
|
|
||
|
return isValid
|
||
|
}
|