Init 2
This commit is contained in:
1 parent
ce00c4c671
commit
bdb9b72fac
66 files changed
+9553
-1547
No files matched your search
@@ -0,0 +1,22 @@
|
||||
/** Объединяет несколько AbortSignal: один abort отменяет общий контроллер. */
|
||||
export function mergeAbortSignals(...signals: AbortSignal[]): AbortSignal {
|
||||
const c = new AbortController()
|
||||
const forward = () => {
|
||||
c.abort()
|
||||
}
|
||||
for (const s of signals) {
|
||||
if (s.aborted) {
|
||||
forward()
|
||||
return c.signal
|
||||
}
|
||||
s.addEventListener("abort", forward, { once: true })
|
||||
}
|
||||
return c.signal
|
||||
}
|
||||
|
||||
/** Отмена через `ms` миллисекунд (таймер не снимается при другой отмене — ок для короткоживущих запросов). */
|
||||
export function abortAfterMs(ms: number): AbortSignal {
|
||||
const c = new AbortController()
|
||||
setTimeout(() => c.abort(), ms)
|
||||
return c.signal
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import dns from "node:dns/promises"
|
||||
|
||||
/** RouterOS «src-address» для /tool/ping и /tool/traceroute ожидает IPv4, не FQDN. */
|
||||
export function isIpv4Literal(host: string): boolean {
|
||||
const s = host.trim()
|
||||
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(s)) return false
|
||||
return s.split(".").every((p) => {
|
||||
const n = Number.parseInt(p, 10)
|
||||
return Number.isFinite(n) && n >= 0 && n <= 255
|
||||
})
|
||||
}
|
||||
|
||||
/** Возвращает первый A-запись IPv4 для управления; если host уже IPv4 — как есть. */
|
||||
export async function resolveRosSrcIpv4(host: string): Promise<string | null> {
|
||||
const h = host.trim()
|
||||
if (!h) return null
|
||||
if (isIpv4Literal(h)) return h
|
||||
try {
|
||||
const addrs = await dns.resolve4(h)
|
||||
return addrs[0] ?? null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user