UNPKG

blockstack-zones

Version:
255 lines (226 loc) 7.44 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseZoneFile = parseZoneFile; function parseZoneFile(text) { text = removeComments(text); text = flatten(text); return parseRRs(text); }; var removeComments = function removeComments(text) { var re = /(^|[^\\]);.*/g; return text.replace(re, function (m, g1) { return g1 ? g1 : ""; // if g1 is set/matched, re-insert it, else remove }); }; var flatten = function flatten(text) { var captured = []; var re = /\([\s\S]*?\)/gim; var match = re.exec(text); while (match !== null) { match.replacement = match[0].replace(/\s+/gm, ' '); captured.push(match); // captured Text, index, input match = re.exec(text); } var arrText = text.split(''); for (var i in captured) { match = captured[i]; arrText.splice(match.index, match[0].length, match.replacement); } return arrText.join('').replace(/\(|\)/gim, ' '); }; var parseRRs = function parseRRs(text) { var ret = {}; var rrs = text.split('\n'); for (var i in rrs) { var rr = rrs[i]; if (!rr || !rr.trim()) { continue; } var uRR = rr.toUpperCase(); if (/\s+TXT\s+/.test(uRR)) { ret.txt = ret.txt || []; ret.txt.push(parseTXT(rr)); } else if (uRR.indexOf('$ORIGIN') === 0) { ret.$origin = rr.split(/\s+/g)[1]; } else if (uRR.indexOf('$TTL') === 0) { ret.$ttl = parseInt(rr.split(/\s+/g)[1], 10); } else if (/\s+SOA\s+/.test(uRR)) { ret.soa = parseSOA(rr); } else if (/\s+NS\s+/.test(uRR)) { ret.ns = ret.ns || []; ret.ns.push(parseNS(rr)); } else if (/\s+A\s+/.test(uRR)) { ret.a = ret.a || []; ret.a.push(parseA(rr, ret.a)); } else if (/\s+AAAA\s+/.test(uRR)) { ret.aaaa = ret.aaaa || []; ret.aaaa.push(parseAAAA(rr)); } else if (/\s+CNAME\s+/.test(uRR)) { ret.cname = ret.cname || []; ret.cname.push(parseCNAME(rr)); } else if (/\s+MX\s+/.test(uRR)) { ret.mx = ret.mx || []; ret.mx.push(parseMX(rr)); } else if (/\s+PTR\s+/.test(uRR)) { ret.ptr = ret.ptr || []; ret.ptr.push(parsePTR(rr, ret.ptr, ret.$origin)); } else if (/\s+SRV\s+/.test(uRR)) { ret.srv = ret.srv || []; ret.srv.push(parseSRV(rr)); } else if (/\s+SPF\s+/.test(uRR)) { ret.spf = ret.spf || []; ret.spf.push(parseSPF(rr)); } else if (/\s+URI\s+/.test(uRR)) { ret.uri = ret.uri || []; ret.uri.push(parseURI(rr)); } } return ret; }; var parseSOA = function parseSOA(rr) { var soa = {}; var rrTokens = rr.trim().split(/\s+/g); var l = rrTokens.length; soa.name = rrTokens[0]; soa.minimum = parseInt(rrTokens[l - 1], 10); soa.expire = parseInt(rrTokens[l - 2], 10); soa.retry = parseInt(rrTokens[l - 3], 10); soa.refresh = parseInt(rrTokens[l - 4], 10); soa.serial = parseInt(rrTokens[l - 5], 10); soa.rname = rrTokens[l - 6]; soa.mname = rrTokens[l - 7]; if (!isNaN(rrTokens[1])) soa.ttl = parseInt(rrTokens[1], 10); return soa; }; var parseNS = function parseNS(rr) { var rrTokens = rr.trim().split(/\s+/g); var l = rrTokens.length; var result = { name: rrTokens[0], host: rrTokens[l - 1] }; if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parseA = function parseA(rr, recordsSoFar) { var rrTokens = rr.trim().split(/\s+/g); var urrTokens = rr.trim().toUpperCase().split(/\s+/g); var l = rrTokens.length; var result = { name: rrTokens[0], ip: rrTokens[l - 1] }; if (urrTokens.lastIndexOf('A') === 0) { if (recordsSoFar.length) { result.name = recordsSoFar[recordsSoFar.length - 1].name; } else { result.name = '@'; } } if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parseAAAA = function parseAAAA(rr) { var rrTokens = rr.trim().split(/\s+/g); var l = rrTokens.length; var result = { name: rrTokens[0], ip: rrTokens[l - 1] }; if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parseCNAME = function parseCNAME(rr) { var rrTokens = rr.trim().split(/\s+/g); var l = rrTokens.length; var result = { name: rrTokens[0], alias: rrTokens[l - 1] }; if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parseMX = function parseMX(rr) { var rrTokens = rr.trim().split(/\s+/g); var l = rrTokens.length; var result = { name: rrTokens[0], preference: parseInt(rrTokens[l - 2], 10), host: rrTokens[l - 1] }; if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parseTXT = function parseTXT(rr) { var rrTokens = rr.trim().match(/[^\s\"']+|\"[^\"]*\"|'[^']*'/g); var l = rrTokens.length; var tokenTxt = rrTokens[l - 1]; if (tokenTxt.indexOf('\"') > -1) { tokenTxt = tokenTxt.split('\"')[1]; } if (tokenTxt.indexOf('"') > -1) { tokenTxt = tokenTxt.split('"')[1]; } var result = { name: rrTokens[0], txt: tokenTxt }; if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parsePTR = function parsePTR(rr, recordsSoFar, currentOrigin) { var rrTokens = rr.trim().split(/\s+/g); var urrTokens = rr.trim().toUpperCase().split(/\s+/g); if (urrTokens.lastIndexOf('PTR') === 0 && recordsSoFar[recordsSoFar.length - 1]) { rrTokens.unshift(recordsSoFar[recordsSoFar.length - 1].name); } var l = rrTokens.length; var result = { name: rrTokens[0], fullname: rrTokens[0] + '.' + currentOrigin, host: rrTokens[l - 1] }; if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parseSRV = function parseSRV(rr) { var rrTokens = rr.trim().split(/\s+/g); var l = rrTokens.length; var result = { name: rrTokens[0], target: rrTokens[l - 1], priority: parseInt(rrTokens[l - 4], 10), weight: parseInt(rrTokens[l - 3], 10), port: parseInt(rrTokens[l - 2], 10) }; if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parseSPF = function parseSPF(rr) { var rrTokens = rr.trim().split(/\s+/g); var result = { name: rrTokens[0], data: '' }; var l = rrTokens.length; while (l-- > 4) { result.data = rrTokens[l] + ' ' + result.data.trim(); } if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; }; var parseURI = function parseURI(rr) { var rrTokens = rr.trim().split(/\s+/g); var l = rrTokens.length; var result = { name: rrTokens[0], target: rrTokens[l - 1].replace(/"/g, ''), priority: parseInt(rrTokens[l - 3], 10), weight: parseInt(rrTokens[l - 2], 10) }; if (!isNaN(rrTokens[1])) result.ttl = parseInt(rrTokens[1], 10); return result; };