-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrunner.js
More file actions
64 lines (58 loc) · 2.25 KB
/
Copy pathrunner.js
File metadata and controls
64 lines (58 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Talks to the local repolens-runner (deeper-scan daemon). Best-effort: every failure —
// runner offline, bad status, timeout — resolves to null so Deep Dive proceeds unchanged.
export const DEFAULT_RUNNER_URL = 'http://localhost:9191';
const POLL_INTERVAL_MS = 1000;
const POLL_TIMEOUT_MS = 90_000;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
export function normalizeRunnerUrl(url) {
return (url || '').trim().replace(/\/+$/, '') || DEFAULT_RUNNER_URL;
}
/**
* Liveness check for the runner. Returns { ok, docker, version } — `ok:false` when the runner
* is offline or unhealthy (never throws). Used to surface a status pill in the UI.
*/
export async function pingRunner(runnerUrl) {
const base = normalizeRunnerUrl(runnerUrl);
try {
const res = await fetch(`${base}/health`);
if (!res.ok) return { ok: false };
const data = await res.json();
return { ok: data.status === 'ok', docker: !!data.docker, version: data.version || '' };
} catch {
return { ok: false };
}
}
/**
* Scan a github/gitlab `owner/repo` via the runner. Returns the Facts object, or null for
* unsupported platforms / bare ids / any runner failure (never throws).
*/
export async function scanRepo(runnerUrl, platform, repoId) {
if (platform !== 'github' && platform !== 'gitlab') return null;
const slash = (repoId || '').indexOf('/');
if (slash < 1) return null;
const owner = repoId.slice(0, slash);
const repo = repoId.slice(slash + 1);
const base = normalizeRunnerUrl(runnerUrl);
try {
const res = await fetch(`${base}/scan`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ platform, owner, repo }),
});
if (!res.ok) return null;
const { jobId } = await res.json();
if (!jobId) return null;
const deadline = Date.now() + POLL_TIMEOUT_MS;
while (Date.now() < deadline) {
const pr = await fetch(`${base}/scan/${jobId}`);
if (!pr.ok) return null;
const data = await pr.json();
if (data.status === 'done') return data.facts || null;
if (data.status === 'error') return null;
await sleep(POLL_INTERVAL_MS);
}
return null; // timed out
} catch {
return null; // runner offline / network error → graceful
}
}