Loading article…
ReferenceJavaScript client API

DocsLoading article…
These declarations are generated by TypeScript from the same code used by the example applications.
import { type DatabaseShape, type RowOf, type InsertOf, type UpdateOf, type Query, type Result, type Session, type Filter, type AggregateExpr, type HavingClause, type RelationsOf } from './contracts/index';
export { QBError } from './contracts/index';
export type { Result, Session, Query } from './contracts/index';
export interface ClientOptions {
url: string;
projectId: string;
branch?: string;
publishableKey: string;
fetch?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
timeoutMs?: number;
credentials?: RequestCredentials;
}
export interface RequestOptions {
signal?: AbortSignal;
idempotencyKey?: string;
revision?: number;
}
export interface DatabaseEvent {
type: 'database';
eventId: string;
table: string;
event: 'insert' | 'update' | 'delete';
payload: Record<string, unknown>;
schemaVersion: number;
}
export interface ChannelOptions {
table: string;
cursor?: string;
onEvent: (event: DatabaseEvent) => void;
onStatus?: (status: string) => void;
onResync?: () => void;
}
/** Create one client per application or SSR request. Only publishable keys belong in browser bundles. */
export type RPCShape = Record<string, {
Args: Record<string, unknown>;
Returns: unknown;
}>;
export declare function createClient<D = DatabaseShape, R = RPCShape>(options: ClientOptions): QBClient<D, R>;
export declare class QBClient<D = DatabaseShape, R = RPCShape> {
readonly options: ClientOptions;
readonly baseURL: string;
readonly scope: string;
private token;
private session;
private listeners;
private refreshPromise;
private channels;
private disposed;
private epoch;
private pending;
private betterAuthClient;
constructor(options: ClientOptions);
getSession(): Session | null;
/**
* Better-auth client for WebAuthn ceremonies against the branch auth realm.
* The custom fetch injects the publishable key plus the current bearer
* session on every request, mirroring `request()` header behavior.
*/
private authClient;
getIdentityVersion(): number;
getToken(): string | null;
onAuthStateChange(listener: (session: Session | null) => void): () => void;
private setSession;
request<T>(path: string, method?: string, body?: unknown, options?: RequestOptions & {
safe?: boolean;
raw?: boolean;
auth?: boolean;
refresh?: boolean;
}): Promise<T>;
private delay;
from<K extends keyof D & string>(table: K): QueryBuilder<D, K, RowOf<D, K>>;
auth: {
signUp: (input: {
email: string;
password: string;
name: string;
}) => Promise<{
user: any;
token: any;
} | null>;
signIn: (input: {
email: string;
password: string;
}) => Promise<{
user: any;
token: any;
}>;
/** Requests a single-use magic link. The success body does not reveal whether the account exists. */
signInWithMagicLink: (email: string, options?: {
callbackURL?: string;
redirectTo?: string;
}) => Promise<{
status: boolean;
}>;
signOut: () => Promise<void>;
passkey: {
/** Runs the WebAuthn registration ceremony for the current application user. */
enroll: (opts?: {
name?: string;
}) => Promise<unknown>;
list: () => Promise<unknown[]>;
remove: (id: string) => Promise<void>;
rename: (id: string, name: string) => Promise<void>;
/** Runs the WebAuthn authentication ceremony and adopts the returned session. */
signIn: () => Promise<{
user: any;
token: any;
} | null>;
};
twoFactor: {
/** Returns the TOTP enrollment URI and one-time backup codes. */
enable: (password: string) => Promise<{
totpURI: string;
backupCodes: string[];
}>;
verify: (code: string) => Promise<void>;
disable: (password: string) => Promise<void>;
};
refreshSession: () => Promise<Session | null>;
resetPassword: (email: string, redirectTo: string) => Promise<unknown>;
updatePassword: (token: string, newPassword: string) => Promise<unknown>;
sendVerification: (email: string, callbackURL: string) => Promise<unknown>;
signInWithProvider: (provider: "google" | "github", callbackURL: string) => Promise<{
url: string;
}>;
};
rpc<K extends keyof R & string>(operation: K, args: R[K] extends {
Args: infer A;
} ? A : never, options?: RequestOptions): Promise<Result<R[K] extends {
Returns: infer T;
} ? T : unknown>>;
search(input: {
collection: string;
q: string;
limit?: number;
cursor?: string;
}, options?: RequestOptions): Promise<Result<{
hits: {
id: string;
table: string;
rank: number;
snippet: string | null;
row: Record<string, unknown>;
}[];
count: number | null;
cursor: string | null;
}>>;
channel(options: ChannelOptions): QBChannel;
storage: {
listBuckets: () => Promise<Result<any[]>>;
list: (bucket: string) => Promise<Result<any[]>>;
upload: (bucket: string, key: string, file: Blob, options?: RequestOptions & {
checksum?: string;
}) => Promise<Result<{
id: string;
state: string;
}>>;
download: (id: string, options?: RequestOptions) => Promise<Blob>;
remove: (id: string, options?: RequestOptions) => Promise<Result<{
deleted: boolean;
}>>;
};
dispose(): void;
}
export declare class QueryBuilder<D, K extends keyof D & string, R> implements PromiseLike<Result<R[]>> {
private client;
private table;
private query;
private options;
constructor(client: QBClient<D, any>, table: K, query: Query, options?: RequestOptions);
private next;
select<C extends keyof RowOf<D, K> & string>(columns?: C[]): QueryBuilder<D, K, Pick<RowOf<D, K>, C>>;
filter(column: keyof RowOf<D, K> & string, op: Filter['op'], value?: Filter['value']): QueryBuilder<D, K, R>;
eq<C extends keyof RowOf<D, K> & string>(column: C, value: RowOf<D, K>[C]): QueryBuilder<D, K, R>;
order(column: keyof RowOf<D, K> & string, direction?: 'asc' | 'desc'): QueryBuilder<D, K, R>;
limit(limit: number): QueryBuilder<D, K, R>;
cursor(cursor: string): QueryBuilder<D, K, R>;
include<N extends keyof RelationsOf<D, K> & string>(relations: {
name: N;
columns?: string[];
limit?: number;
}[]): QueryBuilder<D, K, R & Pick<RelationsOf<D, K>, N>>;
count(): QueryBuilder<D, K, R>;
groupBy(columns: (keyof RowOf<D, K> & string)[]): QueryBuilder<D, K, R>;
aggregate(fn: AggregateExpr['fn'], column?: keyof RowOf<D, K> & string, alias?: string): QueryBuilder<D, K, R>;
having(alias: string, op: HavingClause['op'], value: HavingClause['value']): QueryBuilder<D, K, R>;
abortSignal(signal: AbortSignal): QueryBuilder<D, K, R>;
execute(): Promise<Result<R[]>>;
then<A = Result<R[]>, B = never>(fulfilled?: ((result: Result<R[]>) => A | PromiseLike<A>) | null, rejected?: ((reason: any) => B | PromiseLike<B>) | null): PromiseLike<A | B>;
insert(row: InsertOf<D, K> | InsertOf<D, K>[], options?: RequestOptions): Promise<Result<RowOf<D, K>[]>>;
upsert(row: InsertOf<D, K> | InsertOf<D, K>[], options?: RequestOptions): Promise<Result<RowOf<D, K>[]>>;
update(key: string | number | unknown[], row: UpdateOf<D, K>, options?: RequestOptions): Promise<Result<RowOf<D, K>[]>>;
delete(key: string | number | unknown[], options?: RequestOptions): Promise<Result<RowOf<D, K>[]>>;
}
export declare class QBChannel {
private client;
private options;
private onDispose;
private socket;
private stopped;
private retry;
private timer?;
private heartbeat?;
private cursor?;
private seen;
constructor(client: QBClient<any, any>, options: ChannelOptions, onDispose: () => void);
subscribe(): this;
private connect;
reauthenticate(): void;
unsubscribe(): void;
}