get-db9 0.3.0 → 0.4.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/credentials.ts","../src/client.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\nexport interface HttpClientOptions {\n baseUrl: string;\n fetch?: FetchFn;\n headers?: Record<string, string>;\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}\n\nexport function createHttpClient(options: HttpClientOptions): HttpClient {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const baseUrl = options.baseUrl.replace(/\\/$/, ''); // strip trailing slash\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 // Append query params for GET requests\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, value);\n }\n }\n const qs = searchParams.toString();\n if (qs) url += `?${qs}`;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const response = await fetchFn(url, init);\n\n if (!response.ok) {\n throw await Db9Error.fromResponse(response);\n }\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\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 };\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 } from './http';\nimport {\n defaultCredentialStore,\n type CredentialStore,\n} from './credentials';\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 SchemaResponse,\n DumpRequest,\n DumpResponse,\n MigrationApplyRequest,\n MigrationApplyResponse,\n MigrationMetadata,\n BranchRequest,\n UserResponse,\n CreateUserRequest,\n} from './types';\n\nexport interface Db9ClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\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\n // Public HTTP client — no Authorization header\n const publicClient = createHttpClient({\n baseUrl,\n fetch: options.fetch,\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 });\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 const client = await getAuthClient();\n return client.get<CustomerResponse>('/customer/me');\n },\n\n getAnonymousSecret: async () => {\n const client = await getAuthClient();\n return client.get<AnonymousSecretResponse>(\n '/customer/anonymous-secret'\n );\n },\n\n claim: async (req: ClaimRequest) => {\n const client = await getAuthClient();\n return client.post<ClaimResponse>('/customer/claim', req);\n },\n },\n\n tokens: {\n list: async () => {\n const client = await getAuthClient();\n return client.get<TokenResponse[]>('/customer/tokens');\n },\n\n revoke: async (tokenId: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(`/customer/tokens/${tokenId}`);\n },\n },\n\n databases: {\n // ── CRUD ──────────────────────────────────────────────────\n create: async (req: CreateDatabaseRequest) => {\n const client = await getAuthClient();\n return client.post<DatabaseResponse>('/customer/databases', req);\n },\n\n list: async () => {\n const client = await getAuthClient();\n return client.get<DatabaseResponse[]>('/customer/databases');\n },\n\n get: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<DatabaseResponse>(\n `/customer/databases/${databaseId}`\n );\n },\n\n delete: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(\n `/customer/databases/${databaseId}`\n );\n },\n\n resetPassword: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.post<CustomerPasswordResetResponse>(\n `/customer/databases/${databaseId}/reset-password`\n );\n },\n\n observability: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<TenantObservabilityResponse>(\n `/customer/databases/${databaseId}/observability`\n );\n },\n\n // ── SQL Execution ─────────────────────────────────────────\n sql: async (databaseId: string, query: string) => {\n const client = await getAuthClient();\n return client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { query }\n );\n },\n\n sqlFile: async (databaseId: string, fileContent: string) => {\n const client = await getAuthClient();\n return client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { file_content: fileContent }\n );\n },\n\n // ── Schema & Dump ─────────────────────────────────────────\n schema: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<SchemaResponse>(\n `/customer/databases/${databaseId}/schema`\n );\n },\n\n dump: async (databaseId: string, req?: DumpRequest) => {\n const client = await getAuthClient();\n return 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 const client = await getAuthClient();\n return client.post<MigrationApplyResponse>(\n `/customer/databases/${databaseId}/migrations`,\n req\n );\n },\n\n listMigrations: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<MigrationMetadata[]>(\n `/customer/databases/${databaseId}/migrations`\n );\n },\n\n // ── Branching ─────────────────────────────────────────────\n branch: async (databaseId: string, req: BranchRequest) => {\n const client = await getAuthClient();\n return client.post<DatabaseResponse>(\n `/customer/databases/${databaseId}/branch`,\n req\n );\n },\n\n // ── User Management ───────────────────────────────────────\n users: {\n list: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<UserResponse[]>(\n `/customer/databases/${databaseId}/users`\n );\n },\n\n create: async (databaseId: string, req: CreateUserRequest) => {\n const client = await getAuthClient();\n return client.post<MessageResponse>(\n `/customer/databases/${databaseId}/users`,\n req\n );\n },\n\n delete: async (databaseId: string, username: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(\n `/customer/databases/${databaseId}/users/${username}`\n );\n },\n },\n },\n };\n}\n\nexport type Db9Client = ReturnType<typeof createDb9Client>;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/credentials.ts","../src/client.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}\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}\n\nexport function createHttpClient(options: HttpClientOptions): HttpClient {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const baseUrl = options.baseUrl.replace(/\\/$/, ''); // strip trailing slash\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 // Append query params for GET requests\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, value);\n }\n }\n const qs = searchParams.toString();\n if (qs) url += `?${qs}`;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const response = await fetchFn(url, init);\n\n if (!response.ok) {\n throw await Db9Error.fromResponse(response);\n }\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\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 // Append query params for GET requests\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, value);\n }\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 init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = body;\n }\n\n const response = await fetchFn(url, init);\n\n if (!response.ok) {\n throw await Db9Error.fromResponse(response);\n }\n\n return response;\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 };\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 } from './http';\nimport {\n defaultCredentialStore,\n type CredentialStore,\n} from './credentials';\nimport { Db9Error } from './errors';\nimport type { Fs9FileInfo, Fs9StatResponse, 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 SchemaResponse,\n DumpRequest,\n DumpResponse,\n MigrationApplyRequest,\n MigrationApplyResponse,\n MigrationMetadata,\n BranchRequest,\n UserResponse,\n CreateUserRequest,\n} from './types';\n\nexport interface Db9ClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\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 });\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 });\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 async function fsRequest(\n method: string,\n dbId: string,\n fsPath: string,\n body?: string\n ): Promise<Response> {\n // Ensure token is loaded (lazy auth pattern)\n if (!token && !tokenLoaded) {\n await getAuthClient();\n }\n\n const fs9Url = deriveFs9Url(dbId);\n const url = `${fs9Url}/api/v1${fsPath}`;\n\n const headers: Record<string, string> = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n if (body !== undefined) {\n headers['Content-Type'] = 'text/plain';\n }\n\n const init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = body;\n }\n\n const response = await fetchFn(url, init);\n if (!response.ok) {\n throw await Db9Error.fromResponse(response);\n }\n return response;\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 const client = await getAuthClient();\n return client.get<CustomerResponse>('/customer/me');\n },\n\n getAnonymousSecret: async () => {\n const client = await getAuthClient();\n return client.get<AnonymousSecretResponse>(\n '/customer/anonymous-secret'\n );\n },\n\n claim: async (req: ClaimRequest) => {\n const client = await getAuthClient();\n return client.post<ClaimResponse>('/customer/claim', req);\n },\n },\n\n tokens: {\n list: async () => {\n const client = await getAuthClient();\n return client.get<TokenResponse[]>('/customer/tokens');\n },\n\n revoke: async (tokenId: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(`/customer/tokens/${tokenId}`);\n },\n },\n\n databases: {\n // ── CRUD ──────────────────────────────────────────────────\n create: async (req: CreateDatabaseRequest) => {\n const client = await getAuthClient();\n return client.post<DatabaseResponse>('/customer/databases', req);\n },\n\n list: async () => {\n const client = await getAuthClient();\n return client.get<DatabaseResponse[]>('/customer/databases');\n },\n\n get: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<DatabaseResponse>(\n `/customer/databases/${databaseId}`\n );\n },\n\n delete: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(\n `/customer/databases/${databaseId}`\n );\n },\n\n resetPassword: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.post<CustomerPasswordResetResponse>(\n `/customer/databases/${databaseId}/reset-password`\n );\n },\n\n observability: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<TenantObservabilityResponse>(\n `/customer/databases/${databaseId}/observability`\n );\n },\n\n // ── SQL Execution ─────────────────────────────────────────\n sql: async (databaseId: string, query: string) => {\n const client = await getAuthClient();\n return client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { query }\n );\n },\n\n sqlFile: async (databaseId: string, fileContent: string) => {\n const client = await getAuthClient();\n return client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { file_content: fileContent }\n );\n },\n\n // ── Schema & Dump ─────────────────────────────────────────\n schema: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<SchemaResponse>(\n `/customer/databases/${databaseId}/schema`\n );\n },\n\n dump: async (databaseId: string, req?: DumpRequest) => {\n const client = await getAuthClient();\n return 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 const client = await getAuthClient();\n return client.post<MigrationApplyResponse>(\n `/customer/databases/${databaseId}/migrations`,\n req\n );\n },\n\n listMigrations: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<MigrationMetadata[]>(\n `/customer/databases/${databaseId}/migrations`\n );\n },\n\n // ── Branching ─────────────────────────────────────────────\n branch: async (databaseId: string, req: BranchRequest) => {\n const client = await getAuthClient();\n return client.post<DatabaseResponse>(\n `/customer/databases/${databaseId}/branch`,\n req\n );\n },\n\n // ── User Management ───────────────────────────────────────\n users: {\n list: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<UserResponse[]>(\n `/customer/databases/${databaseId}/users`\n );\n },\n\n create: async (databaseId: string, req: CreateUserRequest) => {\n const client = await getAuthClient();\n return client.post<MessageResponse>(\n `/customer/databases/${databaseId}/users`,\n req\n );\n },\n\n delete: async (databaseId: string, username: string) => {\n const client = await getAuthClient();\n return 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<Fs9FileInfo[]> => {\n const params = new URLSearchParams({ path });\n if (options?.recursive) params.set('recursive', 'true');\n const response = await fsRequest(\n 'GET',\n dbId,\n `/readdir?${params.toString()}`\n );\n return response.json() as Promise<Fs9FileInfo[]>;\n },\n\n read: async (dbId: string, path: string): Promise<string> => {\n const params = new URLSearchParams({ path });\n const response = await fsRequest(\n 'GET',\n dbId,\n `/download?${params.toString()}`\n );\n return response.text();\n },\n\n write: async (\n dbId: string,\n path: string,\n content: string\n ): Promise<void> => {\n const params = new URLSearchParams({ path });\n await fsRequest('PUT', dbId, `/upload?${params.toString()}`, content);\n },\n\n stat: async (dbId: string, path: string): Promise<Fs9StatResponse> => {\n const params = new URLSearchParams({ path });\n const response = await fsRequest(\n 'GET',\n dbId,\n `/stat?${params.toString()}`\n );\n return response.json() as Promise<Fs9StatResponse>;\n },\n },\n };\n}\n\nexport type Db9Client = ReturnType<typeof createDb9Client>;\n"],"mappings":"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","names":["options"]}
package/dist/index.cjs CHANGED
@@ -124,11 +124,39 @@ function createHttpClient(options) {
124
124
  }
125
125
  return response.json();
126
126
  }
