@calimero-network/mero-js 1.1.0 → 2.0.0-beta.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 +341 -319
- package/dist/api/admin/aliases.d.ts +54 -0
- package/dist/api/admin/aliases.d.ts.map +1 -0
- package/dist/api/admin/aliases.js +43 -0
- package/dist/api/admin/aliases.js.map +1 -0
- package/dist/api/admin/applications.d.ts +52 -0
- package/dist/api/admin/applications.d.ts.map +1 -0
- package/dist/api/admin/applications.js +31 -0
- package/dist/api/admin/applications.js.map +1 -0
- package/dist/api/admin/blobs.d.ts +24 -0
- package/dist/api/admin/blobs.d.ts.map +1 -0
- package/dist/api/admin/blobs.js +58 -0
- package/dist/api/admin/blobs.js.map +1 -0
- package/dist/api/admin/capabilities.d.ts +26 -0
- package/dist/api/admin/capabilities.d.ts.map +1 -0
- package/dist/api/admin/capabilities.js +13 -0
- package/dist/api/admin/capabilities.js.map +1 -0
- package/dist/api/admin/client.d.ts +63 -0
- package/dist/api/admin/client.d.ts.map +1 -0
- package/dist/api/admin/client.js +103 -0
- package/dist/api/admin/client.js.map +1 -0
- package/dist/api/admin/contexts.d.ts +110 -0
- package/dist/api/admin/contexts.d.ts.map +1 -0
- package/dist/api/admin/contexts.js +61 -0
- package/dist/api/admin/contexts.js.map +1 -0
- package/dist/api/admin/factory.d.ts +4 -0
- package/dist/api/admin/factory.d.ts.map +1 -0
- package/dist/api/admin/factory.js +5 -0
- package/dist/api/admin/factory.js.map +1 -0
- package/dist/api/admin/identity.d.ts +10 -0
- package/dist/api/admin/identity.d.ts.map +1 -0
- package/dist/api/admin/identity.js +10 -0
- package/dist/api/admin/identity.js.map +1 -0
- package/dist/api/admin/index.d.ts +23 -0
- package/dist/api/admin/index.d.ts.map +1 -0
- package/dist/api/admin/index.js +26 -0
- package/dist/api/admin/index.js.map +1 -0
- package/dist/api/admin/network.d.ts +10 -0
- package/dist/api/admin/network.d.ts.map +1 -0
- package/dist/api/admin/network.js +9 -0
- package/dist/api/admin/network.js.map +1 -0
- package/dist/api/admin/proposals.d.ts +49 -0
- package/dist/api/admin/proposals.d.ts.map +1 -0
- package/dist/api/admin/proposals.js +34 -0
- package/dist/api/admin/proposals.js.map +1 -0
- package/dist/api/admin/public.d.ts +15 -0
- package/dist/api/admin/public.d.ts.map +1 -0
- package/dist/api/admin/public.js +18 -0
- package/dist/api/admin/public.js.map +1 -0
- package/dist/api/admin/tee.d.ts +74 -0
- package/dist/api/admin/tee.d.ts.map +1 -0
- package/dist/api/admin/tee.js +16 -0
- package/dist/api/admin/tee.js.map +1 -0
- package/dist/api/auth/client.d.ts +55 -0
- package/dist/api/auth/client.d.ts.map +1 -0
- package/dist/api/auth/client.js +127 -0
- package/dist/api/auth/client.js.map +1 -0
- package/dist/api/auth/factory.d.ts +4 -0
- package/dist/api/auth/factory.d.ts.map +1 -0
- package/dist/api/auth/factory.js +5 -0
- package/dist/api/auth/factory.js.map +1 -0
- package/dist/api/auth/index.d.ts +4 -0
- package/dist/api/auth/index.d.ts.map +1 -0
- package/dist/api/auth/index.js +4 -0
- package/dist/api/auth/index.js.map +1 -0
- package/dist/api/auth/types.d.ts +94 -0
- package/dist/api/auth/types.d.ts.map +1 -0
- package/dist/api/auth/types.js +4 -0
- package/dist/api/auth/types.js.map +1 -0
- package/dist/api/index.d.ts +15 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +18 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/rpc/client.d.ts +76 -0
- package/dist/api/rpc/client.d.ts.map +1 -0
- package/dist/api/rpc/client.js +126 -0
- package/dist/api/rpc/client.js.map +1 -0
- package/dist/api/rpc/index.d.ts +3 -0
- package/dist/api/rpc/index.d.ts.map +1 -0
- package/dist/api/rpc/index.js +2 -0
- package/dist/api/rpc/index.js.map +1 -0
- package/dist/api/rpc/types.d.ts +74 -0
- package/dist/api/rpc/types.d.ts.map +1 -0
- package/dist/api/rpc/types.js +6 -0
- package/dist/api/rpc/types.js.map +1 -0
- package/dist/api/sse/client.d.ts +76 -0
- package/dist/api/sse/client.d.ts.map +1 -0
- package/dist/api/sse/client.js +203 -0
- package/dist/api/sse/client.js.map +1 -0
- package/dist/api/sse/index.d.ts +4 -0
- package/dist/api/sse/index.d.ts.map +1 -0
- package/dist/api/sse/index.js +2 -0
- package/dist/api/sse/index.js.map +1 -0
- package/dist/api/sse/types.d.ts +35 -0
- package/dist/api/sse/types.d.ts.map +1 -0
- package/dist/api/sse/types.js +6 -0
- package/dist/api/sse/types.js.map +1 -0
- package/dist/api/utils.d.ts +68 -0
- package/dist/api/utils.d.ts.map +1 -0
- package/dist/api/utils.js +83 -0
- package/dist/api/utils.js.map +1 -0
- package/dist/api/ws/client.d.ts +72 -0
- package/dist/api/ws/client.d.ts.map +1 -0
- package/dist/api/ws/client.js +202 -0
- package/dist/api/ws/client.js.map +1 -0
- package/dist/api/ws/index.d.ts +4 -0
- package/dist/api/ws/index.d.ts.map +1 -0
- package/dist/api/ws/index.js +2 -0
- package/dist/api/ws/index.js.map +1 -0
- package/dist/api/ws/types.d.ts +32 -0
- package/dist/api/ws/types.d.ts.map +1 -0
- package/dist/api/ws/types.js +6 -0
- package/dist/api/ws/types.js.map +1 -0
- package/dist/http-client/index.d.ts +1 -1
- package/dist/http-client/index.d.ts.map +1 -1
- package/dist/http-client/index.js +2 -1
- package/dist/http-client/index.js.map +1 -1
- package/dist/http-client/web-client.d.ts +3 -3
- package/dist/http-client/web-client.d.ts.map +1 -1
- package/dist/http-client/web-client.js +16 -6
- package/dist/http-client/web-client.js.map +1 -1
- package/dist/index.browser.mjs +1 -1
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +1590 -281
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1596 -281
- package/dist/index.mjs.map +4 -4
- package/dist/mero-js.d.ts +198 -7
- package/dist/mero-js.d.ts.map +1 -1
- package/dist/mero-js.js +329 -38
- package/dist/mero-js.js.map +1 -1
- package/package.json +42 -7
- package/dist/admin-api/admin-client.d.ts +0 -38
- package/dist/admin-api/admin-client.d.ts.map +0 -1
- package/dist/admin-api/admin-client.js +0 -104
- package/dist/admin-api/admin-client.js.map +0 -1
- package/dist/admin-api/admin-factory.d.ts +0 -8
- package/dist/admin-api/admin-factory.d.ts.map +0 -1
- package/dist/admin-api/admin-factory.js +0 -42
- package/dist/admin-api/admin-factory.js.map +0 -1
- package/dist/admin-api/admin-types.d.ts +0 -213
- package/dist/admin-api/admin-types.d.ts.map +0 -1
- package/dist/admin-api/admin-types.js +0 -3
- package/dist/admin-api/admin-types.js.map +0 -1
- package/dist/admin-api/index.d.ts +0 -4
- package/dist/admin-api/index.d.ts.map +0 -1
- package/dist/admin-api/index.js +0 -5
- package/dist/admin-api/index.js.map +0 -1
- package/dist/auth-api/auth-client.d.ts +0 -34
- package/dist/auth-api/auth-client.d.ts.map +0 -1
- package/dist/auth-api/auth-client.js +0 -112
- package/dist/auth-api/auth-client.js.map +0 -1
- package/dist/auth-api/auth-factory.d.ts +0 -8
- package/dist/auth-api/auth-factory.d.ts.map +0 -1
- package/dist/auth-api/auth-factory.js +0 -42
- package/dist/auth-api/auth-factory.js.map +0 -1
- package/dist/auth-api/auth-types.d.ts +0 -127
- package/dist/auth-api/auth-types.d.ts.map +0 -1
- package/dist/auth-api/auth-types.js +0 -3
- package/dist/auth-api/auth-types.js.map +0 -1
- package/dist/auth-api/index.d.ts +0 -4
- package/dist/auth-api/index.d.ts.map +0 -1
- package/dist/auth-api/index.js +0 -5
- package/dist/auth-api/index.js.map +0 -1
- package/dist/http-client/api-response.d.ts +0 -16
- package/dist/http-client/api-response.d.ts.map +0 -1
- package/dist/http-client/api-response.js +0 -2
- package/dist/http-client/api-response.js.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
1
7
|
// src/http-client/signal-utils.ts
|
|
2
8
|
function combineSignals(signals) {
|
|
3
9
|
const list = signals.filter(Boolean);
|
|
@@ -71,10 +77,15 @@ var WebHttpClient = class {
|
|
|
71
77
|
return this.request(path, { ...init, method: "GET" });
|
|
72
78
|
}
|
|
73
79
|
async post(path, body, init) {
|
|
80
|
+
const jsonBody = body ? JSON.stringify(body) : void 0;
|
|
81
|
+
if (path.includes("/refresh")) {
|
|
82
|
+
console.log("[HTTP POST /refresh] Body being sent:", jsonBody);
|
|
83
|
+
console.log("[HTTP POST /refresh] Body type:", typeof body, body ? Object.keys(body) : "undefined");
|
|
84
|
+
}
|
|
74
85
|
return this.request(path, {
|
|
75
86
|
...init,
|
|
76
87
|
method: "POST",
|
|
77
|
-
body:
|
|
88
|
+
body: jsonBody,
|
|
78
89
|
headers: {
|
|
79
90
|
"Content-Type": "application/json",
|
|
80
91
|
...init?.headers
|
|
@@ -197,8 +208,11 @@ var WebHttpClient = class {
|
|
|
197
208
|
bodyText
|
|
198
209
|
);
|
|
199
210
|
const userAborted = init?.signal?.aborted === true;
|
|
200
|
-
|
|
201
|
-
!
|
|
211
|
+
const hasAuthError = response.headers.get("x-auth-error");
|
|
212
|
+
const shouldAttemptRefresh = response.status === 401 && this.transport.refreshToken && retryCount < MAX_RETRY_ATTEMPTS && !isStreamBody && // Can't retry with stream bodies
|
|
213
|
+
!userAborted;
|
|
214
|
+
if (shouldAttemptRefresh && this.transport.refreshToken) {
|
|
215
|
+
console.log("[mero-js] 401 received, attempting token refresh...", { hasAuthError });
|
|
202
216
|
try {
|
|
203
217
|
let refreshPromise = this.refreshTokenPromise;
|
|
204
218
|
if (!refreshPromise) {
|
|
@@ -238,6 +252,7 @@ var WebHttpClient = class {
|
|
|
238
252
|
} catch (refreshError) {
|
|
239
253
|
this.refreshTokenPromise = null;
|
|
240
254
|
this.onTokenRefreshPromise = null;
|
|
255
|
+
console.log("[mero-js] Token refresh failed:", refreshError);
|
|
241
256
|
if (refreshError instanceof Error && refreshError.message.includes("onTokenRefresh")) {
|
|
242
257
|
throw refreshError;
|
|
243
258
|
}
|
|
@@ -456,394 +471,1481 @@ function createRetryableMethod(method, retryOptions = {}) {
|
|
|
456
471
|
};
|
|
457
472
|
}
|
|
458
473
|
|
|
459
|
-
// src/
|
|
474
|
+
// src/api/auth/index.ts
|
|
475
|
+
var auth_exports = {};
|
|
476
|
+
__export(auth_exports, {
|
|
477
|
+
AuthApiClient: () => AuthApiClient,
|
|
478
|
+
createAuthApiClient: () => createAuthApiClient
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// src/api/utils.ts
|
|
482
|
+
var ApiResponseError = class extends Error {
|
|
483
|
+
constructor(error) {
|
|
484
|
+
super(error.message);
|
|
485
|
+
this.name = "ApiResponseError";
|
|
486
|
+
this.type = error.type;
|
|
487
|
+
this.code = error.code;
|
|
488
|
+
this.data = error.data;
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
function hasErrorPayload(response) {
|
|
492
|
+
return typeof response === "object" && response !== null && "error" in response && response.error !== null && response.error !== void 0 && typeof response.error === "object";
|
|
493
|
+
}
|
|
494
|
+
async function unwrap(response) {
|
|
495
|
+
const result = await response;
|
|
496
|
+
if (hasErrorPayload(result)) {
|
|
497
|
+
throw new ApiResponseError(result.error);
|
|
498
|
+
}
|
|
499
|
+
if (result.data === null || result.data === void 0) {
|
|
500
|
+
throw new Error("Response data is null or undefined");
|
|
501
|
+
}
|
|
502
|
+
return result.data;
|
|
503
|
+
}
|
|
504
|
+
async function unwrapOrNull(response) {
|
|
505
|
+
const result = await response;
|
|
506
|
+
if (hasErrorPayload(result)) {
|
|
507
|
+
throw new ApiResponseError(result.error);
|
|
508
|
+
}
|
|
509
|
+
if (result.data === null || result.data === void 0) {
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
return result.data;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// src/api/auth/client.ts
|
|
460
516
|
var AuthApiClient = class {
|
|
461
|
-
constructor(httpClient) {
|
|
517
|
+
constructor(httpClient, config) {
|
|
462
518
|
this.httpClient = httpClient;
|
|
519
|
+
this.embedded = config.embedded ?? true;
|
|
463
520
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if (!response.data) {
|
|
468
|
-
throw new Error("Health response data is null");
|
|
521
|
+
getAuthPath(path) {
|
|
522
|
+
if (this.embedded) {
|
|
523
|
+
return `/auth${path}`;
|
|
469
524
|
}
|
|
470
|
-
return
|
|
525
|
+
return path;
|
|
471
526
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
throw new Error("Identity response data is null");
|
|
478
|
-
}
|
|
479
|
-
return response.data;
|
|
527
|
+
// Public endpoints
|
|
528
|
+
async getLogin() {
|
|
529
|
+
return this.httpClient.get(this.getAuthPath("/login"), {
|
|
530
|
+
parse: "text"
|
|
531
|
+
});
|
|
480
532
|
}
|
|
481
|
-
async
|
|
482
|
-
|
|
483
|
-
|
|
533
|
+
async getChallenge() {
|
|
534
|
+
return unwrap(
|
|
535
|
+
this.httpClient.get(
|
|
536
|
+
this.getAuthPath("/challenge")
|
|
537
|
+
)
|
|
484
538
|
);
|
|
485
|
-
if (!response.data) {
|
|
486
|
-
throw new Error("Providers response data is null");
|
|
487
|
-
}
|
|
488
|
-
return response.data;
|
|
489
|
-
}
|
|
490
|
-
// Authentication Endpoints
|
|
491
|
-
async getLoginPage() {
|
|
492
|
-
return this.httpClient.get("/auth/login", { parse: "text" });
|
|
493
539
|
}
|
|
494
|
-
async
|
|
495
|
-
return
|
|
540
|
+
async getToken(request) {
|
|
541
|
+
return unwrap(
|
|
542
|
+
this.httpClient.post(
|
|
543
|
+
this.getAuthPath("/token"),
|
|
544
|
+
request
|
|
545
|
+
)
|
|
546
|
+
);
|
|
496
547
|
}
|
|
497
548
|
async refreshToken(request) {
|
|
498
|
-
return
|
|
549
|
+
return unwrap(
|
|
550
|
+
this.httpClient.post(
|
|
551
|
+
this.getAuthPath("/refresh"),
|
|
552
|
+
request
|
|
553
|
+
)
|
|
554
|
+
);
|
|
499
555
|
}
|
|
500
|
-
async
|
|
501
|
-
return
|
|
556
|
+
async getProviders() {
|
|
557
|
+
return unwrap(
|
|
558
|
+
this.httpClient.get(
|
|
559
|
+
this.getAuthPath("/providers")
|
|
560
|
+
)
|
|
561
|
+
);
|
|
502
562
|
}
|
|
503
|
-
async
|
|
504
|
-
return
|
|
563
|
+
async getIdentity() {
|
|
564
|
+
return unwrap(
|
|
565
|
+
this.httpClient.get(
|
|
566
|
+
this.getAuthPath("/identity")
|
|
567
|
+
)
|
|
568
|
+
);
|
|
505
569
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
return {
|
|
516
|
-
valid: false,
|
|
517
|
-
headers: {},
|
|
518
|
-
status: 401
|
|
519
|
-
};
|
|
570
|
+
/**
|
|
571
|
+
* Validate a JWT token.
|
|
572
|
+
*
|
|
573
|
+
* Note: The server returns an empty string "" on success with auth info in headers
|
|
574
|
+
* (X-Auth-User, X-Auth-Permissions). If no error is thrown, the token is valid.
|
|
575
|
+
*/
|
|
576
|
+
async validateToken(request) {
|
|
577
|
+
const response = await this.httpClient.post(this.getAuthPath("/validate"), request);
|
|
578
|
+
if (response.data === "" || response.data === void 0 || response.data === null) {
|
|
579
|
+
return { valid: true };
|
|
520
580
|
}
|
|
581
|
+
if (typeof response.data === "object" && "valid" in response.data) {
|
|
582
|
+
return response.data;
|
|
583
|
+
}
|
|
584
|
+
return { valid: true };
|
|
521
585
|
}
|
|
586
|
+
/**
|
|
587
|
+
* Validate a JWT token using GET with Authorization header.
|
|
588
|
+
*
|
|
589
|
+
* Note: The server returns an empty string "" on success with auth info in headers
|
|
590
|
+
* (X-Auth-User, X-Auth-Permissions). If no error is thrown, the token is valid.
|
|
591
|
+
*/
|
|
522
592
|
async validateTokenGet(token) {
|
|
523
|
-
const response = await this.httpClient.
|
|
524
|
-
headers: {
|
|
593
|
+
const response = await this.httpClient.get(this.getAuthPath("/validate"), {
|
|
594
|
+
headers: {
|
|
595
|
+
Authorization: `Bearer ${token}`
|
|
596
|
+
}
|
|
525
597
|
});
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
598
|
+
if (response.data === "" || response.data === void 0 || response.data === null) {
|
|
599
|
+
return { valid: true };
|
|
600
|
+
}
|
|
601
|
+
if (typeof response.data === "object" && "valid" in response.data) {
|
|
602
|
+
return response.data;
|
|
603
|
+
}
|
|
604
|
+
return { valid: true };
|
|
530
605
|
}
|
|
531
|
-
async
|
|
532
|
-
return
|
|
606
|
+
async getHealth() {
|
|
607
|
+
return unwrap(
|
|
608
|
+
this.httpClient.get(
|
|
609
|
+
this.getAuthPath("/health")
|
|
610
|
+
)
|
|
611
|
+
);
|
|
533
612
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
return this.httpClient.
|
|
613
|
+
async getCallback(callbackUrl) {
|
|
614
|
+
const params = callbackUrl ? `?callback-url=${encodeURIComponent(callbackUrl)}` : "";
|
|
615
|
+
return this.httpClient.get(
|
|
616
|
+
this.getAuthPath(`/callback${params}`),
|
|
617
|
+
{
|
|
618
|
+
parse: "text"
|
|
619
|
+
}
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
// Protected endpoints (require JWT token)
|
|
623
|
+
async revokeToken() {
|
|
624
|
+
return unwrap(
|
|
625
|
+
this.httpClient.post(
|
|
626
|
+
this.getAuthPath("/admin/revoke"),
|
|
627
|
+
{}
|
|
628
|
+
)
|
|
629
|
+
);
|
|
537
630
|
}
|
|
538
|
-
// Key Management Endpoints
|
|
539
631
|
async listRootKeys() {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
632
|
+
return unwrap(
|
|
633
|
+
this.httpClient.get(
|
|
634
|
+
this.getAuthPath("/admin/keys")
|
|
635
|
+
)
|
|
636
|
+
);
|
|
545
637
|
}
|
|
546
638
|
async createRootKey(request) {
|
|
547
|
-
return
|
|
639
|
+
return unwrap(
|
|
640
|
+
this.httpClient.post(
|
|
641
|
+
this.getAuthPath("/admin/keys"),
|
|
642
|
+
request
|
|
643
|
+
)
|
|
644
|
+
);
|
|
548
645
|
}
|
|
549
646
|
async deleteRootKey(keyId) {
|
|
550
|
-
return
|
|
647
|
+
return unwrap(
|
|
648
|
+
this.httpClient.delete(
|
|
649
|
+
this.getAuthPath(`/admin/keys/${keyId}`)
|
|
650
|
+
)
|
|
651
|
+
);
|
|
551
652
|
}
|
|
552
|
-
// Client Management Endpoints
|
|
553
653
|
async listClientKeys() {
|
|
554
|
-
|
|
555
|
-
|
|
654
|
+
return unwrap(
|
|
655
|
+
this.httpClient.get(
|
|
656
|
+
this.getAuthPath("/admin/keys/clients")
|
|
657
|
+
)
|
|
556
658
|
);
|
|
557
|
-
if (!response.data) {
|
|
558
|
-
throw new Error("Client keys response data is null");
|
|
559
|
-
}
|
|
560
|
-
return response.data;
|
|
561
659
|
}
|
|
562
660
|
async generateClientKey(request) {
|
|
563
|
-
return
|
|
661
|
+
return unwrap(
|
|
662
|
+
this.httpClient.post(
|
|
663
|
+
this.getAuthPath("/admin/client-key"),
|
|
664
|
+
request
|
|
665
|
+
)
|
|
666
|
+
);
|
|
564
667
|
}
|
|
565
668
|
async deleteClientKey(keyId, clientId) {
|
|
566
|
-
return
|
|
567
|
-
|
|
669
|
+
return unwrap(
|
|
670
|
+
this.httpClient.delete(
|
|
671
|
+
this.getAuthPath(`/admin/keys/${keyId}/clients/${clientId}`)
|
|
672
|
+
)
|
|
568
673
|
);
|
|
569
674
|
}
|
|
570
|
-
// Permission Management Endpoints
|
|
571
675
|
async getKeyPermissions(keyId) {
|
|
572
|
-
return
|
|
573
|
-
|
|
676
|
+
return unwrap(
|
|
677
|
+
this.httpClient.get(
|
|
678
|
+
this.getAuthPath(`/admin/keys/${keyId}/permissions`)
|
|
679
|
+
)
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
async updateKeyPermissions(keyId, request) {
|
|
683
|
+
return unwrap(
|
|
684
|
+
this.httpClient.put(
|
|
685
|
+
this.getAuthPath(`/admin/keys/${keyId}/permissions`),
|
|
686
|
+
request
|
|
687
|
+
)
|
|
574
688
|
);
|
|
575
689
|
}
|
|
576
|
-
async
|
|
577
|
-
return
|
|
578
|
-
|
|
579
|
-
|
|
690
|
+
async getProtectedIdentity() {
|
|
691
|
+
return unwrap(
|
|
692
|
+
this.httpClient.get(
|
|
693
|
+
this.getAuthPath("/admin/identity")
|
|
694
|
+
)
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
async getMetrics() {
|
|
698
|
+
return unwrap(
|
|
699
|
+
this.httpClient.get(
|
|
700
|
+
this.getAuthPath("/admin/metrics")
|
|
701
|
+
)
|
|
580
702
|
);
|
|
581
703
|
}
|
|
582
704
|
};
|
|
583
705
|
|
|
584
|
-
// src/
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
706
|
+
// src/api/auth/factory.ts
|
|
707
|
+
function createAuthApiClient(httpClient, config) {
|
|
708
|
+
return new AuthApiClient(httpClient, config);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// src/api/admin/index.ts
|
|
712
|
+
var admin_exports = {};
|
|
713
|
+
__export(admin_exports, {
|
|
714
|
+
AdminApiClient: () => AdminApiClient,
|
|
715
|
+
AliasesApiClient: () => AliasesApiClient,
|
|
716
|
+
ApplicationsApiClient: () => ApplicationsApiClient,
|
|
717
|
+
BlobsApiClient: () => BlobsApiClient,
|
|
718
|
+
CapabilitiesApiClient: () => CapabilitiesApiClient,
|
|
719
|
+
ContextsApiClient: () => ContextsApiClient,
|
|
720
|
+
IdentityApiClient: () => IdentityApiClient,
|
|
721
|
+
NetworkApiClient: () => NetworkApiClient,
|
|
722
|
+
ProposalsApiClient: () => ProposalsApiClient,
|
|
723
|
+
PublicApiClient: () => PublicApiClient,
|
|
724
|
+
TeeApiClient: () => TeeApiClient,
|
|
725
|
+
createAdminApiClient: () => createAdminApiClient
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
// src/api/admin/public.ts
|
|
729
|
+
var PublicApiClient = class {
|
|
730
|
+
constructor(httpClient) {
|
|
731
|
+
this.httpClient = httpClient;
|
|
732
|
+
}
|
|
733
|
+
async health() {
|
|
734
|
+
return unwrap(
|
|
735
|
+
this.httpClient.get("/admin-api/health")
|
|
589
736
|
);
|
|
590
737
|
}
|
|
591
|
-
async
|
|
592
|
-
|
|
593
|
-
|
|
738
|
+
async isAuthed() {
|
|
739
|
+
return unwrap(
|
|
740
|
+
this.httpClient.get(
|
|
741
|
+
"/admin-api/is-authed"
|
|
742
|
+
)
|
|
594
743
|
);
|
|
595
744
|
}
|
|
596
|
-
async
|
|
597
|
-
|
|
598
|
-
|
|
745
|
+
async getCertificate() {
|
|
746
|
+
return this.httpClient.get("/admin-api/certificate", {
|
|
747
|
+
parse: "text"
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
// src/api/admin/applications.ts
|
|
753
|
+
var ApplicationsApiClient = class {
|
|
754
|
+
constructor(httpClient) {
|
|
755
|
+
this.httpClient = httpClient;
|
|
756
|
+
}
|
|
757
|
+
async installApplication(request) {
|
|
758
|
+
return unwrap(
|
|
759
|
+
this.httpClient.post(
|
|
760
|
+
"/admin-api/install-application",
|
|
761
|
+
request
|
|
762
|
+
)
|
|
599
763
|
);
|
|
600
764
|
}
|
|
601
|
-
async
|
|
602
|
-
|
|
603
|
-
|
|
765
|
+
async installDevApplication(request) {
|
|
766
|
+
return unwrap(
|
|
767
|
+
this.httpClient.post(
|
|
768
|
+
"/admin-api/install-dev-application",
|
|
769
|
+
request
|
|
770
|
+
)
|
|
604
771
|
);
|
|
605
772
|
}
|
|
606
|
-
async
|
|
607
|
-
|
|
608
|
-
|
|
773
|
+
async listApplications() {
|
|
774
|
+
return unwrap(
|
|
775
|
+
this.httpClient.get(
|
|
776
|
+
"/admin-api/applications"
|
|
777
|
+
)
|
|
609
778
|
);
|
|
610
779
|
}
|
|
611
|
-
async
|
|
612
|
-
|
|
613
|
-
|
|
780
|
+
async getApplication(applicationId) {
|
|
781
|
+
return unwrap(
|
|
782
|
+
this.httpClient.get(
|
|
783
|
+
`/admin-api/applications/${applicationId}`
|
|
784
|
+
)
|
|
614
785
|
);
|
|
615
786
|
}
|
|
616
|
-
async
|
|
617
|
-
|
|
618
|
-
|
|
787
|
+
async uninstallApplication(applicationId) {
|
|
788
|
+
return unwrap(
|
|
789
|
+
this.httpClient.delete(
|
|
790
|
+
`/admin-api/applications/${applicationId}`
|
|
791
|
+
)
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
async listPackages() {
|
|
795
|
+
return unwrap(
|
|
796
|
+
this.httpClient.get(
|
|
797
|
+
"/admin-api/packages"
|
|
798
|
+
)
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
async listVersions(packageName) {
|
|
802
|
+
return unwrap(
|
|
803
|
+
this.httpClient.get(
|
|
804
|
+
`/admin-api/packages/${packageName}/versions`
|
|
805
|
+
)
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
async getLatestVersion(packageName) {
|
|
809
|
+
return unwrap(
|
|
810
|
+
this.httpClient.get(
|
|
811
|
+
`/admin-api/packages/${packageName}/latest`
|
|
812
|
+
)
|
|
619
813
|
);
|
|
620
814
|
}
|
|
621
815
|
};
|
|
622
|
-
function createBrowserAuthApiClient(_config) {
|
|
623
|
-
const httpClient = new MockHttpClient();
|
|
624
|
-
return new AuthApiClient(httpClient);
|
|
625
|
-
}
|
|
626
|
-
function createNodeAuthApiClient(_config) {
|
|
627
|
-
const httpClient = new MockHttpClient();
|
|
628
|
-
return new AuthApiClient(httpClient);
|
|
629
|
-
}
|
|
630
|
-
function createAuthApiClient(_config) {
|
|
631
|
-
const httpClient = new MockHttpClient();
|
|
632
|
-
return new AuthApiClient(httpClient);
|
|
633
|
-
}
|
|
634
|
-
function createAuthApiClientFromHttpClient(httpClient, _config) {
|
|
635
|
-
return new AuthApiClient(httpClient);
|
|
636
|
-
}
|
|
637
816
|
|
|
638
|
-
// src/
|
|
639
|
-
var
|
|
817
|
+
// src/api/admin/contexts.ts
|
|
818
|
+
var ContextsApiClient = class {
|
|
640
819
|
constructor(httpClient) {
|
|
641
820
|
this.httpClient = httpClient;
|
|
642
821
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
return response.data;
|
|
822
|
+
async listContexts() {
|
|
823
|
+
return unwrap(
|
|
824
|
+
this.httpClient.get(
|
|
825
|
+
"/admin-api/contexts"
|
|
826
|
+
)
|
|
827
|
+
);
|
|
650
828
|
}
|
|
651
|
-
async
|
|
652
|
-
return
|
|
829
|
+
async createContext(request) {
|
|
830
|
+
return unwrap(
|
|
831
|
+
this.httpClient.post(
|
|
832
|
+
"/admin-api/contexts",
|
|
833
|
+
request
|
|
834
|
+
)
|
|
835
|
+
);
|
|
653
836
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
837
|
+
async getContext(contextId) {
|
|
838
|
+
return unwrap(
|
|
839
|
+
this.httpClient.get(
|
|
840
|
+
`/admin-api/contexts/${contextId}`
|
|
841
|
+
)
|
|
659
842
|
);
|
|
660
843
|
}
|
|
661
|
-
async
|
|
662
|
-
return
|
|
663
|
-
|
|
664
|
-
|
|
844
|
+
async deleteContext(contextId) {
|
|
845
|
+
return unwrap(
|
|
846
|
+
this.httpClient.delete(
|
|
847
|
+
`/admin-api/contexts/${contextId}`
|
|
848
|
+
)
|
|
665
849
|
);
|
|
666
850
|
}
|
|
667
|
-
async
|
|
668
|
-
return
|
|
669
|
-
|
|
851
|
+
async getContextStorage(contextId) {
|
|
852
|
+
return unwrap(
|
|
853
|
+
this.httpClient.get(
|
|
854
|
+
`/admin-api/contexts/${contextId}/storage`
|
|
855
|
+
)
|
|
670
856
|
);
|
|
671
857
|
}
|
|
672
|
-
async
|
|
673
|
-
return
|
|
858
|
+
async getContextIdentities(contextId) {
|
|
859
|
+
return unwrap(
|
|
860
|
+
this.httpClient.get(
|
|
861
|
+
`/admin-api/contexts/${contextId}/identities`
|
|
862
|
+
)
|
|
863
|
+
);
|
|
674
864
|
}
|
|
675
|
-
async
|
|
676
|
-
return
|
|
677
|
-
|
|
865
|
+
async getContextIdentitiesOwned(contextId) {
|
|
866
|
+
return unwrap(
|
|
867
|
+
this.httpClient.get(
|
|
868
|
+
`/admin-api/contexts/${contextId}/identities-owned`
|
|
869
|
+
)
|
|
678
870
|
);
|
|
679
871
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
872
|
+
async inviteToContext(request) {
|
|
873
|
+
return unwrap(
|
|
874
|
+
this.httpClient.post(
|
|
875
|
+
"/admin-api/contexts/invite",
|
|
876
|
+
request
|
|
877
|
+
)
|
|
878
|
+
);
|
|
683
879
|
}
|
|
684
|
-
async
|
|
685
|
-
return
|
|
686
|
-
|
|
880
|
+
async inviteToContextOpenInvitation(request) {
|
|
881
|
+
return unwrap(
|
|
882
|
+
this.httpClient.post(
|
|
883
|
+
"/admin-api/contexts/invite_by_open_invitation",
|
|
884
|
+
request
|
|
885
|
+
)
|
|
687
886
|
);
|
|
688
887
|
}
|
|
689
|
-
async
|
|
690
|
-
return
|
|
888
|
+
async inviteSpecializedNode(request) {
|
|
889
|
+
return unwrap(
|
|
890
|
+
this.httpClient.post(
|
|
891
|
+
"/admin-api/contexts/invite-specialized-node",
|
|
892
|
+
request
|
|
893
|
+
)
|
|
894
|
+
);
|
|
691
895
|
}
|
|
692
|
-
async
|
|
693
|
-
return
|
|
896
|
+
async joinContext(request) {
|
|
897
|
+
return unwrap(
|
|
898
|
+
this.httpClient.post(
|
|
899
|
+
"/admin-api/contexts/join",
|
|
900
|
+
request
|
|
901
|
+
)
|
|
902
|
+
);
|
|
694
903
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
904
|
+
async joinContextByOpenInvitation(request) {
|
|
905
|
+
return unwrap(
|
|
906
|
+
this.httpClient.post(
|
|
907
|
+
"/admin-api/contexts/join_by_open_invitation",
|
|
908
|
+
request
|
|
909
|
+
)
|
|
910
|
+
);
|
|
698
911
|
}
|
|
699
|
-
async
|
|
700
|
-
return
|
|
912
|
+
async updateContextApplication(contextId, request) {
|
|
913
|
+
return unwrap(
|
|
914
|
+
this.httpClient.put(
|
|
915
|
+
`/admin-api/contexts/${contextId}/application`,
|
|
916
|
+
request
|
|
917
|
+
)
|
|
918
|
+
);
|
|
701
919
|
}
|
|
702
|
-
async
|
|
703
|
-
return
|
|
920
|
+
async getContextsForApplication(applicationId) {
|
|
921
|
+
return unwrap(
|
|
922
|
+
this.httpClient.get(
|
|
923
|
+
`/admin-api/contexts/for-application/${applicationId}`
|
|
924
|
+
)
|
|
925
|
+
);
|
|
704
926
|
}
|
|
705
|
-
async
|
|
706
|
-
return
|
|
927
|
+
async getContextsWithExecutorsForApplication(applicationId) {
|
|
928
|
+
return unwrap(
|
|
929
|
+
this.httpClient.get(
|
|
930
|
+
`/admin-api/contexts/with-executors/for-application/${applicationId}`
|
|
931
|
+
)
|
|
932
|
+
);
|
|
933
|
+
}
|
|
934
|
+
async getProxyContract(contextId) {
|
|
935
|
+
return unwrap(
|
|
936
|
+
this.httpClient.get(
|
|
937
|
+
`/admin-api/contexts/${contextId}/proxy-contract`
|
|
938
|
+
)
|
|
939
|
+
);
|
|
940
|
+
}
|
|
941
|
+
async syncContext() {
|
|
942
|
+
return unwrap(
|
|
943
|
+
this.httpClient.post(
|
|
944
|
+
"/admin-api/contexts/sync",
|
|
945
|
+
{}
|
|
946
|
+
)
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
async syncContextById(contextId) {
|
|
950
|
+
return unwrap(
|
|
951
|
+
this.httpClient.post(
|
|
952
|
+
`/admin-api/contexts/sync/${contextId}`,
|
|
953
|
+
{}
|
|
954
|
+
)
|
|
955
|
+
);
|
|
707
956
|
}
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
// src/api/admin/proposals.ts
|
|
960
|
+
var ProposalsApiClient = class {
|
|
961
|
+
constructor(httpClient) {
|
|
962
|
+
this.httpClient = httpClient;
|
|
711
963
|
}
|
|
712
|
-
async
|
|
713
|
-
return
|
|
964
|
+
async getProposals(contextId, request) {
|
|
965
|
+
return unwrap(
|
|
966
|
+
this.httpClient.post(
|
|
967
|
+
`/admin-api/contexts/${contextId}/proposals`,
|
|
968
|
+
request
|
|
969
|
+
)
|
|
970
|
+
);
|
|
714
971
|
}
|
|
715
|
-
async
|
|
716
|
-
return
|
|
972
|
+
async getProposal(contextId, proposalId) {
|
|
973
|
+
return unwrap(
|
|
974
|
+
this.httpClient.get(
|
|
975
|
+
`/admin-api/contexts/${contextId}/proposals/${proposalId}`
|
|
976
|
+
)
|
|
977
|
+
);
|
|
717
978
|
}
|
|
718
|
-
async
|
|
719
|
-
return
|
|
979
|
+
async createAndApproveProposal(contextId, request) {
|
|
980
|
+
return unwrap(
|
|
981
|
+
this.httpClient.post(
|
|
982
|
+
`/admin-api/contexts/${contextId}/proposals/create-and-approve`,
|
|
983
|
+
request
|
|
984
|
+
)
|
|
985
|
+
);
|
|
720
986
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
987
|
+
async approveProposal(contextId, request) {
|
|
988
|
+
return unwrap(
|
|
989
|
+
this.httpClient.post(
|
|
990
|
+
`/admin-api/contexts/${contextId}/proposals/approve`,
|
|
991
|
+
request
|
|
992
|
+
)
|
|
993
|
+
);
|
|
724
994
|
}
|
|
725
|
-
async
|
|
726
|
-
return
|
|
995
|
+
async getNumberOfActiveProposals(contextId) {
|
|
996
|
+
return unwrap(
|
|
997
|
+
this.httpClient.get(
|
|
998
|
+
`/admin-api/contexts/${contextId}/proposals/count`
|
|
999
|
+
)
|
|
1000
|
+
);
|
|
727
1001
|
}
|
|
728
|
-
async
|
|
729
|
-
return
|
|
1002
|
+
async getNumberOfProposalApprovals(contextId, proposalId) {
|
|
1003
|
+
return unwrap(
|
|
1004
|
+
this.httpClient.get(
|
|
1005
|
+
`/admin-api/contexts/${contextId}/proposals/${proposalId}/approvals/count`
|
|
1006
|
+
)
|
|
1007
|
+
);
|
|
730
1008
|
}
|
|
731
|
-
async
|
|
732
|
-
return
|
|
733
|
-
|
|
734
|
-
|
|
1009
|
+
async getProposalApprovers(contextId, proposalId) {
|
|
1010
|
+
return unwrap(
|
|
1011
|
+
this.httpClient.get(
|
|
1012
|
+
`/admin-api/contexts/${contextId}/proposals/${proposalId}/approvals/users`
|
|
1013
|
+
)
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
1016
|
+
async getContextValue(contextId, request) {
|
|
1017
|
+
return unwrap(
|
|
1018
|
+
this.httpClient.post(
|
|
1019
|
+
`/admin-api/contexts/${contextId}/proposals/get-context-value`,
|
|
1020
|
+
request
|
|
1021
|
+
)
|
|
1022
|
+
);
|
|
1023
|
+
}
|
|
1024
|
+
async getContextStorageEntries(contextId, request) {
|
|
1025
|
+
return unwrap(
|
|
1026
|
+
this.httpClient.post(
|
|
1027
|
+
`/admin-api/contexts/${contextId}/proposals/context-storage-entries`,
|
|
1028
|
+
request
|
|
1029
|
+
)
|
|
735
1030
|
);
|
|
736
1031
|
}
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
// src/api/admin/capabilities.ts
|
|
1035
|
+
var CapabilitiesApiClient = class {
|
|
1036
|
+
constructor(httpClient) {
|
|
1037
|
+
this.httpClient = httpClient;
|
|
1038
|
+
}
|
|
1039
|
+
async grantPermission(contextId, request) {
|
|
1040
|
+
return unwrap(
|
|
1041
|
+
this.httpClient.post(
|
|
1042
|
+
`/admin-api/contexts/${contextId}/capabilities/grant`,
|
|
1043
|
+
request
|
|
1044
|
+
)
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1047
|
+
async revokePermission(contextId, request) {
|
|
1048
|
+
return unwrap(
|
|
1049
|
+
this.httpClient.post(
|
|
1050
|
+
`/admin-api/contexts/${contextId}/capabilities/revoke`,
|
|
1051
|
+
request
|
|
1052
|
+
)
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
// src/api/admin/identity.ts
|
|
1058
|
+
var IdentityApiClient = class {
|
|
1059
|
+
constructor(httpClient) {
|
|
1060
|
+
this.httpClient = httpClient;
|
|
1061
|
+
}
|
|
1062
|
+
async generateContextIdentity() {
|
|
1063
|
+
return unwrap(
|
|
1064
|
+
this.httpClient.post(
|
|
1065
|
+
"/admin-api/identity/context",
|
|
1066
|
+
{}
|
|
1067
|
+
)
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
// src/api/admin/network.ts
|
|
1073
|
+
var NetworkApiClient = class {
|
|
1074
|
+
constructor(httpClient) {
|
|
1075
|
+
this.httpClient = httpClient;
|
|
1076
|
+
}
|
|
737
1077
|
async getPeersCount() {
|
|
738
|
-
return this.httpClient.get("/
|
|
1078
|
+
return this.httpClient.get("/admin-api/peers");
|
|
1079
|
+
}
|
|
1080
|
+
};
|
|
1081
|
+
|
|
1082
|
+
// src/api/admin/blobs.ts
|
|
1083
|
+
var BlobsApiClient = class {
|
|
1084
|
+
constructor(httpClient) {
|
|
1085
|
+
this.httpClient = httpClient;
|
|
739
1086
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
1087
|
+
async uploadBlob(blob) {
|
|
1088
|
+
const response = await unwrap(
|
|
1089
|
+
this.httpClient.request(
|
|
1090
|
+
"/admin-api/blobs",
|
|
1091
|
+
{
|
|
1092
|
+
method: "PUT",
|
|
1093
|
+
body: blob,
|
|
1094
|
+
headers: {
|
|
1095
|
+
"Content-Type": "application/octet-stream"
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
)
|
|
1099
|
+
);
|
|
1100
|
+
return {
|
|
1101
|
+
blobId: response.blob_id,
|
|
1102
|
+
size: response.size,
|
|
1103
|
+
hash: response.hash ?? null
|
|
1104
|
+
};
|
|
743
1105
|
}
|
|
744
|
-
async
|
|
745
|
-
|
|
1106
|
+
async listBlobs() {
|
|
1107
|
+
const response = await unwrap(
|
|
1108
|
+
this.httpClient.get("/admin-api/blobs")
|
|
1109
|
+
);
|
|
1110
|
+
return {
|
|
1111
|
+
blobs: response.blobs.map((blob) => ({
|
|
1112
|
+
blobId: blob.blob_id,
|
|
1113
|
+
size: blob.size,
|
|
1114
|
+
hash: blob.hash ?? null
|
|
1115
|
+
}))
|
|
1116
|
+
};
|
|
746
1117
|
}
|
|
747
|
-
async
|
|
748
|
-
return this.httpClient.get(
|
|
1118
|
+
async getBlob(blobId) {
|
|
1119
|
+
return this.httpClient.get(`/admin-api/blobs/${blobId}`, {
|
|
1120
|
+
parse: "blob"
|
|
1121
|
+
});
|
|
749
1122
|
}
|
|
750
|
-
async
|
|
751
|
-
|
|
1123
|
+
async getBlobInfo(blobId) {
|
|
1124
|
+
const response = await this.httpClient.head(`/admin-api/blobs/${blobId}`);
|
|
1125
|
+
return {
|
|
1126
|
+
blobId,
|
|
1127
|
+
size: parseInt(response.headers["content-length"] || "0", 10),
|
|
1128
|
+
hash: response.headers["x-blob-hash"] || null
|
|
1129
|
+
};
|
|
752
1130
|
}
|
|
753
|
-
async
|
|
754
|
-
|
|
1131
|
+
async deleteBlob(blobId) {
|
|
1132
|
+
const response = await unwrap(
|
|
1133
|
+
this.httpClient.delete(
|
|
1134
|
+
`/admin-api/blobs/${blobId}`
|
|
1135
|
+
)
|
|
1136
|
+
);
|
|
1137
|
+
return {
|
|
1138
|
+
blobId: response.blob_id || response.blobId || blobId,
|
|
1139
|
+
deleted: response.deleted
|
|
1140
|
+
};
|
|
755
1141
|
}
|
|
756
1142
|
};
|
|
757
1143
|
|
|
758
|
-
// src/
|
|
759
|
-
var
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
1144
|
+
// src/api/admin/aliases.ts
|
|
1145
|
+
var AliasesApiClient = class {
|
|
1146
|
+
constructor(httpClient) {
|
|
1147
|
+
this.httpClient = httpClient;
|
|
1148
|
+
}
|
|
1149
|
+
async createContextAlias(request) {
|
|
1150
|
+
return unwrap(
|
|
1151
|
+
this.httpClient.post(
|
|
1152
|
+
"/admin-api/alias/create/context",
|
|
1153
|
+
request
|
|
1154
|
+
)
|
|
763
1155
|
);
|
|
764
1156
|
}
|
|
765
|
-
async
|
|
766
|
-
|
|
767
|
-
|
|
1157
|
+
async createApplicationAlias(request) {
|
|
1158
|
+
return unwrap(
|
|
1159
|
+
this.httpClient.post(
|
|
1160
|
+
"/admin-api/alias/create/application",
|
|
1161
|
+
request
|
|
1162
|
+
)
|
|
768
1163
|
);
|
|
769
1164
|
}
|
|
770
|
-
async
|
|
771
|
-
|
|
772
|
-
|
|
1165
|
+
async createIdentityAlias(context, request) {
|
|
1166
|
+
return unwrap(
|
|
1167
|
+
this.httpClient.post(
|
|
1168
|
+
`/admin-api/alias/create/identity/${context}`,
|
|
1169
|
+
request
|
|
1170
|
+
)
|
|
773
1171
|
);
|
|
774
1172
|
}
|
|
775
|
-
async
|
|
776
|
-
|
|
777
|
-
|
|
1173
|
+
async lookupContextAlias(name) {
|
|
1174
|
+
return unwrap(
|
|
1175
|
+
this.httpClient.post(
|
|
1176
|
+
`/admin-api/alias/lookup/context/${name}`,
|
|
1177
|
+
{}
|
|
1178
|
+
)
|
|
778
1179
|
);
|
|
779
1180
|
}
|
|
780
|
-
async
|
|
781
|
-
|
|
782
|
-
|
|
1181
|
+
async lookupApplicationAlias(name) {
|
|
1182
|
+
return unwrap(
|
|
1183
|
+
this.httpClient.post(
|
|
1184
|
+
`/admin-api/alias/lookup/application/${name}`,
|
|
1185
|
+
{}
|
|
1186
|
+
)
|
|
783
1187
|
);
|
|
784
1188
|
}
|
|
785
|
-
async
|
|
786
|
-
|
|
787
|
-
|
|
1189
|
+
async lookupIdentityAlias(context, name) {
|
|
1190
|
+
return unwrap(
|
|
1191
|
+
this.httpClient.post(
|
|
1192
|
+
`/admin-api/alias/lookup/identity/${context}/${name}`,
|
|
1193
|
+
{}
|
|
1194
|
+
)
|
|
788
1195
|
);
|
|
789
1196
|
}
|
|
790
|
-
async
|
|
791
|
-
|
|
792
|
-
|
|
1197
|
+
async listContextAliases() {
|
|
1198
|
+
return unwrap(
|
|
1199
|
+
this.httpClient.get(
|
|
1200
|
+
"/admin-api/alias/list/context"
|
|
1201
|
+
)
|
|
1202
|
+
);
|
|
1203
|
+
}
|
|
1204
|
+
async listApplicationAliases() {
|
|
1205
|
+
return unwrap(
|
|
1206
|
+
this.httpClient.get(
|
|
1207
|
+
"/admin-api/alias/list/application"
|
|
1208
|
+
)
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
async listIdentityAliases(context) {
|
|
1212
|
+
return unwrap(
|
|
1213
|
+
this.httpClient.get(
|
|
1214
|
+
`/admin-api/alias/list/identity/${context}`
|
|
1215
|
+
)
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
async deleteContextAlias(name) {
|
|
1219
|
+
return unwrap(
|
|
1220
|
+
this.httpClient.post(
|
|
1221
|
+
`/admin-api/alias/delete/context/${name}`,
|
|
1222
|
+
{}
|
|
1223
|
+
)
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1226
|
+
async deleteApplicationAlias(name) {
|
|
1227
|
+
return unwrap(
|
|
1228
|
+
this.httpClient.post(
|
|
1229
|
+
`/admin-api/alias/delete/application/${name}`,
|
|
1230
|
+
{}
|
|
1231
|
+
)
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1234
|
+
async deleteIdentityAlias(context, name) {
|
|
1235
|
+
return unwrap(
|
|
1236
|
+
this.httpClient.post(
|
|
1237
|
+
`/admin-api/alias/delete/identity/${context}/${name}`,
|
|
1238
|
+
{}
|
|
1239
|
+
)
|
|
793
1240
|
);
|
|
794
1241
|
}
|
|
795
1242
|
};
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
1243
|
+
|
|
1244
|
+
// src/api/admin/tee.ts
|
|
1245
|
+
var TeeApiClient = class {
|
|
1246
|
+
constructor(httpClient) {
|
|
1247
|
+
this.httpClient = httpClient;
|
|
1248
|
+
}
|
|
1249
|
+
async getTeeInfo() {
|
|
1250
|
+
return unwrap(
|
|
1251
|
+
this.httpClient.get("/admin-api/tee/info")
|
|
1252
|
+
);
|
|
1253
|
+
}
|
|
1254
|
+
async attestTee(request) {
|
|
1255
|
+
return unwrap(
|
|
1256
|
+
this.httpClient.post(
|
|
1257
|
+
"/admin-api/tee/attest",
|
|
1258
|
+
request
|
|
1259
|
+
)
|
|
1260
|
+
);
|
|
1261
|
+
}
|
|
1262
|
+
async verifyTeeQuote(request) {
|
|
1263
|
+
return unwrap(
|
|
1264
|
+
this.httpClient.post(
|
|
1265
|
+
"/admin-api/tee/verify-quote",
|
|
1266
|
+
request
|
|
1267
|
+
)
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
|
|
1272
|
+
// src/api/admin/client.ts
|
|
1273
|
+
var AdminApiClient = class {
|
|
1274
|
+
constructor(httpClient) {
|
|
1275
|
+
this.httpClient = httpClient;
|
|
1276
|
+
}
|
|
1277
|
+
/** Public endpoints (health checks, etc.) - no authentication required */
|
|
1278
|
+
get public() {
|
|
1279
|
+
if (!this._public) {
|
|
1280
|
+
this._public = new PublicApiClient(this.httpClient);
|
|
1281
|
+
}
|
|
1282
|
+
return this._public;
|
|
1283
|
+
}
|
|
1284
|
+
/** Application management (install, list, uninstall) */
|
|
1285
|
+
get applications() {
|
|
1286
|
+
if (!this._applications) {
|
|
1287
|
+
this._applications = new ApplicationsApiClient(this.httpClient);
|
|
1288
|
+
}
|
|
1289
|
+
return this._applications;
|
|
1290
|
+
}
|
|
1291
|
+
/** Context management (create, list, join, leave) */
|
|
1292
|
+
get contexts() {
|
|
1293
|
+
if (!this._contexts) {
|
|
1294
|
+
this._contexts = new ContextsApiClient(this.httpClient);
|
|
1295
|
+
}
|
|
1296
|
+
return this._contexts;
|
|
1297
|
+
}
|
|
1298
|
+
/** Proposal management for context governance */
|
|
1299
|
+
get proposals() {
|
|
1300
|
+
if (!this._proposals) {
|
|
1301
|
+
this._proposals = new ProposalsApiClient(this.httpClient);
|
|
1302
|
+
}
|
|
1303
|
+
return this._proposals;
|
|
1304
|
+
}
|
|
1305
|
+
/** Capability queries for feature detection */
|
|
1306
|
+
get capabilities() {
|
|
1307
|
+
if (!this._capabilities) {
|
|
1308
|
+
this._capabilities = new CapabilitiesApiClient(this.httpClient);
|
|
1309
|
+
}
|
|
1310
|
+
return this._capabilities;
|
|
1311
|
+
}
|
|
1312
|
+
/** Identity management (key generation, context identities) */
|
|
1313
|
+
get identity() {
|
|
1314
|
+
if (!this._identity) {
|
|
1315
|
+
this._identity = new IdentityApiClient(this.httpClient);
|
|
1316
|
+
}
|
|
1317
|
+
return this._identity;
|
|
1318
|
+
}
|
|
1319
|
+
/** Network and peer management */
|
|
1320
|
+
get network() {
|
|
1321
|
+
if (!this._network) {
|
|
1322
|
+
this._network = new NetworkApiClient(this.httpClient);
|
|
1323
|
+
}
|
|
1324
|
+
return this._network;
|
|
1325
|
+
}
|
|
1326
|
+
/** Blob storage (upload, list, delete binary data) */
|
|
1327
|
+
get blobs() {
|
|
1328
|
+
if (!this._blobs) {
|
|
1329
|
+
this._blobs = new BlobsApiClient(this.httpClient);
|
|
1330
|
+
}
|
|
1331
|
+
return this._blobs;
|
|
1332
|
+
}
|
|
1333
|
+
/** Alias management for human-readable names */
|
|
1334
|
+
get aliases() {
|
|
1335
|
+
if (!this._aliases) {
|
|
1336
|
+
this._aliases = new AliasesApiClient(this.httpClient);
|
|
1337
|
+
}
|
|
1338
|
+
return this._aliases;
|
|
1339
|
+
}
|
|
1340
|
+
/** TEE (Trusted Execution Environment) operations */
|
|
1341
|
+
get tee() {
|
|
1342
|
+
if (!this._tee) {
|
|
1343
|
+
this._tee = new TeeApiClient(this.httpClient);
|
|
1344
|
+
}
|
|
1345
|
+
return this._tee;
|
|
1346
|
+
}
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
// src/api/admin/factory.ts
|
|
1350
|
+
function createAdminApiClient(httpClient) {
|
|
809
1351
|
return new AdminApiClient(httpClient);
|
|
810
1352
|
}
|
|
811
1353
|
|
|
1354
|
+
// src/api/rpc/index.ts
|
|
1355
|
+
var rpc_exports = {};
|
|
1356
|
+
__export(rpc_exports, {
|
|
1357
|
+
JsonRpcError: () => JsonRpcError,
|
|
1358
|
+
RpcClient: () => RpcClient
|
|
1359
|
+
});
|
|
1360
|
+
|
|
1361
|
+
// src/api/rpc/client.ts
|
|
1362
|
+
var JsonRpcError = class extends Error {
|
|
1363
|
+
constructor(type, data, requestId) {
|
|
1364
|
+
const message = typeof data === "string" ? data : data?.message ? String(data.message) : type;
|
|
1365
|
+
super(message);
|
|
1366
|
+
this.type = type;
|
|
1367
|
+
this.data = data;
|
|
1368
|
+
this.requestId = requestId;
|
|
1369
|
+
this.name = "JsonRpcError";
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
var RpcClient = class {
|
|
1373
|
+
constructor(httpClient) {
|
|
1374
|
+
this.httpClient = httpClient;
|
|
1375
|
+
this.path = "/jsonrpc";
|
|
1376
|
+
}
|
|
1377
|
+
/**
|
|
1378
|
+
* Generate a random request ID
|
|
1379
|
+
*/
|
|
1380
|
+
generateRequestId() {
|
|
1381
|
+
return Math.floor(Math.random() * Math.pow(2, 32));
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Execute a method on a context
|
|
1385
|
+
*
|
|
1386
|
+
* @param params - Execution parameters
|
|
1387
|
+
* @returns The execution result
|
|
1388
|
+
* @throws JsonRpcError if execution fails
|
|
1389
|
+
*
|
|
1390
|
+
* @example
|
|
1391
|
+
* ```typescript
|
|
1392
|
+
* // Query (view) operation
|
|
1393
|
+
* const result = await rpc.execute({
|
|
1394
|
+
* contextId: 'ctx_123',
|
|
1395
|
+
* method: 'get',
|
|
1396
|
+
* args: { key: 'myKey' },
|
|
1397
|
+
* executorPublicKey: 'ed25519:...',
|
|
1398
|
+
* });
|
|
1399
|
+
* console.log(result.output); // "myValue"
|
|
1400
|
+
*
|
|
1401
|
+
* // Mutate operation
|
|
1402
|
+
* await rpc.execute({
|
|
1403
|
+
* contextId: 'ctx_123',
|
|
1404
|
+
* method: 'set',
|
|
1405
|
+
* args: { key: 'myKey', value: 'myValue' },
|
|
1406
|
+
* executorPublicKey: 'ed25519:...',
|
|
1407
|
+
* });
|
|
1408
|
+
* ```
|
|
1409
|
+
*/
|
|
1410
|
+
async execute(params) {
|
|
1411
|
+
const requestId = this.generateRequestId();
|
|
1412
|
+
const request = {
|
|
1413
|
+
jsonrpc: "2.0",
|
|
1414
|
+
id: requestId,
|
|
1415
|
+
method: "execute",
|
|
1416
|
+
params: {
|
|
1417
|
+
contextId: params.contextId,
|
|
1418
|
+
method: params.method,
|
|
1419
|
+
argsJson: params.args,
|
|
1420
|
+
executorPublicKey: params.executorPublicKey,
|
|
1421
|
+
substitute: params.substitute ?? []
|
|
1422
|
+
}
|
|
1423
|
+
};
|
|
1424
|
+
const response = await this.httpClient.post(
|
|
1425
|
+
this.path,
|
|
1426
|
+
request
|
|
1427
|
+
);
|
|
1428
|
+
if (response.id !== requestId) {
|
|
1429
|
+
throw new JsonRpcError(
|
|
1430
|
+
"MismatchedRequestIdError",
|
|
1431
|
+
`Expected request ID ${requestId}, got ${response.id}`,
|
|
1432
|
+
response.id
|
|
1433
|
+
);
|
|
1434
|
+
}
|
|
1435
|
+
if (response.error) {
|
|
1436
|
+
throw new JsonRpcError(
|
|
1437
|
+
response.error.type,
|
|
1438
|
+
response.error.data,
|
|
1439
|
+
response.id
|
|
1440
|
+
);
|
|
1441
|
+
}
|
|
1442
|
+
return response.result ?? { output: null };
|
|
1443
|
+
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Execute a query (view) method - convenience wrapper
|
|
1446
|
+
*
|
|
1447
|
+
* @param contextId - Context ID
|
|
1448
|
+
* @param method - Method name
|
|
1449
|
+
* @param args - Method arguments
|
|
1450
|
+
* @param executorPublicKey - Executor's public key
|
|
1451
|
+
*/
|
|
1452
|
+
async query(contextId, method, args, executorPublicKey) {
|
|
1453
|
+
const result = await this.execute({
|
|
1454
|
+
contextId,
|
|
1455
|
+
method,
|
|
1456
|
+
args,
|
|
1457
|
+
executorPublicKey
|
|
1458
|
+
});
|
|
1459
|
+
return result.output;
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Execute a mutate method - convenience wrapper
|
|
1463
|
+
*
|
|
1464
|
+
* @param contextId - Context ID
|
|
1465
|
+
* @param method - Method name
|
|
1466
|
+
* @param args - Method arguments
|
|
1467
|
+
* @param executorPublicKey - Executor's public key
|
|
1468
|
+
*/
|
|
1469
|
+
async mutate(contextId, method, args, executorPublicKey) {
|
|
1470
|
+
const result = await this.execute({
|
|
1471
|
+
contextId,
|
|
1472
|
+
method,
|
|
1473
|
+
args,
|
|
1474
|
+
executorPublicKey
|
|
1475
|
+
});
|
|
1476
|
+
return result.output;
|
|
1477
|
+
}
|
|
1478
|
+
};
|
|
1479
|
+
|
|
1480
|
+
// src/api/ws/index.ts
|
|
1481
|
+
var ws_exports = {};
|
|
1482
|
+
__export(ws_exports, {
|
|
1483
|
+
WebSocketClient: () => WebSocketClient
|
|
1484
|
+
});
|
|
1485
|
+
|
|
1486
|
+
// src/api/ws/client.ts
|
|
1487
|
+
var WebSocketClient = class {
|
|
1488
|
+
constructor(options) {
|
|
1489
|
+
this.ws = null;
|
|
1490
|
+
this.requestId = 0;
|
|
1491
|
+
this.pendingRequests = /* @__PURE__ */ new Map();
|
|
1492
|
+
this.eventHandlers = [];
|
|
1493
|
+
this.errorHandlers = [];
|
|
1494
|
+
this.closeHandlers = [];
|
|
1495
|
+
this.reconnectAttempts = 0;
|
|
1496
|
+
this.subscribedContexts = /* @__PURE__ */ new Set();
|
|
1497
|
+
this.options = {
|
|
1498
|
+
autoReconnect: true,
|
|
1499
|
+
reconnectDelay: 1e3,
|
|
1500
|
+
maxReconnectAttempts: 5,
|
|
1501
|
+
getAuthToken: async () => null,
|
|
1502
|
+
...options
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Connect to the WebSocket server
|
|
1507
|
+
*/
|
|
1508
|
+
async connect() {
|
|
1509
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
const wsUrl = this.options.baseUrl.replace(/^http:/, "ws:").replace(/^https:/, "wss:").replace(/\/$/, "") + "/ws";
|
|
1513
|
+
const token = await this.options.getAuthToken();
|
|
1514
|
+
return new Promise((resolve, reject) => {
|
|
1515
|
+
const url = token ? `${wsUrl}?token=${encodeURIComponent(token)}` : wsUrl;
|
|
1516
|
+
this.ws = new WebSocket(url);
|
|
1517
|
+
this.ws.onopen = () => {
|
|
1518
|
+
this.reconnectAttempts = 0;
|
|
1519
|
+
resolve();
|
|
1520
|
+
};
|
|
1521
|
+
this.ws.onerror = (_event) => {
|
|
1522
|
+
const error = new Error("WebSocket error");
|
|
1523
|
+
this.errorHandlers.forEach((h) => h(error));
|
|
1524
|
+
reject(error);
|
|
1525
|
+
};
|
|
1526
|
+
this.ws.onclose = (event) => {
|
|
1527
|
+
this.closeHandlers.forEach((h) => h(event.code, event.reason));
|
|
1528
|
+
this.handleDisconnect();
|
|
1529
|
+
};
|
|
1530
|
+
this.ws.onmessage = (event) => {
|
|
1531
|
+
this.handleMessage(event.data);
|
|
1532
|
+
};
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Disconnect from the WebSocket server
|
|
1537
|
+
*/
|
|
1538
|
+
disconnect() {
|
|
1539
|
+
this.options.autoReconnect = false;
|
|
1540
|
+
this.ws?.close();
|
|
1541
|
+
this.ws = null;
|
|
1542
|
+
this.subscribedContexts.clear();
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Subscribe to context events
|
|
1546
|
+
*/
|
|
1547
|
+
async subscribe(contextIds) {
|
|
1548
|
+
const response = await this.send({
|
|
1549
|
+
id: ++this.requestId,
|
|
1550
|
+
method: "subscribe",
|
|
1551
|
+
params: { contextIds }
|
|
1552
|
+
});
|
|
1553
|
+
if (!response.error) {
|
|
1554
|
+
contextIds.forEach((id) => this.subscribedContexts.add(id));
|
|
1555
|
+
}
|
|
1556
|
+
return response;
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* Unsubscribe from context events
|
|
1560
|
+
*/
|
|
1561
|
+
async unsubscribe(contextIds) {
|
|
1562
|
+
const response = await this.send({
|
|
1563
|
+
id: ++this.requestId,
|
|
1564
|
+
method: "unsubscribe",
|
|
1565
|
+
params: { contextIds }
|
|
1566
|
+
});
|
|
1567
|
+
if (!response.error) {
|
|
1568
|
+
contextIds.forEach((id) => this.subscribedContexts.delete(id));
|
|
1569
|
+
}
|
|
1570
|
+
return response;
|
|
1571
|
+
}
|
|
1572
|
+
/**
|
|
1573
|
+
* Add event handler
|
|
1574
|
+
*/
|
|
1575
|
+
onEvent(handler) {
|
|
1576
|
+
this.eventHandlers.push(handler);
|
|
1577
|
+
return () => {
|
|
1578
|
+
this.eventHandlers = this.eventHandlers.filter((h) => h !== handler);
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
/**
|
|
1582
|
+
* Add error handler
|
|
1583
|
+
*/
|
|
1584
|
+
onError(handler) {
|
|
1585
|
+
this.errorHandlers.push(handler);
|
|
1586
|
+
return () => {
|
|
1587
|
+
this.errorHandlers = this.errorHandlers.filter((h) => h !== handler);
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
/**
|
|
1591
|
+
* Add close handler
|
|
1592
|
+
*/
|
|
1593
|
+
onClose(handler) {
|
|
1594
|
+
this.closeHandlers.push(handler);
|
|
1595
|
+
return () => {
|
|
1596
|
+
this.closeHandlers = this.closeHandlers.filter((h) => h !== handler);
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* Check if connected
|
|
1601
|
+
*/
|
|
1602
|
+
isConnected() {
|
|
1603
|
+
return this.ws?.readyState === WebSocket.OPEN;
|
|
1604
|
+
}
|
|
1605
|
+
/**
|
|
1606
|
+
* Get subscribed context IDs
|
|
1607
|
+
*/
|
|
1608
|
+
getSubscribedContexts() {
|
|
1609
|
+
return Array.from(this.subscribedContexts);
|
|
1610
|
+
}
|
|
1611
|
+
async send(request) {
|
|
1612
|
+
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
1613
|
+
throw new Error("WebSocket not connected");
|
|
1614
|
+
}
|
|
1615
|
+
return new Promise((resolve, reject) => {
|
|
1616
|
+
const id = request.id;
|
|
1617
|
+
if (id !== null) {
|
|
1618
|
+
this.pendingRequests.set(id, { resolve, reject });
|
|
1619
|
+
}
|
|
1620
|
+
this.ws.send(JSON.stringify(request));
|
|
1621
|
+
setTimeout(() => {
|
|
1622
|
+
if (id !== null && this.pendingRequests.has(id)) {
|
|
1623
|
+
this.pendingRequests.delete(id);
|
|
1624
|
+
reject(new Error("WebSocket request timeout"));
|
|
1625
|
+
}
|
|
1626
|
+
}, 3e4);
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
handleMessage(data) {
|
|
1630
|
+
try {
|
|
1631
|
+
const message = JSON.parse(data);
|
|
1632
|
+
if (message.id !== void 0 && this.pendingRequests.has(message.id)) {
|
|
1633
|
+
const { resolve } = this.pendingRequests.get(message.id);
|
|
1634
|
+
this.pendingRequests.delete(message.id);
|
|
1635
|
+
resolve(message);
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
const event = {
|
|
1639
|
+
contextId: message.contextId || message.context_id,
|
|
1640
|
+
type: message.type || message.event,
|
|
1641
|
+
data: message.data || message.payload
|
|
1642
|
+
};
|
|
1643
|
+
this.eventHandlers.forEach((h) => h(event));
|
|
1644
|
+
} catch (error) {
|
|
1645
|
+
this.errorHandlers.forEach((h) => h(error instanceof Error ? error : new Error(String(error))));
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
handleDisconnect() {
|
|
1649
|
+
if (!this.options.autoReconnect) {
|
|
1650
|
+
return;
|
|
1651
|
+
}
|
|
1652
|
+
if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
|
|
1653
|
+
this.errorHandlers.forEach((h) => h(new Error("Max reconnect attempts reached")));
|
|
1654
|
+
return;
|
|
1655
|
+
}
|
|
1656
|
+
this.reconnectAttempts++;
|
|
1657
|
+
const delay = this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
|
|
1658
|
+
setTimeout(async () => {
|
|
1659
|
+
try {
|
|
1660
|
+
await this.connect();
|
|
1661
|
+
if (this.subscribedContexts.size > 0) {
|
|
1662
|
+
await this.subscribe(Array.from(this.subscribedContexts));
|
|
1663
|
+
}
|
|
1664
|
+
} catch {
|
|
1665
|
+
}
|
|
1666
|
+
}, delay);
|
|
1667
|
+
}
|
|
1668
|
+
};
|
|
1669
|
+
|
|
1670
|
+
// src/api/sse/index.ts
|
|
1671
|
+
var sse_exports = {};
|
|
1672
|
+
__export(sse_exports, {
|
|
1673
|
+
SseClient: () => SseClient
|
|
1674
|
+
});
|
|
1675
|
+
|
|
1676
|
+
// src/api/sse/client.ts
|
|
1677
|
+
var SseClient = class {
|
|
1678
|
+
constructor(options) {
|
|
1679
|
+
this.eventSource = null;
|
|
1680
|
+
this.sessionId = null;
|
|
1681
|
+
this.eventHandlers = [];
|
|
1682
|
+
this.errorHandlers = [];
|
|
1683
|
+
this.subscribedContexts = /* @__PURE__ */ new Set();
|
|
1684
|
+
// Track last event ID for reconnection (used for resumable streams)
|
|
1685
|
+
this._lastEventId = null;
|
|
1686
|
+
this.options = {
|
|
1687
|
+
autoReconnect: true,
|
|
1688
|
+
reconnectDelay: 1e3,
|
|
1689
|
+
getAuthToken: async () => null,
|
|
1690
|
+
...options
|
|
1691
|
+
};
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Connect to the SSE stream
|
|
1695
|
+
*/
|
|
1696
|
+
async connect() {
|
|
1697
|
+
if (this.eventSource) {
|
|
1698
|
+
throw new Error("Already connected");
|
|
1699
|
+
}
|
|
1700
|
+
const token = await this.options.getAuthToken();
|
|
1701
|
+
let url = `${this.options.baseUrl}/sse`;
|
|
1702
|
+
if (token) {
|
|
1703
|
+
url += `?token=${encodeURIComponent(token)}`;
|
|
1704
|
+
}
|
|
1705
|
+
return new Promise((resolve, reject) => {
|
|
1706
|
+
this.eventSource = new EventSource(url, {
|
|
1707
|
+
withCredentials: true
|
|
1708
|
+
});
|
|
1709
|
+
this.eventSource.addEventListener("connect", (event) => {
|
|
1710
|
+
const messageEvent = event;
|
|
1711
|
+
try {
|
|
1712
|
+
const data = messageEvent.data;
|
|
1713
|
+
this.sessionId = typeof data === "string" && data.startsWith("{") ? JSON.parse(data).session_id || JSON.parse(data).sessionId : data;
|
|
1714
|
+
resolve(this.sessionId);
|
|
1715
|
+
} catch {
|
|
1716
|
+
this.sessionId = messageEvent.data;
|
|
1717
|
+
resolve(this.sessionId);
|
|
1718
|
+
}
|
|
1719
|
+
});
|
|
1720
|
+
this.eventSource.onmessage = (event) => {
|
|
1721
|
+
this._lastEventId = event.lastEventId;
|
|
1722
|
+
try {
|
|
1723
|
+
const data = JSON.parse(event.data);
|
|
1724
|
+
const sseEvent = {
|
|
1725
|
+
id: event.lastEventId,
|
|
1726
|
+
event: "message",
|
|
1727
|
+
data
|
|
1728
|
+
};
|
|
1729
|
+
this.eventHandlers.forEach((h) => h(sseEvent));
|
|
1730
|
+
} catch {
|
|
1731
|
+
const sseEvent = {
|
|
1732
|
+
id: event.lastEventId,
|
|
1733
|
+
event: "message",
|
|
1734
|
+
data: event.data
|
|
1735
|
+
};
|
|
1736
|
+
this.eventHandlers.forEach((h) => h(sseEvent));
|
|
1737
|
+
}
|
|
1738
|
+
};
|
|
1739
|
+
this.eventSource.onerror = (_event) => {
|
|
1740
|
+
const error = new Error("SSE connection error");
|
|
1741
|
+
this.errorHandlers.forEach((h) => h(error));
|
|
1742
|
+
if (this.eventSource?.readyState === EventSource.CLOSED) {
|
|
1743
|
+
this.handleDisconnect();
|
|
1744
|
+
if (!this.sessionId) {
|
|
1745
|
+
reject(error);
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
};
|
|
1749
|
+
});
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* Disconnect from the SSE stream
|
|
1753
|
+
*/
|
|
1754
|
+
disconnect() {
|
|
1755
|
+
this.options.autoReconnect = false;
|
|
1756
|
+
this.eventSource?.close();
|
|
1757
|
+
this.eventSource = null;
|
|
1758
|
+
this.sessionId = null;
|
|
1759
|
+
this.subscribedContexts.clear();
|
|
1760
|
+
}
|
|
1761
|
+
/**
|
|
1762
|
+
* Subscribe to context events
|
|
1763
|
+
*/
|
|
1764
|
+
async subscribe(contextIds) {
|
|
1765
|
+
if (!this.sessionId) {
|
|
1766
|
+
throw new Error("Not connected");
|
|
1767
|
+
}
|
|
1768
|
+
const request = {
|
|
1769
|
+
id: this.sessionId,
|
|
1770
|
+
method: "subscribe",
|
|
1771
|
+
params: { contextIds }
|
|
1772
|
+
};
|
|
1773
|
+
const response = await this.options.httpClient.post(
|
|
1774
|
+
"/sse/subscription",
|
|
1775
|
+
request
|
|
1776
|
+
);
|
|
1777
|
+
if (!response.error) {
|
|
1778
|
+
contextIds.forEach((id) => this.subscribedContexts.add(id));
|
|
1779
|
+
}
|
|
1780
|
+
return response;
|
|
1781
|
+
}
|
|
1782
|
+
/**
|
|
1783
|
+
* Unsubscribe from context events
|
|
1784
|
+
*/
|
|
1785
|
+
async unsubscribe(contextIds) {
|
|
1786
|
+
if (!this.sessionId) {
|
|
1787
|
+
throw new Error("Not connected");
|
|
1788
|
+
}
|
|
1789
|
+
const request = {
|
|
1790
|
+
id: this.sessionId,
|
|
1791
|
+
method: "unsubscribe",
|
|
1792
|
+
params: { contextIds }
|
|
1793
|
+
};
|
|
1794
|
+
const response = await this.options.httpClient.post(
|
|
1795
|
+
"/sse/subscription",
|
|
1796
|
+
request
|
|
1797
|
+
);
|
|
1798
|
+
if (!response.error) {
|
|
1799
|
+
contextIds.forEach((id) => this.subscribedContexts.delete(id));
|
|
1800
|
+
}
|
|
1801
|
+
return response;
|
|
1802
|
+
}
|
|
1803
|
+
/**
|
|
1804
|
+
* Get session information
|
|
1805
|
+
*/
|
|
1806
|
+
async getSession() {
|
|
1807
|
+
if (!this.sessionId) {
|
|
1808
|
+
throw new Error("Not connected");
|
|
1809
|
+
}
|
|
1810
|
+
return this.options.httpClient.get(
|
|
1811
|
+
`/sse/session/${this.sessionId}`
|
|
1812
|
+
);
|
|
1813
|
+
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Add event handler
|
|
1816
|
+
*/
|
|
1817
|
+
onEvent(handler) {
|
|
1818
|
+
this.eventHandlers.push(handler);
|
|
1819
|
+
return () => {
|
|
1820
|
+
this.eventHandlers = this.eventHandlers.filter((h) => h !== handler);
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* Add error handler
|
|
1825
|
+
*/
|
|
1826
|
+
onError(handler) {
|
|
1827
|
+
this.errorHandlers.push(handler);
|
|
1828
|
+
return () => {
|
|
1829
|
+
this.errorHandlers = this.errorHandlers.filter((h) => h !== handler);
|
|
1830
|
+
};
|
|
1831
|
+
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Check if connected
|
|
1834
|
+
*/
|
|
1835
|
+
isConnected() {
|
|
1836
|
+
return this.eventSource?.readyState === EventSource.OPEN;
|
|
1837
|
+
}
|
|
1838
|
+
/**
|
|
1839
|
+
* Get current session ID
|
|
1840
|
+
*/
|
|
1841
|
+
getSessionId() {
|
|
1842
|
+
return this.sessionId;
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* Get subscribed context IDs
|
|
1846
|
+
*/
|
|
1847
|
+
getSubscribedContexts() {
|
|
1848
|
+
return Array.from(this.subscribedContexts);
|
|
1849
|
+
}
|
|
1850
|
+
/**
|
|
1851
|
+
* Get the last event ID (useful for resumable connections)
|
|
1852
|
+
*/
|
|
1853
|
+
getLastEventId() {
|
|
1854
|
+
return this._lastEventId;
|
|
1855
|
+
}
|
|
1856
|
+
handleDisconnect() {
|
|
1857
|
+
if (!this.options.autoReconnect) {
|
|
1858
|
+
return;
|
|
1859
|
+
}
|
|
1860
|
+
setTimeout(async () => {
|
|
1861
|
+
try {
|
|
1862
|
+
await this.connect();
|
|
1863
|
+
if (this.subscribedContexts.size > 0) {
|
|
1864
|
+
await this.subscribe(Array.from(this.subscribedContexts));
|
|
1865
|
+
}
|
|
1866
|
+
} catch {
|
|
1867
|
+
}
|
|
1868
|
+
}, this.options.reconnectDelay);
|
|
1869
|
+
}
|
|
1870
|
+
};
|
|
1871
|
+
|
|
812
1872
|
// src/mero-js.ts
|
|
813
1873
|
var MeroJs = class {
|
|
814
1874
|
constructor(config) {
|
|
815
1875
|
this.tokenData = null;
|
|
816
1876
|
this.refreshPromise = null;
|
|
1877
|
+
this.tokenStorage = null;
|
|
817
1878
|
this.config = {
|
|
818
1879
|
timeoutMs: 1e4,
|
|
819
1880
|
...config
|
|
820
1881
|
};
|
|
1882
|
+
this.tokenStorage = config.tokenStorage || null;
|
|
821
1883
|
const isTauri = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
|
|
1884
|
+
const authBaseUrl = this.config.authBaseUrl ?? this.config.baseUrl;
|
|
1885
|
+
const isEmbedded = authBaseUrl === this.config.baseUrl;
|
|
822
1886
|
this.httpClient = createBrowserHttpClient({
|
|
823
1887
|
baseUrl: this.config.baseUrl,
|
|
824
1888
|
getAuthToken: async () => {
|
|
825
1889
|
const token = await this.getValidToken();
|
|
826
1890
|
return token?.access_token || "";
|
|
827
1891
|
},
|
|
1892
|
+
// Wire up automatic token refresh on 401
|
|
1893
|
+
refreshToken: async () => {
|
|
1894
|
+
const refreshed = await this.performTokenRefresh();
|
|
1895
|
+
return refreshed.access_token;
|
|
1896
|
+
},
|
|
1897
|
+
onTokenRefresh: async (_newToken) => {
|
|
1898
|
+
if (this.tokenData && this.tokenStorage) {
|
|
1899
|
+
await this.tokenStorage.set(this.tokenData);
|
|
1900
|
+
}
|
|
1901
|
+
},
|
|
828
1902
|
timeoutMs: this.config.timeoutMs,
|
|
829
1903
|
credentials: this.config.requestCredentials ?? (isTauri ? "omit" : void 0)
|
|
830
1904
|
});
|
|
831
|
-
|
|
832
|
-
baseUrl:
|
|
1905
|
+
const authHttpClient = createBrowserHttpClient({
|
|
1906
|
+
baseUrl: authBaseUrl,
|
|
833
1907
|
getAuthToken: async () => {
|
|
834
1908
|
const token = await this.getValidToken();
|
|
835
1909
|
return token?.access_token || "";
|
|
836
1910
|
},
|
|
837
|
-
|
|
1911
|
+
// NO refreshToken callback - auth endpoints handle their own auth
|
|
1912
|
+
// Wiring refreshToken here would cause infinite loops when refresh fails
|
|
1913
|
+
timeoutMs: this.config.timeoutMs,
|
|
1914
|
+
credentials: this.config.requestCredentials ?? (isTauri ? "omit" : void 0)
|
|
838
1915
|
});
|
|
839
|
-
this.
|
|
840
|
-
baseUrl:
|
|
841
|
-
|
|
842
|
-
const token = await this.getValidToken();
|
|
843
|
-
return token?.access_token || "";
|
|
844
|
-
},
|
|
845
|
-
timeoutMs: this.config.timeoutMs
|
|
1916
|
+
this.authClient = createAuthApiClient(authHttpClient, {
|
|
1917
|
+
baseUrl: authBaseUrl,
|
|
1918
|
+
embedded: isEmbedded
|
|
846
1919
|
});
|
|
1920
|
+
this.adminClient = createAdminApiClient(this.httpClient);
|
|
1921
|
+
this.rpcClient = new RpcClient(this.httpClient);
|
|
1922
|
+
}
|
|
1923
|
+
/**
|
|
1924
|
+
* Initialize the SDK by loading tokens from storage (if provided).
|
|
1925
|
+
* Call this after construction if using tokenStorage.
|
|
1926
|
+
*
|
|
1927
|
+
* @example
|
|
1928
|
+
* ```typescript
|
|
1929
|
+
* const mero = new MeroJs({ baseUrl: '...', tokenStorage: myStorage });
|
|
1930
|
+
* await mero.init(); // Load stored tokens
|
|
1931
|
+
*
|
|
1932
|
+
* if (!mero.isAuthenticated()) {
|
|
1933
|
+
* await mero.authenticate({ username: '...', password: '...' });
|
|
1934
|
+
* }
|
|
1935
|
+
* ```
|
|
1936
|
+
*/
|
|
1937
|
+
async init() {
|
|
1938
|
+
console.log("[mero-js] init() called, tokenStorage:", this.tokenStorage ? "EXISTS" : "NULL");
|
|
1939
|
+
if (this.tokenStorage) {
|
|
1940
|
+
const storedToken = await this.tokenStorage.get();
|
|
1941
|
+
console.log("[mero-js] init() storedToken:", storedToken ? "LOADED" : "NULL");
|
|
1942
|
+
if (storedToken) {
|
|
1943
|
+
this.tokenData = storedToken;
|
|
1944
|
+
console.log("[mero-js] init() tokenData set, expires_at:", storedToken.expires_at);
|
|
1945
|
+
}
|
|
1946
|
+
} else {
|
|
1947
|
+
console.log("[mero-js] init() no tokenStorage configured");
|
|
1948
|
+
}
|
|
847
1949
|
}
|
|
848
1950
|
/**
|
|
849
1951
|
* Get the Auth API client
|
|
@@ -857,6 +1959,39 @@ var MeroJs = class {
|
|
|
857
1959
|
get admin() {
|
|
858
1960
|
return this.adminClient;
|
|
859
1961
|
}
|
|
1962
|
+
/**
|
|
1963
|
+
* Get the RPC client for executing queries and mutations
|
|
1964
|
+
*
|
|
1965
|
+
* @example
|
|
1966
|
+
* ```typescript
|
|
1967
|
+
* // Execute a query
|
|
1968
|
+
* const result = await meroJs.rpc.query(
|
|
1969
|
+
* 'context-id',
|
|
1970
|
+
* 'get',
|
|
1971
|
+
* { key: 'myKey' },
|
|
1972
|
+
* 'ed25519:executor-public-key'
|
|
1973
|
+
* );
|
|
1974
|
+
*
|
|
1975
|
+
* // Execute a mutation
|
|
1976
|
+
* await meroJs.rpc.mutate(
|
|
1977
|
+
* 'context-id',
|
|
1978
|
+
* 'set',
|
|
1979
|
+
* { key: 'myKey', value: 'myValue' },
|
|
1980
|
+
* 'ed25519:executor-public-key'
|
|
1981
|
+
* );
|
|
1982
|
+
*
|
|
1983
|
+
* // Or use the generic execute method
|
|
1984
|
+
* const result = await meroJs.rpc.execute({
|
|
1985
|
+
* contextId: 'context-id',
|
|
1986
|
+
* method: 'set',
|
|
1987
|
+
* args: { key: 'myKey', value: 'myValue' },
|
|
1988
|
+
* executorPublicKey: 'ed25519:...',
|
|
1989
|
+
* });
|
|
1990
|
+
* ```
|
|
1991
|
+
*/
|
|
1992
|
+
get rpc() {
|
|
1993
|
+
return this.rpcClient;
|
|
1994
|
+
}
|
|
860
1995
|
/**
|
|
861
1996
|
* Authenticate with the provided credentials
|
|
862
1997
|
* This will create the root key on first use
|
|
@@ -878,44 +2013,82 @@ var MeroJs = class {
|
|
|
878
2013
|
password: creds.password
|
|
879
2014
|
}
|
|
880
2015
|
};
|
|
881
|
-
const response = await this.authClient.
|
|
2016
|
+
const response = await this.authClient.getToken(requestBody);
|
|
2017
|
+
let expiresAt;
|
|
2018
|
+
try {
|
|
2019
|
+
const payload = JSON.parse(atob(response.access_token.split(".")[1]));
|
|
2020
|
+
expiresAt = payload.exp * 1e3;
|
|
2021
|
+
console.log("[mero-js] Extracted exp from JWT:", payload.exp, "-> expires_at:", expiresAt);
|
|
2022
|
+
} catch (e) {
|
|
2023
|
+
expiresAt = Date.now() + (response.expires_in || 3600) * 1e3;
|
|
2024
|
+
console.warn("[mero-js] Failed to parse JWT, using expires_in fallback:", expiresAt);
|
|
2025
|
+
}
|
|
882
2026
|
this.tokenData = {
|
|
883
|
-
access_token: response.
|
|
884
|
-
refresh_token: response.
|
|
885
|
-
expires_at:
|
|
886
|
-
// Default to 24 hours
|
|
2027
|
+
access_token: response.access_token,
|
|
2028
|
+
refresh_token: response.refresh_token,
|
|
2029
|
+
expires_at: expiresAt
|
|
887
2030
|
};
|
|
2031
|
+
if (this.tokenStorage) {
|
|
2032
|
+
await this.tokenStorage.set(this.tokenData);
|
|
2033
|
+
}
|
|
888
2034
|
return this.tokenData;
|
|
889
2035
|
} catch (error) {
|
|
2036
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
2037
|
+
const httpStatus = error && typeof error === "object" && "status" in error ? `HTTP ${String(error.status)}` : "";
|
|
2038
|
+
const httpStatusText = error && typeof error === "object" && "statusText" in error ? ` ${String(error.statusText)}` : "";
|
|
2039
|
+
const bodyText = error && typeof error === "object" && "bodyText" in error ? `: ${String(error.bodyText)}` : "";
|
|
890
2040
|
throw new Error(
|
|
891
|
-
`Authentication failed: ${
|
|
2041
|
+
`Authentication failed: ${httpStatus}${httpStatusText}${bodyText || errorMessage}`
|
|
892
2042
|
);
|
|
893
2043
|
}
|
|
894
2044
|
}
|
|
895
2045
|
/**
|
|
896
|
-
* Get a valid token, refreshing if necessary
|
|
2046
|
+
* Get a valid token, refreshing if necessary.
|
|
2047
|
+
* This is called automatically by the HTTP client.
|
|
2048
|
+
*
|
|
2049
|
+
* Note: The HTTP client also handles 401 errors with automatic refresh,
|
|
2050
|
+
* so this preemptive check is an optimization to avoid unnecessary 401s.
|
|
897
2051
|
*/
|
|
898
2052
|
async getValidToken() {
|
|
2053
|
+
console.log("[mero-js] getValidToken called, tokenData:", this.tokenData ? "EXISTS" : "NULL");
|
|
899
2054
|
if (!this.tokenData) {
|
|
2055
|
+
console.log("[mero-js] No tokenData, returning null");
|
|
900
2056
|
return null;
|
|
901
2057
|
}
|
|
902
|
-
const
|
|
903
|
-
|
|
2058
|
+
const now = Date.now();
|
|
2059
|
+
const expiresAt = this.tokenData.expires_at;
|
|
2060
|
+
const isExpired = now >= expiresAt;
|
|
2061
|
+
console.log("[mero-js] Token check: now=", now, "expires_at=", expiresAt, "isExpired=", isExpired);
|
|
2062
|
+
if (isExpired) {
|
|
2063
|
+
console.log("[mero-js] Token expired, attempting preemptive refresh");
|
|
904
2064
|
return await this.refreshToken();
|
|
905
2065
|
}
|
|
2066
|
+
console.log("[mero-js] Token valid, returning tokenData");
|
|
906
2067
|
return this.tokenData;
|
|
907
2068
|
}
|
|
908
2069
|
/**
|
|
909
|
-
* Refresh the access token using the refresh token
|
|
2070
|
+
* Refresh the access token using the refresh token.
|
|
2071
|
+
* Called automatically when token is about to expire or on 401.
|
|
2072
|
+
*
|
|
2073
|
+
* @deprecated Use performTokenRefresh instead - this is kept for compatibility
|
|
910
2074
|
*/
|
|
911
2075
|
async refreshToken() {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
2076
|
+
return this.performTokenRefresh();
|
|
2077
|
+
}
|
|
2078
|
+
/**
|
|
2079
|
+
* Perform the actual token refresh.
|
|
2080
|
+
* This is used by both preemptive refresh and HTTP client's 401 handler.
|
|
2081
|
+
*
|
|
2082
|
+
* Uses a shared promise to prevent multiple simultaneous refresh attempts,
|
|
2083
|
+
* even when called from multiple sources (preemptive check, HTTP 401 handler, etc.)
|
|
2084
|
+
*/
|
|
2085
|
+
async performTokenRefresh() {
|
|
915
2086
|
if (this.refreshPromise) {
|
|
2087
|
+
console.log("[mero-js] Refresh already in progress, waiting for existing promise");
|
|
916
2088
|
return this.refreshPromise;
|
|
917
2089
|
}
|
|
918
|
-
|
|
2090
|
+
console.log("[mero-js] Starting new refresh attempt");
|
|
2091
|
+
this.refreshPromise = this.doTokenRefresh();
|
|
919
2092
|
try {
|
|
920
2093
|
const newToken = await this.refreshPromise;
|
|
921
2094
|
return newToken;
|
|
@@ -924,36 +2097,87 @@ var MeroJs = class {
|
|
|
924
2097
|
}
|
|
925
2098
|
}
|
|
926
2099
|
/**
|
|
927
|
-
*
|
|
2100
|
+
* Internal: Actually perform the refresh request.
|
|
2101
|
+
* Called only from performTokenRefresh() which manages the deduplication.
|
|
928
2102
|
*/
|
|
929
|
-
async
|
|
2103
|
+
async doTokenRefresh() {
|
|
2104
|
+
console.log("[mero-js doTokenRefresh] STARTING refresh...");
|
|
2105
|
+
console.log("[mero-js doTokenRefresh] tokenData exists:", !!this.tokenData);
|
|
2106
|
+
console.log("[mero-js doTokenRefresh] access_token exists:", !!this.tokenData?.access_token);
|
|
2107
|
+
console.log("[mero-js doTokenRefresh] refresh_token exists:", !!this.tokenData?.refresh_token);
|
|
930
2108
|
if (!this.tokenData?.refresh_token) {
|
|
931
2109
|
throw new Error("No refresh token available");
|
|
932
2110
|
}
|
|
2111
|
+
if (!this.tokenData?.access_token) {
|
|
2112
|
+
throw new Error("No access token available for refresh (server requires both tokens)");
|
|
2113
|
+
}
|
|
933
2114
|
try {
|
|
934
|
-
const
|
|
2115
|
+
const refreshPayload = {
|
|
935
2116
|
access_token: this.tokenData.access_token,
|
|
936
2117
|
refresh_token: this.tokenData.refresh_token
|
|
937
|
-
}
|
|
2118
|
+
};
|
|
2119
|
+
console.log("[mero-js doTokenRefresh] Payload keys:", Object.keys(refreshPayload));
|
|
2120
|
+
console.log("[mero-js doTokenRefresh] access_token length:", refreshPayload.access_token?.length);
|
|
2121
|
+
console.log("[mero-js doTokenRefresh] refresh_token length:", refreshPayload.refresh_token?.length);
|
|
2122
|
+
const response = await this.authClient.refreshToken(refreshPayload);
|
|
2123
|
+
let expiresAt;
|
|
2124
|
+
try {
|
|
2125
|
+
const payload = JSON.parse(atob(response.access_token.split(".")[1]));
|
|
2126
|
+
expiresAt = payload.exp * 1e3;
|
|
2127
|
+
console.log("[mero-js] Extracted exp from JWT:", payload.exp, "-> expires_at:", expiresAt);
|
|
2128
|
+
} catch (e) {
|
|
2129
|
+
expiresAt = Date.now() + (response.expires_in || 3600) * 1e3;
|
|
2130
|
+
console.warn("[mero-js] Failed to parse JWT, using expires_in fallback:", expiresAt);
|
|
2131
|
+
}
|
|
938
2132
|
this.tokenData = {
|
|
939
|
-
access_token: response.
|
|
940
|
-
refresh_token: response.
|
|
941
|
-
expires_at:
|
|
942
|
-
// Default to 24 hours
|
|
2133
|
+
access_token: response.access_token,
|
|
2134
|
+
refresh_token: response.refresh_token,
|
|
2135
|
+
expires_at: expiresAt
|
|
943
2136
|
};
|
|
2137
|
+
if (this.tokenStorage) {
|
|
2138
|
+
await this.tokenStorage.set(this.tokenData);
|
|
2139
|
+
}
|
|
944
2140
|
return this.tokenData;
|
|
945
2141
|
} catch (error) {
|
|
946
|
-
|
|
2142
|
+
console.error("[mero-js] Token refresh failed:", error);
|
|
2143
|
+
const httpError = error;
|
|
2144
|
+
const status = httpError?.status;
|
|
2145
|
+
const errorBody = httpError?.body || httpError?.message || "";
|
|
2146
|
+
if (status) {
|
|
2147
|
+
console.error("[mero-js] Refresh error status:", status);
|
|
2148
|
+
console.error("[mero-js] Refresh error body:", errorBody);
|
|
2149
|
+
}
|
|
2150
|
+
if (errorBody.includes("still valid") || errorBody.includes("token valid")) {
|
|
2151
|
+
console.warn("[mero-js] Server says token is still valid - NOT clearing tokens");
|
|
2152
|
+
console.warn("[mero-js] This usually means the 401 came from a different issue (wrong endpoint, missing header, etc.)");
|
|
2153
|
+
const tokenValidError = new Error("Token is valid but request failed. Check Authorization header.");
|
|
2154
|
+
tokenValidError.tokenStillValid = true;
|
|
2155
|
+
throw tokenValidError;
|
|
2156
|
+
}
|
|
2157
|
+
if (status && status >= 400 && status < 500) {
|
|
2158
|
+
console.warn("[mero-js] Refresh failed with 4XX - clearing tokens, user must re-authenticate");
|
|
2159
|
+
await this.clearToken();
|
|
2160
|
+
throw new Error(`Session expired. Please log in again. (${status})`);
|
|
2161
|
+
}
|
|
2162
|
+
if (status && status >= 500) {
|
|
2163
|
+
console.warn("[mero-js] Refresh failed with 5XX - server error, keeping tokens");
|
|
2164
|
+
throw new Error(`Server error during refresh. Please try again later. (${status})`);
|
|
2165
|
+
}
|
|
2166
|
+
console.warn("[mero-js] Refresh failed with unknown error - clearing tokens");
|
|
2167
|
+
await this.clearToken();
|
|
947
2168
|
throw new Error(
|
|
948
2169
|
`Token refresh failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
949
2170
|
);
|
|
950
2171
|
}
|
|
951
2172
|
}
|
|
952
2173
|
/**
|
|
953
|
-
* Clear the current token
|
|
2174
|
+
* Clear the current token from memory and storage
|
|
954
2175
|
*/
|
|
955
|
-
clearToken() {
|
|
2176
|
+
async clearToken() {
|
|
956
2177
|
this.tokenData = null;
|
|
2178
|
+
if (this.tokenStorage) {
|
|
2179
|
+
await this.tokenStorage.clear();
|
|
2180
|
+
}
|
|
957
2181
|
}
|
|
958
2182
|
/**
|
|
959
2183
|
* Check if the SDK is authenticated
|
|
@@ -967,32 +2191,123 @@ var MeroJs = class {
|
|
|
967
2191
|
getTokenData() {
|
|
968
2192
|
return this.tokenData;
|
|
969
2193
|
}
|
|
2194
|
+
/**
|
|
2195
|
+
* Manually set the token data.
|
|
2196
|
+
* Use this when handling authentication externally (e.g., OAuth flows).
|
|
2197
|
+
*
|
|
2198
|
+
* @param tokenData - The token data to set, or null to clear
|
|
2199
|
+
* @example
|
|
2200
|
+
* ```typescript
|
|
2201
|
+
* // After receiving tokens from external auth flow
|
|
2202
|
+
* await meroJs.setToken({
|
|
2203
|
+
* access_token: 'eyJ...',
|
|
2204
|
+
* refresh_token: 'eyJ...',
|
|
2205
|
+
* expires_at: Date.now() + 3600000,
|
|
2206
|
+
* });
|
|
2207
|
+
* ```
|
|
2208
|
+
*/
|
|
2209
|
+
async setToken(tokenData) {
|
|
2210
|
+
this.tokenData = tokenData;
|
|
2211
|
+
if (this.tokenStorage) {
|
|
2212
|
+
if (tokenData) {
|
|
2213
|
+
await this.tokenStorage.set(tokenData);
|
|
2214
|
+
} else {
|
|
2215
|
+
await this.tokenStorage.clear();
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
/**
|
|
2220
|
+
* Create a WebSocket client for real-time event subscriptions
|
|
2221
|
+
*
|
|
2222
|
+
* @param options - Optional WebSocket client options to override defaults
|
|
2223
|
+
* @returns A new WebSocketClient instance
|
|
2224
|
+
*
|
|
2225
|
+
* @example
|
|
2226
|
+
* ```typescript
|
|
2227
|
+
* const ws = meroJs.createWebSocket();
|
|
2228
|
+
* await ws.connect();
|
|
2229
|
+
*
|
|
2230
|
+
* ws.onEvent((event) => {
|
|
2231
|
+
* console.log('Received event:', event);
|
|
2232
|
+
* });
|
|
2233
|
+
*
|
|
2234
|
+
* await ws.subscribe(['context-id-1', 'context-id-2']);
|
|
2235
|
+
*
|
|
2236
|
+
* // Later...
|
|
2237
|
+
* ws.disconnect();
|
|
2238
|
+
* ```
|
|
2239
|
+
*/
|
|
2240
|
+
createWebSocket(options) {
|
|
2241
|
+
return new WebSocketClient({
|
|
2242
|
+
baseUrl: this.config.baseUrl,
|
|
2243
|
+
getAuthToken: async () => this.tokenData?.access_token || null,
|
|
2244
|
+
...options
|
|
2245
|
+
});
|
|
2246
|
+
}
|
|
2247
|
+
/**
|
|
2248
|
+
* Create an SSE client for server-sent event streaming
|
|
2249
|
+
*
|
|
2250
|
+
* @param options - Optional SSE client options to override defaults
|
|
2251
|
+
* @returns A new SseClient instance
|
|
2252
|
+
*
|
|
2253
|
+
* @example
|
|
2254
|
+
* ```typescript
|
|
2255
|
+
* const sse = meroJs.createSse();
|
|
2256
|
+
* const sessionId = await sse.connect();
|
|
2257
|
+
*
|
|
2258
|
+
* sse.onEvent((event) => {
|
|
2259
|
+
* console.log('Received event:', event);
|
|
2260
|
+
* });
|
|
2261
|
+
*
|
|
2262
|
+
* await sse.subscribe(['context-id-1', 'context-id-2']);
|
|
2263
|
+
*
|
|
2264
|
+
* // Get session info
|
|
2265
|
+
* const session = await sse.getSession();
|
|
2266
|
+
*
|
|
2267
|
+
* // Later...
|
|
2268
|
+
* sse.disconnect();
|
|
2269
|
+
* ```
|
|
2270
|
+
*/
|
|
2271
|
+
createSse(options) {
|
|
2272
|
+
return new SseClient({
|
|
2273
|
+
baseUrl: this.config.baseUrl,
|
|
2274
|
+
httpClient: this.httpClient,
|
|
2275
|
+
getAuthToken: async () => this.tokenData?.access_token || null,
|
|
2276
|
+
...options
|
|
2277
|
+
});
|
|
2278
|
+
}
|
|
970
2279
|
};
|
|
971
2280
|
function createMeroJs(config) {
|
|
972
2281
|
return new MeroJs(config);
|
|
973
2282
|
}
|
|
974
2283
|
export {
|
|
2284
|
+
admin_exports as AdminApi,
|
|
975
2285
|
AdminApiClient,
|
|
2286
|
+
ApiResponseError,
|
|
2287
|
+
auth_exports as AuthApi,
|
|
976
2288
|
AuthApiClient,
|
|
977
2289
|
HTTPError,
|
|
2290
|
+
JsonRpcError,
|
|
978
2291
|
MeroJs,
|
|
2292
|
+
rpc_exports as RpcApi,
|
|
2293
|
+
RpcClient,
|
|
2294
|
+
sse_exports as SseApi,
|
|
2295
|
+
SseClient,
|
|
979
2296
|
WebHttpClient,
|
|
2297
|
+
WebSocketClient,
|
|
2298
|
+
ws_exports as WsApi,
|
|
980
2299
|
combineSignals,
|
|
981
2300
|
createAdminApiClient,
|
|
982
|
-
createAdminApiClientFromHttpClient,
|
|
983
2301
|
createAuthApiClient,
|
|
984
|
-
createAuthApiClientFromHttpClient,
|
|
985
|
-
createBrowserAdminApiClient,
|
|
986
|
-
createBrowserAuthApiClient,
|
|
987
2302
|
createBrowserHttpClient,
|
|
988
2303
|
createHttpClient,
|
|
989
2304
|
createMeroJs,
|
|
990
|
-
createNodeAdminApiClient,
|
|
991
|
-
createNodeAuthApiClient,
|
|
992
2305
|
createNodeHttpClient,
|
|
993
2306
|
createRetryableMethod,
|
|
994
2307
|
createTimeoutSignal,
|
|
995
2308
|
createUniversalHttpClient,
|
|
2309
|
+
unwrap,
|
|
2310
|
+
unwrapOrNull,
|
|
996
2311
|
withRetry
|
|
997
2312
|
};
|
|
998
2313
|
//# sourceMappingURL=index.mjs.map
|