@xylex-group/athena 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Floris (XYLEX Group)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # athena-js
2
+
3
+ Athena is a database driver + API gateway SDK that lets you interact with SQL backends using the familiar `supabase-js` syntax.
4
+
5
+ ## Gateway query builder
6
+
7
+ ```ts
8
+ import { createClient } from "athena-js";
9
+
10
+ const athena = createClient(
11
+ "https://athena-db.com",
12
+ process.env.ATHENA_API_KEY,
13
+ );
14
+
15
+ const { data, error } = await athena.from("characters").select(`
16
+ id,
17
+ name,
18
+ from:sender_id(name),
19
+ to:receiver_id(name)
20
+ `);
21
+
22
+ if (error) {
23
+ console.error("gateway error", error);
24
+ } else {
25
+ console.table(data);
26
+ }
27
+ ```
28
+
29
+ Use `select`, `insert`, `update`, and `delete` just like Supabase. The builder supports `.eq()`, `.match()`, `.limit()`, `.offset()`, and `.single()` / `.maybeSingle()`.
30
+
31
+ ## React hook
32
+
33
+ ```tsx
34
+ "use client";
35
+
36
+ import { useAthenaGateway } from "athena-js/react";
37
+ import { useEffect } from "react";
38
+
39
+ export function UsersPanel() {
40
+ const { fetchGateway, lastResponse, isLoading, error } = useAthenaGateway({
41
+ baseUrl: "https://athena-db.com",
42
+ apiKey: process.env.NEXT_PUBLIC_ATHENA_API_KEY,
43
+ });
44
+
45
+ useEffect(() => {
46
+ fetchGateway({
47
+ table_name: "users",
48
+ columns: ["id", "email"],
49
+ limit: 25,
50
+ });
51
+ }, [fetchGateway]);
52
+
53
+ if (error) return <div>Error: {error}</div>;
54
+ if (isLoading) return <div>Loading…</div>;
55
+
56
+ return <pre>{JSON.stringify(lastResponse?.data, null, 2)}</pre>;
57
+ }
58
+ ```
59
+
60
+ ## Learn more
61
+
62
+ - [API reference](docs/api-reference.md)
63
+ - [Getting started](docs/getting-started.md)
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+
3
+ import('../dist/cli/index.js').then(({ runCLI }) => {
4
+ runCLI(process.argv.slice(2))
5
+ }).catch(err => {
6
+ console.error('Failed to start athena-js CLI:', err)
7
+ process.exit(1)
8
+ })
9
+
@@ -0,0 +1,31 @@
1
+ import { A as AthenaGatewayCallOptions } from './types-DFvltfTX.mjs';
2
+ export { a as AthenaDeletePayload, b as AthenaFetchPayload, c as AthenaGatewayBaseOptions, d as AthenaGatewayCallLog, e as AthenaGatewayCondition, f as AthenaGatewayEndpointPath, g as AthenaGatewayHookConfig, h as AthenaGatewayHookResult, i as AthenaGatewayMethod, j as AthenaGatewayResponse, k as AthenaGatewayResponseLog, l as AthenaInsertPayload, m as AthenaUpdatePayload } from './types-DFvltfTX.mjs';
3
+
4
+ type AthenaConditionValue = string | number | boolean | null;
5
+ interface SupabaseResult<T> {
6
+ data: T | null;
7
+ error: string | null;
8
+ status: number;
9
+ raw: unknown;
10
+ }
11
+ interface TableQueryBuilder<Row> {
12
+ select<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T>>;
13
+ insert(values: Row | Row[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<Row | Row[]>>;
14
+ update(values: Partial<Row>, options?: AthenaGatewayCallOptions): Promise<SupabaseResult<Row[]>>;
15
+ delete(options?: AthenaGatewayCallOptions & {
16
+ resourceId?: string;
17
+ }): Promise<SupabaseResult<null>>;
18
+ eq(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
19
+ match(filters: Record<string, AthenaConditionValue>): TableQueryBuilder<Row>;
20
+ limit(count: number): TableQueryBuilder<Row>;
21
+ offset(count: number): TableQueryBuilder<Row>;
22
+ single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
23
+ maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
24
+ reset(): TableQueryBuilder<Row>;
25
+ }
26
+ interface SupabaseClient {
27
+ from<Row = unknown>(table: string): TableQueryBuilder<Row>;
28
+ }
29
+ declare function createClient(url: string, apiKey: string, options?: AthenaGatewayCallOptions): SupabaseClient;
30
+
31
+ export { AthenaGatewayCallOptions, type SupabaseClient, type SupabaseResult, type TableQueryBuilder, createClient };
@@ -0,0 +1,31 @@
1
+ import { A as AthenaGatewayCallOptions } from './types-DFvltfTX.js';
2
+ export { a as AthenaDeletePayload, b as AthenaFetchPayload, c as AthenaGatewayBaseOptions, d as AthenaGatewayCallLog, e as AthenaGatewayCondition, f as AthenaGatewayEndpointPath, g as AthenaGatewayHookConfig, h as AthenaGatewayHookResult, i as AthenaGatewayMethod, j as AthenaGatewayResponse, k as AthenaGatewayResponseLog, l as AthenaInsertPayload, m as AthenaUpdatePayload } from './types-DFvltfTX.js';
3
+
4
+ type AthenaConditionValue = string | number | boolean | null;
5
+ interface SupabaseResult<T> {
6
+ data: T | null;
7
+ error: string | null;
8
+ status: number;
9
+ raw: unknown;
10
+ }
11
+ interface TableQueryBuilder<Row> {
12
+ select<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T>>;
13
+ insert(values: Row | Row[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<Row | Row[]>>;
14
+ update(values: Partial<Row>, options?: AthenaGatewayCallOptions): Promise<SupabaseResult<Row[]>>;
15
+ delete(options?: AthenaGatewayCallOptions & {
16
+ resourceId?: string;
17
+ }): Promise<SupabaseResult<null>>;
18
+ eq(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>;
19
+ match(filters: Record<string, AthenaConditionValue>): TableQueryBuilder<Row>;
20
+ limit(count: number): TableQueryBuilder<Row>;
21
+ offset(count: number): TableQueryBuilder<Row>;
22
+ single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
23
+ maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>;
24
+ reset(): TableQueryBuilder<Row>;
25
+ }
26
+ interface SupabaseClient {
27
+ from<Row = unknown>(table: string): TableQueryBuilder<Row>;
28
+ }
29
+ declare function createClient(url: string, apiKey: string, options?: AthenaGatewayCallOptions): SupabaseClient;
30
+
31
+ export { AthenaGatewayCallOptions, type SupabaseClient, type SupabaseResult, type TableQueryBuilder, createClient };
package/dist/index.js ADDED
@@ -0,0 +1,250 @@
1
+ 'use strict';
2
+
3
+ // src/gateway/client.ts
4
+ var DEFAULT_BASE_URL = "https://athena-db.com";
5
+ var DEFAULT_CLIENT = "railway_direct";
6
+ function parseResponseText(text) {
7
+ if (!text) return null;
8
+ try {
9
+ return JSON.parse(text);
10
+ } catch {
11
+ return text;
12
+ }
13
+ }
14
+ function normalizeHeaderValue(value) {
15
+ return value ? value : void 0;
16
+ }
17
+ function buildHeaders(config, options) {
18
+ const mergedStripNulls = options?.stripNulls ?? config.stripNulls ?? true;
19
+ const finalClient = options?.client ?? config.client ?? DEFAULT_CLIENT;
20
+ const finalApiKey = options?.apiKey ?? config.apiKey;
21
+ const finalSupabaseUrl = options?.supabaseUrl ?? config.supabaseUrl;
22
+ const finalSupabaseKey = options?.supabaseKey ?? config.supabaseKey;
23
+ const finalPublishEvent = options?.publishEvent ?? config.publishEvent;
24
+ const extraHeaders = {
25
+ ...config.headers ?? {},
26
+ ...options?.headers ?? {}
27
+ };
28
+ const headers = {
29
+ "Content-Type": "application/json"
30
+ };
31
+ if (options?.userId ?? config.userId) {
32
+ headers["X-User-Id"] = options?.userId ?? config.userId ?? "";
33
+ }
34
+ if (options?.companyId ?? config.companyId) {
35
+ headers["X-Company-Id"] = options?.companyId ?? config.companyId ?? "";
36
+ }
37
+ if (options?.organizationId ?? config.organizationId) {
38
+ headers["X-Organization-Id"] = options?.organizationId ?? config.organizationId ?? "";
39
+ }
40
+ if (finalClient) {
41
+ headers["X-Athena-Client"] = finalClient;
42
+ }
43
+ if (typeof mergedStripNulls === "boolean") {
44
+ headers["X-Strip-Nulls"] = mergedStripNulls ? "true" : "false";
45
+ }
46
+ if (finalPublishEvent) {
47
+ headers["X-Publish-Event"] = finalPublishEvent;
48
+ }
49
+ if (finalApiKey) {
50
+ headers["apikey"] = finalApiKey;
51
+ headers["x-api-key"] = headers["x-api-key"] ?? finalApiKey;
52
+ }
53
+ if (finalSupabaseUrl) {
54
+ headers["x-supabase-url"] = finalSupabaseUrl;
55
+ }
56
+ if (finalSupabaseKey) {
57
+ headers["x-supabase-key"] = finalSupabaseKey;
58
+ }
59
+ Object.entries(extraHeaders).forEach(([key, value]) => {
60
+ const normalized = normalizeHeaderValue(value);
61
+ if (normalized) {
62
+ headers[key] = normalized;
63
+ }
64
+ });
65
+ return headers;
66
+ }
67
+ async function callAthena(config, endpoint, method, payload, options) {
68
+ const baseUrl = (options?.baseUrl ?? config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
69
+ const url = `${baseUrl}${endpoint}`;
70
+ const headers = buildHeaders(config, options);
71
+ try {
72
+ const response = await fetch(url, {
73
+ method,
74
+ headers,
75
+ body: JSON.stringify(payload)
76
+ });
77
+ const rawText = await response.text();
78
+ const parsed = parseResponseText(rawText ?? "");
79
+ const parsedPayload = parsed;
80
+ const parsedError = parsedPayload && typeof parsedPayload === "object" ? parsedPayload.error ?? parsedPayload.message : void 0;
81
+ const hasError = typeof parsedError === "string" && parsedError.length > 0 ? parsedError : void 0;
82
+ return {
83
+ ok: response.ok,
84
+ status: response.status,
85
+ data: parsed ?? null,
86
+ error: hasError,
87
+ raw: parsed
88
+ };
89
+ } catch (callError) {
90
+ const message = callError instanceof Error ? callError.message : String(callError);
91
+ return {
92
+ ok: false,
93
+ status: 0,
94
+ data: null,
95
+ error: message,
96
+ raw: null
97
+ };
98
+ }
99
+ }
100
+ function createAthenaGatewayClient(config = {}) {
101
+ return {
102
+ baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, ""),
103
+ buildHeaders(options) {
104
+ return buildHeaders(config, options);
105
+ },
106
+ fetchGateway(payload, options) {
107
+ return callAthena(config, "/gateway/fetch", "POST", payload, options);
108
+ },
109
+ insertGateway(payload, options) {
110
+ return callAthena(config, "/gateway/insert", "PUT", payload, options);
111
+ },
112
+ updateGateway(payload, options) {
113
+ return callAthena(config, "/gateway/update", "POST", payload, options);
114
+ },
115
+ deleteGateway(payload, options) {
116
+ return callAthena(config, "/gateway/delete", "DELETE", payload, options);
117
+ }
118
+ };
119
+ }
120
+
121
+ // src/supabase.ts
122
+ function formatResult(response) {
123
+ return {
124
+ data: response.data ?? null,
125
+ error: response.error ?? null,
126
+ status: response.status,
127
+ raw: response.raw
128
+ };
129
+ }
130
+ function ensureConditionValue(value) {
131
+ return value;
132
+ }
133
+ function buildCondition(column, value) {
134
+ return {
135
+ eq_column: column,
136
+ eq_value: ensureConditionValue(value)
137
+ };
138
+ }
139
+ function getResourceId(state) {
140
+ const candidate = state.conditions.find(
141
+ (condition) => condition.eq_column === "resource_id" || condition.eq_column === "id"
142
+ );
143
+ return candidate?.eq_value?.toString();
144
+ }
145
+ function createTableBuilder(tableName, client) {
146
+ const state = {
147
+ conditions: []
148
+ };
149
+ const builder = {
150
+ reset() {
151
+ state.conditions = [];
152
+ state.limit = void 0;
153
+ state.offset = void 0;
154
+ return builder;
155
+ },
156
+ limit(count) {
157
+ state.limit = count;
158
+ return builder;
159
+ },
160
+ offset(count) {
161
+ state.offset = count;
162
+ return builder;
163
+ },
164
+ match(filters) {
165
+ Object.entries(filters).forEach(([column, value]) => {
166
+ state.conditions.push(buildCondition(column, value));
167
+ });
168
+ return builder;
169
+ },
170
+ eq(column, value) {
171
+ state.conditions.push(buildCondition(column, value));
172
+ return builder;
173
+ },
174
+ async select(columns = "*", options) {
175
+ const payload = {
176
+ table_name: tableName,
177
+ columns,
178
+ conditions: state.conditions.length ? [...state.conditions] : void 0,
179
+ limit: state.limit,
180
+ offset: state.offset,
181
+ strip_nulls: options?.stripNulls ?? true
182
+ };
183
+ const response = await client.fetchGateway(payload, options);
184
+ return formatResult(response);
185
+ },
186
+ async insert(values, options) {
187
+ const response = await client.insertGateway(
188
+ {
189
+ table_name: tableName,
190
+ insert_body: values
191
+ },
192
+ options
193
+ );
194
+ return formatResult(response);
195
+ },
196
+ async update(values, options) {
197
+ const payload = {
198
+ table_name: tableName,
199
+ update_body: values,
200
+ conditions: state.conditions.length ? [...state.conditions] : void 0,
201
+ strip_nulls: options?.stripNulls ?? true
202
+ };
203
+ const response = await client.updateGateway(payload, options);
204
+ return formatResult(response);
205
+ },
206
+ async delete(options) {
207
+ const resourceId = options?.resourceId ?? getResourceId(state);
208
+ if (!resourceId) {
209
+ throw new Error('delete requires a resource_id either via eq("resource_id", ...) or options.resourceId');
210
+ }
211
+ const response = await client.deleteGateway(
212
+ {
213
+ table_name: tableName,
214
+ resource_id: resourceId
215
+ },
216
+ options
217
+ );
218
+ return formatResult(response);
219
+ },
220
+ async single(columns, options) {
221
+ const response = await builder.select(columns, options);
222
+ const rows = Array.isArray(response.data) ? response.data : response.data ? [response.data] : [];
223
+ return {
224
+ ...response,
225
+ data: rows[0] ?? null
226
+ };
227
+ },
228
+ async maybeSingle(columns, options) {
229
+ return builder.single(columns ?? "*", options);
230
+ }
231
+ };
232
+ return builder;
233
+ }
234
+ function createClient(url, apiKey, options) {
235
+ const { baseUrl: optBaseUrl, apiKey: optApiKey, ...restOptions } = options ?? {};
236
+ const client = createAthenaGatewayClient({
237
+ baseUrl: optBaseUrl ?? url,
238
+ apiKey: optApiKey ?? apiKey,
239
+ ...restOptions
240
+ });
241
+ return {
242
+ from(table) {
243
+ return createTableBuilder(table, client);
244
+ }
245
+ };
246
+ }
247
+
248
+ exports.createClient = createClient;
249
+ //# sourceMappingURL=index.js.map
250
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/gateway/client.ts","../src/supabase.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type {\r\n AthenaGatewayBaseOptions,\r\n AthenaGatewayCallOptions,\r\n AthenaGatewayEndpointPath,\r\n AthenaGatewayMethod,\r\n AthenaGatewayResponse,\r\n} from './types.js'\r\nimport type {\r\n AthenaDeletePayload,\r\n AthenaFetchPayload,\r\n AthenaInsertPayload,\r\n AthenaUpdatePayload,\r\n} from './types.js'\r\n\r\nconst DEFAULT_BASE_URL = 'https://athena-db.com'\r\nconst DEFAULT_CLIENT = 'railway_direct'\r\n\r\nfunction parseResponseText(text: string) {\r\n if (!text) return null\r\n try {\r\n return JSON.parse(text)\r\n } catch {\r\n return text\r\n }\r\n}\r\n\r\nfunction normalizeHeaderValue(value?: string | null) {\r\n return value ? value : undefined\r\n}\r\n\r\nfunction buildHeaders(\r\n config: AthenaGatewayBaseOptions,\r\n options?: AthenaGatewayCallOptions,\r\n): Record<string, string> {\r\n const mergedStripNulls = options?.stripNulls ?? config.stripNulls ?? true\r\n const finalClient = options?.client ?? config.client ?? DEFAULT_CLIENT\r\n const finalApiKey = options?.apiKey ?? config.apiKey\r\n const finalSupabaseUrl = options?.supabaseUrl ?? config.supabaseUrl\r\n const finalSupabaseKey = options?.supabaseKey ?? config.supabaseKey\r\n const finalPublishEvent = options?.publishEvent ?? config.publishEvent\r\n const extraHeaders = {\r\n ...(config.headers ?? {}),\r\n ...(options?.headers ?? {}),\r\n }\r\n\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n }\r\n\r\n if (options?.userId ?? config.userId) {\r\n headers['X-User-Id'] = options?.userId ?? config.userId ?? ''\r\n }\r\n\r\n if (options?.companyId ?? config.companyId) {\r\n headers['X-Company-Id'] = options?.companyId ?? config.companyId ?? ''\r\n }\r\n\r\n if (options?.organizationId ?? config.organizationId) {\r\n headers['X-Organization-Id'] = options?.organizationId ?? config.organizationId ?? ''\r\n }\r\n\r\n if (finalClient) {\r\n headers['X-Athena-Client'] = finalClient\r\n }\r\n\r\n if (typeof mergedStripNulls === 'boolean') {\r\n headers['X-Strip-Nulls'] = mergedStripNulls ? 'true' : 'false'\r\n }\r\n\r\n if (finalPublishEvent) {\r\n headers['X-Publish-Event'] = finalPublishEvent\r\n }\r\n\r\n if (finalApiKey) {\r\n headers['apikey'] = finalApiKey\r\n headers['x-api-key'] = headers['x-api-key'] ?? finalApiKey\r\n }\r\n\r\n if (finalSupabaseUrl) {\r\n headers['x-supabase-url'] = finalSupabaseUrl\r\n }\r\n\r\n if (finalSupabaseKey) {\r\n headers['x-supabase-key'] = finalSupabaseKey\r\n }\r\n\r\n Object.entries(extraHeaders).forEach(([key, value]) => {\r\n const normalized = normalizeHeaderValue(value)\r\n if (normalized) {\r\n headers[key] = normalized\r\n }\r\n })\r\n\r\n return headers\r\n}\r\n\r\nasync function callAthena<T>(\r\n config: AthenaGatewayBaseOptions,\r\n endpoint: AthenaGatewayEndpointPath,\r\n method: AthenaGatewayMethod,\r\n payload: unknown,\r\n options?: AthenaGatewayCallOptions,\r\n): Promise<AthenaGatewayResponse<T>> {\r\n const baseUrl = (options?.baseUrl ?? config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\r\n const url = `${baseUrl}${endpoint}`\r\n const headers = buildHeaders(config, options)\r\n\r\n try {\r\n const response = await fetch(url, {\r\n method,\r\n headers,\r\n body: JSON.stringify(payload),\r\n })\r\n\r\n const rawText = await response.text()\r\n const parsed = parseResponseText(rawText ?? '')\r\n const parsedPayload = parsed as Record<string, unknown> | null\r\n const parsedError =\r\n parsedPayload && typeof parsedPayload === 'object'\r\n ? ((parsedPayload.error as string | undefined) ?? (parsedPayload.message as string | undefined))\r\n : undefined\r\n const hasError = typeof parsedError === 'string' && parsedError.length > 0 ? parsedError : undefined\r\n\r\n return {\r\n ok: response.ok,\r\n status: response.status,\r\n data: (parsed as T) ?? null,\r\n error: hasError,\r\n raw: parsed,\r\n }\r\n } catch (callError) {\r\n const message = callError instanceof Error ? callError.message : String(callError)\r\n return {\r\n ok: false,\r\n status: 0,\r\n data: null,\r\n error: message,\r\n raw: null,\r\n }\r\n }\r\n}\r\n\r\nexport interface AthenaGatewayClient {\r\n baseUrl: string\r\n buildHeaders(options?: AthenaGatewayCallOptions): Record<string, string>\r\n fetchGateway<T>(payload: AthenaFetchPayload, options?: AthenaGatewayCallOptions): Promise<AthenaGatewayResponse<T>>\r\n insertGateway<T>(payload: AthenaInsertPayload, options?: AthenaGatewayCallOptions): Promise<AthenaGatewayResponse<T>>\r\n updateGateway<T>(payload: AthenaUpdatePayload, options?: AthenaGatewayCallOptions): Promise<AthenaGatewayResponse<T>>\r\n deleteGateway<T>(payload: AthenaDeletePayload, options?: AthenaGatewayCallOptions): Promise<AthenaGatewayResponse<T>>\r\n}\r\n\r\nexport function createAthenaGatewayClient(config: AthenaGatewayBaseOptions = {}): AthenaGatewayClient {\r\n return {\r\n baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, ''),\r\n buildHeaders(options) {\r\n return buildHeaders(config, options)\r\n },\r\n fetchGateway(payload, options) {\r\n return callAthena(config, '/gateway/fetch', 'POST', payload, options)\r\n },\r\n insertGateway(payload, options) {\r\n return callAthena(config, '/gateway/insert', 'PUT', payload, options)\r\n },\r\n updateGateway(payload, options) {\r\n return callAthena(config, '/gateway/update', 'POST', payload, options)\r\n },\r\n deleteGateway(payload, options) {\r\n return callAthena(config, '/gateway/delete', 'DELETE', payload, options)\r\n },\r\n }\r\n}\r\n","import type {\r\n AthenaGatewayCallOptions,\r\n AthenaGatewayCondition,\r\n AthenaGatewayResponse,\r\n} from './gateway/types.js'\r\nimport { createAthenaGatewayClient } from './gateway/client.js'\r\n\r\ntype AthenaConditionValue = string | number | boolean | null\r\n\r\nexport interface SupabaseResult<T> {\r\n data: T | null\r\n error: string | null\r\n status: number\r\n raw: unknown\r\n}\r\n\r\ntype TableBuilderState = {\r\n conditions: AthenaGatewayCondition[]\r\n limit?: number\r\n offset?: number\r\n}\r\n\r\nfunction formatResult<T>(response: AthenaGatewayResponse<T>): SupabaseResult<T> {\r\n return {\r\n data: response.data ?? null,\r\n error: response.error ?? null,\r\n status: response.status,\r\n raw: response.raw,\r\n }\r\n}\r\n\r\nfunction ensureConditionValue(value: AthenaConditionValue): AthenaConditionValue {\r\n return value\r\n}\r\n\r\nfunction buildCondition(column: string, value: AthenaConditionValue): AthenaGatewayCondition {\r\n return {\r\n eq_column: column,\r\n eq_value: ensureConditionValue(value),\r\n }\r\n}\r\n\r\nexport interface TableQueryBuilder<Row> {\r\n select<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T>>\r\n insert(values: Row | Row[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<Row | Row[]>>\r\n update(values: Partial<Row>, options?: AthenaGatewayCallOptions): Promise<SupabaseResult<Row[]>>\r\n delete(options?: AthenaGatewayCallOptions & { resourceId?: string }): Promise<SupabaseResult<null>>\r\n eq(column: string, value: AthenaConditionValue): TableQueryBuilder<Row>\r\n match(filters: Record<string, AthenaConditionValue>): TableQueryBuilder<Row>\r\n limit(count: number): TableQueryBuilder<Row>\r\n offset(count: number): TableQueryBuilder<Row>\r\n single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>\r\n maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<SupabaseResult<T | null>>\r\n reset(): TableQueryBuilder<Row>\r\n}\r\n\r\nfunction getResourceId(state: TableBuilderState): string | undefined {\r\n const candidate = state.conditions.find(\r\n condition => condition.eq_column === 'resource_id' || condition.eq_column === 'id',\r\n )\r\n return candidate?.eq_value?.toString()\r\n}\r\n\r\nfunction createTableBuilder<Row>(\r\n tableName: string,\r\n client: ReturnType<typeof createAthenaGatewayClient>,\r\n): TableQueryBuilder<Row> {\r\n const state: TableBuilderState = {\r\n conditions: [],\r\n }\r\n\r\n const builder: TableQueryBuilder<Row> = {\r\n reset() {\r\n state.conditions = []\r\n state.limit = undefined\r\n state.offset = undefined\r\n return builder\r\n },\r\n limit(count: number) {\r\n state.limit = count\r\n return builder\r\n },\r\n offset(count: number) {\r\n state.offset = count\r\n return builder\r\n },\r\n match(filters: Record<string, AthenaConditionValue>) {\r\n Object.entries(filters).forEach(([column, value]) => {\r\n state.conditions.push(buildCondition(column, value))\r\n })\r\n return builder\r\n },\r\n eq(column: string, value: AthenaConditionValue) {\r\n state.conditions.push(buildCondition(column, value))\r\n return builder\r\n },\r\n async select<T = Row>(columns: string | string[] = '*', options?: AthenaGatewayCallOptions) {\r\n const payload = {\r\n table_name: tableName,\r\n columns,\r\n conditions: state.conditions.length ? [...state.conditions] : undefined,\r\n limit: state.limit,\r\n offset: state.offset,\r\n strip_nulls: options?.stripNulls ?? true,\r\n }\r\n const response = await client.fetchGateway<T>(payload, options)\r\n return formatResult(response)\r\n },\r\n async insert(values: Row | Row[], options?: AthenaGatewayCallOptions) {\r\n const response = await client.insertGateway<Row | Row[]>(\r\n {\r\n table_name: tableName,\r\n insert_body: values as Record<string, unknown>,\r\n },\r\n options,\r\n )\r\n return formatResult(response)\r\n },\r\n async update(values: Partial<Row>, options?: AthenaGatewayCallOptions) {\r\n const payload = {\r\n table_name: tableName,\r\n update_body: values,\r\n conditions: state.conditions.length ? [...state.conditions] : undefined,\r\n strip_nulls: options?.stripNulls ?? true,\r\n }\r\n const response = await client.updateGateway<Row[]>(payload, options)\r\n return formatResult(response)\r\n },\r\n async delete(options?: AthenaGatewayCallOptions & { resourceId?: string }) {\r\n const resourceId = options?.resourceId ?? getResourceId(state)\r\n if (!resourceId) {\r\n throw new Error('delete requires a resource_id either via eq(\"resource_id\", ...) or options.resourceId')\r\n }\r\n const response = await client.deleteGateway<null>(\r\n {\r\n table_name: tableName,\r\n resource_id: resourceId,\r\n },\r\n options,\r\n )\r\n return formatResult(response)\r\n },\r\n async single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions) {\r\n const response = await builder.select<T[]>(columns, options)\r\n const rows = Array.isArray(response.data) ? response.data : response.data ? [response.data] : []\r\n return {\r\n ...response,\r\n data: (rows[0] ?? null) as unknown as T | null,\r\n }\r\n },\r\n async maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions) {\r\n return builder.single<T | null>(columns ?? '*', options)\r\n },\r\n }\r\n\r\n return builder\r\n}\r\n\r\nexport interface SupabaseClient {\r\n from<Row = unknown>(table: string): TableQueryBuilder<Row>\r\n}\r\n\r\nexport function createClient(\r\n url: string,\r\n apiKey: string,\r\n options?: AthenaGatewayCallOptions,\r\n): SupabaseClient {\r\n const { baseUrl: optBaseUrl, apiKey: optApiKey, ...restOptions } = options ?? {}\r\n const client = createAthenaGatewayClient({\r\n baseUrl: optBaseUrl ?? url,\r\n apiKey: optApiKey ?? apiKey,\r\n ...restOptions,\r\n })\r\n\r\n return {\r\n from<Row = unknown>(table: string) {\r\n return createTableBuilder<Row>(table, client)\r\n },\r\n }\r\n}\r\n"]}