@onyx.dev/onyx-database
Version:
TypeScript client SDK for Onyx Database
1,191 lines (1,178 loc) • 37.2 kB
TypeScript
/**
* Supported operators for building query criteria.
*
* @example
* ```ts
* const criteria = { field: 'age', operator: 'GREATER_THAN', value: 21 };
* ```
*/
type QueryCriteriaOperator = 'EQUAL' | 'NOT_EQUAL' | 'IN' | 'NOT_IN' | 'GREATER_THAN' | 'GREATER_THAN_EQUAL' | 'LESS_THAN' | 'LESS_THAN_EQUAL' | 'MATCHES' | 'NOT_MATCHES' | 'BETWEEN' | 'LIKE' | 'NOT_LIKE' | 'CONTAINS' | 'CONTAINS_IGNORE_CASE' | 'NOT_CONTAINS' | 'NOT_CONTAINS_IGNORE_CASE' | 'STARTS_WITH' | 'NOT_STARTS_WITH' | 'IS_NULL' | 'NOT_NULL';
/** Logical operator used to join conditions in a query. */
type LogicalOperator = 'AND' | 'OR';
/**
* Sorting instruction for query results.
*
* @property field - Field name to order by.
* @property order - Sort direction.
* @example
* ```ts
* const sort: Sort = { field: 'name', order: 'ASC' };
* ```
*/
interface Sort {
field: string;
order: 'ASC' | 'DESC';
}
/** Actions emitted by real-time data streams. */
type StreamAction = 'CREATE' | 'UPDATE' | 'DELETE' | 'QUERY_RESPONSE' | 'KEEP_ALIVE';
/**
* Basic document representation used by the SDK.
*
* @example
* ```ts
* const doc: OnyxDocument = { documentId: '1', content: 'hello' };
* ```
*/
interface OnyxDocument {
/** Unique document identifier. */
documentId?: string;
/** Path within the Onyx database. */
path?: string;
/** Creation timestamp. */
created?: Date;
/** Last update timestamp. */
updated?: Date;
/** MIME type of the content. */
mimeType?: string;
/** Raw document content. */
content?: string;
}
/** Minimal fetch typing to avoid DOM lib dependency */
interface FetchResponse {
/** Whether the request succeeded (status in the range 200–299). */
ok: boolean;
/** HTTP status code. */
status: number;
/** HTTP status text. */
statusText: string;
/** Response headers getter. */
headers: {
get(name: string): string | null;
};
/** Reads the body as text. */
text(): Promise<string>;
/** Raw body for streams; left as unknown to avoid DOM typings */
body?: unknown;
}
/**
* Fetch implementation signature used by the SDK.
*
* @param url - Resource URL.
* @param init - Optional init parameters.
* @example
* ```ts
* const res = await fetchImpl('https://api.onyx.dev');
* ```
*/
type FetchImpl = (url: string, init?: {
method?: string;
headers?: Record<string, string>;
body?: string;
}) => Promise<FetchResponse>;
/**
* Represents a single field comparison in a query.
*
* @property field - Field name to evaluate.
* @property operator - Comparison operator.
* @property value - Value to compare against.
* @example
* ```ts
* const criteria: QueryCriteria = { field: 'age', operator: 'GREATER_THAN', value: 18 };
* ```
*/
interface QueryCriteria {
field: string;
operator: QueryCriteriaOperator;
value?: unknown;
}
/**
* Recursive condition structure used to express complex WHERE clauses.
*
* @example
* ```ts
* const condition: QueryCondition = {
* conditionType: 'CompoundCondition',
* operator: 'AND',
* conditions: [
* { conditionType: 'SingleCondition', criteria: { field: 'age', operator: 'GREATER_THAN', value: 18 } },
* { conditionType: 'SingleCondition', criteria: { field: 'status', operator: 'EQUAL', value: 'ACTIVE' } }
* ]
* };
* ```
*/
type QueryCondition = {
conditionType: 'SingleCondition';
criteria: QueryCriteria;
} | {
conditionType: 'CompoundCondition';
operator: LogicalOperator;
conditions: QueryCondition[];
};
/**
* Wire format for select queries sent to the server.
*
* @example
* ```ts
* const query: SelectQuery = {
* type: 'SelectQuery',
* fields: ['id', 'name'],
* limit: 10
* };
* ```
*/
interface SelectQuery {
type: 'SelectQuery';
fields?: string[] | null;
conditions?: QueryCondition | null;
sort?: Sort[] | null;
limit?: number | null;
distinct?: boolean | null;
groupBy?: string[] | null;
partition?: string | null;
resolvers?: string[] | null;
}
/**
* Wire format for update queries sent to the server.
*
* @example
* ```ts
* const update: UpdateQuery = {
* type: 'UpdateQuery',
* updates: { name: 'New Name' }
* };
* ```
*/
interface UpdateQuery {
type: 'UpdateQuery';
conditions?: QueryCondition | null;
updates: Record<string, unknown>;
sort?: Sort[] | null;
limit?: number | null;
partition?: string | null;
}
/**
* A single page of query results.
*
* @example
* ```ts
* const page: QueryPage<User> = { records: users, nextPage: token };
* ```
*/
interface QueryPage<T> {
/** Records in the current page. */
records: T[];
/** Token for the next page or null if none. */
nextPage?: string | null;
}
/**
* Array-like container for paginated query results. Provides helper methods
* to traverse and aggregate records across pages.
*
* @example
* ```ts
* const results = new QueryResults(users, nextToken, fetchNext);
* const firstUser = results.first();
* ```
*/
type QueryResultsPromise<T> = Promise<QueryResults<T>> & {
[K in keyof QueryResults<T> as QueryResults<T>[K] extends (...args: any[]) => any ? K : never]: QueryResults<T>[K] extends (...args: infer P) => infer R ? (...args: P) => Promise<Awaited<R>> : never;
};
declare class QueryResults<T> extends Array<T> {
/** Token for the next page of results or null. */
nextPage: string | null;
private readonly fetcher?;
/**
* @param records - Records in the current page.
* @param nextPage - Token representing the next page.
* @param fetcher - Function used to fetch the next page when needed.
* @example
* ```ts
* const results = new QueryResults(users, token, t => fetchMore(t));
* ```
*/
constructor(records: Iterable<T> | ArrayLike<T> | T | null | undefined, nextPage: string | null, fetcher?: (token: string) => Promise<QueryResults<T>>);
/**
* Returns the first record in the result set.
* @throws Error if the result set is empty.
* @example
* ```ts
* const user = results.first();
* ```
*/
first(): T;
/**
* Returns the first record or `null` if the result set is empty.
* @example
* ```ts
* const user = results.firstOrNull();
* ```
*/
firstOrNull(): T | null;
/**
* Checks whether the current page has no records.
* @example
* ```ts
* if (results.isEmpty()) console.log('no data');
* ```
*/
isEmpty(): boolean;
/**
* Number of records on the current page.
* @example
* ```ts
* console.log(results.size());
* ```
*/
size(): number;
/**
* Iterates over each record on the current page only.
* @param action - Function to invoke for each record.
* @param thisArg - Optional `this` binding for the callback.
* @example
* ```ts
* results.forEachOnPage(u => console.log(u.id));
* ```
*/
forEachOnPage(action: (item: T, index: number, array: QueryResults<T>) => void, thisArg?: unknown): void;
/**
* Iterates over every record across all pages sequentially.
* @param action - Function executed for each record. Returning `false`
* stops iteration early.
* @param thisArg - Optional `this` binding for the callback.
* @example
* ```ts
* await results.forEach(u => {
* console.log(u.id);
* });
* ```
*/
forEach(action: (item: T, index: number, array: T[]) => void, thisArg?: unknown): Promise<void>;
/**
* Iterates over every record across all pages sequentially.
* @param action - Function executed for each record. Returning `false`
* stops iteration early.
* @example
* ```ts
* await results.forEachAll(u => {
* if (u.disabled) return false;
* });
* ```
*/
forEachAll(action: (item: T) => boolean | void | Promise<boolean | void>): Promise<void>;
/**
* Iterates page by page across the result set.
* @param action - Function invoked with each page of records. Returning
* `false` stops iteration.
* @example
* ```ts
* await results.forEachPage(page => {
* console.log(page.length);
* });
* ```
*/
forEachPage(action: (records: T[]) => boolean | void | Promise<boolean | void>): Promise<void>;
/**
* Collects all records from every page into a single array.
* @returns All records.
* @example
* ```ts
* const allUsers = await results.getAllRecords();
* ```
*/
getAllRecords(): Promise<T[]>;
/**
* Filters all records using the provided predicate.
* @param predicate - Function used to test each record.
* @example
* ```ts
* const enabled = await results.filterAll(u => u.enabled);
* ```
*/
filterAll(predicate: (record: T) => boolean): Promise<T[]>;
/**
* Maps all records using the provided transform.
* @param transform - Mapping function.
* @example
* ```ts
* const names = await results.mapAll(u => u.name);
* ```
*/
mapAll<R>(transform: (record: T) => R): Promise<R[]>;
/**
* Extracts values for a field across all records.
* @param field - Name of the field to pluck.
* @example
* ```ts
* const ids = await results.values('id');
* ```
*/
values<K extends keyof T>(field: K): Promise<Array<T[K]>>;
/**
* Maximum value produced by the selector across all records.
* @param selector - Function extracting a numeric value.
* @example
* ```ts
* const maxAge = await results.maxOfDouble(u => u.age);
* ```
*/
maxOfDouble(selector: (record: T) => number): Promise<number>;
/**
* Minimum value produced by the selector across all records.
* @param selector - Function extracting a numeric value.
* @example
* ```ts
* const minAge = await results.minOfDouble(u => u.age);
* ```
*/
minOfDouble(selector: (record: T) => number): Promise<number>;
/**
* Sum of values produced by the selector across all records.
* @param selector - Function extracting a numeric value.
* @example
* ```ts
* const total = await results.sumOfDouble(u => u.score);
* ```
*/
sumOfDouble(selector: (record: T) => number): Promise<number>;
/**
* Maximum float value from the selector.
* @param selector - Function extracting a numeric value.
*/
maxOfFloat(selector: (record: T) => number): Promise<number>;
/**
* Minimum float value from the selector.
* @param selector - Function extracting a numeric value.
*/
minOfFloat(selector: (record: T) => number): Promise<number>;
/**
* Sum of float values from the selector.
* @param selector - Function extracting a numeric value.
*/
sumOfFloat(selector: (record: T) => number): Promise<number>;
/**
* Maximum integer value from the selector.
* @param selector - Function extracting a numeric value.
*/
maxOfInt(selector: (record: T) => number): Promise<number>;
/**
* Minimum integer value from the selector.
* @param selector - Function extracting a numeric value.
*/
minOfInt(selector: (record: T) => number): Promise<number>;
/**
* Sum of integer values from the selector.
* @param selector - Function extracting a numeric value.
*/
sumOfInt(selector: (record: T) => number): Promise<number>;
/**
* Maximum long value from the selector.
* @param selector - Function extracting a numeric value.
*/
maxOfLong(selector: (record: T) => number): Promise<number>;
/**
* Minimum long value from the selector.
* @param selector - Function extracting a numeric value.
*/
minOfLong(selector: (record: T) => number): Promise<number>;
/**
* Sum of long values from the selector.
* @param selector - Function extracting a numeric value.
*/
sumOfLong(selector: (record: T) => number): Promise<number>;
/**
* Sum of bigint values from the selector.
* @param selector - Function extracting a bigint value.
* @example
* ```ts
* const total = await results.sumOfBigInt(u => u.balance);
* ```
*/
sumOfBigInt(selector: (record: T) => bigint): Promise<bigint>;
/**
* Executes an action for each page in parallel.
* @param action - Function executed for each record concurrently.
* @example
* ```ts
* await results.forEachPageParallel(async u => sendEmail(u));
* ```
*/
forEachPageParallel(action: (item: T) => void | Promise<void>): Promise<void>;
}
/**
* Builder used to compose query conditions.
*/
interface IConditionBuilder {
/**
* Combines the current condition with another using `AND`.
* @param condition - Additional condition or builder.
* @example
* ```ts
* cb.and({ field: 'age', operator: 'GREATER_THAN', value: 18 });
* ```
*/
and(condition: IConditionBuilder | QueryCriteria): IConditionBuilder;
/**
* Combines the current condition with another using `OR`.
* @param condition - Additional condition or builder.
* @example
* ```ts
* cb.or({ field: 'status', operator: 'EQUAL', value: 'ACTIVE' });
* ```
*/
or(condition: IConditionBuilder | QueryCriteria): IConditionBuilder;
/**
* Materializes the composed condition into a `QueryCondition` object.
* @example
* ```ts
* const cond = cb.toCondition();
* ```
*/
toCondition(): QueryCondition;
}
/**
* Fluent query builder for constructing and executing select/update/delete operations.
*/
interface IQueryBuilder<T = unknown> {
/**
* Sets the table to query.
* @example
* ```ts
* const users = await db.from('User').list();
* ```
*/
from(table: string): IQueryBuilder<T>;
/**
* Selects a subset of fields to return.
* @example
* ```ts
* const emails = await db.from('User').selectFields('email').list();
* ```
*/
selectFields(...fields: Array<string | string[]>): IQueryBuilder<T>;
/**
* Resolves related values by name.
* @example
* ```ts
* const users = await db
* .from('User')
* .resolve('profile', 'roles')
* .list();
* ```
*/
resolve(...values: Array<string | string[]>): IQueryBuilder<T>;
/**
* Adds a filter condition.
* @example
* ```ts
* const active = await db.from('User').where(eq('status', 'active')).list();
* ```
*/
where(condition: IConditionBuilder | QueryCriteria): IQueryBuilder<T>;
/**
* Adds an additional filter with `AND`.
* @example
* ```ts
* qb.where(eq('status', 'active')).and(eq('role', 'admin'));
* ```
*/
and(condition: IConditionBuilder | QueryCriteria): IQueryBuilder<T>;
/**
* Adds an additional filter with `OR`.
* @example
* ```ts
* qb.where(eq('status', 'active')).or(eq('status', 'invited'));
* ```
*/
or(condition: IConditionBuilder | QueryCriteria): IQueryBuilder<T>;
/**
* Orders results by the provided fields.
* @example
* ```ts
* const users = await db.from('User').orderBy(asc('createdAt')).list();
* ```
*/
orderBy(...sorts: Sort[]): IQueryBuilder<T>;
/**
* Groups results by the provided fields.
* @example
* ```ts
* const stats = await db.from('User').groupBy('status').list();
* ```
*/
groupBy(...fields: string[]): IQueryBuilder<T>;
/**
* Ensures only distinct records are returned.
* @example
* ```ts
* const roles = await db.from('User').selectFields('role').distinct().list();
* ```
*/
distinct(): IQueryBuilder<T>;
/**
* Limits the number of records returned.
* @example
* ```ts
* const few = await db.from('User').limit(5).list();
* ```
*/
limit(n: number): IQueryBuilder<T>;
/**
* Restricts the query to a specific partition.
* @example
* ```ts
* const tenantUsers = await db.from('User').inPartition('tenantA').list();
* ```
*/
inPartition(partition: string): IQueryBuilder<T>;
/** Sets the page size for subsequent `list` or `page` calls. */
pageSize(n: number): IQueryBuilder<T>;
/**
* Continues a paged query using a next-page token.
* @example
* ```ts
* const page2 = await db.from('User').nextPage(token).list();
* ```
*/
nextPage(token: string): IQueryBuilder<T>;
/**
* Counts matching records.
* @example
* ```ts
* const total = await db.from('User').count();
* ```
*/
count(): Promise<number>;
/**
* Lists records with optional pagination.
* @example
* ```ts
* const users = await db.from('User').list({ pageSize: 10 });
* ```
*/
list(options?: {
pageSize?: number;
nextPage?: string;
}): QueryResultsPromise<T>;
/**
* Retrieves the first record or null.
* @example
* ```ts
* const user = await db.from('User').firstOrNull();
* ```
*/
firstOrNull(): Promise<T | null>;
/**
* Retrieves exactly one record or null.
* @example
* ```ts
* const user = await db
* .from('User')
* .where(eq('email', 'a@b.com'))
* .one();
* ```
*/
one(): Promise<T | null>;
/**
* Retrieves a single page of records with optional next token.
* @example
* ```ts
* const { records, nextPage } = await db.from('User').page({ pageSize: 25 });
* ```
*/
page(options?: {
pageSize?: number;
nextPage?: string;
}): Promise<{
records: T[];
nextPage?: string | null;
}>;
/**
* Sets field updates for an update query.
* @example
* ```ts
* await db
* .from('User')
* .where(eq('id', 'u1'))
* .setUpdates({ status: 'active' })
* .update();
* ```
*/
setUpdates(updates: Partial<T>): IQueryBuilder<T>;
/**
* Executes an update operation.
* @example
* ```ts
* await db.from('User').where(eq('id', 'u1')).setUpdates({ status: 'active' }).update();
* ```
*/
update(): Promise<unknown>;
/**
* Executes a delete operation.
* @example
* ```ts
* await db.from('User').where(eq('status', 'inactive')).delete();
* ```
*/
delete(): Promise<unknown>;
/**
* Registers a listener for added items on a stream.
* @example
* ```ts
* db.from('User').onItemAdded(u => console.log('added', u));
* ```
*/
onItemAdded(listener: (entity: T) => void): IQueryBuilder<T>;
/**
* Registers a listener for updated items on a stream.
* @example
* ```ts
* db.from('User').onItemUpdated(u => console.log('updated', u));
* ```
*/
onItemUpdated(listener: (entity: T) => void): IQueryBuilder<T>;
/**
* Registers a listener for deleted items on a stream.
* @example
* ```ts
* db.from('User').onItemDeleted(u => console.log('deleted', u));
* ```
*/
onItemDeleted(listener: (entity: T) => void): IQueryBuilder<T>;
/**
* Registers a listener for any stream item with its action.
* @example
* ```ts
* db.from('User').onItem((u, action) => console.log(action, u));
* ```
*/
onItem(listener: (entity: T | null, action: StreamAction) => void): IQueryBuilder<T>;
/**
* Starts a stream including query results.
* @example
* ```ts
* const { cancel } = await db.from('User').stream();
* ```
*/
stream(includeQueryResults?: boolean, keepAlive?: boolean): Promise<{
cancel: () => void;
}>;
/**
* Starts a stream emitting only events.
* @example
* ```ts
* const { cancel } = await db.from('User').streamEventsOnly();
* ```
*/
streamEventsOnly(keepAlive?: boolean): Promise<{
cancel: () => void;
}>;
/**
* Starts a stream that returns events alongside query results.
* @example
* ```ts
* const { cancel } = await db.from('User').streamWithQueryResults();
* ```
*/
streamWithQueryResults(keepAlive?: boolean): Promise<{
cancel: () => void;
}>;
}
/** Builder for save operations. */
interface ISaveBuilder<T = unknown> {
/**
* Cascades specified relationships when saving.
* @example
* ```ts
* await db.save('User').cascade('role').one(user);
* ```
*/
cascade(...relationships: Array<string | string[]>): ISaveBuilder<T>;
/**
* Persists a single entity.
* @example
* ```ts
* await db.save('User').one({ id: 'u1' });
* ```
*/
one(entity: Partial<T>): Promise<unknown>;
/**
* Persists multiple entities.
* @example
* ```ts
* await db.save('User').many([{ id: 'u1' }, { id: 'u2' }]);
* ```
*/
many(entities: Array<Partial<T>>): Promise<unknown>;
}
/** Builder for cascading save/delete operations across multiple tables. */
interface ICascadeBuilder<Schema = Record<string, unknown>> {
/**
* Specifies relationships to cascade through.
* @example
* ```ts
* const builder = db.cascade('permissions');
* ```
*/
cascade(...relationships: Array<string | string[]>): ICascadeBuilder<Schema>;
/**
* Saves one or many entities for a given table.
* @example
* ```ts
* await db.cascade('permissions').save('Role', role);
* ```
*/
save<Table extends keyof Schema & string>(table: Table, entityOrEntities: Partial<Schema[Table]> | Array<Partial<Schema[Table]>>): Promise<unknown>;
/**
* Deletes an entity by primary key.
* @example
* ```ts
* await db.cascade('permissions').delete('Role', 'admin');
* ```
*/
delete<Table extends keyof Schema & string>(table: Table, primaryKey: string): Promise<Schema[Table]>;
}
/** Builder for describing cascade relationship metadata. */
interface ICascadeRelationshipBuilder {
/**
* Names the relationship graph.
* @example
* ```ts
* builder.graph('permissions');
* ```
*/
graph(name: string): ICascadeRelationshipBuilder;
/**
* Sets the graph type.
* @example
* ```ts
* builder.graphType('Permission');
* ```
*/
graphType(type: string): ICascadeRelationshipBuilder;
/**
* Field on the target entity.
* @example
* ```ts
* builder.targetField('roleId');
* ```
*/
targetField(field: string): ICascadeRelationshipBuilder;
/**
* Field on the source entity.
* @example
* ```ts
* const rel = builder.sourceField('id');
* ```
*/
sourceField(field: string): string;
}
interface OnyxConfig {
baseUrl?: string;
databaseId?: string;
apiKey?: string;
apiSecret?: string;
fetch?: FetchImpl;
/**
* Default partition for queries, `findById`, and deletes when removing by
* primary key. Saves rely on the entity's partition field instead.
*/
partition?: string;
/**
* When true, log HTTP requests and bodies to the console.
*/
requestLoggingEnabled?: boolean;
/**
* When true, log HTTP responses and bodies to the console.
*/
responseLoggingEnabled?: boolean;
/**
* Milliseconds to cache resolved credentials; defaults to 5 minutes.
*/
ttl?: number;
}
interface IOnyxDatabase<Schema = Record<string, unknown>> {
/**
* Begin a query against a table.
*
* @example
* ```ts
* const maybeUser = await db
* .from('User')
* .where(eq('email', 'a@b.com'))
* .firstOrNull(); // or .one()
* ```
*
* @example
* ```ts
* const users = await db
* .select('id', 'email')
* .from('User')
* .list();
* ```
*
* @param table Table name to query.
*/
from<Table extends keyof Schema & string>(table: Table): IQueryBuilder<Schema[Table]>;
/**
* Select specific fields for a query.
*
* @example
* ```ts
* const users = await db
* .select('id', 'name')
* .from('User')
* .list();
* ```
*
* @param fields Field names to project; omit to select all.
*/
select(...fields: string[]): IQueryBuilder<Record<string, unknown>>;
/**
* Include related records in the next save or delete.
*
* @example
* ```ts
* // Save a role and its permissions
* await db
* .cascade('permissions:Permission(roleId, id)')
* .save('Role', role);
*
* // Delete a role and all of its permissions via resolver
* await db
* .cascade('permissions')
* .delete('Role', 'admin');
* ```
*
* @param relationships Cascade relationship strings using
* `graph:Type(targetField, sourceField)` syntax when saving.
* When deleting, pass resolver attribute names only.
*/
cascade(...relationships: Array<string | string[]>): ICascadeBuilder<Schema>;
/**
* Build cascade relationship strings programmatically.
*
* @example
* ```ts
* const rel = db
* .cascadeBuilder()
* .graph('permissions')
* .graphType('Permission')
* .targetField('roleId')
* .sourceField('id');
* await db.cascade(rel).save('Role', role);
* ```
*
* @returns Builder that emits strings like
* `graphName:TypeName(targetField, sourceField)`.
*/
cascadeBuilder(): ICascadeRelationshipBuilder;
/**
* Start a save builder for inserting or updating entities.
*
* @example
* ```ts
* await db
* .save('User')
* .cascade('role:Role(userId, id)')
* .one({
* id: 'u1',
* email: 'a@b.com',
* role: { id: 'admin', userId: 'u1' }
* });
* ```
*
* @param table Table to save into.
*/
save<Table extends keyof Schema & string>(table: Table): ISaveBuilder<Schema[Table]>;
/**
* Save one or many entities immediately.
*
* @example
* ```ts
* await db.save(
* 'Role',
* [{ id: 'admin', permissions: [{ id: 'perm1', roleId: 'admin' }] }],
* { relationships: ['permissions:Permission(roleId, id)'] }
* );
* ```
*
* The `relationships` option accepts cascade strings in the form
* `graphName:TypeName(targetField, sourceField)` describing how child records relate to the
* parent. Use {@link cascadeBuilder} to construct them safely.
*
* @param table Table to save into.
* @param entityOrEntities Object or array of objects to persist.
* @param options Optional settings for the save operation.
* @param options.relationships Cascade relationships to include.
*/
save<Table extends keyof Schema & string>(table: Table, entityOrEntities: Partial<Schema[Table]> | Array<Partial<Schema[Table]>>, options?: {
relationships?: string[];
}): Promise<unknown>;
/**
* Save many entities in configurable batches.
*
* @example
* ```ts
* await db.batchSave('User', users, 500);
* ```
*
* @param table Table to save into.
* @param entities Array of entities to persist.
* @param batchSize Number of entities per batch; defaults to 1000.
*/
batchSave<Table extends keyof Schema & string>(table: Table, entities: Array<Partial<Schema[Table]>>, batchSize?: number, options?: {
relationships?: string[];
}): Promise<void>;
/**
* Retrieve an entity by its primary key.
*
* @example
* ```ts
* const user = await db.findById('User', 'user_1', {
* partition: 'tenantA',
* resolvers: ['profile']
* });
* ```
*
* @param table Table to search.
* @param primaryKey Primary key value.
* @param options Optional partition and resolver settings.
*/
findById<Table extends keyof Schema & string, T = Schema[Table]>(table: Table, primaryKey: string, options?: {
partition?: string;
resolvers?: string[];
}): Promise<T | null>;
/**
* Delete an entity by primary key.
*
* @example
* ```ts
* const deleted = await db.delete('Role', 'admin', {
* relationships: ['permissions']
* });
* ```
*
* @param table Table containing the entity.
* @param primaryKey Primary key value.
* @param options Optional partition and cascade relationships.
*/
delete<Table extends keyof Schema & string, T = Schema[Table]>(table: Table, primaryKey: string, options?: {
partition?: string;
relationships?: string[];
}): Promise<T>;
/**
* Store a document (file blob) for later retrieval.
*
* @example
* ```ts
* const id = await db.saveDocument({
* path: '/docs/note.txt',
* mimeType: 'text/plain',
* content: 'hello world'
* });
* ```
*/
saveDocument(doc: OnyxDocument): Promise<unknown>;
/**
* Fetch a previously saved document.
*
* @example
* ```ts
* const doc = await db.getDocument('doc123', { width: 640, height: 480 });
* ```
*
* @param documentId ID of the document to fetch.
* @param options Optional image resize settings.
*/
getDocument(documentId: string, options?: {
width?: number;
height?: number;
}): Promise<unknown>;
/**
* Remove a stored document permanently.
*
* @example
* ```ts
* await db.deleteDocument('doc123');
* ```
*
* @param documentId ID of the document to delete.
*/
deleteDocument(documentId: string): Promise<unknown>;
/**
* Cancels active streams; safe to call multiple times.
* @example
* ```ts
* const stream = await db.from('User').stream();
* stream.cancel();
* db.close();
* ```
*/
close(): void;
}
interface OnyxFacade {
/**
* Initialize a database client.
*
* @example
* ```ts
* const db = onyx.init({
* baseUrl: 'https://api.onyx.dev',
* databaseId: 'my-db',
* apiKey: 'key',
* apiSecret: 'secret'
* });
* ```
*
* @param config Connection settings and optional custom fetch.
* @remarks
* Each `db` instance resolves configuration once and holds a single internal
* HTTP client. Requests leverage Node's built-in `fetch`, which reuses and
* pools connections for keep-alive, so additional connection caching or
* pooling is rarely necessary.
*/
init<Schema = Record<string, unknown>>(config?: OnyxConfig): IOnyxDatabase<Schema>;
/**
* Clear cached configuration so the next {@link init} call re-resolves
* credentials immediately.
*/
clearCacheConfig(): void;
}
/** -------------------------
* Facade export
* --------------------------*/
declare const onyx: OnyxFacade;
declare const asc: (field: string) => Sort;
declare const desc: (field: string) => Sort;
/** Builder for combining query conditions with logical operators. */
declare class ConditionBuilderImpl implements IConditionBuilder {
private condition;
/**
* Initialize with an optional starting criteria.
*
* @param criteria Initial query criteria to seed the builder.
* @example
* ```ts
* const builder = new ConditionBuilderImpl({ field: 'id', operator: 'eq', value: '1' });
* ```
*/
constructor(criteria?: QueryCriteria | null);
/**
* Add a criteria combined with AND.
*
* @param condition Another builder or raw criteria to AND.
* @example
* ```ts
* builder.and({ field: 'name', operator: 'eq', value: 'Ada' });
* ```
*/
and(condition: IConditionBuilder | QueryCriteria): IConditionBuilder;
/**
* Add a criteria combined with OR.
*
* @param condition Another builder or raw criteria to OR.
* @example
* ```ts
* builder.or({ field: 'status', operator: 'eq', value: 'active' });
* ```
*/
or(condition: IConditionBuilder | QueryCriteria): IConditionBuilder;
/**
* Produce the composed QueryCondition.
*
* @example
* ```ts
* const condition = builder.toCondition();
* ```
*/
toCondition(): QueryCondition;
/**
* Wrap raw criteria into a single condition object.
*
* @param criteria Criteria to wrap.
* @example
* ```ts
* builder['single']({ field: 'id', operator: 'eq', value: '1' });
* ```
*/
private single;
/**
* Create a compound condition using the provided operator.
*
* @param operator Logical operator to apply.
* @param conditions Child conditions to combine.
* @example
* ```ts
* builder['compound']('AND', [condA, condB]);
* ```
*/
private compound;
/**
* Merge the next condition into the existing tree using the operator.
*
* @param operator Logical operator for the merge.
* @param next Condition to merge into the tree.
* @example
* ```ts
* builder['addCompound']('AND', someCondition);
* ```
*/
private addCompound;
/**
* Normalize input into a QueryCondition instance.
*
* @param condition Builder or raw criteria to normalize.
* @example
* ```ts
* const qc = builder['prepare']({ field: 'id', operator: 'eq', value: '1' });
* ```
*/
private prepare;
}
declare const eq: (field: string, value: unknown) => ConditionBuilderImpl;
declare const neq: (field: string, value: unknown) => ConditionBuilderImpl;
declare const inOp: (field: string, values: unknown[] | string) => ConditionBuilderImpl;
declare const notIn: (field: string, values: unknown[]) => ConditionBuilderImpl;
declare const between: (field: string, lower: unknown, upper: unknown) => ConditionBuilderImpl;
declare const gt: (field: string, value: unknown) => ConditionBuilderImpl;
declare const gte: (field: string, value: unknown) => ConditionBuilderImpl;
declare const lt: (field: string, value: unknown) => ConditionBuilderImpl;
declare const lte: (field: string, value: unknown) => ConditionBuilderImpl;
declare const matches: (field: string, regex: string) => ConditionBuilderImpl;
declare const notMatches: (field: string, regex: string) => ConditionBuilderImpl;
declare const like: (field: string, pattern: string) => ConditionBuilderImpl;
declare const notLike: (field: string, pattern: string) => ConditionBuilderImpl;
declare const contains: (field: string, value: unknown) => ConditionBuilderImpl;
declare const containsIgnoreCase: (field: string, value: unknown) => ConditionBuilderImpl;
declare const notContains: (field: string, value: unknown) => ConditionBuilderImpl;
declare const notContainsIgnoreCase: (field: string, value: unknown) => ConditionBuilderImpl;
declare const startsWith: (field: string, prefix: string) => ConditionBuilderImpl;
declare const notStartsWith: (field: string, prefix: string) => ConditionBuilderImpl;
declare const isNull: (field: string) => ConditionBuilderImpl;
declare const notNull: (field: string) => ConditionBuilderImpl;
declare const avg: (attribute: string) => string;
declare const sum: (attribute: string) => string;
declare const count: (attribute: string) => string;
declare const min: (attribute: string) => string;
declare const max: (attribute: string) => string;
declare const std: (attribute: string) => string;
declare const variance: (attribute: string) => string;
declare const median: (attribute: string) => string;
declare const upper: (attribute: string) => string;
declare const lower: (attribute: string) => string;
declare const substring: (attribute: string, from: number, length: number) => string;
declare const replace: (attribute: string, pattern: string, repl: string) => string;
declare const percentile: (attribute: string, p: number) => string;
declare const sdkName = "@onyx.dev/onyx-database";
declare const sdkVersion = "0.1.0";
export { type FetchImpl, type FetchResponse, type ICascadeBuilder, type ICascadeRelationshipBuilder, type IConditionBuilder, type IOnyxDatabase, type IQueryBuilder, type ISaveBuilder, type LogicalOperator, type OnyxConfig, type OnyxDocument, type OnyxFacade, type QueryCondition, type QueryCriteria, type QueryCriteriaOperator, type QueryPage, QueryResults, type QueryResultsPromise, type SelectQuery, type Sort, type StreamAction, type UpdateQuery, asc, avg, between, contains, containsIgnoreCase, count, desc, eq, gt, gte, inOp, isNull, like, lower, lt, lte, matches, max, median, min, neq, notContains, notContainsIgnoreCase, notIn, notLike, notMatches, notNull, notStartsWith, onyx, percentile, replace, sdkName, sdkVersion, startsWith, std, substring, sum, upper, variance };