You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

dnsz

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dnsz - npm Package Compare versions

Comparing version
4.3.2
to
4.3.4
+1
dist/index.js.map
{"version":3,"file":"index.js","names":["value: string","node: any","state: Record<string, any>","value","indexes: Array<number>","parts: Array<string>","data: Partial<DnszDnsData>","headerLines: Array<string>","valid: boolean","recordsByType: Record<string, Array<DnszDnsRecord>>","vars: Array<string>"],"sources":["../index.ts"],"sourcesContent":["export type DnszDnsRecord = {\n /**The lowercase DNS name without a trailing dot, e.g. `\"example.com\"`. */\n name: string;\n /** The TTL in seconds, e.g. `60`. */\n ttl: number;\n /** The DNS class, e.g. `\"IN\"`. */\n class: string;\n /** The record type, e.g. `\"A\"`. */\n type: string;\n /** The record content, e.g. `\"2001:db8::1\"` or `\"example.com.\"`. */\n content: string;\n /** A comment, e.g. `\"a comment\"`, `null` if absent. */\n comment: string | null;\n};\n\nexport type DnszDnsData = {\n /** Array of `record` */\n records: Array<DnszDnsRecord>;\n /** The value of `$ORIGIN` in the zone file. */\n origin?: string;\n /** The value of `$TTL` in the zone file. */\n ttl?: number;\n /** An optional header at the start of the file. Can be multiline. Does not include comment markers. */\n header?: string;\n};\n\nexport type DnszParseOptions = {\n /** When specified, replaces any `@` in `name` or `content` with it. */\n replaceOrigin?: string | null;\n /** When true, emit `\\r\\n` instead of `\\n` in `header`. */\n crlf?: boolean;\n /** Default class when absent. */\n defaultClass?: string;\n /** Default TTL when absent and `$TTL` is not present. */\n defaultTTL?: number;\n /** Ensure trailing dots on FQDNs in content. Supports a limited amount of record types. */\n dots?: boolean;\n};\n\nexport type DnszStringifyOptions = {\n /** Whether to group records into sections. */\n sections?: boolean;\n /** When `true`, emit `\\r\\n` instead of `\\n` for the resulting zone file. */\n crlf?: boolean;\n /** Ensure trailing dots on FQDNs in content. Supports a limited amount of record types. Default: `false`. */\n dots?: boolean;\n};\n\n// List of types and places where they have name-like content, used on the `dot` option.\nconst nameLike = {\n ALIAS: [0],\n ANAME: [0],\n CNAME: [0],\n DNAME: [0],\n MX: [1],\n NAPTR: [5],\n NS: [0],\n NSEC: [0],\n PTR: [0],\n RP: [0, 1],\n RRSIG: [7],\n SIG: [7],\n SOA: [0, 1],\n SRV: [3],\n TKEY: [0],\n TSIG: [0],\n};\n\nfunction normalize(name: string) {\n name = (name || \"\").toLowerCase();\n if (name.endsWith(\".\") && name.length > 1) {\n name = name.substring(0, name.length - 1);\n }\n return name.replace(/\\.{2,}/g, \".\").replace(/@\\./, \"@\");\n}\n\nfunction splitString(input: string, {separator = \" \", quotes = []}: {separator?: string, quotes?: Array<string>} = {}) {\n const ast = {type: \"root\", nodes: [], stash: [\"\"]};\n const stack = [ast];\n const string = input;\n let value: string;\n let node: any;\n let i = -1;\n const state: Record<string, any> = {\n input,\n separator,\n stack,\n prev: () => string[i - 1],\n next: () => string[i + 1],\n };\n\n const block = () => (state.block = stack[stack.length - 1]);\n const peek = () => string[i + 1];\n const next = () => string[++i];\n const append = (value: string) => {\n state.value = value;\n if (value) {\n state.block.stash[state.block.stash.length - 1] += value;\n }\n };\n\n const closeIndex = (value: string, startIdx: number) => {\n let idx = string.indexOf(value, startIdx);\n if (idx > -1 && string[idx - 1] === \"\\\\\") {\n idx = closeIndex(value, idx + 1);\n }\n return idx;\n };\n\n while (i < string.length - 1) {\n state.value = value = next();\n state.index = i;\n block();\n\n if (value === \"\\\\\") {\n if (peek() === \"\\\\\") {\n append(value + next());\n } else {\n append(value);\n append(next());\n }\n continue;\n }\n\n if (quotes.includes(value)) {\n const pos = i + 1;\n const idx = closeIndex(value, pos);\n\n if (idx > -1) {\n append(value);\n append(string.slice(pos, idx));\n append(string[idx]);\n i = idx;\n continue;\n }\n\n append(value);\n continue;\n }\n\n if (value === separator && state.block.type === \"root\") {\n state.block.stash.push(\"\");\n continue;\n }\n\n append(value);\n }\n\n node = stack.pop();\n while (node !== ast) {\n value = (node.parent.stash.pop() + node.stash.join(\".\"));\n node.parent.stash = node.parent.stash.concat(value.split(\".\"));\n node = stack.pop();\n }\n\n return node.stash;\n}\n\nfunction denormalize(name: string) {\n if (!name.endsWith(\".\") && name.length > 1) {\n name = `${name}.`;\n }\n return name.replace(/\\.{2,}/g, \".\").replace(/@\\./, \"@\");\n}\n\nfunction esc(str: string) {\n return str.replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\");\n}\n\nfunction addDots(content: string, indexes: Array<number>): string {\n const parts = splitString(content, {\n quotes: [`\"`],\n separator: \" \",\n }).map((s: string) => s.trim()).filter(Boolean);\n for (const index of indexes) {\n if (!parts[index].endsWith(\".\")) {\n parts[index] += \".\";\n }\n }\n return parts.join(\" \");\n}\n\nfunction parseTTL(ttl: string | number, def?: number): number {\n if (typeof ttl === \"number\") {\n return ttl;\n }\n\n if (def && !ttl) {\n return def;\n }\n\n if (/s$/i.test(ttl)) {\n ttl = parseInt(ttl);\n } else if (/m$/i.test(ttl)) {\n ttl = parseInt(ttl) * 60;\n } else if (/h$/i.test(ttl)) {\n ttl = parseInt(ttl) * 60 * 60;\n } else if (/d$/i.test(ttl)) {\n ttl = parseInt(ttl) * 60 * 60 * 24;\n } else if (/w$/i.test(ttl)) {\n ttl = parseInt(ttl) * 60 * 60 * 24 * 7;\n } else {\n ttl = parseInt(ttl);\n }\n\n return ttl;\n}\n\ntype FormatOpts = {\n origin: string,\n newline: string,\n sections: boolean,\n dots: boolean,\n};\n\nfunction format(records: Array<DnszDnsRecord | undefined>, type: string | null, {origin, newline, sections, dots}: FormatOpts) {\n let str = ``;\n\n if (sections && type) {\n str += `;; ${type} Records${newline}`;\n }\n\n for (const record of records || []) {\n if (!record) continue;\n let name = normalize(record.name || \"\");\n\n if (origin) {\n if (name === origin) {\n name = \"@\";\n } else if (name.endsWith(origin)) {\n // subdomain, remove origin and trailing dots\n name = normalize(name.replace(new RegExp(`${esc(`${origin}.`)}?$`, \"gm\"), \"\"));\n } else {\n // assume it's a subdomain, remove trailing dots\n name = normalize(name);\n }\n } else {\n if (name.includes(\".\")) {\n // assume it's a fqdn, add trailing dots\n name = denormalize(name);\n } else {\n name = normalize(name);\n }\n }\n\n let content = record.content;\n if (dots && Object.keys(nameLike).includes(record.type)) {\n const indexes: Array<number> = nameLike[record.type as keyof typeof nameLike];\n content = addDots(content, indexes);\n }\n\n const fields = [\n name,\n record.ttl,\n record.class,\n record.type,\n content,\n ];\n\n if (record.comment) {\n fields.push(`; ${record.comment}`);\n }\n\n str += `${fields.join(\"\\t\")}${newline}`;\n }\n return `${str}${sections ? newline : \"\"}`;\n}\n\nfunction splitContentAndComment(str?: string): [content: string | null, comment: string | null | undefined] {\n if (!str) return [null, null];\n const splitted = splitString(str, {\n quotes: [`\"`],\n separator: \";\",\n });\n\n let parts: Array<string>;\n if (splitted.length > 2) { // more than one semicolon\n parts = [splitted[0], splitted.slice(1).join(\";\")];\n } else {\n parts = splitted;\n }\n\n parts = parts.map((part: string) => (part || \"\").trim()).filter(Boolean);\n\n if (parts.length <= 2) {\n return [parts[0] || null, parts[1] || null];\n } else {\n const comment = parts.pop();\n const content = parts.join(\"; \");\n return [content, comment];\n }\n}\n\n/** Parse a string of a DNS zone file and returns a `data` object. */\nexport function parseZone(str: string, {replaceOrigin = null, crlf = false, defaultTTL = 60, defaultClass = \"IN\", dots = false}: DnszParseOptions = {}): DnszDnsData {\n const data: Partial<DnszDnsData> = {};\n const rawLines = str.split(/\\r?\\n/).map(l => l.trim());\n const lines = rawLines.filter(l => Boolean(l) && !l.startsWith(\";\"));\n const newline = crlf ? \"\\r\\n\" : \"\\n\";\n\n // search for header\n const headerLines: Array<string> = [];\n let valid: boolean = false;\n for (const [index, line] of rawLines.entries()) {\n if (line.startsWith(\";;\")) {\n headerLines.push(line.substring(2).trim());\n } else {\n const prev = rawLines[index - 1];\n if (line === \"\" && index > 1 && prev.startsWith(\";;\")) {\n valid = true;\n break;\n }\n }\n }\n if (valid && headerLines.length) {\n data.header = headerLines.join(newline);\n }\n\n // https://regex101.com/r/aKuGyZ/3\n const reLine = /^([a-z0-9_.\\-@*]+)?\\s*([0-9]+[smhdw]?)?\\s*([a-z]+)?\\s+([a-z]+[0-9]*)?\\s+(.+)$/i;\n\n // create records\n data.records = [];\n for (const line of lines) {\n const parsedOrigin = (/\\$ORIGIN\\s+(\\S+)/.exec(line) || [])[1];\n if (parsedOrigin && !data.origin) {\n data.origin = normalize(parsedOrigin);\n }\n\n const parsedTtl = (/\\$TTL\\s+(\\S+)/.exec(line) || [])[1];\n if (line.startsWith(\"$TTL \") && !data.ttl) {\n data.ttl = parseTTL(normalize(parsedTtl));\n }\n\n let [, name, ttl, cls, type, contentAndComment] = reLine.exec(line) || [];\n if (!ttl && name && /[0-9]+/.test(name)) { // no name\n ttl = name;\n name = \"\";\n }\n if (cls && !type) { // class is optional\n type = cls;\n cls = \"\";\n }\n if (!cls) {\n cls = defaultClass;\n }\n let [content, comment] = splitContentAndComment(contentAndComment);\n\n if (!name) {\n name = \"\";\n }\n\n if (!cls || !type || !content) {\n continue;\n }\n\n type = type.toUpperCase();\n content = (content || \"\").trim();\n if (dots && Object.keys(nameLike).includes(type)) {\n content = addDots(content, nameLike[type as keyof typeof nameLike]);\n }\n\n data.records.push({\n name: normalize(([\"\", \"@\"].includes(name) && data.origin) ? data.origin : name),\n ttl: parseTTL(ttl, data.ttl !== undefined ? data.ttl : defaultTTL),\n class: cls.toUpperCase(),\n type,\n content,\n comment: (comment || \"\").trim() || null,\n });\n }\n\n if (replaceOrigin) {\n data.origin = replaceOrigin;\n }\n\n return data as DnszDnsData;\n}\n\n/** Parse a `data` object and return a string with the zone file contents. */\nexport function stringifyZone(data: DnszDnsData, {crlf = false, sections = true, dots = false}: DnszStringifyOptions = {}): string {\n const recordsByType: Record<string, Array<DnszDnsRecord>> = {};\n const newline = crlf ? \"\\r\\n\" : \"\\n\";\n\n if (sections) {\n for (const record of data.records) {\n if (!recordsByType[record.type]) recordsByType[record.type] = [];\n recordsByType[record.type].push(record);\n }\n }\n\n let output = \"\";\n if (data.header) {\n output += `${data.header\n .split(/\\r?\\n/)\n .map(l => l.trim())\n .map(l => l ? `;; ${l}` : \";;\")\n .join(newline)\n .trim()}${newline}${newline}`;\n }\n\n const vars: Array<string> = [];\n if (data.origin) vars.push(`$ORIGIN ${denormalize(data.origin)}`);\n if (data.ttl) vars.push(`$TTL ${data.ttl}`);\n if (vars.length) output += `${vars.join(newline)}${newline}${newline}`;\n\n const origin = normalize(data.origin || \"\");\n if (sections) {\n if (recordsByType.SOA) {\n output += format(recordsByType.SOA, \"SOA\", {origin, newline, sections, dots});\n delete recordsByType.SOA;\n }\n\n for (const type of Object.keys(recordsByType).sort()) {\n output += format(recordsByType[type], type, {origin, newline, sections, dots});\n }\n } else {\n const recordsSOA = data.records.filter(r => r.type === \"SOA\");\n const recordsMinusSOA = data.records.filter(r => r.type !== \"SOA\");\n\n output += format(recordsSOA, null, {origin, newline, sections, dots});\n output += format(recordsMinusSOA, null, {origin, newline, sections, dots});\n }\n\n return `${output.trim()}${newline}`;\n}\n"],"mappings":"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"}
+55
-42

