@reactor-cloud/data 0.2.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.
- package/README.md +112 -0
- package/dist/index.cjs +423 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +310 -0
- package/dist/index.d.ts +310 -0
- package/dist/index.js +416 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { RequestContext, Result } from '@reactor-cloud/shared';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generic schema for untyped queries.
|
|
5
|
+
*/
|
|
6
|
+
type GenericSchema = {
|
|
7
|
+
Tables: Record<string, {
|
|
8
|
+
Row: Record<string, unknown>;
|
|
9
|
+
Insert: Record<string, unknown>;
|
|
10
|
+
Update: Record<string, unknown>;
|
|
11
|
+
}>;
|
|
12
|
+
Views: Record<string, {
|
|
13
|
+
Row: Record<string, unknown>;
|
|
14
|
+
}>;
|
|
15
|
+
Functions: Record<string, {
|
|
16
|
+
Args: Record<string, unknown>;
|
|
17
|
+
Returns: unknown;
|
|
18
|
+
}>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Count mode for queries.
|
|
22
|
+
*/
|
|
23
|
+
type CountMode = 'exact' | 'planned' | 'estimated';
|
|
24
|
+
/**
|
|
25
|
+
* Response format options.
|
|
26
|
+
*/
|
|
27
|
+
type ResponseFormat = 'json' | 'csv' | 'geojson';
|
|
28
|
+
/**
|
|
29
|
+
* Filter operators supported by reactor-data.
|
|
30
|
+
*/
|
|
31
|
+
type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'ilike' | 'in' | 'is' | 'cs' | 'cd' | 'ov' | 'fts';
|
|
32
|
+
/**
|
|
33
|
+
* Result modifier for single row queries.
|
|
34
|
+
*/
|
|
35
|
+
type ResultModifier = 'single' | 'maybeSingle';
|
|
36
|
+
/**
|
|
37
|
+
* Query execution options.
|
|
38
|
+
*/
|
|
39
|
+
interface QueryOptions {
|
|
40
|
+
/** AbortSignal for cancellation */
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
/** Count mode */
|
|
43
|
+
count?: CountMode;
|
|
44
|
+
/** Custom headers */
|
|
45
|
+
headers?: Record<string, string>;
|
|
46
|
+
/** Return result as CSV */
|
|
47
|
+
csv?: boolean;
|
|
48
|
+
/** Return query execution plan */
|
|
49
|
+
explain?: boolean | {
|
|
50
|
+
analyze?: boolean;
|
|
51
|
+
verbose?: boolean;
|
|
52
|
+
costs?: boolean;
|
|
53
|
+
buffers?: boolean;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Order options.
|
|
58
|
+
*/
|
|
59
|
+
interface OrderOptions {
|
|
60
|
+
ascending?: boolean;
|
|
61
|
+
nullsFirst?: boolean;
|
|
62
|
+
foreignTable?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Upsert options.
|
|
66
|
+
*/
|
|
67
|
+
interface UpsertOptions {
|
|
68
|
+
onConflict?: string;
|
|
69
|
+
ignoreDuplicates?: boolean;
|
|
70
|
+
count?: CountMode;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Query result with optional count.
|
|
74
|
+
*/
|
|
75
|
+
interface QueryResult<T> {
|
|
76
|
+
data: T;
|
|
77
|
+
count?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Full-text search options.
|
|
81
|
+
*/
|
|
82
|
+
interface TextSearchOptions {
|
|
83
|
+
type?: 'plain' | 'phrase' | 'websearch';
|
|
84
|
+
config?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Filter value types.
|
|
88
|
+
*/
|
|
89
|
+
type FilterValue = string | number | boolean | null | (string | number | boolean)[];
|
|
90
|
+
/**
|
|
91
|
+
* Pending filter to be applied.
|
|
92
|
+
*/
|
|
93
|
+
interface PendingFilter {
|
|
94
|
+
column: string;
|
|
95
|
+
operator: FilterOperator;
|
|
96
|
+
value: FilterValue;
|
|
97
|
+
negated: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Type helper for selecting specific columns.
|
|
101
|
+
*/
|
|
102
|
+
type SelectResult<T, Columns extends string> = Pick<T, Extract<keyof T, Columns>>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* PostgrestFilterBuilder provides methods for building filter queries.
|
|
106
|
+
*/
|
|
107
|
+
declare class PostgrestFilterBuilder<T, ResultType = T[]> {
|
|
108
|
+
protected table: string;
|
|
109
|
+
protected ctx: RequestContext;
|
|
110
|
+
protected selectColumns: string;
|
|
111
|
+
protected filters: PendingFilter[];
|
|
112
|
+
protected orderClauses: string[];
|
|
113
|
+
protected limitValue?: number;
|
|
114
|
+
protected offsetValue?: number;
|
|
115
|
+
protected countMode?: CountMode;
|
|
116
|
+
protected signalValue?: AbortSignal;
|
|
117
|
+
protected customHeaders: Record<string, string>;
|
|
118
|
+
protected responseFormat: 'json' | 'csv';
|
|
119
|
+
protected explainMode?: {
|
|
120
|
+
analyze?: boolean;
|
|
121
|
+
verbose?: boolean;
|
|
122
|
+
costs?: boolean;
|
|
123
|
+
buffers?: boolean;
|
|
124
|
+
};
|
|
125
|
+
protected resultModifier?: 'single' | 'maybeSingle';
|
|
126
|
+
protected method: 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
127
|
+
protected body?: unknown;
|
|
128
|
+
constructor(ctx: RequestContext, table: string);
|
|
129
|
+
/** Equal to */
|
|
130
|
+
eq<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
131
|
+
/** Not equal to */
|
|
132
|
+
neq<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
133
|
+
/** Greater than */
|
|
134
|
+
gt<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
135
|
+
/** Greater than or equal */
|
|
136
|
+
gte<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
137
|
+
/** Less than */
|
|
138
|
+
lt<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
139
|
+
/** Less than or equal */
|
|
140
|
+
lte<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
141
|
+
/** Pattern match (LIKE) */
|
|
142
|
+
like<K extends keyof T & string>(column: K, pattern: string): this;
|
|
143
|
+
/** Case-insensitive pattern match (ILIKE) */
|
|
144
|
+
ilike<K extends keyof T & string>(column: K, pattern: string): this;
|
|
145
|
+
/** Is NULL or boolean */
|
|
146
|
+
is<K extends keyof T & string>(column: K, value: null | boolean): this;
|
|
147
|
+
/** In list */
|
|
148
|
+
in<K extends keyof T & string>(column: K, values: T[K][]): this;
|
|
149
|
+
/** Array contains */
|
|
150
|
+
contains<K extends keyof T & string>(column: K, values: unknown[]): this;
|
|
151
|
+
/** Array contained by */
|
|
152
|
+
containedBy<K extends keyof T & string>(column: K, values: unknown[]): this;
|
|
153
|
+
/** Array overlaps */
|
|
154
|
+
overlaps<K extends keyof T & string>(column: K, values: unknown[]): this;
|
|
155
|
+
/** Full-text search */
|
|
156
|
+
textSearch<K extends keyof T & string>(column: K, query: string, options?: TextSearchOptions): this;
|
|
157
|
+
/** Match multiple conditions (shorthand for multiple eq) */
|
|
158
|
+
match(query: Partial<T>): this;
|
|
159
|
+
/** Negate a filter */
|
|
160
|
+
not<K extends keyof T & string>(column: K, operator: FilterOperator, value: FilterValue): this;
|
|
161
|
+
/** OR condition (raw string format) */
|
|
162
|
+
or(conditions: string, options?: {
|
|
163
|
+
foreignTable?: string;
|
|
164
|
+
}): this;
|
|
165
|
+
/** Generic filter (escape hatch) */
|
|
166
|
+
filter<K extends keyof T & string>(column: K, operator: FilterOperator, value: FilterValue): this;
|
|
167
|
+
/** Order results */
|
|
168
|
+
order<K extends keyof T & string>(column: K, options?: OrderOptions): this;
|
|
169
|
+
/** Limit results */
|
|
170
|
+
limit(count: number, options?: {
|
|
171
|
+
foreignTable?: string;
|
|
172
|
+
}): this;
|
|
173
|
+
/** Offset results (for pagination) */
|
|
174
|
+
range(from: number, to: number, options?: {
|
|
175
|
+
foreignTable?: string;
|
|
176
|
+
}): this;
|
|
177
|
+
/** Provide an AbortSignal */
|
|
178
|
+
abortSignal(signal: AbortSignal): this;
|
|
179
|
+
/** Return CSV instead of JSON */
|
|
180
|
+
csv(): PostgrestFilterBuilder<T, string>;
|
|
181
|
+
/** Return query execution plan */
|
|
182
|
+
explain(options?: {
|
|
183
|
+
analyze?: boolean;
|
|
184
|
+
verbose?: boolean;
|
|
185
|
+
costs?: boolean;
|
|
186
|
+
buffers?: boolean;
|
|
187
|
+
}): this;
|
|
188
|
+
/** Override return type */
|
|
189
|
+
returns<R>(): PostgrestFilterBuilder<R, R[]>;
|
|
190
|
+
/** Execute and return exactly one row (throws if not exactly one) */
|
|
191
|
+
single(): PostgrestFilterBuilder<T, T>;
|
|
192
|
+
/** Execute and return zero or one row */
|
|
193
|
+
maybeSingle(): PostgrestFilterBuilder<T, T | null>;
|
|
194
|
+
protected buildUrl(): string;
|
|
195
|
+
protected buildHeaders(): Record<string, string>;
|
|
196
|
+
/** Execute the query */
|
|
197
|
+
then<TResult1 = Result<ResultType>, TResult2 = never>(onfulfilled?: ((value: Result<ResultType>) => TResult1 | PromiseLike<TResult1>) | null, _onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
198
|
+
protected execute(): Promise<Result<unknown>>;
|
|
199
|
+
/** Throw on error instead of returning { data, error } */
|
|
200
|
+
throwOnError(): Promise<ResultType>;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Builder for SELECT queries with column selection.
|
|
204
|
+
*/
|
|
205
|
+
declare class PostgrestQueryBuilder<T> extends PostgrestFilterBuilder<T> {
|
|
206
|
+
/** Select specific columns */
|
|
207
|
+
select<Columns extends string = '*'>(columns?: Columns, options?: {
|
|
208
|
+
count?: CountMode;
|
|
209
|
+
}): PostgrestFilterBuilder<T>;
|
|
210
|
+
/** Insert row(s) */
|
|
211
|
+
insert(values: Partial<T> | Partial<T>[], options?: {
|
|
212
|
+
count?: CountMode;
|
|
213
|
+
}): PostgrestFilterBuilder<T>;
|
|
214
|
+
/** Upsert row(s) */
|
|
215
|
+
upsert(values: Partial<T> | Partial<T>[], options?: UpsertOptions): PostgrestFilterBuilder<T>;
|
|
216
|
+
/** Update row(s) */
|
|
217
|
+
update(values: Partial<T>, options?: {
|
|
218
|
+
count?: CountMode;
|
|
219
|
+
}): PostgrestFilterBuilder<T>;
|
|
220
|
+
/** Delete row(s) */
|
|
221
|
+
delete(options?: {
|
|
222
|
+
count?: CountMode;
|
|
223
|
+
}): PostgrestFilterBuilder<T>;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Call a database function via RPC.
|
|
228
|
+
*/
|
|
229
|
+
declare function rpc<Args extends Record<string, unknown>, Returns>(ctx: RequestContext, functionName: string, args: Args, options?: {
|
|
230
|
+
signal?: AbortSignal;
|
|
231
|
+
headers?: Record<string, string>;
|
|
232
|
+
}): Promise<Result<Returns>>;
|
|
233
|
+
/**
|
|
234
|
+
* RPC builder for type-safe function calls.
|
|
235
|
+
*/
|
|
236
|
+
declare class RpcBuilder<Args extends Record<string, unknown>, Returns> {
|
|
237
|
+
private ctx;
|
|
238
|
+
private functionName;
|
|
239
|
+
private args?;
|
|
240
|
+
private signal?;
|
|
241
|
+
private customHeaders;
|
|
242
|
+
constructor(ctx: RequestContext, functionName: string);
|
|
243
|
+
/** Set function arguments */
|
|
244
|
+
call(args: Args): this;
|
|
245
|
+
/** Provide an AbortSignal */
|
|
246
|
+
abortSignal(signal: AbortSignal): this;
|
|
247
|
+
/** Set custom headers */
|
|
248
|
+
headers(headers: Record<string, string>): this;
|
|
249
|
+
/** Execute the RPC call */
|
|
250
|
+
then<TResult1 = Result<Returns>, TResult2 = never>(onfulfilled?: ((value: Result<Returns>) => TResult1 | PromiseLike<TResult1>) | null, _onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
251
|
+
/** Throw on error */
|
|
252
|
+
throwOnError(): Promise<Returns>;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Data client for Reactor - PostgREST-style query builder.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```ts
|
|
260
|
+
* const client = new DataClient(ctx);
|
|
261
|
+
*
|
|
262
|
+
* // Select with filters
|
|
263
|
+
* const { data, error } = await client
|
|
264
|
+
* .from('posts')
|
|
265
|
+
* .select('id, title, author:users(name)')
|
|
266
|
+
* .eq('published', true)
|
|
267
|
+
* .order('created_at', { ascending: false })
|
|
268
|
+
* .limit(10);
|
|
269
|
+
*
|
|
270
|
+
* // Insert
|
|
271
|
+
* const { data } = await client
|
|
272
|
+
* .from('posts')
|
|
273
|
+
* .insert({ title: 'Hello', body: 'World' })
|
|
274
|
+
* .select()
|
|
275
|
+
* .single();
|
|
276
|
+
*
|
|
277
|
+
* // RPC
|
|
278
|
+
* const { data } = await client.rpc('search', { query: 'rust' });
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
declare class DataClient<Schema extends GenericSchema = GenericSchema> {
|
|
282
|
+
private ctx;
|
|
283
|
+
constructor(ctx: RequestContext);
|
|
284
|
+
/**
|
|
285
|
+
* Start a query on a table.
|
|
286
|
+
*
|
|
287
|
+
* @param table - The table name
|
|
288
|
+
* @returns A query builder
|
|
289
|
+
*/
|
|
290
|
+
from<TableName extends keyof Schema['Tables'] & string>(table: TableName): PostgrestQueryBuilder<Schema['Tables'][TableName]['Row']>;
|
|
291
|
+
/**
|
|
292
|
+
* Call a database function via RPC.
|
|
293
|
+
*
|
|
294
|
+
* @param functionName - The function name
|
|
295
|
+
* @param args - Function arguments
|
|
296
|
+
* @returns RPC builder
|
|
297
|
+
*/
|
|
298
|
+
rpc<FunctionName extends keyof Schema['Functions'] & string, Args extends Schema['Functions'][FunctionName]['Args'], Returns = Schema['Functions'][FunctionName]['Returns']>(functionName: FunctionName, args?: Args): RpcBuilder<Args, Returns>;
|
|
299
|
+
/**
|
|
300
|
+
* Access a schema (for multi-schema support).
|
|
301
|
+
* Currently returns self as we only support public schema.
|
|
302
|
+
*/
|
|
303
|
+
schema(_name: string): DataClient<Schema>;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Create a data client with typed schema.
|
|
307
|
+
*/
|
|
308
|
+
declare function createDataClient<Schema extends GenericSchema = GenericSchema>(ctx: RequestContext): DataClient<Schema>;
|
|
309
|
+
|
|
310
|
+
export { type CountMode, DataClient, type FilterOperator, type FilterValue, type GenericSchema, type OrderOptions, type PendingFilter, PostgrestFilterBuilder, PostgrestQueryBuilder, type QueryOptions, type QueryResult, type ResponseFormat, type ResultModifier, RpcBuilder, type SelectResult, type TextSearchOptions, type UpsertOptions, createDataClient, rpc };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { RequestContext, Result } from '@reactor-cloud/shared';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generic schema for untyped queries.
|
|
5
|
+
*/
|
|
6
|
+
type GenericSchema = {
|
|
7
|
+
Tables: Record<string, {
|
|
8
|
+
Row: Record<string, unknown>;
|
|
9
|
+
Insert: Record<string, unknown>;
|
|
10
|
+
Update: Record<string, unknown>;
|
|
11
|
+
}>;
|
|
12
|
+
Views: Record<string, {
|
|
13
|
+
Row: Record<string, unknown>;
|
|
14
|
+
}>;
|
|
15
|
+
Functions: Record<string, {
|
|
16
|
+
Args: Record<string, unknown>;
|
|
17
|
+
Returns: unknown;
|
|
18
|
+
}>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Count mode for queries.
|
|
22
|
+
*/
|
|
23
|
+
type CountMode = 'exact' | 'planned' | 'estimated';
|
|
24
|
+
/**
|
|
25
|
+
* Response format options.
|
|
26
|
+
*/
|
|
27
|
+
type ResponseFormat = 'json' | 'csv' | 'geojson';
|
|
28
|
+
/**
|
|
29
|
+
* Filter operators supported by reactor-data.
|
|
30
|
+
*/
|
|
31
|
+
type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'ilike' | 'in' | 'is' | 'cs' | 'cd' | 'ov' | 'fts';
|
|
32
|
+
/**
|
|
33
|
+
* Result modifier for single row queries.
|
|
34
|
+
*/
|
|
35
|
+
type ResultModifier = 'single' | 'maybeSingle';
|
|
36
|
+
/**
|
|
37
|
+
* Query execution options.
|
|
38
|
+
*/
|
|
39
|
+
interface QueryOptions {
|
|
40
|
+
/** AbortSignal for cancellation */
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
/** Count mode */
|
|
43
|
+
count?: CountMode;
|
|
44
|
+
/** Custom headers */
|
|
45
|
+
headers?: Record<string, string>;
|
|
46
|
+
/** Return result as CSV */
|
|
47
|
+
csv?: boolean;
|
|
48
|
+
/** Return query execution plan */
|
|
49
|
+
explain?: boolean | {
|
|
50
|
+
analyze?: boolean;
|
|
51
|
+
verbose?: boolean;
|
|
52
|
+
costs?: boolean;
|
|
53
|
+
buffers?: boolean;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Order options.
|
|
58
|
+
*/
|
|
59
|
+
interface OrderOptions {
|
|
60
|
+
ascending?: boolean;
|
|
61
|
+
nullsFirst?: boolean;
|
|
62
|
+
foreignTable?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Upsert options.
|
|
66
|
+
*/
|
|
67
|
+
interface UpsertOptions {
|
|
68
|
+
onConflict?: string;
|
|
69
|
+
ignoreDuplicates?: boolean;
|
|
70
|
+
count?: CountMode;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Query result with optional count.
|
|
74
|
+
*/
|
|
75
|
+
interface QueryResult<T> {
|
|
76
|
+
data: T;
|
|
77
|
+
count?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Full-text search options.
|
|
81
|
+
*/
|
|
82
|
+
interface TextSearchOptions {
|
|
83
|
+
type?: 'plain' | 'phrase' | 'websearch';
|
|
84
|
+
config?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Filter value types.
|
|
88
|
+
*/
|
|
89
|
+
type FilterValue = string | number | boolean | null | (string | number | boolean)[];
|
|
90
|
+
/**
|
|
91
|
+
* Pending filter to be applied.
|
|
92
|
+
*/
|
|
93
|
+
interface PendingFilter {
|
|
94
|
+
column: string;
|
|
95
|
+
operator: FilterOperator;
|
|
96
|
+
value: FilterValue;
|
|
97
|
+
negated: boolean;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Type helper for selecting specific columns.
|
|
101
|
+
*/
|
|
102
|
+
type SelectResult<T, Columns extends string> = Pick<T, Extract<keyof T, Columns>>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* PostgrestFilterBuilder provides methods for building filter queries.
|
|
106
|
+
*/
|
|
107
|
+
declare class PostgrestFilterBuilder<T, ResultType = T[]> {
|
|
108
|
+
protected table: string;
|
|
109
|
+
protected ctx: RequestContext;
|
|
110
|
+
protected selectColumns: string;
|
|
111
|
+
protected filters: PendingFilter[];
|
|
112
|
+
protected orderClauses: string[];
|
|
113
|
+
protected limitValue?: number;
|
|
114
|
+
protected offsetValue?: number;
|
|
115
|
+
protected countMode?: CountMode;
|
|
116
|
+
protected signalValue?: AbortSignal;
|
|
117
|
+
protected customHeaders: Record<string, string>;
|
|
118
|
+
protected responseFormat: 'json' | 'csv';
|
|
119
|
+
protected explainMode?: {
|
|
120
|
+
analyze?: boolean;
|
|
121
|
+
verbose?: boolean;
|
|
122
|
+
costs?: boolean;
|
|
123
|
+
buffers?: boolean;
|
|
124
|
+
};
|
|
125
|
+
protected resultModifier?: 'single' | 'maybeSingle';
|
|
126
|
+
protected method: 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
127
|
+
protected body?: unknown;
|
|
128
|
+
constructor(ctx: RequestContext, table: string);
|
|
129
|
+
/** Equal to */
|
|
130
|
+
eq<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
131
|
+
/** Not equal to */
|
|
132
|
+
neq<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
133
|
+
/** Greater than */
|
|
134
|
+
gt<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
135
|
+
/** Greater than or equal */
|
|
136
|
+
gte<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
137
|
+
/** Less than */
|
|
138
|
+
lt<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
139
|
+
/** Less than or equal */
|
|
140
|
+
lte<K extends keyof T & string>(column: K, value: T[K]): this;
|
|
141
|
+
/** Pattern match (LIKE) */
|
|
142
|
+
like<K extends keyof T & string>(column: K, pattern: string): this;
|
|
143
|
+
/** Case-insensitive pattern match (ILIKE) */
|
|
144
|
+
ilike<K extends keyof T & string>(column: K, pattern: string): this;
|
|
145
|
+
/** Is NULL or boolean */
|
|
146
|
+
is<K extends keyof T & string>(column: K, value: null | boolean): this;
|
|
147
|
+
/** In list */
|
|
148
|
+
in<K extends keyof T & string>(column: K, values: T[K][]): this;
|
|
149
|
+
/** Array contains */
|
|
150
|
+
contains<K extends keyof T & string>(column: K, values: unknown[]): this;
|
|
151
|
+
/** Array contained by */
|
|
152
|
+
containedBy<K extends keyof T & string>(column: K, values: unknown[]): this;
|
|
153
|
+
/** Array overlaps */
|
|
154
|
+
overlaps<K extends keyof T & string>(column: K, values: unknown[]): this;
|
|
155
|
+
/** Full-text search */
|
|
156
|
+
textSearch<K extends keyof T & string>(column: K, query: string, options?: TextSearchOptions): this;
|
|
157
|
+
/** Match multiple conditions (shorthand for multiple eq) */
|
|
158
|
+
match(query: Partial<T>): this;
|
|
159
|
+
/** Negate a filter */
|
|
160
|
+
not<K extends keyof T & string>(column: K, operator: FilterOperator, value: FilterValue): this;
|
|
161
|
+
/** OR condition (raw string format) */
|
|
162
|
+
or(conditions: string, options?: {
|
|
163
|
+
foreignTable?: string;
|
|
164
|
+
}): this;
|
|
165
|
+
/** Generic filter (escape hatch) */
|
|
166
|
+
filter<K extends keyof T & string>(column: K, operator: FilterOperator, value: FilterValue): this;
|
|
167
|
+
/** Order results */
|
|
168
|
+
order<K extends keyof T & string>(column: K, options?: OrderOptions): this;
|
|
169
|
+
/** Limit results */
|
|
170
|
+
limit(count: number, options?: {
|
|
171
|
+
foreignTable?: string;
|
|
172
|
+
}): this;
|
|
173
|
+
/** Offset results (for pagination) */
|
|
174
|
+
range(from: number, to: number, options?: {
|
|
175
|
+
foreignTable?: string;
|
|
176
|
+
}): this;
|
|
177
|
+
/** Provide an AbortSignal */
|
|
178
|
+
abortSignal(signal: AbortSignal): this;
|
|
179
|
+
/** Return CSV instead of JSON */
|
|
180
|
+
csv(): PostgrestFilterBuilder<T, string>;
|
|
181
|
+
/** Return query execution plan */
|
|
182
|
+
explain(options?: {
|
|
183
|
+
analyze?: boolean;
|
|
184
|
+
verbose?: boolean;
|
|
185
|
+
costs?: boolean;
|
|
186
|
+
buffers?: boolean;
|
|
187
|
+
}): this;
|
|
188
|
+
/** Override return type */
|
|
189
|
+
returns<R>(): PostgrestFilterBuilder<R, R[]>;
|
|
190
|
+
/** Execute and return exactly one row (throws if not exactly one) */
|
|
191
|
+
single(): PostgrestFilterBuilder<T, T>;
|
|
192
|
+
/** Execute and return zero or one row */
|
|
193
|
+
maybeSingle(): PostgrestFilterBuilder<T, T | null>;
|
|
194
|
+
protected buildUrl(): string;
|
|
195
|
+
protected buildHeaders(): Record<string, string>;
|
|
196
|
+
/** Execute the query */
|
|
197
|
+
then<TResult1 = Result<ResultType>, TResult2 = never>(onfulfilled?: ((value: Result<ResultType>) => TResult1 | PromiseLike<TResult1>) | null, _onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
198
|
+
protected execute(): Promise<Result<unknown>>;
|
|
199
|
+
/** Throw on error instead of returning { data, error } */
|
|
200
|
+
throwOnError(): Promise<ResultType>;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Builder for SELECT queries with column selection.
|
|
204
|
+
*/
|
|
205
|
+
declare class PostgrestQueryBuilder<T> extends PostgrestFilterBuilder<T> {
|
|
206
|
+
/** Select specific columns */
|
|
207
|
+
select<Columns extends string = '*'>(columns?: Columns, options?: {
|
|
208
|
+
count?: CountMode;
|
|
209
|
+
}): PostgrestFilterBuilder<T>;
|
|
210
|
+
/** Insert row(s) */
|
|
211
|
+
insert(values: Partial<T> | Partial<T>[], options?: {
|
|
212
|
+
count?: CountMode;
|
|
213
|
+
}): PostgrestFilterBuilder<T>;
|
|
214
|
+
/** Upsert row(s) */
|
|
215
|
+
upsert(values: Partial<T> | Partial<T>[], options?: UpsertOptions): PostgrestFilterBuilder<T>;
|
|
216
|
+
/** Update row(s) */
|
|
217
|
+
update(values: Partial<T>, options?: {
|
|
218
|
+
count?: CountMode;
|
|
219
|
+
}): PostgrestFilterBuilder<T>;
|
|
220
|
+
/** Delete row(s) */
|
|
221
|
+
delete(options?: {
|
|
222
|
+
count?: CountMode;
|
|
223
|
+
}): PostgrestFilterBuilder<T>;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Call a database function via RPC.
|
|
228
|
+
*/
|
|
229
|
+
declare function rpc<Args extends Record<string, unknown>, Returns>(ctx: RequestContext, functionName: string, args: Args, options?: {
|
|
230
|
+
signal?: AbortSignal;
|
|
231
|
+
headers?: Record<string, string>;
|
|
232
|
+
}): Promise<Result<Returns>>;
|
|
233
|
+
/**
|
|
234
|
+
* RPC builder for type-safe function calls.
|
|
235
|
+
*/
|
|
236
|
+
declare class RpcBuilder<Args extends Record<string, unknown>, Returns> {
|
|
237
|
+
private ctx;
|
|
238
|
+
private functionName;
|
|
239
|
+
private args?;
|
|
240
|
+
private signal?;
|
|
241
|
+
private customHeaders;
|
|
242
|
+
constructor(ctx: RequestContext, functionName: string);
|
|
243
|
+
/** Set function arguments */
|
|
244
|
+
call(args: Args): this;
|
|
245
|
+
/** Provide an AbortSignal */
|
|
246
|
+
abortSignal(signal: AbortSignal): this;
|
|
247
|
+
/** Set custom headers */
|
|
248
|
+
headers(headers: Record<string, string>): this;
|
|
249
|
+
/** Execute the RPC call */
|
|
250
|
+
then<TResult1 = Result<Returns>, TResult2 = never>(onfulfilled?: ((value: Result<Returns>) => TResult1 | PromiseLike<TResult1>) | null, _onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
251
|
+
/** Throw on error */
|
|
252
|
+
throwOnError(): Promise<Returns>;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Data client for Reactor - PostgREST-style query builder.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```ts
|
|
260
|
+
* const client = new DataClient(ctx);
|
|
261
|
+
*
|
|
262
|
+
* // Select with filters
|
|
263
|
+
* const { data, error } = await client
|
|
264
|
+
* .from('posts')
|
|
265
|
+
* .select('id, title, author:users(name)')
|
|
266
|
+
* .eq('published', true)
|
|
267
|
+
* .order('created_at', { ascending: false })
|
|
268
|
+
* .limit(10);
|
|
269
|
+
*
|
|
270
|
+
* // Insert
|
|
271
|
+
* const { data } = await client
|
|
272
|
+
* .from('posts')
|
|
273
|
+
* .insert({ title: 'Hello', body: 'World' })
|
|
274
|
+
* .select()
|
|
275
|
+
* .single();
|
|
276
|
+
*
|
|
277
|
+
* // RPC
|
|
278
|
+
* const { data } = await client.rpc('search', { query: 'rust' });
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
declare class DataClient<Schema extends GenericSchema = GenericSchema> {
|
|
282
|
+
private ctx;
|
|
283
|
+
constructor(ctx: RequestContext);
|
|
284
|
+
/**
|
|
285
|
+
* Start a query on a table.
|
|
286
|
+
*
|
|
287
|
+
* @param table - The table name
|
|
288
|
+
* @returns A query builder
|
|
289
|
+
*/
|
|
290
|
+
from<TableName extends keyof Schema['Tables'] & string>(table: TableName): PostgrestQueryBuilder<Schema['Tables'][TableName]['Row']>;
|
|
291
|
+
/**
|
|
292
|
+
* Call a database function via RPC.
|
|
293
|
+
*
|
|
294
|
+
* @param functionName - The function name
|
|
295
|
+
* @param args - Function arguments
|
|
296
|
+
* @returns RPC builder
|
|
297
|
+
*/
|
|
298
|
+
rpc<FunctionName extends keyof Schema['Functions'] & string, Args extends Schema['Functions'][FunctionName]['Args'], Returns = Schema['Functions'][FunctionName]['Returns']>(functionName: FunctionName, args?: Args): RpcBuilder<Args, Returns>;
|
|
299
|
+
/**
|
|
300
|
+
* Access a schema (for multi-schema support).
|
|
301
|
+
* Currently returns self as we only support public schema.
|
|
302
|
+
*/
|
|
303
|
+
schema(_name: string): DataClient<Schema>;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Create a data client with typed schema.
|
|
307
|
+
*/
|
|
308
|
+
declare function createDataClient<Schema extends GenericSchema = GenericSchema>(ctx: RequestContext): DataClient<Schema>;
|
|
309
|
+
|
|
310
|
+
export { type CountMode, DataClient, type FilterOperator, type FilterValue, type GenericSchema, type OrderOptions, type PendingFilter, PostgrestFilterBuilder, PostgrestQueryBuilder, type QueryOptions, type QueryResult, type ResponseFormat, type ResultModifier, RpcBuilder, type SelectResult, type TextSearchOptions, type UpsertOptions, createDataClient, rpc };
|