@calimero-network/mero-js 1.1.0 → 2.0.0-beta.1

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