Download src/api/no-direct-agent-server-calls.test.ts from SaylorTwift/openhands: direct link, hf CLI and curl.
- Browser
- Download file 2.71 kB
-
https://huggingface.co/SaylorTwift/openhands/resolve/main/src/api/no-direct-agent-server-calls.test.ts
- Command line
-
hf download hf://SaylorTwift/openhands/src/api/no-direct-agent-server-calls.test.ts
-
curl -L -o no-direct-agent-server-calls.test.ts https://huggingface.co/SaylorTwift/openhands/resolve/main/src/api/no-direct-agent-server-calls.test.ts
2.71 kB
| import { describe, expect, it } from "vitest"; | |
| import { readdirSync, readFileSync } from "node:fs"; | |
| import { join, relative } from "node:path"; | |
| const SRC_ROOT = join(process.cwd(), "src"); | |
| const EXCLUDED_SEGMENTS = new Set(["mocks", "routeTree.gen.ts"]); | |
| const ALLOWED_AD_HOC_HTTP_FILES = new Set([ | |
| "api/automation-service/automation-service.api.ts", | |
| "api/cloud/proxy.ts", | |
| "api/main-app-auth.ts", | |
| ]); | |
| function collectSourceFiles(dir: string): string[] { | |
| return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => { | |
| const fullPath = join(dir, entry.name); | |
| // Normalize to forward slashes so the path matches ALLOWED_AD_HOC_HTTP_FILES | |
| // entries on Windows where path.relative() returns backslash-separated paths. | |
| const relPath = relative(SRC_ROOT, fullPath).replace(/\\/g, "/"); | |
| if (entry.isDirectory()) { | |
| if (EXCLUDED_SEGMENTS.has(entry.name)) return []; | |
| return collectSourceFiles(fullPath); | |
| } | |
| if (EXCLUDED_SEGMENTS.has(entry.name)) return []; | |
| if (!/\.(ts|tsx)$/.test(entry.name)) return []; | |
| if (/\.(test|spec)\.(ts|tsx)$/.test(entry.name)) return []; | |
| return [relPath]; | |
| }); | |
| } | |
| describe("agent-server API access", () => { | |
| it("uses typed @openhands/typescript-client access instead of ad-hoc HTTP", () => { | |
| const violations = collectSourceFiles(SRC_ROOT).flatMap((relPath) => { | |
| const source = readFileSync(join(SRC_ROOT, relPath), "utf8"); | |
| const fileViolations: string[] = []; | |
| if (/openHands\s*\./.test(source)) { | |
| fileViolations.push("uses the shared axios instance directly"); | |
| } | |
| if (/\bcreateHttpClient\s*\(/.test(source)) { | |
| fileViolations.push("uses createHttpClient directly"); | |
| } | |
| if ( | |
| /from\s+["']@openhands\/typescript-client\/client\/http-client["']/.test( | |
| source, | |
| ) | |
| ) { | |
| fileViolations.push("imports the low-level SDK HttpClient directly"); | |
| } | |
| if (/\bnew\s+HttpClient\s*\(/.test(source)) { | |
| fileViolations.push("constructs HttpClient directly"); | |
| } | |
| if ( | |
| (/\baxios\s*\(/.test(source) || | |
| /\baxios\s*\.\s*(?:create|get|post|put|patch|delete|request)\s*\(/.test( | |
| source, | |
| )) && | |
| !ALLOWED_AD_HOC_HTTP_FILES.has(relPath) | |
| ) { | |
| fileViolations.push("uses axios directly for HTTP calls"); | |
| } | |
| if ( | |
| /\bfetch\s*\([\s\S]{0,200}['"`]\/api\//.test(source) && | |
| !ALLOWED_AD_HOC_HTTP_FILES.has(relPath) | |
| ) { | |
| fileViolations.push("calls an /api path with fetch directly"); | |
| } | |
| return fileViolations.map((violation) => `${relPath}: ${violation}`); | |
| }); | |
| expect(violations).toEqual([]); | |
| }); | |
| }); | |