@calimero-network/mero-js 2.0.0-beta.1 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +302 -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 +497 -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 +1033 -1415
- 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 +1032 -1420
- 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,1161 @@ 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) {
|
|
804
|
-
return unwrap(
|
|
805
|
-
this.httpClient.post(
|
|
806
|
-
"/admin-api/install-application",
|
|
807
|
-
request
|
|
808
|
-
)
|
|
809
|
-
);
|
|
709
|
+
return unwrap(await this.httpClient.post("/admin-api/install-application", request));
|
|
810
710
|
}
|
|
811
711
|
async installDevApplication(request) {
|
|
812
|
-
return unwrap(
|
|
813
|
-
this.httpClient.post(
|
|
814
|
-
"/admin-api/install-dev-application",
|
|
815
|
-
request
|
|
816
|
-
)
|
|
817
|
-
);
|
|
712
|
+
return unwrap(await this.httpClient.post("/admin-api/install-dev-application", request));
|
|
818
713
|
}
|
|
819
|
-
async
|
|
820
|
-
return unwrap(
|
|
821
|
-
this.httpClient.get(
|
|
822
|
-
"/admin-api/applications"
|
|
823
|
-
)
|
|
824
|
-
);
|
|
714
|
+
async uninstallApplication(appId) {
|
|
715
|
+
return unwrap(await this.httpClient.delete(`/admin-api/applications/${appId}`));
|
|
825
716
|
}
|
|
826
|
-
async
|
|
827
|
-
return unwrap(
|
|
828
|
-
this.httpClient.get(
|
|
829
|
-
`/admin-api/applications/${applicationId}`
|
|
830
|
-
)
|
|
831
|
-
);
|
|
717
|
+
async listApplications() {
|
|
718
|
+
return unwrap(await this.httpClient.get("/admin-api/applications"));
|
|
832
719
|
}
|
|
833
|
-
async
|
|
834
|
-
return unwrap(
|
|
835
|
-
this.httpClient.delete(
|
|
836
|
-
`/admin-api/applications/${applicationId}`
|
|
837
|
-
)
|
|
838
|
-
);
|
|
720
|
+
async getApplication(appId) {
|
|
721
|
+
return unwrap(await this.httpClient.get(`/admin-api/applications/${appId}`));
|
|
839
722
|
}
|
|
723
|
+
// ---- Package Management ----
|
|
840
724
|
async listPackages() {
|
|
841
|
-
return unwrap(
|
|
842
|
-
this.httpClient.get(
|
|
843
|
-
"/admin-api/packages"
|
|
844
|
-
)
|
|
845
|
-
);
|
|
846
|
-
}
|
|
847
|
-
async listVersions(packageName) {
|
|
848
|
-
return unwrap(
|
|
849
|
-
this.httpClient.get(
|
|
850
|
-
`/admin-api/packages/${packageName}/versions`
|
|
851
|
-
)
|
|
852
|
-
);
|
|
725
|
+
return unwrap(await this.httpClient.get("/admin-api/packages"));
|
|
853
726
|
}
|
|
854
|
-
async
|
|
727
|
+
async listPackageVersions(packageName) {
|
|
855
728
|
return unwrap(
|
|
856
|
-
this.httpClient.get(
|
|
857
|
-
`/admin-api/packages/${packageName}/
|
|
729
|
+
await this.httpClient.get(
|
|
730
|
+
`/admin-api/packages/${encodeURIComponent(packageName)}/versions`
|
|
858
731
|
)
|
|
859
732
|
);
|
|
860
733
|
}
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
var ContextsApiClient = class {
|
|
865
|
-
constructor(httpClient) {
|
|
866
|
-
this.httpClient = httpClient;
|
|
867
|
-
}
|
|
868
|
-
async listContexts() {
|
|
869
|
-
return unwrap(
|
|
870
|
-
this.httpClient.get(
|
|
871
|
-
"/admin-api/contexts"
|
|
872
|
-
)
|
|
734
|
+
async getLatestPackageVersion(packageName) {
|
|
735
|
+
return this.httpClient.get(
|
|
736
|
+
`/admin-api/packages/${encodeURIComponent(packageName)}/latest`
|
|
873
737
|
);
|
|
874
738
|
}
|
|
739
|
+
// ---- Context Management ----
|
|
875
740
|
async createContext(request) {
|
|
876
|
-
return unwrap(
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
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"));
|
|
882
757
|
}
|
|
883
758
|
async getContext(contextId) {
|
|
884
|
-
return unwrap(
|
|
885
|
-
this.httpClient.get(
|
|
886
|
-
`/admin-api/contexts/${contextId}`
|
|
887
|
-
)
|
|
888
|
-
);
|
|
759
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}`));
|
|
889
760
|
}
|
|
890
|
-
async
|
|
891
|
-
return unwrap(
|
|
892
|
-
this.httpClient.delete(
|
|
893
|
-
`/admin-api/contexts/${contextId}`
|
|
894
|
-
)
|
|
895
|
-
);
|
|
761
|
+
async getContextsForApplication(applicationId) {
|
|
762
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/for-application/${applicationId}`));
|
|
896
763
|
}
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
`/admin-api/contexts/${contextId}/storage`
|
|
901
|
-
)
|
|
902
|
-
);
|
|
764
|
+
// ---- Context Identity ----
|
|
765
|
+
async generateContextIdentity() {
|
|
766
|
+
return unwrap(await this.httpClient.post("/admin-api/identity/context", {}));
|
|
903
767
|
}
|
|
904
768
|
async getContextIdentities(contextId) {
|
|
905
|
-
return unwrap(
|
|
906
|
-
this.httpClient.get(
|
|
907
|
-
`/admin-api/contexts/${contextId}/identities`
|
|
908
|
-
)
|
|
909
|
-
);
|
|
769
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/identities`));
|
|
910
770
|
}
|
|
911
771
|
async getContextIdentitiesOwned(contextId) {
|
|
912
|
-
return unwrap(
|
|
913
|
-
this.httpClient.get(
|
|
914
|
-
`/admin-api/contexts/${contextId}/identities-owned`
|
|
915
|
-
)
|
|
916
|
-
);
|
|
772
|
+
return unwrap(await this.httpClient.get(`/admin-api/contexts/${contextId}/identities-owned`));
|
|
917
773
|
}
|
|
918
|
-
|
|
774
|
+
// ---- Context join (group membership) ----
|
|
775
|
+
async joinContext(contextId) {
|
|
919
776
|
return unwrap(
|
|
920
|
-
this.httpClient.post(
|
|
921
|
-
"/admin-api/contexts/invite",
|
|
922
|
-
request
|
|
923
|
-
)
|
|
777
|
+
await this.httpClient.post(`/admin-api/contexts/${contextId}/join`, {})
|
|
924
778
|
);
|
|
925
779
|
}
|
|
926
|
-
|
|
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) {
|
|
927
791
|
return unwrap(
|
|
928
|
-
this.httpClient.post(
|
|
929
|
-
"/admin-api/contexts/
|
|
792
|
+
await this.httpClient.post(
|
|
793
|
+
"/admin-api/contexts/invite-specialized-node",
|
|
930
794
|
request
|
|
931
795
|
)
|
|
932
796
|
);
|
|
933
797
|
}
|
|
934
|
-
async
|
|
798
|
+
async updateContextApplication(contextId, request) {
|
|
799
|
+
await this.httpClient.post(`/admin-api/contexts/${contextId}/application`, request);
|
|
800
|
+
}
|
|
801
|
+
async getContextsWithExecutorsForApplication(applicationId) {
|
|
935
802
|
return unwrap(
|
|
936
|
-
this.httpClient.
|
|
937
|
-
|
|
938
|
-
request
|
|
803
|
+
await this.httpClient.get(
|
|
804
|
+
`/admin-api/contexts/with-executors/for-application/${applicationId}`
|
|
939
805
|
)
|
|
940
806
|
);
|
|
941
807
|
}
|
|
942
|
-
|
|
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) {
|
|
943
829
|
return unwrap(
|
|
944
|
-
this.httpClient.post(
|
|
945
|
-
|
|
946
|
-
|
|
830
|
+
await this.httpClient.post(
|
|
831
|
+
`/admin-api/alias/lookup/context/${encodeURIComponent(name)}`,
|
|
832
|
+
{}
|
|
947
833
|
)
|
|
948
834
|
);
|
|
949
835
|
}
|
|
950
|
-
async
|
|
836
|
+
async lookupApplicationAlias(name) {
|
|
951
837
|
return unwrap(
|
|
952
|
-
this.httpClient.post(
|
|
953
|
-
|
|
954
|
-
|
|
838
|
+
await this.httpClient.post(
|
|
839
|
+
`/admin-api/alias/lookup/application/${encodeURIComponent(name)}`,
|
|
840
|
+
{}
|
|
955
841
|
)
|
|
956
842
|
);
|
|
957
843
|
}
|
|
958
|
-
async
|
|
844
|
+
async deleteContextAlias(name) {
|
|
959
845
|
return unwrap(
|
|
960
|
-
this.httpClient.
|
|
961
|
-
`/admin-api/
|
|
962
|
-
|
|
846
|
+
await this.httpClient.post(
|
|
847
|
+
`/admin-api/alias/delete/context/${encodeURIComponent(name)}`,
|
|
848
|
+
{}
|
|
963
849
|
)
|
|
964
850
|
);
|
|
965
851
|
}
|
|
966
|
-
async
|
|
852
|
+
async deleteApplicationAlias(name) {
|
|
967
853
|
return unwrap(
|
|
968
|
-
this.httpClient.
|
|
969
|
-
`/admin-api/
|
|
854
|
+
await this.httpClient.post(
|
|
855
|
+
`/admin-api/alias/delete/application/${encodeURIComponent(name)}`,
|
|
856
|
+
{}
|
|
970
857
|
)
|
|
971
858
|
);
|
|
972
859
|
}
|
|
973
|
-
async
|
|
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"));
|
|
865
|
+
}
|
|
866
|
+
// ---- Context Identity Aliases ----
|
|
867
|
+
async listContextIdentityAliases(contextId) {
|
|
974
868
|
return unwrap(
|
|
975
|
-
this.httpClient.get(
|
|
976
|
-
`/admin-api/
|
|
869
|
+
await this.httpClient.get(
|
|
870
|
+
`/admin-api/alias/list/identity/${contextId}`
|
|
977
871
|
)
|
|
978
872
|
);
|
|
979
873
|
}
|
|
980
|
-
async
|
|
874
|
+
async createContextIdentityAlias(contextId, request) {
|
|
981
875
|
return unwrap(
|
|
982
|
-
this.httpClient.
|
|
983
|
-
`/admin-api/
|
|
876
|
+
await this.httpClient.post(
|
|
877
|
+
`/admin-api/alias/create/identity/${contextId}`,
|
|
878
|
+
request
|
|
984
879
|
)
|
|
985
880
|
);
|
|
986
881
|
}
|
|
987
|
-
async
|
|
882
|
+
async lookupContextIdentityAlias(contextId, name) {
|
|
988
883
|
return unwrap(
|
|
989
|
-
this.httpClient.post(
|
|
990
|
-
|
|
884
|
+
await this.httpClient.post(
|
|
885
|
+
`/admin-api/alias/lookup/identity/${contextId}/${encodeURIComponent(name)}`,
|
|
991
886
|
{}
|
|
992
887
|
)
|
|
993
888
|
);
|
|
994
889
|
}
|
|
995
|
-
async
|
|
890
|
+
async deleteContextIdentityAlias(contextId, name) {
|
|
996
891
|
return unwrap(
|
|
997
|
-
this.httpClient.post(
|
|
998
|
-
`/admin-api/
|
|
892
|
+
await this.httpClient.post(
|
|
893
|
+
`/admin-api/alias/delete/identity/${contextId}/${encodeURIComponent(name)}`,
|
|
999
894
|
{}
|
|
1000
895
|
)
|
|
1001
896
|
);
|
|
1002
897
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
var ProposalsApiClient = class {
|
|
1007
|
-
constructor(httpClient) {
|
|
1008
|
-
this.httpClient = httpClient;
|
|
898
|
+
// ---- Namespace Management ----
|
|
899
|
+
async listNamespaces() {
|
|
900
|
+
return unwrap(await this.httpClient.get("/admin-api/namespaces"));
|
|
1009
901
|
}
|
|
1010
|
-
async
|
|
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) {
|
|
1011
915
|
return unwrap(
|
|
1012
|
-
this.httpClient.
|
|
1013
|
-
|
|
1014
|
-
request
|
|
1015
|
-
|
|
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
|
+
})
|
|
1016
921
|
);
|
|
1017
922
|
}
|
|
1018
|
-
async
|
|
923
|
+
async createNamespaceInvitation(namespaceId, request) {
|
|
1019
924
|
return unwrap(
|
|
1020
|
-
this.httpClient.
|
|
1021
|
-
`/admin-api/
|
|
925
|
+
await this.httpClient.post(
|
|
926
|
+
`/admin-api/namespaces/${namespaceId}/invite`,
|
|
927
|
+
request ?? {}
|
|
1022
928
|
)
|
|
1023
929
|
);
|
|
1024
930
|
}
|
|
1025
|
-
async
|
|
931
|
+
async joinNamespace(namespaceId, request) {
|
|
1026
932
|
return unwrap(
|
|
1027
|
-
this.httpClient.post(
|
|
1028
|
-
`/admin-api/
|
|
1029
|
-
request
|
|
933
|
+
await this.httpClient.post(
|
|
934
|
+
`/admin-api/namespaces/${namespaceId}/join`,
|
|
935
|
+
request,
|
|
936
|
+
{ timeoutMs: 65e3 }
|
|
1030
937
|
)
|
|
1031
938
|
);
|
|
1032
939
|
}
|
|
1033
|
-
async
|
|
940
|
+
async createGroupInNamespace(namespaceId, request) {
|
|
1034
941
|
return unwrap(
|
|
1035
|
-
this.httpClient.post(
|
|
1036
|
-
`/admin-api/
|
|
1037
|
-
request
|
|
942
|
+
await this.httpClient.post(
|
|
943
|
+
`/admin-api/namespaces/${namespaceId}/groups`,
|
|
944
|
+
request ?? {}
|
|
1038
945
|
)
|
|
1039
946
|
);
|
|
1040
947
|
}
|
|
1041
|
-
async
|
|
1042
|
-
return unwrap(
|
|
1043
|
-
this.httpClient.get(
|
|
1044
|
-
`/admin-api/contexts/${contextId}/proposals/count`
|
|
1045
|
-
)
|
|
1046
|
-
);
|
|
948
|
+
async listNamespaceGroups(namespaceId) {
|
|
949
|
+
return unwrap(await this.httpClient.get(`/admin-api/namespaces/${namespaceId}/groups`));
|
|
1047
950
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
`/admin-api/contexts/${contextId}/proposals/${proposalId}/approvals/count`
|
|
1052
|
-
)
|
|
1053
|
-
);
|
|
951
|
+
// ---- Group Management ----
|
|
952
|
+
async getGroupInfo(groupId) {
|
|
953
|
+
return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}`));
|
|
1054
954
|
}
|
|
1055
|
-
async
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
`/admin-api/
|
|
1059
|
-
|
|
1060
|
-
|
|
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}`));
|
|
1061
966
|
}
|
|
1062
|
-
async
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
`/admin-api/contexts/${contextId}/proposals/get-context-value`,
|
|
1066
|
-
request
|
|
1067
|
-
)
|
|
967
|
+
async listGroupMembers(groupId) {
|
|
968
|
+
const response = await this.httpClient.get(
|
|
969
|
+
`/admin-api/groups/${groupId}/members`
|
|
1068
970
|
);
|
|
971
|
+
if (!Array.isArray(response?.members)) {
|
|
972
|
+
const safeId = String(groupId).replace(/[\r\n\t\s]/g, "").slice(0, 64);
|
|
973
|
+
throw new Error(
|
|
974
|
+
`Invalid listGroupMembers response for group ${safeId}: missing or non-array \`members\` field`
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
return response;
|
|
1069
978
|
}
|
|
1070
|
-
async
|
|
1071
|
-
return unwrap(
|
|
1072
|
-
this.httpClient.post(
|
|
1073
|
-
`/admin-api/contexts/${contextId}/proposals/context-storage-entries`,
|
|
1074
|
-
request
|
|
1075
|
-
)
|
|
1076
|
-
);
|
|
979
|
+
async listGroupContexts(groupId) {
|
|
980
|
+
return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}/contexts`));
|
|
1077
981
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
// src/api/admin/capabilities.ts
|
|
1081
|
-
var CapabilitiesApiClient = class {
|
|
1082
|
-
constructor(httpClient) {
|
|
1083
|
-
this.httpClient = httpClient;
|
|
982
|
+
async addGroupMembers(groupId, request) {
|
|
983
|
+
await this.httpClient.post(`/admin-api/groups/${groupId}/members`, request);
|
|
1084
984
|
}
|
|
1085
|
-
async
|
|
1086
|
-
|
|
1087
|
-
this.httpClient.post(
|
|
1088
|
-
`/admin-api/contexts/${contextId}/capabilities/grant`,
|
|
1089
|
-
request
|
|
1090
|
-
)
|
|
1091
|
-
);
|
|
985
|
+
async removeGroupMembers(groupId, request) {
|
|
986
|
+
await this.httpClient.post(`/admin-api/groups/${groupId}/members/remove`, request);
|
|
1092
987
|
}
|
|
1093
|
-
async
|
|
1094
|
-
|
|
1095
|
-
this.httpClient.post(
|
|
1096
|
-
`/admin-api/contexts/${contextId}/capabilities/revoke`,
|
|
1097
|
-
request
|
|
1098
|
-
)
|
|
1099
|
-
);
|
|
1100
|
-
}
|
|
1101
|
-
};
|
|
1102
|
-
|
|
1103
|
-
// src/api/admin/identity.ts
|
|
1104
|
-
var IdentityApiClient = class {
|
|
1105
|
-
constructor(httpClient) {
|
|
1106
|
-
this.httpClient = httpClient;
|
|
988
|
+
async updateMemberRole(groupId, identity, request) {
|
|
989
|
+
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/role`, request);
|
|
1107
990
|
}
|
|
1108
|
-
async
|
|
991
|
+
async getMemberCapabilities(groupId, identity) {
|
|
1109
992
|
return unwrap(
|
|
1110
|
-
this.httpClient.
|
|
1111
|
-
|
|
1112
|
-
{}
|
|
993
|
+
await this.httpClient.get(
|
|
994
|
+
`/admin-api/groups/${groupId}/members/${identity}/capabilities`
|
|
1113
995
|
)
|
|
1114
996
|
);
|
|
1115
997
|
}
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
// src/api/admin/network.ts
|
|
1119
|
-
var NetworkApiClient = class {
|
|
1120
|
-
constructor(httpClient) {
|
|
1121
|
-
this.httpClient = httpClient;
|
|
998
|
+
async setMemberCapabilities(groupId, identity, request) {
|
|
999
|
+
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/capabilities`, request);
|
|
1122
1000
|
}
|
|
1123
|
-
async
|
|
1124
|
-
|
|
1001
|
+
async setDefaultCapabilities(groupId, request) {
|
|
1002
|
+
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/default-capabilities`, request);
|
|
1125
1003
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
// src/api/admin/blobs.ts
|
|
1129
|
-
var BlobsApiClient = class {
|
|
1130
|
-
constructor(httpClient) {
|
|
1131
|
-
this.httpClient = httpClient;
|
|
1004
|
+
async setSubgroupVisibility(groupId, request) {
|
|
1005
|
+
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/subgroup-visibility`, request);
|
|
1132
1006
|
}
|
|
1133
|
-
async
|
|
1134
|
-
|
|
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
|
-
};
|
|
1007
|
+
async setTeeAdmissionPolicy(groupId, request) {
|
|
1008
|
+
await this.httpClient.put(`/admin-api/groups/${groupId}/settings/tee-admission-policy`, request);
|
|
1151
1009
|
}
|
|
1152
|
-
async
|
|
1153
|
-
|
|
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
|
-
};
|
|
1010
|
+
async updateGroupSettings(groupId, request) {
|
|
1011
|
+
await this.httpClient.patch(`/admin-api/groups/${groupId}`, request);
|
|
1163
1012
|
}
|
|
1164
|
-
async
|
|
1165
|
-
|
|
1166
|
-
parse: "blob"
|
|
1167
|
-
});
|
|
1013
|
+
async setGroupAlias(groupId, request) {
|
|
1014
|
+
await this.httpClient.put(`/admin-api/groups/${groupId}/alias`, request);
|
|
1168
1015
|
}
|
|
1169
|
-
async
|
|
1170
|
-
|
|
1171
|
-
return {
|
|
1172
|
-
blobId,
|
|
1173
|
-
size: parseInt(response.headers["content-length"] || "0", 10),
|
|
1174
|
-
hash: response.headers["x-blob-hash"] || null
|
|
1175
|
-
};
|
|
1016
|
+
async setMemberAlias(groupId, identity, request) {
|
|
1017
|
+
await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/alias`, request);
|
|
1176
1018
|
}
|
|
1177
|
-
async
|
|
1178
|
-
|
|
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
|
-
};
|
|
1019
|
+
async syncGroup(groupId, request) {
|
|
1020
|
+
return unwrap(await this.httpClient.post(`/admin-api/groups/${groupId}/sync`, request ?? {}));
|
|
1187
1021
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
// src/api/admin/aliases.ts
|
|
1191
|
-
var AliasesApiClient = class {
|
|
1192
|
-
constructor(httpClient) {
|
|
1193
|
-
this.httpClient = httpClient;
|
|
1194
|
-
}
|
|
1195
|
-
async createContextAlias(request) {
|
|
1022
|
+
async registerGroupSigningKey(groupId, request) {
|
|
1196
1023
|
return unwrap(
|
|
1197
|
-
this.httpClient.post(
|
|
1198
|
-
|
|
1024
|
+
await this.httpClient.post(
|
|
1025
|
+
`/admin-api/groups/${groupId}/signing-key`,
|
|
1199
1026
|
request
|
|
1200
1027
|
)
|
|
1201
1028
|
);
|
|
1202
1029
|
}
|
|
1203
|
-
async
|
|
1204
|
-
return unwrap(
|
|
1205
|
-
this.httpClient.post(
|
|
1206
|
-
"/admin-api/alias/create/application",
|
|
1207
|
-
request
|
|
1208
|
-
)
|
|
1209
|
-
);
|
|
1030
|
+
async upgradeGroup(groupId, request) {
|
|
1031
|
+
return unwrap(await this.httpClient.post(`/admin-api/groups/${groupId}/upgrade`, request));
|
|
1210
1032
|
}
|
|
1211
|
-
async
|
|
1033
|
+
async getGroupUpgradeStatus(groupId) {
|
|
1212
1034
|
return unwrap(
|
|
1213
|
-
this.httpClient.
|
|
1214
|
-
`/admin-api/alias/create/identity/${context}`,
|
|
1215
|
-
request
|
|
1216
|
-
)
|
|
1035
|
+
await this.httpClient.get(`/admin-api/groups/${groupId}/upgrade/status`)
|
|
1217
1036
|
);
|
|
1218
1037
|
}
|
|
1219
|
-
async
|
|
1038
|
+
async retryGroupUpgrade(groupId, request) {
|
|
1220
1039
|
return unwrap(
|
|
1221
|
-
this.httpClient.post(
|
|
1222
|
-
`/admin-api/
|
|
1223
|
-
{}
|
|
1040
|
+
await this.httpClient.post(
|
|
1041
|
+
`/admin-api/groups/${groupId}/upgrade/retry`,
|
|
1042
|
+
request ?? {}
|
|
1224
1043
|
)
|
|
1225
1044
|
);
|
|
1226
1045
|
}
|
|
1227
|
-
async
|
|
1228
|
-
|
|
1229
|
-
this.httpClient.post(
|
|
1230
|
-
`/admin-api/alias/lookup/application/${name}`,
|
|
1231
|
-
{}
|
|
1232
|
-
)
|
|
1233
|
-
);
|
|
1046
|
+
async nestGroup(parentGroupId, request) {
|
|
1047
|
+
await this.httpClient.post(`/admin-api/groups/${parentGroupId}/nest`, request);
|
|
1234
1048
|
}
|
|
1235
|
-
async
|
|
1236
|
-
|
|
1237
|
-
this.httpClient.post(
|
|
1238
|
-
`/admin-api/alias/lookup/identity/${context}/${name}`,
|
|
1239
|
-
{}
|
|
1240
|
-
)
|
|
1241
|
-
);
|
|
1049
|
+
async unnestGroup(parentGroupId, request) {
|
|
1050
|
+
await this.httpClient.post(`/admin-api/groups/${parentGroupId}/unnest`, request);
|
|
1242
1051
|
}
|
|
1243
|
-
async
|
|
1244
|
-
return unwrap(
|
|
1245
|
-
this.httpClient.get(
|
|
1246
|
-
"/admin-api/alias/list/context"
|
|
1247
|
-
)
|
|
1248
|
-
);
|
|
1052
|
+
async listSubgroups(groupId) {
|
|
1053
|
+
return unwrap(await this.httpClient.get(`/admin-api/groups/${groupId}/subgroups`));
|
|
1249
1054
|
}
|
|
1250
|
-
async
|
|
1251
|
-
|
|
1252
|
-
this.httpClient.get(
|
|
1253
|
-
"/admin-api/alias/list/application"
|
|
1254
|
-
)
|
|
1255
|
-
);
|
|
1055
|
+
async detachContextFromGroup(groupId, contextId, request) {
|
|
1056
|
+
await this.httpClient.post(`/admin-api/groups/${groupId}/contexts/${contextId}/remove`, request ?? {});
|
|
1256
1057
|
}
|
|
1257
|
-
|
|
1058
|
+
// ---- Group Invitation & Join ----
|
|
1059
|
+
async createGroupInvitation(groupId, request) {
|
|
1258
1060
|
return unwrap(
|
|
1259
|
-
this.httpClient.
|
|
1260
|
-
`/admin-api/
|
|
1061
|
+
await this.httpClient.post(
|
|
1062
|
+
`/admin-api/groups/${groupId}/invite`,
|
|
1063
|
+
request ?? {}
|
|
1261
1064
|
)
|
|
1262
1065
|
);
|
|
1263
1066
|
}
|
|
1264
|
-
async
|
|
1067
|
+
async joinGroup(request) {
|
|
1265
1068
|
return unwrap(
|
|
1266
|
-
this.httpClient.post(
|
|
1267
|
-
`/admin-api/alias/delete/context/${name}`,
|
|
1268
|
-
{}
|
|
1269
|
-
)
|
|
1069
|
+
await this.httpClient.post("/admin-api/groups/join", request)
|
|
1270
1070
|
);
|
|
1271
1071
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
);
|
|
1072
|
+
// ---- TEE ----
|
|
1073
|
+
async getTeeInfo() {
|
|
1074
|
+
return unwrap(await this.httpClient.get("/admin-api/tee/info"));
|
|
1075
|
+
}
|
|
1076
|
+
async teeAttest(request) {
|
|
1077
|
+
return unwrap(await this.httpClient.post("/admin-api/tee/attest", request));
|
|
1279
1078
|
}
|
|
1280
|
-
async
|
|
1079
|
+
async teeVerifyQuote(request) {
|
|
1281
1080
|
return unwrap(
|
|
1282
|
-
this.httpClient.post(
|
|
1283
|
-
`/admin-api/alias/delete/identity/${context}/${name}`,
|
|
1284
|
-
{}
|
|
1285
|
-
)
|
|
1081
|
+
await this.httpClient.post("/admin-api/tee/verify-quote", request)
|
|
1286
1082
|
);
|
|
1287
1083
|
}
|
|
1084
|
+
// ---- Network ----
|
|
1085
|
+
async getPeersCount() {
|
|
1086
|
+
return this.httpClient.get("/admin-api/peers");
|
|
1087
|
+
}
|
|
1288
1088
|
};
|
|
1289
1089
|
|
|
1290
|
-
// src/api/admin
|
|
1291
|
-
var
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
async getTeeInfo() {
|
|
1296
|
-
return unwrap(
|
|
1297
|
-
this.httpClient.get("/admin-api/tee/info")
|
|
1090
|
+
// src/admin-api/admin-factory.ts
|
|
1091
|
+
var MockHttpClient2 = class {
|
|
1092
|
+
async get() {
|
|
1093
|
+
throw new Error(
|
|
1094
|
+
"HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client"
|
|
1298
1095
|
);
|
|
1299
1096
|
}
|
|
1300
|
-
async
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
"/admin-api/tee/attest",
|
|
1304
|
-
request
|
|
1305
|
-
)
|
|
1097
|
+
async post() {
|
|
1098
|
+
throw new Error(
|
|
1099
|
+
"HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client"
|
|
1306
1100
|
);
|
|
1307
1101
|
}
|
|
1308
|
-
async
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
"/admin-api/tee/verify-quote",
|
|
1312
|
-
request
|
|
1313
|
-
)
|
|
1102
|
+
async put() {
|
|
1103
|
+
throw new Error(
|
|
1104
|
+
"HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client"
|
|
1314
1105
|
);
|
|
1315
1106
|
}
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
constructor(httpClient) {
|
|
1321
|
-
this.httpClient = httpClient;
|
|
1322
|
-
}
|
|
1323
|
-
/** Public endpoints (health checks, etc.) - no authentication required */
|
|
1324
|
-
get public() {
|
|
1325
|
-
if (!this._public) {
|
|
1326
|
-
this._public = new PublicApiClient(this.httpClient);
|
|
1327
|
-
}
|
|
1328
|
-
return this._public;
|
|
1329
|
-
}
|
|
1330
|
-
/** Application management (install, list, uninstall) */
|
|
1331
|
-
get applications() {
|
|
1332
|
-
if (!this._applications) {
|
|
1333
|
-
this._applications = new ApplicationsApiClient(this.httpClient);
|
|
1334
|
-
}
|
|
1335
|
-
return this._applications;
|
|
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;
|
|
1107
|
+
async delete() {
|
|
1108
|
+
throw new Error(
|
|
1109
|
+
"HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client"
|
|
1110
|
+
);
|
|
1343
1111
|
}
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
}
|
|
1349
|
-
return this._proposals;
|
|
1112
|
+
async patch() {
|
|
1113
|
+
throw new Error(
|
|
1114
|
+
"HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client"
|
|
1115
|
+
);
|
|
1350
1116
|
}
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
}
|
|
1356
|
-
return this._capabilities;
|
|
1117
|
+
async head() {
|
|
1118
|
+
throw new Error(
|
|
1119
|
+
"HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client"
|
|
1120
|
+
);
|
|
1357
1121
|
}
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
}
|
|
1363
|
-
return this._identity;
|
|
1122
|
+
async request() {
|
|
1123
|
+
throw new Error(
|
|
1124
|
+
"HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client"
|
|
1125
|
+
);
|
|
1364
1126
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1127
|
+
};
|
|
1128
|
+
function createBrowserAdminApiClient(_config) {
|
|
1129
|
+
const httpClient = new MockHttpClient2();
|
|
1130
|
+
return new AdminApiClient(httpClient);
|
|
1131
|
+
}
|
|
1132
|
+
function createNodeAdminApiClient(_config) {
|
|
1133
|
+
const httpClient = new MockHttpClient2();
|
|
1134
|
+
return new AdminApiClient(httpClient);
|
|
1135
|
+
}
|
|
1136
|
+
function createAdminApiClient(_config) {
|
|
1137
|
+
const httpClient = new MockHttpClient2();
|
|
1138
|
+
return new AdminApiClient(httpClient);
|
|
1139
|
+
}
|
|
1140
|
+
function createAdminApiClientFromHttpClient(httpClient, _config) {
|
|
1141
|
+
return new AdminApiClient(httpClient);
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
// src/auth/index.ts
|
|
1145
|
+
function parseAuthCallback(url) {
|
|
1146
|
+
try {
|
|
1147
|
+
const hashIndex = url.indexOf("#");
|
|
1148
|
+
if (hashIndex === -1) return null;
|
|
1149
|
+
const hash = url.substring(hashIndex + 1);
|
|
1150
|
+
const params = new URLSearchParams(hash);
|
|
1151
|
+
const accessToken = params.get("access_token");
|
|
1152
|
+
if (!accessToken) return null;
|
|
1153
|
+
return {
|
|
1154
|
+
accessToken,
|
|
1155
|
+
refreshToken: params.get("refresh_token") ?? "",
|
|
1156
|
+
applicationId: params.get("application_id") ?? "",
|
|
1157
|
+
contextId: params.get("context_id") ?? "",
|
|
1158
|
+
contextIdentity: params.get("context_identity") ?? "",
|
|
1159
|
+
nodeUrl: params.get("node_url") ?? ""
|
|
1160
|
+
};
|
|
1161
|
+
} catch {
|
|
1162
|
+
return null;
|
|
1371
1163
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1164
|
+
}
|
|
1165
|
+
function buildAuthLoginUrl(nodeUrl, opts) {
|
|
1166
|
+
const params = new URLSearchParams();
|
|
1167
|
+
params.set("callback-url", opts.callbackUrl);
|
|
1168
|
+
if (opts.permissions && opts.permissions.length > 0) {
|
|
1169
|
+
params.set("permissions", opts.permissions.join(","));
|
|
1378
1170
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1171
|
+
params.set("mode", opts.mode);
|
|
1172
|
+
if (opts.packageName) {
|
|
1173
|
+
params.set("package-name", opts.packageName);
|
|
1174
|
+
if (opts.packageVersion) {
|
|
1175
|
+
params.set("package-version", opts.packageVersion);
|
|
1383
1176
|
}
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
/** TEE (Trusted Execution Environment) operations */
|
|
1387
|
-
get tee() {
|
|
1388
|
-
if (!this._tee) {
|
|
1389
|
-
this._tee = new TeeApiClient(this.httpClient);
|
|
1177
|
+
if (opts.registryUrl) {
|
|
1178
|
+
params.set("registry-url", opts.registryUrl);
|
|
1390
1179
|
}
|
|
1391
|
-
return this._tee;
|
|
1392
1180
|
}
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
// src/api/admin/factory.ts
|
|
1396
|
-
function createAdminApiClient(httpClient) {
|
|
1397
|
-
return new AdminApiClient(httpClient);
|
|
1181
|
+
const base = nodeUrl.replace(/\/+$/, "");
|
|
1182
|
+
return `${base}/auth/login?${params.toString()}`;
|
|
1398
1183
|
}
|
|
1399
1184
|
|
|
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;
|
|
1185
|
+
// src/rpc/index.ts
|
|
1186
|
+
var RpcError = class extends Error {
|
|
1187
|
+
constructor(code, message, data, type) {
|
|
1411
1188
|
super(message);
|
|
1412
|
-
this.
|
|
1189
|
+
this.name = "RpcError";
|
|
1190
|
+
this.code = code;
|
|
1413
1191
|
this.data = data;
|
|
1414
|
-
this.
|
|
1415
|
-
this.name = "JsonRpcError";
|
|
1192
|
+
this.type = type;
|
|
1416
1193
|
}
|
|
1417
1194
|
};
|
|
1418
1195
|
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));
|
|
1196
|
+
constructor(opts) {
|
|
1197
|
+
this.httpClient = opts.httpClient;
|
|
1428
1198
|
}
|
|
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
1199
|
async execute(params) {
|
|
1457
|
-
const
|
|
1458
|
-
const request = {
|
|
1200
|
+
const body = {
|
|
1459
1201
|
jsonrpc: "2.0",
|
|
1460
|
-
id:
|
|
1202
|
+
id: 1,
|
|
1461
1203
|
method: "execute",
|
|
1462
1204
|
params: {
|
|
1463
1205
|
contextId: params.contextId,
|
|
1464
1206
|
method: params.method,
|
|
1465
|
-
argsJson: params.
|
|
1466
|
-
executorPublicKey: params.executorPublicKey,
|
|
1467
|
-
substitute: params.substitute ?? []
|
|
1207
|
+
argsJson: params.argsJson ?? {}
|
|
1468
1208
|
}
|
|
1469
1209
|
};
|
|
1470
1210
|
const response = await this.httpClient.post(
|
|
1471
|
-
|
|
1472
|
-
|
|
1211
|
+
"/jsonrpc",
|
|
1212
|
+
body
|
|
1473
1213
|
);
|
|
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
1214
|
if (response.error) {
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
);
|
|
1215
|
+
const err = response.error;
|
|
1216
|
+
const code = err.code ?? -1;
|
|
1217
|
+
const message = err.message ?? err.type ?? "RPC error";
|
|
1218
|
+
throw new RpcError(code, message, err.data, err.type);
|
|
1487
1219
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
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;
|
|
1220
|
+
if (response.result && "output" in response.result) {
|
|
1221
|
+
return response.result.output;
|
|
1222
|
+
}
|
|
1223
|
+
return response.result;
|
|
1523
1224
|
}
|
|
1524
1225
|
};
|
|
1525
1226
|
|
|
1526
|
-
// src/
|
|
1527
|
-
var
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
this.
|
|
1536
|
-
this.
|
|
1537
|
-
this.
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
this.
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1227
|
+
// src/events/sse.ts
|
|
1228
|
+
var SseClient = class {
|
|
1229
|
+
constructor(opts) {
|
|
1230
|
+
this.sessionId = null;
|
|
1231
|
+
this.abortController = null;
|
|
1232
|
+
this.reconnectTimer = null;
|
|
1233
|
+
this.subscribedContextIds = /* @__PURE__ */ new Set();
|
|
1234
|
+
this.closed = false;
|
|
1235
|
+
this.listeners = { connect: [], event: [], error: [] };
|
|
1236
|
+
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
1237
|
+
this.getAuthToken = opts.getAuthToken;
|
|
1238
|
+
this.reconnectDelayMs = opts.reconnectDelayMs ?? 3e3;
|
|
1239
|
+
}
|
|
1240
|
+
on(event, handler) {
|
|
1241
|
+
const key = event;
|
|
1242
|
+
if (key in this.listeners) {
|
|
1243
|
+
const arr = this.listeners[key];
|
|
1244
|
+
if (!arr.includes(handler)) arr.push(handler);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
off(event, handler) {
|
|
1248
|
+
const key = event;
|
|
1249
|
+
if (key in this.listeners) {
|
|
1250
|
+
const arr = this.listeners[key];
|
|
1251
|
+
const idx = arr.indexOf(handler);
|
|
1252
|
+
if (idx !== -1) arr.splice(idx, 1);
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
emit(event, arg) {
|
|
1256
|
+
const key = event;
|
|
1257
|
+
if (key in this.listeners) {
|
|
1258
|
+
for (const handler of this.listeners[key]) {
|
|
1259
|
+
try {
|
|
1260
|
+
handler(arg);
|
|
1261
|
+
} catch {
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1550
1265
|
}
|
|
1551
|
-
/**
|
|
1552
|
-
* Connect to the WebSocket server
|
|
1553
|
-
*/
|
|
1554
1266
|
async connect() {
|
|
1555
|
-
if (this.
|
|
1267
|
+
if (this.abortController && !this.closed) {
|
|
1556
1268
|
return;
|
|
1557
1269
|
}
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
const
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
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));
|
|
1270
|
+
this.closed = false;
|
|
1271
|
+
this.abortController = new AbortController();
|
|
1272
|
+
try {
|
|
1273
|
+
const token = await this.getAuthToken();
|
|
1274
|
+
const response = await fetch(`${this.baseUrl}/sse`, {
|
|
1275
|
+
headers: {
|
|
1276
|
+
"Authorization": `Bearer ${token}`,
|
|
1277
|
+
"Accept": "text/event-stream"
|
|
1278
|
+
},
|
|
1279
|
+
signal: this.abortController.signal
|
|
1280
|
+
});
|
|
1281
|
+
if (!response.ok) {
|
|
1282
|
+
throw new Error(`SSE connection failed: ${response.status}`);
|
|
1283
|
+
}
|
|
1284
|
+
if (!response.body) {
|
|
1285
|
+
throw new Error("SSE response has no body");
|
|
1286
|
+
}
|
|
1287
|
+
this.readStream(response.body).catch((err) => {
|
|
1288
|
+
if (this.closed) return;
|
|
1289
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1290
|
+
this.emit("error", error);
|
|
1291
|
+
this.scheduleReconnect();
|
|
1292
|
+
});
|
|
1293
|
+
} catch (err) {
|
|
1294
|
+
if (this.closed) return;
|
|
1295
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1296
|
+
this.emit("error", error);
|
|
1297
|
+
this.scheduleReconnect();
|
|
1615
1298
|
}
|
|
1616
|
-
return response;
|
|
1617
1299
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
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
|
-
};
|
|
1644
|
-
}
|
|
1645
|
-
/**
|
|
1646
|
-
* Check if connected
|
|
1647
|
-
*/
|
|
1648
|
-
isConnected() {
|
|
1649
|
-
return this.ws?.readyState === WebSocket.OPEN;
|
|
1650
|
-
}
|
|
1651
|
-
/**
|
|
1652
|
-
* Get subscribed context IDs
|
|
1653
|
-
*/
|
|
1654
|
-
getSubscribedContexts() {
|
|
1655
|
-
return Array.from(this.subscribedContexts);
|
|
1656
|
-
}
|
|
1657
|
-
async send(request) {
|
|
1658
|
-
if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
|
|
1659
|
-
throw new Error("WebSocket not connected");
|
|
1660
|
-
}
|
|
1661
|
-
return new Promise((resolve, reject) => {
|
|
1662
|
-
const id = request.id;
|
|
1663
|
-
if (id !== null) {
|
|
1664
|
-
this.pendingRequests.set(id, { resolve, reject });
|
|
1300
|
+
async readStream(body) {
|
|
1301
|
+
const reader = body.getReader();
|
|
1302
|
+
const decoder = new TextDecoder();
|
|
1303
|
+
let buffer = "";
|
|
1304
|
+
try {
|
|
1305
|
+
for (; ; ) {
|
|
1306
|
+
const { done, value } = await reader.read();
|
|
1307
|
+
if (done) break;
|
|
1308
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1309
|
+
const lines = buffer.split("\n");
|
|
1310
|
+
buffer = lines.pop() ?? "";
|
|
1311
|
+
for (const line of lines) {
|
|
1312
|
+
if (line.startsWith("data:")) {
|
|
1313
|
+
const jsonStr = line.slice(5).trim();
|
|
1314
|
+
if (jsonStr) {
|
|
1315
|
+
this.handleMessage(jsonStr);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1665
1319
|
}
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1320
|
+
buffer += decoder.decode();
|
|
1321
|
+
if (buffer.startsWith("data:")) {
|
|
1322
|
+
const jsonStr = buffer.slice(5).trim();
|
|
1323
|
+
if (jsonStr) {
|
|
1324
|
+
this.handleMessage(jsonStr);
|
|
1671
1325
|
}
|
|
1672
|
-
}
|
|
1673
|
-
})
|
|
1326
|
+
}
|
|
1327
|
+
} catch (err) {
|
|
1328
|
+
if (this.closed) return;
|
|
1329
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1330
|
+
this.emit("error", error);
|
|
1331
|
+
}
|
|
1332
|
+
if (!this.closed) {
|
|
1333
|
+
this.scheduleReconnect();
|
|
1334
|
+
}
|
|
1674
1335
|
}
|
|
1675
|
-
handleMessage(
|
|
1336
|
+
handleMessage(jsonStr) {
|
|
1676
1337
|
try {
|
|
1677
|
-
const
|
|
1678
|
-
if (
|
|
1679
|
-
|
|
1680
|
-
this.
|
|
1681
|
-
|
|
1338
|
+
const msg = JSON.parse(jsonStr);
|
|
1339
|
+
if (msg.type === "connect" && msg.session_id) {
|
|
1340
|
+
this.sessionId = msg.session_id;
|
|
1341
|
+
this.emit("connect", msg.session_id);
|
|
1342
|
+
if (this.subscribedContextIds.size > 0) {
|
|
1343
|
+
this.sendSubscription("subscribe", [...this.subscribedContextIds]);
|
|
1344
|
+
}
|
|
1682
1345
|
return;
|
|
1683
1346
|
}
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1347
|
+
if (msg.result && msg.result.contextId) {
|
|
1348
|
+
let eventData = msg.result.data;
|
|
1349
|
+
if (Array.isArray(eventData)) {
|
|
1350
|
+
try {
|
|
1351
|
+
const bytes = new Uint8Array(eventData);
|
|
1352
|
+
const text = new TextDecoder().decode(bytes);
|
|
1353
|
+
eventData = JSON.parse(text);
|
|
1354
|
+
} catch {
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
this.emit("event", {
|
|
1358
|
+
contextId: msg.result.contextId,
|
|
1359
|
+
data: eventData
|
|
1360
|
+
});
|
|
1361
|
+
}
|
|
1362
|
+
} catch {
|
|
1692
1363
|
}
|
|
1693
1364
|
}
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1365
|
+
async subscribe(contextIds) {
|
|
1366
|
+
const newIds = contextIds.filter((id) => !this.subscribedContextIds.has(id));
|
|
1367
|
+
for (const id of contextIds) {
|
|
1368
|
+
this.subscribedContextIds.add(id);
|
|
1697
1369
|
}
|
|
1698
|
-
if (
|
|
1699
|
-
this.
|
|
1700
|
-
return;
|
|
1370
|
+
if (newIds.length > 0 && this.sessionId) {
|
|
1371
|
+
await this.sendSubscription("subscribe", newIds);
|
|
1701
1372
|
}
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1373
|
+
}
|
|
1374
|
+
async unsubscribe(contextIds) {
|
|
1375
|
+
const hadIds = contextIds.filter((id) => this.subscribedContextIds.has(id));
|
|
1376
|
+
for (const id of contextIds) {
|
|
1377
|
+
this.subscribedContextIds.delete(id);
|
|
1378
|
+
}
|
|
1379
|
+
if (hadIds.length > 0 && this.sessionId) {
|
|
1380
|
+
await this.sendSubscription("unsubscribe", hadIds);
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
async sendSubscription(method, contextIds) {
|
|
1384
|
+
try {
|
|
1385
|
+
const token = await this.getAuthToken();
|
|
1386
|
+
const response = await fetch(`${this.baseUrl}/sse/subscription`, {
|
|
1387
|
+
method: "POST",
|
|
1388
|
+
headers: {
|
|
1389
|
+
"Authorization": `Bearer ${token}`,
|
|
1390
|
+
"Content-Type": "application/json"
|
|
1391
|
+
},
|
|
1392
|
+
body: JSON.stringify({
|
|
1393
|
+
id: this.sessionId,
|
|
1394
|
+
method,
|
|
1395
|
+
params: { contextIds }
|
|
1396
|
+
})
|
|
1397
|
+
});
|
|
1398
|
+
if (!response.ok) {
|
|
1399
|
+
this.emit("error", new Error(`SSE ${method} failed: ${response.status}`));
|
|
1711
1400
|
}
|
|
1712
|
-
}
|
|
1401
|
+
} catch (err) {
|
|
1402
|
+
this.emit("error", err instanceof Error ? err : new Error(`SSE ${method} failed`));
|
|
1403
|
+
}
|
|
1713
1404
|
}
|
|
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;
|
|
1405
|
+
forceReconnect() {
|
|
1406
|
+
if (this.abortController) {
|
|
1407
|
+
this.abortController.abort();
|
|
1408
|
+
this.abortController = null;
|
|
1409
|
+
}
|
|
1726
1410
|
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
|
-
};
|
|
1411
|
+
this.connect();
|
|
1738
1412
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
if (this.eventSource) {
|
|
1744
|
-
throw new Error("Already connected");
|
|
1413
|
+
scheduleReconnect() {
|
|
1414
|
+
if (this.closed) return;
|
|
1415
|
+
if (this.reconnectTimer) {
|
|
1416
|
+
clearTimeout(this.reconnectTimer);
|
|
1745
1417
|
}
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1418
|
+
this.reconnectTimer = setTimeout(() => {
|
|
1419
|
+
this.reconnectTimer = null;
|
|
1420
|
+
this.forceReconnect();
|
|
1421
|
+
}, this.reconnectDelayMs);
|
|
1422
|
+
}
|
|
1423
|
+
close() {
|
|
1424
|
+
this.closed = true;
|
|
1425
|
+
if (this.abortController) {
|
|
1426
|
+
this.abortController.abort();
|
|
1427
|
+
this.abortController = null;
|
|
1750
1428
|
}
|
|
1751
|
-
|
|
1752
|
-
this.
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1429
|
+
if (this.reconnectTimer) {
|
|
1430
|
+
clearTimeout(this.reconnectTimer);
|
|
1431
|
+
this.reconnectTimer = null;
|
|
1432
|
+
}
|
|
1433
|
+
this.sessionId = null;
|
|
1434
|
+
this.subscribedContextIds.clear();
|
|
1435
|
+
}
|
|
1436
|
+
};
|
|
1437
|
+
|
|
1438
|
+
// src/events/ws.ts
|
|
1439
|
+
var _WsClient = class _WsClient {
|
|
1440
|
+
constructor(opts) {
|
|
1441
|
+
this.ws = null;
|
|
1442
|
+
this.closed = false;
|
|
1443
|
+
this.reconnectAttempt = 0;
|
|
1444
|
+
this.reconnectTimer = null;
|
|
1445
|
+
this.subscribedContextIds = /* @__PURE__ */ new Set();
|
|
1446
|
+
this.listeners = { connect: [], event: [], error: [] };
|
|
1447
|
+
this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
|
|
1448
|
+
this.getAuthToken = opts.getAuthToken;
|
|
1449
|
+
}
|
|
1450
|
+
on(event, handler) {
|
|
1451
|
+
const key = event;
|
|
1452
|
+
if (key in this.listeners) {
|
|
1453
|
+
const arr = this.listeners[key];
|
|
1454
|
+
if (!arr.includes(handler)) arr.push(handler);
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
off(event, handler) {
|
|
1458
|
+
const key = event;
|
|
1459
|
+
if (key in this.listeners) {
|
|
1460
|
+
const arr = this.listeners[key];
|
|
1461
|
+
const idx = arr.indexOf(handler);
|
|
1462
|
+
if (idx !== -1) arr.splice(idx, 1);
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
emit(event, arg) {
|
|
1466
|
+
const key = event;
|
|
1467
|
+
if (key in this.listeners) {
|
|
1468
|
+
for (const handler of this.listeners[key]) {
|
|
1757
1469
|
try {
|
|
1758
|
-
|
|
1759
|
-
this.sessionId = typeof data === "string" && data.startsWith("{") ? JSON.parse(data).session_id || JSON.parse(data).sessionId : data;
|
|
1760
|
-
resolve(this.sessionId);
|
|
1470
|
+
handler(arg);
|
|
1761
1471
|
} catch {
|
|
1762
|
-
this.sessionId = messageEvent.data;
|
|
1763
|
-
resolve(this.sessionId);
|
|
1764
1472
|
}
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
async connect() {
|
|
1477
|
+
if (this.ws && (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN)) {
|
|
1478
|
+
return;
|
|
1479
|
+
}
|
|
1480
|
+
this.closed = false;
|
|
1481
|
+
try {
|
|
1482
|
+
const token = await this.getAuthToken();
|
|
1483
|
+
if (!token) {
|
|
1484
|
+
throw new Error("No authentication token available for WebSocket connection");
|
|
1485
|
+
}
|
|
1486
|
+
const wsUrl = this.baseUrl.replace(/^http/, "ws");
|
|
1487
|
+
this.ws = new WebSocket(`${wsUrl}/ws?token=${encodeURIComponent(token)}`);
|
|
1488
|
+
this.ws.onopen = () => {
|
|
1489
|
+
this.reconnectAttempt = 0;
|
|
1490
|
+
this.emit("connect");
|
|
1491
|
+
if (this.subscribedContextIds.size > 0) {
|
|
1492
|
+
this.sendMessage({
|
|
1493
|
+
id: null,
|
|
1494
|
+
method: "subscribe",
|
|
1495
|
+
params: { contextIds: [...this.subscribedContextIds] }
|
|
1496
|
+
});
|
|
1783
1497
|
}
|
|
1784
1498
|
};
|
|
1785
|
-
this.
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1499
|
+
this.ws.onmessage = (event) => {
|
|
1500
|
+
this.handleMessage(event.data);
|
|
1501
|
+
};
|
|
1502
|
+
this.ws.onerror = () => {
|
|
1503
|
+
this.emit("error", new Error("WebSocket error"));
|
|
1504
|
+
};
|
|
1505
|
+
this.ws.onclose = () => {
|
|
1506
|
+
if (!this.closed) {
|
|
1507
|
+
this.scheduleReconnect();
|
|
1793
1508
|
}
|
|
1794
1509
|
};
|
|
1795
|
-
})
|
|
1510
|
+
} catch (err) {
|
|
1511
|
+
if (this.closed) return;
|
|
1512
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1513
|
+
this.emit("error", error);
|
|
1514
|
+
this.scheduleReconnect();
|
|
1515
|
+
}
|
|
1796
1516
|
}
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1517
|
+
handleMessage(raw) {
|
|
1518
|
+
if (typeof raw !== "string") return;
|
|
1519
|
+
try {
|
|
1520
|
+
const msg = JSON.parse(raw);
|
|
1521
|
+
if (msg.result && msg.result.contextId) {
|
|
1522
|
+
let eventData = msg.result.data;
|
|
1523
|
+
if (Array.isArray(eventData)) {
|
|
1524
|
+
try {
|
|
1525
|
+
const bytes = new Uint8Array(eventData);
|
|
1526
|
+
const text = new TextDecoder().decode(bytes);
|
|
1527
|
+
eventData = JSON.parse(text);
|
|
1528
|
+
} catch {
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
this.emit("event", {
|
|
1532
|
+
contextId: msg.result.contextId,
|
|
1533
|
+
data: eventData
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1536
|
+
} catch {
|
|
1537
|
+
}
|
|
1806
1538
|
}
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
async subscribe(contextIds) {
|
|
1811
|
-
if (!this.sessionId) {
|
|
1812
|
-
throw new Error("Not connected");
|
|
1539
|
+
subscribe(contextIds) {
|
|
1540
|
+
for (const id of contextIds) {
|
|
1541
|
+
this.subscribedContextIds.add(id);
|
|
1813
1542
|
}
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
"/sse/subscription",
|
|
1821
|
-
request
|
|
1822
|
-
);
|
|
1823
|
-
if (!response.error) {
|
|
1824
|
-
contextIds.forEach((id) => this.subscribedContexts.add(id));
|
|
1543
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
1544
|
+
this.sendMessage({
|
|
1545
|
+
id: null,
|
|
1546
|
+
method: "subscribe",
|
|
1547
|
+
params: { contextIds }
|
|
1548
|
+
});
|
|
1825
1549
|
}
|
|
1826
|
-
return response;
|
|
1827
1550
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
async unsubscribe(contextIds) {
|
|
1832
|
-
if (!this.sessionId) {
|
|
1833
|
-
throw new Error("Not connected");
|
|
1551
|
+
unsubscribe(contextIds) {
|
|
1552
|
+
for (const id of contextIds) {
|
|
1553
|
+
this.subscribedContextIds.delete(id);
|
|
1834
1554
|
}
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
"/sse/subscription",
|
|
1842
|
-
request
|
|
1843
|
-
);
|
|
1844
|
-
if (!response.error) {
|
|
1845
|
-
contextIds.forEach((id) => this.subscribedContexts.delete(id));
|
|
1555
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
1556
|
+
this.sendMessage({
|
|
1557
|
+
id: null,
|
|
1558
|
+
method: "unsubscribe",
|
|
1559
|
+
params: { contextIds }
|
|
1560
|
+
});
|
|
1846
1561
|
}
|
|
1847
|
-
return response;
|
|
1848
1562
|
}
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
async getSession() {
|
|
1853
|
-
if (!this.sessionId) {
|
|
1854
|
-
throw new Error("Not connected");
|
|
1563
|
+
sendMessage(msg) {
|
|
1564
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
1565
|
+
this.ws.send(JSON.stringify(msg));
|
|
1855
1566
|
}
|
|
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
1567
|
}
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
*/
|
|
1899
|
-
getLastEventId() {
|
|
1900
|
-
return this._lastEventId;
|
|
1568
|
+
scheduleReconnect() {
|
|
1569
|
+
if (this.closed) return;
|
|
1570
|
+
if (this.reconnectTimer) {
|
|
1571
|
+
clearTimeout(this.reconnectTimer);
|
|
1572
|
+
}
|
|
1573
|
+
const delay = Math.min(
|
|
1574
|
+
1e3 * Math.pow(2, this.reconnectAttempt),
|
|
1575
|
+
_WsClient.MAX_BACKOFF_MS
|
|
1576
|
+
);
|
|
1577
|
+
this.reconnectAttempt++;
|
|
1578
|
+
this.reconnectTimer = setTimeout(() => {
|
|
1579
|
+
this.reconnectTimer = null;
|
|
1580
|
+
this.connect();
|
|
1581
|
+
}, delay);
|
|
1901
1582
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1583
|
+
close() {
|
|
1584
|
+
this.closed = true;
|
|
1585
|
+
if (this.reconnectTimer) {
|
|
1586
|
+
clearTimeout(this.reconnectTimer);
|
|
1587
|
+
this.reconnectTimer = null;
|
|
1905
1588
|
}
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
} catch {
|
|
1913
|
-
}
|
|
1914
|
-
}, this.options.reconnectDelay);
|
|
1589
|
+
if (this.ws) {
|
|
1590
|
+
this.ws.onclose = null;
|
|
1591
|
+
this.ws.close();
|
|
1592
|
+
this.ws = null;
|
|
1593
|
+
}
|
|
1594
|
+
this.subscribedContextIds.clear();
|
|
1915
1595
|
}
|
|
1916
1596
|
};
|
|
1597
|
+
_WsClient.MAX_BACKOFF_MS = 3e4;
|
|
1598
|
+
var WsClient = _WsClient;
|
|
1917
1599
|
|
|
1918
1600
|
// src/mero-js.ts
|
|
1601
|
+
function expiresAtFromJwt(token, fallbackMs) {
|
|
1602
|
+
try {
|
|
1603
|
+
const parts = token.split(".");
|
|
1604
|
+
if (parts.length === 3) {
|
|
1605
|
+
let b64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
1606
|
+
while (b64.length % 4) b64 += "=";
|
|
1607
|
+
const payload = JSON.parse(atob(b64));
|
|
1608
|
+
if (typeof payload.exp === "number") {
|
|
1609
|
+
return payload.exp * 1e3;
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
} catch {
|
|
1613
|
+
}
|
|
1614
|
+
return fallbackMs;
|
|
1615
|
+
}
|
|
1919
1616
|
var MeroJs = class {
|
|
1920
1617
|
constructor(config) {
|
|
1921
1618
|
this.tokenData = null;
|
|
1922
1619
|
this.refreshPromise = null;
|
|
1923
|
-
this.
|
|
1620
|
+
this.rpcClient = null;
|
|
1621
|
+
this.sseClient = null;
|
|
1622
|
+
this.wsClient = null;
|
|
1623
|
+
this.wsWarned = false;
|
|
1924
1624
|
this.config = {
|
|
1925
1625
|
timeoutMs: 1e4,
|
|
1926
1626
|
...config
|
|
1927
1627
|
};
|
|
1928
|
-
this.
|
|
1628
|
+
this.tokenStore = config.tokenStore ?? null;
|
|
1629
|
+
if (this.tokenStore) {
|
|
1630
|
+
this.tokenData = this.tokenStore.getTokens();
|
|
1631
|
+
}
|
|
1929
1632
|
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
1633
|
this.httpClient = createBrowserHttpClient({
|
|
1933
1634
|
baseUrl: this.config.baseUrl,
|
|
1934
1635
|
getAuthToken: async () => {
|
|
1935
1636
|
const token = await this.getValidToken();
|
|
1936
1637
|
return token?.access_token || "";
|
|
1937
1638
|
},
|
|
1938
|
-
// Wire up automatic token refresh on 401
|
|
1939
1639
|
refreshToken: async () => {
|
|
1940
1640
|
const refreshed = await this.performTokenRefresh();
|
|
1941
1641
|
return refreshed.access_token;
|
|
1942
1642
|
},
|
|
1943
|
-
onTokenRefresh: async (
|
|
1944
|
-
if (this.tokenData
|
|
1945
|
-
|
|
1643
|
+
onTokenRefresh: async (newToken) => {
|
|
1644
|
+
if (this.tokenData) {
|
|
1645
|
+
this.tokenData.access_token = newToken;
|
|
1646
|
+
this.tokenStore?.setTokens(this.tokenData);
|
|
1946
1647
|
}
|
|
1947
1648
|
},
|
|
1948
1649
|
timeoutMs: this.config.timeoutMs,
|
|
1949
1650
|
credentials: this.config.requestCredentials ?? (isTauri ? "omit" : void 0)
|
|
1950
1651
|
});
|
|
1951
|
-
|
|
1952
|
-
baseUrl:
|
|
1652
|
+
this.authClient = createAuthApiClientFromHttpClient(this.httpClient, {
|
|
1653
|
+
baseUrl: this.config.baseUrl,
|
|
1953
1654
|
getAuthToken: async () => {
|
|
1954
1655
|
const token = await this.getValidToken();
|
|
1955
1656
|
return token?.access_token || "";
|
|
1956
1657
|
},
|
|
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)
|
|
1658
|
+
timeoutMs: this.config.timeoutMs
|
|
1961
1659
|
});
|
|
1962
|
-
this.
|
|
1963
|
-
baseUrl:
|
|
1964
|
-
|
|
1660
|
+
this.adminClient = createAdminApiClientFromHttpClient(this.httpClient, {
|
|
1661
|
+
baseUrl: this.config.baseUrl,
|
|
1662
|
+
getAuthToken: async () => {
|
|
1663
|
+
const token = await this.getValidToken();
|
|
1664
|
+
return token?.access_token || "";
|
|
1665
|
+
},
|
|
1666
|
+
timeoutMs: this.config.timeoutMs
|
|
1965
1667
|
});
|
|
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
1668
|
}
|
|
1996
1669
|
/**
|
|
1997
1670
|
* Get the Auth API client
|
|
@@ -2006,38 +1679,49 @@ var MeroJs = class {
|
|
|
2006
1679
|
return this.adminClient;
|
|
2007
1680
|
}
|
|
2008
1681
|
/**
|
|
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
|
-
* ```
|
|
1682
|
+
* Get the RPC client (lazy initialized)
|
|
2037
1683
|
*/
|
|
2038
1684
|
get rpc() {
|
|
1685
|
+
if (!this.rpcClient) {
|
|
1686
|
+
this.rpcClient = new RpcClient({ httpClient: this.httpClient });
|
|
1687
|
+
}
|
|
2039
1688
|
return this.rpcClient;
|
|
2040
1689
|
}
|
|
1690
|
+
/**
|
|
1691
|
+
* Get the SSE event client (lazy initialized)
|
|
1692
|
+
*/
|
|
1693
|
+
get events() {
|
|
1694
|
+
if (!this.sseClient) {
|
|
1695
|
+
this.sseClient = new SseClient({
|
|
1696
|
+
baseUrl: this.config.baseUrl,
|
|
1697
|
+
getAuthToken: async () => {
|
|
1698
|
+
const token = await this.getValidToken();
|
|
1699
|
+
return token?.access_token || "";
|
|
1700
|
+
}
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
return this.sseClient;
|
|
1704
|
+
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Get the WebSocket event client (lazy initialized).
|
|
1707
|
+
* @experimental Use `events` (SSE) for production. WsClient is experimental.
|
|
1708
|
+
*/
|
|
1709
|
+
get ws() {
|
|
1710
|
+
if (!this.wsWarned) {
|
|
1711
|
+
this.wsWarned = true;
|
|
1712
|
+
console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.");
|
|
1713
|
+
}
|
|
1714
|
+
if (!this.wsClient) {
|
|
1715
|
+
this.wsClient = new WsClient({
|
|
1716
|
+
baseUrl: this.config.baseUrl,
|
|
1717
|
+
getAuthToken: async () => {
|
|
1718
|
+
const token = await this.getValidToken();
|
|
1719
|
+
return token?.access_token || "";
|
|
1720
|
+
}
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
return this.wsClient;
|
|
1724
|
+
}
|
|
2041
1725
|
/**
|
|
2042
1726
|
* Authenticate with the provided credentials
|
|
2043
1727
|
* This will create the root key on first use
|
|
@@ -2059,82 +1743,41 @@ var MeroJs = class {
|
|
|
2059
1743
|
password: creds.password
|
|
2060
1744
|
}
|
|
2061
1745
|
};
|
|
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
|
-
}
|
|
1746
|
+
const response = await this.authClient.generateTokens(requestBody);
|
|
1747
|
+
const accessToken = response.data.access_token;
|
|
2072
1748
|
this.tokenData = {
|
|
2073
|
-
access_token:
|
|
2074
|
-
refresh_token: response.refresh_token,
|
|
2075
|
-
expires_at:
|
|
1749
|
+
access_token: accessToken,
|
|
1750
|
+
refresh_token: response.data.refresh_token,
|
|
1751
|
+
expires_at: expiresAtFromJwt(accessToken, Date.now() + 36e5)
|
|
2076
1752
|
};
|
|
2077
|
-
|
|
2078
|
-
await this.tokenStorage.set(this.tokenData);
|
|
2079
|
-
}
|
|
1753
|
+
this.tokenStore?.setTokens(this.tokenData);
|
|
2080
1754
|
return this.tokenData;
|
|
2081
1755
|
} 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
1756
|
throw new Error(
|
|
2087
|
-
`Authentication failed: ${
|
|
1757
|
+
`Authentication failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2088
1758
|
);
|
|
2089
1759
|
}
|
|
2090
1760
|
}
|
|
2091
1761
|
/**
|
|
2092
|
-
* Get a valid token
|
|
2093
|
-
*
|
|
2094
|
-
*
|
|
2095
|
-
*
|
|
2096
|
-
* so this preemptive check is an optimization to avoid unnecessary 401s.
|
|
1762
|
+
* Get a valid token. Returns the current token as-is.
|
|
1763
|
+
* The server rejects refresh attempts while the access token is still valid,
|
|
1764
|
+
* so we never proactively refresh. Instead, the WebHttpClient handles 401
|
|
1765
|
+
* responses reactively via the refreshToken transport hook.
|
|
2097
1766
|
*/
|
|
2098
1767
|
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
1768
|
return this.tokenData;
|
|
2114
1769
|
}
|
|
2115
1770
|
/**
|
|
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
|
|
1771
|
+
* Refresh the access token using the refresh token
|
|
2120
1772
|
*/
|
|
2121
1773
|
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() {
|
|
1774
|
+
if (!this.tokenData?.refresh_token) {
|
|
1775
|
+
throw new Error("No refresh token available");
|
|
1776
|
+
}
|
|
2132
1777
|
if (this.refreshPromise) {
|
|
2133
|
-
console.log("[mero-js] Refresh already in progress, waiting for existing promise");
|
|
2134
1778
|
return this.refreshPromise;
|
|
2135
1779
|
}
|
|
2136
|
-
|
|
2137
|
-
this.refreshPromise = this.doTokenRefresh();
|
|
1780
|
+
this.refreshPromise = this.performTokenRefresh();
|
|
2138
1781
|
try {
|
|
2139
1782
|
const newToken = await this.refreshPromise;
|
|
2140
1783
|
return newToken;
|
|
@@ -2143,87 +1786,37 @@ var MeroJs = class {
|
|
|
2143
1786
|
}
|
|
2144
1787
|
}
|
|
2145
1788
|
/**
|
|
2146
|
-
*
|
|
2147
|
-
* Called only from performTokenRefresh() which manages the deduplication.
|
|
1789
|
+
* Perform the actual token refresh
|
|
2148
1790
|
*/
|
|
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);
|
|
1791
|
+
async performTokenRefresh() {
|
|
2154
1792
|
if (!this.tokenData?.refresh_token) {
|
|
2155
1793
|
throw new Error("No refresh token available");
|
|
2156
1794
|
}
|
|
2157
|
-
if (!this.tokenData?.access_token) {
|
|
2158
|
-
throw new Error("No access token available for refresh (server requires both tokens)");
|
|
2159
|
-
}
|
|
2160
1795
|
try {
|
|
2161
|
-
const
|
|
1796
|
+
const response = await this.authClient.refreshToken({
|
|
2162
1797
|
access_token: this.tokenData.access_token,
|
|
2163
1798
|
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
|
-
}
|
|
1799
|
+
});
|
|
1800
|
+
const accessToken = response.data.access_token;
|
|
2178
1801
|
this.tokenData = {
|
|
2179
|
-
access_token:
|
|
2180
|
-
refresh_token: response.refresh_token,
|
|
2181
|
-
expires_at:
|
|
1802
|
+
access_token: accessToken,
|
|
1803
|
+
refresh_token: response.data.refresh_token,
|
|
1804
|
+
expires_at: expiresAtFromJwt(accessToken, Date.now() + 36e5)
|
|
2182
1805
|
};
|
|
2183
|
-
|
|
2184
|
-
await this.tokenStorage.set(this.tokenData);
|
|
2185
|
-
}
|
|
1806
|
+
this.tokenStore?.setTokens(this.tokenData);
|
|
2186
1807
|
return this.tokenData;
|
|
2187
1808
|
} 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
1809
|
throw new Error(
|
|
2215
1810
|
`Token refresh failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2216
1811
|
);
|
|
2217
1812
|
}
|
|
2218
1813
|
}
|
|
2219
1814
|
/**
|
|
2220
|
-
* Clear the current token
|
|
1815
|
+
* Clear the current token
|
|
2221
1816
|
*/
|
|
2222
|
-
|
|
1817
|
+
clearToken() {
|
|
2223
1818
|
this.tokenData = null;
|
|
2224
|
-
|
|
2225
|
-
await this.tokenStorage.clear();
|
|
2226
|
-
}
|
|
1819
|
+
this.tokenStore?.clear();
|
|
2227
1820
|
}
|
|
2228
1821
|
/**
|
|
2229
1822
|
* Check if the SDK is authenticated
|
|
@@ -2231,6 +1824,16 @@ var MeroJs = class {
|
|
|
2231
1824
|
isAuthenticated() {
|
|
2232
1825
|
return this.tokenData !== null;
|
|
2233
1826
|
}
|
|
1827
|
+
/**
|
|
1828
|
+
* Set token data directly (e.g., from auth callback).
|
|
1829
|
+
* If `expires_at` is missing or 0, attempts to parse the JWT exp claim,
|
|
1830
|
+
* falling back to 1 hour from now.
|
|
1831
|
+
*/
|
|
1832
|
+
setTokenData(data) {
|
|
1833
|
+
const expiresAt = data.expires_at || expiresAtFromJwt(data.access_token, Date.now() + 36e5);
|
|
1834
|
+
this.tokenData = { ...data, expires_at: expiresAt };
|
|
1835
|
+
this.tokenStore?.setTokens(this.tokenData);
|
|
1836
|
+
}
|
|
2234
1837
|
/**
|
|
2235
1838
|
* Get the current token data (for debugging)
|
|
2236
1839
|
*/
|
|
@@ -2238,92 +1841,107 @@ var MeroJs = class {
|
|
|
2238
1841
|
return this.tokenData;
|
|
2239
1842
|
}
|
|
2240
1843
|
/**
|
|
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
|
-
* ```
|
|
1844
|
+
* Close all event connections and clean up resources
|
|
2254
1845
|
*/
|
|
2255
|
-
|
|
2256
|
-
this.
|
|
2257
|
-
|
|
2258
|
-
if (tokenData) {
|
|
2259
|
-
await this.tokenStorage.set(tokenData);
|
|
2260
|
-
} else {
|
|
2261
|
-
await this.tokenStorage.clear();
|
|
2262
|
-
}
|
|
2263
|
-
}
|
|
1846
|
+
close() {
|
|
1847
|
+
this.sseClient?.close();
|
|
1848
|
+
this.wsClient?.close();
|
|
2264
1849
|
}
|
|
2265
1850
|
/**
|
|
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
|
-
* ```
|
|
1851
|
+
* Parse an auth callback URL hash fragment (static utility)
|
|
2285
1852
|
*/
|
|
2286
|
-
|
|
2287
|
-
return
|
|
2288
|
-
baseUrl: this.config.baseUrl,
|
|
2289
|
-
getAuthToken: async () => this.tokenData?.access_token || null,
|
|
2290
|
-
...options
|
|
2291
|
-
});
|
|
1853
|
+
static parseAuthCallback(url) {
|
|
1854
|
+
return parseAuthCallback(url);
|
|
2292
1855
|
}
|
|
2293
1856
|
/**
|
|
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
|
-
* ```
|
|
1857
|
+
* Build an auth login URL (static utility)
|
|
2316
1858
|
*/
|
|
2317
|
-
|
|
2318
|
-
return
|
|
2319
|
-
baseUrl: this.config.baseUrl,
|
|
2320
|
-
httpClient: this.httpClient,
|
|
2321
|
-
getAuthToken: async () => this.tokenData?.access_token || null,
|
|
2322
|
-
...options
|
|
2323
|
-
});
|
|
1859
|
+
static buildAuthLoginUrl(nodeUrl, opts) {
|
|
1860
|
+
return buildAuthLoginUrl(nodeUrl, opts);
|
|
2324
1861
|
}
|
|
2325
1862
|
};
|
|
2326
1863
|
function createMeroJs(config) {
|
|
2327
1864
|
return new MeroJs(config);
|
|
2328
1865
|
}
|
|
1866
|
+
|
|
1867
|
+
// src/token-store/index.ts
|
|
1868
|
+
var MemoryTokenStore = class {
|
|
1869
|
+
constructor() {
|
|
1870
|
+
this.tokens = null;
|
|
1871
|
+
}
|
|
1872
|
+
getTokens() {
|
|
1873
|
+
return this.tokens;
|
|
1874
|
+
}
|
|
1875
|
+
setTokens(data) {
|
|
1876
|
+
this.tokens = data;
|
|
1877
|
+
}
|
|
1878
|
+
clear() {
|
|
1879
|
+
this.tokens = null;
|
|
1880
|
+
}
|
|
1881
|
+
};
|
|
1882
|
+
var STORAGE_KEY = "mero-tokens";
|
|
1883
|
+
var LocalStorageTokenStore = class {
|
|
1884
|
+
constructor(key = STORAGE_KEY) {
|
|
1885
|
+
this.key = key;
|
|
1886
|
+
}
|
|
1887
|
+
getTokens() {
|
|
1888
|
+
try {
|
|
1889
|
+
if (typeof localStorage === "undefined") return null;
|
|
1890
|
+
const raw = localStorage.getItem(this.key);
|
|
1891
|
+
if (!raw) return null;
|
|
1892
|
+
const parsed = JSON.parse(raw);
|
|
1893
|
+
if (parsed && parsed.access_token && parsed.refresh_token) {
|
|
1894
|
+
return {
|
|
1895
|
+
access_token: parsed.access_token,
|
|
1896
|
+
refresh_token: parsed.refresh_token,
|
|
1897
|
+
expires_at: typeof parsed.expires_at === "number" ? parsed.expires_at : Date.now() + 36e5
|
|
1898
|
+
};
|
|
1899
|
+
}
|
|
1900
|
+
return null;
|
|
1901
|
+
} catch {
|
|
1902
|
+
return null;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
setTokens(data) {
|
|
1906
|
+
try {
|
|
1907
|
+
if (typeof localStorage === "undefined") return;
|
|
1908
|
+
localStorage.setItem(this.key, JSON.stringify(data));
|
|
1909
|
+
} catch {
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
clear() {
|
|
1913
|
+
try {
|
|
1914
|
+
if (typeof localStorage === "undefined") return;
|
|
1915
|
+
localStorage.removeItem(this.key);
|
|
1916
|
+
} catch {
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
|
|
1921
|
+
// src/cloud/cloud-client.ts
|
|
1922
|
+
var CloudClient = class {
|
|
1923
|
+
constructor(config = {}) {
|
|
1924
|
+
this.baseUrl = (config.cloudBaseUrl || "https://cloud.calimero.network").replace(/\/+$/, "");
|
|
1925
|
+
}
|
|
1926
|
+
enableHA(options) {
|
|
1927
|
+
const params = new URLSearchParams({
|
|
1928
|
+
group_id: options.groupId,
|
|
1929
|
+
context_id: options.contextId
|
|
1930
|
+
});
|
|
1931
|
+
if (options.redirectUrl) {
|
|
1932
|
+
params.set("redirect_url", options.redirectUrl);
|
|
1933
|
+
}
|
|
1934
|
+
window.open(`${this.baseUrl}/enable-ha?${params.toString()}`);
|
|
1935
|
+
}
|
|
1936
|
+
disableHA(options) {
|
|
1937
|
+
const params = new URLSearchParams({
|
|
1938
|
+
group_id: options.groupId,
|
|
1939
|
+
context_id: options.contextId
|
|
1940
|
+
});
|
|
1941
|
+
if (options.redirectUrl) {
|
|
1942
|
+
params.set("redirect_url", options.redirectUrl);
|
|
1943
|
+
}
|
|
1944
|
+
window.open(`${this.baseUrl}/disable-ha?${params.toString()}`);
|
|
1945
|
+
}
|
|
1946
|
+
};
|
|
2329
1947
|
//# sourceMappingURL=index.cjs.map
|