Download packages/cli/src/commands/handlers/api.ts from SaylorTwift/opencode: direct link, hf CLI and curl.
- Browser
- Download file 3.43 kB
-
https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/cli/src/commands/handlers/api.ts
- Command line
-
hf download hf://SaylorTwift/opencode/packages/cli/src/commands/handlers/api.ts
-
curl -L -o api.ts https://huggingface.co/SaylorTwift/opencode/resolve/main/packages/cli/src/commands/handlers/api.ts
3.43 kB
| import { EOL } from "node:os" | |
| import { Effect, Option } from "effect" | |
| import { Commands } from "../commands" | |
| import { Runtime } from "../../framework/runtime" | |
| import { Daemon } from "../../services/daemon" | |
| const methods = new Set(["delete", "get", "head", "options", "patch", "post", "put"]) | |
| type Operation = { | |
| operationId?: string | |
| } | |
| type OpenApi = { | |
| paths?: Record<string, Record<string, Operation>> | |
| } | |
| export default Runtime.handler( | |
| Commands.commands.api, | |
| Effect.fn("cli.api")(function* (input) { | |
| const daemon = yield* Daemon.Service | |
| const transport = yield* daemon.transport() | |
| const params = Option.getOrElse(input.param, () => ({})) | |
| const request = yield* resolveRequest(transport, input.request, params) | |
| const headers = new Headers(transport.headers) | |
| for (const header of input.header) { | |
| const index = header.indexOf(":") | |
| if (index < 1) return yield* Effect.fail(new Error(`Invalid header, expected name:value: ${header}`)) | |
| headers.set(header.slice(0, index).trim(), header.slice(index + 1).trim()) | |
| } | |
| const body = Option.getOrUndefined(input.data) | |
| if (body !== undefined && !headers.has("content-type")) headers.set("content-type", "application/json") | |
| const response = yield* Effect.tryPromise(() => | |
| fetch(new URL(request.path, transport.url), { | |
| method: request.method, | |
| headers, | |
| body, | |
| }), | |
| ) | |
| const output = yield* Effect.promise(() => response.text()) | |
| if (output) process.stdout.write(output + (output.endsWith(EOL) ? "" : EOL)) | |
| }), | |
| ) | |
| export function resolveOperation(spec: OpenApi, operationID: string, params: Record<string, string>) { | |
| for (const [path, operations] of Object.entries(spec.paths ?? {})) { | |
| for (const [method, operation] of Object.entries(operations)) { | |
| if (!methods.has(method) || operation.operationId !== operationID) continue | |
| return { method: method.toUpperCase(), path: interpolate(path, params) } | |
| } | |
| } | |
| throw new Error(`Operation not found: ${operationID}`) | |
| } | |
| export function rawRequest(input: readonly string[]) { | |
| if (input.length !== 2 || !methods.has(input[0].toLowerCase()) || !input[1].startsWith("/")) return | |
| return { method: input[0].toUpperCase(), path: input[1] } | |
| } | |
| function resolveRequest( | |
| transport: { url: string; headers: RequestInit["headers"] }, | |
| input: readonly string[], | |
| params: Record<string, string>, | |
| ) { | |
| const raw = rawRequest(input) | |
| if (raw) return Effect.succeed(raw) | |
| if (input.length !== 1) return Effect.fail(new Error("Expected an operation name or an HTTP method and path")) | |
| return Effect.tryPromise(async () => { | |
| const response = await fetch(new URL("/openapi.json", transport.url), { headers: transport.headers }) | |
| if (!response.ok) throw new Error(`Failed to load OpenAPI document: HTTP ${response.status}`) | |
| return resolveOperation((await response.json()) as OpenApi, input[0], params) | |
| }) | |
| } | |
| function interpolate(path: string, params: Record<string, string>) { | |
| const used = new Set<string>() | |
| const pathname = path.replaceAll(/\{([^}]+)\}/g, (_, name: string) => { | |
| const value = params[name] | |
| if (value === undefined) throw new Error(`Missing path parameter: ${name}`) | |
| used.add(name) | |
| return encodeURIComponent(value) | |
| }) | |
| const query = new URLSearchParams(Object.entries(params).filter(([name]) => !used.has(name))).toString() | |
| return query ? `${pathname}?${query}` : pathname | |
| } | |