@calimero-network/mero-js 1.0.2 → 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 (178) 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/http-factory.d.ts +18 -0
  115. package/dist/http-client/http-factory.d.ts.map +1 -1
  116. package/dist/http-client/http-factory.js +2 -0
  117. package/dist/http-client/http-factory.js.map +1 -1
  118. package/dist/http-client/http-types.d.ts +6 -0
  119. package/dist/http-client/http-types.d.ts.map +1 -1
  120. package/dist/http-client/index.d.ts +1 -1
  121. package/dist/http-client/index.d.ts.map +1 -1
  122. package/dist/http-client/index.js +2 -1
  123. package/dist/http-client/index.js.map +1 -1
  124. package/dist/http-client/web-client.d.ts +5 -3
  125. package/dist/http-client/web-client.d.ts.map +1 -1
  126. package/dist/http-client/web-client.js +142 -59
  127. package/dist/http-client/web-client.js.map +1 -1
  128. package/dist/index.browser.mjs +1 -1
  129. package/dist/index.browser.mjs.map +4 -4
  130. package/dist/index.cjs +1669 -341
  131. package/dist/index.cjs.map +4 -4
  132. package/dist/index.d.ts +8 -3
  133. package/dist/index.d.ts.map +1 -1
  134. package/dist/index.js +7 -5
  135. package/dist/index.js.map +1 -1
  136. package/dist/index.mjs +1675 -341
  137. package/dist/index.mjs.map +4 -4
  138. package/dist/mero-js.d.ts +198 -7
  139. package/dist/mero-js.d.ts.map +1 -1
  140. package/dist/mero-js.js +329 -38
  141. package/dist/mero-js.js.map +1 -1
  142. package/package.json +42 -7
  143. package/dist/admin-api/admin-client.d.ts +0 -38
  144. package/dist/admin-api/admin-client.d.ts.map +0 -1
  145. package/dist/admin-api/admin-client.js +0 -104
  146. package/dist/admin-api/admin-client.js.map +0 -1
  147. package/dist/admin-api/admin-factory.d.ts +0 -8
  148. package/dist/admin-api/admin-factory.d.ts.map +0 -1
  149. package/dist/admin-api/admin-factory.js +0 -42
  150. package/dist/admin-api/admin-factory.js.map +0 -1
  151. package/dist/admin-api/admin-types.d.ts +0 -213
  152. package/dist/admin-api/admin-types.d.ts.map +0 -1
  153. package/dist/admin-api/admin-types.js +0 -3
  154. package/dist/admin-api/admin-types.js.map +0 -1
  155. package/dist/admin-api/index.d.ts +0 -4
  156. package/dist/admin-api/index.d.ts.map +0 -1
  157. package/dist/admin-api/index.js +0 -5
  158. package/dist/admin-api/index.js.map +0 -1
  159. package/dist/auth-api/auth-client.d.ts +0 -34
  160. package/dist/auth-api/auth-client.d.ts.map +0 -1
  161. package/dist/auth-api/auth-client.js +0 -112
  162. package/dist/auth-api/auth-client.js.map +0 -1
  163. package/dist/auth-api/auth-factory.d.ts +0 -8
  164. package/dist/auth-api/auth-factory.d.ts.map +0 -1
  165. package/dist/auth-api/auth-factory.js +0 -42
  166. package/dist/auth-api/auth-factory.js.map +0 -1
  167. package/dist/auth-api/auth-types.d.ts +0 -127
  168. package/dist/auth-api/auth-types.d.ts.map +0 -1
  169. package/dist/auth-api/auth-types.js +0 -3
  170. package/dist/auth-api/auth-types.js.map +0 -1
  171. package/dist/auth-api/index.d.ts +0 -4
  172. package/dist/auth-api/index.d.ts.map +0 -1
  173. package/dist/auth-api/index.js +0 -5
  174. package/dist/auth-api/index.js.map +0 -1
  175. package/dist/http-client/api-response.d.ts +0 -16
  176. package/dist/http-client/api-response.d.ts.map +0 -1
  177. package/dist/http-client/api-response.js +0 -2
  178. 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);
