get-db9 0.5.0 → 0.6.1

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/credentials.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["export class Db9Error extends Error {\n readonly statusCode: number;\n readonly response?: Response;\n\n constructor(message: string, statusCode: number, response?: Response) {\n super(message);\n this.name = 'Db9Error';\n this.statusCode = statusCode;\n this.response = response;\n }\n\n static async fromResponse(response: Response): Promise<Db9Error> {\n // Parse { \"message\": string } body — the ONLY error format from the API\n let message: string;\n try {\n const body = (await response.json()) as { message?: string };\n message = body.message || response.statusText;\n } catch {\n message = response.statusText;\n }\n\n // Return specific subclass based on status code\n switch (response.status) {\n case 401:\n return new Db9AuthError(message, response);\n case 404:\n return new Db9NotFoundError(message, response);\n case 409:\n return new Db9ConflictError(message, response);\n default:\n return new Db9Error(message, response.status, response);\n }\n }\n}\n\nexport class Db9AuthError extends Db9Error {\n constructor(message: string, response?: Response) {\n super(message, 401, response);\n this.name = 'Db9AuthError';\n }\n}\n\nexport class Db9NotFoundError extends Db9Error {\n constructor(message: string, response?: Response) {\n super(message, 404, response);\n this.name = 'Db9NotFoundError';\n }\n}\n\nexport class Db9ConflictError extends Db9Error {\n constructor(message: string, response?: Response) {\n super(message, 409, response);\n this.name = 'Db9ConflictError';\n }\n}\n","import { Db9Error } from './errors';\n\nexport type FetchFn = typeof globalThis.fetch;\n\n// BodyInit type for raw request bodies (string, Blob, ArrayBuffer, etc.)\nexport type BodyInit = string | Blob | ArrayBuffer | FormData | URLSearchParams | ReadableStream<Uint8Array>;\n\nexport interface HttpClientOptions {\n baseUrl: string;\n fetch?: FetchFn;\n headers?: Record<string, string>;\n timeout?: number; // Request timeout in ms (default: none)\n maxRetries?: number; // Max retry attempts on 5xx/network errors (default: 0 = disabled)\n retryDelay?: number; // Base delay in ms for exponential backoff (default: 1000)\n}\n\nexport interface HttpClient {\n get<T>(path: string, params?: Record<string, string | undefined>): Promise<T>;\n post<T>(path: string, body?: unknown): Promise<T>;\n put<T>(path: string, body?: unknown): Promise<T>;\n del<T>(path: string): Promise<T>;\n getRaw(path: string, params?: Record<string, string | undefined>): Promise<Response>;\n putRaw(path: string, body: BodyInit, headers?: Record<string, string>): Promise<Response>;\n postRaw(path: string, body?: BodyInit, headers?: Record<string, string>): Promise<Response>;\n delRaw(path: string, params?: Record<string, string | undefined>): Promise<Response>;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function createHttpClient(options: HttpClientOptions): HttpClient {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const baseUrl = options.baseUrl.replace(/\\/$/, '');\n\n async function request<T>(\n method: string,\n path: string,\n body?: unknown,\n params?: Record<string, string | undefined>\n ): Promise<T> {\n let url = `${baseUrl}${path}`;\n\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) searchParams.set(key, value);\n }\n const qs = searchParams.toString();\n if (qs) url += `?${qs}`;\n }\n\n const reqHeaders: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const init: RequestInit = { method, headers: reqHeaders };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const maxAttempts = Math.min(options.maxRetries ?? 0, 3) + 1;\n const baseDelay = options.retryDelay ?? 1000;\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n const fetchInit = { ...init };\n if (options.timeout) {\n const controller = new AbortController();\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => controller.abort(), options.timeout);\n }\n\n const response = await fetchFn(url, fetchInit);\n if (timeoutId) clearTimeout(timeoutId);\n\n if (!response.ok) {\n if (response.status >= 500 && attempt < maxAttempts - 1) {\n lastError = await Db9Error.fromResponse(response);\n await delay(baseDelay * Math.pow(2, attempt));\n continue;\n }\n throw await Db9Error.fromResponse(response);\n }\n\n if (response.status === 204) return undefined as T;\n return response.json() as Promise<T>;\n } catch (err) {\n if (timeoutId) clearTimeout(timeoutId);\n if (err instanceof TypeError && attempt < maxAttempts - 1) {\n lastError = err;\n await delay(baseDelay * Math.pow(2, attempt));\n continue;\n }\n throw err;\n }\n }\n throw lastError;\n }\n\n async function requestRaw(\n method: string,\n path: string,\n body?: BodyInit,\n params?: Record<string, string | undefined>,\n customHeaders?: Record<string, string>\n ): Promise<Response> {\n let url = `${baseUrl}${path}`;\n\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) searchParams.set(key, value);\n }\n const qs = searchParams.toString();\n if (qs) url += `?${qs}`;\n }\n\n const headers: Record<string, string> = {\n ...options.headers,\n ...customHeaders,\n };\n\n const fetchInit: RequestInit = { method, headers };\n if (body !== undefined) fetchInit.body = body;\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n if (options.timeout) {\n const controller = new AbortController();\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => controller.abort(), options.timeout);\n }\n\n try {\n const response = await fetchFn(url, fetchInit);\n if (timeoutId) clearTimeout(timeoutId);\n if (!response.ok) throw await Db9Error.fromResponse(response);\n return response;\n } catch (err) {\n if (timeoutId) clearTimeout(timeoutId);\n throw err;\n }\n }\n\n return {\n get: <T>(path: string, params?: Record<string, string | undefined>) =>\n request<T>('GET', path, undefined, params),\n post: <T>(path: string, body?: unknown) => request<T>('POST', path, body),\n put: <T>(path: string, body?: unknown) => request<T>('PUT', path, body),\n del: <T>(path: string) => request<T>('DELETE', path),\n getRaw: (path: string, params?: Record<string, string | undefined>) =>\n requestRaw('GET', path, undefined, params),\n putRaw: (path: string, body: BodyInit, headers?: Record<string, string>) =>\n requestRaw('PUT', path, body, undefined, headers),\n postRaw: (path: string, body?: BodyInit, headers?: Record<string, string>) =>\n requestRaw('POST', path, body, undefined, headers),\n delRaw: (path: string, params?: Record<string, string | undefined>) =>\n requestRaw('DELETE', path, undefined, params),\n };\n}\n","import { parse as parseToml, stringify as stringifyToml } from '@iarna/toml';\n\n// ---------------------------------------------------------------------------\n// Interfaces\n// ---------------------------------------------------------------------------\n\n/** Credential fields stored in `~/.db9/credentials` (TOML). */\nexport interface Credentials {\n token: string;\n is_anonymous?: boolean;\n anonymous_id?: string;\n anonymous_secret?: string;\n}\n\n/** Async credential persistence abstraction. */\nexport interface CredentialStore {\n load(): Promise<Credentials | null>;\n save(credentials: Credentials): Promise<void>;\n clear(): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// FileCredentialStore — TOML file at ~/.db9/credentials (matches db9 CLI)\n// ---------------------------------------------------------------------------\n\nexport class FileCredentialStore implements CredentialStore {\n private readonly customPath: string | undefined;\n\n /**\n * @param path — Override the credential file location.\n * Defaults to `~/.db9/credentials` (resolved lazily).\n */\n constructor(path?: string) {\n this.customPath = path;\n }\n\n /** Resolve the credential file path (lazy to avoid top-level `os` import). */\n private async resolvePath(): Promise<string> {\n if (this.customPath) return this.customPath;\n const os = await import('node:os');\n const nodePath = await import('node:path');\n return nodePath.join(os.homedir(), '.db9', 'credentials');\n }\n\n async load(): Promise<Credentials | null> {\n const fs = await import('node:fs/promises');\n const filePath = await this.resolvePath();\n\n let content: string;\n try {\n content = await fs.readFile(filePath, 'utf-8');\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n\n const parsed = parseToml(content);\n const token = parsed['token'];\n if (typeof token !== 'string') return null;\n\n const creds: Credentials = { token };\n if (typeof parsed['is_anonymous'] === 'boolean') {\n creds.is_anonymous = parsed['is_anonymous'];\n }\n if (typeof parsed['anonymous_id'] === 'string') {\n creds.anonymous_id = parsed['anonymous_id'];\n }\n if (typeof parsed['anonymous_secret'] === 'string') {\n creds.anonymous_secret = parsed['anonymous_secret'];\n }\n\n return creds;\n }\n\n async save(credentials: Credentials): Promise<void> {\n const fs = await import('node:fs/promises');\n const nodePath = await import('node:path');\n const filePath = await this.resolvePath();\n const dir = nodePath.dirname(filePath);\n\n // Ensure directory exists with 0o700 (matches CLI: ensure_config_dir)\n await fs.mkdir(dir, { recursive: true, mode: 0o700 });\n\n // Read → merge → write (preserves unknown fields as scalars)\n const data: Record<string, string | boolean | number> = {};\n try {\n const raw = await fs.readFile(filePath, 'utf-8');\n const parsed = parseToml(raw);\n for (const [k, v] of Object.entries(parsed)) {\n if (typeof v === 'string' || typeof v === 'boolean' || typeof v === 'number') {\n data[k] = v;\n }\n }\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n\n // Merge: always update token, only override optional fields when provided\n data['token'] = credentials.token;\n if (credentials.is_anonymous !== undefined) {\n data['is_anonymous'] = credentials.is_anonymous;\n }\n if (credentials.anonymous_id !== undefined) {\n data['anonymous_id'] = credentials.anonymous_id;\n }\n if (credentials.anonymous_secret !== undefined) {\n data['anonymous_secret'] = credentials.anonymous_secret;\n }\n\n // Serialize and write with 0o600 permissions (matches CLI: save_token)\n const toml = stringifyToml(\n data as Parameters<typeof stringifyToml>[0],\n );\n await fs.writeFile(filePath, toml, { mode: 0o600 });\n }\n\n async clear(): Promise<void> {\n const fs = await import('node:fs/promises');\n const filePath = await this.resolvePath();\n\n try {\n await fs.unlink(filePath);\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// MemoryCredentialStore — in-memory, no persistence\n// ---------------------------------------------------------------------------\n\nexport class MemoryCredentialStore implements CredentialStore {\n private credentials: Credentials | null = null;\n\n async load(): Promise<Credentials | null> {\n return this.credentials ? { ...this.credentials } : null;\n }\n\n async save(credentials: Credentials): Promise<void> {\n this.credentials = {\n token: credentials.token,\n is_anonymous: credentials.is_anonymous ?? this.credentials?.is_anonymous,\n anonymous_id: credentials.anonymous_id ?? this.credentials?.anonymous_id,\n anonymous_secret: credentials.anonymous_secret ?? this.credentials?.anonymous_secret,\n };\n }\n\n async clear(): Promise<void> {\n this.credentials = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/** Returns a FileCredentialStore with the default path (`~/.db9/credentials`). */\nexport function defaultCredentialStore(): CredentialStore {\n return new FileCredentialStore();\n}\n","import { createHttpClient, type FetchFn, type HttpClient, type BodyInit } from './http';\nimport {\n defaultCredentialStore,\n type CredentialStore,\n} from './credentials';\nimport { Db9Error } from './errors';\nimport type { Fs9FileEntry, Fs9ListOptions } from './fs-types';\nimport type {\n RegisterRequest,\n CustomerResponse,\n LoginRequest,\n LoginResponse,\n AnonymousRegisterResponse,\n AnonymousRefreshRequest,\n AnonymousRefreshResponse,\n AnonymousSecretResponse,\n ClaimRequest,\n ClaimResponse,\n TokenResponse,\n MessageResponse,\n CreateDatabaseRequest,\n DatabaseResponse,\n CustomerPasswordResetResponse,\n TenantObservabilityResponse,\n SqlResult,\n SqlErrorDetail,\n SchemaResponse,\n DumpRequest,\n DumpResponse,\n MigrationApplyRequest,\n MigrationApplyResponse,\n MigrationMetadata,\n BranchRequest,\n UserResponse,\n CreateUserRequest,\n CreateTokenRequest,\n CreateTokenResponse,\n Fs9EventEntry,\n Fs9EventOptions,\n} from './types';\n\nexport interface Db9ClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\n timeout?: number;\n maxRetries?: number;\n retryDelay?: number;\n}\n\nexport function createDb9Client(options: Db9ClientOptions = {}) {\n const baseUrl =\n options.baseUrl ?? 'https://db9.shared.aws.tidbcloud.com/api';\n let token = options.token;\n let tokenLoaded = !!token;\n const store = options.credentialStore ?? defaultCredentialStore();\n const fetchFn = options.fetch ?? globalThis.fetch;\n\n // Public HTTP client — no Authorization header\n const publicClient = createHttpClient({\n baseUrl,\n fetch: options.fetch,\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n retryDelay: options.retryDelay,\n });\n\n // Lazy-loading authenticated HTTP client\n async function getAuthClient(): Promise<HttpClient> {\n if (!token && !tokenLoaded) {\n const creds = await store.load();\n if (creds?.token) token = creds.token;\n tokenLoaded = true;\n }\n if (!token) {\n const reg = await publicClient.post<AnonymousRegisterResponse>(\n '/customer/anonymous-register'\n );\n token = reg.token;\n await store.save({\n token: reg.token,\n is_anonymous: reg.is_anonymous,\n anonymous_id: reg.anonymous_id,\n anonymous_secret: reg.anonymous_secret,\n });\n }\n return createHttpClient({\n baseUrl,\n fetch: options.fetch,\n headers: { Authorization: `Bearer ${token}` },\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n retryDelay: options.retryDelay,\n });\n }\n\n // ── Token auto-refresh on 401 ─────────────────────────────────\n let refreshPromise: Promise<void> | null = null;\n\n async function refreshAnonymousToken(): Promise<void> {\n const creds = await store.load();\n if (!creds?.anonymous_id || !creds?.anonymous_secret) {\n throw new Error('Not an anonymous session');\n }\n const resp = await publicClient.post<AnonymousRefreshResponse>(\n '/customer/anonymous-refresh',\n {\n anonymous_id: creds.anonymous_id,\n anonymous_secret: creds.anonymous_secret,\n }\n );\n token = resp.token;\n await store.save({ ...creds, token: resp.token });\n }\n\n async function withAuthRetry<T>(\n operation: (client: HttpClient) => Promise<T>\n ): Promise<T> {\n const client = await getAuthClient();\n try {\n return await operation(client);\n } catch (err) {\n if (!(err instanceof Db9Error) || err.statusCode !== 401) {\n throw err;\n }\n // 401 — try anonymous refresh\n try {\n if (!refreshPromise) {\n refreshPromise = refreshAnonymousToken();\n }\n await refreshPromise;\n } catch {\n throw err; // Refresh failed — throw original 401\n } finally {\n refreshPromise = null;\n }\n // Retry with new token\n const newClient = await getAuthClient();\n return operation(newClient);\n }\n }\n\n // ── fs9 helpers ──────────────────────────────────────────────\n function deriveFs9Url(dbId: string): string {\n const origin = baseUrl.replace(/\\/api\\/?$/, '');\n return `${origin}/fs9/${dbId}`;\n }\n\n // ── FS-specific auth retry (shares refreshPromise singleton) ──\n function getFsClient(dbId: string): HttpClient {\n const fs9Base = deriveFs9Url(dbId) + '/api/v1';\n return createHttpClient({\n baseUrl: fs9Base,\n fetch: options.fetch,\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n retryDelay: options.retryDelay,\n });\n }\n\n async function withFsAuthRetry<T>(\n dbId: string,\n operation: (client: HttpClient) => Promise<T>\n ): Promise<T> {\n // Ensure token is loaded first\n if (!token && !tokenLoaded) {\n await getAuthClient(); // triggers lazy auth\n }\n const client = getFsClient(dbId);\n try {\n return await operation(client);\n } catch (err) {\n if (!(err instanceof Db9Error) || err.statusCode !== 401) {\n throw err;\n }\n try {\n if (!refreshPromise) {\n refreshPromise = refreshAnonymousToken();\n }\n await refreshPromise;\n } catch {\n throw err;\n } finally {\n refreshPromise = null;\n }\n const newClient = getFsClient(dbId);\n return operation(newClient);\n }\n }\n\n // ── SQL Error Parsing ────────────────────────────────────────\n function parseSqlError(raw: string): SqlErrorDetail {\n // Strategy 1: Try JSON.parse\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed === 'object' && parsed !== null && typeof parsed.message === 'string') {\n return parsed as SqlErrorDetail;\n }\n } catch {\n // not JSON, continue\n }\n\n // Strategy 2: Regex for PostgreSQL-style errors\n const pgMatch = raw.match(/^(?:ERROR:\\s*)?(.+?)(?:\\s+DETAIL:\\s+(.+?))?(?:\\s+HINT:\\s+(.+?))?(?:\\s+\\(SQLSTATE\\s+(\\w+)\\))?$/s);\n if (pgMatch && pgMatch[1]) {\n const result: SqlErrorDetail = { message: pgMatch[1].trim() };\n if (pgMatch[2]) result.detail = pgMatch[2].trim();\n if (pgMatch[3]) result.hint = pgMatch[3].trim();\n if (pgMatch[4]) result.code = pgMatch[4];\n return result;\n }\n\n // Strategy 3: Fallback\n return { message: raw };\n }\n\n async function fsStat(dbId: string, path: string): Promise<Fs9FileEntry> {\n return withFsAuthRetry(dbId, (client) =>\n client.get<Fs9FileEntry>('/stat', { path })\n );\n }\n\n // ── Anonymous Secret Helper ──────────────────────────────────\n async function fetchAnonymousSecret(): Promise<AnonymousSecretResponse> {\n return withAuthRetry((client) =>\n client.post<AnonymousSecretResponse>('/customer/anonymous-secret', {})\n );\n }\n\n return {\n auth: {\n // Public endpoints (no token required)\n register: (req: RegisterRequest) =>\n publicClient.post<CustomerResponse>('/customer/register', req),\n\n login: (req: LoginRequest) =>\n publicClient.post<LoginResponse>('/customer/login', req),\n\n anonymousRegister: () =>\n publicClient.post<AnonymousRegisterResponse>(\n '/customer/anonymous-register'\n ),\n\n anonymousRefresh: (req: AnonymousRefreshRequest) =>\n publicClient.post<AnonymousRefreshResponse>(\n '/customer/anonymous-refresh',\n req\n ),\n\n // Authenticated endpoints\n me: async () =>\n withAuthRetry((client) =>\n client.get<CustomerResponse>('/customer/me')\n ),\n\n getAnonymousSecret: (): Promise<AnonymousSecretResponse> => {\n return fetchAnonymousSecret();\n },\n\n claim: async (req: ClaimRequest) =>\n withAuthRetry((client) =>\n client.post<ClaimResponse>('/customer/claim', req)\n ),\n\n ensureAnonymousSecret: async () => {\n const creds = await store.load();\n if (!creds?.anonymous_id || creds.anonymous_secret) {\n return; // No anonymous_id, or secret already exists\n }\n // Anonymous session without a secret — fetch one\n const resp = await fetchAnonymousSecret();\n await store.save({\n ...creds,\n anonymous_secret: resp.anonymous_secret,\n });\n },\n },\n\n tokens: {\n list: async () =>\n withAuthRetry((client) =>\n client.get<TokenResponse[]>('/customer/tokens')\n ),\n\n revoke: async (tokenId: string) =>\n withAuthRetry((client) =>\n client.del<MessageResponse>(`/customer/tokens/${tokenId}`)\n ),\n\n create: async (req: CreateTokenRequest) =>\n withAuthRetry((client) =>\n client.post<CreateTokenResponse>('/customer/tokens', req)\n ),\n },\n\n databases: {\n // ── CRUD ──────────────────────────────────────────────────\n create: async (req: CreateDatabaseRequest) =>\n withAuthRetry((client) =>\n client.post<DatabaseResponse>('/customer/databases', req)\n ),\n\n list: async () =>\n withAuthRetry((client) =>\n client.get<DatabaseResponse[]>('/customer/databases')\n ),\n\n get: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<DatabaseResponse>(\n `/customer/databases/${databaseId}`\n )\n ),\n\n delete: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.del<MessageResponse>(\n `/customer/databases/${databaseId}`\n )\n ),\n\n resetPassword: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.post<CustomerPasswordResetResponse>(\n `/customer/databases/${databaseId}/reset-password`\n )\n ),\n\n observability: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<TenantObservabilityResponse>(\n `/customer/databases/${databaseId}/observability`\n )\n ),\n\n // ── SQL Execution ─────────────────────────────────────────\n sql: async (databaseId: string, query: string) => {\n const result = await withAuthRetry((client) =>\n client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { query }\n )\n );\n if (result.error && typeof result.error === 'string') {\n result.error = parseSqlError(result.error);\n }\n return result;\n },\n\n sqlFile: async (databaseId: string, fileContent: string) => {\n const result = await withAuthRetry((client) =>\n client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { file_content: fileContent }\n )\n );\n if (result.error && typeof result.error === 'string') {\n result.error = parseSqlError(result.error);\n }\n return result;\n },\n\n // ── Schema & Dump ─────────────────────────────────────────\n schema: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<SchemaResponse>(\n `/customer/databases/${databaseId}/schema`\n )\n ),\n\n dump: async (databaseId: string, req?: DumpRequest) =>\n withAuthRetry((client) =>\n client.post<DumpResponse>(\n `/customer/databases/${databaseId}/dump`,\n req\n )\n ),\n\n // ── Migrations ────────────────────────────────────────────\n applyMigration: async (\n databaseId: string,\n req: MigrationApplyRequest\n ) =>\n withAuthRetry((client) =>\n client.post<MigrationApplyResponse>(\n `/customer/databases/${databaseId}/migrations`,\n req\n )\n ),\n\n listMigrations: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<MigrationMetadata[]>(\n `/customer/databases/${databaseId}/migrations`\n )\n ),\n\n // ── Branching ─────────────────────────────────────────────\n branch: async (databaseId: string, req: BranchRequest) =>\n withAuthRetry((client) =>\n client.post<DatabaseResponse>(\n `/customer/databases/${databaseId}/branch`,\n req\n )\n ),\n\n // ── User Management ───────────────────────────────────────\n users: {\n list: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<UserResponse[]>(\n `/customer/databases/${databaseId}/users`\n )\n ),\n\n create: async (databaseId: string, req: CreateUserRequest) =>\n withAuthRetry((client) =>\n client.post<MessageResponse>(\n `/customer/databases/${databaseId}/users`,\n req\n )\n ),\n\n delete: async (databaseId: string, username: string) =>\n withAuthRetry((client) =>\n client.del<MessageResponse>(\n `/customer/databases/${databaseId}/users/${username}`\n )\n ),\n },\n },\n\n fs: {\n list: async (\n dbId: string,\n path: string,\n options?: Fs9ListOptions\n ): Promise<Fs9FileEntry[]> => {\n const params: Record<string, string | undefined> = { path };\n if (options?.recursive) params.recursive = 'true';\n return withFsAuthRetry(dbId, (client) =>\n client.get<Fs9FileEntry[]>('/readdir', params)\n );\n },\n\n read: async (dbId: string, path: string): Promise<string> => {\n return withFsAuthRetry(dbId, async (client) => {\n const resp = await client.getRaw('/download', { path });\n return resp.text();\n });\n },\n\n readBinary: async (dbId: string, path: string): Promise<ArrayBuffer> => {\n return withFsAuthRetry(dbId, async (client) => {\n const resp = await client.getRaw('/download', { path });\n return resp.arrayBuffer();\n });\n },\n\n write: async (\n dbId: string,\n path: string,\n content: string | ArrayBuffer | Uint8Array | Blob\n ): Promise<void> => {\n const contentType = typeof content === 'string' ? 'text/plain' : 'application/octet-stream';\n await withFsAuthRetry(dbId, (client) =>\n client.putRaw(`/upload?${new URLSearchParams({ path })}`, content as BodyInit, { 'Content-Type': contentType })\n );\n },\n\n stat: (dbId: string, path: string): Promise<Fs9FileEntry> => {\n return fsStat(dbId, path);\n },\n\n exists: async (dbId: string, path: string): Promise<boolean> => {\n try {\n await fsStat(dbId, path);\n return true;\n } catch (err) {\n if (err instanceof Db9Error && err.statusCode === 404) {\n return false;\n }\n throw err;\n }\n },\n\n mkdir: async (dbId: string, path: string): Promise<void> => {\n await withFsAuthRetry(dbId, (client) =>\n client.postRaw(`/mkdir?${new URLSearchParams({ path, recursive: 'true' })}`)\n );\n },\n\n remove: async (dbId: string, path: string): Promise<void> => {\n await withFsAuthRetry(dbId, (client) =>\n client.delRaw('/remove', { path })\n );\n },\n\n events: async (\n dbId: string,\n options?: Fs9EventOptions\n ): Promise<Fs9EventEntry[]> => {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.offset !== undefined) params.offset = String(options.offset);\n if (options?.path) params.path = options.path;\n if (options?.type) params.type = options.type;\n return withFsAuthRetry(dbId, (client) =>\n client.get<Fs9EventEntry[]>('/events', params)\n );\n },\n },\n };\n}\n\nexport type Db9Client = ReturnType<typeof createDb9Client>;\n","import { createDb9Client } from './client';\nimport type { CredentialStore } from './credentials';\nimport type { FetchFn } from './http';\nimport type { DatabaseResponse } from './types';\n\nexport interface InstantDatabaseOptions {\n name?: string;\n baseUrl?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\n seed?: string;\n seedFile?: string;\n timeout?: number;\n maxRetries?: number;\n retryDelay?: number;\n}\n\nexport interface InstantDatabaseResult {\n databaseId: string;\n connectionString: string;\n adminUser: string;\n adminPassword: string;\n state: string;\n createdAt: string;\n}\n\nexport async function instantDatabase(\n options: InstantDatabaseOptions = {}\n): Promise<InstantDatabaseResult> {\n const dbName = options.name ?? 'default';\n\n const client = createDb9Client({\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n credentialStore: options.credentialStore,\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n retryDelay: options.retryDelay,\n });\n\n const existing = await client.databases.list();\n const found = existing.find((db: DatabaseResponse) => db.name === dbName);\n if (found) {\n return toResult(found);\n }\n\n const created = await client.databases.create({ name: dbName });\n\n if (options.seed) {\n await client.databases.sql(created.id, options.seed);\n } else if (options.seedFile) {\n await client.databases.sqlFile(created.id, options.seedFile);\n }\n\n return toResult(created);\n}\n\nfunction toResult(db: DatabaseResponse): InstantDatabaseResult {\n return {\n databaseId: db.id,\n connectionString: db.connection_string ?? '',\n adminUser: db.admin_user ?? '',\n adminPassword: db.admin_password ?? '',\n state: db.state,\n createdAt: db.created_at,\n };\n}\n\nexport { createDb9Client } from './client';\nexport type { Db9ClientOptions, Db9Client } from './client';\n\nexport {\n Db9Error,\n Db9AuthError,\n Db9NotFoundError,\n Db9ConflictError,\n} from './errors';\n\nexport {\n FileCredentialStore,\n MemoryCredentialStore,\n defaultCredentialStore,\n} from './credentials';\nexport type { CredentialStore, Credentials } from './credentials';\n\nexport type { FetchFn, HttpClient, HttpClientOptions } from './http';\n\nexport type * from './types';\n"],"mappings":"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","names":["options"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/credentials.ts","../src/ws.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["export class Db9Error extends Error {\n readonly statusCode: number;\n readonly response?: Response;\n\n constructor(message: string, statusCode: number, response?: Response) {\n super(message);\n this.name = 'Db9Error';\n this.statusCode = statusCode;\n this.response = response;\n }\n\n static async fromResponse(response: Response): Promise<Db9Error> {\n // Parse common API error shapes:\n // { message }, { detail }, OAuth-style { error, error_description }\n let message: string;\n try {\n const body = (await response.json()) as {\n message?: string;\n detail?: string;\n error_description?: string;\n error?: string;\n };\n message =\n body.message ||\n body.detail ||\n body.error_description ||\n body.error ||\n response.statusText;\n } catch {\n message = response.statusText;\n }\n\n // Return specific subclass based on status code\n switch (response.status) {\n case 401:\n return new Db9AuthError(message, response);\n case 404:\n return new Db9NotFoundError(message, response);\n case 409:\n return new Db9ConflictError(message, response);\n default:\n return new Db9Error(message, response.status, response);\n }\n }\n}\n\nexport class Db9AuthError extends Db9Error {\n constructor(message: string, response?: Response) {\n super(message, 401, response);\n this.name = 'Db9AuthError';\n }\n}\n\nexport class Db9NotFoundError extends Db9Error {\n constructor(message: string, response?: Response) {\n super(message, 404, response);\n this.name = 'Db9NotFoundError';\n }\n}\n\nexport class Db9ConflictError extends Db9Error {\n constructor(message: string, response?: Response) {\n super(message, 409, response);\n this.name = 'Db9ConflictError';\n }\n}\n","import { Db9Error } from './errors';\n\nexport type FetchFn = typeof globalThis.fetch;\n\n// BodyInit type for raw request bodies (string, Blob, ArrayBuffer, etc.)\nexport type BodyInit = string | Blob | ArrayBuffer | FormData | URLSearchParams | ReadableStream<Uint8Array>;\n\nexport interface HttpClientOptions {\n baseUrl: string;\n fetch?: FetchFn;\n headers?: Record<string, string>;\n timeout?: number; // Request timeout in ms (default: none)\n maxRetries?: number; // Max retry attempts on 5xx/network errors (default: 0 = disabled)\n retryDelay?: number; // Base delay in ms for exponential backoff (default: 1000)\n}\n\nexport interface HttpClient {\n get<T>(path: string, params?: Record<string, string | undefined>): Promise<T>;\n post<T>(path: string, body?: unknown): Promise<T>;\n put<T>(path: string, body?: unknown): Promise<T>;\n del<T>(path: string): Promise<T>;\n getRaw(path: string, params?: Record<string, string | undefined>): Promise<Response>;\n putRaw(path: string, body: BodyInit, headers?: Record<string, string>): Promise<Response>;\n postRaw(path: string, body?: BodyInit, headers?: Record<string, string>): Promise<Response>;\n delRaw(path: string, params?: Record<string, string | undefined>): Promise<Response>;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function createHttpClient(options: HttpClientOptions): HttpClient {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const baseUrl = options.baseUrl.replace(/\\/$/, '');\n\n async function request<T>(\n method: string,\n path: string,\n body?: unknown,\n params?: Record<string, string | undefined>\n ): Promise<T> {\n let url = `${baseUrl}${path}`;\n\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) searchParams.set(key, value);\n }\n const qs = searchParams.toString();\n if (qs) url += `?${qs}`;\n }\n\n const reqHeaders: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const init: RequestInit = { method, headers: reqHeaders };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const maxAttempts = Math.min(options.maxRetries ?? 0, 3) + 1;\n const baseDelay = options.retryDelay ?? 1000;\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n const fetchInit = { ...init };\n if (options.timeout) {\n const controller = new AbortController();\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => controller.abort(), options.timeout);\n }\n\n const response = await fetchFn(url, fetchInit);\n if (timeoutId) clearTimeout(timeoutId);\n\n if (!response.ok) {\n if (response.status >= 500 && attempt < maxAttempts - 1) {\n lastError = await Db9Error.fromResponse(response);\n await delay(baseDelay * Math.pow(2, attempt));\n continue;\n }\n throw await Db9Error.fromResponse(response);\n }\n\n if (response.status === 204) return undefined as T;\n return response.json() as Promise<T>;\n } catch (err) {\n if (timeoutId) clearTimeout(timeoutId);\n if (err instanceof TypeError && attempt < maxAttempts - 1) {\n lastError = err;\n await delay(baseDelay * Math.pow(2, attempt));\n continue;\n }\n throw err;\n }\n }\n throw lastError;\n }\n\n async function requestRaw(\n method: string,\n path: string,\n body?: BodyInit,\n params?: Record<string, string | undefined>,\n customHeaders?: Record<string, string>\n ): Promise<Response> {\n let url = `${baseUrl}${path}`;\n\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) searchParams.set(key, value);\n }\n const qs = searchParams.toString();\n if (qs) url += `?${qs}`;\n }\n\n const headers: Record<string, string> = {\n ...options.headers,\n ...customHeaders,\n };\n\n const fetchInit: RequestInit = { method, headers };\n if (body !== undefined) fetchInit.body = body;\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n if (options.timeout) {\n const controller = new AbortController();\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => controller.abort(), options.timeout);\n }\n\n try {\n const response = await fetchFn(url, fetchInit);\n if (timeoutId) clearTimeout(timeoutId);\n if (!response.ok) throw await Db9Error.fromResponse(response);\n return response;\n } catch (err) {\n if (timeoutId) clearTimeout(timeoutId);\n throw err;\n }\n }\n\n return {\n get: <T>(path: string, params?: Record<string, string | undefined>) =>\n request<T>('GET', path, undefined, params),\n post: <T>(path: string, body?: unknown) => request<T>('POST', path, body),\n put: <T>(path: string, body?: unknown) => request<T>('PUT', path, body),\n del: <T>(path: string) => request<T>('DELETE', path),\n getRaw: (path: string, params?: Record<string, string | undefined>) =>\n requestRaw('GET', path, undefined, params),\n putRaw: (path: string, body: BodyInit, headers?: Record<string, string>) =>\n requestRaw('PUT', path, body, undefined, headers),\n postRaw: (path: string, body?: BodyInit, headers?: Record<string, string>) =>\n requestRaw('POST', path, body, undefined, headers),\n delRaw: (path: string, params?: Record<string, string | undefined>) =>\n requestRaw('DELETE', path, undefined, params),\n };\n}\n","import { parse as parseToml, stringify as stringifyToml } from '@iarna/toml';\n\n// ---------------------------------------------------------------------------\n// Interfaces\n// ---------------------------------------------------------------------------\n\n/** Credential fields stored in `~/.db9/credentials` (TOML). */\nexport interface Credentials {\n token: string;\n}\n\n/** Async credential persistence abstraction. */\nexport interface CredentialStore {\n load(): Promise<Credentials | null>;\n save(credentials: Credentials): Promise<void>;\n clear(): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// FileCredentialStore — TOML file at ~/.db9/credentials (matches db9 CLI)\n// ---------------------------------------------------------------------------\n\nexport class FileCredentialStore implements CredentialStore {\n private readonly customPath: string | undefined;\n\n /**\n * @param path — Override the credential file location.\n * Defaults to `~/.db9/credentials` (resolved lazily).\n */\n constructor(path?: string) {\n this.customPath = path;\n }\n\n /** Resolve the credential file path (lazy to avoid top-level `os` import). */\n private async resolvePath(): Promise<string> {\n if (this.customPath) return this.customPath;\n const os = await import('node:os');\n const nodePath = await import('node:path');\n return nodePath.join(os.homedir(), '.db9', 'credentials');\n }\n\n async load(): Promise<Credentials | null> {\n const fs = await import('node:fs/promises');\n const filePath = await this.resolvePath();\n\n let content: string;\n try {\n content = await fs.readFile(filePath, 'utf-8');\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return null;\n throw err;\n }\n\n const parsed = parseToml(content);\n const token = parsed['token'];\n if (typeof token !== 'string') return null;\n\n return { token };\n }\n\n async save(credentials: Credentials): Promise<void> {\n const fs = await import('node:fs/promises');\n const nodePath = await import('node:path');\n const filePath = await this.resolvePath();\n const dir = nodePath.dirname(filePath);\n\n // Ensure directory exists with 0o700 (matches CLI: ensure_config_dir)\n await fs.mkdir(dir, { recursive: true, mode: 0o700 });\n\n // Read → merge → write (preserves unknown fields as scalars)\n const data: Record<string, string | boolean | number> = {};\n try {\n const raw = await fs.readFile(filePath, 'utf-8');\n const parsed = parseToml(raw);\n for (const [k, v] of Object.entries(parsed)) {\n if (typeof v === 'string' || typeof v === 'boolean' || typeof v === 'number') {\n data[k] = v;\n }\n }\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n\n // Merge: always update token\n data['token'] = credentials.token;\n\n // Serialize and write with 0o600 permissions (matches CLI: save_token)\n const toml = stringifyToml(\n data as Parameters<typeof stringifyToml>[0],\n );\n await fs.writeFile(filePath, toml, { mode: 0o600 });\n }\n\n async clear(): Promise<void> {\n const fs = await import('node:fs/promises');\n const filePath = await this.resolvePath();\n\n try {\n await fs.unlink(filePath);\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// MemoryCredentialStore — in-memory, no persistence\n// ---------------------------------------------------------------------------\n\nexport class MemoryCredentialStore implements CredentialStore {\n private credentials: Credentials | null = null;\n\n async load(): Promise<Credentials | null> {\n return this.credentials ? { ...this.credentials } : null;\n }\n\n async save(credentials: Credentials): Promise<void> {\n this.credentials = { token: credentials.token };\n }\n\n async clear(): Promise<void> {\n this.credentials = null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/** Returns a FileCredentialStore with the default path (`~/.db9/credentials`). */\nexport function defaultCredentialStore(): CredentialStore {\n return new FileCredentialStore();\n}\n","/**\n * WebSocket client for the fs9 filesystem protocol.\n *\n * Mirrors db9-cli/src/fssh/client.rs — each public method maps to a single\n * request–response round-trip over a JSON text WebSocket.\n *\n * For files >= 1 MB, writeFile() automatically switches to streaming mode\n * using binary WebSocket frames to bypass the 2 MB JSON frame limit and\n * eliminate base64 encoding overhead.\n *\n * Node-only: requires the `ws` package or Node 21+ native WebSocket.\n */\n\nimport { createHash } from 'node:crypto';\nimport type {\n FileInfo,\n FsAuthInfo,\n FsWsResponse,\n FsWsError,\n StreamWriteReady,\n} from './fs-types';\n\n// ── Types ───────────────────────────────────────────────────────\n\n/** Minimal WebSocket interface we depend on (compatible with `ws` package). */\nexport interface WebSocketLike {\n readonly readyState: number;\n send(data: string | Buffer | Uint8Array): void;\n close(code?: number, reason?: string): void;\n onopen: ((ev: unknown) => void) | null;\n onclose: ((ev: unknown) => void) | null;\n onerror: ((ev: unknown) => void) | null;\n onmessage: ((ev: { data: unknown }) => void) | null;\n}\n\n/** Constructor for a W3C-compatible WebSocket. */\nexport type WebSocketConstructor = new (url: string) => WebSocketLike;\n\n/** Error from an fs9 WebSocket operation. */\nexport class FsError extends Error {\n readonly code: string;\n\n constructor(code: string, message: string) {\n super(message);\n this.name = 'FsError';\n this.code = code;\n }\n}\n\n// ── Constants ────────────────────────────────────────────────────\n\n/** Threshold above which streaming mode is used (matches server/Rust client). */\nconst STREAMING_THRESHOLD = 1024 * 1024; // 1 MB\n\n/** Default chunk size for streaming transfers. */\nconst DEFAULT_CHUNK_SIZE = 64 * 1024; // 64 KB\n\n// ── Request ID ──────────────────────────────────────────────────\n\nlet nextId = 1;\nfunction nextRequestId(): string {\n return String(nextId++);\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction toBase64(data: Uint8Array | ArrayBuffer): string {\n const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);\n return Buffer.from(bytes).toString('base64');\n}\n\nfunction fromBase64(b64: string): Uint8Array {\n return new Uint8Array(Buffer.from(b64, 'base64'));\n}\n\n/** Compute SHA-256 checksum, returning \"sha256:<hex>\". */\nfunction computeChecksum(data: Uint8Array): string {\n const hash = createHash('sha256').update(data).digest('hex');\n return `sha256:${hash}`;\n}\n\n/** Encode a binary frame: [8-byte stream_id BE][chunk_data]. */\nfunction encodeBinaryFrame(streamId: number, chunk: Uint8Array): Buffer {\n const frame = Buffer.alloc(8 + chunk.length);\n frame.writeBigUInt64BE(BigInt(streamId), 0);\n frame.set(chunk, 8);\n return frame;\n}\n\n// ── FsClient ────────────────────────────────────────────────────\n\n/**\n * Async WebSocket client for fs9 file operations.\n *\n * Usage:\n * ```ts\n * const client = await FsClient.connect('wss://host:5480', WebSocket);\n * await client.authenticate('tenant.admin', 'password');\n * const entries = await client.readdir('/');\n * await client.close();\n * ```\n */\nexport class FsClient {\n private ws: WebSocketLike;\n private pending = new Map<string, {\n resolve: (resp: FsWsResponse) => void;\n reject: (err: Error) => void;\n }>();\n private closed = false;\n\n private constructor(ws: WebSocketLike) {\n this.ws = ws;\n ws.onmessage = (ev: { data: unknown }) => {\n const text = typeof ev.data === 'string' ? ev.data : String(ev.data);\n let resp: FsWsResponse;\n try {\n resp = JSON.parse(text) as FsWsResponse;\n } catch {\n return; // ignore non-JSON frames\n }\n const p = this.pending.get(resp.id);\n if (p) {\n this.pending.delete(resp.id);\n p.resolve(resp);\n }\n };\n ws.onclose = () => {\n this.closed = true;\n // Reject all pending requests\n for (const [, p] of this.pending) {\n p.reject(new FsError('CONNECTION_CLOSED', 'WebSocket connection closed'));\n }\n this.pending.clear();\n };\n ws.onerror = () => {\n // onclose will fire after onerror, which handles cleanup\n };\n }\n\n /**\n * Connect to an fs9 WebSocket server.\n *\n * @param url WebSocket URL, e.g. `wss://host:5480`\n * @param WS WebSocket constructor (native or from `ws` package)\n */\n static connect(url: string, WS: WebSocketConstructor): Promise<FsClient> {\n return new Promise((resolve, reject) => {\n const ws = new WS(url);\n ws.onopen = () => {\n ws.onopen = null;\n ws.onerror = null;\n resolve(new FsClient(ws));\n };\n ws.onerror = (ev: unknown) => {\n ws.onopen = null;\n ws.onerror = null;\n const msg = ev && typeof ev === 'object' && 'message' in ev\n ? String((ev as { message: unknown }).message)\n : 'WebSocket connection failed';\n reject(new FsError('CONNECTION_ERROR', msg));\n };\n });\n }\n\n /** Authenticate with the server. Must be called first after connect. */\n async authenticate(username: string, password: string): Promise<FsAuthInfo> {\n const resp = await this.sendAndRecv({\n id: nextRequestId(),\n op: 'auth',\n username,\n password,\n });\n if (!resp.ok) {\n throw new FsError('AUTH_FAILED', this.errorMessage(resp));\n }\n const data = resp.data as Record<string, unknown> | undefined;\n return {\n user: String(data?.user ?? ''),\n tenant: String(data?.tenant ?? ''),\n keyspace: String(data?.keyspace ?? ''),\n };\n }\n\n /** Get file or directory metadata. */\n async stat(path: string): Promise<FileInfo> {\n const resp = await this.sendAndRecv({\n id: nextRequestId(),\n op: 'stat',\n path,\n });\n this.expectOk(resp);\n return resp.data as FileInfo;\n }\n\n /** List directory contents. */\n async readdir(path: string): Promise<FileInfo[]> {\n const resp = await this.sendAndRecv({\n id: nextRequestId(),\n op: 'readdir',\n path,\n });\n this.expectOk(resp);\n const data = resp.data as { entries: FileInfo[] } | undefined;\n return data?.entries ?? [];\n }\n\n /** Create a directory. Always recursive (mkdir -p). */\n async mkdir(path: string, recursive = true): Promise<void> {\n const resp = await this.sendAndRecv({\n id: nextRequestId(),\n op: 'mkdir',\n path,\n recursive,\n });\n this.expectOk(resp);\n }\n\n /** Read an entire file, returning raw bytes. */\n async readFile(path: string): Promise<Uint8Array> {\n const resp = await this.sendAndRecv({\n id: nextRequestId(),\n op: 'read',\n path,\n });\n this.expectOk(resp);\n const data = resp.data as { content?: string } | undefined;\n const content = data?.content;\n if (typeof content !== 'string') {\n throw new FsError('PROTOCOL', 'missing content field in read response');\n }\n return fromBase64(content);\n }\n\n /**\n * Write (overwrite) a file. Returns bytes written.\n *\n * Automatically uses streaming mode for files >= 1 MB to avoid base64\n * overhead and bypass the 2 MB JSON frame limit.\n */\n async writeFile(path: string, data: Uint8Array | ArrayBuffer | string): Promise<number> {\n const bytes = typeof data === 'string'\n ? new TextEncoder().encode(data)\n : data instanceof Uint8Array ? data : new Uint8Array(data);\n if (bytes.byteLength >= STREAMING_THRESHOLD) {\n return this.writeFileStreaming(path, bytes);\n }\n const resp = await this.sendAndRecv({\n id: nextRequestId(),\n op: 'write',\n path,\n content: toBase64(bytes),\n encoding: 'base64',\n });\n this.expectOk(resp);\n const result = resp.data as { written?: number } | undefined;\n return result?.written ?? bytes.byteLength;\n }\n\n /** Append to a file. Returns bytes written. */\n async appendFile(path: string, data: Uint8Array | ArrayBuffer | string): Promise<number> {\n const bytes = typeof data === 'string'\n ? new TextEncoder().encode(data)\n : data instanceof Uint8Array ? data : new Uint8Array(data);\n const resp = await this.sendAndRecv({\n id: nextRequestId(),\n op: 'append',\n path,\n content: toBase64(bytes),\n encoding: 'base64',\n });\n this.expectOk(resp);\n const result = resp.data as { written?: number } | undefined;\n return result?.written ?? bytes.byteLength;\n }\n\n /** Remove a file (non-recursive) or directory (recursive). */\n async rm(path: string, recursive = false): Promise<void> {\n const resp = await this.sendAndRecv(recursive\n ? { id: nextRequestId(), op: 'rm', path, recursive: true }\n : { id: nextRequestId(), op: 'unlink', path }\n );\n this.expectOk(resp);\n }\n\n /** Rename (move) a file or directory. */\n async rename(oldPath: string, newPath: string): Promise<void> {\n const resp = await this.sendAndRecv({\n id: nextRequestId(),\n op: 'rename',\n old_path: oldPath,\n new_path: newPath,\n });\n this.expectOk(resp);\n }\n\n /** Gracefully close the WebSocket connection. */\n async close(): Promise<void> {\n if (!this.closed) {\n this.ws.close();\n }\n }\n\n // ── streaming internals ────────────────────────────────────────\n\n /**\n * Write a file using streaming mode (binary frames, no base64).\n *\n * Protocol:\n * 1. Send streaming write request with file size\n * 2. Receive ready response with stream_id and chunk_size\n * 3. Send binary frames: [8-byte stream_id BE][chunk_data]\n * 4. Send stream end with checksum\n * 5. Receive final write confirmation\n */\n private async writeFileStreaming(path: string, bytes: Uint8Array): Promise<number> {\n // 1. Initiate streaming write\n const requestId = nextRequestId();\n const readyResp = await this.sendAndRecv({\n id: requestId,\n op: 'write',\n path,\n streaming: true,\n size: bytes.byteLength,\n });\n this.expectOk(readyResp);\n\n const ready = readyResp.data as StreamWriteReady | undefined;\n if (!ready?.ready) {\n throw new FsError('PROTOCOL', 'server not ready for streaming');\n }\n\n const streamId = ready.stream_id;\n const chunkSize = ready.chunk_size > 0 ? ready.chunk_size : DEFAULT_CHUNK_SIZE;\n\n // 3. Send binary frames (abort stream on failure)\n try {\n for (let offset = 0; offset < bytes.byteLength; offset += chunkSize) {\n const chunk = bytes.subarray(offset, offset + chunkSize);\n const frame = encodeBinaryFrame(streamId, chunk);\n this.ws.send(frame);\n }\n } catch (err) {\n this.tryAbortStream(streamId);\n throw new FsError('CONNECTION_ERROR', `send chunk: ${err}`);\n }\n\n // 4. Send stream end with checksum\n const checksum = computeChecksum(bytes);\n const finalResp = await this.sendAndRecv({\n id: requestId,\n stream: 'end',\n stream_id: streamId,\n checksum,\n });\n this.expectOk(finalResp);\n\n const result = finalResp.data as { written?: number } | undefined;\n return result?.written ?? bytes.byteLength;\n }\n\n /** Best-effort abort of an in-progress stream so the server can clean up. */\n private tryAbortStream(streamId: number): void {\n try {\n this.ws.send(JSON.stringify({ stream: 'abort', stream_id: streamId }));\n } catch {\n // best-effort — ignore send failures during abort\n }\n }\n\n // ── internals ──────────────────────────────────────────────────\n\n private sendAndRecv(request: Record<string, unknown>): Promise<FsWsResponse> {\n if (this.closed) {\n return Promise.reject(new FsError('CONNECTION_CLOSED', 'WebSocket is closed'));\n }\n return new Promise((resolve, reject) => {\n const id = request.id as string;\n this.pending.set(id, { resolve, reject });\n try {\n this.ws.send(JSON.stringify(request));\n } catch (err) {\n this.pending.delete(id);\n reject(new FsError('CONNECTION_ERROR', String(err)));\n }\n });\n }\n\n private expectOk(resp: FsWsResponse): void {\n if (!resp.ok) {\n const detail = resp.error as FsWsError | undefined;\n throw new FsError(\n detail?.code ?? 'UNKNOWN',\n detail?.message ?? 'unknown error',\n );\n }\n }\n\n private errorMessage(resp: FsWsResponse): string {\n const detail = resp.error as FsWsError | undefined;\n return detail ? `${detail.code}: ${detail.message}` : 'unknown error';\n }\n}\n","import { createHttpClient, type FetchFn, type HttpClient } from './http';\nimport {\n defaultCredentialStore,\n type CredentialStore,\n} from './credentials';\nimport { Db9Error } from './errors';\nimport type { FileInfo, FsConnectOptions } from './fs-types';\nimport { FsClient, FsError, type WebSocketConstructor } from './ws';\nimport type {\n CustomerResponse,\n TokenResponse,\n MessageResponse,\n CreateDatabaseRequest,\n DatabaseResponse,\n CustomerPasswordResetResponse,\n TenantObservabilityResponse,\n SqlResult,\n SqlErrorDetail,\n SchemaResponse,\n DumpRequest,\n DumpResponse,\n MigrationApplyRequest,\n MigrationApplyResponse,\n MigrationMetadata,\n BranchRequest,\n UserResponse,\n CreateUserRequest,\n CreateTokenRequest,\n CreateTokenResponse,\n} from './types';\n\nexport interface Db9ClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\n timeout?: number;\n maxRetries?: number;\n retryDelay?: number;\n /** WebSocket constructor for fs operations (native WebSocket, or `ws` package for Node 18–20). */\n WebSocket?: WebSocketConstructor;\n /** WebSocket port for fs9 server (default: 5480). */\n wsPort?: number;\n}\n\nexport function createDb9Client(options: Db9ClientOptions = {}) {\n const baseUrl =\n options.baseUrl ?? 'https://db9.ai/api';\n let token = options.token;\n let tokenLoaded = !!token;\n const store = options.credentialStore ?? defaultCredentialStore();\n const fetchFn = options.fetch ?? globalThis.fetch;\n\n // Public HTTP client — no Authorization header\n const publicClient = createHttpClient({\n baseUrl,\n fetch: options.fetch,\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n retryDelay: options.retryDelay,\n });\n\n // Lazy-loading authenticated HTTP client\n async function getAuthClient(): Promise<HttpClient> {\n if (!token && !tokenLoaded) {\n const creds = await store.load();\n if (creds?.token) token = creds.token;\n tokenLoaded = true;\n }\n if (!token) {\n throw new Db9Error(\n 'No token available. Run `db9 login` or pass a token via Db9ClientOptions.',\n 401\n );\n }\n return createHttpClient({\n baseUrl,\n fetch: options.fetch,\n headers: { Authorization: `Bearer ${token}` },\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n retryDelay: options.retryDelay,\n });\n }\n\n async function withAuthRetry<T>(\n operation: (client: HttpClient) => Promise<T>\n ): Promise<T> {\n const client = await getAuthClient();\n return operation(client);\n }\n\n // ── fs9 WebSocket helpers ───────────────────────────────────\n const fsWsPort = options.wsPort ?? 5480;\n\n /**\n * Resolve WebSocket connection credentials for a database.\n * Uses the credentials API to get host, username, and password,\n * then constructs the WS URL and auth username.\n */\n async function resolveFsConn(dbId: string): Promise<FsConnectOptions> {\n // Try credentials endpoint first (returns admin_user, admin_password, connection_string)\n const creds = await withAuthRetry((client) =>\n client.get<CustomerPasswordResetResponse>(\n `/customer/databases/${dbId}/credentials`\n )\n );\n\n // Parse host from connection_string: postgresql://tenant.user:pass@HOST:port/db\n const connStr = creds.connection_string;\n const hostMatch = connStr.match(/@([^:/?]+)/);\n const host = hostMatch?.[1];\n if (!host) {\n throw new Error(`Cannot parse host from connection string for database '${dbId}'`);\n }\n\n // Username format: connection_string already has tenant.user, extract it\n const userMatch = connStr.match(/:\\/\\/([^:@]+)/);\n const username = userMatch?.[1] ?? creds.admin_user;\n\n const protocol = host === 'localhost' || host === '127.0.0.1' ? 'ws' : 'wss';\n\n return {\n wsUrl: `${protocol}://${host}:${fsWsPort}`,\n username,\n password: creds.admin_password,\n };\n }\n\n /**\n * Run an operation on an authenticated FsClient, then close the connection.\n * The WebSocket constructor must be provided via `Db9ClientOptions.WebSocket`.\n */\n async function withFsClient<T>(\n dbId: string,\n operation: (client: FsClient) => Promise<T>\n ): Promise<T> {\n const WS = options.WebSocket ?? (typeof globalThis !== 'undefined' ? (globalThis as Record<string, unknown>).WebSocket as WebSocketConstructor | undefined : undefined);\n if (!WS) {\n throw new Error(\n 'WebSocket constructor not available. Pass `WebSocket` in Db9ClientOptions, ' +\n 'or use Node 21+ / a browser environment with native WebSocket support, ' +\n 'or install the `ws` package for Node 18–20.'\n );\n }\n\n const conn = await resolveFsConn(dbId);\n const client = await FsClient.connect(conn.wsUrl, WS);\n try {\n await client.authenticate(conn.username, conn.password);\n return await operation(client);\n } finally {\n await client.close();\n }\n }\n\n // ── SQL Error Parsing ────────────────────────────────────────\n function parseSqlError(raw: string): SqlErrorDetail {\n // Strategy 1: Try JSON.parse\n try {\n const parsed = JSON.parse(raw);\n if (typeof parsed === 'object' && parsed !== null && typeof parsed.message === 'string') {\n return parsed as SqlErrorDetail;\n }\n } catch {\n // not JSON, continue\n }\n\n // Strategy 2: Regex for PostgreSQL-style errors\n const pgMatch = raw.match(/^(?:ERROR:\\s*)?(.+?)(?:\\s+DETAIL:\\s+(.+?))?(?:\\s+HINT:\\s+(.+?))?(?:\\s+\\(SQLSTATE\\s+(\\w+)\\))?$/s);\n if (pgMatch && pgMatch[1]) {\n const result: SqlErrorDetail = { message: pgMatch[1].trim() };\n if (pgMatch[2]) result.detail = pgMatch[2].trim();\n if (pgMatch[3]) result.hint = pgMatch[3].trim();\n if (pgMatch[4]) result.code = pgMatch[4];\n return result;\n }\n\n // Strategy 3: Fallback\n return { message: raw };\n }\n\n return {\n auth: {\n me: async () =>\n withAuthRetry((client) =>\n client.get<CustomerResponse>('/customer/me')\n ),\n },\n\n tokens: {\n list: async () =>\n withAuthRetry((client) =>\n client.get<TokenResponse[]>('/customer/tokens')\n ),\n\n revoke: async (tokenId: string) =>\n withAuthRetry((client) =>\n client.del<MessageResponse>(`/customer/tokens/${tokenId}`)\n ),\n\n create: async (req: CreateTokenRequest) =>\n withAuthRetry((client) =>\n client.post<CreateTokenResponse>('/customer/tokens', req)\n ),\n },\n\n databases: {\n // ── CRUD ──────────────────────────────────────────────────\n create: async (req: CreateDatabaseRequest) =>\n withAuthRetry((client) =>\n client.post<DatabaseResponse>('/customer/databases', req)\n ),\n\n list: async () =>\n withAuthRetry((client) =>\n client.get<DatabaseResponse[]>('/customer/databases')\n ),\n\n get: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<DatabaseResponse>(\n `/customer/databases/${databaseId}`\n )\n ),\n\n delete: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.del<MessageResponse>(\n `/customer/databases/${databaseId}`\n )\n ),\n\n resetPassword: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.post<CustomerPasswordResetResponse>(\n `/customer/databases/${databaseId}/reset-password`\n )\n ),\n\n credentials: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<CustomerPasswordResetResponse>(\n `/customer/databases/${databaseId}/credentials`\n )\n ),\n\n\n observability: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<TenantObservabilityResponse>(\n `/customer/databases/${databaseId}/observability`\n )\n ),\n\n // ── SQL Execution ─────────────────────────────────────────\n sql: async (databaseId: string, query: string) => {\n const result = await withAuthRetry((client) =>\n client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { query }\n )\n );\n if (result.error && typeof result.error === 'string') {\n result.error = parseSqlError(result.error);\n }\n return result;\n },\n\n sqlFile: async (databaseId: string, fileContent: string) => {\n const result = await withAuthRetry((client) =>\n client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { file_content: fileContent }\n )\n );\n if (result.error && typeof result.error === 'string') {\n result.error = parseSqlError(result.error);\n }\n return result;\n },\n\n // ── Schema & Dump ─────────────────────────────────────────\n schema: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<SchemaResponse>(\n `/customer/databases/${databaseId}/schema`\n )\n ),\n\n dump: async (databaseId: string, req?: DumpRequest) =>\n withAuthRetry((client) =>\n client.post<DumpResponse>(\n `/customer/databases/${databaseId}/dump`,\n req\n )\n ),\n\n // ── Migrations ────────────────────────────────────────────\n applyMigration: async (\n databaseId: string,\n req: MigrationApplyRequest\n ) =>\n withAuthRetry((client) =>\n client.post<MigrationApplyResponse>(\n `/customer/databases/${databaseId}/migrations`,\n req\n )\n ),\n\n listMigrations: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<MigrationMetadata[]>(\n `/customer/databases/${databaseId}/migrations`\n )\n ),\n\n // ── Branching ─────────────────────────────────────────────\n branch: async (databaseId: string, req: BranchRequest) =>\n withAuthRetry((client) =>\n client.post<DatabaseResponse>(\n `/customer/databases/${databaseId}/branch`,\n req\n )\n ),\n\n // ── User Management ───────────────────────────────────────\n users: {\n list: async (databaseId: string) =>\n withAuthRetry((client) =>\n client.get<UserResponse[]>(\n `/customer/databases/${databaseId}/users`\n )\n ),\n\n create: async (databaseId: string, req: CreateUserRequest) =>\n withAuthRetry((client) =>\n client.post<MessageResponse>(\n `/customer/databases/${databaseId}/users`,\n req\n )\n ),\n\n delete: async (databaseId: string, username: string) =>\n withAuthRetry((client) =>\n client.del<MessageResponse>(\n `/customer/databases/${databaseId}/users/${username}`\n )\n ),\n },\n },\n\n fs: {\n /**\n * Open a persistent WebSocket connection for multiple fs operations.\n * Caller is responsible for calling `client.close()` when done.\n */\n connect: async (dbId: string): Promise<FsClient> => {\n const WS = options.WebSocket ?? (typeof globalThis !== 'undefined' ? (globalThis as Record<string, unknown>).WebSocket as WebSocketConstructor | undefined : undefined);\n if (!WS) {\n throw new Error(\n 'WebSocket constructor not available. Pass `WebSocket` in Db9ClientOptions, ' +\n 'or use Node 21+ / a browser environment with native WebSocket support, ' +\n 'or install the `ws` package for Node 18–20.'\n );\n }\n const conn = await resolveFsConn(dbId);\n const client = await FsClient.connect(conn.wsUrl, WS);\n await client.authenticate(conn.username, conn.password);\n return client;\n },\n\n /** List directory contents. */\n list: async (dbId: string, path: string): Promise<FileInfo[]> =>\n withFsClient(dbId, (client) => client.readdir(path)),\n\n /** Read a file as text (UTF-8). */\n read: async (dbId: string, path: string): Promise<string> =>\n withFsClient(dbId, async (client) => {\n const bytes = await client.readFile(path);\n return new TextDecoder().decode(bytes);\n }),\n\n /** Read a file as raw bytes. */\n readBinary: async (dbId: string, path: string): Promise<Uint8Array> =>\n withFsClient(dbId, (client) => client.readFile(path)),\n\n /** Write (overwrite) a file. Accepts string, ArrayBuffer, or Uint8Array. */\n write: async (\n dbId: string,\n path: string,\n content: string | ArrayBuffer | Uint8Array\n ): Promise<void> => {\n await withFsClient(dbId, (client) => client.writeFile(path, content));\n },\n\n /** Append to a file. Returns bytes written. */\n append: async (\n dbId: string,\n path: string,\n content: string | ArrayBuffer | Uint8Array\n ): Promise<number> =>\n withFsClient(dbId, (client) => client.appendFile(path, content)),\n\n /** Get file or directory metadata. */\n stat: async (dbId: string, path: string): Promise<FileInfo> =>\n withFsClient(dbId, (client) => client.stat(path)),\n\n /** Check if a file or directory exists. */\n exists: async (dbId: string, path: string): Promise<boolean> => {\n try {\n await withFsClient(dbId, (client) => client.stat(path));\n return true;\n } catch (err) {\n if (err instanceof FsError && err.code === 'ENOENT') {\n return false;\n }\n throw err;\n }\n },\n\n /** Create a directory (recursive by default). */\n mkdir: async (dbId: string, path: string): Promise<void> => {\n await withFsClient(dbId, (client) => client.mkdir(path, true));\n },\n\n /** Remove a file or directory. */\n remove: async (dbId: string, path: string, opts?: { recursive?: boolean }): Promise<void> => {\n await withFsClient(dbId, (client) => client.rm(path, opts?.recursive ?? false));\n },\n\n /** Rename (move) a file or directory. */\n rename: async (dbId: string, oldPath: string, newPath: string): Promise<void> => {\n await withFsClient(dbId, (client) => client.rename(oldPath, newPath));\n },\n },\n\n };\n}\n\nexport type Db9Client = ReturnType<typeof createDb9Client>;\n","import { createDb9Client } from './client';\nimport type { CredentialStore } from './credentials';\nimport type { FetchFn } from './http';\nimport type { DatabaseResponse } from './types';\n\nexport interface InstantDatabaseOptions {\n name?: string;\n baseUrl?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\n seed?: string;\n seedFile?: string;\n timeout?: number;\n maxRetries?: number;\n retryDelay?: number;\n}\n\nexport interface InstantDatabaseResult {\n databaseId: string;\n connectionString: string;\n adminUser: string;\n adminPassword: string;\n state: string;\n createdAt: string;\n}\n\nexport async function instantDatabase(\n options: InstantDatabaseOptions = {}\n): Promise<InstantDatabaseResult> {\n const dbName = options.name ?? 'default';\n\n const client = createDb9Client({\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n credentialStore: options.credentialStore,\n timeout: options.timeout,\n maxRetries: options.maxRetries,\n retryDelay: options.retryDelay,\n });\n\n const existing = await client.databases.list();\n const found = existing.find((db: DatabaseResponse) => db.name === dbName);\n if (found) {\n return toResult(found);\n }\n\n const created = await client.databases.create({ name: dbName });\n\n if (options.seed) {\n await client.databases.sql(created.id, options.seed);\n } else if (options.seedFile) {\n await client.databases.sqlFile(created.id, options.seedFile);\n }\n\n return toResult(created);\n}\n\nfunction toResult(db: DatabaseResponse): InstantDatabaseResult {\n return {\n databaseId: db.id,\n connectionString: db.connection_string ?? '',\n adminUser: db.admin_user ?? '',\n adminPassword: db.admin_password ?? '',\n state: db.state,\n createdAt: db.created_at,\n };\n}\n\nexport { createDb9Client } from './client';\nexport type { Db9ClientOptions, Db9Client } from './client';\n\nexport {\n Db9Error,\n Db9AuthError,\n Db9NotFoundError,\n Db9ConflictError,\n} from './errors';\n\nexport {\n FileCredentialStore,\n MemoryCredentialStore,\n defaultCredentialStore,\n} from './credentials';\nexport type { CredentialStore, Credentials } from './credentials';\n\nexport type { FetchFn, HttpClient, HttpClientOptions } from './http';\n\nexport { FsClient, FsError } from './ws';\nexport type { WebSocketLike, WebSocketConstructor } from './ws';\n\nexport type {\n FileInfo,\n FsListOptions,\n FsRemoveOptions,\n FsConnectOptions,\n FsAuthInfo,\n FsWsRequest,\n FsWsResponse,\n FsWsError,\n StreamWriteReady,\n} from './fs-types';\n// Backward-compat aliases\nexport type { Fs9FileEntry, Fs9ListOptions } from './fs-types';\nexport type * from './types';\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "get-db9",
3
- "version": "0.5.0",
4
- "description": "TypeScript SDK for pg-tikv — instant PostgreSQL databases",
3
+ "version": "0.6.1",
4
+ "description": "TypeScript SDK for db9-server — instant PostgreSQL databases",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=18"
@@ -26,13 +26,15 @@
26
26
  ],
27
27
  "scripts": {
28
28
  "build": "tsup",
29
+ "prepack": "npm run build && npm run verify:dist",
29
30
  "test": "vitest run",
30
31
  "test:e2e": "vitest run --config vitest.e2e.config.ts",
31
32
  "typecheck": "tsc --noEmit",
32
- "dev": "vitest"
33
+ "dev": "vitest",
34
+ "verify:dist": "node ./scripts/verify-dist.mjs"
33
35
  },
34
36
  "keywords": [
35
- "pg-tikv",
37
+ "db9-server",
36
38
  "postgres",
37
39
  "database",
38
40
  "sdk",
@@ -42,11 +44,13 @@
42
44
  "license": "Apache-2.0",
43
45
  "repository": {
44
46
  "type": "git",
45
- "url": "https://github.com/pgtikv/pg-tikv",
47
+ "url": "https://github.com/c4pt0r/db9-backend",
46
48
  "directory": "sdk/ts"
47
49
  },
48
50
  "dependencies": {
49
- "@iarna/toml": "^3.0.0"
51
+ "@iarna/toml": "^3.0.0",
52
+ "@types/ws": "^8.18.1",
53
+ "ws": "^8.19.0"
50
54
  },
51
55
  "devDependencies": {
52
56
  "@types/node": "^20.0.0",