Private
Public Access
feat: initial Go/JS/Rust Origin check-in client SDKs
CI / rust (push) Successful in 3m6s
CI / go (push) Successful in 33s
CI / js (push) Successful in 34s
CI / rust (push) Successful in 3m6s
CI / go (push) Successful in 33s
CI / js (push) Successful in 34s
Standalone clients that resolve a machine unique ID (OS machine ID first, falling back to a generated UUID persisted to disk), detect hostname/IP/ container/orchestrator, and register+re-ping origin.warky.dev's public service-checkin endpoint on a daily interval. Ported from icy2's internal origincheckin package but extended to the full check-in contract and made dependency-light for external reuse. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
import { createServer, type IncomingMessage, type Server, type ServerResponse } from "node:http";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { OriginClient } from "../src/client.js";
|
||||
|
||||
function withServer(
|
||||
handler: (req: IncomingMessage, res: ServerResponse) => void,
|
||||
): Promise<{ server: Server; url: string }> {
|
||||
return new Promise((resolve) => {
|
||||
const server = createServer(handler);
|
||||
server.listen(0, "127.0.0.1", () => {
|
||||
const address = server.address();
|
||||
const port = typeof address === "object" && address ? address.port : 0;
|
||||
resolve({ server, url: `http://127.0.0.1:${port}` });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe("OriginClient", () => {
|
||||
it("requires serviceKey/type/version/name", () => {
|
||||
expect(() => new OriginClient({ serviceKey: "", type: "", version: "", name: "" })).toThrow();
|
||||
});
|
||||
|
||||
it("sends the expected payload and headers on checkinOnce", async () => {
|
||||
let gotKey = "";
|
||||
let gotBody: Record<string, unknown> = {};
|
||||
const { server, url } = await withServer((req, res) => {
|
||||
gotKey = req.headers["x-origin-service-key"] as string;
|
||||
let raw = "";
|
||||
req.on("data", (chunk) => {
|
||||
raw += chunk;
|
||||
});
|
||||
req.on("end", () => {
|
||||
gotBody = JSON.parse(raw);
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
success: true,
|
||||
service_instance_id: 42,
|
||||
unique_install_id: gotBody.unique_install_id,
|
||||
status: "provisioning",
|
||||
pinged_at: "2026-08-01T00:00:00Z",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
const client = new OriginClient({
|
||||
url,
|
||||
serviceKey: "test-key",
|
||||
type: "icy2",
|
||||
version: "v1.0.0",
|
||||
name: "icy2-test",
|
||||
installId: "test-install-id",
|
||||
});
|
||||
|
||||
const resp = await client.checkinOnce();
|
||||
|
||||
expect(gotKey).toBe("test-key");
|
||||
expect(gotBody.type).toBe("icy2");
|
||||
expect(gotBody.name).toBe("icy2-test");
|
||||
expect(gotBody.unique_install_id).toBe("test-install-id");
|
||||
expect(resp.success).toBe(true);
|
||||
expect(resp.service_instance_id).toBe(42);
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("throws on a non-2xx response", async () => {
|
||||
const { server, url } = await withServer((_req, res) => {
|
||||
res.writeHead(500);
|
||||
res.end();
|
||||
});
|
||||
|
||||
try {
|
||||
const client = new OriginClient({
|
||||
url,
|
||||
serviceKey: "test-key",
|
||||
type: "icy2",
|
||||
version: "v1.0.0",
|
||||
name: "icy2-test",
|
||||
installId: "test-install-id",
|
||||
});
|
||||
|
||||
await expect(client.checkinOnce()).rejects.toThrow();
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("does not throw for an unreachable server", async () => {
|
||||
const client = new OriginClient({
|
||||
url: "http://127.0.0.1:1",
|
||||
serviceKey: "test-key",
|
||||
type: "icy2",
|
||||
version: "v1.0.0",
|
||||
name: "icy2-test",
|
||||
installId: "test-install-id",
|
||||
});
|
||||
|
||||
await expect(client.checkinOnce()).rejects.toThrow();
|
||||
});
|
||||
|
||||
it("start() checks in immediately and stop() prevents further calls", async () => {
|
||||
let calls = 0;
|
||||
const { server, url } = await withServer((_req, res) => {
|
||||
calls += 1;
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
success: true,
|
||||
service_instance_id: 1,
|
||||
unique_install_id: "x",
|
||||
status: "provisioning",
|
||||
pinged_at: "2026-08-01T00:00:00Z",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
const client = new OriginClient({
|
||||
url,
|
||||
serviceKey: "test-key",
|
||||
type: "icy2",
|
||||
version: "v1.0.0",
|
||||
name: "icy2-test",
|
||||
installId: "test-install-id",
|
||||
intervalHours: 24,
|
||||
});
|
||||
|
||||
client.start();
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
client.stop();
|
||||
|
||||
expect(calls).toBe(1);
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user