127
+ async function requestRaw(method, path, body, params, customHeaders) {
128
+ let url = `${baseUrl}${path}`;
129
+ if (params) {
130
+ const searchParams = new URLSearchParams();
131
+ for (const [key, value] of Object.entries(params)) {
132
+ if (value !== void 0) {
133
+ searchParams.set(key, value);
134
+ }
135
+ }
136
+ const qs = searchParams.toString();
137
+ if (qs) url += `?${qs}`;
138
+ }
139
+ const headers = {
140
+ ...options.headers,
141
+ ...customHeaders
142
+ };
143
+ const init = { method, headers };
144
+ if (body !== void 0) {
145
+ init.body = body;
146
+ }
147
+ const response = await fetchFn(url, init);
148
+ if (!response.ok) {
149
+ throw await Db9Error.fromResponse(response);
150
+ }
151
+ return response;
152
+ }
127
153
  return {
128
154
  get: (path, params) => request("GET", path, void 0, params),
129
155
  post: (path, body) => request("POST", path, body),
130
156
  put: (path, body) => request("PUT", path, body),
131
- del: (path) => request("DELETE", path)
157
+ del: (path) => request("DELETE", path),
158
+ getRaw: (path, params) => requestRaw("GET", path, void 0, params),
159
+ putRaw: (path, body, headers) => requestRaw("PUT", path, body, void 0, headers)
132
160
  };
