@debros/orama 0.122.4-nightly
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 +21 -0
- package/README.md +665 -0
- package/dist/index.d.ts +1334 -0
- package/dist/index.js +2553 -0
- package/dist/index.js.map +1 -0
- package/package.json +82 -0
- package/src/auth/client.ts +276 -0
- package/src/auth/index.ts +3 -0
- package/src/auth/types.ts +62 -0
- package/src/cache/client.ts +203 -0
- package/src/cache/index.ts +14 -0
- package/src/core/http.ts +541 -0
- package/src/core/index.ts +10 -0
- package/src/core/interfaces/IAuthStrategy.ts +28 -0
- package/src/core/interfaces/IHttpTransport.ts +73 -0
- package/src/core/interfaces/IRetryPolicy.ts +20 -0
- package/src/core/interfaces/IWebSocketClient.ts +60 -0
- package/src/core/interfaces/index.ts +4 -0
- package/src/core/transport/AuthHeaderStrategy.ts +108 -0
- package/src/core/transport/RequestLogger.ts +116 -0
- package/src/core/transport/RequestRetryPolicy.ts +53 -0
- package/src/core/transport/TLSConfiguration.ts +53 -0
- package/src/core/transport/index.ts +4 -0
- package/src/core/ws.ts +246 -0
- package/src/db/client.ts +126 -0
- package/src/db/index.ts +13 -0
- package/src/db/qb.ts +111 -0
- package/src/db/repository.ts +128 -0
- package/src/db/types.ts +67 -0
- package/src/errors.ts +38 -0
- package/src/functions/client.ts +62 -0
- package/src/functions/index.ts +2 -0
- package/src/functions/types.ts +21 -0
- package/src/index.ts +201 -0
- package/src/network/client.ts +119 -0
- package/src/network/index.ts +7 -0
- package/src/pubsub/client.ts +361 -0
- package/src/pubsub/index.ts +12 -0
- package/src/pubsub/types.ts +46 -0
- package/src/storage/client.ts +272 -0
- package/src/storage/index.ts +7 -0
- package/src/utils/codec.ts +68 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/platform.ts +44 -0
- package/src/utils/retry.ts +58 -0
- package/src/vault/auth.ts +98 -0
- package/src/vault/client.ts +197 -0
- package/src/vault/crypto/aes.ts +271 -0
- package/src/vault/crypto/hkdf.ts +42 -0
- package/src/vault/crypto/index.ts +27 -0
- package/src/vault/crypto/shamir.ts +173 -0
- package/src/vault/index.ts +65 -0
- package/src/vault/quorum.ts +16 -0
- package/src/vault/transport/fanout.ts +94 -0
- package/src/vault/transport/guardian.ts +285 -0
- package/src/vault/transport/index.ts +19 -0
- package/src/vault/transport/types.ts +101 -0
- package/src/vault/types.ts +62 -0
package/src/db/client.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { HttpClient } from "../core/http";
|
|
2
|
+
import { QueryBuilder } from "./qb";
|
|
3
|
+
import { Repository } from "./repository";
|
|
4
|
+
import {
|
|
5
|
+
QueryResponse,
|
|
6
|
+
TransactionOp,
|
|
7
|
+
TransactionRequest,
|
|
8
|
+
Entity,
|
|
9
|
+
FindOptions,
|
|
10
|
+
} from "./types";
|
|
11
|
+
|
|
12
|
+
export class DBClient {
|
|
13
|
+
private httpClient: HttpClient;
|
|
14
|
+
|
|
15
|
+
constructor(httpClient: HttpClient) {
|
|
16
|
+
this.httpClient = httpClient;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Execute a write/DDL SQL statement.
|
|
21
|
+
*/
|
|
22
|
+
async exec(
|
|
23
|
+
sql: string,
|
|
24
|
+
args: any[] = []
|
|
25
|
+
): Promise<{ rows_affected: number; last_insert_id?: number }> {
|
|
26
|
+
return this.httpClient.post("/v1/rqlite/exec", { sql, args });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Execute a SELECT query.
|
|
31
|
+
*/
|
|
32
|
+
async query<T = any>(sql: string, args: any[] = []): Promise<T[]> {
|
|
33
|
+
const response = await this.httpClient.post<QueryResponse>(
|
|
34
|
+
"/v1/rqlite/query",
|
|
35
|
+
{ sql, args }
|
|
36
|
+
);
|
|
37
|
+
return response.items || [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Find rows with map-based criteria.
|
|
42
|
+
*/
|
|
43
|
+
async find<T = any>(
|
|
44
|
+
table: string,
|
|
45
|
+
criteria: Record<string, any> = {},
|
|
46
|
+
options: FindOptions = {}
|
|
47
|
+
): Promise<T[]> {
|
|
48
|
+
const response = await this.httpClient.post<QueryResponse>(
|
|
49
|
+
"/v1/rqlite/find",
|
|
50
|
+
{
|
|
51
|
+
table,
|
|
52
|
+
criteria,
|
|
53
|
+
options,
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
return response.items || [];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Find a single row with map-based criteria.
|
|
61
|
+
*/
|
|
62
|
+
async findOne<T = any>(
|
|
63
|
+
table: string,
|
|
64
|
+
criteria: Record<string, any>
|
|
65
|
+
): Promise<T | null> {
|
|
66
|
+
return this.httpClient.post<T | null>("/v1/rqlite/find-one", {
|
|
67
|
+
table,
|
|
68
|
+
criteria,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create a fluent QueryBuilder for complex SELECT queries.
|
|
74
|
+
*/
|
|
75
|
+
createQueryBuilder(table: string): QueryBuilder {
|
|
76
|
+
return new QueryBuilder(this.httpClient, table);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Create a Repository for entity-based operations.
|
|
81
|
+
*/
|
|
82
|
+
repository<T extends Record<string, any>>(
|
|
83
|
+
tableName: string,
|
|
84
|
+
primaryKey = "id"
|
|
85
|
+
): Repository<T> {
|
|
86
|
+
return new Repository(this.httpClient, tableName, primaryKey);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Execute multiple operations atomically.
|
|
91
|
+
*/
|
|
92
|
+
async transaction(
|
|
93
|
+
ops: TransactionOp[],
|
|
94
|
+
returnResults = true
|
|
95
|
+
): Promise<any[]> {
|
|
96
|
+
const response = await this.httpClient.post<{ results?: any[] }>(
|
|
97
|
+
"/v1/rqlite/transaction",
|
|
98
|
+
{
|
|
99
|
+
ops,
|
|
100
|
+
return_results: returnResults,
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
return response.results || [];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Create a table from DDL SQL.
|
|
108
|
+
*/
|
|
109
|
+
async createTable(schema: string): Promise<void> {
|
|
110
|
+
await this.httpClient.post("/v1/rqlite/create-table", { schema });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Drop a table.
|
|
115
|
+
*/
|
|
116
|
+
async dropTable(table: string): Promise<void> {
|
|
117
|
+
await this.httpClient.post("/v1/rqlite/drop-table", { table });
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get current database schema.
|
|
122
|
+
*/
|
|
123
|
+
async getSchema(): Promise<any> {
|
|
124
|
+
return this.httpClient.get("/v1/rqlite/schema");
|
|
125
|
+
}
|
|
126
|
+
}
|
package/src/db/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { DBClient } from "./client";
|
|
2
|
+
export { QueryBuilder } from "./qb";
|
|
3
|
+
export { Repository } from "./repository";
|
|
4
|
+
export type {
|
|
5
|
+
Entity,
|
|
6
|
+
QueryResponse,
|
|
7
|
+
TransactionOp,
|
|
8
|
+
TransactionRequest,
|
|
9
|
+
SelectOptions,
|
|
10
|
+
FindOptions,
|
|
11
|
+
ColumnDefinition,
|
|
12
|
+
} from "./types";
|
|
13
|
+
export { extractTableName, extractPrimaryKey } from "./types";
|
package/src/db/qb.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { HttpClient } from "../core/http";
|
|
2
|
+
import { SelectOptions, QueryResponse } from "./types";
|
|
3
|
+
|
|
4
|
+
export class QueryBuilder {
|
|
5
|
+
private httpClient: HttpClient;
|
|
6
|
+
private table: string;
|
|
7
|
+
private options: SelectOptions = {};
|
|
8
|
+
|
|
9
|
+
constructor(httpClient: HttpClient, table: string) {
|
|
10
|
+
this.httpClient = httpClient;
|
|
11
|
+
this.table = table;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
select(...columns: string[]): this {
|
|
15
|
+
this.options.select = columns;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
innerJoin(table: string, on: string): this {
|
|
20
|
+
if (!this.options.joins) this.options.joins = [];
|
|
21
|
+
this.options.joins.push({ kind: "INNER", table, on });
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
leftJoin(table: string, on: string): this {
|
|
26
|
+
if (!this.options.joins) this.options.joins = [];
|
|
27
|
+
this.options.joins.push({ kind: "LEFT", table, on });
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
rightJoin(table: string, on: string): this {
|
|
32
|
+
if (!this.options.joins) this.options.joins = [];
|
|
33
|
+
this.options.joins.push({ kind: "RIGHT", table, on });
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
where(expr: string, args?: any[]): this {
|
|
38
|
+
if (!this.options.where) this.options.where = [];
|
|
39
|
+
this.options.where.push({ conj: "AND", expr, args });
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
andWhere(expr: string, args?: any[]): this {
|
|
44
|
+
return this.where(expr, args);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
orWhere(expr: string, args?: any[]): this {
|
|
48
|
+
if (!this.options.where) this.options.where = [];
|
|
49
|
+
this.options.where.push({ conj: "OR", expr, args });
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
groupBy(...columns: string[]): this {
|
|
54
|
+
this.options.group_by = columns;
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
orderBy(...columns: string[]): this {
|
|
59
|
+
this.options.order_by = columns;
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
limit(n: number): this {
|
|
64
|
+
this.options.limit = n;
|
|
65
|
+
return this;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
offset(n: number): this {
|
|
69
|
+
this.options.offset = n;
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async getMany<T = any>(ctx?: any): Promise<T[]> {
|
|
74
|
+
const response = await this.httpClient.post<QueryResponse>(
|
|
75
|
+
"/v1/rqlite/select",
|
|
76
|
+
{
|
|
77
|
+
table: this.table,
|
|
78
|
+
...this.options,
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
return response.items || [];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async getOne<T = any>(ctx?: any): Promise<T | null> {
|
|
85
|
+
const response = await this.httpClient.post<QueryResponse>(
|
|
86
|
+
"/v1/rqlite/select",
|
|
87
|
+
{
|
|
88
|
+
table: this.table,
|
|
89
|
+
...this.options,
|
|
90
|
+
one: true,
|
|
91
|
+
limit: 1,
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
const items = response.items || [];
|
|
95
|
+
return items.length > 0 ? items[0] : null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async count(): Promise<number> {
|
|
99
|
+
const response = await this.httpClient.post<QueryResponse>(
|
|
100
|
+
"/v1/rqlite/select",
|
|
101
|
+
{
|
|
102
|
+
table: this.table,
|
|
103
|
+
select: ["COUNT(*) AS count"],
|
|
104
|
+
where: this.options.where,
|
|
105
|
+
one: true,
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
const items = response.items || [];
|
|
109
|
+
return items.length > 0 ? items[0].count : 0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { HttpClient } from "../core/http";
|
|
2
|
+
import { QueryBuilder } from "./qb";
|
|
3
|
+
import { QueryResponse, FindOptions } from "./types";
|
|
4
|
+
import { SDKError } from "../errors";
|
|
5
|
+
|
|
6
|
+
export class Repository<T extends Record<string, any>> {
|
|
7
|
+
private httpClient: HttpClient;
|
|
8
|
+
private tableName: string;
|
|
9
|
+
private primaryKey: string;
|
|
10
|
+
|
|
11
|
+
constructor(httpClient: HttpClient, tableName: string, primaryKey = "id") {
|
|
12
|
+
this.httpClient = httpClient;
|
|
13
|
+
this.tableName = tableName;
|
|
14
|
+
this.primaryKey = primaryKey;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
createQueryBuilder(): QueryBuilder {
|
|
18
|
+
return new QueryBuilder(this.httpClient, this.tableName);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async find(
|
|
22
|
+
criteria: Record<string, any> = {},
|
|
23
|
+
options: FindOptions = {}
|
|
24
|
+
): Promise<T[]> {
|
|
25
|
+
const response = await this.httpClient.post<QueryResponse>(
|
|
26
|
+
"/v1/rqlite/find",
|
|
27
|
+
{
|
|
28
|
+
table: this.tableName,
|
|
29
|
+
criteria,
|
|
30
|
+
options,
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
return response.items || [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async findOne(criteria: Record<string, any>): Promise<T | null> {
|
|
37
|
+
try {
|
|
38
|
+
const response = await this.httpClient.post<T | null>(
|
|
39
|
+
"/v1/rqlite/find-one",
|
|
40
|
+
{
|
|
41
|
+
table: this.tableName,
|
|
42
|
+
criteria,
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
return response;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// Return null if not found instead of throwing
|
|
48
|
+
if (error instanceof SDKError && error.httpStatus === 404) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async save(entity: T): Promise<T> {
|
|
56
|
+
const pkValue = entity[this.primaryKey];
|
|
57
|
+
|
|
58
|
+
if (!pkValue) {
|
|
59
|
+
// INSERT
|
|
60
|
+
const response = await this.httpClient.post<{
|
|
61
|
+
rows_affected: number;
|
|
62
|
+
last_insert_id: number;
|
|
63
|
+
}>("/v1/rqlite/exec", {
|
|
64
|
+
sql: this.buildInsertSql(entity),
|
|
65
|
+
args: this.buildInsertArgs(entity),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (response.last_insert_id) {
|
|
69
|
+
(entity as any)[this.primaryKey] = response.last_insert_id;
|
|
70
|
+
}
|
|
71
|
+
return entity;
|
|
72
|
+
} else {
|
|
73
|
+
// UPDATE
|
|
74
|
+
await this.httpClient.post("/v1/rqlite/exec", {
|
|
75
|
+
sql: this.buildUpdateSql(entity),
|
|
76
|
+
args: this.buildUpdateArgs(entity),
|
|
77
|
+
});
|
|
78
|
+
return entity;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async remove(entity: T | Record<string, any>): Promise<void> {
|
|
83
|
+
const pkValue = entity[this.primaryKey];
|
|
84
|
+
if (!pkValue) {
|
|
85
|
+
throw new SDKError(
|
|
86
|
+
`Primary key "${this.primaryKey}" is required for remove`,
|
|
87
|
+
400,
|
|
88
|
+
"MISSING_PK"
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
await this.httpClient.post("/v1/rqlite/exec", {
|
|
93
|
+
sql: `DELETE FROM ${this.tableName} WHERE ${this.primaryKey} = ?`,
|
|
94
|
+
args: [pkValue],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private buildInsertSql(entity: T): string {
|
|
99
|
+
const columns = Object.keys(entity).filter((k) => entity[k] !== undefined);
|
|
100
|
+
const placeholders = columns.map(() => "?").join(", ");
|
|
101
|
+
return `INSERT INTO ${this.tableName} (${columns.join(
|
|
102
|
+
", "
|
|
103
|
+
)}) VALUES (${placeholders})`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private buildInsertArgs(entity: T): any[] {
|
|
107
|
+
return Object.entries(entity)
|
|
108
|
+
.filter(([, v]) => v !== undefined)
|
|
109
|
+
.map(([, v]) => v);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private buildUpdateSql(entity: T): string {
|
|
113
|
+
const columns = Object.keys(entity)
|
|
114
|
+
.filter((k) => entity[k] !== undefined && k !== this.primaryKey)
|
|
115
|
+
.map((k) => `${k} = ?`);
|
|
116
|
+
return `UPDATE ${this.tableName} SET ${columns.join(", ")} WHERE ${
|
|
117
|
+
this.primaryKey
|
|
118
|
+
} = ?`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private buildUpdateArgs(entity: T): any[] {
|
|
122
|
+
const args = Object.entries(entity)
|
|
123
|
+
.filter(([k, v]) => v !== undefined && k !== this.primaryKey)
|
|
124
|
+
.map(([, v]) => v);
|
|
125
|
+
args.push(entity[this.primaryKey]);
|
|
126
|
+
return args;
|
|
127
|
+
}
|
|
128
|
+
}
|
package/src/db/types.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export interface Entity {
|
|
2
|
+
TableName(): string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface QueryResponse {
|
|
6
|
+
columns?: string[];
|
|
7
|
+
rows?: any[][];
|
|
8
|
+
count?: number;
|
|
9
|
+
items?: any[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface TransactionOp {
|
|
13
|
+
kind: "exec" | "query";
|
|
14
|
+
sql: string;
|
|
15
|
+
args?: any[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TransactionRequest {
|
|
19
|
+
statements?: string[];
|
|
20
|
+
ops?: TransactionOp[];
|
|
21
|
+
return_results?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface SelectOptions {
|
|
25
|
+
select?: string[];
|
|
26
|
+
joins?: Array<{
|
|
27
|
+
kind: "INNER" | "LEFT" | "RIGHT" | "FULL";
|
|
28
|
+
table: string;
|
|
29
|
+
on: string;
|
|
30
|
+
}>;
|
|
31
|
+
where?: Array<{
|
|
32
|
+
conj?: "AND" | "OR";
|
|
33
|
+
expr: string;
|
|
34
|
+
args?: any[];
|
|
35
|
+
}>;
|
|
36
|
+
group_by?: string[];
|
|
37
|
+
order_by?: string[];
|
|
38
|
+
limit?: number;
|
|
39
|
+
offset?: number;
|
|
40
|
+
one?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type FindOptions = Omit<SelectOptions, "select" | "joins" | "one">;
|
|
44
|
+
|
|
45
|
+
export interface ColumnDefinition {
|
|
46
|
+
name: string;
|
|
47
|
+
isPrimaryKey?: boolean;
|
|
48
|
+
isAutoIncrement?: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function extractTableName(entity: Entity | string): string {
|
|
52
|
+
if (typeof entity === "string") return entity;
|
|
53
|
+
return entity.TableName();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function extractPrimaryKey(entity: any): string | undefined {
|
|
57
|
+
if (typeof entity === "string") return undefined;
|
|
58
|
+
|
|
59
|
+
// Check for explicit pk tag
|
|
60
|
+
const metadata = (entity as any)._dbMetadata;
|
|
61
|
+
if (metadata?.primaryKey) return metadata.primaryKey;
|
|
62
|
+
|
|
63
|
+
// Check for ID field
|
|
64
|
+
if (entity.id !== undefined) return "id";
|
|
65
|
+
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export class SDKError extends Error {
|
|
2
|
+
public readonly httpStatus: number;
|
|
3
|
+
public readonly code: string;
|
|
4
|
+
public readonly details: Record<string, any>;
|
|
5
|
+
|
|
6
|
+
constructor(
|
|
7
|
+
message: string,
|
|
8
|
+
httpStatus: number = 500,
|
|
9
|
+
code: string = "SDK_ERROR",
|
|
10
|
+
details: Record<string, any> = {}
|
|
11
|
+
) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "SDKError";
|
|
14
|
+
this.httpStatus = httpStatus;
|
|
15
|
+
this.code = code;
|
|
16
|
+
this.details = details;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static fromResponse(
|
|
20
|
+
status: number,
|
|
21
|
+
body: any,
|
|
22
|
+
message?: string
|
|
23
|
+
): SDKError {
|
|
24
|
+
const errorMsg = message || body?.error || `HTTP ${status}`;
|
|
25
|
+
const code = body?.code || `HTTP_${status}`;
|
|
26
|
+
return new SDKError(errorMsg, status, code, body);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
toJSON() {
|
|
30
|
+
return {
|
|
31
|
+
name: this.name,
|
|
32
|
+
message: this.message,
|
|
33
|
+
httpStatus: this.httpStatus,
|
|
34
|
+
code: this.code,
|
|
35
|
+
details: this.details,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functions Client
|
|
3
|
+
* Client for calling serverless functions on the Orama Network
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { HttpClient } from "../core/http";
|
|
7
|
+
import { SDKError } from "../errors";
|
|
8
|
+
|
|
9
|
+
export interface FunctionsClientConfig {
|
|
10
|
+
/**
|
|
11
|
+
* Base URL for the functions gateway
|
|
12
|
+
* Defaults to using the same baseURL as the HTTP client
|
|
13
|
+
*/
|
|
14
|
+
gatewayURL?: string;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Namespace for the functions
|
|
18
|
+
*/
|
|
19
|
+
namespace: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class FunctionsClient {
|
|
23
|
+
private httpClient: HttpClient;
|
|
24
|
+
private gatewayURL?: string;
|
|
25
|
+
private namespace: string;
|
|
26
|
+
|
|
27
|
+
constructor(httpClient: HttpClient, config?: FunctionsClientConfig) {
|
|
28
|
+
this.httpClient = httpClient;
|
|
29
|
+
this.gatewayURL = config?.gatewayURL;
|
|
30
|
+
this.namespace = config?.namespace ?? "default";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Invoke a serverless function by name
|
|
35
|
+
*
|
|
36
|
+
* @param functionName - Name of the function to invoke
|
|
37
|
+
* @param input - Input payload for the function
|
|
38
|
+
* @returns The function response
|
|
39
|
+
*/
|
|
40
|
+
async invoke<TInput = any, TOutput = any>(
|
|
41
|
+
functionName: string,
|
|
42
|
+
input: TInput
|
|
43
|
+
): Promise<TOutput> {
|
|
44
|
+
const url = this.gatewayURL
|
|
45
|
+
? `${this.gatewayURL}/v1/invoke/${this.namespace}/${functionName}`
|
|
46
|
+
: `/v1/invoke/${this.namespace}/${functionName}`;
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const response = await this.httpClient.post<TOutput>(url, input);
|
|
50
|
+
return response;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (error instanceof SDKError) {
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
throw new SDKError(
|
|
56
|
+
`Function ${functionName} failed`,
|
|
57
|
+
500,
|
|
58
|
+
error instanceof Error ? error.message : String(error)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serverless Functions Types
|
|
3
|
+
* Type definitions for calling serverless functions on the Orama Network
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generic response from a serverless function
|
|
8
|
+
*/
|
|
9
|
+
export interface FunctionResponse<T = unknown> {
|
|
10
|
+
success: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
data?: T;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Standard success/error response used by many functions
|
|
17
|
+
*/
|
|
18
|
+
export interface SuccessResponse {
|
|
19
|
+
success: boolean;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|