@ragable/sdk 0.0.3 → 0.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/dist/index.d.mts +383 -1
- package/dist/index.d.ts +383 -1
- package/dist/index.js +769 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +752 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,14 +23,30 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
23
23
|
var index_exports = {};
|
|
24
24
|
__export(index_exports, {
|
|
25
25
|
AgentsClient: () => AgentsClient,
|
|
26
|
+
PostgrestDeleteBuilder: () => PostgrestDeleteBuilder,
|
|
27
|
+
PostgrestInsertBuilder: () => PostgrestInsertBuilder,
|
|
28
|
+
PostgrestSelectBuilder: () => PostgrestSelectBuilder,
|
|
29
|
+
PostgrestTableApi: () => PostgrestTableApi,
|
|
30
|
+
PostgrestUpdateBuilder: () => PostgrestUpdateBuilder,
|
|
26
31
|
Ragable: () => Ragable,
|
|
32
|
+
RagableBrowser: () => RagableBrowser,
|
|
33
|
+
RagableBrowserAgentsClient: () => RagableBrowserAgentsClient,
|
|
34
|
+
RagableBrowserAuthClient: () => RagableBrowserAuthClient,
|
|
35
|
+
RagableBrowserDatabaseClient: () => RagableBrowserDatabaseClient,
|
|
27
36
|
RagableError: () => RagableError,
|
|
28
37
|
RagableRequestClient: () => RagableRequestClient,
|
|
29
38
|
ShiftClient: () => ShiftClient,
|
|
39
|
+
asPostgrestResponse: () => asPostgrestResponse,
|
|
40
|
+
createBrowserClient: () => createBrowserClient,
|
|
30
41
|
createClient: () => createClient,
|
|
31
42
|
createRagPipeline: () => createRagPipeline,
|
|
43
|
+
createRagableBrowserClient: () => createRagableBrowserClient,
|
|
44
|
+
createRagableServerClient: () => createRagableServerClient,
|
|
32
45
|
extractErrorMessage: () => extractErrorMessage,
|
|
33
|
-
formatRetrievalContext: () => formatRetrievalContext
|
|
46
|
+
formatRetrievalContext: () => formatRetrievalContext,
|
|
47
|
+
normalizeBrowserApiBase: () => normalizeBrowserApiBase,
|
|
48
|
+
parseSseDataLine: () => parseSseDataLine,
|
|
49
|
+
readSseStream: () => readSseStream
|
|
34
50
|
});
|
|
35
51
|
module.exports = __toCommonJS(index_exports);
|
|
36
52
|
|
|
@@ -255,6 +271,74 @@ function toArrayBuffer(value) {
|
|
|
255
271
|
return copy.buffer;
|
|
256
272
|
}
|
|
257
273
|
|
|
274
|
+
// src/sse.ts
|
|
275
|
+
async function parseMaybeJsonBody(response) {
|
|
276
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
277
|
+
if (contentType.includes("application/json")) {
|
|
278
|
+
try {
|
|
279
|
+
return await response.json();
|
|
280
|
+
} catch {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
return await response.text();
|
|
286
|
+
} catch {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function parseSseDataLine(line) {
|
|
291
|
+
const dataPrefix = "data: ";
|
|
292
|
+
if (!line.startsWith(dataPrefix)) {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
const json = line.slice(dataPrefix.length).trim();
|
|
296
|
+
if (json.length === 0 || json === "[DONE]") {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
return JSON.parse(json);
|
|
301
|
+
} catch {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async function* readSseStream(body) {
|
|
306
|
+
const reader = body.getReader();
|
|
307
|
+
const decoder = new TextDecoder();
|
|
308
|
+
let buffer = "";
|
|
309
|
+
try {
|
|
310
|
+
while (true) {
|
|
311
|
+
const { done, value } = await reader.read();
|
|
312
|
+
if (done) {
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
buffer += decoder.decode(value, { stream: true });
|
|
316
|
+
let boundary = buffer.indexOf("\n\n");
|
|
317
|
+
while (boundary !== -1) {
|
|
318
|
+
const block = buffer.slice(0, boundary);
|
|
319
|
+
buffer = buffer.slice(boundary + 2);
|
|
320
|
+
for (const line of block.split("\n")) {
|
|
321
|
+
const evt = parseSseDataLine(line);
|
|
322
|
+
if (evt) {
|
|
323
|
+
yield evt;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
boundary = buffer.indexOf("\n\n");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
if (buffer.trim().length > 0) {
|
|
330
|
+
for (const line of buffer.split("\n")) {
|
|
331
|
+
const evt = parseSseDataLine(line);
|
|
332
|
+
if (evt) {
|
|
333
|
+
yield evt;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
} finally {
|
|
338
|
+
reader.releaseLock();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
258
342
|
// src/agents.ts
|
|
259
343
|
var AgentsClient = class {
|
|
260
344
|
constructor(client) {
|
|
@@ -298,72 +382,655 @@ var AgentsClient = class {
|
|
|
298
382
|
if (!body) {
|
|
299
383
|
return;
|
|
300
384
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
385
|
+
yield* readSseStream(body);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
// src/browser-postgrest.ts
|
|
390
|
+
function assertIdent(name, ctx) {
|
|
391
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
392
|
+
throw new RagableError(
|
|
393
|
+
`Invalid ${ctx} identifier "${name}" (use letters, numbers, underscore)`,
|
|
394
|
+
400,
|
|
395
|
+
null
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function quoteIdent(name) {
|
|
400
|
+
assertIdent(name, "column");
|
|
401
|
+
return `"${name}"`;
|
|
402
|
+
}
|
|
403
|
+
var OP_SQL = {
|
|
404
|
+
eq: "=",
|
|
405
|
+
neq: "<>",
|
|
406
|
+
gt: ">",
|
|
407
|
+
gte: ">=",
|
|
408
|
+
lt: "<",
|
|
409
|
+
lte: "<=",
|
|
410
|
+
like: "LIKE",
|
|
411
|
+
ilike: "ILIKE"
|
|
412
|
+
};
|
|
413
|
+
async function asPostgrestResponse(fn) {
|
|
414
|
+
try {
|
|
415
|
+
const data = await fn();
|
|
416
|
+
return { data, error: null };
|
|
417
|
+
} catch (e) {
|
|
418
|
+
const err = e instanceof RagableError ? e : new RagableError(e.message, 500, null);
|
|
419
|
+
return { data: null, error: err };
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
function buildWhere(filters, params) {
|
|
423
|
+
if (filters.length === 0) return { clause: "", nextIdx: 1 };
|
|
424
|
+
const parts = [];
|
|
425
|
+
let i = params.length;
|
|
426
|
+
for (const f of filters) {
|
|
427
|
+
assertIdent(f.column, "filter");
|
|
428
|
+
i += 1;
|
|
429
|
+
parts.push(`${quoteIdent(f.column)} ${OP_SQL[f.op]} $${i}`);
|
|
430
|
+
params.push(f.value);
|
|
431
|
+
}
|
|
432
|
+
return { clause: ` WHERE ${parts.join(" AND ")}`, nextIdx: i };
|
|
433
|
+
}
|
|
434
|
+
var PostgrestSelectBuilder = class {
|
|
435
|
+
constructor(run, databaseInstanceId, table, columns) {
|
|
436
|
+
this.run = run;
|
|
437
|
+
this.databaseInstanceId = databaseInstanceId;
|
|
438
|
+
this.table = table;
|
|
439
|
+
this.columns = columns;
|
|
440
|
+
__publicField(this, "filters", []);
|
|
441
|
+
__publicField(this, "_limit");
|
|
442
|
+
__publicField(this, "_order");
|
|
443
|
+
assertIdent(table, "table");
|
|
444
|
+
}
|
|
445
|
+
eq(column, value) {
|
|
446
|
+
this.filters.push({ op: "eq", column, value });
|
|
447
|
+
return this;
|
|
448
|
+
}
|
|
449
|
+
neq(column, value) {
|
|
450
|
+
this.filters.push({ op: "neq", column, value });
|
|
451
|
+
return this;
|
|
452
|
+
}
|
|
453
|
+
gt(column, value) {
|
|
454
|
+
this.filters.push({ op: "gt", column, value });
|
|
455
|
+
return this;
|
|
456
|
+
}
|
|
457
|
+
gte(column, value) {
|
|
458
|
+
this.filters.push({ op: "gte", column, value });
|
|
459
|
+
return this;
|
|
460
|
+
}
|
|
461
|
+
lt(column, value) {
|
|
462
|
+
this.filters.push({ op: "lt", column, value });
|
|
463
|
+
return this;
|
|
464
|
+
}
|
|
465
|
+
lte(column, value) {
|
|
466
|
+
this.filters.push({ op: "lte", column, value });
|
|
467
|
+
return this;
|
|
468
|
+
}
|
|
469
|
+
like(column, value) {
|
|
470
|
+
this.filters.push({ op: "like", column, value });
|
|
471
|
+
return this;
|
|
472
|
+
}
|
|
473
|
+
ilike(column, value) {
|
|
474
|
+
this.filters.push({ op: "ilike", column, value });
|
|
475
|
+
return this;
|
|
476
|
+
}
|
|
477
|
+
limit(n) {
|
|
478
|
+
this._limit = n;
|
|
479
|
+
return this;
|
|
480
|
+
}
|
|
481
|
+
order(column, options) {
|
|
482
|
+
this._order = { column, ascending: options?.ascending !== false };
|
|
483
|
+
return this;
|
|
484
|
+
}
|
|
485
|
+
/** @param includeUserLimit when false, omit `.limit()` (for `.single()` / `.maybeSingle()`). */
|
|
486
|
+
buildSelectCore(params, includeUserLimit) {
|
|
487
|
+
const tbl = quoteIdent(this.table);
|
|
488
|
+
const { clause } = buildWhere(this.filters, params);
|
|
489
|
+
let sql = `SELECT ${this.columns} FROM ${tbl}${clause}`;
|
|
490
|
+
if (this._order) {
|
|
491
|
+
sql += ` ORDER BY ${quoteIdent(this._order.column)} ${this._order.ascending ? "ASC" : "DESC"}`;
|
|
492
|
+
}
|
|
493
|
+
if (includeUserLimit && this._limit != null) {
|
|
494
|
+
sql += ` LIMIT ${Math.max(0, Math.floor(this._limit))}`;
|
|
495
|
+
}
|
|
496
|
+
return sql;
|
|
497
|
+
}
|
|
498
|
+
then(onfulfilled, onrejected) {
|
|
499
|
+
return this.executeMany().then(onfulfilled, onrejected);
|
|
500
|
+
}
|
|
501
|
+
async executeMany() {
|
|
502
|
+
return asPostgrestResponse(async () => {
|
|
503
|
+
const params = [];
|
|
504
|
+
const sql = this.buildSelectCore(params, true);
|
|
505
|
+
const res = await this.run({
|
|
506
|
+
databaseInstanceId: this.databaseInstanceId,
|
|
507
|
+
sql,
|
|
508
|
+
params,
|
|
509
|
+
readOnly: true
|
|
510
|
+
});
|
|
511
|
+
return res.rows;
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
async single() {
|
|
515
|
+
return asPostgrestResponse(async () => {
|
|
516
|
+
const params = [];
|
|
517
|
+
const base = this.buildSelectCore(params, false);
|
|
518
|
+
const sql = `${base} LIMIT 2`;
|
|
519
|
+
const res = await this.run({
|
|
520
|
+
databaseInstanceId: this.databaseInstanceId,
|
|
521
|
+
sql,
|
|
522
|
+
params,
|
|
523
|
+
readOnly: true
|
|
524
|
+
});
|
|
525
|
+
if (res.rows.length === 0) {
|
|
526
|
+
throw new RagableError("JSON object requested, multiple (or no) rows returned", 406, {
|
|
527
|
+
code: "PGRST116"
|
|
528
|
+
});
|
|
323
529
|
}
|
|
324
|
-
if (
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
530
|
+
if (res.rows.length > 1) {
|
|
531
|
+
throw new RagableError("JSON object requested, multiple (or no) rows returned", 406, {
|
|
532
|
+
code: "PGRST116"
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
return res.rows[0];
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
async maybeSingle() {
|
|
539
|
+
return asPostgrestResponse(async () => {
|
|
540
|
+
const params = [];
|
|
541
|
+
const base = this.buildSelectCore(params, false);
|
|
542
|
+
const sql = `${base} LIMIT 2`;
|
|
543
|
+
const res = await this.run({
|
|
544
|
+
databaseInstanceId: this.databaseInstanceId,
|
|
545
|
+
sql,
|
|
546
|
+
params,
|
|
547
|
+
readOnly: true
|
|
548
|
+
});
|
|
549
|
+
if (res.rows.length > 1) {
|
|
550
|
+
throw new RagableError("JSON object requested, multiple (or no) rows returned", 406, {
|
|
551
|
+
code: "PGRST116"
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
return res.rows[0] ?? null;
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
var PostgrestInsertBuilder = class {
|
|
559
|
+
constructor(run, databaseInstanceId, table, rows) {
|
|
560
|
+
this.run = run;
|
|
561
|
+
this.databaseInstanceId = databaseInstanceId;
|
|
562
|
+
this.table = table;
|
|
563
|
+
this.rows = rows;
|
|
564
|
+
__publicField(this, "returning", "*");
|
|
565
|
+
assertIdent(table, "table");
|
|
566
|
+
}
|
|
567
|
+
select(columns = "*") {
|
|
568
|
+
this.returning = columns;
|
|
569
|
+
return this;
|
|
570
|
+
}
|
|
571
|
+
then(onfulfilled, onrejected) {
|
|
572
|
+
return this.execute().then(onfulfilled, onrejected);
|
|
573
|
+
}
|
|
574
|
+
async execute() {
|
|
575
|
+
return asPostgrestResponse(async () => {
|
|
576
|
+
if (this.rows.length === 0) return [];
|
|
577
|
+
const keys = Object.keys(this.rows[0]);
|
|
578
|
+
for (const k of keys) assertIdent(k, "column");
|
|
579
|
+
const tbl = quoteIdent(this.table);
|
|
580
|
+
const params = [];
|
|
581
|
+
const valueGroups = [];
|
|
582
|
+
for (const row of this.rows) {
|
|
583
|
+
const placeholders = [];
|
|
584
|
+
for (const k of keys) {
|
|
585
|
+
params.push(row[k]);
|
|
586
|
+
placeholders.push(`$${params.length}`);
|
|
330
587
|
}
|
|
588
|
+
valueGroups.push(`(${placeholders.join(", ")})`);
|
|
331
589
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
590
|
+
const cols = keys.map(quoteIdent).join(", ");
|
|
591
|
+
const sql = `INSERT INTO ${tbl} (${cols}) VALUES ${valueGroups.join(", ")} RETURNING ${this.returning}`;
|
|
592
|
+
const res = await this.run({
|
|
593
|
+
databaseInstanceId: this.databaseInstanceId,
|
|
594
|
+
sql,
|
|
595
|
+
params,
|
|
596
|
+
readOnly: false
|
|
597
|
+
});
|
|
598
|
+
return res.rows;
|
|
599
|
+
});
|
|
335
600
|
}
|
|
336
601
|
};
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
602
|
+
var PostgrestUpdateBuilder = class {
|
|
603
|
+
constructor(run, databaseInstanceId, table, patch) {
|
|
604
|
+
this.run = run;
|
|
605
|
+
this.databaseInstanceId = databaseInstanceId;
|
|
606
|
+
this.table = table;
|
|
607
|
+
this.patch = patch;
|
|
608
|
+
__publicField(this, "filters", []);
|
|
609
|
+
__publicField(this, "returning", "*");
|
|
610
|
+
assertIdent(table, "table");
|
|
345
611
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
612
|
+
eq(column, value) {
|
|
613
|
+
this.filters.push({ op: "eq", column, value });
|
|
614
|
+
return this;
|
|
615
|
+
}
|
|
616
|
+
select(columns = "*") {
|
|
617
|
+
this.returning = columns;
|
|
618
|
+
return this;
|
|
619
|
+
}
|
|
620
|
+
then(onfulfilled, onrejected) {
|
|
621
|
+
return this.execute().then(onfulfilled, onrejected);
|
|
622
|
+
}
|
|
623
|
+
async execute() {
|
|
624
|
+
return asPostgrestResponse(async () => {
|
|
625
|
+
const keys = Object.keys(this.patch);
|
|
626
|
+
if (keys.length === 0) {
|
|
627
|
+
throw new RagableError("Empty update payload", 400, null);
|
|
628
|
+
}
|
|
629
|
+
for (const k of keys) assertIdent(k, "column");
|
|
630
|
+
if (this.filters.length === 0) {
|
|
631
|
+
throw new RagableError(
|
|
632
|
+
"UPDATE requires a filter (e.g. .eq('id', value)) \u2014 refusing unscoped update",
|
|
633
|
+
400,
|
|
634
|
+
null
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
const params = [];
|
|
638
|
+
const sets = [];
|
|
639
|
+
for (const k of keys) {
|
|
640
|
+
params.push(this.patch[k]);
|
|
641
|
+
sets.push(`${quoteIdent(k)} = $${params.length}`);
|
|
642
|
+
}
|
|
643
|
+
const { clause } = buildWhere(this.filters, params);
|
|
644
|
+
const tbl = quoteIdent(this.table);
|
|
645
|
+
const sql = `UPDATE ${tbl} SET ${sets.join(", ")}${clause} RETURNING ${this.returning}`;
|
|
646
|
+
const res = await this.run({
|
|
647
|
+
databaseInstanceId: this.databaseInstanceId,
|
|
648
|
+
sql,
|
|
649
|
+
params,
|
|
650
|
+
readOnly: false
|
|
651
|
+
});
|
|
652
|
+
return res.rows;
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
var PostgrestDeleteBuilder = class {
|
|
657
|
+
constructor(run, databaseInstanceId, table) {
|
|
658
|
+
this.run = run;
|
|
659
|
+
this.databaseInstanceId = databaseInstanceId;
|
|
660
|
+
this.table = table;
|
|
661
|
+
__publicField(this, "filters", []);
|
|
662
|
+
__publicField(this, "returning", "*");
|
|
663
|
+
assertIdent(table, "table");
|
|
664
|
+
}
|
|
665
|
+
eq(column, value) {
|
|
666
|
+
this.filters.push({ op: "eq", column, value });
|
|
667
|
+
return this;
|
|
668
|
+
}
|
|
669
|
+
select(columns = "*") {
|
|
670
|
+
this.returning = columns;
|
|
671
|
+
return this;
|
|
672
|
+
}
|
|
673
|
+
then(onfulfilled, onrejected) {
|
|
674
|
+
return this.execute().then(onfulfilled, onrejected);
|
|
675
|
+
}
|
|
676
|
+
async execute() {
|
|
677
|
+
return asPostgrestResponse(async () => {
|
|
678
|
+
if (this.filters.length === 0) {
|
|
679
|
+
throw new RagableError(
|
|
680
|
+
"DELETE requires a filter (e.g. .eq('id', value)) \u2014 refusing unscoped delete",
|
|
681
|
+
400,
|
|
682
|
+
null
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
const params = [];
|
|
686
|
+
const { clause } = buildWhere(this.filters, params);
|
|
687
|
+
const tbl = quoteIdent(this.table);
|
|
688
|
+
const sql = `DELETE FROM ${tbl}${clause} RETURNING ${this.returning}`;
|
|
689
|
+
const res = await this.run({
|
|
690
|
+
databaseInstanceId: this.databaseInstanceId,
|
|
691
|
+
sql,
|
|
692
|
+
params,
|
|
693
|
+
readOnly: false
|
|
694
|
+
});
|
|
695
|
+
return res.rows;
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
var PostgrestTableApi = class {
|
|
700
|
+
constructor(run, databaseInstanceId, table) {
|
|
701
|
+
this.run = run;
|
|
702
|
+
this.databaseInstanceId = databaseInstanceId;
|
|
703
|
+
this.table = table;
|
|
704
|
+
}
|
|
705
|
+
select(columns = "*") {
|
|
706
|
+
return new PostgrestSelectBuilder(
|
|
707
|
+
this.run,
|
|
708
|
+
this.databaseInstanceId,
|
|
709
|
+
this.table,
|
|
710
|
+
columns
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
insert(values) {
|
|
714
|
+
const rows = Array.isArray(values) ? values : [values];
|
|
715
|
+
return new PostgrestInsertBuilder(
|
|
716
|
+
this.run,
|
|
717
|
+
this.databaseInstanceId,
|
|
718
|
+
this.table,
|
|
719
|
+
rows
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
update(patch) {
|
|
723
|
+
return new PostgrestUpdateBuilder(
|
|
724
|
+
this.run,
|
|
725
|
+
this.databaseInstanceId,
|
|
726
|
+
this.table,
|
|
727
|
+
patch
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
delete() {
|
|
731
|
+
return new PostgrestDeleteBuilder(
|
|
732
|
+
this.run,
|
|
733
|
+
this.databaseInstanceId,
|
|
734
|
+
this.table
|
|
735
|
+
);
|
|
350
736
|
}
|
|
737
|
+
};
|
|
738
|
+
|
|
739
|
+
// src/browser.ts
|
|
740
|
+
function normalizeBrowserApiBase(baseUrl) {
|
|
741
|
+
return (baseUrl ?? "http://localhost:8080/api").replace(/\/+$/, "");
|
|
351
742
|
}
|
|
352
|
-
function
|
|
353
|
-
const
|
|
354
|
-
if (!
|
|
355
|
-
|
|
743
|
+
function requireAuthGroupId(options) {
|
|
744
|
+
const id = options.authGroupId?.trim();
|
|
745
|
+
if (!id) {
|
|
746
|
+
throw new Error(
|
|
747
|
+
"authGroupId is required for auth and database methods on the browser client"
|
|
748
|
+
);
|
|
356
749
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
750
|
+
return id;
|
|
751
|
+
}
|
|
752
|
+
async function requireAccessToken(options) {
|
|
753
|
+
const getter = options.getAccessToken;
|
|
754
|
+
if (!getter) {
|
|
755
|
+
throw new Error(
|
|
756
|
+
"getAccessToken is required for this call (return the end-user access JWT)"
|
|
757
|
+
);
|
|
360
758
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
759
|
+
const token = await getter();
|
|
760
|
+
if (!token?.trim()) {
|
|
761
|
+
throw new Error("getAccessToken returned no token");
|
|
762
|
+
}
|
|
763
|
+
return token.trim();
|
|
764
|
+
}
|
|
765
|
+
async function parseJsonOrThrow(response) {
|
|
766
|
+
const payload = await parseMaybeJsonBody(response);
|
|
767
|
+
if (!response.ok) {
|
|
768
|
+
const message = extractErrorMessage(payload, response.statusText);
|
|
769
|
+
throw new RagableError(message, response.status, payload);
|
|
770
|
+
}
|
|
771
|
+
return payload;
|
|
772
|
+
}
|
|
773
|
+
function parseExpiresInSeconds(expiresIn) {
|
|
774
|
+
const s = expiresIn.trim().toLowerCase();
|
|
775
|
+
const m = /^(\d+)([smhd])?$/.exec(s);
|
|
776
|
+
if (m) {
|
|
777
|
+
const n = Number(m[1]);
|
|
778
|
+
const u = m[2] ?? "s";
|
|
779
|
+
const mult = u === "s" ? 1 : u === "m" ? 60 : u === "h" ? 3600 : u === "d" ? 86400 : 1;
|
|
780
|
+
return n * mult;
|
|
781
|
+
}
|
|
782
|
+
const asNum = Number(s);
|
|
783
|
+
return Number.isFinite(asNum) ? asNum : 0;
|
|
784
|
+
}
|
|
785
|
+
function toSupabaseSession(s) {
|
|
786
|
+
return {
|
|
787
|
+
access_token: s.accessToken,
|
|
788
|
+
refresh_token: s.refreshToken,
|
|
789
|
+
expires_in: parseExpiresInSeconds(s.expiresIn),
|
|
790
|
+
token_type: "bearer",
|
|
791
|
+
user: s.user
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
var RagableBrowserAuthClient = class {
|
|
795
|
+
constructor(options) {
|
|
796
|
+
this.options = options;
|
|
797
|
+
}
|
|
798
|
+
get fetchImpl() {
|
|
799
|
+
return this.options.fetch ?? fetch;
|
|
800
|
+
}
|
|
801
|
+
toUrl(path) {
|
|
802
|
+
return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith("/") ? path : `/${path}`}`;
|
|
803
|
+
}
|
|
804
|
+
baseHeaders(json) {
|
|
805
|
+
const h = new Headers(this.options.headers);
|
|
806
|
+
if (json) {
|
|
807
|
+
h.set("Content-Type", "application/json");
|
|
808
|
+
}
|
|
809
|
+
return h;
|
|
810
|
+
}
|
|
811
|
+
authPrefix() {
|
|
812
|
+
const gid = requireAuthGroupId(this.options);
|
|
813
|
+
return `/auth-groups/${gid}/auth`;
|
|
814
|
+
}
|
|
815
|
+
/** Supabase: `signUp` → `{ data: { user, session }, error }` */
|
|
816
|
+
async signUp(credentials) {
|
|
817
|
+
return asPostgrestResponse(async () => {
|
|
818
|
+
const name = typeof credentials.options?.data?.name === "string" ? credentials.options.data.name : void 0;
|
|
819
|
+
const session = await this.register({
|
|
820
|
+
email: credentials.email,
|
|
821
|
+
password: credentials.password,
|
|
822
|
+
name
|
|
823
|
+
});
|
|
824
|
+
return { user: session.user, session: toSupabaseSession(session) };
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
/** Supabase: `signInWithPassword` */
|
|
828
|
+
async signInWithPassword(credentials) {
|
|
829
|
+
return asPostgrestResponse(async () => {
|
|
830
|
+
const session = await this.login(credentials);
|
|
831
|
+
return { user: session.user, session: toSupabaseSession(session) };
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
/** Supabase: `refreshSession` */
|
|
835
|
+
async refreshSession(refreshToken) {
|
|
836
|
+
return asPostgrestResponse(async () => {
|
|
837
|
+
const tokens = await this.refresh({ refreshToken });
|
|
838
|
+
const me = await this.getUserFromToken(tokens.accessToken);
|
|
839
|
+
const session = {
|
|
840
|
+
access_token: tokens.accessToken,
|
|
841
|
+
refresh_token: tokens.refreshToken,
|
|
842
|
+
expires_in: parseExpiresInSeconds(tokens.expiresIn),
|
|
843
|
+
token_type: "bearer",
|
|
844
|
+
user: me.user
|
|
845
|
+
};
|
|
846
|
+
return { session, user: me.user };
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
/** Supabase: `getUser()` — needs `getAccessToken` on the client */
|
|
850
|
+
async getUser() {
|
|
851
|
+
return asPostgrestResponse(() => this.getMe());
|
|
852
|
+
}
|
|
853
|
+
/** Supabase: `updateUser` */
|
|
854
|
+
async updateUser(attributes) {
|
|
855
|
+
return asPostgrestResponse(
|
|
856
|
+
() => this.updateMe({
|
|
857
|
+
password: attributes.password,
|
|
858
|
+
name: attributes.data?.name
|
|
859
|
+
})
|
|
860
|
+
);
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* Supabase/Firebase: no server call — clear tokens in your app.
|
|
864
|
+
* Returns `{ error: null }` for API compatibility.
|
|
865
|
+
*/
|
|
866
|
+
async signOut(_options) {
|
|
867
|
+
return { error: null };
|
|
868
|
+
}
|
|
869
|
+
async getUserFromToken(accessToken) {
|
|
870
|
+
const headers = this.baseHeaders(false);
|
|
871
|
+
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
872
|
+
const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/me`, {
|
|
873
|
+
method: "GET",
|
|
874
|
+
headers
|
|
875
|
+
});
|
|
876
|
+
return parseJsonOrThrow(response);
|
|
877
|
+
}
|
|
878
|
+
async register(body) {
|
|
879
|
+
const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/register`, {
|
|
880
|
+
method: "POST",
|
|
881
|
+
headers: this.baseHeaders(true),
|
|
882
|
+
body: JSON.stringify(body)
|
|
883
|
+
});
|
|
884
|
+
return parseJsonOrThrow(response);
|
|
365
885
|
}
|
|
886
|
+
async login(body) {
|
|
887
|
+
const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/login`, {
|
|
888
|
+
method: "POST",
|
|
889
|
+
headers: this.baseHeaders(true),
|
|
890
|
+
body: JSON.stringify(body)
|
|
891
|
+
});
|
|
892
|
+
return parseJsonOrThrow(response);
|
|
893
|
+
}
|
|
894
|
+
async refresh(body) {
|
|
895
|
+
const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/refresh`, {
|
|
896
|
+
method: "POST",
|
|
897
|
+
headers: this.baseHeaders(true),
|
|
898
|
+
body: JSON.stringify(body)
|
|
899
|
+
});
|
|
900
|
+
return parseJsonOrThrow(response);
|
|
901
|
+
}
|
|
902
|
+
async getMe() {
|
|
903
|
+
const token = await requireAccessToken(this.options);
|
|
904
|
+
const headers = this.baseHeaders(false);
|
|
905
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
906
|
+
const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/me`, {
|
|
907
|
+
method: "GET",
|
|
908
|
+
headers
|
|
909
|
+
});
|
|
910
|
+
return parseJsonOrThrow(response);
|
|
911
|
+
}
|
|
912
|
+
async updateMe(body) {
|
|
913
|
+
const token = await requireAccessToken(this.options);
|
|
914
|
+
const headers = this.baseHeaders(true);
|
|
915
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
916
|
+
const response = await this.fetchImpl(`${this.toUrl(this.authPrefix())}/me`, {
|
|
917
|
+
method: "PATCH",
|
|
918
|
+
headers,
|
|
919
|
+
body: JSON.stringify(body)
|
|
920
|
+
});
|
|
921
|
+
return parseJsonOrThrow(response);
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
var RagableBrowserDatabaseClient = class {
|
|
925
|
+
constructor(options) {
|
|
926
|
+
this.options = options;
|
|
927
|
+
}
|
|
928
|
+
get fetchImpl() {
|
|
929
|
+
return this.options.fetch ?? fetch;
|
|
930
|
+
}
|
|
931
|
+
toUrl(path) {
|
|
932
|
+
return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith("/") ? path : `/${path}`}`;
|
|
933
|
+
}
|
|
934
|
+
async query(params) {
|
|
935
|
+
const gid = requireAuthGroupId(this.options);
|
|
936
|
+
const token = await requireAccessToken(this.options);
|
|
937
|
+
const headers = this.baseHeaders();
|
|
938
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
939
|
+
headers.set("Content-Type", "application/json");
|
|
940
|
+
const response = await this.fetchImpl(
|
|
941
|
+
this.toUrl(`/auth-groups/${gid}/data/query`),
|
|
942
|
+
{
|
|
943
|
+
method: "POST",
|
|
944
|
+
headers,
|
|
945
|
+
body: JSON.stringify({
|
|
946
|
+
databaseInstanceId: params.databaseInstanceId,
|
|
947
|
+
sql: params.sql,
|
|
948
|
+
...params.params !== void 0 ? { params: params.params } : {},
|
|
949
|
+
...params.readOnly === false ? { readOnly: false } : {},
|
|
950
|
+
...params.timeoutMs !== void 0 ? { timeoutMs: params.timeoutMs } : {},
|
|
951
|
+
...params.rowLimit !== void 0 ? { rowLimit: params.rowLimit } : {}
|
|
952
|
+
})
|
|
953
|
+
}
|
|
954
|
+
);
|
|
955
|
+
return parseJsonOrThrow(response);
|
|
956
|
+
}
|
|
957
|
+
baseHeaders() {
|
|
958
|
+
return new Headers(this.options.headers);
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
var RagableBrowserAgentsClient = class {
|
|
962
|
+
constructor(options) {
|
|
963
|
+
this.options = options;
|
|
964
|
+
}
|
|
965
|
+
get fetchImpl() {
|
|
966
|
+
return this.options.fetch ?? fetch;
|
|
967
|
+
}
|
|
968
|
+
toUrl(path) {
|
|
969
|
+
return `${normalizeBrowserApiBase(this.options.baseUrl)}${path.startsWith("/") ? path : `/${path}`}`;
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* Stream agent execution as SSE (`POST /public/organizations/:orgId/agents/:agentId/chat/stream`).
|
|
973
|
+
*/
|
|
974
|
+
async *chatStream(agentId, params) {
|
|
975
|
+
const orgId = this.options.organizationId;
|
|
976
|
+
const body = {
|
|
977
|
+
message: params.message,
|
|
978
|
+
...params.history !== void 0 ? { history: params.history } : {},
|
|
979
|
+
...params.triggerSubtype !== void 0 ? { triggerSubtype: params.triggerSubtype } : {},
|
|
980
|
+
...params.triggerNodeId !== void 0 ? { triggerNodeId: params.triggerNodeId } : {}
|
|
981
|
+
};
|
|
982
|
+
const headers = new Headers(this.options.headers);
|
|
983
|
+
headers.set("Content-Type", "application/json");
|
|
984
|
+
const response = await this.fetchImpl(
|
|
985
|
+
this.toUrl(`/public/organizations/${orgId}/agents/${agentId}/chat/stream`),
|
|
986
|
+
{
|
|
987
|
+
method: "POST",
|
|
988
|
+
headers,
|
|
989
|
+
body: JSON.stringify(body)
|
|
990
|
+
}
|
|
991
|
+
);
|
|
992
|
+
if (!response.ok) {
|
|
993
|
+
const payload = await parseMaybeJsonBody(response);
|
|
994
|
+
const message = extractErrorMessage(payload, response.statusText);
|
|
995
|
+
throw new RagableError(message, response.status, payload);
|
|
996
|
+
}
|
|
997
|
+
const streamBody = response.body;
|
|
998
|
+
if (!streamBody) {
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
yield* readSseStream(streamBody);
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
var RagableBrowser = class {
|
|
1005
|
+
constructor(options) {
|
|
1006
|
+
__publicField(this, "agents");
|
|
1007
|
+
__publicField(this, "auth");
|
|
1008
|
+
__publicField(this, "database");
|
|
1009
|
+
__publicField(this, "options");
|
|
1010
|
+
this.options = options;
|
|
1011
|
+
this.agents = new RagableBrowserAgentsClient(options);
|
|
1012
|
+
this.auth = new RagableBrowserAuthClient(options);
|
|
1013
|
+
this.database = new RagableBrowserDatabaseClient(options);
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* Supabase-style table API: `.from('items').select().eq('id', 1).single()`.
|
|
1017
|
+
* Pass `databaseInstanceId` here or set `databaseInstanceId` on the client options.
|
|
1018
|
+
*/
|
|
1019
|
+
from(table, databaseInstanceId) {
|
|
1020
|
+
const id = databaseInstanceId?.trim() || this.options.databaseInstanceId?.trim();
|
|
1021
|
+
if (!id) {
|
|
1022
|
+
throw new Error(
|
|
1023
|
+
"RagableBrowser.from() requires databaseInstanceId in client options or as the second argument"
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
const run = (p) => this.database.query(p);
|
|
1027
|
+
return new PostgrestTableApi(run, id, table);
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
function createBrowserClient(options) {
|
|
1031
|
+
return new RagableBrowser(options);
|
|
366
1032
|
}
|
|
1033
|
+
var createRagableBrowserClient = createBrowserClient;
|
|
367
1034
|
|
|
368
1035
|
// src/rag.ts
|
|
369
1036
|
function formatRetrievalContext(results, options = {}) {
|
|
@@ -421,19 +1088,64 @@ var Ragable = class {
|
|
|
421
1088
|
};
|
|
422
1089
|
}
|
|
423
1090
|
};
|
|
424
|
-
function
|
|
1091
|
+
function isServerClientOptions(o) {
|
|
1092
|
+
return typeof o === "object" && o !== null && "apiKey" in o && typeof o.apiKey === "string" && o.apiKey.length > 0;
|
|
1093
|
+
}
|
|
1094
|
+
function createClient(urlOrOptions, browserOptions) {
|
|
1095
|
+
if (typeof urlOrOptions === "string") {
|
|
1096
|
+
if (!browserOptions) {
|
|
1097
|
+
throw new Error(
|
|
1098
|
+
"createClient(url, options) requires options with at least organizationId"
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
const raw = urlOrOptions.trim().replace(/\/+$/, "");
|
|
1102
|
+
const baseUrl = raw.endsWith("/api") ? raw : `${raw}/api`;
|
|
1103
|
+
return createBrowserClient({
|
|
1104
|
+
...browserOptions,
|
|
1105
|
+
baseUrl: normalizeBrowserApiBase(baseUrl)
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1108
|
+
if (isServerClientOptions(urlOrOptions)) {
|
|
1109
|
+
return new Ragable(urlOrOptions);
|
|
1110
|
+
}
|
|
1111
|
+
if (typeof urlOrOptions === "object" && urlOrOptions !== null && "organizationId" in urlOrOptions && typeof urlOrOptions.organizationId === "string") {
|
|
1112
|
+
return createBrowserClient(
|
|
1113
|
+
urlOrOptions
|
|
1114
|
+
);
|
|
1115
|
+
}
|
|
1116
|
+
throw new Error(
|
|
1117
|
+
"createClient(options) requires apiKey (server) or organizationId (browser)"
|
|
1118
|
+
);
|
|
1119
|
+
}
|
|
1120
|
+
function createRagableServerClient(options) {
|
|
425
1121
|
return new Ragable(options);
|
|
426
1122
|
}
|
|
427
1123
|
// Annotate the CommonJS export names for ESM import in node:
|
|
428
1124
|
0 && (module.exports = {
|
|
429
1125
|
AgentsClient,
|
|
1126
|
+
PostgrestDeleteBuilder,
|
|
1127
|
+
PostgrestInsertBuilder,
|
|
1128
|
+
PostgrestSelectBuilder,
|
|
1129
|
+
PostgrestTableApi,
|
|
1130
|
+
PostgrestUpdateBuilder,
|
|
430
1131
|
Ragable,
|
|
1132
|
+
RagableBrowser,
|
|
1133
|
+
RagableBrowserAgentsClient,
|
|
1134
|
+
RagableBrowserAuthClient,
|
|
1135
|
+
RagableBrowserDatabaseClient,
|
|
431
1136
|
RagableError,
|
|
432
1137
|
RagableRequestClient,
|
|
433
1138
|
ShiftClient,
|
|
1139
|
+
asPostgrestResponse,
|
|
1140
|
+
createBrowserClient,
|
|
434
1141
|
createClient,
|
|
435
1142
|
createRagPipeline,
|
|
1143
|
+
createRagableBrowserClient,
|
|
1144
|
+
createRagableServerClient,
|
|
436
1145
|
extractErrorMessage,
|
|
437
|
-
formatRetrievalContext
|
|
1146
|
+
formatRetrievalContext,
|
|
1147
|
+
normalizeBrowserApiBase,
|
|
1148
|
+
parseSseDataLine,
|
|
1149
|
+
readSseStream
|
|
438
1150
|
});
|
|
439
1151
|
//# sourceMappingURL=index.js.map
|