@@ -1,49 +0,62 @@

export type DnszDnsRecord = {
/**The lowercase DNS name without a trailing dot, e.g. `"example.com"`. */
name: string;
/** The TTL in seconds, e.g. `60`. */
ttl: number;
/** The DNS class, e.g. `"IN"`. */
class: string;
/** The record type, e.g. `"A"`. */
type: string;
/** The record content, e.g. `"2001:db8::1"` or `"example.com."`. */
content: string;
/** A comment, e.g. `"a comment"`, `null` if absent. */
comment: string | null;
//#region index.d.ts
type DnszDnsRecord = {
/**The lowercase DNS name without a trailing dot, e.g. `"example.com"`. */
name: string;
/** The TTL in seconds, e.g. `60`. */
ttl: number;
/** The DNS class, e.g. `"IN"`. */
class: string;
/** The record type, e.g. `"A"`. */
type: string;
/** The record content, e.g. `"2001:db8::1"` or `"example.com."`. */
content: string;
/** A comment, e.g. `"a comment"`, `null` if absent. */
comment: string | null;
};
export type DnszDnsData = {
/** Array of `record` */
records: DnszDnsRecord[];
/** The value of `$ORIGIN` in the zone file. */
origin?: string;
/** The value of `$TTL` in the zone file. */
ttl?: number;
/** An optional header at the start of the file. Can be multiline. Does not include comment markers. */
header?: string;
type DnszDnsData = {
/** Array of `record` */
records: Array<DnszDnsRecord>;
/** The value of `$ORIGIN` in the zone file. */
origin?: string;
/** The value of `$TTL` in the zone file. */
ttl?: number;
/** An optional header at the start of the file. Can be multiline. Does not include comment markers. */
header?: string;
};
export type DnszParseOptions = {
/** When specified, replaces any `@` in `name` or `content` with it. */
replaceOrigin?: string | null;
/** When true, emit `\r\n` instead of `\n` in `header`. */
crlf?: boolean;
/** Default class when absent. */
defaultClass?: string;
/** Default TTL when absent and `$TTL` is not present. */
defaultTTL?: number;
/** Ensure trailing dots on FQDNs in content. Supports a limited amount of record types. */
dots?: boolean;
type DnszParseOptions = {
/** When specified, replaces any `@` in `name` or `content` with it. */
replaceOrigin?: string | null;
/** When true, emit `\r\n` instead of `\n` in `header`. */
crlf?: boolean;
/** Default class when absent. */
defaultClass?: string;
/** Default TTL when absent and `$TTL` is not present. */
defaultTTL?: number;
/** Ensure trailing dots on FQDNs in content. Supports a limited amount of record types. */
dots?: boolean;
};
export type DnszStringifyOptions = {
/** Whether to group records into sections. */
sections?: boolean;
/** When `true`, emit `\r\n` instead of `\n` for the resulting zone file. */
crlf?: boolean;
/** Ensure trailing dots on FQDNs in content. Supports a limited amount of record types. Default: `false`. */
dots?: boolean;
type DnszStringifyOptions = {
/** Whether to group records into sections. */
sections?: boolean;
/** When `true`, emit `\r\n` instead of `\n` for the resulting zone file. */
crlf?: boolean;
/** Ensure trailing dots on FQDNs in content. Supports a limited amount of record types. Default: `false`. */
dots?: boolean;
};
/** Parse a string of a DNS zone file and returns a `data` object. */
export declare function parseZone(str: string, { replaceOrigin, crlf, defaultTTL, defaultClass, dots }?: DnszParseOptions): DnszDnsData;
declare function parseZone(str: string, {
replaceOrigin,
crlf,
defaultTTL,
defaultClass,
dots
}?: DnszParseOptions): DnszDnsData;
/** Parse a `data` object and return a string with the zone file contents. */
export declare function stringifyZone(data: DnszDnsData, { crlf, sections, dots }?: DnszStringifyOptions): string;
declare function stringifyZone(data: DnszDnsData, {
crlf,
sections,
dots
}?: DnszStringifyOptions): string;
//#endregion
export { DnszDnsData, DnszDnsRecord, DnszParseOptions, DnszStringifyOptions, parseZone, stringifyZone };
//# sourceMappingURL=index.d.ts.map

@@ -0,303 +1,268 @@

//#region index.ts
const nameLike = {
ALIAS: [0],
ANAME: [0],
CNAME: [0],
DNAME: [0],
MX: [1],
NAPTR: [5],
NS: [0],
NSEC: [0],
PTR: [0],
RP: [0, 1],
RRSIG: [7],
SIG: [7],
SOA: [0, 1],
SRV: [3],
TKEY: [0],
TSIG: [0]
ALIAS: [0],
ANAME: [0],
CNAME: [0],
DNAME: [0],
MX: [1],
NAPTR: [5],
NS: [0],
NSEC: [0],
PTR: [0],
RP: [0, 1],
RRSIG: [7],
SIG: [7],
SOA: [0, 1],
SRV: [3],
TKEY: [0],
TSIG: [0]
};
function normalize(name) {
name = (name || "").toLowerCase();
if (name.endsWith(".") && name.length > 1) {
name = name.substring(0, name.length - 1);
}
return name.replace(/\.{2,}/g, ".").replace(/@\./, "@");
name = (name || "").toLowerCase();
if (name.endsWith(".") && name.length > 1) name = name.substring(0, name.length - 1);
return name.replace(/\.{2,}/g, ".").replace(/@\./, "@");
}
function splitString(input, { separator = " ", quotes = [] } = {}) {
const ast = { type: "root", nodes: [], stash: [""] };
const stack = [ast];
const string = input;
let value;
let node;
let i = -1;
const state = {};
const block = () => state.block = stack[stack.length - 1];
const peek = () => string[i + 1];
const next = () => string[++i];
const append = (value2) => {
state.value = value2;
if (value2) {
state.block.stash[state.block.stash.length - 1] += value2;
}
};
const closeIndex = (value2, startIdx) => {
let idx = string.indexOf(value2, startIdx);
if (idx > -1 && string[idx - 1] === "\\") {
idx = closeIndex(value2, idx + 1);
}
return idx;
};
while (i < string.length - 1) {
state.value = value = next();
state.index = i;
block();
if (value === "\\") {
if (peek() === "\\") {
append(value + next());
} else {
append(value);
append(next());
}
continue;
}
if (quotes.includes(value)) {
const pos = i + 1;
const idx = closeIndex(value, pos);
if (idx > -1) {
append(value);
append(string.slice(pos, idx));
append(string[idx]);
i = idx;
continue;
}
append(value);
continue;
}
if (value === separator && state.block.type === "root") {
state.block.stash.push("");
continue;
}
append(value);
}
node = stack.pop();
while (node !== ast) {
value = node.parent.stash.pop() + node.stash.join(".");
node.parent.stash = node.parent.stash.concat(value.split("."));
node = stack.pop();
}
return node.stash;
const ast = {
type: "root",
nodes: [],
stash: [""]
};
const stack = [ast];
const string = input;
let value;
let node;
let i = -1;
const state = {
input,
separator,
stack,
prev: () => string[i - 1],
next: () => string[i + 1]
};
const block = () => state.block = stack[stack.length - 1];
const peek = () => string[i + 1];
const next = () => string[++i];
const append = (value$1) => {
state.value = value$1;
if (value$1) state.block.stash[state.block.stash.length - 1] += value$1;
};
const closeIndex = (value$1, startIdx) => {
let idx = string.indexOf(value$1, startIdx);
if (idx > -1 && string[idx - 1] === "\\") idx = closeIndex(value$1, idx + 1);
return idx;
};
while (i < string.length - 1) {
state.value = value = next();
state.index = i;
block();
if (value === "\\") {
if (peek() === "\\") append(value + next());
else {
append(value);
append(next());
}
continue;
}
if (quotes.includes(value)) {
const pos = i + 1;
const idx = closeIndex(value, pos);
if (idx > -1) {
append(value);
append(string.slice(pos, idx));
append(string[idx]);
i = idx;
continue;
}
append(value);
continue;
}
if (value === separator && state.block.type === "root") {
state.block.stash.push("");
continue;
}
append(value);
}
node = stack.pop();
while (node !== ast) {
value = node.parent.stash.pop() + node.stash.join(".");
node.parent.stash = node.parent.stash.concat(value.split("."));
node = stack.pop();
}
return node.stash;
}
function denormalize(name) {
if (!name.endsWith(".") && name.length > 1) {
name = `${name}.`;
}
return name.replace(/\.{2,}/g, ".").replace(/@\./, "@");
if (!name.endsWith(".") && name.length > 1) name = `${name}.`;
return name.replace(/\.{2,}/g, ".").replace(/@\./, "@");
}
function esc(str) {
return str.replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&");
return str.replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&");
}
function addDots(content, indexes) {
const parts = splitString(content, {
quotes: [`"`],
separator: " "
}).map((s) => s.trim()).filter(Boolean);
for (const index of indexes) {
if (!parts[index].endsWith(".")) {
parts[index] += ".";
}
}
return parts.join(" ");
const parts = splitString(content, {
quotes: [`"`],
separator: " "
}).map((s) => s.trim()).filter(Boolean);
for (const index of indexes) if (!parts[index].endsWith(".")) parts[index] += ".";
return parts.join(" ");
}
function parseTTL(ttl, def) {
if (typeof ttl === "number") {
return ttl;
}
if (def && !ttl) {
return def;
}
if (/s$/i.test(ttl)) {
ttl = parseInt(ttl);
} else if (/m$/i.test(ttl)) {
ttl = parseInt(ttl) * 60;
} else if (/h$/i.test(ttl)) {
ttl = parseInt(ttl) * 60 * 60;
} else if (/d$/i.test(ttl)) {
ttl = parseInt(ttl) * 60 * 60 * 24;
} else if (/w$/i.test(ttl)) {
ttl = parseInt(ttl) * 60 * 60 * 24 * 7;
} else {
ttl = parseInt(ttl);
}
return ttl;
if (typeof ttl === "number") return ttl;
if (def && !ttl) return def;
if (/s$/i.test(ttl)) ttl = parseInt(ttl);
else if (/m$/i.test(ttl)) ttl = parseInt(ttl) * 60;
else if (/h$/i.test(ttl)) ttl = parseInt(ttl) * 60 * 60;
else if (/d$/i.test(ttl)) ttl = parseInt(ttl) * 60 * 60 * 24;
else if (/w$/i.test(ttl)) ttl = parseInt(ttl) * 60 * 60 * 24 * 7;
else ttl = parseInt(ttl);
return ttl;
}
function format(records, type, { origin, newline, sections, dots }) {
let str = ``;
if (sections && type) {
str += `;; ${type} Records${newline}`;
}
for (const record of records || []) {
if (!record) continue;
let name = normalize(record.name || "");
if (origin) {
if (name === origin) {
name = "@";
} else if (name.endsWith(origin)) {
name = normalize(name.replace(new RegExp(`${esc(`${origin}.`)}?$`, "gm"), ""));
} else {
name = normalize(name);
}
} else {
if (name.includes(".")) {
name = denormalize(name);
} else {
name = normalize(name);
}
}
let content = record.content;
if (dots && Object.keys(nameLike).includes(record.type)) {
const indexes = nameLike[record.type];
content = addDots(content, indexes);
}
const fields = [
name,
record.ttl,
record.class,
record.type,
content
];
if (record.comment) {
fields.push(`; ${record.comment}`);
}
str += `${fields.join(" ")}${newline}`;
}
return `${str}${sections ? newline : ""}`;
let str = ``;
if (sections && type) str += `;; ${type} Records${newline}`;
for (const record of records || []) {
if (!record) continue;
let name = normalize(record.name || "");
if (origin) if (name === origin) name = "@";
else if (name.endsWith(origin)) name = normalize(name.replace(new RegExp(`${esc(`${origin}.`)}?$`, "gm"), ""));
else name = normalize(name);
else if (name.includes(".")) name = denormalize(name);
else name = normalize(name);
let content = record.content;
if (dots && Object.keys(nameLike).includes(record.type)) {
const indexes = nameLike[record.type];
content = addDots(content, indexes);
}
const fields = [
name,
record.ttl,
record.class,
record.type,
content
];
if (record.comment) fields.push(`; ${record.comment}`);
str += `${fields.join(" ")}${newline}`;
}
return `${str}${sections ? newline : ""}`;
}
function splitContentAndComment(str) {
if (!str) return [null, null];
const splitted = splitString(str, {
quotes: [`"`],
separator: ";"
});
let parts;
if (splitted.length > 2) {
parts = [splitted[0], splitted.slice(1).join(";")];
} else {
parts = splitted;
}
parts = parts.map((part) => (part || "").trim()).filter(Boolean);
if (parts.length <= 2) {
return [parts[0] || null, parts[1] || null];
} else {
const comment = parts.pop();
const content = parts.join("; ");
return [content, comment];
}
if (!str) return [null, null];
const splitted = splitString(str, {
quotes: [`"`],
separator: ";"
});
let parts;
if (splitted.length > 2) parts = [splitted[0], splitted.slice(1).join(";")];
else parts = splitted;
parts = parts.map((part) => (part || "").trim()).filter(Boolean);
if (parts.length <= 2) return [parts[0] || null, parts[1] || null];
else {
const comment = parts.pop();
return [parts.join("; "), comment];
}
}
/** Parse a string of a DNS zone file and returns a `data` object. */
function parseZone(str, { replaceOrigin = null, crlf = false, defaultTTL = 60, defaultClass = "IN", dots = false } = {}) {
const data = {};
const rawLines = str.split(/\r?\n/).map((l) => l.trim());
const lines = rawLines.filter((l) => Boolean(l) && !l.startsWith(";"));
const newline = crlf ? "\r\n" : "\n";
const headerLines = [];
let valid;
for (const [index, line] of rawLines.entries()) {
if (line.startsWith(";;")) {
headerLines.push(line.substring(2).trim());
} else {
const prev = rawLines[index - 1];
if (line === "" && index > 1 && prev.startsWith(";;")) {
valid = true;
break;
}
}
}
if (valid && headerLines.length) {
data.header = headerLines.join(newline);
}
const reLine = /^([a-z0-9_.\-@*]+)?\s*([0-9]+[smhdw]?)?\s*([a-z]+)?\s+([a-z]+[0-9]*)?\s+(.+)$/i;
data.records = [];
for (const line of lines) {
const parsedOrigin = (/\$ORIGIN\s+(\S+)/.exec(line) || [])[1];
if (parsedOrigin && !data.origin) {
data.origin = normalize(parsedOrigin);
}
const parsedTtl = (/\$TTL\s+(\S+)/.exec(line) || [])[1];
if (line.startsWith("$TTL ") && !data.ttl) {
data.ttl = parseTTL(normalize(parsedTtl));
}
let [, name, ttl, cls, type, contentAndComment] = reLine.exec(line) || [];
if (!ttl && name && /[0-9]+/.test(name)) {
ttl = name;
name = "";
}
if (cls && !type) {
type = cls;
cls = "";
}
if (!cls) {
cls = defaultClass;
}
let [content, comment] = splitContentAndComment(contentAndComment);
if (!name) {
name = "";
}
if (!cls || !type || !content) {
continue;
}
type = type.toUpperCase();
content = (content || "").trim();
if (dots && Object.keys(nameLike).includes(type)) {
content = addDots(content, nameLike[type]);
}
data.records.push({
name: normalize(["", "@"].includes(name) && data.origin ? data.origin : name),
ttl: parseTTL(ttl, data.ttl !== void 0 ? data.ttl : defaultTTL),
class: cls.toUpperCase(),
type,
content,
comment: (comment || "").trim() || null
});
}
if (replaceOrigin) {
data.origin = replaceOrigin;
}
return data;
const data = {};
const rawLines = str.split(/\r?\n/).map((l) => l.trim());
const lines = rawLines.filter((l) => Boolean(l) && !l.startsWith(";"));
const newline = crlf ? "\r\n" : "\n";
const headerLines = [];
let valid = false;
for (const [index, line] of rawLines.entries()) if (line.startsWith(";;")) headerLines.push(line.substring(2).trim());
else {
const prev = rawLines[index - 1];
if (line === "" && index > 1 && prev.startsWith(";;")) {
valid = true;
break;
}
}
if (valid && headerLines.length) data.header = headerLines.join(newline);
const reLine = /^([a-z0-9_.\-@*]+)?\s*([0-9]+[smhdw]?)?\s*([a-z]+)?\s+([a-z]+[0-9]*)?\s+(.+)$/i;
data.records = [];
for (const line of lines) {
const parsedOrigin = (/\$ORIGIN\s+(\S+)/.exec(line) || [])[1];
if (parsedOrigin && !data.origin) data.origin = normalize(parsedOrigin);
const parsedTtl = (/\$TTL\s+(\S+)/.exec(line) || [])[1];
if (line.startsWith("$TTL ") && !data.ttl) data.ttl = parseTTL(normalize(parsedTtl));
let [, name, ttl, cls, type, contentAndComment] = reLine.exec(line) || [];
if (!ttl && name && /[0-9]+/.test(name)) {
ttl = name;
name = "";
}
if (cls && !type) {
type = cls;
cls = "";
}
if (!cls) cls = defaultClass;
let [content, comment] = splitContentAndComment(contentAndComment);
if (!name) name = "";
if (!cls || !type || !content) continue;
type = type.toUpperCase();
content = (content || "").trim();
if (dots && Object.keys(nameLike).includes(type)) content = addDots(content, nameLike[type]);
data.records.push({
name: normalize(["", "@"].includes(name) && data.origin ? data.origin : name),
ttl: parseTTL(ttl, data.ttl !== void 0 ? data.ttl : defaultTTL),
class: cls.toUpperCase(),
type,
content,
comment: (comment || "").trim() || null
});
}
if (replaceOrigin) data.origin = replaceOrigin;
return data;
}
/** Parse a `data` object and return a string with the zone file contents. */
function stringifyZone(data, { crlf = false, sections = true, dots = false } = {}) {
const recordsByType = {};
const newline = crlf ? "\r\n" : "\n";
if (sections) {
for (const record of data.records) {
if (!recordsByType[record.type]) recordsByType[record.type] = [];
recordsByType[record.type].push(record);
}
}
let output = "";
if (data.header) {
output += `${data.header.split(/\r?\n/).map((l) => l.trim()).map((l) => l ? `;; ${l}` : ";;").join(newline).trim()}${newline}${newline}`;
}
const vars = [];
if (data.origin) vars.push(`$ORIGIN ${denormalize(data.origin)}`);
if (data.ttl) vars.push(`$TTL ${data.ttl}`);
if (vars.length) output += `${vars.join(newline)}${newline}${newline}`;
const origin = normalize(data.origin);
if (sections) {
if (recordsByType.SOA) {
output += format(recordsByType.SOA, "SOA", { origin, newline, sections, dots });
delete recordsByType.SOA;
}
for (const type of Object.keys(recordsByType).sort()) {
output += format(recordsByType[type], type, { origin, newline, sections, dots });
}
} else {
const recordsSOA = data.records.filter((r) => r.type === "SOA");
const recordsMinusSOA = data.records.filter((r) => r.type !== "SOA");
output += format(recordsSOA, null, { origin, newline, sections, dots });
output += format(recordsMinusSOA, null, { origin, newline, sections, dots });
}
return `${output.trim()}${newline}`;
const recordsByType = {};
const newline = crlf ? "\r\n" : "\n";
if (sections) for (const record of data.records) {
if (!recordsByType[record.type]) recordsByType[record.type] = [];
recordsByType[record.type].push(record);
}
let output = "";
if (data.header) output += `${data.header.split(/\r?\n/).map((l) => l.trim()).map((l) => l ? `;; ${l}` : ";;").join(newline).trim()}${newline}${newline}`;
const vars = [];
if (data.origin) vars.push(`$ORIGIN ${denormalize(data.origin)}`);
if (data.ttl) vars.push(`$TTL ${data.ttl}`);
if (vars.length) output += `${vars.join(newline)}${newline}${newline}`;
const origin = normalize(data.origin || "");
if (sections) {
if (recordsByType.SOA) {
output += format(recordsByType.SOA, "SOA", {
origin,
newline,
sections,
dots
});
delete recordsByType.SOA;
}
for (const type of Object.keys(recordsByType).sort()) output += format(recordsByType[type], type, {
origin,
newline,
sections,
dots
});
} else {
const recordsSOA = data.records.filter((r) => r.type === "SOA");
const recordsMinusSOA = data.records.filter((r) => r.type !== "SOA");
output += format(recordsSOA, null, {
origin,
newline,
sections,
dots
});
output += format(recordsMinusSOA, null, {
origin,
newline,
sections,
dots
});
}
return `${output.trim()}${newline}`;
}
export {
parseZone,
stringifyZone
};
//#endregion
export { parseZone, stringifyZone };
//# sourceMappingURL=index.js.map
{
"name": "dnsz",
"version": "4.3.2",
"version": "4.3.4",
"description": "Generic DNS zone file parser and stringifier",

@@ -17,13 +17,14 @@ "author": "silverwind <me@silverwind.io>",

"devDependencies": {
"@types/node": "22.15.3",
"eslint": "8.57.0",
"eslint-config-silverwind": "100.1.4",
"typescript-config-silverwind": "9.0.7",
"updates": "16.4.2",
"versions": "12.1.3",
"vite": "6.3.3",
"vite-config-silverwind": "5.2.3",
"vitest": "3.1.2",
"vitest-config-silverwind": "10.0.2"
"@types/node": "24.10.1",
"eslint": "9.39.1",
"eslint-config-silverwind": "112.0.1",
"tsdown": "0.16.7",
"tsdown-config-silverwind": "1.5.3",
"typescript-config-silverwind": "14.0.0",
"updates": "16.9.1",
"versions": "14.0.3",
"vite-config-silverwind": "6.0.5",
"vitest": "4.0.14",
"vitest-config-silverwind": "10.4.2"
}
}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IACxB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACtB,wBAAwB;IACxB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uGAAuG;IACvG,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,uEAAuE;IACvE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2FAA2F;IAC3F,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6GAA6G;IAC7G,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAuPF,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,EAAC,aAAoB,EAAE,IAAY,EAAE,UAAe,EAAE,YAAmB,EAAE,IAAY,EAAC,GAAE,gBAAqB,GAAG,WAAW,CAmFnK;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,EAAC,IAAY,EAAE,QAAe,EAAE,IAAY,EAAC,GAAE,oBAAyB,GAAG,MAAM,CA6CjI"}