Init 2
This commit is contained in:
1 parent
ce00c4c671
commit
bdb9b72fac
66 files changed
+9553
-1547
No files matched your search
@@ -79,6 +79,7 @@ function rosPost(
|
||||
path: string,
|
||||
body: Record<string, string>,
|
||||
timeoutMs: number,
|
||||
externalSignal?: AbortSignal,
|
||||
): Promise<unknown> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const basePath = params.apiPath ?? "/rest"
|
||||
@@ -100,25 +101,55 @@ function rosPost(
|
||||
|
||||
const lib = params.useSsl ? https : http
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
req.destroy(new Error(`Connection to ${params.host}:${params.port} timed out after ${timeoutMs / 1000}s`))
|
||||
}, timeoutMs)
|
||||
let req: ReturnType<typeof lib.request> | undefined
|
||||
|
||||
const req = lib.request(options, (res) => {
|
||||
let settled = false
|
||||
const settle = (fn: () => void) => {
|
||||
if (settled) return
|
||||
settled = true
|
||||
if (req) {
|
||||
req.setTimeout(0)
|
||||
req.removeListener("timeout", onSocketTimeout)
|
||||
}
|
||||
externalSignal?.removeEventListener("abort", onExternalAbort)
|
||||
fn()
|
||||
}
|
||||
|
||||
const onExternalAbort = () => {
|
||||
req?.destroy(new DOMException("Aborted", "AbortError"))
|
||||
}
|
||||
|
||||
const onSocketTimeout = () => {
|
||||
req?.destroy()
|
||||
settle(() => reject(new Error(`Connection to ${params.host}:${params.port} timed out after ${timeoutMs / 1000}s`)))
|
||||
}
|
||||
|
||||
if (externalSignal?.aborted) {
|
||||
settle(() => reject(new DOMException("Aborted", "AbortError")))
|
||||
return
|
||||
}
|
||||
externalSignal?.addEventListener("abort", onExternalAbort)
|
||||
|
||||
req = lib.request(options, (res) => {
|
||||
let buf = ""
|
||||
res.setEncoding("utf8")
|
||||
res.on("data", (chunk: string) => { buf += chunk })
|
||||
res.on("end", () => {
|
||||
clearTimeout(timer)
|
||||
if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
|
||||
reject(new MikrotikError(res.statusCode ?? 0, path, buf)); return
|
||||
}
|
||||
try { resolve(JSON.parse(buf)) } catch {
|
||||
reject(new Error(`Invalid JSON from RouterOS: ${buf.slice(0, 200)}`))
|
||||
}
|
||||
settle(() => {
|
||||
if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
|
||||
reject(new MikrotikError(res.statusCode ?? 0, path, buf)); return
|
||||
}
|
||||
try { resolve(JSON.parse(buf)) } catch {
|
||||
reject(new Error(`Invalid JSON from RouterOS: ${buf.slice(0, 200)}`))
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
req.on("error", (err) => { clearTimeout(timer); reject(err) })
|
||||
req.setTimeout(timeoutMs)
|
||||
req.on("timeout", onSocketTimeout)
|
||||
req.on("error", (err) => {
|
||||
settle(() => reject(err))
|
||||
})
|
||||
req.write(payload)
|
||||
req.end()
|
||||
})
|
||||
@@ -189,8 +220,8 @@ export class MikrotikClient {
|
||||
return rosRequest(this.params, path, timeoutMs) as Promise<T>
|
||||
}
|
||||
|
||||
async post<T>(path: string, body: Record<string, string>, timeoutMs = 15_000): Promise<T> {
|
||||
return rosPost(this.params, path, body, timeoutMs) as Promise<T>
|
||||
async post<T>(path: string, body: Record<string, string>, timeoutMs = 15_000, signal?: AbortSignal): Promise<T> {
|
||||
return rosPost(this.params, path, body, timeoutMs, signal) as Promise<T>
|
||||
}
|
||||
|
||||
async delete(path: string, timeoutMs = 10_000): Promise<void> {
|
||||
@@ -260,12 +291,18 @@ export class MikrotikClient {
|
||||
return this.get<RosLogEntry[]>(`/log?limit=${limit}`)
|
||||
}
|
||||
|
||||
async ping(address: string, count = 4, interfaceName?: string): Promise<RosPingResult[]> {
|
||||
async ping(
|
||||
address: string,
|
||||
count = 4,
|
||||
interfaceName?: string,
|
||||
options?: { interval?: string },
|
||||
): Promise<RosPingResult[]> {
|
||||
const body: Record<string, string> = {
|
||||
address,
|
||||
count: String(count),
|
||||
interval: "0.2s",
|
||||
}
|
||||
if (options?.interval && options.interval.trim()) body.interval = options.interval.trim()
|
||||
else body.interval = "0.2s"
|
||||
if (interfaceName && interfaceName.trim()) body.interface = interfaceName.trim()
|
||||
return this.post<RosPingResult[]>("/tool/ping", body, 20_000)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user