@xylex-group/athena 0.2.1 → 1.0.4
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 +294 -103
- package/bin/athena-js.js +1 -1
- package/dist/index.d.mts +51 -25
- package/dist/index.d.ts +51 -25
- package/dist/index.js +193 -79
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +192 -80
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +21 -32
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +21 -32
- package/dist/react.mjs.map +1 -1
- package/dist/{types-DzCf3v76.d.mts → types-D0uYdUea.d.mts} +30 -7
- package/dist/{types-DzCf3v76.d.ts → types-D0uYdUea.d.ts} +30 -7
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -1,103 +1,294 @@
|
|
|
1
|
-
# athena-js
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.
|
|
40
|
-
|
|
41
|
-
.
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
1
|
+
# athena-js
|
|
2
|
+
|
|
3
|
+
`@xylex-group/athena` is a database driver and API gateway SDK that lets you interact with SQL backends over HTTP through a fluent builder API. It ships a typed query builder for Node.js / server environments and a React hook for client-side use.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @xylex-group/athena
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @xylex-group/athena
|
|
11
|
+
# or
|
|
12
|
+
yarn add @xylex-group/athena
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
React peer dependency is optional — only needed if you use `useAthenaGateway`.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install react # React >=17 required for the hook
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { createClient } from "@xylex-group/athena";
|
|
25
|
+
|
|
26
|
+
const athena = createClient(
|
|
27
|
+
"https://athena-db.com",
|
|
28
|
+
process.env.ATHENA_API_KEY,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const { data, error } = await athena.from("characters").select(`
|
|
32
|
+
id,
|
|
33
|
+
name,
|
|
34
|
+
from:sender_id(name),
|
|
35
|
+
to:receiver_id(name)
|
|
36
|
+
`);
|
|
37
|
+
|
|
38
|
+
if (error) {
|
|
39
|
+
console.error("gateway error", error);
|
|
40
|
+
} else {
|
|
41
|
+
console.table(data);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Every query resolves to `{ data, error, status, raw }`. `data` is `null` on error; `error` is `null` on success.
|
|
46
|
+
|
|
47
|
+
## Query builder
|
|
48
|
+
|
|
49
|
+
### Reading rows
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// select all columns
|
|
53
|
+
const { data } = await athena.from("users").select();
|
|
54
|
+
|
|
55
|
+
// select specific columns
|
|
56
|
+
const { data } = await athena.from("users").select("id, name, email");
|
|
57
|
+
|
|
58
|
+
// select with type annotation
|
|
59
|
+
const { data } = await athena.from<User>("users").select("id, name");
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Filters
|
|
63
|
+
|
|
64
|
+
Filters accumulate on the builder and are sent together when the query executes.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
const { data } = await athena
|
|
68
|
+
.from("characters")
|
|
69
|
+
.select("id, name")
|
|
70
|
+
.eq("active", true) // column = value
|
|
71
|
+
.neq("role", "guest") // column != value
|
|
72
|
+
.gt("level", 5) // column > value
|
|
73
|
+
.gte("score", 100) // column >= value
|
|
74
|
+
.lt("age", 30) // column < value
|
|
75
|
+
.lte("created_at", "2024-01-01") // column <= value
|
|
76
|
+
.like("name", "Ali%") // SQL LIKE (case-sensitive)
|
|
77
|
+
.ilike("email", "%@example%") // SQL ILIKE (case-insensitive)
|
|
78
|
+
.is("deleted_at", null) // IS NULL / IS TRUE etc.
|
|
79
|
+
.in("status", ["active", "pending"]) // IN (…)
|
|
80
|
+
.contains("tags", ["hero"]) // array contains value
|
|
81
|
+
.containedBy("tags", ["hero", "villain"]) // array is subset of value
|
|
82
|
+
.match({ role: "admin", active: true }) // multiple eq filters at once
|
|
83
|
+
.not("role", "eq", "banned") // NOT col op val
|
|
84
|
+
.or("status.eq.active,status.eq.pending"); // OR expression
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Pagination
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// explicit limit and offset
|
|
91
|
+
const { data } = await athena.from("users").select().limit(25).offset(50);
|
|
92
|
+
|
|
93
|
+
// range shorthand — equivalent to offset(from).limit(to - from + 1)
|
|
94
|
+
const { data } = await athena.from("users").select().range(0, 24);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Single row
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
// returns the first row or null instead of an array
|
|
101
|
+
const { data: user } = await athena
|
|
102
|
+
.from("users")
|
|
103
|
+
.select("id, name")
|
|
104
|
+
.eq("id", 42)
|
|
105
|
+
.single();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`maybeSingle` behaves identically — both return the first element of the result set.
|
|
109
|
+
|
|
110
|
+
### Options
|
|
111
|
+
|
|
112
|
+
Pass options as the second argument to `.select()`:
|
|
113
|
+
|
|
114
|
+
| Option | Type | Description |
|
|
115
|
+
|--------|------|-------------|
|
|
116
|
+
| `count` | `"exact" \| "planned" \| "estimated"` | request a row count alongside the data |
|
|
117
|
+
| `head` | `boolean` | return response headers only (no rows) |
|
|
118
|
+
| `stripNulls` | `boolean` | strip null values from rows (default `true`) |
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
const { data } = await athena
|
|
122
|
+
.from("orders")
|
|
123
|
+
.select("id", { count: "exact", stripNulls: false });
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Mutations
|
|
127
|
+
|
|
128
|
+
Insert, update, upsert, and delete all return a `MutationQuery` that you can await directly or chain further calls onto before the request fires.
|
|
129
|
+
|
|
130
|
+
### Insert
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const { data: inserted } = await athena
|
|
134
|
+
.from("countries")
|
|
135
|
+
.insert({ name: "Mordor" })
|
|
136
|
+
.select("id, name");
|
|
137
|
+
|
|
138
|
+
// insert multiple rows
|
|
139
|
+
const { data } = await athena
|
|
140
|
+
.from("characters")
|
|
141
|
+
.insert([{ name: "Frodo" }, { name: "Sam" }])
|
|
142
|
+
.select();
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Update
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
const { data: updated } = await athena
|
|
149
|
+
.from("countries")
|
|
150
|
+
.update({ name: "Gondor" })
|
|
151
|
+
.eq("id", 1)
|
|
152
|
+
.select();
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Filters (`.eq()`, `.match()`, etc.) applied before `.update()` are used as `WHERE` conditions.
|
|
156
|
+
|
|
157
|
+
### Upsert
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
const { data } = await athena
|
|
161
|
+
.from("countries")
|
|
162
|
+
.upsert(
|
|
163
|
+
{ id: 2, name: "Rohan" },
|
|
164
|
+
{ updateBody: { name: "Rohan" }, onConflict: "id" },
|
|
165
|
+
)
|
|
166
|
+
.select();
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
| Option | Type | Description |
|
|
170
|
+
|--------|------|-------------|
|
|
171
|
+
| `onConflict` | `string \| string[]` | column(s) that determine a conflict |
|
|
172
|
+
| `updateBody` | `object` | fields to apply when a conflict occurs |
|
|
173
|
+
| `defaultToNull` | `boolean` | write explicit `null` for missing fields |
|
|
174
|
+
| `count` | `"exact" \| "planned" \| "estimated"` | request a row count |
|
|
175
|
+
| `head` | `boolean` | return headers only |
|
|
176
|
+
|
|
177
|
+
### Delete
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
// delete by id filter
|
|
181
|
+
await athena.from("countries").eq("id", 1).delete();
|
|
182
|
+
|
|
183
|
+
// delete with explicit resourceId option
|
|
184
|
+
await athena.from("countries").delete({ resourceId: "abc-123" });
|
|
185
|
+
|
|
186
|
+
// chain .select() to get the deleted row back
|
|
187
|
+
const { data: deleted } = await athena
|
|
188
|
+
.from("countries")
|
|
189
|
+
.eq("resource_id", "abc-123")
|
|
190
|
+
.delete()
|
|
191
|
+
.select("id, name");
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Delete requires either `.eq("resource_id", …)`, `.eq("id", …)`, or `options.resourceId` — calling `.delete()` without any of these throws an error.
|
|
195
|
+
|
|
196
|
+
### MutationQuery chaining
|
|
197
|
+
|
|
198
|
+
All mutation methods return a `MutationQuery` which supports:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
const mutation = athena.from("users").insert({ name: "Alice" });
|
|
202
|
+
|
|
203
|
+
await mutation.select("id, name"); // fire request, return rows
|
|
204
|
+
await mutation.returning("id"); // alias for .select()
|
|
205
|
+
await mutation.single("id"); // return first row or null
|
|
206
|
+
await mutation.maybeSingle("id"); // same as .single()
|
|
207
|
+
await mutation; // fire request, return default columns
|
|
208
|
+
mutation.then(({ data }) => …); // thenable
|
|
209
|
+
mutation.catch(err => …);
|
|
210
|
+
mutation.finally(() => …);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The request fires only once regardless of how many times you call `.then()` or await the object.
|
|
214
|
+
|
|
215
|
+
## React hook
|
|
216
|
+
|
|
217
|
+
```tsx
|
|
218
|
+
"use client";
|
|
219
|
+
|
|
220
|
+
import { useAthenaGateway } from "@xylex-group/athena/react";
|
|
221
|
+
import { useEffect } from "react";
|
|
222
|
+
|
|
223
|
+
export function UsersPanel() {
|
|
224
|
+
const { fetchGateway, lastResponse, isLoading, error } = useAthenaGateway({
|
|
225
|
+
baseUrl: "https://athena-db.com",
|
|
226
|
+
apiKey: process.env.NEXT_PUBLIC_ATHENA_API_KEY,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
useEffect(() => {
|
|
230
|
+
fetchGateway({
|
|
231
|
+
table_name: "users",
|
|
232
|
+
columns: ["id", "email"],
|
|
233
|
+
limit: 25,
|
|
234
|
+
});
|
|
235
|
+
}, [fetchGateway]);
|
|
236
|
+
|
|
237
|
+
if (error) return <div>Error: {error}</div>;
|
|
238
|
+
if (isLoading) return <div>Loading…</div>;
|
|
239
|
+
|
|
240
|
+
return <pre>{JSON.stringify(lastResponse?.data, null, 2)}</pre>;
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The hook returns `fetchGateway`, `insertGateway`, `updateGateway`, `deleteGateway`, `isLoading`, `error`, `lastRequest`, `lastResponse`, and `baseUrl`.
|
|
245
|
+
|
|
246
|
+
Hook config options mirror the client options: `baseUrl`, `apiKey`, `headers`, `userId`, `organizationId`, `publishEvent`.
|
|
247
|
+
|
|
248
|
+
## User context headers
|
|
249
|
+
|
|
250
|
+
Pass user and tenant context to every request without repeating it on each call:
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
const athena = createClient("https://athena-db.com", process.env.ATHENA_API_KEY, {
|
|
254
|
+
headers: {
|
|
255
|
+
"X-User-Id": currentUser.id,
|
|
256
|
+
"X-Organization-Id": currentUser.organizationId ?? "",
|
|
257
|
+
},
|
|
258
|
+
});
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Or pass per-call via options. The Athena server interprets `url` and `key` based on the backend type (Supabase, PostgREST, etc.).
|
|
262
|
+
|
|
263
|
+
## Custom headers
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
const athena = createClient("https://athena-db.com", process.env.ATHENA_API_KEY, {
|
|
267
|
+
headers: {
|
|
268
|
+
"X-Custom-Header": "value",
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Per-call headers are merged with the client-level headers, with per-call values winning on conflict.
|
|
274
|
+
|
|
275
|
+
## TypeScript
|
|
276
|
+
|
|
277
|
+
The package is written in TypeScript and ships declaration files. Pass a row type to `.from()` for fully-typed builder methods and results:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
interface User {
|
|
281
|
+
id: number;
|
|
282
|
+
name: string;
|
|
283
|
+
email: string;
|
|
284
|
+
active: boolean;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const { data } = await athena.from<User>("users").select("id, name").eq("active", true);
|
|
288
|
+
// data is User[] | null
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## Learn more
|
|
292
|
+
|
|
293
|
+
- [Getting started](docs/getting-started.md) — step-by-step walkthrough
|
|
294
|
+
- [API reference](docs/api-reference.md) — complete method and type reference
|
package/bin/athena-js.js
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { B as BackendConfig, a as BackendType, A as AthenaConditionValue, b as AthenaConditionArrayValue, c as AthenaConditionOperator, d as AthenaGatewayCallOptions } from './types-D0uYdUea.mjs';
|
|
2
|
+
export { e as Backend } from './types-D0uYdUea.mjs';
|
|
3
3
|
|
|
4
4
|
interface SupabaseResult<T> {
|
|
5
5
|
data: T | null;
|
|
@@ -17,35 +17,46 @@ interface MutationQuery<Result> extends PromiseLike<SupabaseResult<Result>> {
|
|
|
17
17
|
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | undefined | null): Promise<SupabaseResult<Result> | TResult>;
|
|
18
18
|
finally(onfinally?: (() => void) | undefined | null): Promise<SupabaseResult<Result>>;
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
/** Shared filter chain - supports eq, limit, etc. in any order relative to select/update */
|
|
21
|
+
interface FilterChain<Self> {
|
|
22
|
+
eq(column: string, value: AthenaConditionValue): Self;
|
|
23
|
+
match(filters: Record<string, AthenaConditionValue>): Self;
|
|
24
|
+
range(from: number, to: number): Self;
|
|
25
|
+
limit(count: number): Self;
|
|
26
|
+
offset(count: number): Self;
|
|
27
|
+
gt(column: string, value: AthenaConditionValue): Self;
|
|
28
|
+
gte(column: string, value: AthenaConditionValue): Self;
|
|
29
|
+
lt(column: string, value: AthenaConditionValue): Self;
|
|
30
|
+
lte(column: string, value: AthenaConditionValue): Self;
|
|
31
|
+
neq(column: string, value: AthenaConditionValue): Self;
|
|
32
|
+
like(column: string, value: AthenaConditionValue): Self;
|
|
33
|
+
ilike(column: string, value: AthenaConditionValue): Self;
|
|
34
|
+
is(column: string, value: AthenaConditionValue): Self;
|
|
35
|
+
in(column: string, values: AthenaConditionArrayValue): Self;
|
|
36
|
+
contains(column: string, values: AthenaConditionArrayValue): Self;
|
|
37
|
+
containedBy(column: string, values: AthenaConditionArrayValue): Self;
|
|
38
|
+
not(columnOrExpression: string, operator?: AthenaConditionOperator, value?: AthenaConditionValue): Self;
|
|
39
|
+
or(expression: string): Self;
|
|
40
|
+
}
|
|
41
|
+
/** Chain returned by select() - supports filters and single/maybeSingle before execution */
|
|
42
|
+
interface SelectChain<Row> extends FilterChain<SelectChain<Row>>, PromiseLike<SupabaseResult<Row[]>> {
|
|
43
|
+
single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
|
|
44
|
+
maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
|
|
45
|
+
}
|
|
46
|
+
/** Chain returned by update() - supports filters before execution, plus select/returning */
|
|
47
|
+
interface UpdateChain<Row> extends FilterChain<UpdateChain<Row>>, MutationQuery<Row[]> {
|
|
48
|
+
}
|
|
49
|
+
interface TableQueryBuilder<Row> extends FilterChain<TableQueryBuilder<Row>> {
|
|
50
|
+
select<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): SelectChain<T>;
|
|
22
51
|
insert(values: Row | Row[], options?: AthenaGatewayCallOptions): MutationQuery<Row | Row[]>;
|
|
23
52
|
upsert(values: Row | Row[], options?: AthenaGatewayCallOptions & {
|
|
24
53
|
updateBody?: Partial<Row>;
|
|
25
54
|
onConflict?: string | string[];
|
|
26
55
|
}): MutationQuery<Row | Row[]>;
|
|
27
|
-
update(values: Partial<Row>, options?: AthenaGatewayCallOptions):
|
|
56
|
+
update(values: Partial<Row>, options?: AthenaGatewayCallOptions): UpdateChain<Row>;
|
|
28
57
|
delete(options?: AthenaGatewayCallOptions & {
|
|
29
58
|
resourceId?: string;
|
|
30
59
|
}): MutationQuery<Row | null>;
|
|
31
|
-
eq(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
32
|
-
match(filters: Record<string, AthenaConditionValue>): TableQueryBuilder<Row>;
|
|
33
|
-
range(from: number, to: number): TableQueryBuilder<Row>;
|
|
34
|
-
limit(count: number): TableQueryBuilder<Row>;
|
|
35
|
-
offset(count: number): TableQueryBuilder<Row>;
|
|
36
|
-
gt(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
37
|
-
gte(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
38
|
-
lt(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
39
|
-
lte(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
40
|
-
neq(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
41
|
-
like(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
42
|
-
ilike(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
43
|
-
is(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
44
|
-
in(column: string, values: AthenaConditionArrayValue): TableQueryBuilder<Row>;
|
|
45
|
-
contains(column: string, values: AthenaConditionArrayValue): TableQueryBuilder<Row>;
|
|
46
|
-
containedBy(column: string, values: AthenaConditionArrayValue): TableQueryBuilder<Row>;
|
|
47
|
-
not(columnOrExpression: string, operator?: AthenaConditionOperator, value?: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
48
|
-
or(expression: string): TableQueryBuilder<Row>;
|
|
49
60
|
single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
|
|
50
61
|
maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
|
|
51
62
|
reset(): TableQueryBuilder<Row>;
|
|
@@ -53,6 +64,21 @@ interface TableQueryBuilder<Row> {
|
|
|
53
64
|
interface SupabaseClient {
|
|
54
65
|
from<Row = unknown>(table: string): TableQueryBuilder<Row>;
|
|
55
66
|
}
|
|
56
|
-
|
|
67
|
+
interface AthenaClientBuilder {
|
|
68
|
+
url(url: string): AthenaClientBuilder;
|
|
69
|
+
key(apiKey: string): AthenaClientBuilder;
|
|
70
|
+
backend(backend: BackendConfig | BackendType): AthenaClientBuilder;
|
|
71
|
+
client(clientName: string): AthenaClientBuilder;
|
|
72
|
+
headers(headers: Record<string, string>): AthenaClientBuilder;
|
|
73
|
+
healthTracking(enabled: boolean): AthenaClientBuilder;
|
|
74
|
+
build(): SupabaseClient;
|
|
75
|
+
}
|
|
76
|
+
declare const AthenaClient: {
|
|
77
|
+
builder(): AthenaClientBuilder;
|
|
78
|
+
/** Build client from env: ATHENA_SUPABASE_URL, ATHENA_SUPABASE_KEY (or SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY) */
|
|
79
|
+
fromSupabaseEnv(): SupabaseClient;
|
|
80
|
+
};
|
|
81
|
+
/** Create client (convenience wrapper; use AthenaClient.builder() for full control) */
|
|
82
|
+
declare function createClient(url: string, apiKey: string, options?: Pick<AthenaGatewayCallOptions, 'client' | 'headers' | 'backend'>): SupabaseClient;
|
|
57
83
|
|
|
58
|
-
export { AthenaGatewayCallOptions, type SupabaseClient, type SupabaseResult, type TableQueryBuilder, createClient };
|
|
84
|
+
export { AthenaClient, AthenaGatewayCallOptions, BackendConfig, BackendType, type SupabaseClient, type SupabaseResult, type TableQueryBuilder, createClient };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { B as BackendConfig, a as BackendType, A as AthenaConditionValue, b as AthenaConditionArrayValue, c as AthenaConditionOperator, d as AthenaGatewayCallOptions } from './types-D0uYdUea.js';
|
|
2
|
+
export { e as Backend } from './types-D0uYdUea.js';
|
|
3
3
|
|
|
4
4
|
interface SupabaseResult<T> {
|
|
5
5
|
data: T | null;
|
|
@@ -17,35 +17,46 @@ interface MutationQuery<Result> extends PromiseLike<SupabaseResult<Result>> {
|
|
|
17
17
|
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | undefined | null): Promise<SupabaseResult<Result> | TResult>;
|
|
18
18
|
finally(onfinally?: (() => void) | undefined | null): Promise<SupabaseResult<Result>>;
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
/** Shared filter chain - supports eq, limit, etc. in any order relative to select/update */
|
|
21
|
+
interface FilterChain<Self> {
|
|
22
|
+
eq(column: string, value: AthenaConditionValue): Self;
|
|
23
|
+
match(filters: Record<string, AthenaConditionValue>): Self;
|
|
24
|
+
range(from: number, to: number): Self;
|
|
25
|
+
limit(count: number): Self;
|
|
26
|
+
offset(count: number): Self;
|
|
27
|
+
gt(column: string, value: AthenaConditionValue): Self;
|
|
28
|
+
gte(column: string, value: AthenaConditionValue): Self;
|
|
29
|
+
lt(column: string, value: AthenaConditionValue): Self;
|
|
30
|
+
lte(column: string, value: AthenaConditionValue): Self;
|
|
31
|
+
neq(column: string, value: AthenaConditionValue): Self;
|
|
32
|
+
like(column: string, value: AthenaConditionValue): Self;
|
|
33
|
+
ilike(column: string, value: AthenaConditionValue): Self;
|
|
34
|
+
is(column: string, value: AthenaConditionValue): Self;
|
|
35
|
+
in(column: string, values: AthenaConditionArrayValue): Self;
|
|
36
|
+
contains(column: string, values: AthenaConditionArrayValue): Self;
|
|
37
|
+
containedBy(column: string, values: AthenaConditionArrayValue): Self;
|
|
38
|
+
not(columnOrExpression: string, operator?: AthenaConditionOperator, value?: AthenaConditionValue): Self;
|
|
39
|
+
or(expression: string): Self;
|
|
40
|
+
}
|
|
41
|
+
/** Chain returned by select() - supports filters and single/maybeSingle before execution */
|
|
42
|
+
interface SelectChain<Row> extends FilterChain<SelectChain<Row>>, PromiseLike<SupabaseResult<Row[]>> {
|
|
43
|
+
single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
|
|
44
|
+
maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
|
|
45
|
+
}
|
|
46
|
+
/** Chain returned by update() - supports filters before execution, plus select/returning */
|
|
47
|
+
interface UpdateChain<Row> extends FilterChain<UpdateChain<Row>>, MutationQuery<Row[]> {
|
|
48
|
+
}
|
|
49
|
+
interface TableQueryBuilder<Row> extends FilterChain<TableQueryBuilder<Row>> {
|
|
50
|
+
select<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): SelectChain<T>;
|
|
22
51
|
insert(values: Row | Row[], options?: AthenaGatewayCallOptions): MutationQuery<Row | Row[]>;
|
|
23
52
|
upsert(values: Row | Row[], options?: AthenaGatewayCallOptions & {
|
|
24
53
|
updateBody?: Partial<Row>;
|
|
25
54
|
onConflict?: string | string[];
|
|
26
55
|
}): MutationQuery<Row | Row[]>;
|
|
27
|
-
update(values: Partial<Row>, options?: AthenaGatewayCallOptions):
|
|
56
|
+
update(values: Partial<Row>, options?: AthenaGatewayCallOptions): UpdateChain<Row>;
|
|
28
57
|
delete(options?: AthenaGatewayCallOptions & {
|
|
29
58
|
resourceId?: string;
|
|
30
59
|
}): MutationQuery<Row | null>;
|
|
31
|
-
eq(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
32
|
-
match(filters: Record<string, AthenaConditionValue>): TableQueryBuilder<Row>;
|
|
33
|
-
range(from: number, to: number): TableQueryBuilder<Row>;
|
|
34
|
-
limit(count: number): TableQueryBuilder<Row>;
|
|
35
|
-
offset(count: number): TableQueryBuilder<Row>;
|
|
36
|
-
gt(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
37
|
-
gte(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
38
|
-
lt(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
39
|
-
lte(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
40
|
-
neq(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
41
|
-
like(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
42
|
-
ilike(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
43
|
-
is(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
44
|
-
in(column: string, values: AthenaConditionArrayValue): TableQueryBuilder<Row>;
|
|
45
|
-
contains(column: string, values: AthenaConditionArrayValue): TableQueryBuilder<Row>;
|
|
46
|
-
containedBy(column: string, values: AthenaConditionArrayValue): TableQueryBuilder<Row>;
|
|
47
|
-
not(columnOrExpression: string, operator?: AthenaConditionOperator, value?: AthenaConditionValue): TableQueryBuilder<Row>;
|
|
48
|
-
or(expression: string): TableQueryBuilder<Row>;
|
|
49
60
|
single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
|
|
50
61
|
maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
|
|
51
62
|
reset(): TableQueryBuilder<Row>;
|
|
@@ -53,6 +64,21 @@ interface TableQueryBuilder<Row> {
|
|
|
53
64
|
interface SupabaseClient {
|
|
54
65
|
from<Row = unknown>(table: string): TableQueryBuilder<Row>;
|
|
55
66
|
}
|
|
56
|
-
|
|
67
|
+
interface AthenaClientBuilder {
|
|
68
|
+
url(url: string): AthenaClientBuilder;
|
|
69
|
+
key(apiKey: string): AthenaClientBuilder;
|
|
70
|
+
backend(backend: BackendConfig | BackendType): AthenaClientBuilder;
|
|
71
|
+
client(clientName: string): AthenaClientBuilder;
|
|
72
|
+
headers(headers: Record<string, string>): AthenaClientBuilder;
|
|
73
|
+
healthTracking(enabled: boolean): AthenaClientBuilder;
|
|
74
|
+
build(): SupabaseClient;
|
|
75
|
+
}
|
|
76
|
+
declare const AthenaClient: {
|
|
77
|
+
builder(): AthenaClientBuilder;
|
|
78
|
+
/** Build client from env: ATHENA_SUPABASE_URL, ATHENA_SUPABASE_KEY (or SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY) */
|
|
79
|
+
fromSupabaseEnv(): SupabaseClient;
|
|
80
|
+
};
|
|
81
|
+
/** Create client (convenience wrapper; use AthenaClient.builder() for full control) */
|
|
82
|
+
declare function createClient(url: string, apiKey: string, options?: Pick<AthenaGatewayCallOptions, 'client' | 'headers' | 'backend'>): SupabaseClient;
|
|
57
83
|
|
|
58
|
-
export { AthenaGatewayCallOptions, type SupabaseClient, type SupabaseResult, type TableQueryBuilder, createClient };
|
|
84
|
+
export { AthenaClient, AthenaGatewayCallOptions, BackendConfig, BackendType, type SupabaseClient, type SupabaseResult, type TableQueryBuilder, createClient };
|