133
161
  }
134
162
 
@@ -245,6 +273,7 @@ function createDb9Client(options = {}) {
245
273
  let token = options.token;
246
274
  let tokenLoaded = !!token;
247
275
  const store = options.credentialStore ?? defaultCredentialStore();
276
+ const fetchFn = options.fetch ?? globalThis.fetch;
248
277
  const publicClient = createHttpClient({
249
278
  baseUrl,
250
279
  fetch: options.fetch
@@ -273,6 +302,33 @@ function createDb9Client(options = {}) {
273
302
  headers: { Authorization: `Bearer ${token}` }
274
303
  });
275
304
  }
305
+ function deriveFs9Url(dbId) {
306
+ const origin = baseUrl.replace(/\/api\/?$/, "");
307
+ return `${origin}/fs9/${dbId}`;
308
+ }
309
+ async function fsRequest(method, dbId, fsPath, body) {
310
+ if (!token && !tokenLoaded) {
311
+ await getAuthClient();
312
+ }
313
+ const fs9Url = deriveFs9Url(dbId);
314
+ const url = `${fs9Url}/api/v1${fsPath}`;
315
+ const headers = {};
316
+ if (token) {
317
+ headers["Authorization"] = `Bearer ${token}`;
318
+ }
319
+ if (body !== void 0) {
320
+ headers["Content-Type"] = "text/plain";
321
+ }
322
+ const init = { method, headers };
323
+ if (body !== void 0) {
324
+ init.body = body;
325
+ }
326
+ const response = await fetchFn(url, init);
327
+ if (!response.ok) {
328
+ throw await Db9Error.fromResponse(response);
329
+ }
330
+ return response;
331
+ }
276
332
  return {
277
333
  auth: {
278
334
  // Public endpoints (no token required)
@@ -418,6 +474,40 @@ function createDb9Client(options = {}) {
418
474
  );
419
475
  }
420
476
  }
477
+ },
478
+ fs: {
479
+ list: async (dbId, path, options2) => {
480
+ const params = new URLSearchParams({ path });
481
+ if (options2?.recursive) params.set("recursive", "true");
482
+ const response = await fsRequest(
483
+ "GET",
484
+ dbId,
485
+ `/readdir?${params.toString()}`
486
+ );
487
+ return response.json();
488
+ },
489
+ read: async (dbId, path) => {
490
+ const params = new URLSearchParams({ path });
491
+ const response = await fsRequest(
492
+ "GET",
493
+ dbId,
494
+ `/download?${params.toString()}`
495
+ );
496
+ return response.text();
497
+ },
498
+ write: async (dbId, path, content) => {
499
+ const params = new URLSearchParams({ path });
500
+ await fsRequest("PUT", dbId, `/upload?${params.toString()}`, content);
501
+ },
502
+ stat: async (dbId, path) => {
503
+ const params = new URLSearchParams({ path });
504
+ const response = await fsRequest(
505
+ "GET",
506
+ dbId,
507
+ `/stat?${params.toString()}`
508
+ );
509
+ return response.json();
510
+ }
421
511
  }
