get-db9 0.2.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 +0,0 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/customer.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 { createHttpClient, type FetchFn, type HttpClient } from './http';\nimport type { CredentialStore } 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 CustomerClientOptions {\n baseUrl?: string;\n token?: string;\n fetch?: FetchFn;\n credentialStore?: CredentialStore;\n}\n\nexport function createCustomerClient(options: CustomerClientOptions = {}) {\n const baseUrl =\n options.baseUrl ?? 'https://db9.shared.aws.tidbcloud.com/api';\n let token = options.token;\n let tokenLoaded = !!token;\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 && options.credentialStore) {\n const creds = await options.credentialStore.load();\n if (creds) token = creds.token;\n tokenLoaded = true;\n }\n if (!token) throw new Error('No authentication token available');\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 CustomerClient = ReturnType<typeof createCustomerClient>;\n"],"mappings":"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","names":[]}