@opendray/sdk 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +62 -0
- package/dist/index.cjs +317 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +209 -0
- package/dist/index.d.ts +209 -0
- package/dist/index.js +287 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/events.ts","../src/session.ts"],"sourcesContent":["import type {\n Channel,\n Integration,\n IntegrationCreated,\n IntegrationRegistration,\n IntegrationUpdate,\n Provider,\n Session,\n SessionBuffer,\n SessionCreateRequest,\n SessionInputRequest,\n SessionResizeRequest,\n} from \"./types.js\";\n\nexport interface ClientOptions {\n /** Base URL of the gateway, e.g. `https://opendray.example.com`. */\n baseUrl: string;\n /** Admin bearer token or integration API key (`odk_live_…`). */\n token: string;\n /** Optional custom fetch (e.g. for proxying or instrumentation). */\n fetch?: typeof fetch;\n /** Default request timeout in ms. 30s if omitted. 0 disables. */\n timeoutMs?: number;\n}\n\nexport class OpendrayError extends Error {\n readonly status: number;\n readonly body: unknown;\n constructor(status: number, body: unknown, message: string) {\n super(message);\n this.name = \"OpendrayError\";\n this.status = status;\n this.body = body;\n }\n}\n\nexport class Client {\n readonly baseUrl: string;\n readonly token: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n\n constructor(opts: ClientOptions) {\n if (!opts.baseUrl) throw new Error(\"Client: baseUrl is required\");\n if (!opts.token) throw new Error(\"Client: token is required\");\n let trimmed = opts.baseUrl;\n while (trimmed.endsWith(\"/\")) trimmed = trimmed.slice(0, -1);\n this.baseUrl = trimmed;\n this.token = opts.token;\n this.fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!this.fetchImpl) {\n throw new Error(\n \"Client: no fetch available — pass `fetch` in options on platforms older than Node 18.\",\n );\n }\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n // ── low level ──────────────────────────────────────────────────────\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const url = `${this.baseUrl}/api/v1${path}`;\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.token}`,\n Accept: \"application/json\",\n };\n let payload: BodyInit | undefined;\n if (body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n payload = JSON.stringify(body);\n }\n\n const ctrl = this.timeoutMs > 0 ? new AbortController() : null;\n const timer = ctrl\n ? setTimeout(() => ctrl.abort(new Error(\"request timed out\")), this.timeoutMs)\n : null;\n\n const init: RequestInit = { method, headers };\n if (payload !== undefined) init.body = payload;\n if (ctrl) init.signal = ctrl.signal;\n\n try {\n const res = await this.fetchImpl(url, init);\n const text = await res.text();\n let parsed: unknown = undefined;\n if (text.length > 0) {\n try {\n parsed = JSON.parse(text);\n } catch {\n parsed = text;\n }\n }\n if (!res.ok) {\n const msg =\n (parsed && typeof parsed === \"object\" && \"error\" in parsed\n ? String((parsed as { error: unknown }).error)\n : undefined) ?? `${method} ${path} -> ${res.status}`;\n throw new OpendrayError(res.status, parsed, msg);\n }\n return parsed as T;\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n // ── integrations (admin-only) ──────────────────────────────────────\n\n registerIntegration(input: IntegrationRegistration): Promise<IntegrationCreated> {\n return this.request(\"POST\", \"/integrations\", input);\n }\n\n listIntegrations(): Promise<Integration[]> {\n return this.request(\"GET\", \"/integrations\");\n }\n\n getIntegration(id: string): Promise<Integration> {\n return this.request(\"GET\", `/integrations/${encodeURIComponent(id)}`);\n }\n\n updateIntegration(id: string, patch: IntegrationUpdate): Promise<Integration> {\n return this.request(\"PATCH\", `/integrations/${encodeURIComponent(id)}`, patch);\n }\n\n deleteIntegration(id: string): Promise<void> {\n return this.request(\"DELETE\", `/integrations/${encodeURIComponent(id)}`);\n }\n\n rotateIntegrationKey(id: string): Promise<IntegrationCreated> {\n return this.request(\"POST\", `/integrations/${encodeURIComponent(id)}/rotate-key`);\n }\n\n // ── sessions (dual-auth) ───────────────────────────────────────────\n\n createSession(input: SessionCreateRequest): Promise<Session> {\n return this.request(\"POST\", \"/sessions\", input);\n }\n\n listSessions(): Promise<Session[]> {\n return this.request(\"GET\", \"/sessions\");\n }\n\n getSession(id: string): Promise<Session> {\n return this.request(\"GET\", `/sessions/${encodeURIComponent(id)}`);\n }\n\n deleteSession(id: string): Promise<void> {\n return this.request(\"DELETE\", `/sessions/${encodeURIComponent(id)}`);\n }\n\n sendInput(id: string, input: SessionInputRequest): Promise<void> {\n return this.request(\"POST\", `/sessions/${encodeURIComponent(id)}/input`, input);\n }\n\n resizeSession(id: string, size: SessionResizeRequest): Promise<void> {\n return this.request(\"POST\", `/sessions/${encodeURIComponent(id)}/resize`, size);\n }\n\n getSessionBuffer(id: string): Promise<SessionBuffer> {\n return this.request(\"GET\", `/sessions/${encodeURIComponent(id)}/buffer`);\n }\n\n // ── providers / channels (dual-auth) ───────────────────────────────\n\n listProviders(): Promise<Provider[]> {\n return this.request(\"GET\", \"/providers\");\n }\n\n setProviderConfig(id: string, config: Record<string, unknown>): Promise<Provider> {\n return this.request(\n \"PATCH\",\n `/providers/${encodeURIComponent(id)}/config`,\n config,\n );\n }\n\n listChannels(): Promise<Channel[]> {\n return this.request(\"GET\", \"/channels\");\n }\n\n // ── ws helpers (URLs only — open via subscribeEvents / streamSession) ─\n\n /**\n * Compose the WS URL for the events stream. Used by `subscribeEvents`,\n * exposed publicly for callers that want to manage the socket lifecycle\n * themselves.\n */\n eventsUrl(topics: string[]): string {\n const u = new URL(`${this.baseUrl}/api/v1/integrations/_events`);\n u.protocol = u.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n u.searchParams.set(\"token\", this.token);\n if (topics.length > 0) u.searchParams.set(\"topics\", topics.join(\",\"));\n return u.toString();\n }\n\n sessionStreamUrl(id: string): string {\n const u = new URL(\n `${this.baseUrl}/api/v1/sessions/${encodeURIComponent(id)}/stream`,\n );\n u.protocol = u.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n u.searchParams.set(\"token\", this.token);\n return u.toString();\n }\n}\n","import type { Client } from \"./client.js\";\nimport type { EventFrame } from \"./types.js\";\n\nexport interface SubscribeOptions {\n /** Topic patterns. Use `session.*` for prefix wildcards. */\n topics: string[];\n /** AbortSignal closes the socket and ends the iterator. */\n signal?: AbortSignal;\n /**\n * Custom WebSocket implementation. Defaults to globalThis.WebSocket.\n * On Node <22 you'll need to pass `ws`'s default export.\n */\n WebSocket?: typeof globalThis.WebSocket;\n /** Reconnect on unexpected close. Defaults to true. */\n reconnect?: boolean;\n /** Initial backoff in ms (doubles up to 30s). Defaults to 1000. */\n reconnectBaseMs?: number;\n}\n\n/**\n * Returns an async iterable that yields one EventFrame per server message.\n * Reconnects automatically on transient drops; an AbortSignal ends the\n * stream cleanly.\n *\n * ```ts\n * for await (const frame of subscribeEvents(client, { topics: [\"session.*\"] })) {\n * console.log(frame.topic, frame.data);\n * }\n * ```\n */\nexport async function* subscribeEvents<T = unknown>(\n client: Client,\n opts: SubscribeOptions,\n): AsyncGenerator<EventFrame<T>, void, void> {\n const WS = opts.WebSocket ?? globalThis.WebSocket;\n if (!WS) {\n throw new Error(\n \"subscribeEvents: no WebSocket available. On Node <22 import 'ws' and pass it via `WebSocket`.\",\n );\n }\n\n const url = client.eventsUrl(opts.topics);\n const reconnect = opts.reconnect ?? true;\n const baseDelay = opts.reconnectBaseMs ?? 1000;\n let attempt = 0;\n\n while (true) {\n if (opts.signal?.aborted) return;\n const queue: EventFrame<T>[] = [];\n let resolve: (() => void) | null = null;\n let closed = false;\n let closeReason: Error | null = null;\n\n const ws = new WS(url);\n ws.addEventListener(\"message\", (ev: MessageEvent) => {\n try {\n const frame = JSON.parse(String(ev.data)) as EventFrame<T>;\n queue.push(frame);\n if (resolve) {\n const r = resolve;\n resolve = null;\n r();\n }\n } catch (err) {\n closeReason = err instanceof Error ? err : new Error(String(err));\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n }\n });\n ws.addEventListener(\"close\", () => {\n closed = true;\n if (resolve) {\n const r = resolve;\n resolve = null;\n r();\n }\n });\n ws.addEventListener(\"error\", (ev: Event) => {\n closeReason = new Error(`websocket error: ${(ev as ErrorEvent).message ?? \"unknown\"}`);\n });\n\n const onAbort = () => {\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n };\n opts.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n try {\n while (!closed) {\n while (queue.length > 0) {\n const frame = queue.shift()!;\n yield frame;\n attempt = 0; // reset backoff on successful delivery\n }\n if (closed) break;\n await new Promise<void>((r) => {\n resolve = r;\n });\n }\n } finally {\n opts.signal?.removeEventListener(\"abort\", onAbort);\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n }\n\n if (opts.signal?.aborted) return;\n if (closeReason) throw closeReason;\n if (!reconnect) return;\n\n attempt += 1;\n const delay = Math.min(30_000, baseDelay * 2 ** (attempt - 1));\n await new Promise((r) => setTimeout(r, delay));\n }\n}\n","import type { Client } from \"./client.js\";\n\nexport interface SessionStreamHandle {\n /** Send raw bytes to the session's PTY stdin. */\n send(data: string): void;\n /** Close the stream. */\n close(): void;\n /** Resolves when the socket closes (cleanly or with an error). */\n readonly closed: Promise<void>;\n}\n\nexport interface SessionStreamOptions {\n /** Called with each chunk of terminal output. */\n onOutput?: (data: string) => void;\n /** Called when the server reports the session has ended. */\n onEnded?: (info: { exitCode?: number | undefined; reason?: string | undefined }) => void;\n /** AbortSignal closes the socket. */\n signal?: AbortSignal;\n /**\n * Custom WebSocket implementation. Defaults to globalThis.WebSocket.\n * On Node <22 pass `ws`'s default export.\n */\n WebSocket?: typeof globalThis.WebSocket;\n}\n\n/**\n * Open a bidirectional terminal stream against the given session.\n *\n * The wire format is gateway-specific JSON frames:\n * { kind: \"output\", data: \"<chunk>\" } (server → client)\n * { kind: \"ended\", exit_code?, reason? } (server → client)\n * { kind: \"input\", data: \"<chunk>\" } (client → server)\n *\n * The returned handle exposes `send()` and `close()`, and a `closed`\n * promise that resolves when the socket finishes.\n */\nexport function streamSession(\n client: Client,\n sessionId: string,\n opts: SessionStreamOptions = {},\n): SessionStreamHandle {\n const WS = opts.WebSocket ?? globalThis.WebSocket;\n if (!WS) {\n throw new Error(\n \"streamSession: no WebSocket available. On Node <22 import 'ws' and pass it via `WebSocket`.\",\n );\n }\n\n const ws = new WS(client.sessionStreamUrl(sessionId));\n let resolveClosed!: () => void;\n const closed = new Promise<void>((r) => {\n resolveClosed = r;\n });\n\n ws.addEventListener(\"message\", (ev: MessageEvent) => {\n let frame: { kind?: string; data?: string; exit_code?: number; reason?: string };\n try {\n frame = JSON.parse(String(ev.data));\n } catch {\n return;\n }\n if (frame.kind === \"output\" && typeof frame.data === \"string\") {\n opts.onOutput?.(frame.data);\n } else if (frame.kind === \"ended\") {\n opts.onEnded?.({ exitCode: frame.exit_code, reason: frame.reason });\n }\n });\n ws.addEventListener(\"close\", () => {\n resolveClosed();\n });\n\n const onAbort = () => {\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n };\n opts.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n return {\n send(data: string) {\n if (ws.readyState !== WS.OPEN) {\n throw new Error(\"streamSession: socket not open\");\n }\n ws.send(JSON.stringify({ kind: \"input\", data }));\n },\n close() {\n try {\n ws.close();\n } catch {\n /* ignore */\n }\n },\n closed,\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opendray/sdk",
|
|
3
|
+
"version": "2.6.0",
|
|
4
|
+
"description": "TypeScript client for the opendray gateway: REST + WebSocket access to sessions, channels, integrations, and events.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://opendray.dev",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/Opendray/opendray.git",
|
|
10
|
+
"directory": "npm/sdk"
|
|
11
|
+
},
|
|
12
|
+
"bugs": "https://github.com/Opendray/opendray/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"opendray",
|
|
15
|
+
"sdk",
|
|
16
|
+
"claude-code",
|
|
17
|
+
"codex",
|
|
18
|
+
"gemini",
|
|
19
|
+
"ai-coding-agent",
|
|
20
|
+
"self-hosted"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/index.cjs",
|
|
24
|
+
"module": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js",
|
|
30
|
+
"require": "./dist/index.cjs"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsup",
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"prepublishOnly": "npm run build"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "^22.0.0",
|
|
48
|
+
"tsup": "^8.3.0",
|
|
49
|
+
"typescript": "^5.6.0"
|
|
50
|
+
}
|
|
51
|
+
}
|