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