35 lines
2.0 KiB
TypeScript
35 lines
2.0 KiB
TypeScript
import type { FastifyPluginAsyncZod } from "@fastify/type-provider-zod"
|
|
import { speedTestCommandSchema, type SpeedTestCommand } from "@mmapp/contracts"
|
|
import type { SpeedTestRunResult } from "../services/uptime-speed-service.js"
|
|
import { SpeedProbeContextChanged, SpeedRunPersistenceUnknown } from "../services/speed-run-persistence.js"
|
|
import { speedRunErrorMessage } from "../services/speed-run-error-message.js"
|
|
|
|
export function createSpeedTestRoute(deps: {
|
|
serverExists: (id: number) => Promise<boolean>
|
|
run: (command: SpeedTestCommand) => Promise<SpeedTestRunResult>
|
|
failure: (command: SpeedTestCommand & { message: string }) => Promise<void>
|
|
}): FastifyPluginAsyncZod {
|
|
return async app => {
|
|
app.post("/uptime/speed-test", async (req, reply) => {
|
|
const parsed = speedTestCommandSchema.safeParse(req.body)
|
|
if (!parsed.success) return reply.code(400).send({ error: "Проверьте источник, назначение, протокол, направление и целую длительность теста от 3 секунд." })
|
|
const command = parsed.data
|
|
const exists = await Promise.all([deps.serverExists(command.srcServerId), deps.serverExists(command.dstServerId)])
|
|
if (exists.some(value => !value)) return reply.code(404).send({ error: "Server not found" })
|
|
try {
|
|
return reply.send({ ok: true, result: await deps.run(command) })
|
|
} catch (error) {
|
|
if (error instanceof SpeedRunPersistenceUnknown) {
|
|
return reply.code(502).send({ error: error.message, outcome: "unknown", runId: error.runId })
|
|
}
|
|
const raw = error instanceof Error ? error.message : "Bandwidth test failed"
|
|
await deps.failure({ ...command, message: raw })
|
|
const message = speedRunErrorMessage(raw)
|
|
if (error instanceof SpeedProbeContextChanged) return reply.code(409).send({ error: message })
|
|
if (/активного IP|Server not found/i.test(raw)) return reply.code(400).send({ error: message })
|
|
return reply.code(502).send({ error: message })
|
|
}
|
|
})
|
|
}
|
|
}
|