422
512
  };
423
513
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/credentials.ts","../src/client.ts"],"sourcesContent":["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}\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 });\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","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\nexport interface HttpClientOptions {\n baseUrl: string;\n fetch?: FetchFn;\n headers?: Record<string, string>;\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}\n\nexport function createHttpClient(options: HttpClientOptions): HttpClient {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const baseUrl = options.baseUrl.replace(/\\/$/, ''); // strip trailing slash\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 // Append query params for GET requests\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, value);\n }\n }\n const qs = searchParams.toString();\n if (qs) url += `?${qs}`;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const response = await fetchFn(url, init);\n\n if (!response.ok) {\n throw await Db9Error.fromResponse(response);\n }\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\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 };\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 } from './http';\nimport {\n defaultCredentialStore,\n type CredentialStore,\n} from './credentials';\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 SchemaResponse,\n DumpRequest,\n DumpResponse,\n MigrationApplyRequest,\n MigrationApplyResponse,\n MigrationMetadata,\n BranchRequest,\n UserResponse,\n CreateUserRequest,\n} from './types';\n\nexport interface Db9ClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\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\n // Public HTTP client — no Authorization header\n const publicClient = createHttpClient({\n baseUrl,\n fetch: options.fetch,\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 });\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 const client = await getAuthClient();\n return client.get<CustomerResponse>('/customer/me');\n },\n\n getAnonymousSecret: async () => {\n const client = await getAuthClient();\n return client.get<AnonymousSecretResponse>(\n '/customer/anonymous-secret'\n );\n },\n\n claim: async (req: ClaimRequest) => {\n const client = await getAuthClient();\n return client.post<ClaimResponse>('/customer/claim', req);\n },\n },\n\n tokens: {\n list: async () => {\n const client = await getAuthClient();\n return client.get<TokenResponse[]>('/customer/tokens');\n },\n\n revoke: async (tokenId: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(`/customer/tokens/${tokenId}`);\n },\n },\n\n databases: {\n // ── CRUD ──────────────────────────────────────────────────\n create: async (req: CreateDatabaseRequest) => {\n const client = await getAuthClient();\n return client.post<DatabaseResponse>('/customer/databases', req);\n },\n\n list: async () => {\n const client = await getAuthClient();\n return client.get<DatabaseResponse[]>('/customer/databases');\n },\n\n get: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<DatabaseResponse>(\n `/customer/databases/${databaseId}`\n );\n },\n\n delete: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(\n `/customer/databases/${databaseId}`\n );\n },\n\n resetPassword: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.post<CustomerPasswordResetResponse>(\n `/customer/databases/${databaseId}/reset-password`\n );\n },\n\n observability: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<TenantObservabilityResponse>(\n `/customer/databases/${databaseId}/observability`\n );\n },\n\n // ── SQL Execution ─────────────────────────────────────────\n sql: async (databaseId: string, query: string) => {\n const client = await getAuthClient();\n return client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { query }\n );\n },\n\n sqlFile: async (databaseId: string, fileContent: string) => {\n const client = await getAuthClient();\n return client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { file_content: fileContent }\n );\n },\n\n // ── Schema & Dump ─────────────────────────────────────────\n schema: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<SchemaResponse>(\n `/customer/databases/${databaseId}/schema`\n );\n },\n\n dump: async (databaseId: string, req?: DumpRequest) => {\n const client = await getAuthClient();\n return 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 const client = await getAuthClient();\n return client.post<MigrationApplyResponse>(\n `/customer/databases/${databaseId}/migrations`,\n req\n );\n },\n\n listMigrations: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<MigrationMetadata[]>(\n `/customer/databases/${databaseId}/migrations`\n );\n },\n\n // ── Branching ─────────────────────────────────────────────\n branch: async (databaseId: string, req: BranchRequest) => {\n const client = await getAuthClient();\n return client.post<DatabaseResponse>(\n `/customer/databases/${databaseId}/branch`,\n req\n );\n },\n\n // ── User Management ───────────────────────────────────────\n users: {\n list: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<UserResponse[]>(\n `/customer/databases/${databaseId}/users`\n );\n },\n\n create: async (databaseId: string, req: CreateUserRequest) => {\n const client = await getAuthClient();\n return client.post<MessageResponse>(\n `/customer/databases/${databaseId}/users`,\n req\n );\n },\n\n delete: async (databaseId: string, username: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(\n `/customer/databases/${databaseId}/users/${username}`\n );\n },\n },\n },\n };\n}\n\nexport type Db9Client = ReturnType<typeof createDb9Client>;\n"],"mappings":"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","names":["parseToml","stringifyToml"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/credentials.ts","../src/client.ts"],"sourcesContent":["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}\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 });\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","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}\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}\n\nexport function createHttpClient(options: HttpClientOptions): HttpClient {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const baseUrl = options.baseUrl.replace(/\\/$/, ''); // strip trailing slash\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 // Append query params for GET requests\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, value);\n }\n }\n const qs = searchParams.toString();\n if (qs) url += `?${qs}`;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = JSON.stringify(body);\n }\n\n const response = await fetchFn(url, init);\n\n if (!response.ok) {\n throw await Db9Error.fromResponse(response);\n }\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\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 // Append query params for GET requests\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n searchParams.set(key, value);\n }\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 init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = body;\n }\n\n const response = await fetchFn(url, init);\n\n if (!response.ok) {\n throw await Db9Error.fromResponse(response);\n }\n\n return response;\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 };\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 } from './http';\nimport {\n defaultCredentialStore,\n type CredentialStore,\n} from './credentials';\nimport { Db9Error } from './errors';\nimport type { Fs9FileInfo, Fs9StatResponse, 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 SchemaResponse,\n DumpRequest,\n DumpResponse,\n MigrationApplyRequest,\n MigrationApplyResponse,\n MigrationMetadata,\n BranchRequest,\n UserResponse,\n CreateUserRequest,\n} from './types';\n\nexport interface Db9ClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\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 });\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 });\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 async function fsRequest(\n method: string,\n dbId: string,\n fsPath: string,\n body?: string\n ): Promise<Response> {\n // Ensure token is loaded (lazy auth pattern)\n if (!token && !tokenLoaded) {\n await getAuthClient();\n }\n\n const fs9Url = deriveFs9Url(dbId);\n const url = `${fs9Url}/api/v1${fsPath}`;\n\n const headers: Record<string, string> = {};\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n if (body !== undefined) {\n headers['Content-Type'] = 'text/plain';\n }\n\n const init: RequestInit = { method, headers };\n if (body !== undefined) {\n init.body = body;\n }\n\n const response = await fetchFn(url, init);\n if (!response.ok) {\n throw await Db9Error.fromResponse(response);\n }\n return response;\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 const client = await getAuthClient();\n return client.get<CustomerResponse>('/customer/me');\n },\n\n getAnonymousSecret: async () => {\n const client = await getAuthClient();\n return client.get<AnonymousSecretResponse>(\n '/customer/anonymous-secret'\n );\n },\n\n claim: async (req: ClaimRequest) => {\n const client = await getAuthClient();\n return client.post<ClaimResponse>('/customer/claim', req);\n },\n },\n\n tokens: {\n list: async () => {\n const client = await getAuthClient();\n return client.get<TokenResponse[]>('/customer/tokens');\n },\n\n revoke: async (tokenId: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(`/customer/tokens/${tokenId}`);\n },\n },\n\n databases: {\n // ── CRUD ──────────────────────────────────────────────────\n create: async (req: CreateDatabaseRequest) => {\n const client = await getAuthClient();\n return client.post<DatabaseResponse>('/customer/databases', req);\n },\n\n list: async () => {\n const client = await getAuthClient();\n return client.get<DatabaseResponse[]>('/customer/databases');\n },\n\n get: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<DatabaseResponse>(\n `/customer/databases/${databaseId}`\n );\n },\n\n delete: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.del<MessageResponse>(\n `/customer/databases/${databaseId}`\n );\n },\n\n resetPassword: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.post<CustomerPasswordResetResponse>(\n `/customer/databases/${databaseId}/reset-password`\n );\n },\n\n observability: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<TenantObservabilityResponse>(\n `/customer/databases/${databaseId}/observability`\n );\n },\n\n // ── SQL Execution ─────────────────────────────────────────\n sql: async (databaseId: string, query: string) => {\n const client = await getAuthClient();\n return client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { query }\n );\n },\n\n sqlFile: async (databaseId: string, fileContent: string) => {\n const client = await getAuthClient();\n return client.post<SqlResult>(\n `/customer/databases/${databaseId}/sql`,\n { file_content: fileContent }\n );\n },\n\n // ── Schema & Dump ─────────────────────────────────────────\n schema: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<SchemaResponse>(\n `/customer/databases/${databaseId}/schema`\n );\n },\n\n dump: async (databaseId: string, req?: DumpRequest) => {\n const client = await getAuthClient();\n return 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 const client = await getAuthClient();\n return client.post<MigrationApplyResponse>(\n `/customer/databases/${databaseId}/migrations`,\n req\n );\n },\n\n listMigrations: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<MigrationMetadata[]>(\n `/customer/databases/${databaseId}/migrations`\n );\n },\n\n // ── Branching ─────────────────────────────────────────────\n branch: async (databaseId: string, req: BranchRequest) => {\n const client = await getAuthClient();\n return client.post<DatabaseResponse>(\n `/customer/databases/${databaseId}/branch`,\n req\n );\n },\n\n // ── User Management ───────────────────────────────────────\n users: {\n list: async (databaseId: string) => {\n const client = await getAuthClient();\n return client.get<UserResponse[]>(\n `/customer/databases/${databaseId}/users`\n );\n },\n\n create: async (databaseId: string, req: CreateUserRequest) => {\n const client = await getAuthClient();\n return client.post<MessageResponse>(\n `/customer/databases/${databaseId}/users`,\n req\n );\n },\n\n delete: async (databaseId: string, username: string) => {\n const client = await getAuthClient();\n return 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<Fs9FileInfo[]> => {\n const params = new URLSearchParams({ path });\n if (options?.recursive) params.set('recursive', 'true');\n const response = await fsRequest(\n 'GET',\n dbId,\n `/readdir?${params.toString()}`\n );\n return response.json() as Promise<Fs9FileInfo[]>;\n },\n\n read: async (dbId: string, path: string): Promise<string> => {\n const params = new URLSearchParams({ path });\n const response = await fsRequest(\n 'GET',\n dbId,\n `/download?${params.toString()}`\n );\n return response.text();\n },\n\n write: async (\n dbId: string,\n path: string,\n content: string\n ): Promise<void> => {\n const params = new URLSearchParams({ path });\n await fsRequest('PUT', dbId, `/upload?${params.toString()}`, content);\n },\n\n stat: async (dbId: string, path: string): Promise<Fs9StatResponse> => {\n const params = new URLSearchParams({ path });\n const response = await fsRequest(\n 'GET',\n dbId,\n `/stat?${params.toString()}`\n );\n return response.json() as Promise<Fs9StatResponse>;\n },\n },\n };\n}\n\nexport type Db9Client = ReturnType<typeof createDb9Client>;\n"],"mappings":"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","names":["parseToml","stringifyToml","options"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FetchFn, C as CredentialStore } from './client-CSOh3r_q.cjs';
2
- export { A as AdminCreateUserRequest, a as AnonymousRefreshRequest, b as AnonymousRefreshResponse, c as AnonymousRegisterResponse, d as AnonymousSecretResponse, e as AuditLogParams, f as AuditLogResponse, B as BatchCreateRequest, g as BatchCreateResponse, h as BatchDeleteRequest, i as BatchDeleteResponse, j as BatchItemError, k as BatchUpdateRequest, l as BatchUpdateResponse, m as BranchRequest, n as ClaimRequest, o as ClaimResponse, p as ColumnInfo, q as ColumnMetadata, r as CreateDatabaseRequest, s as CreateTenantRequest, t as CreateTenantResponse, u as CreateUserRequest, v as Credentials, w as CustomerPasswordResetResponse, x as CustomerResponse, D as DatabaseResponse, y as Db9Client, z as Db9ClientOptions, E as DumpRequest, G as DumpResponse, H as Endpoint, I as FileCredentialStore, J as HealthResponse, K as HttpClient, L as HttpClientOptions, M as ListTenantsParams, N as LoginRequest, O as LoginResponse, P as MemoryCredentialStore, Q as MessageResponse, R as MigrationApplyRequest, S as MigrationApplyResponse, T as MigrationMetadata, U as ObservabilitySummary, V as PasswordResetResponse, W as QuerySample, X as RegisterRequest, Y as SchemaResponse, Z as SqlExecuteRequest, _ as SqlQueryRequest, $ as SqlQueryResponse, a0 as SqlResult, a1 as TableMetadata, a2 as TenantConnectRequest, a3 as TenantConnectResponse, a4 as TenantListResponse, a5 as TenantObservabilityResponse, a6 as TenantResponse, a7 as TenantState, a8 as TenantUpdateRequest, a9 as TokenResponse, aa as UserCreateResponse, ab as UserResponse, ac as ViewMetadata, ad as createDb9Client, ae as defaultCredentialStore } from './client-CSOh3r_q.cjs';
1
+ import { F as FetchFn, C as CredentialStore } from './client-fUeI7kwU.cjs';
2
+ export { A as AdminCreateUserRequest, a as AnonymousRefreshRequest, b as AnonymousRefreshResponse, c as AnonymousRegisterResponse, d as AnonymousSecretResponse, e as AuditLogParams, f as AuditLogResponse, B as BatchCreateRequest, g as BatchCreateResponse, h as BatchDeleteRequest, i as BatchDeleteResponse, j as BatchItemError, k as BatchUpdateRequest, l as BatchUpdateResponse, m as BranchRequest, n as ClaimRequest, o as ClaimResponse, p as ColumnInfo, q as ColumnMetadata, r as CreateDatabaseRequest, s as CreateTenantRequest, t as CreateTenantResponse, u as CreateUserRequest, v as Credentials, w as CustomerPasswordResetResponse, x as CustomerResponse, D as DatabaseResponse, y as Db9Client, z as Db9ClientOptions, E as DumpRequest, G as DumpResponse, H as Endpoint, I as FileCredentialStore, J as HealthResponse, K as HttpClient, L as HttpClientOptions, M as ListTenantsParams, N as LoginRequest, O as LoginResponse, P as MemoryCredentialStore, Q as MessageResponse, R as MigrationApplyRequest, S as MigrationApplyResponse, T as MigrationMetadata, U as ObservabilitySummary, V as PasswordResetResponse, W as QuerySample, X as RegisterRequest, Y as SchemaResponse, Z as SqlExecuteRequest, _ as SqlQueryRequest, $ as SqlQueryResponse, a0 as SqlResult, a1 as TableMetadata, a2 as TenantConnectRequest, a3 as TenantConnectResponse, a4 as TenantListResponse, a5 as TenantObservabilityResponse, a6 as TenantResponse, a7 as TenantState, a8 as TenantUpdateRequest, a9 as TokenResponse, aa as UserCreateResponse, ab as UserResponse, ac as ViewMetadata, ad as createDb9Client, ae as defaultCredentialStore } from './client-fUeI7kwU.cjs';
3
3
 
4
4
  declare class Db9Error extends Error {
5
5
  readonly statusCode: number;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FetchFn, C as CredentialStore } from './client-CSOh3r_q.js';
2
- export { A as AdminCreateUserRequest, a as AnonymousRefreshRequest, b as AnonymousRefreshResponse, c as AnonymousRegisterResponse, d as AnonymousSecretResponse, e as AuditLogParams, f as AuditLogResponse, B as BatchCreateRequest, g as BatchCreateResponse, h as BatchDeleteRequest, i as BatchDeleteResponse, j as BatchItemError, k as BatchUpdateRequest, l as BatchUpdateResponse, m as BranchRequest, n as ClaimRequest, o as ClaimResponse, p as ColumnInfo, q as ColumnMetadata, r as CreateDatabaseRequest, s as CreateTenantRequest, t as CreateTenantResponse, u as CreateUserRequest, v as Credentials, w as CustomerPasswordResetResponse, x as CustomerResponse, D as DatabaseResponse, y as Db9Client, z as Db9ClientOptions, E as DumpRequest, G as DumpResponse, H as Endpoint, I as FileCredentialStore, J as HealthResponse, K as HttpClient, L as HttpClientOptions, M as ListTenantsParams, N as LoginRequest, O as LoginResponse, P as MemoryCredentialStore, Q as MessageResponse, R as MigrationApplyRequest, S as MigrationApplyResponse, T as MigrationMetadata, U as ObservabilitySummary, V as PasswordResetResponse, W as QuerySample, X as RegisterRequest, Y as SchemaResponse, Z as SqlExecuteRequest, _ as SqlQueryRequest, $ as SqlQueryResponse, a0 as SqlResult, a1 as TableMetadata, a2 as TenantConnectRequest, a3 as TenantConnectResponse, a4 as TenantListResponse, a5 as TenantObservabilityResponse, a6 as TenantResponse, a7 as TenantState, a8 as TenantUpdateRequest, a9 as TokenResponse, aa as UserCreateResponse, ab as UserResponse, ac as ViewMetadata, ad as createDb9Client, ae as defaultCredentialStore } from './client-CSOh3r_q.js';
1
+ import { F as FetchFn, C as CredentialStore } from './client-fUeI7kwU.js';
2
+ export { A as AdminCreateUserRequest, a as AnonymousRefreshRequest, b as AnonymousRefreshResponse, c as AnonymousRegisterResponse, d as AnonymousSecretResponse, e as AuditLogParams, f as AuditLogResponse, B as BatchCreateRequest, g as BatchCreateResponse, h as BatchDeleteRequest, i as BatchDeleteResponse, j as BatchItemError, k as BatchUpdateRequest, l as BatchUpdateResponse, m as BranchRequest, n as ClaimRequest, o as ClaimResponse, p as ColumnInfo, q as ColumnMetadata, r as CreateDatabaseRequest, s as CreateTenantRequest, t as CreateTenantResponse, u as CreateUserRequest, v as Credentials, w as CustomerPasswordResetResponse, x as CustomerResponse, D as DatabaseResponse, y as Db9Client, z as Db9ClientOptions, E as DumpRequest, G as DumpResponse, H as Endpoint, I as FileCredentialStore, J as HealthResponse, K as HttpClient, L as HttpClientOptions, M as ListTenantsParams, N as LoginRequest, O as LoginResponse, P as MemoryCredentialStore, Q as MessageResponse, R as MigrationApplyRequest, S as MigrationApplyResponse, T as MigrationMetadata, U as ObservabilitySummary, V as PasswordResetResponse, W as QuerySample, X as RegisterRequest, Y as SchemaResponse, Z as SqlExecuteRequest, _ as SqlQueryRequest, $ as SqlQueryResponse, a0 as SqlResult, a1 as TableMetadata, a2 as TenantConnectRequest, a3 as TenantConnectResponse, a4 as TenantListResponse, a5 as TenantObservabilityResponse, a6 as TenantResponse, a7 as TenantState, a8 as TenantUpdateRequest, a9 as TokenResponse, aa as UserCreateResponse, ab as UserResponse, ac as ViewMetadata, ad as createDb9Client, ae as defaultCredentialStore } from './client-fUeI7kwU.js';
3
3
 
4
4
  declare class Db9Error extends Error {
5
5
  readonly statusCode: number;
package/dist/index.js CHANGED
@@ -80,11 +80,39 @@ function createHttpClient(options) {
80
80
  }
81
81
  return response.json();
82
82
  }
83
+ async function requestRaw(method, path, body, params, customHeaders) {
84
+ let url = `${baseUrl}${path}`;
85
+ if (params) {
86
+ const searchParams = new URLSearchParams();
87
+ for (const [key, value] of Object.entries(params)) {
88
+ if (value !== void 0) {
89
+ searchParams.set(key, value);
90
+ }
91
+ }
92
+ const qs = searchParams.toString();
93
+ if (qs) url += `?${qs}`;
94
+ }
95
+ const headers = {
96
+ ...options.headers,
97
+ ...customHeaders
98
+ };
99
+ const init = { method, headers };
100
+ if (body !== void 0) {
101
+ init.body = body;
102
+ }
103
+ const response = await fetchFn(url, init);
104
+ if (!response.ok) {
105
+ throw await Db9Error.fromResponse(response);
106
+ }
107
+ return response;
108
+ }
83
109
  return {
84
110
  get: (path, params) => request("GET", path, void 0, params),
85
111
  post: (path, body) => request("POST", path, body),
86
112
  put: (path, body) => request("PUT", path, body),
87
- del: (path) => request("DELETE", path)
113
+ del: (path) => request("DELETE", path),
114
+ getRaw: (path, params) => requestRaw("GET", path, void 0, params),
115
+ putRaw: (path, body, headers) => requestRaw("PUT", path, body, void 0, headers)
88
116
  };
89
117
  }
