@syfthub/sdk 0.1.0 → 0.1.1
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 +0 -3
- package/dist/index.cjs +219 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +165 -40
- package/dist/index.d.ts +165 -40
- package/dist/index.js +219 -102
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -604,11 +604,7 @@ var AuthResource = class {
|
|
|
604
604
|
if (!tokens) {
|
|
605
605
|
throw new AuthenticationError("No refresh token available");
|
|
606
606
|
}
|
|
607
|
-
const response = await this.http.post(
|
|
608
|
-
"/api/v1/auth/refresh",
|
|
609
|
-
{ refreshToken: tokens.refreshToken },
|
|
610
|
-
{ includeAuth: false }
|
|
611
|
-
);
|
|
607
|
+
const response = await this.http.post("/api/v1/auth/refresh", { refreshToken: tokens.refreshToken }, { includeAuth: false });
|
|
612
608
|
this.http.setTokens(response.accessToken, response.refreshToken);
|
|
613
609
|
}
|
|
614
610
|
/**
|
|
@@ -885,22 +881,6 @@ var MyEndpointsResource = class {
|
|
|
885
881
|
}
|
|
886
882
|
return [parts[0], parts[1]];
|
|
887
883
|
}
|
|
888
|
-
/**
|
|
889
|
-
* Resolve an endpoint path to its ID.
|
|
890
|
-
*
|
|
891
|
-
* @param path - Endpoint path in "owner/slug" format
|
|
892
|
-
* @returns The endpoint ID
|
|
893
|
-
*/
|
|
894
|
-
async resolveEndpointId(path) {
|
|
895
|
-
const [owner, slug] = this.parsePath(path);
|
|
896
|
-
const response = await this.http.get(`/${owner}/${slug}`);
|
|
897
|
-
if (response.id === void 0) {
|
|
898
|
-
throw new Error(
|
|
899
|
-
`Could not resolve endpoint ID for '${path}'. Make sure you own this endpoint.`
|
|
900
|
-
);
|
|
901
|
-
}
|
|
902
|
-
return response.id;
|
|
903
|
-
}
|
|
904
884
|
/**
|
|
905
885
|
* List the current user's endpoints.
|
|
906
886
|
*
|
|
@@ -941,8 +921,17 @@ var MyEndpointsResource = class {
|
|
|
941
921
|
* @throws {AuthorizationError} If not authorized to view
|
|
942
922
|
*/
|
|
943
923
|
async get(path) {
|
|
944
|
-
const [
|
|
945
|
-
|
|
924
|
+
const [, slug] = this.parsePath(path);
|
|
925
|
+
const endpoints = await this.http.get("/api/v1/endpoints", { limit: 100 });
|
|
926
|
+
for (const ep of endpoints) {
|
|
927
|
+
if (ep.slug === slug) {
|
|
928
|
+
return ep;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
const { NotFoundError: NotFoundError2 } = await Promise.resolve().then(() => (init_errors(), errors_exports));
|
|
932
|
+
throw new NotFoundError2(
|
|
933
|
+
`Endpoint not found: '${path}'. No endpoint found with slug '${slug}' in your endpoints.`
|
|
934
|
+
);
|
|
946
935
|
}
|
|
947
936
|
/**
|
|
948
937
|
* Update an endpoint.
|
|
@@ -957,8 +946,8 @@ var MyEndpointsResource = class {
|
|
|
957
946
|
* @throws {AuthorizationError} If not owner/admin
|
|
958
947
|
*/
|
|
959
948
|
async update(path, input) {
|
|
960
|
-
const
|
|
961
|
-
return this.http.patch(`/api/v1/endpoints/${
|
|
949
|
+
const [, slug] = this.parsePath(path);
|
|
950
|
+
return this.http.patch(`/api/v1/endpoints/slug/${slug}`, input);
|
|
962
951
|
}
|
|
963
952
|
/**
|
|
964
953
|
* Delete an endpoint.
|
|
@@ -969,8 +958,44 @@ var MyEndpointsResource = class {
|
|
|
969
958
|
* @throws {AuthorizationError} If not owner/admin
|
|
970
959
|
*/
|
|
971
960
|
async delete(path) {
|
|
972
|
-
const
|
|
973
|
-
await this.http.delete(`/api/v1/endpoints/${
|
|
961
|
+
const [, slug] = this.parsePath(path);
|
|
962
|
+
await this.http.delete(`/api/v1/endpoints/slug/${slug}`);
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Synchronize user's endpoints with provided list.
|
|
966
|
+
*
|
|
967
|
+
* This is a DESTRUCTIVE operation that:
|
|
968
|
+
* 1. Deletes ALL existing endpoints owned by the current user
|
|
969
|
+
* 2. Creates ALL endpoints from the provided list
|
|
970
|
+
* 3. Is ATOMIC: either all endpoints sync successfully, or none do
|
|
971
|
+
*
|
|
972
|
+
* Important Notes:
|
|
973
|
+
* - Organization endpoints are NOT affected
|
|
974
|
+
* - Stars on existing endpoints will be lost (reset to 0)
|
|
975
|
+
* - Endpoint IDs will change (new IDs assigned)
|
|
976
|
+
* - Maximum 100 endpoints per sync request
|
|
977
|
+
*
|
|
978
|
+
* @param endpoints - List of endpoint specifications to sync.
|
|
979
|
+
* Pass an empty array to delete ALL user endpoints.
|
|
980
|
+
* @returns SyncEndpointsResponse with synced count, deleted count, and created endpoints
|
|
981
|
+
* @throws {AuthenticationError} If not authenticated
|
|
982
|
+
* @throws {ValidationError} If any endpoint fails validation (entire batch rejected)
|
|
983
|
+
*
|
|
984
|
+
* @example
|
|
985
|
+
* // Sync with new endpoints
|
|
986
|
+
* const result = await client.myEndpoints.sync([
|
|
987
|
+
* { name: 'Model A', type: 'model', visibility: 'public' },
|
|
988
|
+
* { name: 'Data Source B', type: 'data_source', visibility: 'private' },
|
|
989
|
+
* ]);
|
|
990
|
+
* console.log(`Deleted ${result.deleted}, created ${result.synced} endpoints`);
|
|
991
|
+
*
|
|
992
|
+
* @example
|
|
993
|
+
* // Clear all endpoints
|
|
994
|
+
* const result = await client.myEndpoints.sync([]);
|
|
995
|
+
* console.log(`Deleted ${result.deleted} endpoints`);
|
|
996
|
+
*/
|
|
997
|
+
async sync(endpoints = []) {
|
|
998
|
+
return this.http.post("/api/v1/endpoints/sync", { endpoints });
|
|
974
999
|
}
|
|
975
1000
|
};
|
|
976
1001
|
|
|
@@ -1045,12 +1070,61 @@ var HubResource = class {
|
|
|
1045
1070
|
if (options?.minStars !== void 0) {
|
|
1046
1071
|
params["minStars"] = options.minStars;
|
|
1047
1072
|
}
|
|
1048
|
-
return this.http.get(
|
|
1049
|
-
|
|
1050
|
-
|
|
1073
|
+
return this.http.get("/api/v1/endpoints/trending", params, {
|
|
1074
|
+
includeAuth: false
|
|
1075
|
+
});
|
|
1076
|
+
}, pageSize);
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
* Search for endpoints using semantic search.
|
|
1080
|
+
*
|
|
1081
|
+
* Uses RAG-powered semantic search to find endpoints that match the
|
|
1082
|
+
* natural language query. Returns results sorted by relevance score.
|
|
1083
|
+
*
|
|
1084
|
+
* Note: If RAG is not configured on the server (no OpenAI API key),
|
|
1085
|
+
* this method returns an empty array.
|
|
1086
|
+
*
|
|
1087
|
+
* @param query - Natural language search query (e.g., "machine learning models for image classification")
|
|
1088
|
+
* @param options - Search options (topK, type filter, minScore)
|
|
1089
|
+
* @returns Promise resolving to array of EndpointSearchResult with relevance scores.
|
|
1090
|
+
* Returns empty array if query is too short (<3 chars) or no matches found.
|
|
1091
|
+
*
|
|
1092
|
+
* @example
|
|
1093
|
+
* // Search for machine learning models
|
|
1094
|
+
* const results = await client.hub.search('image classification models');
|
|
1095
|
+
* for (const result of results) {
|
|
1096
|
+
* console.log(`${result.ownerUsername}/${result.slug}: ${result.relevanceScore.toFixed(2)}`);
|
|
1097
|
+
* }
|
|
1098
|
+
*
|
|
1099
|
+
* @example
|
|
1100
|
+
* // Filter by type and minimum score
|
|
1101
|
+
* const dataSources = await client.hub.search('customer data', {
|
|
1102
|
+
* type: EndpointType.DATA_SOURCE,
|
|
1103
|
+
* minScore: 0.5,
|
|
1104
|
+
* });
|
|
1105
|
+
*/
|
|
1106
|
+
async search(query, options = {}) {
|
|
1107
|
+
const { topK = 10, type, minScore = 0 } = options;
|
|
1108
|
+
if (!query || query.trim().length < 3) {
|
|
1109
|
+
return [];
|
|
1110
|
+
}
|
|
1111
|
+
const body = {
|
|
1112
|
+
query: query.trim(),
|
|
1113
|
+
top_k: topK
|
|
1114
|
+
};
|
|
1115
|
+
if (type !== void 0) {
|
|
1116
|
+
body["type"] = type;
|
|
1117
|
+
}
|
|
1118
|
+
try {
|
|
1119
|
+
const response = await this.http.post(
|
|
1120
|
+
"/api/v1/endpoints/search",
|
|
1121
|
+
body,
|
|
1051
1122
|
{ includeAuth: false }
|
|
1052
1123
|
);
|
|
1053
|
-
|
|
1124
|
+
return (response.results ?? []).filter((result) => result.relevanceScore >= minScore);
|
|
1125
|
+
} catch {
|
|
1126
|
+
return [];
|
|
1127
|
+
}
|
|
1054
1128
|
}
|
|
1055
1129
|
/**
|
|
1056
1130
|
* Get an endpoint by its path.
|
|
@@ -1083,7 +1157,7 @@ var HubResource = class {
|
|
|
1083
1157
|
*/
|
|
1084
1158
|
async star(path) {
|
|
1085
1159
|
const endpointId = await this.resolveEndpointId(path);
|
|
1086
|
-
await this.http.
|
|
1160
|
+
await this.http.post(`/api/v1/endpoints/${endpointId}/star`);
|
|
1087
1161
|
}
|
|
1088
1162
|
/**
|
|
1089
1163
|
* Unstar an endpoint.
|
|
@@ -1094,7 +1168,7 @@ var HubResource = class {
|
|
|
1094
1168
|
*/
|
|
1095
1169
|
async unstar(path) {
|
|
1096
1170
|
const endpointId = await this.resolveEndpointId(path);
|
|
1097
|
-
await this.http.
|
|
1171
|
+
await this.http.delete(`/api/v1/endpoints/${endpointId}/star`);
|
|
1098
1172
|
}
|
|
1099
1173
|
/**
|
|
1100
1174
|
* Check if you have starred an endpoint.
|
|
@@ -1248,9 +1322,9 @@ var AccountingResource = class {
|
|
|
1248
1322
|
const response = await fetch(url.toString(), {
|
|
1249
1323
|
method,
|
|
1250
1324
|
headers: {
|
|
1251
|
-
|
|
1325
|
+
Authorization: this.authHeader,
|
|
1252
1326
|
"Content-Type": "application/json",
|
|
1253
|
-
|
|
1327
|
+
Accept: "application/json"
|
|
1254
1328
|
},
|
|
1255
1329
|
body: options?.body ? JSON.stringify(options.body) : void 0,
|
|
1256
1330
|
signal: controller.signal
|
|
@@ -1267,7 +1341,10 @@ var AccountingResource = class {
|
|
|
1267
1341
|
if (error instanceof Error && error.name === "AbortError") {
|
|
1268
1342
|
throw new APIError("Request timeout", 408);
|
|
1269
1343
|
}
|
|
1270
|
-
throw new APIError(
|
|
1344
|
+
throw new APIError(
|
|
1345
|
+
`Accounting request failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
1346
|
+
0
|
|
1347
|
+
);
|
|
1271
1348
|
} finally {
|
|
1272
1349
|
clearTimeout(timeoutId);
|
|
1273
1350
|
}
|
|
@@ -1283,9 +1360,9 @@ var AccountingResource = class {
|
|
|
1283
1360
|
const response = await fetch(url.toString(), {
|
|
1284
1361
|
method,
|
|
1285
1362
|
headers: {
|
|
1286
|
-
|
|
1363
|
+
Authorization: `Bearer ${token}`,
|
|
1287
1364
|
"Content-Type": "application/json",
|
|
1288
|
-
|
|
1365
|
+
Accept: "application/json"
|
|
1289
1366
|
},
|
|
1290
1367
|
body: options?.body ? JSON.stringify(options.body) : void 0,
|
|
1291
1368
|
signal: controller.signal
|
|
@@ -1302,7 +1379,10 @@ var AccountingResource = class {
|
|
|
1302
1379
|
if (error instanceof Error && error.name === "AbortError") {
|
|
1303
1380
|
throw new APIError("Request timeout", 408);
|
|
1304
1381
|
}
|
|
1305
|
-
throw new APIError(
|
|
1382
|
+
throw new APIError(
|
|
1383
|
+
`Accounting request failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
1384
|
+
0
|
|
1385
|
+
);
|
|
1306
1386
|
} finally {
|
|
1307
1387
|
clearTimeout(timeoutId);
|
|
1308
1388
|
}
|
|
@@ -1391,15 +1471,12 @@ var AccountingResource = class {
|
|
|
1391
1471
|
*/
|
|
1392
1472
|
getTransactions(options) {
|
|
1393
1473
|
const pageSize = options?.pageSize ?? 20;
|
|
1394
|
-
return new PageIterator(
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
},
|
|
1401
|
-
pageSize
|
|
1402
|
-
);
|
|
1474
|
+
return new PageIterator(async (skip, limit) => {
|
|
1475
|
+
const response = await this.request("GET", "/transactions", {
|
|
1476
|
+
params: { skip, limit }
|
|
1477
|
+
});
|
|
1478
|
+
return response.map(parseTransaction);
|
|
1479
|
+
}, pageSize);
|
|
1403
1480
|
}
|
|
1404
1481
|
/**
|
|
1405
1482
|
* Get a specific transaction by ID.
|
|
@@ -1849,7 +1926,11 @@ var ChatResource = class {
|
|
|
1849
1926
|
stream: false
|
|
1850
1927
|
}
|
|
1851
1928
|
);
|
|
1852
|
-
const
|
|
1929
|
+
const effectiveAggregatorUrl = (options.aggregatorUrl ?? this.aggregatorUrl).replace(
|
|
1930
|
+
/\/+$/,
|
|
1931
|
+
""
|
|
1932
|
+
);
|
|
1933
|
+
const url = `${effectiveAggregatorUrl}/chat`;
|
|
1853
1934
|
const response = await fetch(url, {
|
|
1854
1935
|
method: "POST",
|
|
1855
1936
|
headers: {
|
|
@@ -1918,7 +1999,11 @@ var ChatResource = class {
|
|
|
1918
1999
|
stream: true
|
|
1919
2000
|
}
|
|
1920
2001
|
);
|
|
1921
|
-
const
|
|
2002
|
+
const effectiveAggregatorUrl = (options.aggregatorUrl ?? this.aggregatorUrl).replace(
|
|
2003
|
+
/\/+$/,
|
|
2004
|
+
""
|
|
2005
|
+
);
|
|
2006
|
+
const url = `${effectiveAggregatorUrl}/chat/stream`;
|
|
1922
2007
|
const response = await fetch(url, {
|
|
1923
2008
|
method: "POST",
|
|
1924
2009
|
headers: {
|
|
@@ -2044,9 +2129,7 @@ var ChatResource = class {
|
|
|
2044
2129
|
for await (const endpoint of this.hub.browse()) {
|
|
2045
2130
|
if (results.length >= limit) break;
|
|
2046
2131
|
if (endpoint.type !== EndpointType.MODEL) continue;
|
|
2047
|
-
const hasUrl = endpoint.connect.some(
|
|
2048
|
-
(conn) => conn.enabled && conn.config["url"]
|
|
2049
|
-
);
|
|
2132
|
+
const hasUrl = endpoint.connect.some((conn) => conn.enabled && conn.config["url"]);
|
|
2050
2133
|
if (hasUrl) {
|
|
2051
2134
|
results.push(endpoint);
|
|
2052
2135
|
}
|
|
@@ -2064,9 +2147,7 @@ var ChatResource = class {
|
|
|
2064
2147
|
for await (const endpoint of this.hub.browse()) {
|
|
2065
2148
|
if (results.length >= limit) break;
|
|
2066
2149
|
if (endpoint.type !== EndpointType.DATA_SOURCE) continue;
|
|
2067
|
-
const hasUrl = endpoint.connect.some(
|
|
2068
|
-
(conn) => conn.enabled && conn.config["url"]
|
|
2069
|
-
);
|
|
2150
|
+
const hasUrl = endpoint.connect.some((conn) => conn.enabled && conn.config["url"]);
|
|
2070
2151
|
if (hasUrl) {
|
|
2071
2152
|
results.push(endpoint);
|
|
2072
2153
|
}
|
|
@@ -2320,6 +2401,7 @@ var SyftHubClient = class {
|
|
|
2320
2401
|
_myEndpoints;
|
|
2321
2402
|
_hub;
|
|
2322
2403
|
_accounting;
|
|
2404
|
+
_accountingInitPromise = null;
|
|
2323
2405
|
_chat;
|
|
2324
2406
|
_syftai;
|
|
2325
2407
|
/**
|
|
@@ -2400,44 +2482,86 @@ var SyftHubClient = class {
|
|
|
2400
2482
|
* The accounting service is external and uses separate credentials
|
|
2401
2483
|
* (email/password Basic auth) from SyftHub's JWT authentication.
|
|
2402
2484
|
*
|
|
2403
|
-
* Credentials
|
|
2404
|
-
*
|
|
2405
|
-
* - Environment variables: SYFTHUB_ACCOUNTING_URL, SYFTHUB_ACCOUNTING_EMAIL, SYFTHUB_ACCOUNTING_PASSWORD
|
|
2485
|
+
* Credentials are automatically retrieved from the backend after login.
|
|
2486
|
+
* You must call `initAccounting()` after login to initialize this resource.
|
|
2406
2487
|
*
|
|
2407
|
-
* @throws {
|
|
2488
|
+
* @throws {AuthenticationError} If not initialized
|
|
2408
2489
|
*
|
|
2409
2490
|
* @example
|
|
2410
|
-
*
|
|
2411
|
-
*
|
|
2491
|
+
* // Login first, then initialize accounting
|
|
2492
|
+
* await client.auth.login('alice', 'password');
|
|
2493
|
+
* await client.initAccounting();
|
|
2412
2494
|
*
|
|
2413
|
-
* //
|
|
2414
|
-
* const
|
|
2415
|
-
* recipientEmail: 'bob@example.com',
|
|
2416
|
-
* amount: 10.0
|
|
2417
|
-
* });
|
|
2495
|
+
* // Now accounting is available
|
|
2496
|
+
* const user = await client.accounting.getUser();
|
|
2418
2497
|
*/
|
|
2419
2498
|
get accounting() {
|
|
2420
|
-
if (
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2499
|
+
if (this._accounting) {
|
|
2500
|
+
return this._accounting;
|
|
2501
|
+
}
|
|
2502
|
+
throw new AuthenticationError(
|
|
2503
|
+
"Accounting not initialized. Call `await client.initAccounting()` after login."
|
|
2504
|
+
);
|
|
2505
|
+
}
|
|
2506
|
+
/**
|
|
2507
|
+
* Initialize accounting resource by fetching credentials from the backend.
|
|
2508
|
+
*
|
|
2509
|
+
* This method retrieves accounting credentials from the SyftHub backend
|
|
2510
|
+
* and initializes the accounting resource. Requires authentication.
|
|
2511
|
+
*
|
|
2512
|
+
* @returns The initialized AccountingResource
|
|
2513
|
+
* @throws {AuthenticationError} If not authenticated
|
|
2514
|
+
* @throws {ConfigurationError} If user has no accounting service configured
|
|
2515
|
+
*
|
|
2516
|
+
* @example
|
|
2517
|
+
* // Login first, then initialize accounting
|
|
2518
|
+
* await client.auth.login('alice', 'password');
|
|
2519
|
+
* await client.initAccounting();
|
|
2520
|
+
*
|
|
2521
|
+
* // Now accounting is available
|
|
2522
|
+
* const user = await client.accounting.getUser();
|
|
2523
|
+
*/
|
|
2524
|
+
async initAccounting() {
|
|
2525
|
+
if (this._accounting) {
|
|
2526
|
+
return this._accounting;
|
|
2527
|
+
}
|
|
2528
|
+
if (this._accountingInitPromise) {
|
|
2529
|
+
return this._accountingInitPromise;
|
|
2530
|
+
}
|
|
2531
|
+
this._accountingInitPromise = this._doInitAccounting();
|
|
2532
|
+
try {
|
|
2533
|
+
this._accounting = await this._accountingInitPromise;
|
|
2534
|
+
return this._accounting;
|
|
2535
|
+
} finally {
|
|
2536
|
+
this._accountingInitPromise = null;
|
|
2439
2537
|
}
|
|
2440
|
-
|
|
2538
|
+
}
|
|
2539
|
+
/**
|
|
2540
|
+
* Internal method to perform accounting initialization.
|
|
2541
|
+
*/
|
|
2542
|
+
async _doInitAccounting() {
|
|
2543
|
+
if (!this.isAuthenticated) {
|
|
2544
|
+
throw new AuthenticationError(
|
|
2545
|
+
"Must be logged in to use accounting. Call client.auth.login() first."
|
|
2546
|
+
);
|
|
2547
|
+
}
|
|
2548
|
+
const creds = await this.users.getAccountingCredentials();
|
|
2549
|
+
if (!creds.url) {
|
|
2550
|
+
throw new ConfigurationError(
|
|
2551
|
+
"No accounting service configured for this user. Contact your administrator to set up accounting."
|
|
2552
|
+
);
|
|
2553
|
+
}
|
|
2554
|
+
if (!creds.password) {
|
|
2555
|
+
throw new ConfigurationError(
|
|
2556
|
+
"Accounting password not available. This may indicate an issue with your account setup."
|
|
2557
|
+
);
|
|
2558
|
+
}
|
|
2559
|
+
return new AccountingResource({
|
|
2560
|
+
url: creds.url,
|
|
2561
|
+
email: creds.email,
|
|
2562
|
+
password: creds.password,
|
|
2563
|
+
timeout: this.options.timeout
|
|
2564
|
+
});
|
|
2441
2565
|
}
|
|
2442
2566
|
/**
|
|
2443
2567
|
* Chat resource for RAG-augmented conversations via the Aggregator.
|
|
@@ -2467,11 +2591,7 @@ var SyftHubClient = class {
|
|
|
2467
2591
|
*/
|
|
2468
2592
|
get chat() {
|
|
2469
2593
|
if (!this._chat) {
|
|
2470
|
-
this._chat = new ChatResource(
|
|
2471
|
-
this.hub,
|
|
2472
|
-
this.auth,
|
|
2473
|
-
this.aggregatorUrl
|
|
2474
|
-
);
|
|
2594
|
+
this._chat = new ChatResource(this.hub, this.auth, this.aggregatorUrl);
|
|
2475
2595
|
}
|
|
2476
2596
|
return this._chat;
|
|
2477
2597
|
}
|
|
@@ -2546,23 +2666,20 @@ var SyftHubClient = class {
|
|
|
2546
2666
|
return this.http.hasTokens();
|
|
2547
2667
|
}
|
|
2548
2668
|
/**
|
|
2549
|
-
* Check if accounting
|
|
2669
|
+
* Check if accounting has been initialized.
|
|
2550
2670
|
*
|
|
2551
|
-
* Use this to check if accounting
|
|
2552
|
-
*
|
|
2671
|
+
* Use this to check if accounting is available before accessing
|
|
2672
|
+
* the `accounting` property, which will throw if not initialized.
|
|
2553
2673
|
*
|
|
2554
|
-
* @returns True if accounting
|
|
2674
|
+
* @returns True if accounting has been initialized via `initAccounting()`
|
|
2555
2675
|
*
|
|
2556
2676
|
* @example
|
|
2557
|
-
* if (client.
|
|
2677
|
+
* if (client.isAccountingInitialized) {
|
|
2558
2678
|
* const user = await client.accounting.getUser();
|
|
2559
2679
|
* }
|
|
2560
2680
|
*/
|
|
2561
|
-
get
|
|
2562
|
-
|
|
2563
|
-
const email = this.options.accountingEmail ?? getEnv("SYFTHUB_ACCOUNTING_EMAIL");
|
|
2564
|
-
const password = this.options.accountingPassword ?? getEnv("SYFTHUB_ACCOUNTING_PASSWORD");
|
|
2565
|
-
return Boolean(url && email && password);
|
|
2681
|
+
get isAccountingInitialized() {
|
|
2682
|
+
return this._accounting !== void 0 && this._accounting !== null;
|
|
2566
2683
|
}
|
|
2567
2684
|
/**
|
|
2568
2685
|
* Close the client and clean up resources.
|