@xylex-group/athena 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -4
- package/dist/{errors-DHmpYG46.d.cts → errors-CB-eJQ7x.d.cts} +10 -0
- package/dist/{errors-DHmpYG46.d.ts → errors-CB-eJQ7x.d.ts} +10 -0
- package/dist/index.cjs +41 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +41 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +6 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +6 -1
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# athena-js
|
|
2
2
|
|
|
3
|
-
current version: `1.
|
|
3
|
+
current version: `1.4.0`
|
|
4
4
|
`@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.
|
|
5
5
|
|
|
6
6
|
## Install
|
|
@@ -183,14 +183,73 @@ const { data } = await athena
|
|
|
183
183
|
|
|
184
184
|
### Pagination
|
|
185
185
|
|
|
186
|
+
Two styles, pick whichever matches your UI / backend. Both live on the shared `FilterChain`, so they work before or after `.select()`.
|
|
187
|
+
|
|
186
188
|
```ts
|
|
187
|
-
//
|
|
189
|
+
// 1. offset / limit — contiguous windows
|
|
188
190
|
const { data } = await athena.from("users").select().limit(25).offset(50);
|
|
189
191
|
|
|
190
|
-
// range shorthand
|
|
191
|
-
const { data } = await athena.from("users").select().range(0, 24);
|
|
192
|
+
// range shorthand: offset = from, limit = to - from + 1
|
|
193
|
+
const { data: firstTwentyFive } = await athena.from("users").select().range(0, 24);
|
|
194
|
+
|
|
195
|
+
// 2. page based — maps to current_page / page_size / total_pages
|
|
196
|
+
const { data: page2 } = await athena
|
|
197
|
+
.from("orders")
|
|
198
|
+
.select("id, total")
|
|
199
|
+
.currentPage(2)
|
|
200
|
+
.pageSize(25);
|
|
201
|
+
|
|
202
|
+
// .totalPages() is an optional hint some backends use in the response envelope
|
|
203
|
+
const { data: hinted } = await athena
|
|
204
|
+
.from("orders")
|
|
205
|
+
.select("id, total")
|
|
206
|
+
.currentPage(1)
|
|
207
|
+
.pageSize(25)
|
|
208
|
+
.totalPages(10);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
| Method | Body field |
|
|
212
|
+
|--------|------------|
|
|
213
|
+
| `.limit(n)` | `limit` |
|
|
214
|
+
| `.offset(n)` | `offset` |
|
|
215
|
+
| `.range(from, to)` | `offset` + `limit` |
|
|
216
|
+
| `.currentPage(n)` | `current_page` |
|
|
217
|
+
| `.pageSize(n)` | `page_size` |
|
|
218
|
+
| `.totalPages(n)` | `total_pages` |
|
|
219
|
+
|
|
220
|
+
### Ordering
|
|
221
|
+
|
|
222
|
+
`.order(column, { ascending? })` is available on the table builder, select chain, update chain, and delete — before or after the operation terminator. It serializes to `sort_by: { field, direction }` on the gateway payload and defaults to ascending.
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
// descending + limit
|
|
226
|
+
// SELECT * FROM rsf_messages WHERE room_id = $1 ORDER BY created_at DESC LIMIT 100
|
|
227
|
+
const { data } = await athena
|
|
228
|
+
.from("rsf_messages")
|
|
229
|
+
.eq("room_id", roomId)
|
|
230
|
+
.select("*", { stripNulls: false })
|
|
231
|
+
.order("created_at", { ascending: false })
|
|
232
|
+
.limit(100);
|
|
233
|
+
|
|
234
|
+
// ascending (default) + page-based pagination
|
|
235
|
+
const { data: page } = await athena
|
|
236
|
+
.from("orders")
|
|
237
|
+
.select("id, total, created_at")
|
|
238
|
+
.order("created_at")
|
|
239
|
+
.currentPage(1)
|
|
240
|
+
.pageSize(25);
|
|
241
|
+
|
|
242
|
+
// combine with .single() to grab the newest / oldest row
|
|
243
|
+
const { data: latest } = await athena
|
|
244
|
+
.from("messages")
|
|
245
|
+
.eq("room_id", roomId)
|
|
246
|
+
.select("*")
|
|
247
|
+
.order("created_at", { ascending: false })
|
|
248
|
+
.single();
|
|
192
249
|
```
|
|
193
250
|
|
|
251
|
+
Only the last `.order()` wins — the SDK does not support multi-column ordering on the table builder. Use `.rpc()` or `.query()` for that.
|
|
252
|
+
|
|
194
253
|
### Single row
|
|
195
254
|
|
|
196
255
|
```ts
|
|
@@ -417,6 +476,10 @@ const athena = createClient(
|
|
|
417
476
|
|
|
418
477
|
Per-call headers are merged with the client-level headers, with per-call values winning on conflict.
|
|
419
478
|
|
|
479
|
+
The SDK also sends a standard identification header on every request:
|
|
480
|
+
|
|
481
|
+
- `X-Athena-Sdk: xylex-group/athena <version>`
|
|
482
|
+
|
|
420
483
|
## TypeScript
|
|
421
484
|
|
|
422
485
|
The package is written in TypeScript and ships declaration files. Pass a row type to `.from()` for fully-typed builder methods and results:
|
|
@@ -17,6 +17,11 @@ interface AthenaGatewayCondition {
|
|
|
17
17
|
eq_column?: string;
|
|
18
18
|
eq_value?: AthenaConditionValue | AthenaConditionArrayValue | string;
|
|
19
19
|
}
|
|
20
|
+
type AthenaSortDirection = 'ascending' | 'descending';
|
|
21
|
+
interface AthenaSortBy {
|
|
22
|
+
field: string;
|
|
23
|
+
direction: AthenaSortDirection;
|
|
24
|
+
}
|
|
20
25
|
interface AthenaFetchPayload {
|
|
21
26
|
view_name?: string;
|
|
22
27
|
table_name?: string;
|
|
@@ -33,6 +38,7 @@ interface AthenaFetchPayload {
|
|
|
33
38
|
aggregation_column?: string;
|
|
34
39
|
aggregation_strategy?: 'cumulative_sum';
|
|
35
40
|
aggregation_dedup?: boolean;
|
|
41
|
+
sort_by?: AthenaSortBy;
|
|
36
42
|
}
|
|
37
43
|
interface AthenaInsertPayload {
|
|
38
44
|
table_name: string;
|
|
@@ -49,6 +55,10 @@ interface AthenaDeletePayload {
|
|
|
49
55
|
resource_id?: string;
|
|
50
56
|
columns?: string[] | string;
|
|
51
57
|
conditions?: AthenaGatewayCondition[];
|
|
58
|
+
sort_by?: AthenaSortBy;
|
|
59
|
+
current_page?: number;
|
|
60
|
+
page_size?: number;
|
|
61
|
+
total_pages?: number;
|
|
52
62
|
}
|
|
53
63
|
interface AthenaUpdatePayload extends AthenaFetchPayload {
|
|
54
64
|
set?: Record<string, unknown>;
|
|
@@ -17,6 +17,11 @@ interface AthenaGatewayCondition {
|
|
|
17
17
|
eq_column?: string;
|
|
18
18
|
eq_value?: AthenaConditionValue | AthenaConditionArrayValue | string;
|
|
19
19
|
}
|
|
20
|
+
type AthenaSortDirection = 'ascending' | 'descending';
|
|
21
|
+
interface AthenaSortBy {
|
|
22
|
+
field: string;
|
|
23
|
+
direction: AthenaSortDirection;
|
|
24
|
+
}
|
|
20
25
|
interface AthenaFetchPayload {
|
|
21
26
|
view_name?: string;
|
|
22
27
|
table_name?: string;
|
|
@@ -33,6 +38,7 @@ interface AthenaFetchPayload {
|
|
|
33
38
|
aggregation_column?: string;
|
|
34
39
|
aggregation_strategy?: 'cumulative_sum';
|
|
35
40
|
aggregation_dedup?: boolean;
|
|
41
|
+
sort_by?: AthenaSortBy;
|
|
36
42
|
}
|
|
37
43
|
interface AthenaInsertPayload {
|
|
38
44
|
table_name: string;
|
|
@@ -49,6 +55,10 @@ interface AthenaDeletePayload {
|
|
|
49
55
|
resource_id?: string;
|
|
50
56
|
columns?: string[] | string;
|
|
51
57
|
conditions?: AthenaGatewayCondition[];
|
|
58
|
+
sort_by?: AthenaSortBy;
|
|
59
|
+
current_page?: number;
|
|
60
|
+
page_size?: number;
|
|
61
|
+
total_pages?: number;
|
|
52
62
|
}
|
|
53
63
|
interface AthenaUpdatePayload extends AthenaFetchPayload {
|
|
54
64
|
set?: Record<string, unknown>;
|
package/dist/index.cjs
CHANGED
|
@@ -63,6 +63,10 @@ function isAthenaGatewayError(error) {
|
|
|
63
63
|
// src/gateway/client.ts
|
|
64
64
|
var DEFAULT_BASE_URL = "https://athena-db.com";
|
|
65
65
|
var DEFAULT_CLIENT = "railway_direct";
|
|
66
|
+
var FALLBACK_SDK_VERSION = "1.3.0";
|
|
67
|
+
var SDK_NAME = "xylex-group/athena";
|
|
68
|
+
var SDK_VERSION = typeof process !== "undefined" && process?.env?.npm_package_version ? process.env.npm_package_version : FALLBACK_SDK_VERSION;
|
|
69
|
+
var SDK_HEADER_VALUE = `${SDK_NAME} ${SDK_VERSION}`;
|
|
66
70
|
function parseResponseBody(rawText, contentType) {
|
|
67
71
|
if (!rawText) {
|
|
68
72
|
return { parsed: null, parseFailed: false };
|
|
@@ -201,7 +205,8 @@ function buildHeaders(config, options) {
|
|
|
201
205
|
const finalApiKey = options?.apiKey ?? config.apiKey;
|
|
202
206
|
const finalPublishEvent = options?.publishEvent ?? config.publishEvent;
|
|
203
207
|
const headers = {
|
|
204
|
-
"Content-Type": "application/json"
|
|
208
|
+
"Content-Type": "application/json",
|
|
209
|
+
"X-Athena-Sdk": SDK_HEADER_VALUE
|
|
205
210
|
};
|
|
206
211
|
if (options?.userId ?? config.userId) {
|
|
207
212
|
headers["X-User-Id"] = options?.userId ?? config.userId ?? "";
|
|
@@ -466,6 +471,25 @@ function createFilterMethods(state, addCondition, self) {
|
|
|
466
471
|
state.offset = count;
|
|
467
472
|
return self;
|
|
468
473
|
},
|
|
474
|
+
currentPage(value) {
|
|
475
|
+
state.currentPage = value;
|
|
476
|
+
return self;
|
|
477
|
+
},
|
|
478
|
+
pageSize(value) {
|
|
479
|
+
state.pageSize = value;
|
|
480
|
+
return self;
|
|
481
|
+
},
|
|
482
|
+
totalPages(value) {
|
|
483
|
+
state.totalPages = value;
|
|
484
|
+
return self;
|
|
485
|
+
},
|
|
486
|
+
order(column, options) {
|
|
487
|
+
state.order = {
|
|
488
|
+
field: column,
|
|
489
|
+
direction: options?.ascending === false ? "descending" : "ascending"
|
|
490
|
+
};
|
|
491
|
+
return self;
|
|
492
|
+
},
|
|
469
493
|
gt(column, value) {
|
|
470
494
|
addCondition("gt", column, value);
|
|
471
495
|
return self;
|
|
@@ -680,6 +704,10 @@ function createTableBuilder(tableName, client) {
|
|
|
680
704
|
conditions: state.conditions.length ? [...state.conditions] : void 0,
|
|
681
705
|
limit: state.limit,
|
|
682
706
|
offset: state.offset,
|
|
707
|
+
current_page: state.currentPage,
|
|
708
|
+
page_size: state.pageSize,
|
|
709
|
+
total_pages: state.totalPages,
|
|
710
|
+
sort_by: state.order,
|
|
683
711
|
strip_nulls: options?.stripNulls ?? true,
|
|
684
712
|
count: options?.count,
|
|
685
713
|
head: options?.head
|
|
@@ -715,6 +743,10 @@ function createTableBuilder(tableName, client) {
|
|
|
715
743
|
state.conditions = [];
|
|
716
744
|
state.limit = void 0;
|
|
717
745
|
state.offset = void 0;
|
|
746
|
+
state.order = void 0;
|
|
747
|
+
state.currentPage = void 0;
|
|
748
|
+
state.pageSize = void 0;
|
|
749
|
+
state.totalPages = void 0;
|
|
718
750
|
return builder;
|
|
719
751
|
},
|
|
720
752
|
select(columns = DEFAULT_COLUMNS, options) {
|
|
@@ -806,6 +838,10 @@ function createTableBuilder(tableName, client) {
|
|
|
806
838
|
conditions: filters,
|
|
807
839
|
strip_nulls: mergedOptions?.stripNulls ?? true
|
|
808
840
|
};
|
|
841
|
+
if (state.order) payload.sort_by = state.order;
|
|
842
|
+
if (state.currentPage !== void 0) payload.current_page = state.currentPage;
|
|
843
|
+
if (state.pageSize !== void 0) payload.page_size = state.pageSize;
|
|
844
|
+
if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
|
|
809
845
|
if (columns) payload.columns = columns;
|
|
810
846
|
const response = await client.updateGateway(payload, mergedOptions);
|
|
811
847
|
return formatResult(response);
|
|
@@ -829,6 +865,10 @@ function createTableBuilder(tableName, client) {
|
|
|
829
865
|
resource_id: resourceId,
|
|
830
866
|
conditions: filters
|
|
831
867
|
};
|
|
868
|
+
if (state.order) payload.sort_by = state.order;
|
|
869
|
+
if (state.currentPage !== void 0) payload.current_page = state.currentPage;
|
|
870
|
+
if (state.pageSize !== void 0) payload.page_size = state.pageSize;
|
|
871
|
+
if (state.totalPages !== void 0) payload.total_pages = state.totalPages;
|
|
832
872
|
if (columns) payload.columns = columns;
|
|
833
873
|
const response = await client.deleteGateway(payload, mergedOptions);
|
|
834
874
|
return formatResult(response);
|