@luxdb/sdk 1.3.0 → 1.4.2
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 +132 -0
- package/dist/cjs/auth.js +504 -0
- package/dist/cjs/browser.js +14 -0
- package/dist/{index.js → cjs/index.js} +46 -7
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/project.js +313 -0
- package/dist/cjs/ssr.js +40 -0
- package/dist/{table.js → cjs/table.js} +55 -43
- package/dist/esm/auth.js +500 -0
- package/dist/esm/browser.js +11 -0
- package/dist/esm/index.js +270 -0
- package/dist/esm/namespaces.js +41 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/project.js +303 -0
- package/dist/esm/realtime.js +84 -0
- package/dist/esm/ssr.js +37 -0
- package/dist/esm/table.js +391 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils.js +12 -0
- package/dist/types/auth.d.ts +163 -0
- package/dist/types/browser.d.ts +4 -0
- package/dist/{index.d.ts → types/index.d.ts} +17 -2
- package/dist/types/project.d.ts +121 -0
- package/dist/types/ssr.d.ts +22 -0
- package/dist/{table.d.ts → types/table.d.ts} +11 -2
- package/package.json +40 -6
- /package/dist/{namespaces.js → cjs/namespaces.js} +0 -0
- /package/dist/{realtime.js → cjs/realtime.js} +0 -0
- /package/dist/{types.js → cjs/types.js} +0 -0
- /package/dist/{utils.js → cjs/utils.js} +0 -0
- /package/dist/{namespaces.d.ts → types/namespaces.d.ts} +0 -0
- /package/dist/{realtime.d.ts → types/realtime.d.ts} +0 -0
- /package/dist/{types.d.ts → types/types.d.ts} +0 -0
- /package/dist/{utils.d.ts → types/utils.d.ts} +0 -0
|
@@ -3,26 +3,59 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.Lux = exports.TableSubscription = exports.TableQueryBuilder = void 0;
|
|
6
|
+
exports.Lux = exports.TableSubscription = exports.TableQueryBuilder = exports.createServerClient = exports.createBrowserClient = exports.LuxProjectClient = exports.createProjectClient = void 0;
|
|
7
7
|
exports.createClient = createClient;
|
|
8
|
+
exports.createAuthClient = createAuthClient;
|
|
8
9
|
const ioredis_1 = __importDefault(require("ioredis"));
|
|
10
|
+
const auth_1 = require("./auth");
|
|
11
|
+
const project_1 = require("./project");
|
|
12
|
+
Object.defineProperty(exports, "createProjectClient", { enumerable: true, get: function () { return project_1.createProjectClient; } });
|
|
13
|
+
Object.defineProperty(exports, "LuxProjectClient", { enumerable: true, get: function () { return project_1.LuxProjectClient; } });
|
|
9
14
|
const namespaces_1 = require("./namespaces");
|
|
10
15
|
const realtime_1 = require("./realtime");
|
|
11
16
|
const table_1 = require("./table");
|
|
17
|
+
var browser_1 = require("./browser");
|
|
18
|
+
Object.defineProperty(exports, "createBrowserClient", { enumerable: true, get: function () { return browser_1.createBrowserClient; } });
|
|
19
|
+
var ssr_1 = require("./ssr");
|
|
20
|
+
Object.defineProperty(exports, "createServerClient", { enumerable: true, get: function () { return ssr_1.createServerClient; } });
|
|
12
21
|
var table_2 = require("./table");
|
|
13
22
|
Object.defineProperty(exports, "TableQueryBuilder", { enumerable: true, get: function () { return table_2.TableQueryBuilder; } });
|
|
14
23
|
Object.defineProperty(exports, "TableSubscription", { enumerable: true, get: function () { return table_2.TableSubscription; } });
|
|
24
|
+
function createAuthNamespace(redis, options) {
|
|
25
|
+
const client = new auth_1.LuxAuthClient(options);
|
|
26
|
+
const redisAuth = ((...args) => {
|
|
27
|
+
return redis.call('AUTH', ...args);
|
|
28
|
+
});
|
|
29
|
+
return new Proxy(redisAuth, {
|
|
30
|
+
get(target, prop, receiver) {
|
|
31
|
+
if (prop in client) {
|
|
32
|
+
const value = client[prop];
|
|
33
|
+
return typeof value === 'function' ? value.bind(client) : value;
|
|
34
|
+
}
|
|
35
|
+
return Reflect.get(target, prop, receiver);
|
|
36
|
+
},
|
|
37
|
+
set(_target, prop, value) {
|
|
38
|
+
client[prop] = value;
|
|
39
|
+
return true;
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
15
43
|
class Lux extends ioredis_1.default {
|
|
16
44
|
constructor(options) {
|
|
45
|
+
let authOptions = {};
|
|
17
46
|
if (typeof options === 'string') {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
47
|
+
options = options.replace(/^luxs:\/\//, 'rediss://').replace(/^lux:\/\//, 'redis://');
|
|
48
|
+
}
|
|
49
|
+
else if (options) {
|
|
50
|
+
const { httpUrl, apiKey, authToken, fetch: fetchImpl, ...redisOptions } = options;
|
|
51
|
+
authOptions = { httpUrl, apiKey, authToken, fetch: fetchImpl };
|
|
52
|
+
options = redisOptions;
|
|
22
53
|
}
|
|
23
54
|
super(options);
|
|
24
55
|
this.vectors = new namespaces_1.VectorNamespace(this);
|
|
25
56
|
this.timeseries = new namespaces_1.TimeSeriesNamespace(this);
|
|
57
|
+
this.auth = createAuthNamespace(this, authOptions);
|
|
58
|
+
this.authApi = this.auth;
|
|
26
59
|
}
|
|
27
60
|
table(name, options) {
|
|
28
61
|
return new table_1.TableQueryBuilder(this, name, options);
|
|
@@ -239,7 +272,13 @@ class Lux extends ioredis_1.default {
|
|
|
239
272
|
}
|
|
240
273
|
}
|
|
241
274
|
exports.Lux = Lux;
|
|
242
|
-
function createClient(
|
|
243
|
-
|
|
275
|
+
function createClient(optionsOrUrl, key, projectOptions) {
|
|
276
|
+
if (typeof optionsOrUrl === 'string' && typeof key === 'string') {
|
|
277
|
+
return (0, project_1.createProjectClient)({ ...(projectOptions ?? {}), url: optionsOrUrl, key });
|
|
278
|
+
}
|
|
279
|
+
return new Lux(optionsOrUrl);
|
|
280
|
+
}
|
|
281
|
+
function createAuthClient(options) {
|
|
282
|
+
return new auth_1.LuxAuthClient(options);
|
|
244
283
|
}
|
|
245
284
|
exports.default = Lux;
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LuxProjectMutationBuilder = exports.LuxProjectInsertBuilder = exports.LuxProjectSelectBuilder = exports.LuxProjectTable = exports.LuxProjectClient = void 0;
|
|
4
|
+
exports.createProjectClient = createProjectClient;
|
|
5
|
+
exports.createClient = createClient;
|
|
6
|
+
const auth_1 = require("./auth");
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
class LuxProjectClient {
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.url = options.url.replace(/\/+$/, '');
|
|
11
|
+
this.key = options.key;
|
|
12
|
+
this.fetchImpl = resolveFetch(options.fetch);
|
|
13
|
+
this.auth = new auth_1.LuxAuthClient({
|
|
14
|
+
...options.auth,
|
|
15
|
+
httpUrl: this.url,
|
|
16
|
+
apiKey: this.key,
|
|
17
|
+
fetch: this.fetchImpl,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
table(name) {
|
|
21
|
+
return new LuxProjectTable(this, name);
|
|
22
|
+
}
|
|
23
|
+
async ping() {
|
|
24
|
+
return this.request('GET', '/ping');
|
|
25
|
+
}
|
|
26
|
+
async createTable(name, columns) {
|
|
27
|
+
return this.request('POST', '/tables', { name, columns });
|
|
28
|
+
}
|
|
29
|
+
async exec(command) {
|
|
30
|
+
return this.request('POST', '/exec', { command });
|
|
31
|
+
}
|
|
32
|
+
async vectorSet(key, vector, metadata) {
|
|
33
|
+
return this.request('POST', `/vectors/${encodeURIComponent(key)}`, { vector, metadata });
|
|
34
|
+
}
|
|
35
|
+
async vectorSearch(options) {
|
|
36
|
+
return this.request('POST', '/vectors/search', {
|
|
37
|
+
vector: options.vector,
|
|
38
|
+
k: options.k ?? 10,
|
|
39
|
+
filter: options.filter,
|
|
40
|
+
filter_value: options.filter_value,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async tsAdd(key, value, options) {
|
|
44
|
+
return this.request('POST', `/ts/${encodeURIComponent(key)}`, {
|
|
45
|
+
timestamp: options?.timestamp ?? '*',
|
|
46
|
+
value,
|
|
47
|
+
labels: options?.labels,
|
|
48
|
+
retention: options?.retention,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async tsRange(key, options) {
|
|
52
|
+
const params = new URLSearchParams();
|
|
53
|
+
if (options?.from != null)
|
|
54
|
+
params.set('from', String(options.from));
|
|
55
|
+
if (options?.to != null)
|
|
56
|
+
params.set('to', String(options.to));
|
|
57
|
+
if (options?.count != null)
|
|
58
|
+
params.set('count', String(options.count));
|
|
59
|
+
const query = params.toString();
|
|
60
|
+
return this.request('GET', `/ts/${encodeURIComponent(key)}${query ? `?${query}` : ''}`);
|
|
61
|
+
}
|
|
62
|
+
async request(method, path, body) {
|
|
63
|
+
try {
|
|
64
|
+
const accessToken = await this.auth.getAccessToken();
|
|
65
|
+
const headers = {
|
|
66
|
+
Accept: 'application/json',
|
|
67
|
+
apikey: this.key,
|
|
68
|
+
Authorization: `Bearer ${accessToken ?? this.key}`,
|
|
69
|
+
};
|
|
70
|
+
const init = { method, headers };
|
|
71
|
+
if (body !== undefined) {
|
|
72
|
+
headers['Content-Type'] = 'application/json';
|
|
73
|
+
init.body = JSON.stringify(body);
|
|
74
|
+
}
|
|
75
|
+
const response = await this.fetchImpl(`${this.url}${path}`, init);
|
|
76
|
+
const text = await response.text();
|
|
77
|
+
const payload = text ? JSON.parse(text) : {};
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
return (0, utils_1.err)('LUX_PROJECT_REQUEST_ERROR', payload?.error || `Lux request failed with HTTP ${response.status}`, { status: response.status, payload });
|
|
80
|
+
}
|
|
81
|
+
return (0, utils_1.ok)(payload);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return (0, utils_1.err)('LUX_PROJECT_REQUEST_ERROR', 'Lux request failed', (0, utils_1.toLuxError)(error));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
exports.LuxProjectClient = LuxProjectClient;
|
|
89
|
+
class LuxProjectTable {
|
|
90
|
+
constructor(client, name) {
|
|
91
|
+
this.client = client;
|
|
92
|
+
this.name = name;
|
|
93
|
+
}
|
|
94
|
+
select(columns = '*') {
|
|
95
|
+
return new LuxProjectSelectBuilder(this.client, this.name, columns);
|
|
96
|
+
}
|
|
97
|
+
insert(rowOrRows) {
|
|
98
|
+
return new LuxProjectInsertBuilder(this.client, this.name, rowOrRows);
|
|
99
|
+
}
|
|
100
|
+
update(patch) {
|
|
101
|
+
return new LuxProjectMutationBuilder(this.client, this.name, 'PATCH', patch);
|
|
102
|
+
}
|
|
103
|
+
delete() {
|
|
104
|
+
return new LuxProjectMutationBuilder(this.client, this.name, 'DELETE');
|
|
105
|
+
}
|
|
106
|
+
async count() {
|
|
107
|
+
const result = await this.client.request('GET', `/tables/${encodeURIComponent(this.name)}/count`);
|
|
108
|
+
if (result.error)
|
|
109
|
+
return result;
|
|
110
|
+
return (0, utils_1.ok)(unwrapResult(result.data) ?? 0);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.LuxProjectTable = LuxProjectTable;
|
|
114
|
+
class LuxProjectThenable {
|
|
115
|
+
then(onfulfilled, onrejected) {
|
|
116
|
+
return this.execute().then(onfulfilled, onrejected);
|
|
117
|
+
}
|
|
118
|
+
catch(onrejected) {
|
|
119
|
+
return this.execute().catch(onrejected);
|
|
120
|
+
}
|
|
121
|
+
finally(onfinally) {
|
|
122
|
+
return this.execute().finally(onfinally ?? undefined);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
class LuxProjectFilterBuilder extends LuxProjectThenable {
|
|
126
|
+
constructor(client, tableName) {
|
|
127
|
+
super();
|
|
128
|
+
this.client = client;
|
|
129
|
+
this.tableName = tableName;
|
|
130
|
+
this.filters = [];
|
|
131
|
+
}
|
|
132
|
+
eq(column, value) {
|
|
133
|
+
return this.addFilter(column, 'eq', value);
|
|
134
|
+
}
|
|
135
|
+
neq(column, value) {
|
|
136
|
+
return this.addFilter(column, 'neq', value);
|
|
137
|
+
}
|
|
138
|
+
gt(column, value) {
|
|
139
|
+
return this.addFilter(column, 'gt', value);
|
|
140
|
+
}
|
|
141
|
+
gte(column, value) {
|
|
142
|
+
return this.addFilter(column, 'gte', value);
|
|
143
|
+
}
|
|
144
|
+
lt(column, value) {
|
|
145
|
+
return this.addFilter(column, 'lt', value);
|
|
146
|
+
}
|
|
147
|
+
lte(column, value) {
|
|
148
|
+
return this.addFilter(column, 'lte', value);
|
|
149
|
+
}
|
|
150
|
+
is(column, value) {
|
|
151
|
+
return this.addFilter(column, 'is', value);
|
|
152
|
+
}
|
|
153
|
+
addFilter(column, operator, value) {
|
|
154
|
+
this.filters.push({ column, operator, value });
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
filteredQueryParams() {
|
|
158
|
+
const params = new URLSearchParams();
|
|
159
|
+
if (this.filters.length)
|
|
160
|
+
params.set('where', filtersToWhere(this.filters));
|
|
161
|
+
if (this.orderBy) {
|
|
162
|
+
params.set('order', `${this.orderBy.column} ${this.orderBy.ascending ? 'ASC' : 'DESC'}`);
|
|
163
|
+
}
|
|
164
|
+
if (this.limitCount != null)
|
|
165
|
+
params.set('limit', String(this.limitCount));
|
|
166
|
+
if (this.offsetCount != null)
|
|
167
|
+
params.set('offset', String(this.offsetCount));
|
|
168
|
+
return params;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
class LuxProjectSelectBuilder extends LuxProjectFilterBuilder {
|
|
172
|
+
constructor(client, tableName, columns) {
|
|
173
|
+
super(client, tableName);
|
|
174
|
+
this.columns = columns;
|
|
175
|
+
this.expectSingle = false;
|
|
176
|
+
}
|
|
177
|
+
order(column, options = {}) {
|
|
178
|
+
this.orderBy = { column, ascending: options.ascending ?? true };
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
limit(count) {
|
|
182
|
+
this.limitCount = count;
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
range(from, to) {
|
|
186
|
+
this.offsetCount = from;
|
|
187
|
+
this.limitCount = Math.max(0, to - from + 1);
|
|
188
|
+
return this;
|
|
189
|
+
}
|
|
190
|
+
single() {
|
|
191
|
+
this.expectSingle = true;
|
|
192
|
+
if (this.limitCount == null)
|
|
193
|
+
this.limitCount = 1;
|
|
194
|
+
return this;
|
|
195
|
+
}
|
|
196
|
+
async execute() {
|
|
197
|
+
const params = this.filteredQueryParams();
|
|
198
|
+
if (this.columns && this.columns !== '*')
|
|
199
|
+
params.set('select', this.columns);
|
|
200
|
+
const query = params.toString();
|
|
201
|
+
const result = await this.client.request('GET', `/tables/${encodeURIComponent(this.tableName)}${query ? `?${query}` : ''}`);
|
|
202
|
+
if (result.error)
|
|
203
|
+
return result;
|
|
204
|
+
const rows = unwrapRows(result.data);
|
|
205
|
+
if (!this.expectSingle) {
|
|
206
|
+
return (0, utils_1.ok)(rows);
|
|
207
|
+
}
|
|
208
|
+
if (rows.length === 0) {
|
|
209
|
+
return (0, utils_1.err)('NOT_FOUND', `No rows found in table '${this.tableName}'`);
|
|
210
|
+
}
|
|
211
|
+
return (0, utils_1.ok)(rows[0]);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.LuxProjectSelectBuilder = LuxProjectSelectBuilder;
|
|
215
|
+
class LuxProjectInsertBuilder extends LuxProjectThenable {
|
|
216
|
+
constructor(client, tableName, rowOrRows) {
|
|
217
|
+
super();
|
|
218
|
+
this.client = client;
|
|
219
|
+
this.tableName = tableName;
|
|
220
|
+
this.rowOrRows = rowOrRows;
|
|
221
|
+
}
|
|
222
|
+
async execute() {
|
|
223
|
+
if (!Array.isArray(this.rowOrRows)) {
|
|
224
|
+
return this.client.request('POST', `/tables/${encodeURIComponent(this.tableName)}`, this.rowOrRows);
|
|
225
|
+
}
|
|
226
|
+
const results = [];
|
|
227
|
+
for (const row of this.rowOrRows) {
|
|
228
|
+
const result = await this.client.request('POST', `/tables/${encodeURIComponent(this.tableName)}`, row);
|
|
229
|
+
if (result.error)
|
|
230
|
+
return result;
|
|
231
|
+
results.push(result.data);
|
|
232
|
+
}
|
|
233
|
+
return (0, utils_1.ok)(results);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
exports.LuxProjectInsertBuilder = LuxProjectInsertBuilder;
|
|
237
|
+
class LuxProjectMutationBuilder extends LuxProjectFilterBuilder {
|
|
238
|
+
constructor(client, tableName, method, body) {
|
|
239
|
+
super(client, tableName);
|
|
240
|
+
this.method = method;
|
|
241
|
+
this.body = body;
|
|
242
|
+
}
|
|
243
|
+
async execute() {
|
|
244
|
+
if (this.filters.length === 0) {
|
|
245
|
+
return (0, utils_1.err)('MISSING_FILTER', `${this.method === 'PATCH' ? 'update' : 'delete'}() requires at least one filter`);
|
|
246
|
+
}
|
|
247
|
+
const params = this.filteredQueryParams();
|
|
248
|
+
const query = params.toString();
|
|
249
|
+
return this.client.request(this.method, `/tables/${encodeURIComponent(this.tableName)}${query ? `?${query}` : ''}`, this.body);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
exports.LuxProjectMutationBuilder = LuxProjectMutationBuilder;
|
|
253
|
+
function unwrapRows(payload) {
|
|
254
|
+
if (Array.isArray(payload))
|
|
255
|
+
return payload;
|
|
256
|
+
if (payload && typeof payload === 'object' && Array.isArray(payload.result)) {
|
|
257
|
+
return payload.result;
|
|
258
|
+
}
|
|
259
|
+
return [];
|
|
260
|
+
}
|
|
261
|
+
function unwrapResult(payload) {
|
|
262
|
+
if (payload && typeof payload === 'object' && 'result' in payload) {
|
|
263
|
+
return payload.result;
|
|
264
|
+
}
|
|
265
|
+
return payload;
|
|
266
|
+
}
|
|
267
|
+
function normalizeWhere(where) {
|
|
268
|
+
return where.trim().replace(/\s*(>=|<=|!=|=|>|<)\s*/g, ' $1 ');
|
|
269
|
+
}
|
|
270
|
+
function filtersToWhere(filters) {
|
|
271
|
+
return filters.map((filter) => {
|
|
272
|
+
const op = filterOperatorToWhere(filter.operator);
|
|
273
|
+
return normalizeWhere(`${filter.column} ${op} ${formatWhereValue(filter.value)}`);
|
|
274
|
+
}).join(' AND ');
|
|
275
|
+
}
|
|
276
|
+
function filterOperatorToWhere(operator) {
|
|
277
|
+
switch (operator) {
|
|
278
|
+
case 'eq':
|
|
279
|
+
case 'is':
|
|
280
|
+
return '=';
|
|
281
|
+
case 'neq':
|
|
282
|
+
return '!=';
|
|
283
|
+
case 'gt':
|
|
284
|
+
return '>';
|
|
285
|
+
case 'gte':
|
|
286
|
+
return '>=';
|
|
287
|
+
case 'lt':
|
|
288
|
+
return '<';
|
|
289
|
+
case 'lte':
|
|
290
|
+
return '<=';
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function formatWhereValue(value) {
|
|
294
|
+
if (value === null)
|
|
295
|
+
return '';
|
|
296
|
+
return String(value);
|
|
297
|
+
}
|
|
298
|
+
function createProjectClient(options) {
|
|
299
|
+
return new LuxProjectClient(options);
|
|
300
|
+
}
|
|
301
|
+
function createClient(url, key, options = {}) {
|
|
302
|
+
return new LuxProjectClient({ ...options, url, key });
|
|
303
|
+
}
|
|
304
|
+
function resolveFetch(fetchImpl) {
|
|
305
|
+
const candidate = fetchImpl ?? globalThis.fetch;
|
|
306
|
+
if (!candidate) {
|
|
307
|
+
throw new Error('Lux project client requires a fetch implementation');
|
|
308
|
+
}
|
|
309
|
+
if (typeof globalThis !== 'undefined' && candidate === globalThis.fetch) {
|
|
310
|
+
return candidate.bind(globalThis);
|
|
311
|
+
}
|
|
312
|
+
return candidate;
|
|
313
|
+
}
|
package/dist/cjs/ssr.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createServerClient = createServerClient;
|
|
4
|
+
const project_1 = require("./project");
|
|
5
|
+
const DEFAULT_COOKIE = 'lux-auth-session';
|
|
6
|
+
function createServerClient(url, key, options) {
|
|
7
|
+
const storageKey = options.auth?.storageKey ?? DEFAULT_COOKIE;
|
|
8
|
+
const cookieOptions = options.auth?.cookieOptions ?? {
|
|
9
|
+
path: '/',
|
|
10
|
+
sameSite: 'lax',
|
|
11
|
+
};
|
|
12
|
+
const { cookieOptions: _cookieOptions, ...authOptions } = options.auth ?? {};
|
|
13
|
+
return (0, project_1.createClient)(url, key, {
|
|
14
|
+
fetch: options.fetch,
|
|
15
|
+
auth: {
|
|
16
|
+
persistSession: true,
|
|
17
|
+
autoRefreshToken: false,
|
|
18
|
+
...authOptions,
|
|
19
|
+
storageKey,
|
|
20
|
+
storage: cookieStorage(options.cookies, cookieOptions),
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function cookieStorage(cookies, options) {
|
|
25
|
+
return {
|
|
26
|
+
async getItem(key) {
|
|
27
|
+
return await cookies.get(key) ?? null;
|
|
28
|
+
},
|
|
29
|
+
async setItem(key, value) {
|
|
30
|
+
if (!cookies.set)
|
|
31
|
+
return;
|
|
32
|
+
await cookies.set(key, value, options);
|
|
33
|
+
},
|
|
34
|
+
async removeItem(key) {
|
|
35
|
+
if (!cookies.remove)
|
|
36
|
+
return;
|
|
37
|
+
await cookies.remove(key, { ...options, maxAge: 0, expires: new Date(0) });
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -195,11 +195,32 @@ class TableQueryBuilder {
|
|
|
195
195
|
this.conditions.push({ field, op, value });
|
|
196
196
|
return this;
|
|
197
197
|
}
|
|
198
|
+
eq(field, value) {
|
|
199
|
+
return this.where(field, '=', value);
|
|
200
|
+
}
|
|
201
|
+
neq(field, value) {
|
|
202
|
+
return this.where(field, '!=', value);
|
|
203
|
+
}
|
|
204
|
+
gt(field, value) {
|
|
205
|
+
return this.where(field, '>', value);
|
|
206
|
+
}
|
|
207
|
+
gte(field, value) {
|
|
208
|
+
return this.where(field, '>=', value);
|
|
209
|
+
}
|
|
210
|
+
lt(field, value) {
|
|
211
|
+
return this.where(field, '<', value);
|
|
212
|
+
}
|
|
213
|
+
lte(field, value) {
|
|
214
|
+
return this.where(field, '<=', value);
|
|
215
|
+
}
|
|
198
216
|
orderBy(field, dir = 'asc') {
|
|
199
217
|
this.orderField = field;
|
|
200
218
|
this.orderDir = dir.toUpperCase();
|
|
201
219
|
return this;
|
|
202
220
|
}
|
|
221
|
+
order(field, options = {}) {
|
|
222
|
+
return this.orderBy(field, options.ascending === false ? 'desc' : 'asc');
|
|
223
|
+
}
|
|
203
224
|
limit(n) {
|
|
204
225
|
this.limitCount = n;
|
|
205
226
|
return this;
|
|
@@ -284,6 +305,9 @@ class TableQueryBuilder {
|
|
|
284
305
|
return (0, utils_1.err)('TSELECT_ERROR', `Failed to query table '${this.name}'`, (0, utils_1.toLuxError)(error));
|
|
285
306
|
}
|
|
286
307
|
}
|
|
308
|
+
then(onfulfilled, onrejected) {
|
|
309
|
+
return this.run().then(onfulfilled, onrejected);
|
|
310
|
+
}
|
|
287
311
|
async insert(data) {
|
|
288
312
|
try {
|
|
289
313
|
if (this.schema) {
|
|
@@ -300,35 +324,28 @@ class TableQueryBuilder {
|
|
|
300
324
|
return (0, utils_1.err)('TINSERT_ERROR', `Failed to insert into '${this.name}'`, (0, utils_1.toLuxError)(error));
|
|
301
325
|
}
|
|
302
326
|
}
|
|
303
|
-
async update(
|
|
327
|
+
async update(idOrData, data) {
|
|
304
328
|
try {
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
329
|
+
const hasExplicitId = data !== undefined;
|
|
330
|
+
const patch = hasExplicitId ? data : idOrData;
|
|
331
|
+
if (!hasExplicitId && this.conditions.length === 0) {
|
|
332
|
+
return (0, utils_1.err)('MISSING_WHERE', 'update requires at least one filter');
|
|
308
333
|
}
|
|
309
|
-
args.push('WHERE', 'id', '=', String(id));
|
|
310
|
-
const result = await this.client.call('TUPDATE', ...args);
|
|
311
|
-
return (0, utils_1.ok)(Number(result) || 0);
|
|
312
|
-
}
|
|
313
|
-
catch (error) {
|
|
314
|
-
return (0, utils_1.err)('TUPDATE_ERROR', `Failed to update '${this.name}'`, (0, utils_1.toLuxError)(error));
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
async updateWhere(data) {
|
|
318
|
-
if (this.conditions.length === 0) {
|
|
319
|
-
return (0, utils_1.err)('MISSING_WHERE', 'updateWhere requires at least one where() condition');
|
|
320
|
-
}
|
|
321
|
-
try {
|
|
322
334
|
const args = [this.name, 'SET'];
|
|
323
|
-
for (const [k, v] of Object.entries(
|
|
335
|
+
for (const [k, v] of Object.entries(patch)) {
|
|
324
336
|
args.push(k, String(v));
|
|
325
337
|
}
|
|
326
338
|
args.push('WHERE');
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
339
|
+
if (hasExplicitId) {
|
|
340
|
+
args.push('id', '=', String(idOrData));
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
for (let i = 0; i < this.conditions.length; i++) {
|
|
344
|
+
const cond = this.conditions[i];
|
|
345
|
+
args.push(cond.field, cond.op, String(cond.value));
|
|
346
|
+
if (i < this.conditions.length - 1) {
|
|
347
|
+
args.push('AND');
|
|
348
|
+
}
|
|
332
349
|
}
|
|
333
350
|
}
|
|
334
351
|
const result = await this.client.call('TUPDATE', ...args);
|
|
@@ -340,6 +357,21 @@ class TableQueryBuilder {
|
|
|
340
357
|
}
|
|
341
358
|
async delete(...ids) {
|
|
342
359
|
try {
|
|
360
|
+
if (ids.length === 0) {
|
|
361
|
+
if (this.conditions.length === 0) {
|
|
362
|
+
return (0, utils_1.err)('MISSING_WHERE', 'delete requires at least one filter');
|
|
363
|
+
}
|
|
364
|
+
const args = ['FROM', this.name, 'WHERE'];
|
|
365
|
+
for (let i = 0; i < this.conditions.length; i++) {
|
|
366
|
+
const cond = this.conditions[i];
|
|
367
|
+
args.push(cond.field, cond.op, String(cond.value));
|
|
368
|
+
if (i < this.conditions.length - 1) {
|
|
369
|
+
args.push('AND');
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const result = await this.client.call('TDELETE', ...args);
|
|
373
|
+
return (0, utils_1.ok)(Number(result) || 0);
|
|
374
|
+
}
|
|
343
375
|
let deleted = 0;
|
|
344
376
|
for (const id of ids) {
|
|
345
377
|
const result = await this.client.call('TDELETE', 'FROM', this.name, 'WHERE', 'id', '=', String(id));
|
|
@@ -351,26 +383,6 @@ class TableQueryBuilder {
|
|
|
351
383
|
return (0, utils_1.err)('TDELETE_ERROR', `Failed to delete from '${this.name}'`, (0, utils_1.toLuxError)(error));
|
|
352
384
|
}
|
|
353
385
|
}
|
|
354
|
-
async deleteWhere() {
|
|
355
|
-
if (this.conditions.length === 0) {
|
|
356
|
-
return (0, utils_1.err)('MISSING_WHERE', 'deleteWhere requires at least one where() condition');
|
|
357
|
-
}
|
|
358
|
-
try {
|
|
359
|
-
const args = ['FROM', this.name, 'WHERE'];
|
|
360
|
-
for (let i = 0; i < this.conditions.length; i++) {
|
|
361
|
-
const cond = this.conditions[i];
|
|
362
|
-
args.push(cond.field, cond.op, String(cond.value));
|
|
363
|
-
if (i < this.conditions.length - 1) {
|
|
364
|
-
args.push('AND');
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
const result = await this.client.call('TDELETE', ...args);
|
|
368
|
-
return (0, utils_1.ok)(Number(result) || 0);
|
|
369
|
-
}
|
|
370
|
-
catch (error) {
|
|
371
|
-
return (0, utils_1.err)('TDELETE_ERROR', `Failed to delete from '${this.name}'`, (0, utils_1.toLuxError)(error));
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
386
|
subscribe() {
|
|
375
387
|
if (this.similarityClause) {
|
|
376
388
|
return new TableSubscription(this.client, this.name, (extra) => this.buildSelectArgs(extra), {
|