@@ -62,15 +68,24 @@ function headersToRecord(headers) {
62
68
  var WebHttpClient = class {
63
69
  constructor(transport) {
64
70
  this.transport = transport;
71
+ // Cache for concurrent refresh token calls to prevent race conditions
72
+ this.refreshTokenPromise = null;
73
+ // Cache for concurrent onTokenRefresh calls to prevent duplicate callbacks
74
+ this.onTokenRefreshPromise = null;
65
75
  }
66
76
  async get(path, init) {
67
77
  return this.request(path, { ...init, method: "GET" });
68
78
  }
69
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
+ }
70
85
  return this.request(path, {
71
86
  ...init,
72
87
  method: "POST",
73
- body: body ? JSON.stringify(body) : void 0,
88
+ body: jsonBody,
74
89
  headers: {
75
90
  "Content-Type": "application/json",
76
91
  ...init?.headers
@@ -116,61 +131,10 @@ var WebHttpClient = class {
116
131
  async request(path, init) {
117
132
  return this.makeRequest(path, init);
118
133
  }
119
- async makeRequest(path, init) {
134
+ async makeRequest(path, init, retryCount = 0, requestStartTime) {
135
+ const MAX_RETRY_ATTEMPTS = 1;
120
136
  const url = this.buildUrl(path);
121
- const hasTauriInternals = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
122
- const hasTauri = typeof window !== "undefined" && "__TAURI__" in window;
123
- const isTauri = hasTauriInternals || hasTauri || this.transport.credentials === "omit";
124
- if (isTauri) {
125
- const headers2 = await this.buildHeaders(init?.headers);
126
- let headersObj2;
127
- if (headers2 instanceof Headers) {
128
- headersObj2 = {};
129
- headers2.forEach((value, key) => {
130
- headersObj2[key] = value;
131
- });
132
- } else {
133
- headersObj2 = headers2;
134
- }
135
- const requestInit2 = {};
136
- if (init?.method && init.method !== "GET") {
137
- requestInit2.method = init.method;
138
- }
139
- if (headersObj2 && Object.keys(headersObj2).length > 0) {
140
- requestInit2.headers = headersObj2;
141
- }
142
- if (init?.body !== void 0 && init.body !== null) {
143
- requestInit2.body = init.body;
144
- }
145
- if (this.transport.credentials !== void 0) {
146
- requestInit2.credentials = this.transport.credentials;
147
- }
148
- try {
149
- const response = await globalThis.fetch(url, requestInit2);
150
- if (!response.ok) {
151
- const bodyText = await this.getBodyText(response);
152
- throw new HTTPError(
153
- response.status,
154
- response.statusText,
155
- url,
156
- response.headers,
157
- bodyText
158
- );
159
- }
160
- return this.parseResponse(response, init?.parse);
161
- } catch (error) {
162
- if (error instanceof HTTPError) {
163
- throw error;
164
- }
165
- throw new HTTPError(
166
- 0,
167
- "Network Error",
168
- url,
169
- new Headers(),
170
- error instanceof Error ? error.message : "Unknown error"
171
- );
172
- }
173
- }
137
+ const startTime = requestStartTime ?? Date.now();
174
138
  const signal = this.createAbortSignal(init);
175
139
  const headers = await this.buildHeaders(init?.headers);
176
140
  let headersObj;
@@ -186,11 +150,27 @@ var WebHttpClient = class {
186
150
  method: init?.method || "GET",
187
151
  headers: headersObj
188
152
  };
189
- if (init?.body !== void 0) {
153
+ const isStreamBody = init?.body instanceof ReadableStream || typeof init?.body === "object" && init?.body !== null && "getReader" in init.body && !(init.body instanceof Blob);
154
+ if (init?.body !== void 0 && !isStreamBody) {
155
+ requestInit.body = init.body;
156
+ } else if (init?.body !== void 0 && isStreamBody && retryCount === 0) {
190
157
  requestInit.body = init.body;
191
158
  }
192
- if (signal) {
193
- requestInit.signal = signal;
159
+ let retrySignal;
160
+ if (retryCount > 0 && requestStartTime !== void 0) {
161
+ const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;
162
+ if (timeoutMs) {
163
+ const elapsed = Date.now() - startTime;
164
+ const remaining = Math.max(0, timeoutMs - elapsed);
165
+ retrySignal = this.createAbortSignal({ ...init, timeoutMs: remaining });
166
+ } else {
167
+ retrySignal = this.createAbortSignal(init);
168
+ }
169
+ } else {
170
+ retrySignal = signal;
171
+ }
172
+ if (retrySignal) {
173
+ requestInit.signal = retrySignal;
194
174
  }
195
175
  if (this.transport.credentials !== void 0) {
196
176
  requestInit.credentials = this.transport.credentials;
@@ -220,19 +200,75 @@ var WebHttpClient = class {
220
200
  const response = await this.transport.fetch(url, requestInit);
221
201
  if (!response.ok) {
222
202
  const bodyText = await this.getBodyText(response);
223
- throw new HTTPError(
203
+ const httpError = new HTTPError(
224
204
  response.status,
225
205
  response.statusText,
226
206
  url,
227
207
  response.headers,
228
208
  bodyText
229
209
  );
210
+ const userAborted = init?.signal?.aborted === true;
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 });
216
+ try {
217
+ let refreshPromise = this.refreshTokenPromise;
218
+ if (!refreshPromise) {
219
+ refreshPromise = this.transport.refreshToken();
220
+ this.refreshTokenPromise = refreshPromise;
221
+ }
222
+ const newToken = await refreshPromise;
223
+ if (!newToken || newToken.trim() === "") {
224
+ this.refreshTokenPromise = null;
225
+ this.onTokenRefreshPromise = null;
226
+ throw new Error("Refresh token returned empty token");
227
+ }
228
+ if (!this.transport.onTokenRefresh) {
229
+ this.refreshTokenPromise = null;
230
+ this.onTokenRefreshPromise = null;
231
+ throw new Error(
232
+ "onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token."
233
+ );
234
+ }
235
+ let onTokenRefreshPromise = this.onTokenRefreshPromise;
236
+ if (!onTokenRefreshPromise) {
237
+ onTokenRefreshPromise = this.transport.onTokenRefresh(newToken);
238
+ this.onTokenRefreshPromise = onTokenRefreshPromise;
239
+ }
240
+ await onTokenRefreshPromise;
241
+ this.refreshTokenPromise = null;
242
+ this.onTokenRefreshPromise = null;
243
+ const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;
244
+ if (timeoutMs && requestStartTime !== void 0) {
245
+ const elapsed = Date.now() - startTime;
246
+ const remaining = timeoutMs - elapsed;
247
+ if (remaining <= 0) {
248
+ throw httpError;
249
+ }
250
+ }
251
+ return this.makeRequest(path, init, retryCount + 1, startTime);
252
+ } catch (refreshError) {
253
+ this.refreshTokenPromise = null;
254
+ this.onTokenRefreshPromise = null;
255
+ console.log("[mero-js] Token refresh failed:", refreshError);
256
+ if (refreshError instanceof Error && refreshError.message.includes("onTokenRefresh")) {
257
+ throw refreshError;
258
+ }
259
+ throw httpError;
260
+ }
261
+ }
262
+ throw httpError;
230
263
  }
231
264
  return this.parseResponse(response, init?.parse);
232
265
  } catch (error) {
233
266
  if (error instanceof HTTPError) {
234
267
  throw error;
235
268
  }
269
+ if (error instanceof Error && error.message.includes("onTokenRefresh")) {
270
+ throw error;
271
+ }
236
272
  throw new HTTPError(
237
273
  0,
238
274
  "Network Error",
@@ -256,10 +292,6 @@ var WebHttpClient = class {
256
292
  }
257
293
  }
258
294
  createAbortSignal(init) {
259
- const isTauri = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
260
- if (isTauri) {
261
- return void 0;
262
- }
263
295
  const signals = [];
264
296
  if (this.transport.defaultAbortSignal) {
265
297
  signals.push(this.transport.defaultAbortSignal);
@@ -338,6 +370,7 @@ function createBrowserHttpClient(options) {
338
370
  baseUrl: options.baseUrl,
339
371
  getAuthToken: options.getAuthToken,
340
372
  onTokenRefresh: options.onTokenRefresh,
373
+ refreshToken: options.refreshToken,
341
374
  defaultHeaders: options.defaultHeaders,
342
375
  timeoutMs: options.timeoutMs,
343
376
  credentials: options.credentials,
@@ -362,6 +395,7 @@ function createNodeHttpClient(options) {
362
395
  baseUrl: options.baseUrl,
363
396
  getAuthToken: options.getAuthToken,
364
397
  onTokenRefresh: options.onTokenRefresh,
398
+ refreshToken: options.refreshToken,
365
399
  defaultHeaders: options.defaultHeaders,
366
400
  timeoutMs: options.timeoutMs,
367
401
  credentials: options.credentials,
@@ -437,394 +471,1481 @@ function createRetryableMethod(method, retryOptions = {}) {
437
471
  };
438
472
  }
439
473
 
440
- // 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
441
516
  var AuthApiClient = class {
442
- constructor(httpClient) {
517
+ constructor(httpClient, config) {
443
518
  this.httpClient = httpClient;
519
+ this.embedded = config.embedded ?? true;
444
520
  }
445
- // Health and Status Endpoints
446
- async getHealth() {
447
- const response = await this.httpClient.get("/auth/health");
448
- if (!response.data) {
449
- throw new Error("Health response data is null");
521
+ getAuthPath(path) {
522
+ if (this.embedded) {
523
+ return `/auth${path}`;
450
524
  }
451
- return response.data;
525
+ return path;
452
526
  }
453
- async getIdentity() {
454
- const response = await this.httpClient.get(
455
- "/admin/identity"
456
- );
457
- if (!response.data) {
458
- throw new Error("Identity response data is null");
459
- }
460
- return response.data;
527
+ // Public endpoints
528
+ async getLogin() {
529
+ return this.httpClient.get(this.getAuthPath("/login"), {
530
+ parse: "text"
531
+ });
461
532
  }
462
- async getProviders() {
463
- const response = await this.httpClient.get(
464
- "/auth/providers"
533
+ async getChallenge() {
534
+ return unwrap(
535
+ this.httpClient.get(
536
+ this.getAuthPath("/challenge")
537
+ )
465
538
  );
466
- if (!response.data) {
467
- throw new Error("Providers response data is null");
468
- }
469
- return response.data;
470
539
  }
471
- // Authentication Endpoints
472
- async getLoginPage() {
473
- return this.httpClient.get("/auth/login", { parse: "text" });
474
- }
475
- async generateTokens(request) {
476
- 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
+ );
477
547
  }
478
548
  async refreshToken(request) {
479
- return this.httpClient.post("/auth/refresh", request);
549
+ return unwrap(
550
+ this.httpClient.post(
551
+ this.getAuthPath("/refresh"),
552
+ request
553
+ )
554
+ );
480
555
  }
481
- async generateMockTokens(request) {
482
- return this.httpClient.post("/auth/mock-token", request);
556
+ async getProviders() {
557
+ return unwrap(
558
+ this.httpClient.get(
559
+ this.getAuthPath("/providers")
560
+ )
561
+ );
483
562
  }
484
- async getChallenge() {
485
- return this.httpClient.get("/auth/challenge");
563
+ async getIdentity() {
564
+ return unwrap(
565
+ this.httpClient.get(
566
+ this.getAuthPath("/identity")
567
+ )
568
+ );
486
569
  }
487
- async validateToken(token) {
488
- try {
489
- const response = await this.validateTokenGet(token);
490
- return {
491
- valid: response.status === 200,
492
- headers: response.headers,
493
- status: response.status
494
- };
495
- } catch (error) {
496
- return {
497
- valid: false,
498
- headers: {},
499
- status: 401
500
- };
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 };
580
+ }
581
+ if (typeof response.data === "object" && "valid" in response.data) {
582
+ return response.data;
501
583
  }
584
+ return { valid: true };
502
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
+ */
503
592
  async validateTokenGet(token) {
504
- const response = await this.httpClient.head("/auth/validate", {
505
- headers: { Authorization: `Bearer ${token}` }
593
+ const response = await this.httpClient.get(this.getAuthPath("/validate"), {
594
+ headers: {
595
+ Authorization: `Bearer ${token}`
596
+ }
506
597
  });
507
- return {
508
- status: response.status,
509
- headers: response.headers
510
- };
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 };
511
605
  }
512
- async isAuthed() {
513
- return this.httpClient.get("/auth/is-authed");
606
+ async getHealth() {
607
+ return unwrap(
608
+ this.httpClient.get(
609
+ this.getAuthPath("/health")
610
+ )
611
+ );
514
612
  }
515
- // Token Management Endpoints
516
- async revokeTokens(request) {
517
- 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
+ );
518
630
  }
519
- // Key Management Endpoints
520
631
  async listRootKeys() {
521
- const response = await this.httpClient.get("/admin/keys");
522
- if (!response.data) {
523
- throw new Error("Root keys response data is null");
524
- }
525
- return response.data;
632
+ return unwrap(
633
+ this.httpClient.get(
634
+ this.getAuthPath("/admin/keys")
635
+ )
636
+ );
526
637
  }
527
638
  async createRootKey(request) {
528
- return this.httpClient.post("/admin/keys", request);
639
+ return unwrap(
640
+ this.httpClient.post(
641
+ this.getAuthPath("/admin/keys"),
642
+ request
643
+ )
644
+ );
529
645
  }
530
646
  async deleteRootKey(keyId) {
531
- return this.httpClient.delete(`/admin/keys/${keyId}`);
647
+ return unwrap(
648
+ this.httpClient.delete(
649
+ this.getAuthPath(`/admin/keys/${keyId}`)
650
+ )
651
+ );
532
652
  }
533
- // Client Management Endpoints
534
653
  async listClientKeys() {
535
- const response = await this.httpClient.get(
536
- "/admin/keys/clients"
654
+ return unwrap(
655
+ this.httpClient.get(
656
+ this.getAuthPath("/admin/keys/clients")
657
+ )
537
658
  );
538
- if (!response.data) {
539
- throw new Error("Client keys response data is null");
540
- }
541
- return response.data;
542
659
  }
543
660
  async generateClientKey(request) {
544
- 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
+ );
545
667
  }
546
668
  async deleteClientKey(keyId, clientId) {
547
- return this.httpClient.delete(
548
- `/admin/keys/${keyId}/clients/${clientId}`
669
+ return unwrap(
670
+ this.httpClient.delete(
671
+ this.getAuthPath(`/admin/keys/${keyId}/clients/${clientId}`)
672
+ )
549
673
  );
550
674
  }
551
- // Permission Management Endpoints
552
675
  async getKeyPermissions(keyId) {
553
- return this.httpClient.get(
554
- `/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
+ )
555
688
  );
556
689
  }
557
- async updateKeyPermissions(keyId, permissions) {
558
- return this.httpClient.put(
559
- `/admin/keys/${keyId}/permissions`,
560
- { 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
+ )
561
702
  );
562
703
  }
563
704
  };
564
705
 
565
- // src/auth-api/auth-factory.ts
566
- var MockHttpClient = class {
567
- async get() {
568
- throw new Error(
569
- "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")
570
736
  );
571
737
  }
572
- async post() {
573
- throw new Error(
574
- "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
+ )
575
743
  );
576
744
  }
577
- async put() {
578
- throw new Error(
579
- "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
+ )
580
763
  );
581
764
  }
582
- async delete() {
583
- throw new Error(
584
- "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
+ )
585
771
  );
586
772
  }
587
- async patch() {
588
- throw new Error(
589
- "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
+ )
590
778
  );
591
779
  }
592
- async head() {
593
- throw new Error(
594
- "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
+ )
595
785
  );
596
786
  }
597
- async request() {
598
- throw new Error(
599
- "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
+ )
600
813
  );
601
814
  }
602
815
  };
603
- function createBrowserAuthApiClient(_config) {
604
- const httpClient = new MockHttpClient();
605
- return new AuthApiClient(httpClient);
606
- }
607
- function createNodeAuthApiClient(_config) {
608
- const httpClient = new MockHttpClient();
609
- return new AuthApiClient(httpClient);
610
- }
611
- function createAuthApiClient(_config) {
612
- const httpClient = new MockHttpClient();
613
- return new AuthApiClient(httpClient);
614
- }
615
- function createAuthApiClientFromHttpClient(httpClient, _config) {
616
- return new AuthApiClient(httpClient);
617
- }
618
816
 
619
- // src/admin-api/admin-client.ts
620
- var AdminApiClient = class {
817
+ // src/api/admin/contexts.ts
818
+ var ContextsApiClient = class {
621
819
  constructor(httpClient) {
622
820
  this.httpClient = httpClient;
623
821
  }
624
- // Health and Status Endpoints
625
- async healthCheck() {
626
- const response = await this.httpClient.get("/health");
627
- if (!response.data) {
628
- throw new Error("Health response data is null");
629
- }
630
- return response.data;
822
+ async listContexts() {
823
+ return unwrap(
824
+ this.httpClient.get(
825
+ "/admin-api/contexts"
826
+ )
827
+ );
631
828
  }
632
- async isAuthed() {
633
- 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
+ );
634
836
  }
635
- // Application Management Endpoints
636
- async installApplication(request) {
637
- return this.httpClient.post(
638
- "/install-application",
639
- request
837
+ async getContext(contextId) {
838
+ return unwrap(
839
+ this.httpClient.get(
840
+ `/admin-api/contexts/${contextId}`
841
+ )
640
842
  );
641
843
  }
642
- async installDevApplication(request) {
643
- return this.httpClient.post(
644
- "/install-dev-application",
645
- request
844
+ async deleteContext(contextId) {
845
+ return unwrap(
846
+ this.httpClient.delete(
847
+ `/admin-api/contexts/${contextId}`
848
+ )
646
849
  );
647
850
  }
648
- async uninstallApplication(appId) {
649
- return this.httpClient.delete(
650
- `/applications/${appId}`
851
+ async getContextStorage(contextId) {
852
+ return unwrap(
853
+ this.httpClient.get(
854
+ `/admin-api/contexts/${contextId}/storage`
855
+ )
651
856
  );
652
857
  }
653
- async listApplications() {
654
- return this.httpClient.get("/applications");
858
+ async getContextIdentities(contextId) {
859
+ return unwrap(
860
+ this.httpClient.get(
861
+ `/admin-api/contexts/${contextId}/identities`
862
+ )
863
+ );
655
864
  }
656
- async getApplication(appId) {
657
- return this.httpClient.get(
658
- `/applications/${appId}`
865
+ async getContextIdentitiesOwned(contextId) {
866
+ return unwrap(
867
+ this.httpClient.get(
868
+ `/admin-api/contexts/${contextId}/identities-owned`
869
+ )
659
870
  );
660
871
  }
661
- // Context Management Endpoints
662
- async createContext(request) {
663
- 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
+ );
664
879
  }
665
- async deleteContext(contextId) {
666
- return this.httpClient.delete(
667
- `/contexts/${contextId}`
880
+ async inviteToContextOpenInvitation(request) {
881
+ return unwrap(
882
+ this.httpClient.post(
883
+ "/admin-api/contexts/invite_by_open_invitation",
884
+ request
885
+ )
668
886
  );
669
887
  }
670
- async getContexts() {
671
- 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
+ );
672
895
  }
673
- async getContext(contextId) {
674
- 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
+ );
675
903
  }
676
- // Blob Management Endpoints
677
- async uploadBlob(request) {
678
- 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
+ );
679
911
  }
680
- async deleteBlob(blobId) {
681
- 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
+ );
682
919
  }
683
- async listBlobs() {
684
- 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
+ );
685
926
  }
686
- async getBlob(blobId) {
687
- 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
+ );
688
933
  }
689
- // Alias Management Endpoints
690
- async createAlias(request) {
691
- return this.httpClient.post("/alias", request);
934
+ async getProxyContract(contextId) {
935
+ return unwrap(
936
+ this.httpClient.get(
937
+ `/admin-api/contexts/${contextId}/proxy-contract`
938
+ )
939
+ );
692
940
  }
693
- async deleteAlias(aliasId) {
694
- return this.httpClient.delete(`/alias/${aliasId}`);
941
+ async syncContext() {
942
+ return unwrap(
943
+ this.httpClient.post(
944
+ "/admin-api/contexts/sync",
945
+ {}
946
+ )
947
+ );
695
948
  }
696
- async listAliases() {
697
- return this.httpClient.get("/alias");
949
+ async syncContextById(contextId) {
950
+ return unwrap(
951
+ this.httpClient.post(
952
+ `/admin-api/contexts/sync/${contextId}`,
953
+ {}
954
+ )
955
+ );
698
956
  }
699
- async getAlias(aliasId) {
700
- return this.httpClient.get(`/alias/${aliasId}`);
957
+ };
958
+
959
+ // src/api/admin/proposals.ts
960
+ var ProposalsApiClient = class {
961
+ constructor(httpClient) {
962
+ this.httpClient = httpClient;
701
963
  }
702
- // Network Management Endpoints
703
- async getNetworkPeers() {
704
- return this.httpClient.get("/network/peers");
964
+ async getProposals(contextId, request) {
965
+ return unwrap(
966
+ this.httpClient.post(
967
+ `/admin-api/contexts/${contextId}/proposals`,
968
+ request
969
+ )
970
+ );
705
971
  }
706
- async getNetworkStats() {
707
- return this.httpClient.get("/network/stats");
972
+ async getProposal(contextId, proposalId) {
973
+ return unwrap(
974
+ this.httpClient.get(
975
+ `/admin-api/contexts/${contextId}/proposals/${proposalId}`
976
+ )
977
+ );
708
978
  }
709
- async getNetworkConfig() {
710
- return this.httpClient.get("/network/config");
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
+ );
711
986
  }
712
- async updateNetworkConfig(request) {
713
- return this.httpClient.put(
714
- "/network/config",
715
- request
987
+ async approveProposal(contextId, request) {
988
+ return unwrap(
989
+ this.httpClient.post(
990
+ `/admin-api/contexts/${contextId}/proposals/approve`,
991
+ request
992
+ )
993
+ );
994
+ }
995
+ async getNumberOfActiveProposals(contextId) {
996
+ return unwrap(
997
+ this.httpClient.get(
998
+ `/admin-api/contexts/${contextId}/proposals/count`
999
+ )
1000
+ );
1001
+ }
1002
+ async getNumberOfProposalApprovals(contextId, proposalId) {
1003
+ return unwrap(
1004
+ this.httpClient.get(
1005
+ `/admin-api/contexts/${contextId}/proposals/${proposalId}/approvals/count`
1006
+ )
1007
+ );
1008
+ }
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
+ )
716
1022
  );
717
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
+ )
1030
+ );
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
+ }
718
1077
  async getPeersCount() {
719
- return this.httpClient.get("/network/peers/count");
1078
+ return this.httpClient.get("/admin-api/peers");
720
1079
  }
721
- // System Management Endpoints
722
- async getSystemInfo() {
723
- return this.httpClient.get("/system/info");
1080
+ };
1081
+
1082
+ // src/api/admin/blobs.ts
1083
+ var BlobsApiClient = class {
1084
+ constructor(httpClient) {
1085
+ this.httpClient = httpClient;
724
1086
  }
725
- async getSystemLogs() {
726
- return this.httpClient.get("/system/logs");
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
+ };
727
1105
  }
728
- async getSystemMetrics() {
729
- return this.httpClient.get("/system/metrics");
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
+ };
730
1117
  }
731
- async restartSystem() {
732
- return this.httpClient.post("/system/restart");
1118
+ async getBlob(blobId) {
1119
+ return this.httpClient.get(`/admin-api/blobs/${blobId}`, {
1120
+ parse: "blob"
1121
+ });
733
1122
  }
734
- async shutdownSystem() {
735
- return this.httpClient.post("/system/shutdown");
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
+ };
1130
+ }
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
+ };
736
1141
  }
737
1142
  };
738
1143
 
739
- // src/admin-api/admin-factory.ts
740
- var MockHttpClient2 = class {
741
- async get() {
742
- throw new Error(
743
- "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
+ )
744
1155
  );
745
1156
  }
746
- async post() {
747
- throw new Error(
748
- "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
+ )
749
1163
  );
750
1164
  }
751
- async put() {
752
- throw new Error(
753
- "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
+ )
754
1171
  );
755
1172
  }
756
- async delete() {
757
- throw new Error(
758
- "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
+ )
759
1179
  );
760
1180
  }
761
- async patch() {
762
- throw new Error(
763
- "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
+ )
764
1187
  );
765
1188
  }
766
- async head() {
767
- throw new Error(
768
- "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
+ )
769
1195
  );
770
1196
  }
771
- async request() {
772
- throw new Error(
773
- "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
+ )
774
1240
  );
775
1241
  }
776
1242
  };
777
- function createBrowserAdminApiClient(_config) {
778
- const httpClient = new MockHttpClient2();
779
- return new AdminApiClient(httpClient);
780
- }
781
- function createNodeAdminApiClient(_config) {
782
- const httpClient = new MockHttpClient2();
783
- return new AdminApiClient(httpClient);
784
- }
785
- function createAdminApiClient(_config) {
786
- const httpClient = new MockHttpClient2();
787
- return new AdminApiClient(httpClient);
788
- }
789
- 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) {
790
1351
  return new AdminApiClient(httpClient);
791
1352
  }
792
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
+
793
1872
  // src/mero-js.ts
794
1873
  var MeroJs = class {
795
1874
  constructor(config) {
796
1875
  this.tokenData = null;
797
1876
  this.refreshPromise = null;
1877
+ this.tokenStorage = null;
798
1878
  this.config = {
799
1879
  timeoutMs: 1e4,
800
1880
  ...config
801
1881
  };
1882
+ this.tokenStorage = config.tokenStorage || null;
802
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;
803
1886
  this.httpClient = createBrowserHttpClient({
804
1887
  baseUrl: this.config.baseUrl,
805
1888
  getAuthToken: async () => {
806
1889
  const token = await this.getValidToken();
807
1890
  return token?.access_token || "";
808
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
+ },
809
1902
  timeoutMs: this.config.timeoutMs,
810
1903
  credentials: this.config.requestCredentials ?? (isTauri ? "omit" : void 0)
811
1904
  });
812
- this.authClient = createAuthApiClientFromHttpClient(this.httpClient, {
813
- baseUrl: this.config.baseUrl,
1905
+ const authHttpClient = createBrowserHttpClient({
1906
+ baseUrl: authBaseUrl,
814
1907
  getAuthToken: async () => {
815
1908
  const token = await this.getValidToken();
816
1909
  return token?.access_token || "";
817
1910
  },
818
- 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)
819
1915
  });
820
- this.adminClient = createAdminApiClientFromHttpClient(this.httpClient, {
821
- baseUrl: this.config.baseUrl,
822
- getAuthToken: async () => {
823
- const token = await this.getValidToken();
824
- return token?.access_token || "";
825
- },
826
- timeoutMs: this.config.timeoutMs
1916
+ this.authClient = createAuthApiClient(authHttpClient, {
1917
+ baseUrl: authBaseUrl,
1918
+ embedded: isEmbedded
827
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
+ }
828
1949
  }
829
1950
  /**
830
1951
  * Get the Auth API client
@@ -838,6 +1959,39 @@ var MeroJs = class {
838
1959
  get admin() {
839
1960
  return this.adminClient;
840
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
+ }
841
1995
  /**
842
1996
  * Authenticate with the provided credentials
843
1997
  * This will create the root key on first use
@@ -859,44 +2013,82 @@ var MeroJs = class {
859
2013
  password: creds.password
860
2014
  }
861
2015
  };
862
- 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
+ }
863
2026
  this.tokenData = {
864
- access_token: response.data.access_token,
865
- refresh_token: response.data.refresh_token,
866
- expires_at: Date.now() + 24 * 60 * 60 * 1e3
867
- // Default to 24 hours
2027
+ access_token: response.access_token,
2028
+ refresh_token: response.refresh_token,
2029
+ expires_at: expiresAt
868
2030
  };
2031
+ if (this.tokenStorage) {
2032
+ await this.tokenStorage.set(this.tokenData);
2033
+ }
869
2034
  return this.tokenData;
870
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)}` : "";
871
2040
  throw new Error(
872
- `Authentication failed: ${error instanceof Error ? error.message : "Unknown error"}`
2041
+ `Authentication failed: ${httpStatus}${httpStatusText}${bodyText || errorMessage}`
873
2042
  );
874
2043
  }
875
2044
  }
876
2045
  /**
877
- * 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.
878
2051
  */
879
2052
  async getValidToken() {
2053
+ console.log("[mero-js] getValidToken called, tokenData:", this.tokenData ? "EXISTS" : "NULL");
880
2054
  if (!this.tokenData) {
2055
+ console.log("[mero-js] No tokenData, returning null");
881
2056
  return null;
882
2057
  }
883
- const bufferTime = 5 * 60 * 1e3;
884
- 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");
885
2064
  return await this.refreshToken();
886
2065
  }
2066
+ console.log("[mero-js] Token valid, returning tokenData");
887
2067
  return this.tokenData;
888
2068
  }
889
2069
  /**
890
- * 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
891
2074
  */
892
2075
  async refreshToken() {
893
- if (!this.tokenData?.refresh_token) {
894
- throw new Error("No refresh token available");
895
- }
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() {
896
2086
  if (this.refreshPromise) {
2087
+ console.log("[mero-js] Refresh already in progress, waiting for existing promise");
897
2088
  return this.refreshPromise;
898
2089
  }
899
- this.refreshPromise = this.performTokenRefresh();
2090
+ console.log("[mero-js] Starting new refresh attempt");
2091
+ this.refreshPromise = this.doTokenRefresh();
900
2092
  try {
901
2093
  const newToken = await this.refreshPromise;
902
2094
  return newToken;
@@ -905,36 +2097,87 @@ var MeroJs = class {
905
2097
  }
906
2098
  }
907
2099
  /**
908
- * Perform the actual token refresh
2100
+ * Internal: Actually perform the refresh request.
2101
+ * Called only from performTokenRefresh() which manages the deduplication.
909
2102
  */
910
- 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);
911
2108
  if (!this.tokenData?.refresh_token) {
912
2109
  throw new Error("No refresh token available");
913
2110
  }
2111
+ if (!this.tokenData?.access_token) {
2112
+ throw new Error("No access token available for refresh (server requires both tokens)");
2113
+ }
914
2114
  try {
915
- const response = await this.authClient.refreshToken({
2115
+ const refreshPayload = {
916
2116
  access_token: this.tokenData.access_token,
917
2117
  refresh_token: this.tokenData.refresh_token
918
- });
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
+ }
919
2132
  this.tokenData = {
920
- access_token: response.data.access_token,
921
- refresh_token: response.data.refresh_token,
922
- expires_at: Date.now() + 24 * 60 * 60 * 1e3
923
- // Default to 24 hours
2133
+ access_token: response.access_token,
2134
+ refresh_token: response.refresh_token,
2135
+ expires_at: expiresAt
924
2136
  };
2137
+ if (this.tokenStorage) {
2138
+ await this.tokenStorage.set(this.tokenData);
2139
+ }
925
2140
  return this.tokenData;
926
2141
  } catch (error) {
927
- 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();
928
2168
  throw new Error(
929
2169
  `Token refresh failed: ${error instanceof Error ? error.message : "Unknown error"}`
930
2170
  );
931
2171
  }
932
2172
  }
933
2173
  /**
934
- * Clear the current token
2174
+ * Clear the current token from memory and storage
935
2175
  */
936
- clearToken() {
2176
+ async clearToken() {
937
2177
  this.tokenData = null;
2178
+ if (this.tokenStorage) {
2179
+ await this.tokenStorage.clear();
2180
+ }
938
2181
  }
939
2182
  /**
940
2183
  * Check if the SDK is authenticated
@@ -948,32 +2191,123 @@ var MeroJs = class {
948
2191
  getTokenData() {
949
2192
  return this.tokenData;
950
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
+ }
951
2279
  };
952
2280
  function createMeroJs(config) {
953
2281
  return new MeroJs(config);
954
2282
  }
955
2283
  export {
2284
+ admin_exports as AdminApi,
956
2285
  AdminApiClient,
2286
+ ApiResponseError,
2287
+ auth_exports as AuthApi,
957
2288
  AuthApiClient,
958
2289
  HTTPError,
2290
+ JsonRpcError,
959
2291
  MeroJs,
2292
+ rpc_exports as RpcApi,
2293
+ RpcClient,
2294
+ sse_exports as SseApi,
2295
+ SseClient,
960
2296
  WebHttpClient,
2297
+ WebSocketClient,
2298
+ ws_exports as WsApi,
961
2299
  combineSignals,
962
2300
  createAdminApiClient,
963
- createAdminApiClientFromHttpClient,
964
2301
  createAuthApiClient,
965
- createAuthApiClientFromHttpClient,
966
- createBrowserAdminApiClient,
967
- createBrowserAuthApiClient,
968
2302
  createBrowserHttpClient,
969
2303
  createHttpClient,
970
2304
  createMeroJs,
971
- createNodeAdminApiClient,
972
- createNodeAuthApiClient,
973
2305
  createNodeHttpClient,
974
2306
  createRetryableMethod,
975
2307
  createTimeoutSignal,
976
2308
  createUniversalHttpClient,
2309
+ unwrap,
2310
+ unwrapOrNull,
977
2311
  withRetry
978
2312
  };
979
2313
  //# sourceMappingURL=index.mjs.map