Files
uptimerunner/ts/api-client.ts
T

98 lines
2.5 KiB
TypeScript
Raw Normal View History

2026-04-29 19:48:14 +00:00
import type {
ICheckPollResponse,
IHeartbeatRequest,
IResultSubmitRequest,
IUptimeCheckResult,
IUptimeRunnerConfig,
TCheckJob,
} from './interfaces.ts';
export class UptimeRunnerApiClient {
private readonly instanceUrl: URL;
private readonly token: string;
constructor(configArg: IUptimeRunnerConfig) {
this.instanceUrl = new URL(configArg.instanceUrl);
this.token = configArg.token;
}
public async fetchAssignedChecks(
runnerIdArg: string,
labelsArg: string[] = [],
): Promise<TCheckJob[]> {
const url = this.createUrl('/api/runner/v1/checks');
url.searchParams.set('runnerId', runnerIdArg);
for (const label of labelsArg) {
url.searchParams.append('label', label);
}
const responseData = await this.requestJson<ICheckPollResponse | TCheckJob[]>(url, {
method: 'GET',
});
if (Array.isArray(responseData)) {
return responseData;
}
if (!Array.isArray(responseData.checks)) {
throw new Error('Invalid check poll response: expected checks array.');
}
return responseData.checks;
}
public async submitResults(runnerIdArg: string, resultsArg: IUptimeCheckResult[]): Promise<void> {
if (resultsArg.length === 0) {
return;
}
const body: IResultSubmitRequest = {
runnerId: runnerIdArg,
results: resultsArg,
};
await this.requestJson(this.createUrl('/api/runner/v1/results'), {
method: 'POST',
body: JSON.stringify(body),
});
}
public async heartbeat(requestArg: IHeartbeatRequest): Promise<void> {
await this.requestJson(this.createUrl('/api/runner/v1/heartbeat'), {
method: 'POST',
body: JSON.stringify(requestArg),
});
}
private createUrl(pathArg: string): URL {
return new URL(pathArg, this.instanceUrl);
}
private async requestJson<T = unknown>(urlArg: URL, initArg: RequestInit): Promise<T> {
const response = await fetch(urlArg, {
...initArg,
headers: {
accept: 'application/json',
authorization: `Bearer ${this.token}`,
'content-type': 'application/json',
...(initArg.headers ?? {}),
},
});
if (!response.ok) {
const body = await response.text().catch(() => '');
throw new Error(
`uptime.link API ${
initArg.method ?? 'GET'
} ${urlArg.pathname} failed: ${response.status} ${body}`,
);
}
if (response.status === 204) {
return undefined as T;
}
return await response.json() as T;
}
}