90
118
 
@@ -201,6 +229,7 @@ function createDb9Client(options = {}) {
201
229
  let token = options.token;
202
230
  let tokenLoaded = !!token;
203
231
  const store = options.credentialStore ?? defaultCredentialStore();
232
+ const fetchFn = options.fetch ?? globalThis.fetch;
204
233
  const publicClient = createHttpClient({
205
234
  baseUrl,
206
235
  fetch: options.fetch
@@ -229,6 +258,33 @@ function createDb9Client(options = {}) {
229
258
  headers: { Authorization: `Bearer ${token}` }
230
259
  });
231
260
  }
261
+ function deriveFs9Url(dbId) {
262
+ const origin = baseUrl.replace(/\/api\/?$/, "");
263
+ return `${origin}/fs9/${dbId}`;
264
+ }
265
+ async function fsRequest(method, dbId, fsPath, body) {
266
+ if (!token && !tokenLoaded) {
267
+ await getAuthClient();
268
+ }
269
+ const fs9Url = deriveFs9Url(dbId);
270
+ const url = `${fs9Url}/api/v1${fsPath}`;
271
+ const headers = {};
272
+ if (token) {
273
+ headers["Authorization"] = `Bearer ${token}`;
274
+ }
275
+ if (body !== void 0) {
276
+ headers["Content-Type"] = "text/plain";
277
+ }
278
+ const init = { method, headers };
279
+ if (body !== void 0) {
280
+ init.body = body;
281
+ }
282
+ const response = await fetchFn(url, init);
283
+ if (!response.ok) {
284
+ throw await Db9Error.fromResponse(response);
285
+ }
286
+ return response;
287
+ }
232
288
  return {
233
289
  auth: {
234
290
  // Public endpoints (no token required)
@@ -374,6 +430,40 @@ function createDb9Client(options = {}) {
374
430
  );
375
431
  }
376
432
  }
433
+ },
434
+ fs: {
435
+ list: async (dbId, path, options2) => {
436
+ const params = new URLSearchParams({ path });
437
+ if (options2?.recursive) params.set("recursive", "true");
438
+ const response = await fsRequest(
439
+ "GET",
440
+ dbId,
441
+ `/readdir?${params.toString()}`
442
+ );
443
+ return response.json();
444
+ },
445
+ read: async (dbId, path) => {
446
+ const params = new URLSearchParams({ path });
447
+ const response = await fsRequest(
448
+ "GET",
449
+ dbId,
450
+ `/download?${params.toString()}`
451
+ );
452
+ return response.text();
453
+ },
454
+ write: async (dbId, path, content) => {
455
+ const params = new URLSearchParams({ path });
456
+ await fsRequest("PUT", dbId, `/upload?${params.toString()}`, content);
457
+ },
458
+ stat: async (dbId, path) => {
459
+ const params = new URLSearchParams({ path });
460
+ const response = await fsRequest(
461
+ "GET",
462
+ dbId,
463
+ `/stat?${params.toString()}`
464
+ );
465
+ return response.json();
466
+ }
377
467
  }
378
468
  };
379
469
  }