Files
cloudflare-domain-manager/packages/shared/src/subdomain.ts
T
DenozordecandCursor 0d567379fa
quality / commitlint (push) Skipped
CD / update-wiki (push) Successful in 6s
quality / changes (push) Successful in 10s
quality / docker-check (push) Skipped
quality / web (push) Successful in 1m16s
quality / api (push) Successful in 1m14s
CD / quality (push) Successful in 2m44s
CD / publish (push) Successful in 1m50s
fix(services): разрешить несколько доп. FQDN на IP включая wildcard
У IP был один extra FQDN; wildcard вида *.mdns.shnt.top не матчился с именем из Cloudflare.

Co-authored-by: Cursor <[email protected]>
2026-08-31 12:40:27 +07:00

54 lines
1.4 KiB
TypeScript

export function dnsNameToSubdomainLabel(
recordName: string,
zoneName: string,
): string | null {
const rn = recordName.trim().replace(/\.+$/, "");
const zn = zoneName.trim().replace(/\.+$/, "");
if (!rn || !zn) return null;
if (rn === "*") return "*";
const wildcardFqdn = `*.${zn}`;
if (rn.toLowerCase() === wildcardFqdn.toLowerCase()) return "*";
if (rn.toLowerCase() === zn.toLowerCase()) return "@";
const zoneSuffix = `.${zn}`;
if (rn.toLowerCase().endsWith(zoneSuffix.toLowerCase())) {
const prefix = rn.slice(0, rn.length - zoneSuffix.length);
return prefix || "@";
}
if (rn.startsWith("*.")) return rn;
if (!rn.includes(".")) return rn;
return null;
}
export function subdomainLabelToFqdn(label: string, zoneName: string): string {
return label === "@" ? zoneName : `${label}.${zoneName}`;
}
/** Canonical DNS record name as returned by Cloudflare for a zone. */
export function normalizeDnsRecordName(
recordName: string,
zoneName: string,
): string {
const label = dnsNameToSubdomainLabel(recordName, zoneName);
if (label == null) {
return recordName.trim().replace(/\.+$/, "");
}
return subdomainLabelToFqdn(label, zoneName);
}
export function dnsRecordNamesMatch(
left: string,
right: string,
zoneName: string,
): boolean {
return (
normalizeDnsRecordName(left, zoneName).toLowerCase() ===
normalizeDnsRecordName(right, zoneName).toLowerCase()
);
}