@calimero-network/mero-js 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin-api/admin-client.d.ts.map +1 -1
- package/dist/admin-api/admin-client.js +10 -3
- package/dist/admin-api/admin-client.js.map +1 -1
- package/dist/admin-api/admin-types.d.ts +5 -0
- package/dist/admin-api/admin-types.d.ts.map +1 -1
- package/dist/index.browser.mjs +1 -1
- package/dist/index.browser.mjs.map +2 -2
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +2 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/http-client/signal-utils.ts", "../src/http-client/web-client.ts", "../src/http-client/http-factory.ts", "../src/http-client/retry.ts", "../src/auth-api/auth-client.ts", "../src/auth-api/auth-factory.ts", "../src/admin-api/admin-client.ts", "../src/admin-api/admin-factory.ts", "../src/auth/index.ts", "../src/rpc/index.ts", "../src/events/sse.ts", "../src/events/ws.ts", "../src/mero-js.ts", "../src/token-store/index.ts", "../src/cloud/cloud-client.ts", "../src/capabilities.ts"],
|
|
4
|
-
"sourcesContent": ["// Utility for combining multiple AbortSignals\nexport function combineSignals(\n signals: Array<AbortSignal | undefined>,\n): AbortSignal | undefined {\n const list = signals.filter(Boolean) as AbortSignal[];\n if (list.length === 0) return undefined;\n\n // Prefer native any(), but fall back if unavailable or it throws\n const AbortSignalAny = AbortSignal as {\n any?: (signals: AbortSignal[]) => AbortSignal;\n };\n if (typeof AbortSignalAny.any === 'function') {\n try {\n return AbortSignalAny.any(list);\n } catch {\n // Fall through to manual implementation\n }\n }\n\n const controller = new AbortController();\n const onAbort = (evt: Event) => {\n controller.abort((evt.target as AbortSignal).reason);\n for (const s of list) s.removeEventListener('abort', onAbort);\n };\n\n for (const s of list) {\n if (s.aborted) return AbortSignal.abort(s.reason);\n s.addEventListener('abort', onAbort, { once: true });\n }\n\n return controller.signal;\n}\n\n// Helper to create a timeout signal\nexport function createTimeoutSignal(timeoutMs: number): AbortSignal {\n // Use AbortSignal.timeout if available (Node 18.17+, modern browsers)\n if (typeof AbortSignal.timeout === 'function') {\n return AbortSignal.timeout(timeoutMs);\n }\n\n // Fallback for older environments\n const controller = new AbortController();\n setTimeout(() => {\n controller.abort(new DOMException('Timeout', 'TimeoutError'));\n }, timeoutMs);\n\n return controller.signal;\n}\n", "// ErrorResponse import removed as it's not used\nimport {\n HttpClient,\n Transport,\n RequestOptions,\n ResponseParser,\n} from './http-types';\nimport { combineSignals, createTimeoutSignal } from './signal-utils';\n\n// Custom error class for HTTP errors\nexport class HTTPError extends Error {\n name = 'HTTPError' as const;\n\n constructor(\n public status: number,\n public statusText: string,\n public url: string,\n public headers: Headers,\n public bodyText?: string, // cap at ~64KB\n ) {\n super(`HTTP ${status} ${statusText}`);\n }\n\n toJSON(): {\n status: number;\n statusText: string;\n url: string;\n headers: Record<string, string>;\n bodyText?: string;\n } {\n return {\n status: this.status,\n statusText: this.statusText,\n url: this.url,\n headers: headersToRecord(this.headers),\n bodyText: this.bodyText,\n };\n }\n}\n\n// Helper function to convert Headers to Record\nfunction headersToRecord(headers: Headers): Record<string, string> {\n const record: Record<string, string> = {};\n headers.forEach((value, key) => {\n record[key] = value;\n });\n return record;\n}\n\n// Web Standards HTTP client implementation\nexport class WebHttpClient implements HttpClient {\n // Cache for concurrent refresh token calls to prevent race conditions\n private refreshTokenPromise: Promise<string> | null = null;\n // Cache for concurrent onTokenRefresh calls to prevent duplicate callbacks\n private onTokenRefreshPromise: Promise<void> | null = null;\n \n constructor(private transport: Transport) {}\n\n async get<T>(path: string, init?: RequestOptions): Promise<T> {\n return this.request<T>(path, { ...init, method: 'GET' });\n }\n\n async post<T>(\n path: string,\n body?: unknown,\n init?: RequestOptions,\n ): Promise<T> {\n return this.request<T>(path, {\n ...init,\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n headers: {\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n });\n }\n\n async put<T>(\n path: string,\n body?: unknown,\n init?: RequestOptions,\n ): Promise<T> {\n return this.request<T>(path, {\n ...init,\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined,\n headers: {\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n });\n }\n\n async delete<T>(path: string, init?: RequestOptions): Promise<T> {\n return this.request<T>(path, { ...init, method: 'DELETE' });\n }\n\n async patch<T>(\n path: string,\n body?: unknown,\n init?: RequestOptions,\n ): Promise<T> {\n return this.request<T>(path, {\n ...init,\n method: 'PATCH',\n body: body ? JSON.stringify(body) : undefined,\n headers: {\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n });\n }\n\n async head(\n path: string,\n init?: RequestOptions,\n ): Promise<{ headers: Record<string, string>; status: number }> {\n const response = await this.makeRequest<Response>(path, {\n ...init,\n method: 'HEAD',\n parse: 'response',\n });\n return {\n headers: headersToRecord(response.headers),\n status: response.status,\n };\n }\n\n async request<T>(path: string, init?: RequestOptions): Promise<T> {\n return this.makeRequest<T>(path, init);\n }\n\n private async makeRequest<T>(\n path: string,\n init?: RequestOptions,\n retryCount = 0,\n requestStartTime?: number,\n ): Promise<T> {\n // Maximum retry attempts to prevent infinite loops\n const MAX_RETRY_ATTEMPTS = 1;\n const url = this.buildUrl(path);\n \n // Track request start time for timeout calculation (only on first attempt)\n // Use per-request start time to avoid corruption from concurrent requests\n const startTime = requestStartTime ?? Date.now();\n // Note: Tauri proxy script now handles AbortSignal, so we can use full RequestInit\n // Removed Tauri-specific minimal path - proxy script handles AbortSignal properly\n const signal = this.createAbortSignal(init);\n const headers = await this.buildHeaders(init?.headers);\n let headersObj: Record<string, string>;\n if (headers instanceof Headers) {\n headersObj = {};\n headers.forEach((value, key) => {\n headersObj[key] = value;\n });\n } else {\n headersObj = headers;\n }\n \n const requestInit: RequestInit = {\n method: init?.method || 'GET',\n headers: headersObj,\n };\n \n // Check if body is a stream (ReadableStream) that can't be reused\n // Note: Blob is reusable, so it's not included here\n const isStreamBody = init?.body instanceof ReadableStream ||\n (typeof init?.body === 'object' && init?.body !== null && 'getReader' in init.body && !(init.body instanceof Blob));\n \n if (init?.body !== undefined && !isStreamBody) {\n requestInit.body = init.body;\n } else if (init?.body !== undefined && isStreamBody && retryCount === 0) {\n // Only include stream body on first attempt - can't retry with streams\n requestInit.body = init.body;\n }\n \n // For retries, calculate remaining timeout to prevent timeout reset\n // Track elapsed time and use remaining timeout for retry\n // Note: This is calculated before the request, so it doesn't include token refresh time\n // The actual remaining timeout check happens after token refresh completes\n let retrySignal: AbortSignal | undefined;\n if (retryCount > 0 && requestStartTime !== undefined) {\n const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;\n if (timeoutMs) {\n // Calculate elapsed time (will be recalculated after token refresh if needed)\n const elapsed = Date.now() - startTime;\n const remaining = Math.max(0, timeoutMs - elapsed);\n // Create signal with remaining timeout, preserving user's signal\n retrySignal = this.createAbortSignal({ ...init, timeoutMs: remaining });\n } else {\n // No timeout, just preserve user's signal\n retrySignal = this.createAbortSignal(init);\n }\n } else {\n retrySignal = signal;\n }\n \n if (retrySignal) {\n requestInit.signal = retrySignal;\n }\n \n if (this.transport.credentials !== undefined) {\n requestInit.credentials = this.transport.credentials;\n }\n \n if (init?.mode !== undefined) {\n requestInit.mode = init.mode;\n }\n if (init?.cache !== undefined) {\n requestInit.cache = init.cache;\n }\n if (init?.redirect !== undefined) {\n requestInit.redirect = init.redirect;\n }\n if (init?.referrer !== undefined) {\n requestInit.referrer = init.referrer;\n }\n if (init?.referrerPolicy !== undefined) {\n requestInit.referrerPolicy = init.referrerPolicy;\n }\n if (init?.integrity !== undefined) {\n requestInit.integrity = init.integrity;\n }\n if (init?.keepalive !== undefined) {\n requestInit.keepalive = init.keepalive;\n }\n\n try {\n const response = await this.transport.fetch(url, requestInit);\n\n if (!response.ok) {\n const bodyText = await this.getBodyText(response);\n const httpError = new HTTPError(\n response.status,\n response.statusText,\n url,\n response.headers,\n bodyText,\n );\n\n // Handle 401 with token_expired - attempt automatic token refresh\n const userAborted = init?.signal?.aborted === true;\n if (\n response.status === 401 &&\n this.transport.refreshToken &&\n response.headers.get('x-auth-error') === 'token_expired' &&\n retryCount < MAX_RETRY_ATTEMPTS &&\n !isStreamBody &&\n !userAborted\n ) {\n try {\n // Use cached refresh promise if one is in progress (prevents race conditions)\n let refreshPromise = this.refreshTokenPromise;\n if (!refreshPromise) {\n refreshPromise = this.transport.refreshToken();\n this.refreshTokenPromise = refreshPromise;\n }\n \n // Attempt to refresh the token\n const newToken = await refreshPromise;\n \n // Validate token - must be non-empty\n if (!newToken || newToken.trim() === '') {\n // Clear caches on error\n this.refreshTokenPromise = null;\n this.onTokenRefreshPromise = null;\n throw new Error('Refresh token returned empty token');\n }\n \n // onTokenRefresh is required when refreshToken is provided\n // Without it, the new token cannot be stored and getAuthToken() will return the old token\n if (!this.transport.onTokenRefresh) {\n // Clear caches on error\n this.refreshTokenPromise = null;\n this.onTokenRefreshPromise = null;\n throw new Error(\n 'onTokenRefresh callback is required when refreshToken is provided. ' +\n 'The callback must update the token storage so getAuthToken() returns the new token.'\n );\n }\n \n // Use cached onTokenRefresh promise if one is in progress (prevents duplicate callbacks)\n // This ensures onTokenRefresh is only called once per token refresh, even with concurrent requests\n let onTokenRefreshPromise = this.onTokenRefreshPromise;\n if (!onTokenRefreshPromise) {\n onTokenRefreshPromise = this.transport.onTokenRefresh(newToken);\n this.onTokenRefreshPromise = onTokenRefreshPromise;\n }\n \n // Update token via callback (only called once per refresh, even with concurrent requests)\n // Errors from onTokenRefresh callback should be preserved (don't mask as 401)\n // This helps developers debug token storage issues\n await onTokenRefreshPromise;\n \n // Clear caches after both refresh and callback complete\n this.refreshTokenPromise = null;\n this.onTokenRefreshPromise = null;\n \n // Check if timeout has expired during token refresh\n // If so, throw the original 401 error instead of retrying with 0ms timeout\n // This prevents timeout/abort errors that obscure the root cause (expired token)\n const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;\n if (timeoutMs && requestStartTime !== undefined) {\n const elapsed = Date.now() - startTime;\n const remaining = timeoutMs - elapsed;\n if (remaining <= 0) {\n // Timeout expired during token refresh - throw original 401 error\n // This is better than retrying with 0ms timeout which would cause confusing timeout errors\n throw httpError;\n }\n }\n \n // Retry the request with the new token (increment retry count)\n // Preserve user's abort signal and start time in retry\n return this.makeRequest<T>(path, init, retryCount + 1, startTime);\n } catch (refreshError) {\n // Clear caches on error\n this.refreshTokenPromise = null;\n this.onTokenRefreshPromise = null;\n // Configuration errors (missing onTokenRefresh) should be thrown as-is\n if (refreshError instanceof Error && refreshError.message.includes('onTokenRefresh')) {\n throw refreshError;\n }\n // Errors from onTokenRefresh callback are already thrown above, so if we get here,\n // it's either a refreshToken() failure or empty token - throw original 401\n // This matches the PR description: \"If refresh fails, throws the original 401 error\"\n throw httpError;\n }\n }\n\n throw httpError;\n }\n\n return this.parseResponse<T>(response, init?.parse);\n } catch (error) {\n if (error instanceof HTTPError) {\n throw error;\n }\n // Preserve configuration errors (like missing onTokenRefresh)\n if (error instanceof Error && error.message.includes('onTokenRefresh')) {\n throw error;\n }\n throw new HTTPError(\n 0,\n 'Network Error',\n url,\n new Headers(),\n error instanceof Error ? error.message : 'Unknown error',\n );\n }\n }\n\n private buildUrl(path: string): string {\n // Handle absolute URLs\n if (path.startsWith('http://') || path.startsWith('https://')) {\n return path;\n }\n\n // Handle baseUrl with path\n const baseUrl = this.transport.baseUrl;\n if (path.startsWith('/')) {\n // If path starts with /, combine with baseUrl\n const base = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n return `${base}${path}`;\n } else {\n // If path doesn't start with /, append to baseUrl\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;\n return `${base}${path}`;\n }\n }\n\n private createAbortSignal(init?: RequestOptions): AbortSignal | undefined {\n const signals: AbortSignal[] = [];\n\n if (this.transport.defaultAbortSignal) {\n signals.push(this.transport.defaultAbortSignal);\n }\n\n if (init?.signal) {\n signals.push(init.signal);\n }\n\n const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;\n if (timeoutMs) {\n signals.push(createTimeoutSignal(timeoutMs));\n }\n\n return signals.length > 0 ? combineSignals(signals) : undefined;\n }\n\n private async buildHeaders(\n initHeaders?: HeadersInit,\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n ...this.transport.defaultHeaders,\n };\n\n // Add auth token if available and not empty\n if (this.transport.getAuthToken) {\n try {\n const token = await this.transport.getAuthToken();\n if (token && token.trim() !== '') {\n headers.Authorization = `Bearer ${token}`;\n }\n } catch (error) {\n // Ignore auth token errors\n }\n }\n\n // Add init headers\n if (initHeaders) {\n if (initHeaders instanceof Headers) {\n initHeaders.forEach((value, key) => {\n headers[key] = value;\n });\n } else if (Array.isArray(initHeaders)) {\n initHeaders.forEach(([key, value]) => {\n headers[key] = value;\n });\n } else {\n Object.assign(headers, initHeaders);\n }\n }\n\n return headers;\n }\n\n private async parseResponse<T>(\n response: Response,\n parse?: ResponseParser,\n ): Promise<T> {\n switch (parse) {\n case 'text':\n return (await response.text()) as T;\n case 'blob':\n return (await response.blob()) as T;\n case 'arrayBuffer':\n return (await response.arrayBuffer()) as T;\n case 'response':\n return response as T;\n case 'json':\n default:\n return await response.json();\n }\n }\n\n private async getBodyText(response: Response): Promise<string> {\n try {\n const text = await response.text();\n return text.length > 65536 ? text.slice(0, 65536) + '...' : text;\n } catch {\n return '';\n }\n }\n}\n", "import { WebHttpClient } from './web-client';\nimport { Transport, HttpClient } from './http-types';\n\n// Factory function to create HTTP client with sensible defaults\nexport function createHttpClient(transport: Transport): HttpClient {\n return new WebHttpClient(transport);\n}\n\n// Factory function for browser environments\nexport function createBrowserHttpClient(options: {\n baseUrl: string;\n getAuthToken?: () => Promise<string | undefined>;\n onTokenRefresh?: (newToken: string) => Promise<void>;\n /**\n * Callback to refresh the access token when a 401 error with 'token_expired' is detected.\n * Should return the new access token, or throw an error if refresh fails.\n * If provided, the client will automatically retry the request after a successful refresh.\n */\n refreshToken?: () => Promise<string>;\n defaultHeaders?: Record<string, string>;\n timeoutMs?: number;\n credentials?: RequestCredentials;\n defaultAbortSignal?: AbortSignal;\n}): HttpClient {\n const transport: Transport = {\n // Wrap fetch in arrow function to prevent \"Illegal invocation\" error\n // This preserves the correct 'this' context when fetch is called\n fetch: (url: RequestInfo | URL, init?: RequestInit) => globalThis.fetch(url, init),\n baseUrl: options.baseUrl,\n getAuthToken: options.getAuthToken,\n onTokenRefresh: options.onTokenRefresh,\n refreshToken: options.refreshToken,\n defaultHeaders: options.defaultHeaders,\n timeoutMs: options.timeoutMs,\n credentials: options.credentials, // No default credentials\n defaultAbortSignal: options.defaultAbortSignal,\n };\n\n return createHttpClient(transport);\n}\n\n// Factory function for Node.js environments\nexport function createNodeHttpClient(options: {\n baseUrl: string;\n fetch?: typeof fetch; // Allow injection of undici.fetch or other fetch implementations\n getAuthToken?: () => Promise<string | undefined>;\n onTokenRefresh?: (newToken: string) => Promise<void>;\n /**\n * Callback to refresh the access token when a 401 error with 'token_expired' is detected.\n * Should return the new access token, or throw an error if refresh fails.\n * If provided, the client will automatically retry the request after a successful refresh.\n */\n refreshToken?: () => Promise<string>;\n defaultHeaders?: Record<string, string>;\n timeoutMs?: number;\n credentials?: RequestCredentials;\n defaultAbortSignal?: AbortSignal;\n}): HttpClient {\n // Use provided fetch or try to use global fetch (Node 18+)\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n if (!fetchImpl) {\n throw new Error(\n 'No fetch implementation available. Please provide a fetch implementation ' +\n '(e.g., undici.fetch) or use Node.js 18+ which has native fetch support.',\n );\n }\n\n // Check if we're using the default globalThis.fetch to preserve context\n // When fetchImpl is globalThis.fetch, we must call it directly, not through a variable\n // Custom fetch implementations (like undici.fetch) can be called through the variable\n const isDefaultFetch = fetchImpl === globalThis.fetch;\n\n const transport: Transport = {\n // Wrap fetch in arrow function to prevent \"Illegal invocation\" error\n // For globalThis.fetch, call it directly to preserve 'this' context\n // For custom implementations, calling through the variable is safe\n fetch: isDefaultFetch\n ? (url: RequestInfo | URL, init?: RequestInit) => globalThis.fetch(url, init)\n : (url: RequestInfo | URL, init?: RequestInit) => fetchImpl(url, init),\n baseUrl: options.baseUrl,\n getAuthToken: options.getAuthToken,\n onTokenRefresh: options.onTokenRefresh,\n refreshToken: options.refreshToken,\n defaultHeaders: options.defaultHeaders,\n timeoutMs: options.timeoutMs,\n credentials: options.credentials, // Node.js doesn't have default credentials\n defaultAbortSignal: options.defaultAbortSignal,\n };\n\n return createHttpClient(transport);\n}\n\n// Universal factory that works in both environments\nexport function createUniversalHttpClient(options: {\n baseUrl: string;\n fetch?: typeof fetch;\n getAuthToken?: () => Promise<string | undefined>;\n onTokenRefresh?: (newToken: string) => Promise<void>;\n /**\n * Callback to refresh the access token when a 401 error with 'token_expired' is detected.\n * Should return the new access token, or throw an error if refresh fails.\n * If provided, the client will automatically retry the request after a successful refresh.\n */\n refreshToken?: () => Promise<string>;\n defaultHeaders?: Record<string, string>;\n timeoutMs?: number;\n credentials?: RequestCredentials;\n defaultAbortSignal?: AbortSignal;\n}): HttpClient {\n // Try to detect environment and use appropriate factory\n if (typeof window !== 'undefined') {\n // Browser environment\n return createBrowserHttpClient(options);\n } else {\n // Node.js environment\n return createNodeHttpClient(options);\n }\n}\n", "// Retry helper for HTTP requests\nexport interface RetryOptions {\n attempts?: number;\n}\n\n// Error types for retry logic\ninterface ErrorWithName extends Error {\n name: string;\n}\n\ninterface ErrorWithStatus extends Error {\n status: number;\n}\n\ninterface ErrorWithHeaders extends Error {\n headers?: Headers;\n}\n\n// Default retry condition - retry on network errors and 5xx status codes\nfunction defaultRetryCondition(error: Error, attempt: number): boolean {\n // Don't retry on the last attempt\n if (attempt <= 0) return false;\n\n // Distinguish timeout vs. user abort:\n // - Timeout: name === 'TimeoutError' (per spec/platforms)\n // - User abort: name === 'AbortError'\n const errorWithName = error as ErrorWithName;\n const name = errorWithName?.name;\n if (name === 'TimeoutError') return true;\n if (name === 'AbortError') return false;\n\n // HTTP 5xx and 429 (including HTTPError from web-client)\n const errorWithStatus = error as ErrorWithStatus;\n if (\n 'status' in errorWithStatus &&\n typeof errorWithStatus.status === 'number'\n ) {\n const status = errorWithStatus.status;\n return status >= 500 || status === 429;\n }\n // Network TypeError (DNS/reset) is reasonably retryable\n if (name === 'TypeError') return true;\n\n return false;\n}\n\n// Calculate delay with exponential backoff and jitter\nfunction calculateDelay(attempt: number): number {\n const baseDelayMs = 250; // Base 250ms as per spec\n const delay = baseDelayMs * Math.pow(2, attempt - 1);\n\n // Add \u00B120% jitter to reduce stampedes\n const jitter = (Math.random() - 0.5) * 0.4 * delay;\n return Math.max(0, delay + jitter);\n}\n\n// Retry helper function with new signature\nexport async function withRetry<T>(\n fn: (attempt: number) => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> {\n const { attempts = 3 } = options;\n\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= attempts; attempt++) {\n try {\n return await fn(attempt);\n } catch (error) {\n lastError = error as Error;\n\n // Check if we should retry (this handles the last attempt check)\n if (!defaultRetryCondition(lastError, attempts - attempt)) {\n throw lastError;\n }\n\n // Calculate delay\n let delayMs = calculateDelay(attempt);\n\n // Check for Retry-After header if it's an HTTP error\n const errorWithHeaders = lastError as ErrorWithHeaders;\n const hdrs = errorWithHeaders.headers;\n const retryAfter = hdrs?.get?.('Retry-After');\n if (retryAfter) {\n // If it's a number, treat as seconds\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n delayMs = Math.max(delayMs, seconds * 1000);\n } else {\n // If it's a date, calculate the difference\n const date = new Date(retryAfter);\n if (!isNaN(date.getTime())) {\n const waitTime = Math.max(0, date.getTime() - Date.now());\n // Cap wait at 60s per attempt as per spec\n delayMs = Math.max(delayMs, Math.min(waitTime, 60000));\n }\n }\n }\n\n // Wait before retrying\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n }\n\n throw lastError || new Error('Retry failed without error');\n}\n\n// Helper to create a retry-enabled HTTP client method\nexport function createRetryableMethod<T extends unknown[], R>(\n method: (...args: T) => Promise<R>,\n retryOptions: RetryOptions = {},\n) {\n return async (...args: T): Promise<R> => {\n return withRetry(() => method(...args), retryOptions);\n };\n}\n", "import { HttpClient } from '../http-client';\nimport {\n // Common types\n ApiResponse,\n // Health and Status\n HealthResponse,\n IdentityResponse,\n ProvidersResponse,\n // Authentication\n TokenRequest,\n TokenResponse,\n RefreshTokenRequest,\n ChallengeResponse,\n // Mock Token (testing)\n MockTokenRequest,\n // Token Management\n RevokeTokenRequest,\n RevokeTokenResponse,\n // Key Management\n CreateKeyRequest,\n CreateKeyResponse,\n DeleteKeyResponse,\n RootKeysResponse,\n // Client Management\n ClientKeysResponse,\n GenerateClientKeyRequest,\n DeleteClientResponse,\n // Permissions\n PermissionResponse,\n // Auth Status\n AuthStatus,\n} from './auth-types';\n\nexport class AuthApiClient {\n constructor(private httpClient: HttpClient) {}\n\n // Health and Status Endpoints\n async getHealth(): Promise<HealthResponse> {\n const response =\n await this.httpClient.get<ApiResponse<HealthResponse>>('/auth/health');\n if (!response.data) {\n throw new Error('Health response data is null');\n }\n return response.data;\n }\n\n async getIdentity(): Promise<IdentityResponse> {\n const response =\n await this.httpClient.get<ApiResponse<IdentityResponse>>(\n '/admin/identity',\n );\n if (!response.data) {\n throw new Error('Identity response data is null');\n }\n return response.data;\n }\n\n async getProviders(): Promise<ProvidersResponse> {\n const response =\n await this.httpClient.get<ApiResponse<ProvidersResponse>>(\n '/auth/providers',\n );\n if (!response.data) {\n throw new Error('Providers response data is null');\n }\n return response.data;\n }\n\n // Authentication Endpoints\n async getLoginPage(): Promise<string> {\n return this.httpClient.get<string>('/auth/login', { parse: 'text' });\n }\n\n async generateTokens(request: TokenRequest): Promise<TokenResponse> {\n return this.httpClient.post<TokenResponse>('/auth/token', request);\n }\n\n async refreshToken(request: RefreshTokenRequest): Promise<TokenResponse> {\n return this.httpClient.post<TokenResponse>('/auth/refresh', request);\n }\n\n async generateMockTokens(request: MockTokenRequest): Promise<TokenResponse> {\n return this.httpClient.post<TokenResponse>('/auth/mock-token', request);\n }\n\n async getChallenge(): Promise<ChallengeResponse> {\n return this.httpClient.get<ChallengeResponse>('/auth/challenge');\n }\n\n async validateToken(token: string): Promise<{\n valid: boolean;\n headers: Record<string, string>;\n status: number;\n }> {\n try {\n const response = await this.validateTokenGet(token);\n return {\n valid: response.status === 200,\n headers: response.headers,\n status: response.status,\n };\n } catch (error) {\n return {\n valid: false,\n headers: {},\n status: 401,\n };\n }\n }\n\n async validateTokenGet(\n token: string,\n ): Promise<{ status: number; headers: Record<string, string> }> {\n const response = await this.httpClient.head('/auth/validate', {\n headers: { Authorization: `Bearer ${token}` },\n });\n return {\n status: response.status,\n headers: response.headers,\n };\n }\n\n async isAuthed(): Promise<AuthStatus> {\n return this.httpClient.get<AuthStatus>('/auth/is-authed');\n }\n\n // Token Management Endpoints\n async revokeTokens(\n request: RevokeTokenRequest,\n ): Promise<RevokeTokenResponse> {\n return this.httpClient.post<RevokeTokenResponse>('/admin/revoke', request);\n }\n\n // Key Management Endpoints\n async listRootKeys(): Promise<RootKeysResponse> {\n const response =\n await this.httpClient.get<ApiResponse<RootKeysResponse>>('/admin/keys');\n if (!response.data) {\n throw new Error('Root keys response data is null');\n }\n return response.data;\n }\n\n async createRootKey(request: CreateKeyRequest): Promise<CreateKeyResponse> {\n return this.httpClient.post<CreateKeyResponse>('/admin/keys', request);\n }\n\n async deleteRootKey(keyId: string): Promise<DeleteKeyResponse> {\n return this.httpClient.delete<DeleteKeyResponse>(`/admin/keys/${keyId}`);\n }\n\n // Client Management Endpoints\n async listClientKeys(): Promise<ClientKeysResponse> {\n const response = await this.httpClient.get<ApiResponse<ClientKeysResponse>>(\n '/admin/keys/clients',\n );\n if (!response.data) {\n throw new Error('Client keys response data is null');\n }\n return response.data;\n }\n\n async generateClientKey(\n request: GenerateClientKeyRequest,\n ): Promise<TokenResponse> {\n return this.httpClient.post<TokenResponse>('/admin/client-key', request);\n }\n\n async deleteClientKey(\n keyId: string,\n clientId: string,\n ): Promise<DeleteClientResponse> {\n return this.httpClient.delete<DeleteClientResponse>(\n `/admin/keys/${keyId}/clients/${clientId}`,\n );\n }\n\n // Permission Management Endpoints\n async getKeyPermissions(keyId: string): Promise<PermissionResponse> {\n return this.httpClient.get<PermissionResponse>(\n `/admin/keys/${keyId}/permissions`,\n );\n }\n\n async updateKeyPermissions(\n keyId: string,\n permissions: string[],\n ): Promise<PermissionResponse> {\n return this.httpClient.put<PermissionResponse>(\n `/admin/keys/${keyId}/permissions`,\n { permissions },\n );\n }\n}\n", "import { AuthApiClient } from './auth-client';\nimport { AuthApiClientConfig } from './auth-types';\nimport { HttpClient } from '../http-client';\n\n// Mock HTTP client for testing\nclass MockHttpClient implements HttpClient {\n async get<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async post<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async put<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async delete<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async patch<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async head(): Promise<{ headers: Record<string, string>; status: number }> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async request<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n}\n\n// Factory functions for creating Auth API clients\nexport function createBrowserAuthApiClient(\n _config: AuthApiClientConfig,\n): AuthApiClient {\n const httpClient = new MockHttpClient();\n return new AuthApiClient(httpClient);\n}\n\nexport function createNodeAuthApiClient(\n _config: AuthApiClientConfig,\n): AuthApiClient {\n const httpClient = new MockHttpClient();\n return new AuthApiClient(httpClient);\n}\n\nexport function createAuthApiClient(\n _config: AuthApiClientConfig,\n): AuthApiClient {\n const httpClient = new MockHttpClient();\n return new AuthApiClient(httpClient);\n}\n\nexport function createAuthApiClientFromHttpClient(\n httpClient: HttpClient,\n _config: AuthApiClientConfig,\n): AuthApiClient {\n return new AuthApiClient(httpClient);\n}\n", "import { HttpClient } from '../http-client';\nimport type {\n HealthStatus,\n AdminAuthStatus,\n InstallApplicationRequest,\n InstallApplicationResponseData,\n InstallDevApplicationRequest,\n UninstallApplicationResponseData,\n ListApplicationsResponseData,\n GetApplicationResponseData,\n GetLatestVersionResponseData,\n ListPackagesResponseData,\n ListVersionsResponseData,\n RegistryBundleManifest,\n CreateContextRequest,\n CreateContextResponseData,\n DeleteContextRequest,\n DeleteContextResponseData,\n GetContextsResponseData,\n Context,\n GenerateContextIdentityResponseData,\n GetContextIdentitiesResponseData,\n JoinContextResponseData,\n JoinSubgroupInheritanceResponseData,\n ContextGroupResponseData,\n ContextStorageResponseData,\n InviteSpecializedNodeRequest,\n InviteSpecializedNodeResponseData,\n UpdateContextApplicationRequest,\n ContextsWithExecutorsResponseData,\n UploadBlobRequest,\n UploadBlobResponseData,\n DeleteBlobResponseData,\n ListBlobsResponseData,\n GetBlobResponseData,\n CreateAliasRequest,\n CreateAliasResponseData,\n LookupAliasResponseData,\n DeleteAliasResponseData,\n ListAliasesResponseData,\n ListContextIdentityAliasesResponseData,\n CreateContextIdentityAliasResponseData,\n LookupContextIdentityAliasResponseData,\n DeleteContextIdentityAliasResponseData,\n ListNamespacesResponseData,\n CreateNamespaceRequest,\n CreateNamespaceResponseData,\n DeleteNamespaceRequest,\n DeleteNamespaceResponseData,\n CreateNamespaceInvitationRequest,\n CreateNamespaceInvitationResponseData,\n CreateRecursiveInvitationResponseData,\n JoinNamespaceRequest,\n JoinNamespaceResponseData,\n CreateGroupInNamespaceRequest,\n CreateGroupInNamespaceResponseData,\n SubgroupEntry,\n Namespace,\n NamespaceIdentity,\n GroupInfoResponseData,\n DeleteGroupRequest,\n DeleteGroupResponseData,\n ListGroupMembersResponseData,\n ListGroupContextsResponseData,\n AddGroupMembersRequest,\n RemoveGroupMembersRequest,\n UpdateMemberRoleRequest,\n MemberCapabilities,\n SetMemberCapabilitiesRequest,\n SetDefaultCapabilitiesRequest,\n SetSubgroupVisibilityRequest,\n SetTeeAdmissionPolicyRequest,\n UpdateGroupSettingsRequest,\n SetGroupMetadataRequest,\n SetMemberMetadataRequest,\n SetContextMetadataRequest,\n MetadataRecord,\n GetMetadataResponseData,\n SyncGroupRequest,\n SyncGroupResponseData,\n RegisterGroupSigningKeyRequest,\n RegisterGroupSigningKeyResponseData,\n UpgradeGroupRequest,\n UpgradeGroupResponseData,\n GroupUpgradeStatusResponseData,\n MigrationStatus,\n CascadeStatusEntry,\n RetryGroupUpgradeRequest,\n RetryGroupUpgradeResponseData,\n NestGroupRequest,\n UnnestGroupRequest,\n DetachContextFromGroupRequest,\n CreateGroupInvitationRequest,\n CreateGroupInvitationResponseData,\n CreateRecursiveGroupInvitationResponseData,\n JoinGroupRequest,\n JoinGroupResponseData,\n TeeInfoResponseData,\n TeeAttestRequest,\n TeeAttestResponseData,\n TeeVerifyQuoteRequest,\n TeeVerifyQuoteResponseData,\n} from './admin-types';\n\n/**\n * Helper: server wraps most responses in `{ data: T }`.\n * This extracts `.data` so callers get the inner payload directly.\n */\nfunction unwrap<T>(response: { data: T }): T {\n return response.data;\n}\n\n/**\n * Compare two dotted version strings, ascending: negative if `a < b`, positive\n * if `a > b`, `0` if equal. Components are compared numerically when both parse\n * as integers (so `1.10.0 > 1.9.0`), else lexically; a missing component is `0`.\n * Minimal by design \u2014 sufficient for the `major.minor.patch` registry versions.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.');\n const pb = b.split('.');\n const n = Math.max(pa.length, pb.length);\n for (let i = 0; i < n; i++) {\n const sa = pa[i] ?? '0';\n const sb = pb[i] ?? '0';\n const na = Number.parseInt(sa, 10);\n const nb = Number.parseInt(sb, 10);\n if (Number.isNaN(na) || Number.isNaN(nb)) {\n const c = sa.localeCompare(sb);\n if (c !== 0) return c;\n } else if (na !== nb) {\n return na - nb;\n }\n }\n return 0;\n}\n\nexport class AdminApiClient {\n constructor(private httpClient: HttpClient) {}\n\n // ---- Health and Status (public, no auth) ----\n\n async healthCheck(): Promise<HealthStatus> {\n return unwrap(await this.httpClient.get<{ data: HealthStatus }>('/admin-api/health'));\n }\n\n async isAuthed(): Promise<AdminAuthStatus> {\n return this.httpClient.get<AdminAuthStatus>('/admin-api/is-authed');\n }\n\n // ---- Application Management ----\n\n async installApplication(request: InstallApplicationRequest): Promise<InstallApplicationResponseData> {\n return unwrap(await this.httpClient.post<{ data: InstallApplicationResponseData }>('/admin-api/install-application', request));\n }\n\n /**\n * Resolve a `package@version` to its registry artifact URL and install it.\n * Node install is URL-based (no node-side package+version resolution), so this\n * fetches the bundle manifest from the registry, derives the `.mpk` artifact\n * URL, then calls {@link installApplication}. `registryUrl` is the registry\n * origin. This is the discrete \"download\" step an Updates flow pairs with a\n * subsequent `upgradeGroup`.\n */\n async installFromRegistry(\n registryUrl: string,\n packageName: string,\n version: string,\n ): Promise<InstallApplicationResponseData> {\n const base = new URL(registryUrl).origin;\n const manifestUrl = new URL(\n `/api/v2/bundles/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}`,\n base,\n ).toString();\n const resp = await fetch(manifestUrl);\n if (!resp.ok) {\n throw new Error(\n `registry manifest fetch failed (${resp.status}) for ${packageName}@${version}`,\n );\n }\n const bundle = (await resp.json()) as RegistryBundleManifest;\n // Encode the path segments \u2014 the package/version come from a (best-effort\n // trusted) registry response, so guard against odd characters breaking or\n // traversing the artifact path. For normal ids/semvers this is a no-op.\n const pkg = encodeURIComponent(bundle.package);\n const ver = encodeURIComponent(bundle.appVersion);\n const artifactUrl = `${base}/artifacts/${pkg}/${ver}/${pkg}-${ver}.mpk`;\n return this.installApplication({\n url: artifactUrl,\n package: bundle.package,\n version: bundle.appVersion,\n metadata: [],\n });\n }\n\n /**\n * List a package's published versions from the registry, newest-first by\n * semver. Reads the registry's V2 bundle listing\n * (`GET {registry}/api/v2/bundles?package={package}`), taking each bundle's\n * `appVersion`. Registry-side data \u2014 distinct from the node's\n * installed-version list \u2014 and the source an Updates view compares against\n * the running `Context.applicationVersion` to detect \"a new version exists\".\n */\n async getRegistryVersions(registryUrl: string, packageName: string): Promise<string[]> {\n const url = new URL('/api/v2/bundles', new URL(registryUrl).origin);\n url.searchParams.set('package', packageName);\n const resp = await fetch(url.toString());\n if (!resp.ok) {\n throw new Error(\n `registry versions fetch failed (${resp.status}) for ${packageName}`,\n );\n }\n const bundles = (await resp.json()) as RegistryBundleManifest[];\n return (Array.isArray(bundles) ? bundles : [])\n .map((b) => b.appVersion)\n .filter((v): v is string => typeof v === 'string')\n .sort((a, b) => compareSemver(b, a));\n }\n\n async installDevApplication(request: InstallDevApplicationRequest): Promise<InstallApplicationResponseData> {\n return unwrap(await this.httpClient.post<{ data: InstallApplicationResponseData }>('/admin-api/install-dev-application', request));\n }\n\n async uninstallApplication(appId: string): Promise<UninstallApplicationResponseData> {\n return unwrap(await this.httpClient.delete<{ data: UninstallApplicationResponseData }>(`/admin-api/applications/${appId}`));\n }\n\n async listApplications(): Promise<ListApplicationsResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListApplicationsResponseData }>('/admin-api/applications'));\n }\n\n async getApplication(appId: string): Promise<GetApplicationResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetApplicationResponseData }>(`/admin-api/applications/${appId}`));\n }\n\n // ---- Package Management ----\n\n async listPackages(): Promise<ListPackagesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListPackagesResponseData }>('/admin-api/packages'));\n }\n\n async listPackageVersions(packageName: string): Promise<ListVersionsResponseData> {\n return unwrap(\n await this.httpClient.get<{ data: ListVersionsResponseData }>(\n `/admin-api/packages/${encodeURIComponent(packageName)}/versions`,\n ),\n );\n }\n\n async getLatestPackageVersion(packageName: string): Promise<GetLatestVersionResponseData> {\n return this.httpClient.get<GetLatestVersionResponseData>(\n `/admin-api/packages/${encodeURIComponent(packageName)}/latest`,\n );\n }\n\n // ---- Context Management ----\n\n async createContext(request: CreateContextRequest): Promise<CreateContextResponseData> {\n return unwrap(await this.httpClient.post<{ data: CreateContextResponseData }>('/admin-api/contexts', request));\n }\n\n async deleteContext(contextId: string, request?: DeleteContextRequest): Promise<DeleteContextResponseData> {\n if (request) {\n return unwrap(\n await this.httpClient.request<{ data: DeleteContextResponseData }>(`/admin-api/contexts/${contextId}`, {\n method: 'DELETE',\n body: JSON.stringify(request),\n headers: { 'Content-Type': 'application/json' },\n }),\n );\n }\n return unwrap(await this.httpClient.delete<{ data: DeleteContextResponseData }>(`/admin-api/contexts/${contextId}`));\n }\n\n async getContexts(): Promise<GetContextsResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetContextsResponseData }>('/admin-api/contexts'));\n }\n\n async getContext(contextId: string): Promise<Context> {\n return unwrap(await this.httpClient.get<{ data: Context }>(`/admin-api/contexts/${contextId}`));\n }\n\n async getContextsForApplication(applicationId: string): Promise<GetContextsResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetContextsResponseData }>(`/admin-api/contexts/for-application/${applicationId}`));\n }\n\n // ---- Context Identity ----\n\n async generateContextIdentity(): Promise<GenerateContextIdentityResponseData> {\n return unwrap(await this.httpClient.post<{ data: GenerateContextIdentityResponseData }>('/admin-api/identity/context', {}));\n }\n\n async getContextIdentities(contextId: string): Promise<GetContextIdentitiesResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetContextIdentitiesResponseData }>(`/admin-api/contexts/${contextId}/identities`));\n }\n\n async getContextIdentitiesOwned(contextId: string): Promise<GetContextIdentitiesResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetContextIdentitiesResponseData }>(`/admin-api/contexts/${contextId}/identities-owned`));\n }\n\n // ---- Context join (group membership) ----\n\n async joinContext(contextId: string): Promise<JoinContextResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: JoinContextResponseData }>(`/admin-api/contexts/${contextId}/join`, {}),\n );\n }\n\n // ---- Context group / storage / sync ----\n\n async getContextGroup(contextId: string): Promise<ContextGroupResponseData> {\n return unwrap(await this.httpClient.get<{ data: ContextGroupResponseData }>(`/admin-api/contexts/${contextId}/group`));\n }\n\n async getContextStorage(contextId: string): Promise<ContextStorageResponseData> {\n return unwrap(await this.httpClient.get<{ data: ContextStorageResponseData }>(`/admin-api/contexts/${contextId}/storage`));\n }\n\n async syncContext(contextId?: string): Promise<void> {\n await this.httpClient.post(`/admin-api/contexts/sync/${contextId ?? ''}`, {});\n }\n\n async inviteSpecializedNode(request: InviteSpecializedNodeRequest): Promise<InviteSpecializedNodeResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: InviteSpecializedNodeResponseData }>(\n '/admin-api/contexts/invite-specialized-node',\n request,\n ),\n );\n }\n\n async updateContextApplication(\n contextId: string,\n request: UpdateContextApplicationRequest,\n ): Promise<void> {\n await this.httpClient.post(`/admin-api/contexts/${contextId}/application`, request);\n }\n\n async getContextsWithExecutorsForApplication(applicationId: string): Promise<ContextsWithExecutorsResponseData> {\n return unwrap(\n await this.httpClient.get<{ data: ContextsWithExecutorsResponseData }>(\n `/admin-api/contexts/with-executors/for-application/${applicationId}`,\n ),\n );\n }\n\n // ---- Blob Management ----\n\n async uploadBlob(data: UploadBlobRequest): Promise<UploadBlobResponseData> {\n return unwrap(await this.httpClient.put<{ data: UploadBlobResponseData }>('/admin-api/blobs', data));\n }\n\n async deleteBlob(blobId: string): Promise<DeleteBlobResponseData> {\n return unwrap(await this.httpClient.delete<{ data: DeleteBlobResponseData }>(`/admin-api/blobs/${blobId}`));\n }\n\n async listBlobs(): Promise<ListBlobsResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListBlobsResponseData }>('/admin-api/blobs'));\n }\n\n async getBlob(blobId: string): Promise<GetBlobResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetBlobResponseData }>(`/admin-api/blobs/${blobId}`));\n }\n\n // ---- Alias Management ----\n\n async createContextAlias(request: CreateAliasRequest): Promise<CreateAliasResponseData> {\n return unwrap(await this.httpClient.post<{ data: CreateAliasResponseData }>('/admin-api/alias/create/context', request));\n }\n\n async createApplicationAlias(request: CreateAliasRequest): Promise<CreateAliasResponseData> {\n return unwrap(await this.httpClient.post<{ data: CreateAliasResponseData }>('/admin-api/alias/create/application', request));\n }\n\n async lookupContextAlias(name: string): Promise<LookupAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: LookupAliasResponseData }>(\n `/admin-api/alias/lookup/context/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async lookupApplicationAlias(name: string): Promise<LookupAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: LookupAliasResponseData }>(\n `/admin-api/alias/lookup/application/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async deleteContextAlias(name: string): Promise<DeleteAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: DeleteAliasResponseData }>(\n `/admin-api/alias/delete/context/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async deleteApplicationAlias(name: string): Promise<DeleteAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: DeleteAliasResponseData }>(\n `/admin-api/alias/delete/application/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async listContextAliases(): Promise<ListAliasesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListAliasesResponseData }>('/admin-api/alias/list/context'));\n }\n\n async listApplicationAliases(): Promise<ListAliasesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListAliasesResponseData }>('/admin-api/alias/list/application'));\n }\n\n // ---- Context Identity Aliases ----\n\n async listContextIdentityAliases(contextId: string): Promise<ListContextIdentityAliasesResponseData> {\n return unwrap(\n await this.httpClient.get<{ data: ListContextIdentityAliasesResponseData }>(\n `/admin-api/alias/list/identity/${contextId}`,\n ),\n );\n }\n\n async createContextIdentityAlias(\n contextId: string,\n request: CreateAliasRequest,\n ): Promise<CreateContextIdentityAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: CreateContextIdentityAliasResponseData }>(\n `/admin-api/alias/create/identity/${contextId}`,\n request,\n ),\n );\n }\n\n async lookupContextIdentityAlias(\n contextId: string,\n name: string,\n ): Promise<LookupContextIdentityAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: LookupContextIdentityAliasResponseData }>(\n `/admin-api/alias/lookup/identity/${contextId}/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async deleteContextIdentityAlias(\n contextId: string,\n name: string,\n ): Promise<DeleteContextIdentityAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: DeleteContextIdentityAliasResponseData }>(\n `/admin-api/alias/delete/identity/${contextId}/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n // ---- Namespace Management ----\n\n async listNamespaces(): Promise<ListNamespacesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListNamespacesResponseData }>('/admin-api/namespaces'));\n }\n\n async getNamespace(namespaceId: string): Promise<Namespace> {\n return unwrap(await this.httpClient.get<{ data: Namespace }>(`/admin-api/namespaces/${namespaceId}`));\n }\n\n async getNamespaceIdentity(namespaceId: string): Promise<NamespaceIdentity> {\n return unwrap(await this.httpClient.get<{ data: NamespaceIdentity }>(`/admin-api/namespaces/${namespaceId}/identity`));\n }\n\n async listNamespacesForApplication(applicationId: string): Promise<ListNamespacesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListNamespacesResponseData }>(`/admin-api/namespaces/for-application/${applicationId}`));\n }\n\n async createNamespace(request: CreateNamespaceRequest): Promise<CreateNamespaceResponseData> {\n return unwrap(await this.httpClient.post<{ data: CreateNamespaceResponseData }>('/admin-api/namespaces', request));\n }\n\n async deleteNamespace(\n namespaceId: string,\n request?: DeleteNamespaceRequest,\n ): Promise<DeleteNamespaceResponseData> {\n return unwrap(\n await this.httpClient.request<{ data: DeleteNamespaceResponseData }>(`/admin-api/namespaces/${namespaceId}`, {\n method: 'DELETE',\n body: request ? JSON.stringify(request) : undefined,\n headers: request ? { 'Content-Type': 'application/json' } : undefined,\n }),\n );\n }\n\n async createNamespaceInvitation(\n namespaceId: string,\n request?: CreateNamespaceInvitationRequest,\n ): Promise<CreateNamespaceInvitationResponseData | CreateRecursiveInvitationResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: CreateNamespaceInvitationResponseData | CreateRecursiveInvitationResponseData }>(\n `/admin-api/namespaces/${namespaceId}/invite`,\n request ?? {},\n ),\n );\n }\n\n async joinNamespace(\n namespaceId: string,\n request: JoinNamespaceRequest,\n ): Promise<JoinNamespaceResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: JoinNamespaceResponseData }>(\n `/admin-api/namespaces/${namespaceId}/join`,\n request,\n { timeoutMs: 65000 },\n ),\n );\n }\n\n async createGroupInNamespace(\n namespaceId: string,\n request?: CreateGroupInNamespaceRequest,\n ): Promise<CreateGroupInNamespaceResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: CreateGroupInNamespaceResponseData }>(\n `/admin-api/namespaces/${namespaceId}/groups`,\n request ?? {},\n ),\n );\n }\n\n async listNamespaceGroups(namespaceId: string): Promise<SubgroupEntry[]> {\n return unwrap(await this.httpClient.get<{ data: SubgroupEntry[] }>(`/admin-api/namespaces/${namespaceId}/groups`));\n }\n\n // ---- Group Management ----\n\n async getGroupInfo(groupId: string): Promise<GroupInfoResponseData> {\n return unwrap(await this.httpClient.get<{ data: GroupInfoResponseData }>(`/admin-api/groups/${groupId}`));\n }\n\n /** Thin wrapper over {@link getGroupInfo}: returns the group's `defaultCapabilities` bitmask. */\n async getDefaultCapabilities(groupId: string): Promise<number> {\n return (await this.getGroupInfo(groupId)).defaultCapabilities;\n }\n\n /** Thin wrapper over {@link getGroupInfo}: returns the group's `subgroupVisibility`. */\n async getSubgroupVisibility(groupId: string): Promise<string> {\n return (await this.getGroupInfo(groupId)).subgroupVisibility;\n }\n\n async deleteGroup(groupId: string, request?: DeleteGroupRequest): Promise<DeleteGroupResponseData> {\n if (request) {\n return unwrap(\n await this.httpClient.request<{ data: DeleteGroupResponseData }>(`/admin-api/groups/${groupId}`, {\n method: 'DELETE',\n body: JSON.stringify(request),\n headers: { 'Content-Type': 'application/json' },\n }),\n );\n }\n return unwrap(await this.httpClient.delete<{ data: DeleteGroupResponseData }>(`/admin-api/groups/${groupId}`));\n }\n\n async listGroupMembers(groupId: string): Promise<ListGroupMembersResponseData> {\n const response = await this.httpClient.get<ListGroupMembersResponseData>(\n `/admin-api/groups/${groupId}/members`,\n );\n // Validate the field we declare as non-optional in the type so a\n // contract-violating response (proxy error body, future API drift,\n // etc.) surfaces as a clear error rather than silently producing an\n // empty list. Empty groups still satisfy this \u2014 merod returns\n // `members: []`, not an omitted field.\n if (!Array.isArray(response?.members)) {\n // Sanitize before interpolation: groupId reaches us from caller code,\n // not parsed input, but defending the message keeps untrusted bytes\n // out of error logs and downstream UIs.\n const safeId = String(groupId).replace(/[\\r\\n\\t\\s]/g, '').slice(0, 64);\n throw new Error(\n `Invalid listGroupMembers response for group ${safeId}: missing or non-array \\`members\\` field`,\n );\n }\n return response;\n }\n\n async listGroupContexts(groupId: string): Promise<ListGroupContextsResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListGroupContextsResponseData }>(`/admin-api/groups/${groupId}/contexts`));\n }\n\n async addGroupMembers(groupId: string, request: AddGroupMembersRequest): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${groupId}/members`, request);\n }\n\n async removeGroupMembers(groupId: string, request: RemoveGroupMembersRequest): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${groupId}/members/remove`, request);\n }\n\n async updateMemberRole(\n groupId: string,\n identity: string,\n request: UpdateMemberRoleRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/role`, request);\n }\n\n async getMemberCapabilities(groupId: string, identity: string): Promise<MemberCapabilities> {\n return unwrap(\n await this.httpClient.get<{ data: MemberCapabilities }>(\n `/admin-api/groups/${groupId}/members/${identity}/capabilities`,\n ),\n );\n }\n\n async setMemberCapabilities(\n groupId: string,\n identity: string,\n request: SetMemberCapabilitiesRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/capabilities`, request);\n }\n\n async setDefaultCapabilities(\n groupId: string,\n request: SetDefaultCapabilitiesRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/settings/default-capabilities`, request);\n }\n\n async setSubgroupVisibility(\n groupId: string,\n request: SetSubgroupVisibilityRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/settings/subgroup-visibility`, request);\n }\n\n async setTeeAdmissionPolicy(\n groupId: string,\n request: SetTeeAdmissionPolicyRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/settings/tee-admission-policy`, request);\n }\n\n async updateGroupSettings(\n groupId: string,\n request: UpdateGroupSettingsRequest,\n ): Promise<void> {\n await this.httpClient.patch(`/admin-api/groups/${groupId}`, request);\n }\n\n // ---- Group / member / context metadata ----\n\n async setGroupMetadata(groupId: string, request: SetGroupMetadataRequest): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/metadata`, request);\n }\n\n async getGroupMetadata(groupId: string): Promise<MetadataRecord | null> {\n return unwrap(await this.httpClient.get<{ data: GetMetadataResponseData }>(`/admin-api/groups/${groupId}/metadata`)).data;\n }\n\n async setMemberMetadata(\n groupId: string,\n identity: string,\n request: SetMemberMetadataRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/metadata`, request);\n }\n\n async getMemberMetadata(groupId: string, identity: string): Promise<MetadataRecord | null> {\n return unwrap(\n await this.httpClient.get<{ data: GetMetadataResponseData }>(`/admin-api/groups/${groupId}/members/${identity}/metadata`),\n ).data;\n }\n\n async setContextMetadata(\n groupId: string,\n contextId: string,\n request: SetContextMetadataRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`, request);\n }\n\n async getContextMetadata(groupId: string, contextId: string): Promise<MetadataRecord | null> {\n return unwrap(\n await this.httpClient.get<{ data: GetMetadataResponseData }>(`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`),\n ).data;\n }\n\n async syncGroup(groupId: string, request?: SyncGroupRequest): Promise<SyncGroupResponseData> {\n return unwrap(await this.httpClient.post<{ data: SyncGroupResponseData }>(`/admin-api/groups/${groupId}/sync`, request ?? {}));\n }\n\n async registerGroupSigningKey(\n groupId: string,\n request: RegisterGroupSigningKeyRequest,\n ): Promise<RegisterGroupSigningKeyResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: RegisterGroupSigningKeyResponseData }>(\n `/admin-api/groups/${groupId}/signing-key`,\n request,\n ),\n );\n }\n\n async upgradeGroup(groupId: string, request: UpgradeGroupRequest): Promise<UpgradeGroupResponseData> {\n return unwrap(await this.httpClient.post<{ data: UpgradeGroupResponseData }>(`/admin-api/groups/${groupId}/upgrade`, request));\n }\n\n async getGroupUpgradeStatus(groupId: string): Promise<GroupUpgradeStatusResponseData> {\n return unwrap(\n await this.httpClient.get<{ data: GroupUpgradeStatusResponseData }>(`/admin-api/groups/${groupId}/upgrade/status`),\n );\n }\n\n /**\n * The operator-facing \"have all peers migrated?\" rollup for a namespace.\n * The handler serializes the payload directly, so there is no `{ data }`\n * envelope to unwrap here (unlike most admin reads).\n */\n async getMigrationStatus(namespaceId: string): Promise<MigrationStatus> {\n const id = encodeURIComponent(namespaceId);\n return this.httpClient.get<MigrationStatus>(`/admin-api/groups/${id}/migration-status`);\n }\n\n /** Per-group cascade-migration snapshots for a namespace. */\n async getCascadeStatus(namespaceId: string): Promise<CascadeStatusEntry[]> {\n const id = encodeURIComponent(namespaceId);\n return unwrap(\n await this.httpClient.get<{ data: CascadeStatusEntry[] }>(`/admin-api/groups/${id}/cascade-status`),\n );\n }\n\n async retryGroupUpgrade(\n groupId: string,\n request?: RetryGroupUpgradeRequest,\n ): Promise<RetryGroupUpgradeResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: RetryGroupUpgradeResponseData }>(\n `/admin-api/groups/${groupId}/upgrade/retry`,\n request ?? {},\n ),\n );\n }\n\n async nestGroup(parentGroupId: string, request: NestGroupRequest): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${parentGroupId}/nest`, request);\n }\n\n async unnestGroup(parentGroupId: string, request: UnnestGroupRequest): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${parentGroupId}/unnest`, request);\n }\n\n async listSubgroups(groupId: string): Promise<SubgroupEntry[]> {\n const response = await this.httpClient.get<{ subgroups?: SubgroupEntry[]; data?: SubgroupEntry[] }>(\n `/admin-api/groups/${groupId}/subgroups`,\n );\n return response.subgroups ?? response.data ?? [];\n }\n\n async detachContextFromGroup(\n groupId: string,\n contextId: string,\n request?: DetachContextFromGroupRequest,\n ): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${groupId}/contexts/${contextId}/remove`, request ?? {});\n }\n\n // ---- Group Invitation & Join ----\n\n async createGroupInvitation(\n groupId: string,\n request?: CreateGroupInvitationRequest,\n ): Promise<CreateGroupInvitationResponseData | CreateRecursiveGroupInvitationResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: CreateGroupInvitationResponseData | CreateRecursiveGroupInvitationResponseData }>(\n `/admin-api/groups/${groupId}/invite`,\n request ?? {},\n ),\n );\n }\n\n async joinGroup(request: JoinGroupRequest): Promise<JoinGroupResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: JoinGroupResponseData }>('/admin-api/groups/join', request),\n );\n }\n\n async joinSubgroupInheritance(groupId: string): Promise<JoinSubgroupInheritanceResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: JoinSubgroupInheritanceResponseData }>(\n `/admin-api/groups/${groupId}/join-via-inheritance`,\n {},\n ),\n );\n }\n\n // ---- TEE ----\n\n async getTeeInfo(): Promise<TeeInfoResponseData> {\n return unwrap(await this.httpClient.get<{ data: TeeInfoResponseData }>('/admin-api/tee/info'));\n }\n\n async teeAttest(request: TeeAttestRequest): Promise<TeeAttestResponseData> {\n return unwrap(await this.httpClient.post<{ data: TeeAttestResponseData }>('/admin-api/tee/attest', request));\n }\n\n async teeVerifyQuote(request: TeeVerifyQuoteRequest): Promise<TeeVerifyQuoteResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: TeeVerifyQuoteResponseData }>('/admin-api/tee/verify-quote', request),\n );\n }\n\n // ---- Network ----\n\n async getPeersCount(): Promise<{ count: number }> {\n return this.httpClient.get<{ count: number }>('/admin-api/peers');\n }\n}\n", "import { AdminApiClient } from './admin-client';\nimport { AdminApiClientConfig } from './admin-types';\nimport { HttpClient } from '../http-client';\n\n// Mock HTTP client for testing\nclass MockHttpClient implements HttpClient {\n async get<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async post<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async put<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async delete<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async patch<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async head(): Promise<{ headers: Record<string, string>; status: number }> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async request<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n}\n\n// Factory functions for creating Admin API clients\nexport function createBrowserAdminApiClient(\n _config: AdminApiClientConfig,\n): AdminApiClient {\n const httpClient = new MockHttpClient();\n return new AdminApiClient(httpClient);\n}\n\nexport function createNodeAdminApiClient(\n _config: AdminApiClientConfig,\n): AdminApiClient {\n const httpClient = new MockHttpClient();\n return new AdminApiClient(httpClient);\n}\n\nexport function createAdminApiClient(\n _config: AdminApiClientConfig,\n): AdminApiClient {\n const httpClient = new MockHttpClient();\n return new AdminApiClient(httpClient);\n}\n\nexport function createAdminApiClientFromHttpClient(\n httpClient: HttpClient,\n _config: AdminApiClientConfig,\n): AdminApiClient {\n return new AdminApiClient(httpClient);\n}\n", "export interface AuthCallbackResult {\n accessToken: string;\n refreshToken: string;\n applicationId: string;\n contextId: string;\n contextIdentity: string;\n nodeUrl: string;\n}\n\nexport interface AuthLoginOptions {\n callbackUrl: string;\n packageName?: string;\n mode: string;\n permissions?: string[];\n registryUrl?: string;\n packageVersion?: string;\n}\n\n/**\n * Parse an auth callback URL hash fragment.\n * Returns null if access_token is missing.\n */\nexport function parseAuthCallback(url: string): AuthCallbackResult | null {\n try {\n const hashIndex = url.indexOf('#');\n if (hashIndex === -1) return null;\n\n const hash = url.substring(hashIndex + 1);\n const params = new URLSearchParams(hash);\n\n const accessToken = params.get('access_token');\n if (!accessToken) return null;\n\n return {\n accessToken,\n refreshToken: params.get('refresh_token') ?? '',\n applicationId: params.get('application_id') ?? '',\n contextId: params.get('context_id') ?? '',\n contextIdentity: params.get('context_identity') ?? '',\n nodeUrl: params.get('node_url') ?? '',\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Build the auth login URL for redirecting users to the node's auth page.\n */\nexport function buildAuthLoginUrl(nodeUrl: string, opts: AuthLoginOptions): string {\n const params = new URLSearchParams();\n params.set('callback-url', opts.callbackUrl);\n\n if (opts.permissions && opts.permissions.length > 0) {\n params.set('permissions', opts.permissions.join(','));\n }\n\n params.set('mode', opts.mode);\n\n if (opts.packageName) {\n params.set('package-name', opts.packageName);\n if (opts.packageVersion) {\n params.set('package-version', opts.packageVersion);\n }\n if (opts.registryUrl) {\n params.set('registry-url', opts.registryUrl);\n }\n }\n\n // Trim trailing slash from nodeUrl\n const base = nodeUrl.replace(/\\/+$/, '');\n return `${base}/auth/login?${params.toString()}`;\n}\n", "import type { HttpClient } from '../http-client';\n\n/** Result of the owner-driven `migrate_my_entries` convert (counts are u32). */\nexport interface MigrateMyEntriesSummary {\n converted: number;\n remaining: number;\n}\n\nexport interface ExecuteParams {\n contextId: string;\n method: string;\n argsJson?: Record<string, unknown>;\n /** @deprecated No longer used by the server. Ignored if provided. */\n executorPublicKey?: string;\n}\n\nexport class RpcError extends Error {\n code: number;\n type?: string;\n data?: unknown;\n\n constructor(code: number, message: string, data?: unknown, type?: string) {\n super(message);\n this.name = 'RpcError';\n this.code = code;\n this.data = data;\n this.type = type;\n }\n}\n\ninterface JsonRpcResponse {\n jsonrpc: string;\n id: number;\n result?: {\n output?: unknown;\n [key: string]: unknown;\n };\n error?: {\n // Standard JSON-RPC fields\n code?: number;\n message?: string;\n // Server-specific fields\n type?: string;\n data?: unknown;\n };\n}\n\nexport class RpcClient {\n private httpClient: HttpClient;\n\n constructor(opts: { httpClient: HttpClient }) {\n this.httpClient = opts.httpClient;\n }\n\n async execute<T = unknown>(params: ExecuteParams): Promise<T> {\n const body = {\n jsonrpc: '2.0',\n id: 1,\n method: 'execute',\n params: {\n contextId: params.contextId,\n method: params.method,\n argsJson: params.argsJson ?? {},\n },\n };\n\n const response = await this.httpClient.post<JsonRpcResponse>(\n '/jsonrpc',\n body,\n );\n\n if (response.error) {\n const err = response.error;\n const code = err.code ?? -1;\n const message = err.message ?? err.type ?? 'RPC error';\n throw new RpcError(code, message, err.data, err.type);\n }\n\n if (response.result && 'output' in response.result) {\n return response.result.output as T;\n }\n\n return response.result as T;\n }\n\n /**\n * One-tap owner-driven convert: re-signs the caller's identity-gated entries\n * to the current schema. The export converts all of the caller's\n * below-target entries in a single sweep, so this issues one call and returns\n * the resulting summary \u2014 it does not loop.\n */\n async migrateMyEntries(contextId: string): Promise<MigrateMyEntriesSummary> {\n return this.execute<MigrateMyEntriesSummary>({ contextId, method: 'migrate_my_entries' });\n }\n\n /** Read-only count of the caller's entries still below the target schema. */\n async countMyPending(contextId: string): Promise<number> {\n return this.execute<number>({ contextId, method: 'count_my_pending' });\n }\n}\n", "export interface SseEventData {\n contextId: string;\n data: unknown;\n}\n\n/** Parsed `AppVersionChanged` context event (bundle-version flip; skew #2). */\nexport interface AppVersionChangedEvent {\n contextId: string;\n fromVersion?: string;\n toVersion?: string;\n}\n\ntype SseEventHandler = (event: SseEventData) => void;\ntype SseConnectHandler = (sessionId: string) => void;\ntype SseErrorHandler = (error: Error) => void;\n\ninterface SseListeners {\n connect: SseConnectHandler[];\n event: SseEventHandler[];\n error: SseErrorHandler[];\n}\n\nexport class SseClient {\n private baseUrl: string;\n private getAuthToken: () => Promise<string>;\n private reconnectDelayMs: number;\n private sessionId: string | null = null;\n private abortController: AbortController | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private subscribedContextIds: Set<string> = new Set();\n private closed = false;\n private listeners: SseListeners = { connect: [], event: [], error: [] };\n\n constructor(opts: {\n baseUrl: string;\n getAuthToken: () => Promise<string>;\n reconnectDelayMs?: number;\n }) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, '');\n this.getAuthToken = opts.getAuthToken;\n this.reconnectDelayMs = opts.reconnectDelayMs ?? 3000;\n }\n\n on(event: 'connect', handler: SseConnectHandler): void;\n on(event: 'event', handler: SseEventHandler): void;\n on(event: 'error', handler: SseErrorHandler): void;\n on(event: string, handler: SseConnectHandler | SseEventHandler | SseErrorHandler): void {\n const key = event as keyof SseListeners;\n if (key in this.listeners) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const arr = this.listeners[key] as any[];\n if (!arr.includes(handler)) arr.push(handler);\n }\n }\n\n off(event: 'connect', handler: SseConnectHandler): void;\n off(event: 'event', handler: SseEventHandler): void;\n off(event: 'error', handler: SseErrorHandler): void;\n off(event: string, handler: SseConnectHandler | SseEventHandler | SseErrorHandler): void {\n const key = event as keyof SseListeners;\n if (key in this.listeners) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const arr = this.listeners[key] as any[];\n const idx = arr.indexOf(handler);\n if (idx !== -1) arr.splice(idx, 1);\n }\n }\n\n /**\n * Typed convenience over the generic `'event'` stream: invokes `handler` only\n * for `AppVersionChanged` context events, with the payload already parsed.\n * Returns an unsubscribe closure (so callers need not retain the listener).\n */\n onAppVersionChanged(handler: (e: AppVersionChangedEvent) => void): () => void {\n const listener: SseEventHandler = (ev) => {\n const d = ev.data as\n | { type?: string; data?: { fromVersion?: string; toVersion?: string } }\n | undefined;\n if (d?.type !== 'AppVersionChanged') return;\n handler({ contextId: ev.contextId, fromVersion: d.data?.fromVersion, toVersion: d.data?.toVersion });\n };\n this.on('event', listener);\n return () => this.off('event', listener);\n }\n\n private emit(event: 'connect', sessionId: string): void;\n private emit(event: 'event', data: SseEventData): void;\n private emit(event: 'error', error: Error): void;\n private emit(event: string, arg?: string | SseEventData | Error): void {\n const key = event as keyof SseListeners;\n if (key in this.listeners) {\n for (const handler of this.listeners[key]) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (handler as any)(arg);\n } catch {\n // Swallow handler errors\n }\n }\n }\n }\n\n async connect(): Promise<void> {\n // Already connected \u2014 don't reconnect\n if (this.abortController && !this.closed) {\n return;\n }\n this.closed = false;\n this.abortController = new AbortController();\n\n try {\n const token = await this.getAuthToken();\n const response = await fetch(`${this.baseUrl}/sse`, {\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Accept': 'text/event-stream',\n },\n signal: this.abortController.signal,\n });\n\n if (!response.ok) {\n throw new Error(`SSE connection failed: ${response.status}`);\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body');\n }\n\n this.readStream(response.body).catch((err) => {\n if (this.closed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n this.scheduleReconnect();\n });\n } catch (err) {\n if (this.closed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n this.scheduleReconnect();\n }\n }\n\n private async readStream(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split('\\n');\n // Keep the last partial line in the buffer\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data:')) {\n const jsonStr = line.slice(5).trim();\n if (jsonStr) {\n this.handleMessage(jsonStr);\n }\n }\n }\n }\n // Flush remaining bytes from the decoder\n buffer += decoder.decode();\n if (buffer.startsWith('data:')) {\n const jsonStr = buffer.slice(5).trim();\n if (jsonStr) {\n this.handleMessage(jsonStr);\n }\n }\n } catch (err) {\n if (this.closed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n }\n\n // Stream ended, reconnect\n if (!this.closed) {\n this.scheduleReconnect();\n }\n }\n\n private handleMessage(jsonStr: string): void {\n try {\n const msg = JSON.parse(jsonStr);\n\n // Connection message\n if (msg.type === 'connect' && msg.session_id) {\n this.sessionId = msg.session_id;\n this.emit('connect', msg.session_id);\n // Re-subscribe after reconnect\n if (this.subscribedContextIds.size > 0) {\n this.sendSubscription('subscribe', [...this.subscribedContextIds]);\n }\n return;\n }\n\n // Context event message\n if (msg.result && msg.result.contextId) {\n let eventData = msg.result.data;\n // Decode byte-array data if needed\n if (Array.isArray(eventData)) {\n try {\n const bytes = new Uint8Array(eventData);\n const text = new TextDecoder().decode(bytes);\n eventData = JSON.parse(text);\n } catch {\n // Keep raw data\n }\n }\n\n this.emit('event', {\n contextId: msg.result.contextId,\n data: eventData,\n });\n }\n } catch {\n // Invalid JSON, ignore\n }\n }\n\n async subscribe(contextIds: string[]): Promise<void> {\n const newIds = contextIds.filter(id => !this.subscribedContextIds.has(id));\n for (const id of contextIds) {\n this.subscribedContextIds.add(id);\n }\n if (newIds.length > 0 && this.sessionId) {\n await this.sendSubscription('subscribe', newIds);\n }\n }\n\n async unsubscribe(contextIds: string[]): Promise<void> {\n const hadIds = contextIds.filter(id => this.subscribedContextIds.has(id));\n for (const id of contextIds) {\n this.subscribedContextIds.delete(id);\n }\n if (hadIds.length > 0 && this.sessionId) {\n await this.sendSubscription('unsubscribe', hadIds);\n }\n }\n\n private async sendSubscription(method: 'subscribe' | 'unsubscribe', contextIds: string[]): Promise<void> {\n try {\n const token = await this.getAuthToken();\n const response = await fetch(`${this.baseUrl}/sse/subscription`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n id: this.sessionId,\n method,\n params: { contextIds },\n }),\n });\n if (!response.ok) {\n this.emit('error', new Error(`SSE ${method} failed: ${response.status}`));\n }\n } catch (err) {\n this.emit('error', err instanceof Error ? err : new Error(`SSE ${method} failed`));\n }\n }\n\n private forceReconnect(): void {\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n this.sessionId = null;\n this.connect();\n }\n\n private scheduleReconnect(): void {\n if (this.closed) return;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.forceReconnect();\n }, this.reconnectDelayMs);\n }\n\n close(): void {\n this.closed = true;\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.sessionId = null;\n this.subscribedContextIds.clear();\n }\n}\n", "export interface WsEventData {\n contextId: string;\n data: unknown;\n}\n\ntype WsEventHandler = (event: WsEventData) => void;\ntype WsConnectHandler = () => void;\ntype WsErrorHandler = (error: Error) => void;\n\ninterface WsListeners {\n connect: WsConnectHandler[];\n event: WsEventHandler[];\n error: WsErrorHandler[];\n}\n\n/**\n * @experimental WebSocket event client. The SSE client (`SseClient`) is the\n * recommended transport for production \u2014 use `MeroJs.events` instead of `MeroJs.ws`.\n */\nexport class WsClient {\n private baseUrl: string;\n private getAuthToken: () => Promise<string>;\n private ws: WebSocket | null = null;\n private closed = false;\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private subscribedContextIds: Set<string> = new Set();\n private listeners: WsListeners = { connect: [], event: [], error: [] };\n\n private static readonly MAX_BACKOFF_MS = 30000;\n\n constructor(opts: {\n baseUrl: string;\n getAuthToken: () => Promise<string>;\n }) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, '');\n this.getAuthToken = opts.getAuthToken;\n }\n\n on(event: 'connect', handler: WsConnectHandler): void;\n on(event: 'event', handler: WsEventHandler): void;\n on(event: 'error', handler: WsErrorHandler): void;\n on(event: string, handler: WsConnectHandler | WsEventHandler | WsErrorHandler): void {\n const key = event as keyof WsListeners;\n if (key in this.listeners) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const arr = this.listeners[key] as any[];\n if (!arr.includes(handler)) arr.push(handler);\n }\n }\n\n off(event: 'connect', handler: WsConnectHandler): void;\n off(event: 'event', handler: WsEventHandler): void;\n off(event: 'error', handler: WsErrorHandler): void;\n off(event: string, handler: WsConnectHandler | WsEventHandler | WsErrorHandler): void {\n const key = event as keyof WsListeners;\n if (key in this.listeners) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const arr = this.listeners[key] as any[];\n const idx = arr.indexOf(handler);\n if (idx !== -1) arr.splice(idx, 1);\n }\n }\n\n private emit(event: 'connect'): void;\n private emit(event: 'event', data: WsEventData): void;\n private emit(event: 'error', error: Error): void;\n private emit(event: string, arg?: WsEventData | Error): void {\n const key = event as keyof WsListeners;\n if (key in this.listeners) {\n for (const handler of this.listeners[key]) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (handler as any)(arg);\n } catch {\n // Swallow handler errors\n }\n }\n }\n }\n\n async connect(): Promise<void> {\n if (this.ws && (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN)) {\n return;\n }\n this.closed = false;\n\n try {\n const token = await this.getAuthToken();\n if (!token) {\n throw new Error('No authentication token available for WebSocket connection');\n }\n // Browser WebSocket API can't set headers, use query param\n const wsUrl = this.baseUrl.replace(/^http/, 'ws');\n this.ws = new WebSocket(`${wsUrl}/ws?token=${encodeURIComponent(token)}`);\n\n this.ws.onopen = () => {\n this.reconnectAttempt = 0;\n this.emit('connect');\n // Re-subscribe on reconnect\n if (this.subscribedContextIds.size > 0) {\n this.sendMessage({\n id: null,\n method: 'subscribe',\n params: { contextIds: [...this.subscribedContextIds] },\n });\n }\n };\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data);\n };\n\n this.ws.onerror = () => {\n this.emit('error', new Error('WebSocket error'));\n };\n\n this.ws.onclose = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n } catch (err) {\n if (this.closed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n this.scheduleReconnect();\n }\n }\n\n private handleMessage(raw: string | ArrayBuffer | Blob): void {\n if (typeof raw !== 'string') return;\n\n try {\n const msg = JSON.parse(raw);\n\n if (msg.result && msg.result.contextId) {\n let eventData = msg.result.data;\n if (Array.isArray(eventData)) {\n try {\n const bytes = new Uint8Array(eventData);\n const text = new TextDecoder().decode(bytes);\n eventData = JSON.parse(text);\n } catch {\n // Keep raw data\n }\n }\n\n this.emit('event', {\n contextId: msg.result.contextId,\n data: eventData,\n });\n }\n } catch {\n // Invalid JSON, ignore\n }\n }\n\n subscribe(contextIds: string[]): void {\n for (const id of contextIds) {\n this.subscribedContextIds.add(id);\n }\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.sendMessage({\n id: null,\n method: 'subscribe',\n params: { contextIds },\n });\n }\n }\n\n unsubscribe(contextIds: string[]): void {\n for (const id of contextIds) {\n this.subscribedContextIds.delete(id);\n }\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.sendMessage({\n id: null,\n method: 'unsubscribe',\n params: { contextIds },\n });\n }\n }\n\n private sendMessage(msg: unknown): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(msg));\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed) return;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n const delay = Math.min(\n 1000 * Math.pow(2, this.reconnectAttempt),\n WsClient.MAX_BACKOFF_MS,\n );\n this.reconnectAttempt++;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, delay);\n }\n\n close(): void {\n this.closed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.onclose = null;\n this.ws.close();\n this.ws = null;\n }\n this.subscribedContextIds.clear();\n }\n}\n", "import { createBrowserHttpClient } from './http-client';\nimport { createAuthApiClientFromHttpClient } from './auth-api';\nimport { createAdminApiClientFromHttpClient } from './admin-api';\nimport type { AuthApiClient } from './auth-api';\nimport type { AdminApiClient } from './admin-api';\nimport type { HttpClient } from './http-client';\nimport type { TokenStore } from './token-store';\nimport { parseAuthCallback, buildAuthLoginUrl } from './auth';\nimport type { AuthCallbackResult, AuthLoginOptions } from './auth';\nimport { RpcClient } from './rpc';\nimport { SseClient } from './events/sse';\nimport { WsClient } from './events/ws';\n\nexport interface MeroJsConfig {\n /** Base URL for the Calimero node */\n baseUrl: string;\n /** Initial credentials for authentication */\n credentials?: {\n username: string;\n password: string;\n };\n /** Custom HTTP client timeout in milliseconds */\n timeoutMs?: number;\n /** Request credentials mode for fetch (omit, same-origin, include) */\n requestCredentials?: RequestCredentials;\n /** Optional token store for persistence */\n tokenStore?: TokenStore;\n}\n\nexport interface TokenData {\n access_token: string;\n refresh_token: string;\n expires_at: number;\n}\n\n/** Try to extract `exp` (seconds) from a JWT, return ms timestamp or fallback. */\nfunction expiresAtFromJwt(token: string, fallbackMs: number): number {\n try {\n const parts = token.split('.');\n if (parts.length === 3) {\n // JWT uses base64url encoding: replace -/_ with +// and add padding\n let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n while (b64.length % 4) b64 += '=';\n const payload = JSON.parse(atob(b64));\n if (typeof payload.exp === 'number') {\n return payload.exp * 1000;\n }\n }\n } catch {\n // not a JWT or can't parse\n }\n return fallbackMs;\n}\n\n/**\n * Main MeroJs SDK class that manages all API clients and authentication\n */\nexport class MeroJs {\n private config: MeroJsConfig;\n private httpClient: HttpClient;\n private authClient: AuthApiClient;\n private adminClient: AdminApiClient;\n private tokenData: TokenData | null = null;\n private refreshPromise: Promise<TokenData> | null = null;\n private tokenStore: TokenStore | null;\n private rpcClient: RpcClient | null = null;\n private sseClient: SseClient | null = null;\n private wsClient: WsClient | null = null;\n private wsWarned = false;\n\n constructor(config: MeroJsConfig) {\n this.config = {\n timeoutMs: 10000,\n ...config,\n };\n\n this.tokenStore = config.tokenStore ?? null;\n\n // Restore tokens from store if available\n if (this.tokenStore) {\n this.tokenData = this.tokenStore.getTokens();\n }\n\n // Create HTTP client with token management\n // For Tauri, explicitly set credentials to 'omit' to avoid network errors\n const isTauri = typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;\n this.httpClient = createBrowserHttpClient({\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n refreshToken: async () => {\n const refreshed = await this.performTokenRefresh();\n return refreshed.access_token;\n },\n onTokenRefresh: async (newToken: string) => {\n if (this.tokenData) {\n this.tokenData.access_token = newToken;\n this.tokenStore?.setTokens(this.tokenData);\n }\n },\n timeoutMs: this.config.timeoutMs,\n credentials: this.config.requestCredentials ?? (isTauri ? 'omit' : undefined),\n });\n\n // Create API clients\n this.authClient = createAuthApiClientFromHttpClient(this.httpClient, {\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n timeoutMs: this.config.timeoutMs,\n });\n\n this.adminClient = createAdminApiClientFromHttpClient(this.httpClient, {\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n timeoutMs: this.config.timeoutMs,\n });\n }\n\n /**\n * Get the Auth API client\n */\n get auth(): AuthApiClient {\n return this.authClient;\n }\n\n /**\n * Get the Admin API client\n */\n get admin(): AdminApiClient {\n return this.adminClient;\n }\n\n /**\n * Get the RPC client (lazy initialized)\n */\n get rpc(): RpcClient {\n if (!this.rpcClient) {\n this.rpcClient = new RpcClient({ httpClient: this.httpClient });\n }\n return this.rpcClient;\n }\n\n /**\n * Get the SSE event client (lazy initialized)\n */\n get events(): SseClient {\n if (!this.sseClient) {\n this.sseClient = new SseClient({\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n });\n }\n return this.sseClient;\n }\n\n /**\n * Get the WebSocket event client (lazy initialized).\n * @experimental Use `events` (SSE) for production. WsClient is experimental.\n */\n get ws(): WsClient {\n if (!this.wsWarned) {\n this.wsWarned = true;\n console.warn('[mero-js] WsClient is experimental. Use mero.events (SSE) for production.');\n }\n if (!this.wsClient) {\n this.wsClient = new WsClient({\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n });\n }\n return this.wsClient;\n }\n\n /**\n * Authenticate with the provided credentials\n * This will create the root key on first use\n */\n async authenticate(credentials?: {\n username: string;\n password: string;\n }): Promise<TokenData> {\n const creds = credentials || this.config.credentials;\n if (!creds) {\n throw new Error('No credentials provided for authentication');\n }\n\n try {\n const requestBody = {\n auth_method: 'user_password',\n public_key: creds.username,\n client_name: 'mero-js-sdk',\n permissions: ['admin'],\n timestamp: Math.floor(Date.now() / 1000),\n provider_data: {\n username: creds.username,\n password: creds.password,\n },\n };\n\n const response = await this.authClient.generateTokens(requestBody);\n\n const accessToken = response.data.access_token;\n this.tokenData = {\n access_token: accessToken,\n refresh_token: response.data.refresh_token,\n expires_at: expiresAtFromJwt(accessToken, Date.now() + 3600_000),\n };\n\n this.tokenStore?.setTokens(this.tokenData);\n\n return this.tokenData;\n } catch (error) {\n throw new Error(\n `Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Get a valid token. Returns the current token as-is.\n * The server rejects refresh attempts while the access token is still valid,\n * so we never proactively refresh. Instead, the WebHttpClient handles 401\n * responses reactively via the refreshToken transport hook.\n */\n private async getValidToken(): Promise<TokenData | null> {\n return this.tokenData;\n }\n\n /**\n * Refresh the access token using the refresh token\n */\n private async refreshToken(): Promise<TokenData> {\n if (!this.tokenData?.refresh_token) {\n throw new Error('No refresh token available');\n }\n\n // Prevent multiple simultaneous refresh attempts\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n this.refreshPromise = this.performTokenRefresh();\n\n try {\n const newToken = await this.refreshPromise;\n return newToken;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n /**\n * Perform the actual token refresh\n */\n private async performTokenRefresh(): Promise<TokenData> {\n if (!this.tokenData?.refresh_token) {\n throw new Error('No refresh token available');\n }\n\n try {\n const response = await this.authClient.refreshToken({\n access_token: this.tokenData.access_token,\n refresh_token: this.tokenData.refresh_token,\n });\n\n const accessToken = response.data.access_token;\n this.tokenData = {\n access_token: accessToken,\n refresh_token: response.data.refresh_token,\n expires_at: expiresAtFromJwt(accessToken, Date.now() + 3600_000),\n };\n\n this.tokenStore?.setTokens(this.tokenData);\n\n return this.tokenData;\n } catch (error) {\n // Don't clear tokens on refresh failure \u2014 the access token may still be\n // valid (server rejects refresh while access token hasn't expired yet).\n // Let the caller handle the error.\n throw new Error(\n `Token refresh failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Clear the current token\n */\n public clearToken(): void {\n this.tokenData = null;\n this.tokenStore?.clear();\n }\n\n /**\n * Check if the SDK is authenticated\n */\n public isAuthenticated(): boolean {\n return this.tokenData !== null;\n }\n\n /**\n * Set token data directly (e.g., from auth callback).\n * If `expires_at` is missing or 0, attempts to parse the JWT exp claim,\n * falling back to 1 hour from now.\n */\n public setTokenData(data: TokenData): void {\n const expiresAt = data.expires_at || expiresAtFromJwt(data.access_token, Date.now() + 3600_000);\n this.tokenData = { ...data, expires_at: expiresAt };\n this.tokenStore?.setTokens(this.tokenData);\n }\n\n /**\n * Get the current token data (for debugging)\n */\n public getTokenData(): TokenData | null {\n return this.tokenData;\n }\n\n /**\n * Close all event connections and clean up resources\n */\n public close(): void {\n this.sseClient?.close();\n this.wsClient?.close();\n }\n\n /**\n * Parse an auth callback URL hash fragment (static utility)\n */\n static parseAuthCallback(url: string): AuthCallbackResult | null {\n return parseAuthCallback(url);\n }\n\n /**\n * Build an auth login URL (static utility)\n */\n static buildAuthLoginUrl(nodeUrl: string, opts: AuthLoginOptions): string {\n return buildAuthLoginUrl(nodeUrl, opts);\n }\n}\n\n/**\n * Create a new MeroJs SDK instance\n */\nexport function createMeroJs(config: MeroJsConfig): MeroJs {\n return new MeroJs(config);\n}\n", "import type { TokenData } from '../mero-js';\n\nexport interface TokenStore {\n getTokens(): TokenData | null;\n setTokens(data: TokenData): void;\n clear(): void;\n}\n\nexport class MemoryTokenStore implements TokenStore {\n private tokens: TokenData | null = null;\n\n getTokens(): TokenData | null {\n return this.tokens;\n }\n\n setTokens(data: TokenData): void {\n this.tokens = data;\n }\n\n clear(): void {\n this.tokens = null;\n }\n}\n\nconst STORAGE_KEY = 'mero-tokens';\n\nexport class LocalStorageTokenStore implements TokenStore {\n private readonly key: string;\n\n constructor(key: string = STORAGE_KEY) {\n this.key = key;\n }\n\n getTokens(): TokenData | null {\n try {\n if (typeof localStorage === 'undefined') return null;\n const raw = localStorage.getItem(this.key);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (parsed && parsed.access_token && parsed.refresh_token) {\n return {\n access_token: parsed.access_token,\n refresh_token: parsed.refresh_token,\n expires_at: typeof parsed.expires_at === 'number' ? parsed.expires_at : Date.now() + 3600_000,\n };\n }\n return null;\n } catch {\n return null;\n }\n }\n\n setTokens(data: TokenData): void {\n try {\n if (typeof localStorage === 'undefined') return;\n localStorage.setItem(this.key, JSON.stringify(data));\n } catch {\n // Storage unavailable\n }\n }\n\n clear(): void {\n try {\n if (typeof localStorage === 'undefined') return;\n localStorage.removeItem(this.key);\n } catch {\n // Storage unavailable\n }\n }\n}\n", "export interface CloudClientConfig {\n cloudBaseUrl?: string;\n}\n\nexport interface EnableHAOptions {\n groupId: string;\n contextId: string;\n redirectUrl?: string;\n}\n\nexport interface DisableHAOptions {\n groupId: string;\n contextId: string;\n redirectUrl?: string;\n}\n\nexport class CloudClient {\n private baseUrl: string;\n\n constructor(config: CloudClientConfig = {}) {\n this.baseUrl = (config.cloudBaseUrl || 'https://cloud.calimero.network').replace(/\\/+$/, '');\n }\n\n enableHA(options: EnableHAOptions): void {\n const params = new URLSearchParams({\n group_id: options.groupId,\n context_id: options.contextId,\n });\n if (options.redirectUrl) {\n params.set('redirect_url', options.redirectUrl);\n }\n window.open(`${this.baseUrl}/enable-ha?${params.toString()}`);\n }\n\n disableHA(options: DisableHAOptions): void {\n const params = new URLSearchParams({\n group_id: options.groupId,\n context_id: options.contextId,\n });\n if (options.redirectUrl) {\n params.set('redirect_url', options.redirectUrl);\n }\n window.open(`${this.baseUrl}/disable-ha?${params.toString()}`);\n }\n}\n", "// Member capability bitmask constants \u2014 mirrors core's `MemberCapabilities`\n// (crates/context/config/src/lib.rs). The value stored per-member is a u32\n// bitmask. Core currently assigns bits 0..=8; bits 9 and above are unassigned\n// and may be claimed by future core versions, so an application MUST NOT\n// assume any particular bit is safe for its own use unless core documents it\n// as reserved for applications.\n\n/**\n * Capability bits as defined by core's `MemberCapabilities`.\n *\n * The per-member value is a u32 bitmask. Core currently assigns bits 0..=8\n * (the entries below); bits 9 and above are unassigned \u2014 do not repurpose\n * them for application data, as a future core release may claim them.\n */\nexport const CAPABILITIES = {\n CAN_CREATE_CONTEXT: 1 << 0,\n CAN_INVITE_MEMBERS: 1 << 1,\n CAN_JOIN_OPEN_SUBGROUPS: 1 << 2,\n MANAGE_MEMBERS: 1 << 3,\n MANAGE_APPLICATION: 1 << 4,\n CAN_CREATE_SUBGROUP: 1 << 5,\n CAN_DELETE_SUBGROUP: 1 << 6,\n CAN_MANAGE_VISIBILITY: 1 << 7,\n CAN_MANAGE_METADATA: 1 << 8,\n} as const;\n\nexport type CapabilityName = keyof typeof CAPABILITIES;\nexport type CapabilityBit = (typeof CAPABILITIES)[CapabilityName];\n\n/**\n * Returns true if `mask` has every bit of `cap` set. Both operands are\n * coerced to unsigned 32-bit (`>>> 0`) before comparing so a high bit such\n * as `1 << 31` doesn't fall foul of `&` yielding a signed result.\n */\nexport function hasCap(mask: number, cap: number): boolean {\n const capU32 = cap >>> 0;\n return ((mask & capU32) >>> 0) === capU32;\n}\n\n/** Returns `mask` with every bit of `cap` set (u32-normalized). */\nexport function withCap(mask: number, cap: number): number {\n return (mask | cap) >>> 0;\n}\n\n/** Returns `mask` with every bit of `cap` cleared (u32-normalized). */\nexport function withoutCap(mask: number, cap: number): number {\n return (mask & ~cap) >>> 0;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["// Utility for combining multiple AbortSignals\nexport function combineSignals(\n signals: Array<AbortSignal | undefined>,\n): AbortSignal | undefined {\n const list = signals.filter(Boolean) as AbortSignal[];\n if (list.length === 0) return undefined;\n\n // Prefer native any(), but fall back if unavailable or it throws\n const AbortSignalAny = AbortSignal as {\n any?: (signals: AbortSignal[]) => AbortSignal;\n };\n if (typeof AbortSignalAny.any === 'function') {\n try {\n return AbortSignalAny.any(list);\n } catch {\n // Fall through to manual implementation\n }\n }\n\n const controller = new AbortController();\n const onAbort = (evt: Event) => {\n controller.abort((evt.target as AbortSignal).reason);\n for (const s of list) s.removeEventListener('abort', onAbort);\n };\n\n for (const s of list) {\n if (s.aborted) return AbortSignal.abort(s.reason);\n s.addEventListener('abort', onAbort, { once: true });\n }\n\n return controller.signal;\n}\n\n// Helper to create a timeout signal\nexport function createTimeoutSignal(timeoutMs: number): AbortSignal {\n // Use AbortSignal.timeout if available (Node 18.17+, modern browsers)\n if (typeof AbortSignal.timeout === 'function') {\n return AbortSignal.timeout(timeoutMs);\n }\n\n // Fallback for older environments\n const controller = new AbortController();\n setTimeout(() => {\n controller.abort(new DOMException('Timeout', 'TimeoutError'));\n }, timeoutMs);\n\n return controller.signal;\n}\n", "// ErrorResponse import removed as it's not used\nimport {\n HttpClient,\n Transport,\n RequestOptions,\n ResponseParser,\n} from './http-types';\nimport { combineSignals, createTimeoutSignal } from './signal-utils';\n\n// Custom error class for HTTP errors\nexport class HTTPError extends Error {\n name = 'HTTPError' as const;\n\n constructor(\n public status: number,\n public statusText: string,\n public url: string,\n public headers: Headers,\n public bodyText?: string, // cap at ~64KB\n ) {\n super(`HTTP ${status} ${statusText}`);\n }\n\n toJSON(): {\n status: number;\n statusText: string;\n url: string;\n headers: Record<string, string>;\n bodyText?: string;\n } {\n return {\n status: this.status,\n statusText: this.statusText,\n url: this.url,\n headers: headersToRecord(this.headers),\n bodyText: this.bodyText,\n };\n }\n}\n\n// Helper function to convert Headers to Record\nfunction headersToRecord(headers: Headers): Record<string, string> {\n const record: Record<string, string> = {};\n headers.forEach((value, key) => {\n record[key] = value;\n });\n return record;\n}\n\n// Web Standards HTTP client implementation\nexport class WebHttpClient implements HttpClient {\n // Cache for concurrent refresh token calls to prevent race conditions\n private refreshTokenPromise: Promise<string> | null = null;\n // Cache for concurrent onTokenRefresh calls to prevent duplicate callbacks\n private onTokenRefreshPromise: Promise<void> | null = null;\n \n constructor(private transport: Transport) {}\n\n async get<T>(path: string, init?: RequestOptions): Promise<T> {\n return this.request<T>(path, { ...init, method: 'GET' });\n }\n\n async post<T>(\n path: string,\n body?: unknown,\n init?: RequestOptions,\n ): Promise<T> {\n return this.request<T>(path, {\n ...init,\n method: 'POST',\n body: body ? JSON.stringify(body) : undefined,\n headers: {\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n });\n }\n\n async put<T>(\n path: string,\n body?: unknown,\n init?: RequestOptions,\n ): Promise<T> {\n return this.request<T>(path, {\n ...init,\n method: 'PUT',\n body: body ? JSON.stringify(body) : undefined,\n headers: {\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n });\n }\n\n async delete<T>(path: string, init?: RequestOptions): Promise<T> {\n return this.request<T>(path, { ...init, method: 'DELETE' });\n }\n\n async patch<T>(\n path: string,\n body?: unknown,\n init?: RequestOptions,\n ): Promise<T> {\n return this.request<T>(path, {\n ...init,\n method: 'PATCH',\n body: body ? JSON.stringify(body) : undefined,\n headers: {\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n });\n }\n\n async head(\n path: string,\n init?: RequestOptions,\n ): Promise<{ headers: Record<string, string>; status: number }> {\n const response = await this.makeRequest<Response>(path, {\n ...init,\n method: 'HEAD',\n parse: 'response',\n });\n return {\n headers: headersToRecord(response.headers),\n status: response.status,\n };\n }\n\n async request<T>(path: string, init?: RequestOptions): Promise<T> {\n return this.makeRequest<T>(path, init);\n }\n\n private async makeRequest<T>(\n path: string,\n init?: RequestOptions,\n retryCount = 0,\n requestStartTime?: number,\n ): Promise<T> {\n // Maximum retry attempts to prevent infinite loops\n const MAX_RETRY_ATTEMPTS = 1;\n const url = this.buildUrl(path);\n \n // Track request start time for timeout calculation (only on first attempt)\n // Use per-request start time to avoid corruption from concurrent requests\n const startTime = requestStartTime ?? Date.now();\n // Note: Tauri proxy script now handles AbortSignal, so we can use full RequestInit\n // Removed Tauri-specific minimal path - proxy script handles AbortSignal properly\n const signal = this.createAbortSignal(init);\n const headers = await this.buildHeaders(init?.headers);\n let headersObj: Record<string, string>;\n if (headers instanceof Headers) {\n headersObj = {};\n headers.forEach((value, key) => {\n headersObj[key] = value;\n });\n } else {\n headersObj = headers;\n }\n \n const requestInit: RequestInit = {\n method: init?.method || 'GET',\n headers: headersObj,\n };\n \n // Check if body is a stream (ReadableStream) that can't be reused\n // Note: Blob is reusable, so it's not included here\n const isStreamBody = init?.body instanceof ReadableStream ||\n (typeof init?.body === 'object' && init?.body !== null && 'getReader' in init.body && !(init.body instanceof Blob));\n \n if (init?.body !== undefined && !isStreamBody) {\n requestInit.body = init.body;\n } else if (init?.body !== undefined && isStreamBody && retryCount === 0) {\n // Only include stream body on first attempt - can't retry with streams\n requestInit.body = init.body;\n }\n \n // For retries, calculate remaining timeout to prevent timeout reset\n // Track elapsed time and use remaining timeout for retry\n // Note: This is calculated before the request, so it doesn't include token refresh time\n // The actual remaining timeout check happens after token refresh completes\n let retrySignal: AbortSignal | undefined;\n if (retryCount > 0 && requestStartTime !== undefined) {\n const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;\n if (timeoutMs) {\n // Calculate elapsed time (will be recalculated after token refresh if needed)\n const elapsed = Date.now() - startTime;\n const remaining = Math.max(0, timeoutMs - elapsed);\n // Create signal with remaining timeout, preserving user's signal\n retrySignal = this.createAbortSignal({ ...init, timeoutMs: remaining });\n } else {\n // No timeout, just preserve user's signal\n retrySignal = this.createAbortSignal(init);\n }\n } else {\n retrySignal = signal;\n }\n \n if (retrySignal) {\n requestInit.signal = retrySignal;\n }\n \n if (this.transport.credentials !== undefined) {\n requestInit.credentials = this.transport.credentials;\n }\n \n if (init?.mode !== undefined) {\n requestInit.mode = init.mode;\n }\n if (init?.cache !== undefined) {\n requestInit.cache = init.cache;\n }\n if (init?.redirect !== undefined) {\n requestInit.redirect = init.redirect;\n }\n if (init?.referrer !== undefined) {\n requestInit.referrer = init.referrer;\n }\n if (init?.referrerPolicy !== undefined) {\n requestInit.referrerPolicy = init.referrerPolicy;\n }\n if (init?.integrity !== undefined) {\n requestInit.integrity = init.integrity;\n }\n if (init?.keepalive !== undefined) {\n requestInit.keepalive = init.keepalive;\n }\n\n try {\n const response = await this.transport.fetch(url, requestInit);\n\n if (!response.ok) {\n const bodyText = await this.getBodyText(response);\n const httpError = new HTTPError(\n response.status,\n response.statusText,\n url,\n response.headers,\n bodyText,\n );\n\n // Handle 401 with token_expired - attempt automatic token refresh\n const userAborted = init?.signal?.aborted === true;\n if (\n response.status === 401 &&\n this.transport.refreshToken &&\n response.headers.get('x-auth-error') === 'token_expired' &&\n retryCount < MAX_RETRY_ATTEMPTS &&\n !isStreamBody &&\n !userAborted\n ) {\n try {\n // Use cached refresh promise if one is in progress (prevents race conditions)\n let refreshPromise = this.refreshTokenPromise;\n if (!refreshPromise) {\n refreshPromise = this.transport.refreshToken();\n this.refreshTokenPromise = refreshPromise;\n }\n \n // Attempt to refresh the token\n const newToken = await refreshPromise;\n \n // Validate token - must be non-empty\n if (!newToken || newToken.trim() === '') {\n // Clear caches on error\n this.refreshTokenPromise = null;\n this.onTokenRefreshPromise = null;\n throw new Error('Refresh token returned empty token');\n }\n \n // onTokenRefresh is required when refreshToken is provided\n // Without it, the new token cannot be stored and getAuthToken() will return the old token\n if (!this.transport.onTokenRefresh) {\n // Clear caches on error\n this.refreshTokenPromise = null;\n this.onTokenRefreshPromise = null;\n throw new Error(\n 'onTokenRefresh callback is required when refreshToken is provided. ' +\n 'The callback must update the token storage so getAuthToken() returns the new token.'\n );\n }\n \n // Use cached onTokenRefresh promise if one is in progress (prevents duplicate callbacks)\n // This ensures onTokenRefresh is only called once per token refresh, even with concurrent requests\n let onTokenRefreshPromise = this.onTokenRefreshPromise;\n if (!onTokenRefreshPromise) {\n onTokenRefreshPromise = this.transport.onTokenRefresh(newToken);\n this.onTokenRefreshPromise = onTokenRefreshPromise;\n }\n \n // Update token via callback (only called once per refresh, even with concurrent requests)\n // Errors from onTokenRefresh callback should be preserved (don't mask as 401)\n // This helps developers debug token storage issues\n await onTokenRefreshPromise;\n \n // Clear caches after both refresh and callback complete\n this.refreshTokenPromise = null;\n this.onTokenRefreshPromise = null;\n \n // Check if timeout has expired during token refresh\n // If so, throw the original 401 error instead of retrying with 0ms timeout\n // This prevents timeout/abort errors that obscure the root cause (expired token)\n const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;\n if (timeoutMs && requestStartTime !== undefined) {\n const elapsed = Date.now() - startTime;\n const remaining = timeoutMs - elapsed;\n if (remaining <= 0) {\n // Timeout expired during token refresh - throw original 401 error\n // This is better than retrying with 0ms timeout which would cause confusing timeout errors\n throw httpError;\n }\n }\n \n // Retry the request with the new token (increment retry count)\n // Preserve user's abort signal and start time in retry\n return this.makeRequest<T>(path, init, retryCount + 1, startTime);\n } catch (refreshError) {\n // Clear caches on error\n this.refreshTokenPromise = null;\n this.onTokenRefreshPromise = null;\n // Configuration errors (missing onTokenRefresh) should be thrown as-is\n if (refreshError instanceof Error && refreshError.message.includes('onTokenRefresh')) {\n throw refreshError;\n }\n // Errors from onTokenRefresh callback are already thrown above, so if we get here,\n // it's either a refreshToken() failure or empty token - throw original 401\n // This matches the PR description: \"If refresh fails, throws the original 401 error\"\n throw httpError;\n }\n }\n\n throw httpError;\n }\n\n return this.parseResponse<T>(response, init?.parse);\n } catch (error) {\n if (error instanceof HTTPError) {\n throw error;\n }\n // Preserve configuration errors (like missing onTokenRefresh)\n if (error instanceof Error && error.message.includes('onTokenRefresh')) {\n throw error;\n }\n throw new HTTPError(\n 0,\n 'Network Error',\n url,\n new Headers(),\n error instanceof Error ? error.message : 'Unknown error',\n );\n }\n }\n\n private buildUrl(path: string): string {\n // Handle absolute URLs\n if (path.startsWith('http://') || path.startsWith('https://')) {\n return path;\n }\n\n // Handle baseUrl with path\n const baseUrl = this.transport.baseUrl;\n if (path.startsWith('/')) {\n // If path starts with /, combine with baseUrl\n const base = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n return `${base}${path}`;\n } else {\n // If path doesn't start with /, append to baseUrl\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;\n return `${base}${path}`;\n }\n }\n\n private createAbortSignal(init?: RequestOptions): AbortSignal | undefined {\n const signals: AbortSignal[] = [];\n\n if (this.transport.defaultAbortSignal) {\n signals.push(this.transport.defaultAbortSignal);\n }\n\n if (init?.signal) {\n signals.push(init.signal);\n }\n\n const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;\n if (timeoutMs) {\n signals.push(createTimeoutSignal(timeoutMs));\n }\n\n return signals.length > 0 ? combineSignals(signals) : undefined;\n }\n\n private async buildHeaders(\n initHeaders?: HeadersInit,\n ): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n ...this.transport.defaultHeaders,\n };\n\n // Add auth token if available and not empty\n if (this.transport.getAuthToken) {\n try {\n const token = await this.transport.getAuthToken();\n if (token && token.trim() !== '') {\n headers.Authorization = `Bearer ${token}`;\n }\n } catch (error) {\n // Ignore auth token errors\n }\n }\n\n // Add init headers\n if (initHeaders) {\n if (initHeaders instanceof Headers) {\n initHeaders.forEach((value, key) => {\n headers[key] = value;\n });\n } else if (Array.isArray(initHeaders)) {\n initHeaders.forEach(([key, value]) => {\n headers[key] = value;\n });\n } else {\n Object.assign(headers, initHeaders);\n }\n }\n\n return headers;\n }\n\n private async parseResponse<T>(\n response: Response,\n parse?: ResponseParser,\n ): Promise<T> {\n switch (parse) {\n case 'text':\n return (await response.text()) as T;\n case 'blob':\n return (await response.blob()) as T;\n case 'arrayBuffer':\n return (await response.arrayBuffer()) as T;\n case 'response':\n return response as T;\n case 'json':\n default:\n return await response.json();\n }\n }\n\n private async getBodyText(response: Response): Promise<string> {\n try {\n const text = await response.text();\n return text.length > 65536 ? text.slice(0, 65536) + '...' : text;\n } catch {\n return '';\n }\n }\n}\n", "import { WebHttpClient } from './web-client';\nimport { Transport, HttpClient } from './http-types';\n\n// Factory function to create HTTP client with sensible defaults\nexport function createHttpClient(transport: Transport): HttpClient {\n return new WebHttpClient(transport);\n}\n\n// Factory function for browser environments\nexport function createBrowserHttpClient(options: {\n baseUrl: string;\n getAuthToken?: () => Promise<string | undefined>;\n onTokenRefresh?: (newToken: string) => Promise<void>;\n /**\n * Callback to refresh the access token when a 401 error with 'token_expired' is detected.\n * Should return the new access token, or throw an error if refresh fails.\n * If provided, the client will automatically retry the request after a successful refresh.\n */\n refreshToken?: () => Promise<string>;\n defaultHeaders?: Record<string, string>;\n timeoutMs?: number;\n credentials?: RequestCredentials;\n defaultAbortSignal?: AbortSignal;\n}): HttpClient {\n const transport: Transport = {\n // Wrap fetch in arrow function to prevent \"Illegal invocation\" error\n // This preserves the correct 'this' context when fetch is called\n fetch: (url: RequestInfo | URL, init?: RequestInit) => globalThis.fetch(url, init),\n baseUrl: options.baseUrl,\n getAuthToken: options.getAuthToken,\n onTokenRefresh: options.onTokenRefresh,\n refreshToken: options.refreshToken,\n defaultHeaders: options.defaultHeaders,\n timeoutMs: options.timeoutMs,\n credentials: options.credentials, // No default credentials\n defaultAbortSignal: options.defaultAbortSignal,\n };\n\n return createHttpClient(transport);\n}\n\n// Factory function for Node.js environments\nexport function createNodeHttpClient(options: {\n baseUrl: string;\n fetch?: typeof fetch; // Allow injection of undici.fetch or other fetch implementations\n getAuthToken?: () => Promise<string | undefined>;\n onTokenRefresh?: (newToken: string) => Promise<void>;\n /**\n * Callback to refresh the access token when a 401 error with 'token_expired' is detected.\n * Should return the new access token, or throw an error if refresh fails.\n * If provided, the client will automatically retry the request after a successful refresh.\n */\n refreshToken?: () => Promise<string>;\n defaultHeaders?: Record<string, string>;\n timeoutMs?: number;\n credentials?: RequestCredentials;\n defaultAbortSignal?: AbortSignal;\n}): HttpClient {\n // Use provided fetch or try to use global fetch (Node 18+)\n const fetchImpl = options.fetch ?? globalThis.fetch;\n\n if (!fetchImpl) {\n throw new Error(\n 'No fetch implementation available. Please provide a fetch implementation ' +\n '(e.g., undici.fetch) or use Node.js 18+ which has native fetch support.',\n );\n }\n\n // Check if we're using the default globalThis.fetch to preserve context\n // When fetchImpl is globalThis.fetch, we must call it directly, not through a variable\n // Custom fetch implementations (like undici.fetch) can be called through the variable\n const isDefaultFetch = fetchImpl === globalThis.fetch;\n\n const transport: Transport = {\n // Wrap fetch in arrow function to prevent \"Illegal invocation\" error\n // For globalThis.fetch, call it directly to preserve 'this' context\n // For custom implementations, calling through the variable is safe\n fetch: isDefaultFetch\n ? (url: RequestInfo | URL, init?: RequestInit) => globalThis.fetch(url, init)\n : (url: RequestInfo | URL, init?: RequestInit) => fetchImpl(url, init),\n baseUrl: options.baseUrl,\n getAuthToken: options.getAuthToken,\n onTokenRefresh: options.onTokenRefresh,\n refreshToken: options.refreshToken,\n defaultHeaders: options.defaultHeaders,\n timeoutMs: options.timeoutMs,\n credentials: options.credentials, // Node.js doesn't have default credentials\n defaultAbortSignal: options.defaultAbortSignal,\n };\n\n return createHttpClient(transport);\n}\n\n// Universal factory that works in both environments\nexport function createUniversalHttpClient(options: {\n baseUrl: string;\n fetch?: typeof fetch;\n getAuthToken?: () => Promise<string | undefined>;\n onTokenRefresh?: (newToken: string) => Promise<void>;\n /**\n * Callback to refresh the access token when a 401 error with 'token_expired' is detected.\n * Should return the new access token, or throw an error if refresh fails.\n * If provided, the client will automatically retry the request after a successful refresh.\n */\n refreshToken?: () => Promise<string>;\n defaultHeaders?: Record<string, string>;\n timeoutMs?: number;\n credentials?: RequestCredentials;\n defaultAbortSignal?: AbortSignal;\n}): HttpClient {\n // Try to detect environment and use appropriate factory\n if (typeof window !== 'undefined') {\n // Browser environment\n return createBrowserHttpClient(options);\n } else {\n // Node.js environment\n return createNodeHttpClient(options);\n }\n}\n", "// Retry helper for HTTP requests\nexport interface RetryOptions {\n attempts?: number;\n}\n\n// Error types for retry logic\ninterface ErrorWithName extends Error {\n name: string;\n}\n\ninterface ErrorWithStatus extends Error {\n status: number;\n}\n\ninterface ErrorWithHeaders extends Error {\n headers?: Headers;\n}\n\n// Default retry condition - retry on network errors and 5xx status codes\nfunction defaultRetryCondition(error: Error, attempt: number): boolean {\n // Don't retry on the last attempt\n if (attempt <= 0) return false;\n\n // Distinguish timeout vs. user abort:\n // - Timeout: name === 'TimeoutError' (per spec/platforms)\n // - User abort: name === 'AbortError'\n const errorWithName = error as ErrorWithName;\n const name = errorWithName?.name;\n if (name === 'TimeoutError') return true;\n if (name === 'AbortError') return false;\n\n // HTTP 5xx and 429 (including HTTPError from web-client)\n const errorWithStatus = error as ErrorWithStatus;\n if (\n 'status' in errorWithStatus &&\n typeof errorWithStatus.status === 'number'\n ) {\n const status = errorWithStatus.status;\n return status >= 500 || status === 429;\n }\n // Network TypeError (DNS/reset) is reasonably retryable\n if (name === 'TypeError') return true;\n\n return false;\n}\n\n// Calculate delay with exponential backoff and jitter\nfunction calculateDelay(attempt: number): number {\n const baseDelayMs = 250; // Base 250ms as per spec\n const delay = baseDelayMs * Math.pow(2, attempt - 1);\n\n // Add \u00B120% jitter to reduce stampedes\n const jitter = (Math.random() - 0.5) * 0.4 * delay;\n return Math.max(0, delay + jitter);\n}\n\n// Retry helper function with new signature\nexport async function withRetry<T>(\n fn: (attempt: number) => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> {\n const { attempts = 3 } = options;\n\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= attempts; attempt++) {\n try {\n return await fn(attempt);\n } catch (error) {\n lastError = error as Error;\n\n // Check if we should retry (this handles the last attempt check)\n if (!defaultRetryCondition(lastError, attempts - attempt)) {\n throw lastError;\n }\n\n // Calculate delay\n let delayMs = calculateDelay(attempt);\n\n // Check for Retry-After header if it's an HTTP error\n const errorWithHeaders = lastError as ErrorWithHeaders;\n const hdrs = errorWithHeaders.headers;\n const retryAfter = hdrs?.get?.('Retry-After');\n if (retryAfter) {\n // If it's a number, treat as seconds\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n delayMs = Math.max(delayMs, seconds * 1000);\n } else {\n // If it's a date, calculate the difference\n const date = new Date(retryAfter);\n if (!isNaN(date.getTime())) {\n const waitTime = Math.max(0, date.getTime() - Date.now());\n // Cap wait at 60s per attempt as per spec\n delayMs = Math.max(delayMs, Math.min(waitTime, 60000));\n }\n }\n }\n\n // Wait before retrying\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n }\n }\n\n throw lastError || new Error('Retry failed without error');\n}\n\n// Helper to create a retry-enabled HTTP client method\nexport function createRetryableMethod<T extends unknown[], R>(\n method: (...args: T) => Promise<R>,\n retryOptions: RetryOptions = {},\n) {\n return async (...args: T): Promise<R> => {\n return withRetry(() => method(...args), retryOptions);\n };\n}\n", "import { HttpClient } from '../http-client';\nimport {\n // Common types\n ApiResponse,\n // Health and Status\n HealthResponse,\n IdentityResponse,\n ProvidersResponse,\n // Authentication\n TokenRequest,\n TokenResponse,\n RefreshTokenRequest,\n ChallengeResponse,\n // Mock Token (testing)\n MockTokenRequest,\n // Token Management\n RevokeTokenRequest,\n RevokeTokenResponse,\n // Key Management\n CreateKeyRequest,\n CreateKeyResponse,\n DeleteKeyResponse,\n RootKeysResponse,\n // Client Management\n ClientKeysResponse,\n GenerateClientKeyRequest,\n DeleteClientResponse,\n // Permissions\n PermissionResponse,\n // Auth Status\n AuthStatus,\n} from './auth-types';\n\nexport class AuthApiClient {\n constructor(private httpClient: HttpClient) {}\n\n // Health and Status Endpoints\n async getHealth(): Promise<HealthResponse> {\n const response =\n await this.httpClient.get<ApiResponse<HealthResponse>>('/auth/health');\n if (!response.data) {\n throw new Error('Health response data is null');\n }\n return response.data;\n }\n\n async getIdentity(): Promise<IdentityResponse> {\n const response =\n await this.httpClient.get<ApiResponse<IdentityResponse>>(\n '/admin/identity',\n );\n if (!response.data) {\n throw new Error('Identity response data is null');\n }\n return response.data;\n }\n\n async getProviders(): Promise<ProvidersResponse> {\n const response =\n await this.httpClient.get<ApiResponse<ProvidersResponse>>(\n '/auth/providers',\n );\n if (!response.data) {\n throw new Error('Providers response data is null');\n }\n return response.data;\n }\n\n // Authentication Endpoints\n async getLoginPage(): Promise<string> {\n return this.httpClient.get<string>('/auth/login', { parse: 'text' });\n }\n\n async generateTokens(request: TokenRequest): Promise<TokenResponse> {\n return this.httpClient.post<TokenResponse>('/auth/token', request);\n }\n\n async refreshToken(request: RefreshTokenRequest): Promise<TokenResponse> {\n return this.httpClient.post<TokenResponse>('/auth/refresh', request);\n }\n\n async generateMockTokens(request: MockTokenRequest): Promise<TokenResponse> {\n return this.httpClient.post<TokenResponse>('/auth/mock-token', request);\n }\n\n async getChallenge(): Promise<ChallengeResponse> {\n return this.httpClient.get<ChallengeResponse>('/auth/challenge');\n }\n\n async validateToken(token: string): Promise<{\n valid: boolean;\n headers: Record<string, string>;\n status: number;\n }> {\n try {\n const response = await this.validateTokenGet(token);\n return {\n valid: response.status === 200,\n headers: response.headers,\n status: response.status,\n };\n } catch (error) {\n return {\n valid: false,\n headers: {},\n status: 401,\n };\n }\n }\n\n async validateTokenGet(\n token: string,\n ): Promise<{ status: number; headers: Record<string, string> }> {\n const response = await this.httpClient.head('/auth/validate', {\n headers: { Authorization: `Bearer ${token}` },\n });\n return {\n status: response.status,\n headers: response.headers,\n };\n }\n\n async isAuthed(): Promise<AuthStatus> {\n return this.httpClient.get<AuthStatus>('/auth/is-authed');\n }\n\n // Token Management Endpoints\n async revokeTokens(\n request: RevokeTokenRequest,\n ): Promise<RevokeTokenResponse> {\n return this.httpClient.post<RevokeTokenResponse>('/admin/revoke', request);\n }\n\n // Key Management Endpoints\n async listRootKeys(): Promise<RootKeysResponse> {\n const response =\n await this.httpClient.get<ApiResponse<RootKeysResponse>>('/admin/keys');\n if (!response.data) {\n throw new Error('Root keys response data is null');\n }\n return response.data;\n }\n\n async createRootKey(request: CreateKeyRequest): Promise<CreateKeyResponse> {\n return this.httpClient.post<CreateKeyResponse>('/admin/keys', request);\n }\n\n async deleteRootKey(keyId: string): Promise<DeleteKeyResponse> {\n return this.httpClient.delete<DeleteKeyResponse>(`/admin/keys/${keyId}`);\n }\n\n // Client Management Endpoints\n async listClientKeys(): Promise<ClientKeysResponse> {\n const response = await this.httpClient.get<ApiResponse<ClientKeysResponse>>(\n '/admin/keys/clients',\n );\n if (!response.data) {\n throw new Error('Client keys response data is null');\n }\n return response.data;\n }\n\n async generateClientKey(\n request: GenerateClientKeyRequest,\n ): Promise<TokenResponse> {\n return this.httpClient.post<TokenResponse>('/admin/client-key', request);\n }\n\n async deleteClientKey(\n keyId: string,\n clientId: string,\n ): Promise<DeleteClientResponse> {\n return this.httpClient.delete<DeleteClientResponse>(\n `/admin/keys/${keyId}/clients/${clientId}`,\n );\n }\n\n // Permission Management Endpoints\n async getKeyPermissions(keyId: string): Promise<PermissionResponse> {\n return this.httpClient.get<PermissionResponse>(\n `/admin/keys/${keyId}/permissions`,\n );\n }\n\n async updateKeyPermissions(\n keyId: string,\n permissions: string[],\n ): Promise<PermissionResponse> {\n return this.httpClient.put<PermissionResponse>(\n `/admin/keys/${keyId}/permissions`,\n { permissions },\n );\n }\n}\n", "import { AuthApiClient } from './auth-client';\nimport { AuthApiClientConfig } from './auth-types';\nimport { HttpClient } from '../http-client';\n\n// Mock HTTP client for testing\nclass MockHttpClient implements HttpClient {\n async get<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async post<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async put<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async delete<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async patch<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async head(): Promise<{ headers: Record<string, string>; status: number }> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n async request<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client',\n );\n }\n}\n\n// Factory functions for creating Auth API clients\nexport function createBrowserAuthApiClient(\n _config: AuthApiClientConfig,\n): AuthApiClient {\n const httpClient = new MockHttpClient();\n return new AuthApiClient(httpClient);\n}\n\nexport function createNodeAuthApiClient(\n _config: AuthApiClientConfig,\n): AuthApiClient {\n const httpClient = new MockHttpClient();\n return new AuthApiClient(httpClient);\n}\n\nexport function createAuthApiClient(\n _config: AuthApiClientConfig,\n): AuthApiClient {\n const httpClient = new MockHttpClient();\n return new AuthApiClient(httpClient);\n}\n\nexport function createAuthApiClientFromHttpClient(\n httpClient: HttpClient,\n _config: AuthApiClientConfig,\n): AuthApiClient {\n return new AuthApiClient(httpClient);\n}\n", "import { HttpClient } from '../http-client';\nimport type {\n HealthStatus,\n AdminAuthStatus,\n InstallApplicationRequest,\n InstallApplicationResponseData,\n InstallDevApplicationRequest,\n UninstallApplicationResponseData,\n ListApplicationsResponseData,\n GetApplicationResponseData,\n GetLatestVersionResponseData,\n ListPackagesResponseData,\n ListVersionsResponseData,\n RegistryBundleManifest,\n CreateContextRequest,\n CreateContextResponseData,\n DeleteContextRequest,\n DeleteContextResponseData,\n GetContextsResponseData,\n Context,\n GenerateContextIdentityResponseData,\n GetContextIdentitiesResponseData,\n JoinContextResponseData,\n JoinSubgroupInheritanceResponseData,\n ContextGroupResponseData,\n ContextStorageResponseData,\n InviteSpecializedNodeRequest,\n InviteSpecializedNodeResponseData,\n UpdateContextApplicationRequest,\n ContextsWithExecutorsResponseData,\n UploadBlobRequest,\n UploadBlobResponseData,\n DeleteBlobResponseData,\n ListBlobsResponseData,\n GetBlobResponseData,\n CreateAliasRequest,\n CreateAliasResponseData,\n LookupAliasResponseData,\n DeleteAliasResponseData,\n ListAliasesResponseData,\n ListContextIdentityAliasesResponseData,\n CreateContextIdentityAliasResponseData,\n LookupContextIdentityAliasResponseData,\n DeleteContextIdentityAliasResponseData,\n ListNamespacesResponseData,\n CreateNamespaceRequest,\n CreateNamespaceResponseData,\n DeleteNamespaceRequest,\n DeleteNamespaceResponseData,\n CreateNamespaceInvitationRequest,\n CreateNamespaceInvitationResponseData,\n CreateRecursiveInvitationResponseData,\n JoinNamespaceRequest,\n JoinNamespaceResponseData,\n CreateGroupInNamespaceRequest,\n CreateGroupInNamespaceResponseData,\n SubgroupEntry,\n Namespace,\n NamespaceIdentity,\n GroupInfoResponseData,\n DeleteGroupRequest,\n DeleteGroupResponseData,\n ListGroupMembersResponseData,\n ListGroupContextsResponseData,\n AddGroupMembersRequest,\n RemoveGroupMembersRequest,\n UpdateMemberRoleRequest,\n MemberCapabilities,\n SetMemberCapabilitiesRequest,\n SetDefaultCapabilitiesRequest,\n SetSubgroupVisibilityRequest,\n SetTeeAdmissionPolicyRequest,\n UpdateGroupSettingsRequest,\n SetGroupMetadataRequest,\n SetMemberMetadataRequest,\n SetContextMetadataRequest,\n MetadataRecord,\n GetMetadataResponseData,\n SyncGroupRequest,\n SyncGroupResponseData,\n RegisterGroupSigningKeyRequest,\n RegisterGroupSigningKeyResponseData,\n UpgradeGroupRequest,\n UpgradeGroupResponseData,\n GroupUpgradeStatusResponseData,\n MigrationStatus,\n CascadeStatusEntry,\n RetryGroupUpgradeRequest,\n RetryGroupUpgradeResponseData,\n NestGroupRequest,\n UnnestGroupRequest,\n DetachContextFromGroupRequest,\n CreateGroupInvitationRequest,\n CreateGroupInvitationResponseData,\n CreateRecursiveGroupInvitationResponseData,\n JoinGroupRequest,\n JoinGroupResponseData,\n TeeInfoResponseData,\n TeeAttestRequest,\n TeeAttestResponseData,\n TeeVerifyQuoteRequest,\n TeeVerifyQuoteResponseData,\n} from './admin-types';\n\n/**\n * Helper: server wraps most responses in `{ data: T }`.\n * This extracts `.data` so callers get the inner payload directly.\n */\nfunction unwrap<T>(response: { data: T }): T {\n return response.data;\n}\n\n/**\n * Compare two dotted version strings, ascending: negative if `a < b`, positive\n * if `a > b`, `0` if equal. Components are compared numerically when both parse\n * as integers (so `1.10.0 > 1.9.0`), else lexically; a missing component is `0`.\n * Minimal by design \u2014 sufficient for the `major.minor.patch` registry versions.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.');\n const pb = b.split('.');\n const n = Math.max(pa.length, pb.length);\n for (let i = 0; i < n; i++) {\n const sa = pa[i] ?? '0';\n const sb = pb[i] ?? '0';\n const na = Number.parseInt(sa, 10);\n const nb = Number.parseInt(sb, 10);\n if (Number.isNaN(na) || Number.isNaN(nb)) {\n const c = sa.localeCompare(sb);\n if (c !== 0) return c;\n } else if (na !== nb) {\n return na - nb;\n }\n }\n return 0;\n}\n\nexport class AdminApiClient {\n constructor(private httpClient: HttpClient) {}\n\n // ---- Health and Status (public, no auth) ----\n\n async healthCheck(): Promise<HealthStatus> {\n return unwrap(await this.httpClient.get<{ data: HealthStatus }>('/admin-api/health'));\n }\n\n async isAuthed(): Promise<AdminAuthStatus> {\n return this.httpClient.get<AdminAuthStatus>('/admin-api/is-authed');\n }\n\n // ---- Application Management ----\n\n async installApplication(request: InstallApplicationRequest): Promise<InstallApplicationResponseData> {\n return unwrap(await this.httpClient.post<{ data: InstallApplicationResponseData }>('/admin-api/install-application', request));\n }\n\n /**\n * Resolve a `package@version` to its registry artifact URL and install it.\n * Node install is URL-based (no node-side package+version resolution), so this\n * fetches the bundle manifest from the registry, derives the `.mpk` artifact\n * URL, then calls {@link installApplication}. `registryUrl` is the registry\n * origin. This is the discrete \"download\" step an Updates flow pairs with a\n * subsequent `upgradeGroup`.\n */\n async installFromRegistry(\n registryUrl: string,\n packageName: string,\n version: string,\n ): Promise<InstallApplicationResponseData> {\n const base = new URL(registryUrl).origin;\n const manifestUrl = new URL(\n `/api/v2/bundles/${encodeURIComponent(packageName)}/${encodeURIComponent(version)}`,\n base,\n ).toString();\n const resp = await fetch(manifestUrl);\n if (!resp.ok) {\n throw new Error(\n `registry manifest fetch failed (${resp.status}) for ${packageName}@${version}`,\n );\n }\n const bundle = (await resp.json()) as RegistryBundleManifest;\n // Encode the path segments \u2014 the package/version come from a (best-effort\n // trusted) registry response, so guard against odd characters breaking or\n // traversing the artifact path. For normal ids/semvers this is a no-op.\n const pkg = encodeURIComponent(bundle.package);\n const ver = encodeURIComponent(bundle.appVersion);\n const artifactUrl = `${base}/artifacts/${pkg}/${ver}/${pkg}-${ver}.mpk`;\n return this.installApplication({\n url: artifactUrl,\n package: bundle.package,\n version: bundle.appVersion,\n metadata: [],\n });\n }\n\n /**\n * List a package's published versions from the registry, newest-first by\n * semver. Reads the registry's V2 bundle listing\n * (`GET {registry}/api/v2/bundles?package={package}`), taking each bundle's\n * `appVersion`. Registry-side data \u2014 distinct from the node's\n * installed-version list \u2014 and the source an Updates view compares against\n * the running `Context.applicationVersion` to detect \"a new version exists\".\n */\n async getRegistryVersions(registryUrl: string, packageName: string): Promise<string[]> {\n const url = new URL('/api/v2/bundles', new URL(registryUrl).origin);\n url.searchParams.set('package', packageName);\n const resp = await fetch(url.toString());\n if (!resp.ok) {\n throw new Error(\n `registry versions fetch failed (${resp.status}) for ${packageName}`,\n );\n }\n const bundles = (await resp.json()) as RegistryBundleManifest[];\n return (Array.isArray(bundles) ? bundles : [])\n .map((b) => b.appVersion)\n .filter((v): v is string => typeof v === 'string')\n .sort((a, b) => compareSemver(b, a));\n }\n\n async installDevApplication(request: InstallDevApplicationRequest): Promise<InstallApplicationResponseData> {\n return unwrap(await this.httpClient.post<{ data: InstallApplicationResponseData }>('/admin-api/install-dev-application', request));\n }\n\n async uninstallApplication(appId: string): Promise<UninstallApplicationResponseData> {\n return unwrap(await this.httpClient.delete<{ data: UninstallApplicationResponseData }>(`/admin-api/applications/${appId}`));\n }\n\n async listApplications(): Promise<ListApplicationsResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListApplicationsResponseData }>('/admin-api/applications'));\n }\n\n async getApplication(appId: string): Promise<GetApplicationResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetApplicationResponseData }>(`/admin-api/applications/${appId}`));\n }\n\n // ---- Package Management ----\n\n async listPackages(): Promise<ListPackagesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListPackagesResponseData }>('/admin-api/packages'));\n }\n\n async listPackageVersions(packageName: string): Promise<ListVersionsResponseData> {\n return unwrap(\n await this.httpClient.get<{ data: ListVersionsResponseData }>(\n `/admin-api/packages/${encodeURIComponent(packageName)}/versions`,\n ),\n );\n }\n\n async getLatestPackageVersion(packageName: string): Promise<GetLatestVersionResponseData> {\n return this.httpClient.get<GetLatestVersionResponseData>(\n `/admin-api/packages/${encodeURIComponent(packageName)}/latest`,\n );\n }\n\n // ---- Context Management ----\n\n async createContext(request: CreateContextRequest): Promise<CreateContextResponseData> {\n return unwrap(await this.httpClient.post<{ data: CreateContextResponseData }>('/admin-api/contexts', request));\n }\n\n async deleteContext(contextId: string, request?: DeleteContextRequest): Promise<DeleteContextResponseData> {\n if (request) {\n return unwrap(\n await this.httpClient.request<{ data: DeleteContextResponseData }>(`/admin-api/contexts/${contextId}`, {\n method: 'DELETE',\n body: JSON.stringify(request),\n headers: { 'Content-Type': 'application/json' },\n }),\n );\n }\n return unwrap(await this.httpClient.delete<{ data: DeleteContextResponseData }>(`/admin-api/contexts/${contextId}`));\n }\n\n async getContexts(): Promise<GetContextsResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetContextsResponseData }>('/admin-api/contexts'));\n }\n\n async getContext(contextId: string): Promise<Context> {\n return unwrap(await this.httpClient.get<{ data: Context }>(`/admin-api/contexts/${contextId}`));\n }\n\n async getContextsForApplication(applicationId: string): Promise<GetContextsResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetContextsResponseData }>(`/admin-api/contexts/for-application/${applicationId}`));\n }\n\n // ---- Context Identity ----\n\n async generateContextIdentity(): Promise<GenerateContextIdentityResponseData> {\n return unwrap(await this.httpClient.post<{ data: GenerateContextIdentityResponseData }>('/admin-api/identity/context', {}));\n }\n\n async getContextIdentities(contextId: string): Promise<GetContextIdentitiesResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetContextIdentitiesResponseData }>(`/admin-api/contexts/${contextId}/identities`));\n }\n\n async getContextIdentitiesOwned(contextId: string): Promise<GetContextIdentitiesResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetContextIdentitiesResponseData }>(`/admin-api/contexts/${contextId}/identities-owned`));\n }\n\n // ---- Context join (group membership) ----\n\n async joinContext(contextId: string): Promise<JoinContextResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: JoinContextResponseData }>(`/admin-api/contexts/${contextId}/join`, {}),\n );\n }\n\n // ---- Context group / storage / sync ----\n\n async getContextGroup(contextId: string): Promise<ContextGroupResponseData> {\n return unwrap(await this.httpClient.get<{ data: ContextGroupResponseData }>(`/admin-api/contexts/${contextId}/group`));\n }\n\n async getContextStorage(contextId: string): Promise<ContextStorageResponseData> {\n return unwrap(await this.httpClient.get<{ data: ContextStorageResponseData }>(`/admin-api/contexts/${contextId}/storage`));\n }\n\n async syncContext(contextId?: string): Promise<void> {\n await this.httpClient.post(`/admin-api/contexts/sync/${contextId ?? ''}`, {});\n }\n\n async inviteSpecializedNode(request: InviteSpecializedNodeRequest): Promise<InviteSpecializedNodeResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: InviteSpecializedNodeResponseData }>(\n '/admin-api/contexts/invite-specialized-node',\n request,\n ),\n );\n }\n\n async updateContextApplication(\n contextId: string,\n request: UpdateContextApplicationRequest,\n ): Promise<void> {\n await this.httpClient.post(`/admin-api/contexts/${contextId}/application`, request);\n }\n\n async getContextsWithExecutorsForApplication(applicationId: string): Promise<ContextsWithExecutorsResponseData> {\n return unwrap(\n await this.httpClient.get<{ data: ContextsWithExecutorsResponseData }>(\n `/admin-api/contexts/with-executors/for-application/${applicationId}`,\n ),\n );\n }\n\n // ---- Blob Management ----\n\n async uploadBlob(data: UploadBlobRequest): Promise<UploadBlobResponseData> {\n return unwrap(await this.httpClient.put<{ data: UploadBlobResponseData }>('/admin-api/blobs', data));\n }\n\n async deleteBlob(blobId: string): Promise<DeleteBlobResponseData> {\n return unwrap(await this.httpClient.delete<{ data: DeleteBlobResponseData }>(`/admin-api/blobs/${blobId}`));\n }\n\n async listBlobs(): Promise<ListBlobsResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListBlobsResponseData }>('/admin-api/blobs'));\n }\n\n async getBlob(blobId: string): Promise<GetBlobResponseData> {\n return unwrap(await this.httpClient.get<{ data: GetBlobResponseData }>(`/admin-api/blobs/${blobId}`));\n }\n\n // ---- Alias Management ----\n\n async createContextAlias(request: CreateAliasRequest): Promise<CreateAliasResponseData> {\n return unwrap(await this.httpClient.post<{ data: CreateAliasResponseData }>('/admin-api/alias/create/context', request));\n }\n\n async createApplicationAlias(request: CreateAliasRequest): Promise<CreateAliasResponseData> {\n return unwrap(await this.httpClient.post<{ data: CreateAliasResponseData }>('/admin-api/alias/create/application', request));\n }\n\n async lookupContextAlias(name: string): Promise<LookupAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: LookupAliasResponseData }>(\n `/admin-api/alias/lookup/context/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async lookupApplicationAlias(name: string): Promise<LookupAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: LookupAliasResponseData }>(\n `/admin-api/alias/lookup/application/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async deleteContextAlias(name: string): Promise<DeleteAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: DeleteAliasResponseData }>(\n `/admin-api/alias/delete/context/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async deleteApplicationAlias(name: string): Promise<DeleteAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: DeleteAliasResponseData }>(\n `/admin-api/alias/delete/application/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async listContextAliases(): Promise<ListAliasesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListAliasesResponseData }>('/admin-api/alias/list/context'));\n }\n\n async listApplicationAliases(): Promise<ListAliasesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListAliasesResponseData }>('/admin-api/alias/list/application'));\n }\n\n // ---- Context Identity Aliases ----\n\n async listContextIdentityAliases(contextId: string): Promise<ListContextIdentityAliasesResponseData> {\n return unwrap(\n await this.httpClient.get<{ data: ListContextIdentityAliasesResponseData }>(\n `/admin-api/alias/list/identity/${contextId}`,\n ),\n );\n }\n\n async createContextIdentityAlias(\n contextId: string,\n request: CreateAliasRequest,\n ): Promise<CreateContextIdentityAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: CreateContextIdentityAliasResponseData }>(\n `/admin-api/alias/create/identity/${contextId}`,\n request,\n ),\n );\n }\n\n async lookupContextIdentityAlias(\n contextId: string,\n name: string,\n ): Promise<LookupContextIdentityAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: LookupContextIdentityAliasResponseData }>(\n `/admin-api/alias/lookup/identity/${contextId}/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n async deleteContextIdentityAlias(\n contextId: string,\n name: string,\n ): Promise<DeleteContextIdentityAliasResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: DeleteContextIdentityAliasResponseData }>(\n `/admin-api/alias/delete/identity/${contextId}/${encodeURIComponent(name)}`,\n {},\n ),\n );\n }\n\n // ---- Namespace Management ----\n\n async listNamespaces(): Promise<ListNamespacesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListNamespacesResponseData }>('/admin-api/namespaces'));\n }\n\n async getNamespace(namespaceId: string): Promise<Namespace> {\n return unwrap(await this.httpClient.get<{ data: Namespace }>(`/admin-api/namespaces/${namespaceId}`));\n }\n\n async getNamespaceIdentity(namespaceId: string): Promise<NamespaceIdentity> {\n return unwrap(await this.httpClient.get<{ data: NamespaceIdentity }>(`/admin-api/namespaces/${namespaceId}/identity`));\n }\n\n async listNamespacesForApplication(applicationId: string): Promise<ListNamespacesResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListNamespacesResponseData }>(`/admin-api/namespaces/for-application/${applicationId}`));\n }\n\n async createNamespace(request: CreateNamespaceRequest): Promise<CreateNamespaceResponseData> {\n return unwrap(await this.httpClient.post<{ data: CreateNamespaceResponseData }>('/admin-api/namespaces', request));\n }\n\n async deleteNamespace(\n namespaceId: string,\n request?: DeleteNamespaceRequest,\n ): Promise<DeleteNamespaceResponseData> {\n return unwrap(\n await this.httpClient.request<{ data: DeleteNamespaceResponseData }>(`/admin-api/namespaces/${namespaceId}`, {\n method: 'DELETE',\n body: request ? JSON.stringify(request) : undefined,\n headers: request ? { 'Content-Type': 'application/json' } : undefined,\n }),\n );\n }\n\n async createNamespaceInvitation(\n namespaceId: string,\n request?: CreateNamespaceInvitationRequest,\n ): Promise<CreateNamespaceInvitationResponseData | CreateRecursiveInvitationResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: CreateNamespaceInvitationResponseData | CreateRecursiveInvitationResponseData }>(\n `/admin-api/namespaces/${namespaceId}/invite`,\n request ?? {},\n ),\n );\n }\n\n async joinNamespace(\n namespaceId: string,\n request: JoinNamespaceRequest,\n ): Promise<JoinNamespaceResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: JoinNamespaceResponseData }>(\n `/admin-api/namespaces/${namespaceId}/join`,\n request,\n { timeoutMs: 65000 },\n ),\n );\n }\n\n async createGroupInNamespace(\n namespaceId: string,\n request?: CreateGroupInNamespaceRequest,\n ): Promise<CreateGroupInNamespaceResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: CreateGroupInNamespaceResponseData }>(\n `/admin-api/namespaces/${namespaceId}/groups`,\n request ?? {},\n ),\n );\n }\n\n async listNamespaceGroups(namespaceId: string): Promise<SubgroupEntry[]> {\n return unwrap(await this.httpClient.get<{ data: SubgroupEntry[] }>(`/admin-api/namespaces/${namespaceId}/groups`));\n }\n\n // ---- Group Management ----\n\n async getGroupInfo(groupId: string): Promise<GroupInfoResponseData> {\n return unwrap(await this.httpClient.get<{ data: GroupInfoResponseData }>(`/admin-api/groups/${groupId}`));\n }\n\n /** Thin wrapper over {@link getGroupInfo}: returns the group's `defaultCapabilities` bitmask. */\n async getDefaultCapabilities(groupId: string): Promise<number> {\n return (await this.getGroupInfo(groupId)).defaultCapabilities;\n }\n\n /** Thin wrapper over {@link getGroupInfo}: returns the group's `subgroupVisibility`. */\n async getSubgroupVisibility(groupId: string): Promise<string> {\n return (await this.getGroupInfo(groupId)).subgroupVisibility;\n }\n\n async deleteGroup(groupId: string, request?: DeleteGroupRequest): Promise<DeleteGroupResponseData> {\n if (request) {\n return unwrap(\n await this.httpClient.request<{ data: DeleteGroupResponseData }>(`/admin-api/groups/${groupId}`, {\n method: 'DELETE',\n body: JSON.stringify(request),\n headers: { 'Content-Type': 'application/json' },\n }),\n );\n }\n return unwrap(await this.httpClient.delete<{ data: DeleteGroupResponseData }>(`/admin-api/groups/${groupId}`));\n }\n\n async listGroupMembers(groupId: string): Promise<ListGroupMembersResponseData> {\n const response = await this.httpClient.get<ListGroupMembersResponseData>(\n `/admin-api/groups/${groupId}/members`,\n );\n // Validate the field we declare as non-optional in the type so a\n // contract-violating response (proxy error body, future API drift,\n // etc.) surfaces as a clear error rather than silently producing an\n // empty list. Empty groups still satisfy this \u2014 merod returns\n // `members: []`, not an omitted field.\n if (!Array.isArray(response?.members)) {\n // Sanitize before interpolation: groupId reaches us from caller code,\n // not parsed input, but defending the message keeps untrusted bytes\n // out of error logs and downstream UIs.\n const safeId = String(groupId).replace(/[\\r\\n\\t\\s]/g, '').slice(0, 64);\n throw new Error(\n `Invalid listGroupMembers response for group ${safeId}: missing or non-array \\`members\\` field`,\n );\n }\n return response;\n }\n\n async listGroupContexts(groupId: string): Promise<ListGroupContextsResponseData> {\n return unwrap(await this.httpClient.get<{ data: ListGroupContextsResponseData }>(`/admin-api/groups/${groupId}/contexts`));\n }\n\n async addGroupMembers(groupId: string, request: AddGroupMembersRequest): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${groupId}/members`, request);\n }\n\n async removeGroupMembers(groupId: string, request: RemoveGroupMembersRequest): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${groupId}/members/remove`, request);\n }\n\n async updateMemberRole(\n groupId: string,\n identity: string,\n request: UpdateMemberRoleRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/role`, request);\n }\n\n async getMemberCapabilities(groupId: string, identity: string): Promise<MemberCapabilities> {\n return unwrap(\n await this.httpClient.get<{ data: MemberCapabilities }>(\n `/admin-api/groups/${groupId}/members/${identity}/capabilities`,\n ),\n );\n }\n\n async setMemberCapabilities(\n groupId: string,\n identity: string,\n request: SetMemberCapabilitiesRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/capabilities`, request);\n }\n\n async setDefaultCapabilities(\n groupId: string,\n request: SetDefaultCapabilitiesRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/settings/default-capabilities`, request);\n }\n\n async setSubgroupVisibility(\n groupId: string,\n request: SetSubgroupVisibilityRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/settings/subgroup-visibility`, request);\n }\n\n async setTeeAdmissionPolicy(\n groupId: string,\n request: SetTeeAdmissionPolicyRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/settings/tee-admission-policy`, request);\n }\n\n async updateGroupSettings(\n groupId: string,\n request: UpdateGroupSettingsRequest,\n ): Promise<void> {\n await this.httpClient.patch(`/admin-api/groups/${groupId}`, request);\n }\n\n // ---- Group / member / context metadata ----\n\n async setGroupMetadata(groupId: string, request: SetGroupMetadataRequest): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/metadata`, request);\n }\n\n async getGroupMetadata(groupId: string): Promise<MetadataRecord | null> {\n // Server sends `{ data: null }` when no metadata is set, so the unwrapped\n // payload can be null \u2014 guard the trailing `.data` (else it throws\n // \"Cannot read properties of null (reading 'data')\").\n return unwrap(await this.httpClient.get<{ data: GetMetadataResponseData | null }>(`/admin-api/groups/${groupId}/metadata`))?.data ?? null;\n }\n\n async setMemberMetadata(\n groupId: string,\n identity: string,\n request: SetMemberMetadataRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/members/${identity}/metadata`, request);\n }\n\n async getMemberMetadata(groupId: string, identity: string): Promise<MetadataRecord | null> {\n // `{ data: null }` when no metadata (e.g. no display name set) \u2192 the\n // unwrapped payload is null; guard the trailing `.data`.\n return unwrap(\n await this.httpClient.get<{ data: GetMetadataResponseData | null }>(`/admin-api/groups/${groupId}/members/${identity}/metadata`),\n )?.data ?? null;\n }\n\n async setContextMetadata(\n groupId: string,\n contextId: string,\n request: SetContextMetadataRequest,\n ): Promise<void> {\n await this.httpClient.put(`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`, request);\n }\n\n async getContextMetadata(groupId: string, contextId: string): Promise<MetadataRecord | null> {\n // `{ data: null }` when no metadata \u2192 the unwrapped payload is null; guard\n // the trailing `.data`.\n return unwrap(\n await this.httpClient.get<{ data: GetMetadataResponseData | null }>(`/admin-api/groups/${groupId}/contexts/${contextId}/metadata`),\n )?.data ?? null;\n }\n\n async syncGroup(groupId: string, request?: SyncGroupRequest): Promise<SyncGroupResponseData> {\n return unwrap(await this.httpClient.post<{ data: SyncGroupResponseData }>(`/admin-api/groups/${groupId}/sync`, request ?? {}));\n }\n\n async registerGroupSigningKey(\n groupId: string,\n request: RegisterGroupSigningKeyRequest,\n ): Promise<RegisterGroupSigningKeyResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: RegisterGroupSigningKeyResponseData }>(\n `/admin-api/groups/${groupId}/signing-key`,\n request,\n ),\n );\n }\n\n async upgradeGroup(groupId: string, request: UpgradeGroupRequest): Promise<UpgradeGroupResponseData> {\n return unwrap(await this.httpClient.post<{ data: UpgradeGroupResponseData }>(`/admin-api/groups/${groupId}/upgrade`, request));\n }\n\n async getGroupUpgradeStatus(groupId: string): Promise<GroupUpgradeStatusResponseData> {\n return unwrap(\n await this.httpClient.get<{ data: GroupUpgradeStatusResponseData }>(`/admin-api/groups/${groupId}/upgrade/status`),\n );\n }\n\n /**\n * The operator-facing \"have all peers migrated?\" rollup for a namespace.\n * The handler serializes the payload directly, so there is no `{ data }`\n * envelope to unwrap here (unlike most admin reads).\n */\n async getMigrationStatus(namespaceId: string): Promise<MigrationStatus> {\n const id = encodeURIComponent(namespaceId);\n return this.httpClient.get<MigrationStatus>(`/admin-api/groups/${id}/migration-status`);\n }\n\n /** Per-group cascade-migration snapshots for a namespace. */\n async getCascadeStatus(namespaceId: string): Promise<CascadeStatusEntry[]> {\n const id = encodeURIComponent(namespaceId);\n return unwrap(\n await this.httpClient.get<{ data: CascadeStatusEntry[] }>(`/admin-api/groups/${id}/cascade-status`),\n );\n }\n\n async retryGroupUpgrade(\n groupId: string,\n request?: RetryGroupUpgradeRequest,\n ): Promise<RetryGroupUpgradeResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: RetryGroupUpgradeResponseData }>(\n `/admin-api/groups/${groupId}/upgrade/retry`,\n request ?? {},\n ),\n );\n }\n\n async nestGroup(parentGroupId: string, request: NestGroupRequest): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${parentGroupId}/nest`, request);\n }\n\n async unnestGroup(parentGroupId: string, request: UnnestGroupRequest): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${parentGroupId}/unnest`, request);\n }\n\n async listSubgroups(groupId: string): Promise<SubgroupEntry[]> {\n const response = await this.httpClient.get<{ subgroups?: SubgroupEntry[]; data?: SubgroupEntry[] }>(\n `/admin-api/groups/${groupId}/subgroups`,\n );\n return response.subgroups ?? response.data ?? [];\n }\n\n async detachContextFromGroup(\n groupId: string,\n contextId: string,\n request?: DetachContextFromGroupRequest,\n ): Promise<void> {\n await this.httpClient.post(`/admin-api/groups/${groupId}/contexts/${contextId}/remove`, request ?? {});\n }\n\n // ---- Group Invitation & Join ----\n\n async createGroupInvitation(\n groupId: string,\n request?: CreateGroupInvitationRequest,\n ): Promise<CreateGroupInvitationResponseData | CreateRecursiveGroupInvitationResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: CreateGroupInvitationResponseData | CreateRecursiveGroupInvitationResponseData }>(\n `/admin-api/groups/${groupId}/invite`,\n request ?? {},\n ),\n );\n }\n\n async joinGroup(request: JoinGroupRequest): Promise<JoinGroupResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: JoinGroupResponseData }>('/admin-api/groups/join', request),\n );\n }\n\n async joinSubgroupInheritance(groupId: string): Promise<JoinSubgroupInheritanceResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: JoinSubgroupInheritanceResponseData }>(\n `/admin-api/groups/${groupId}/join-via-inheritance`,\n {},\n ),\n );\n }\n\n // ---- TEE ----\n\n async getTeeInfo(): Promise<TeeInfoResponseData> {\n return unwrap(await this.httpClient.get<{ data: TeeInfoResponseData }>('/admin-api/tee/info'));\n }\n\n async teeAttest(request: TeeAttestRequest): Promise<TeeAttestResponseData> {\n return unwrap(await this.httpClient.post<{ data: TeeAttestResponseData }>('/admin-api/tee/attest', request));\n }\n\n async teeVerifyQuote(request: TeeVerifyQuoteRequest): Promise<TeeVerifyQuoteResponseData> {\n return unwrap(\n await this.httpClient.post<{ data: TeeVerifyQuoteResponseData }>('/admin-api/tee/verify-quote', request),\n );\n }\n\n // ---- Network ----\n\n async getPeersCount(): Promise<{ count: number }> {\n return this.httpClient.get<{ count: number }>('/admin-api/peers');\n }\n}\n", "import { AdminApiClient } from './admin-client';\nimport { AdminApiClientConfig } from './admin-types';\nimport { HttpClient } from '../http-client';\n\n// Mock HTTP client for testing\nclass MockHttpClient implements HttpClient {\n async get<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async post<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async put<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async delete<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async patch<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async head(): Promise<{ headers: Record<string, string>; status: number }> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n async request<T>(): Promise<T> {\n throw new Error(\n 'HTTP client not implemented - use createAdminApiClientFromHttpClient with a real HTTP client',\n );\n }\n}\n\n// Factory functions for creating Admin API clients\nexport function createBrowserAdminApiClient(\n _config: AdminApiClientConfig,\n): AdminApiClient {\n const httpClient = new MockHttpClient();\n return new AdminApiClient(httpClient);\n}\n\nexport function createNodeAdminApiClient(\n _config: AdminApiClientConfig,\n): AdminApiClient {\n const httpClient = new MockHttpClient();\n return new AdminApiClient(httpClient);\n}\n\nexport function createAdminApiClient(\n _config: AdminApiClientConfig,\n): AdminApiClient {\n const httpClient = new MockHttpClient();\n return new AdminApiClient(httpClient);\n}\n\nexport function createAdminApiClientFromHttpClient(\n httpClient: HttpClient,\n _config: AdminApiClientConfig,\n): AdminApiClient {\n return new AdminApiClient(httpClient);\n}\n", "export interface AuthCallbackResult {\n accessToken: string;\n refreshToken: string;\n applicationId: string;\n contextId: string;\n contextIdentity: string;\n nodeUrl: string;\n}\n\nexport interface AuthLoginOptions {\n callbackUrl: string;\n packageName?: string;\n mode: string;\n permissions?: string[];\n registryUrl?: string;\n packageVersion?: string;\n}\n\n/**\n * Parse an auth callback URL hash fragment.\n * Returns null if access_token is missing.\n */\nexport function parseAuthCallback(url: string): AuthCallbackResult | null {\n try {\n const hashIndex = url.indexOf('#');\n if (hashIndex === -1) return null;\n\n const hash = url.substring(hashIndex + 1);\n const params = new URLSearchParams(hash);\n\n const accessToken = params.get('access_token');\n if (!accessToken) return null;\n\n return {\n accessToken,\n refreshToken: params.get('refresh_token') ?? '',\n applicationId: params.get('application_id') ?? '',\n contextId: params.get('context_id') ?? '',\n contextIdentity: params.get('context_identity') ?? '',\n nodeUrl: params.get('node_url') ?? '',\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Build the auth login URL for redirecting users to the node's auth page.\n */\nexport function buildAuthLoginUrl(nodeUrl: string, opts: AuthLoginOptions): string {\n const params = new URLSearchParams();\n params.set('callback-url', opts.callbackUrl);\n\n if (opts.permissions && opts.permissions.length > 0) {\n params.set('permissions', opts.permissions.join(','));\n }\n\n params.set('mode', opts.mode);\n\n if (opts.packageName) {\n params.set('package-name', opts.packageName);\n if (opts.packageVersion) {\n params.set('package-version', opts.packageVersion);\n }\n if (opts.registryUrl) {\n params.set('registry-url', opts.registryUrl);\n }\n }\n\n // Trim trailing slash from nodeUrl\n const base = nodeUrl.replace(/\\/+$/, '');\n return `${base}/auth/login?${params.toString()}`;\n}\n", "import type { HttpClient } from '../http-client';\n\n/** Result of the owner-driven `migrate_my_entries` convert (counts are u32). */\nexport interface MigrateMyEntriesSummary {\n converted: number;\n remaining: number;\n}\n\nexport interface ExecuteParams {\n contextId: string;\n method: string;\n argsJson?: Record<string, unknown>;\n /** @deprecated No longer used by the server. Ignored if provided. */\n executorPublicKey?: string;\n}\n\nexport class RpcError extends Error {\n code: number;\n type?: string;\n data?: unknown;\n\n constructor(code: number, message: string, data?: unknown, type?: string) {\n super(message);\n this.name = 'RpcError';\n this.code = code;\n this.data = data;\n this.type = type;\n }\n}\n\ninterface JsonRpcResponse {\n jsonrpc: string;\n id: number;\n result?: {\n output?: unknown;\n [key: string]: unknown;\n };\n error?: {\n // Standard JSON-RPC fields\n code?: number;\n message?: string;\n // Server-specific fields\n type?: string;\n data?: unknown;\n };\n}\n\nexport class RpcClient {\n private httpClient: HttpClient;\n\n constructor(opts: { httpClient: HttpClient }) {\n this.httpClient = opts.httpClient;\n }\n\n async execute<T = unknown>(params: ExecuteParams): Promise<T> {\n const body = {\n jsonrpc: '2.0',\n id: 1,\n method: 'execute',\n params: {\n contextId: params.contextId,\n method: params.method,\n argsJson: params.argsJson ?? {},\n },\n };\n\n const response = await this.httpClient.post<JsonRpcResponse>(\n '/jsonrpc',\n body,\n );\n\n if (response.error) {\n const err = response.error;\n const code = err.code ?? -1;\n const message = err.message ?? err.type ?? 'RPC error';\n throw new RpcError(code, message, err.data, err.type);\n }\n\n if (response.result && 'output' in response.result) {\n return response.result.output as T;\n }\n\n return response.result as T;\n }\n\n /**\n * One-tap owner-driven convert: re-signs the caller's identity-gated entries\n * to the current schema. The export converts all of the caller's\n * below-target entries in a single sweep, so this issues one call and returns\n * the resulting summary \u2014 it does not loop.\n */\n async migrateMyEntries(contextId: string): Promise<MigrateMyEntriesSummary> {\n return this.execute<MigrateMyEntriesSummary>({ contextId, method: 'migrate_my_entries' });\n }\n\n /** Read-only count of the caller's entries still below the target schema. */\n async countMyPending(contextId: string): Promise<number> {\n return this.execute<number>({ contextId, method: 'count_my_pending' });\n }\n}\n", "export interface SseEventData {\n contextId: string;\n data: unknown;\n}\n\n/** Parsed `AppVersionChanged` context event (bundle-version flip; skew #2). */\nexport interface AppVersionChangedEvent {\n contextId: string;\n fromVersion?: string;\n toVersion?: string;\n}\n\ntype SseEventHandler = (event: SseEventData) => void;\ntype SseConnectHandler = (sessionId: string) => void;\ntype SseErrorHandler = (error: Error) => void;\n\ninterface SseListeners {\n connect: SseConnectHandler[];\n event: SseEventHandler[];\n error: SseErrorHandler[];\n}\n\nexport class SseClient {\n private baseUrl: string;\n private getAuthToken: () => Promise<string>;\n private reconnectDelayMs: number;\n private sessionId: string | null = null;\n private abortController: AbortController | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private subscribedContextIds: Set<string> = new Set();\n private closed = false;\n private listeners: SseListeners = { connect: [], event: [], error: [] };\n\n constructor(opts: {\n baseUrl: string;\n getAuthToken: () => Promise<string>;\n reconnectDelayMs?: number;\n }) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, '');\n this.getAuthToken = opts.getAuthToken;\n this.reconnectDelayMs = opts.reconnectDelayMs ?? 3000;\n }\n\n on(event: 'connect', handler: SseConnectHandler): void;\n on(event: 'event', handler: SseEventHandler): void;\n on(event: 'error', handler: SseErrorHandler): void;\n on(event: string, handler: SseConnectHandler | SseEventHandler | SseErrorHandler): void {\n const key = event as keyof SseListeners;\n if (key in this.listeners) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const arr = this.listeners[key] as any[];\n if (!arr.includes(handler)) arr.push(handler);\n }\n }\n\n off(event: 'connect', handler: SseConnectHandler): void;\n off(event: 'event', handler: SseEventHandler): void;\n off(event: 'error', handler: SseErrorHandler): void;\n off(event: string, handler: SseConnectHandler | SseEventHandler | SseErrorHandler): void {\n const key = event as keyof SseListeners;\n if (key in this.listeners) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const arr = this.listeners[key] as any[];\n const idx = arr.indexOf(handler);\n if (idx !== -1) arr.splice(idx, 1);\n }\n }\n\n /**\n * Typed convenience over the generic `'event'` stream: invokes `handler` only\n * for `AppVersionChanged` context events, with the payload already parsed.\n * Returns an unsubscribe closure (so callers need not retain the listener).\n */\n onAppVersionChanged(handler: (e: AppVersionChangedEvent) => void): () => void {\n const listener: SseEventHandler = (ev) => {\n const d = ev.data as\n | { type?: string; data?: { fromVersion?: string; toVersion?: string } }\n | undefined;\n if (d?.type !== 'AppVersionChanged') return;\n handler({ contextId: ev.contextId, fromVersion: d.data?.fromVersion, toVersion: d.data?.toVersion });\n };\n this.on('event', listener);\n return () => this.off('event', listener);\n }\n\n private emit(event: 'connect', sessionId: string): void;\n private emit(event: 'event', data: SseEventData): void;\n private emit(event: 'error', error: Error): void;\n private emit(event: string, arg?: string | SseEventData | Error): void {\n const key = event as keyof SseListeners;\n if (key in this.listeners) {\n for (const handler of this.listeners[key]) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (handler as any)(arg);\n } catch {\n // Swallow handler errors\n }\n }\n }\n }\n\n async connect(): Promise<void> {\n // Already connected \u2014 don't reconnect\n if (this.abortController && !this.closed) {\n return;\n }\n this.closed = false;\n this.abortController = new AbortController();\n\n try {\n const token = await this.getAuthToken();\n const response = await fetch(`${this.baseUrl}/sse`, {\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Accept': 'text/event-stream',\n },\n signal: this.abortController.signal,\n });\n\n if (!response.ok) {\n throw new Error(`SSE connection failed: ${response.status}`);\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body');\n }\n\n this.readStream(response.body).catch((err) => {\n if (this.closed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n this.scheduleReconnect();\n });\n } catch (err) {\n if (this.closed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n this.scheduleReconnect();\n }\n }\n\n private async readStream(body: ReadableStream<Uint8Array>): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split('\\n');\n // Keep the last partial line in the buffer\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data:')) {\n const jsonStr = line.slice(5).trim();\n if (jsonStr) {\n this.handleMessage(jsonStr);\n }\n }\n }\n }\n // Flush remaining bytes from the decoder\n buffer += decoder.decode();\n if (buffer.startsWith('data:')) {\n const jsonStr = buffer.slice(5).trim();\n if (jsonStr) {\n this.handleMessage(jsonStr);\n }\n }\n } catch (err) {\n if (this.closed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n }\n\n // Stream ended, reconnect\n if (!this.closed) {\n this.scheduleReconnect();\n }\n }\n\n private handleMessage(jsonStr: string): void {\n try {\n const msg = JSON.parse(jsonStr);\n\n // Connection message\n if (msg.type === 'connect' && msg.session_id) {\n this.sessionId = msg.session_id;\n this.emit('connect', msg.session_id);\n // Re-subscribe after reconnect\n if (this.subscribedContextIds.size > 0) {\n this.sendSubscription('subscribe', [...this.subscribedContextIds]);\n }\n return;\n }\n\n // Context event message\n if (msg.result && msg.result.contextId) {\n let eventData = msg.result.data;\n // Decode byte-array data if needed\n if (Array.isArray(eventData)) {\n try {\n const bytes = new Uint8Array(eventData);\n const text = new TextDecoder().decode(bytes);\n eventData = JSON.parse(text);\n } catch {\n // Keep raw data\n }\n }\n\n this.emit('event', {\n contextId: msg.result.contextId,\n data: eventData,\n });\n }\n } catch {\n // Invalid JSON, ignore\n }\n }\n\n async subscribe(contextIds: string[]): Promise<void> {\n const newIds = contextIds.filter(id => !this.subscribedContextIds.has(id));\n for (const id of contextIds) {\n this.subscribedContextIds.add(id);\n }\n if (newIds.length > 0 && this.sessionId) {\n await this.sendSubscription('subscribe', newIds);\n }\n }\n\n async unsubscribe(contextIds: string[]): Promise<void> {\n const hadIds = contextIds.filter(id => this.subscribedContextIds.has(id));\n for (const id of contextIds) {\n this.subscribedContextIds.delete(id);\n }\n if (hadIds.length > 0 && this.sessionId) {\n await this.sendSubscription('unsubscribe', hadIds);\n }\n }\n\n private async sendSubscription(method: 'subscribe' | 'unsubscribe', contextIds: string[]): Promise<void> {\n try {\n const token = await this.getAuthToken();\n const response = await fetch(`${this.baseUrl}/sse/subscription`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n id: this.sessionId,\n method,\n params: { contextIds },\n }),\n });\n if (!response.ok) {\n this.emit('error', new Error(`SSE ${method} failed: ${response.status}`));\n }\n } catch (err) {\n this.emit('error', err instanceof Error ? err : new Error(`SSE ${method} failed`));\n }\n }\n\n private forceReconnect(): void {\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n this.sessionId = null;\n this.connect();\n }\n\n private scheduleReconnect(): void {\n if (this.closed) return;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.forceReconnect();\n }, this.reconnectDelayMs);\n }\n\n close(): void {\n this.closed = true;\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.sessionId = null;\n this.subscribedContextIds.clear();\n }\n}\n", "export interface WsEventData {\n contextId: string;\n data: unknown;\n}\n\ntype WsEventHandler = (event: WsEventData) => void;\ntype WsConnectHandler = () => void;\ntype WsErrorHandler = (error: Error) => void;\n\ninterface WsListeners {\n connect: WsConnectHandler[];\n event: WsEventHandler[];\n error: WsErrorHandler[];\n}\n\n/**\n * @experimental WebSocket event client. The SSE client (`SseClient`) is the\n * recommended transport for production \u2014 use `MeroJs.events` instead of `MeroJs.ws`.\n */\nexport class WsClient {\n private baseUrl: string;\n private getAuthToken: () => Promise<string>;\n private ws: WebSocket | null = null;\n private closed = false;\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private subscribedContextIds: Set<string> = new Set();\n private listeners: WsListeners = { connect: [], event: [], error: [] };\n\n private static readonly MAX_BACKOFF_MS = 30000;\n\n constructor(opts: {\n baseUrl: string;\n getAuthToken: () => Promise<string>;\n }) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, '');\n this.getAuthToken = opts.getAuthToken;\n }\n\n on(event: 'connect', handler: WsConnectHandler): void;\n on(event: 'event', handler: WsEventHandler): void;\n on(event: 'error', handler: WsErrorHandler): void;\n on(event: string, handler: WsConnectHandler | WsEventHandler | WsErrorHandler): void {\n const key = event as keyof WsListeners;\n if (key in this.listeners) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const arr = this.listeners[key] as any[];\n if (!arr.includes(handler)) arr.push(handler);\n }\n }\n\n off(event: 'connect', handler: WsConnectHandler): void;\n off(event: 'event', handler: WsEventHandler): void;\n off(event: 'error', handler: WsErrorHandler): void;\n off(event: string, handler: WsConnectHandler | WsEventHandler | WsErrorHandler): void {\n const key = event as keyof WsListeners;\n if (key in this.listeners) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const arr = this.listeners[key] as any[];\n const idx = arr.indexOf(handler);\n if (idx !== -1) arr.splice(idx, 1);\n }\n }\n\n private emit(event: 'connect'): void;\n private emit(event: 'event', data: WsEventData): void;\n private emit(event: 'error', error: Error): void;\n private emit(event: string, arg?: WsEventData | Error): void {\n const key = event as keyof WsListeners;\n if (key in this.listeners) {\n for (const handler of this.listeners[key]) {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (handler as any)(arg);\n } catch {\n // Swallow handler errors\n }\n }\n }\n }\n\n async connect(): Promise<void> {\n if (this.ws && (this.ws.readyState === WebSocket.CONNECTING || this.ws.readyState === WebSocket.OPEN)) {\n return;\n }\n this.closed = false;\n\n try {\n const token = await this.getAuthToken();\n if (!token) {\n throw new Error('No authentication token available for WebSocket connection');\n }\n // Browser WebSocket API can't set headers, use query param\n const wsUrl = this.baseUrl.replace(/^http/, 'ws');\n this.ws = new WebSocket(`${wsUrl}/ws?token=${encodeURIComponent(token)}`);\n\n this.ws.onopen = () => {\n this.reconnectAttempt = 0;\n this.emit('connect');\n // Re-subscribe on reconnect\n if (this.subscribedContextIds.size > 0) {\n this.sendMessage({\n id: null,\n method: 'subscribe',\n params: { contextIds: [...this.subscribedContextIds] },\n });\n }\n };\n\n this.ws.onmessage = (event) => {\n this.handleMessage(event.data);\n };\n\n this.ws.onerror = () => {\n this.emit('error', new Error('WebSocket error'));\n };\n\n this.ws.onclose = () => {\n if (!this.closed) {\n this.scheduleReconnect();\n }\n };\n } catch (err) {\n if (this.closed) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.emit('error', error);\n this.scheduleReconnect();\n }\n }\n\n private handleMessage(raw: string | ArrayBuffer | Blob): void {\n if (typeof raw !== 'string') return;\n\n try {\n const msg = JSON.parse(raw);\n\n if (msg.result && msg.result.contextId) {\n let eventData = msg.result.data;\n if (Array.isArray(eventData)) {\n try {\n const bytes = new Uint8Array(eventData);\n const text = new TextDecoder().decode(bytes);\n eventData = JSON.parse(text);\n } catch {\n // Keep raw data\n }\n }\n\n this.emit('event', {\n contextId: msg.result.contextId,\n data: eventData,\n });\n }\n } catch {\n // Invalid JSON, ignore\n }\n }\n\n subscribe(contextIds: string[]): void {\n for (const id of contextIds) {\n this.subscribedContextIds.add(id);\n }\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.sendMessage({\n id: null,\n method: 'subscribe',\n params: { contextIds },\n });\n }\n }\n\n unsubscribe(contextIds: string[]): void {\n for (const id of contextIds) {\n this.subscribedContextIds.delete(id);\n }\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.sendMessage({\n id: null,\n method: 'unsubscribe',\n params: { contextIds },\n });\n }\n }\n\n private sendMessage(msg: unknown): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify(msg));\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed) return;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n }\n const delay = Math.min(\n 1000 * Math.pow(2, this.reconnectAttempt),\n WsClient.MAX_BACKOFF_MS,\n );\n this.reconnectAttempt++;\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.connect();\n }, delay);\n }\n\n close(): void {\n this.closed = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n if (this.ws) {\n this.ws.onclose = null;\n this.ws.close();\n this.ws = null;\n }\n this.subscribedContextIds.clear();\n }\n}\n", "import { createBrowserHttpClient } from './http-client';\nimport { createAuthApiClientFromHttpClient } from './auth-api';\nimport { createAdminApiClientFromHttpClient } from './admin-api';\nimport type { AuthApiClient } from './auth-api';\nimport type { AdminApiClient } from './admin-api';\nimport type { HttpClient } from './http-client';\nimport type { TokenStore } from './token-store';\nimport { parseAuthCallback, buildAuthLoginUrl } from './auth';\nimport type { AuthCallbackResult, AuthLoginOptions } from './auth';\nimport { RpcClient } from './rpc';\nimport { SseClient } from './events/sse';\nimport { WsClient } from './events/ws';\n\nexport interface MeroJsConfig {\n /** Base URL for the Calimero node */\n baseUrl: string;\n /** Initial credentials for authentication */\n credentials?: {\n username: string;\n password: string;\n };\n /** Custom HTTP client timeout in milliseconds */\n timeoutMs?: number;\n /** Request credentials mode for fetch (omit, same-origin, include) */\n requestCredentials?: RequestCredentials;\n /** Optional token store for persistence */\n tokenStore?: TokenStore;\n}\n\nexport interface TokenData {\n access_token: string;\n refresh_token: string;\n expires_at: number;\n}\n\n/** Try to extract `exp` (seconds) from a JWT, return ms timestamp or fallback. */\nfunction expiresAtFromJwt(token: string, fallbackMs: number): number {\n try {\n const parts = token.split('.');\n if (parts.length === 3) {\n // JWT uses base64url encoding: replace -/_ with +// and add padding\n let b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');\n while (b64.length % 4) b64 += '=';\n const payload = JSON.parse(atob(b64));\n if (typeof payload.exp === 'number') {\n return payload.exp * 1000;\n }\n }\n } catch {\n // not a JWT or can't parse\n }\n return fallbackMs;\n}\n\n/**\n * Main MeroJs SDK class that manages all API clients and authentication\n */\nexport class MeroJs {\n private config: MeroJsConfig;\n private httpClient: HttpClient;\n private authClient: AuthApiClient;\n private adminClient: AdminApiClient;\n private tokenData: TokenData | null = null;\n private refreshPromise: Promise<TokenData> | null = null;\n private tokenStore: TokenStore | null;\n private rpcClient: RpcClient | null = null;\n private sseClient: SseClient | null = null;\n private wsClient: WsClient | null = null;\n private wsWarned = false;\n\n constructor(config: MeroJsConfig) {\n this.config = {\n timeoutMs: 10000,\n ...config,\n };\n\n this.tokenStore = config.tokenStore ?? null;\n\n // Restore tokens from store if available\n if (this.tokenStore) {\n this.tokenData = this.tokenStore.getTokens();\n }\n\n // Create HTTP client with token management\n // For Tauri, explicitly set credentials to 'omit' to avoid network errors\n const isTauri = typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;\n this.httpClient = createBrowserHttpClient({\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n refreshToken: async () => {\n const refreshed = await this.performTokenRefresh();\n return refreshed.access_token;\n },\n onTokenRefresh: async (newToken: string) => {\n if (this.tokenData) {\n this.tokenData.access_token = newToken;\n this.tokenStore?.setTokens(this.tokenData);\n }\n },\n timeoutMs: this.config.timeoutMs,\n credentials: this.config.requestCredentials ?? (isTauri ? 'omit' : undefined),\n });\n\n // Create API clients\n this.authClient = createAuthApiClientFromHttpClient(this.httpClient, {\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n timeoutMs: this.config.timeoutMs,\n });\n\n this.adminClient = createAdminApiClientFromHttpClient(this.httpClient, {\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n timeoutMs: this.config.timeoutMs,\n });\n }\n\n /**\n * Get the Auth API client\n */\n get auth(): AuthApiClient {\n return this.authClient;\n }\n\n /**\n * Get the Admin API client\n */\n get admin(): AdminApiClient {\n return this.adminClient;\n }\n\n /**\n * Get the RPC client (lazy initialized)\n */\n get rpc(): RpcClient {\n if (!this.rpcClient) {\n this.rpcClient = new RpcClient({ httpClient: this.httpClient });\n }\n return this.rpcClient;\n }\n\n /**\n * Get the SSE event client (lazy initialized)\n */\n get events(): SseClient {\n if (!this.sseClient) {\n this.sseClient = new SseClient({\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n });\n }\n return this.sseClient;\n }\n\n /**\n * Get the WebSocket event client (lazy initialized).\n * @experimental Use `events` (SSE) for production. WsClient is experimental.\n */\n get ws(): WsClient {\n if (!this.wsWarned) {\n this.wsWarned = true;\n console.warn('[mero-js] WsClient is experimental. Use mero.events (SSE) for production.');\n }\n if (!this.wsClient) {\n this.wsClient = new WsClient({\n baseUrl: this.config.baseUrl,\n getAuthToken: async () => {\n const token = await this.getValidToken();\n return token?.access_token || '';\n },\n });\n }\n return this.wsClient;\n }\n\n /**\n * Authenticate with the provided credentials\n * This will create the root key on first use\n */\n async authenticate(credentials?: {\n username: string;\n password: string;\n }): Promise<TokenData> {\n const creds = credentials || this.config.credentials;\n if (!creds) {\n throw new Error('No credentials provided for authentication');\n }\n\n try {\n const requestBody = {\n auth_method: 'user_password',\n public_key: creds.username,\n client_name: 'mero-js-sdk',\n permissions: ['admin'],\n timestamp: Math.floor(Date.now() / 1000),\n provider_data: {\n username: creds.username,\n password: creds.password,\n },\n };\n\n const response = await this.authClient.generateTokens(requestBody);\n\n const accessToken = response.data.access_token;\n this.tokenData = {\n access_token: accessToken,\n refresh_token: response.data.refresh_token,\n expires_at: expiresAtFromJwt(accessToken, Date.now() + 3600_000),\n };\n\n this.tokenStore?.setTokens(this.tokenData);\n\n return this.tokenData;\n } catch (error) {\n throw new Error(\n `Authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Get a valid token. Returns the current token as-is.\n * The server rejects refresh attempts while the access token is still valid,\n * so we never proactively refresh. Instead, the WebHttpClient handles 401\n * responses reactively via the refreshToken transport hook.\n */\n private async getValidToken(): Promise<TokenData | null> {\n return this.tokenData;\n }\n\n /**\n * Refresh the access token using the refresh token\n */\n private async refreshToken(): Promise<TokenData> {\n if (!this.tokenData?.refresh_token) {\n throw new Error('No refresh token available');\n }\n\n // Prevent multiple simultaneous refresh attempts\n if (this.refreshPromise) {\n return this.refreshPromise;\n }\n\n this.refreshPromise = this.performTokenRefresh();\n\n try {\n const newToken = await this.refreshPromise;\n return newToken;\n } finally {\n this.refreshPromise = null;\n }\n }\n\n /**\n * Perform the actual token refresh\n */\n private async performTokenRefresh(): Promise<TokenData> {\n if (!this.tokenData?.refresh_token) {\n throw new Error('No refresh token available');\n }\n\n try {\n const response = await this.authClient.refreshToken({\n access_token: this.tokenData.access_token,\n refresh_token: this.tokenData.refresh_token,\n });\n\n const accessToken = response.data.access_token;\n this.tokenData = {\n access_token: accessToken,\n refresh_token: response.data.refresh_token,\n expires_at: expiresAtFromJwt(accessToken, Date.now() + 3600_000),\n };\n\n this.tokenStore?.setTokens(this.tokenData);\n\n return this.tokenData;\n } catch (error) {\n // Don't clear tokens on refresh failure \u2014 the access token may still be\n // valid (server rejects refresh while access token hasn't expired yet).\n // Let the caller handle the error.\n throw new Error(\n `Token refresh failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n );\n }\n }\n\n /**\n * Clear the current token\n */\n public clearToken(): void {\n this.tokenData = null;\n this.tokenStore?.clear();\n }\n\n /**\n * Check if the SDK is authenticated\n */\n public isAuthenticated(): boolean {\n return this.tokenData !== null;\n }\n\n /**\n * Set token data directly (e.g., from auth callback).\n * If `expires_at` is missing or 0, attempts to parse the JWT exp claim,\n * falling back to 1 hour from now.\n */\n public setTokenData(data: TokenData): void {\n const expiresAt = data.expires_at || expiresAtFromJwt(data.access_token, Date.now() + 3600_000);\n this.tokenData = { ...data, expires_at: expiresAt };\n this.tokenStore?.setTokens(this.tokenData);\n }\n\n /**\n * Get the current token data (for debugging)\n */\n public getTokenData(): TokenData | null {\n return this.tokenData;\n }\n\n /**\n * Close all event connections and clean up resources\n */\n public close(): void {\n this.sseClient?.close();\n this.wsClient?.close();\n }\n\n /**\n * Parse an auth callback URL hash fragment (static utility)\n */\n static parseAuthCallback(url: string): AuthCallbackResult | null {\n return parseAuthCallback(url);\n }\n\n /**\n * Build an auth login URL (static utility)\n */\n static buildAuthLoginUrl(nodeUrl: string, opts: AuthLoginOptions): string {\n return buildAuthLoginUrl(nodeUrl, opts);\n }\n}\n\n/**\n * Create a new MeroJs SDK instance\n */\nexport function createMeroJs(config: MeroJsConfig): MeroJs {\n return new MeroJs(config);\n}\n", "import type { TokenData } from '../mero-js';\n\nexport interface TokenStore {\n getTokens(): TokenData | null;\n setTokens(data: TokenData): void;\n clear(): void;\n}\n\nexport class MemoryTokenStore implements TokenStore {\n private tokens: TokenData | null = null;\n\n getTokens(): TokenData | null {\n return this.tokens;\n }\n\n setTokens(data: TokenData): void {\n this.tokens = data;\n }\n\n clear(): void {\n this.tokens = null;\n }\n}\n\nconst STORAGE_KEY = 'mero-tokens';\n\nexport class LocalStorageTokenStore implements TokenStore {\n private readonly key: string;\n\n constructor(key: string = STORAGE_KEY) {\n this.key = key;\n }\n\n getTokens(): TokenData | null {\n try {\n if (typeof localStorage === 'undefined') return null;\n const raw = localStorage.getItem(this.key);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (parsed && parsed.access_token && parsed.refresh_token) {\n return {\n access_token: parsed.access_token,\n refresh_token: parsed.refresh_token,\n expires_at: typeof parsed.expires_at === 'number' ? parsed.expires_at : Date.now() + 3600_000,\n };\n }\n return null;\n } catch {\n return null;\n }\n }\n\n setTokens(data: TokenData): void {\n try {\n if (typeof localStorage === 'undefined') return;\n localStorage.setItem(this.key, JSON.stringify(data));\n } catch {\n // Storage unavailable\n }\n }\n\n clear(): void {\n try {\n if (typeof localStorage === 'undefined') return;\n localStorage.removeItem(this.key);\n } catch {\n // Storage unavailable\n }\n }\n}\n", "export interface CloudClientConfig {\n cloudBaseUrl?: string;\n}\n\nexport interface EnableHAOptions {\n groupId: string;\n contextId: string;\n redirectUrl?: string;\n}\n\nexport interface DisableHAOptions {\n groupId: string;\n contextId: string;\n redirectUrl?: string;\n}\n\nexport class CloudClient {\n private baseUrl: string;\n\n constructor(config: CloudClientConfig = {}) {\n this.baseUrl = (config.cloudBaseUrl || 'https://cloud.calimero.network').replace(/\\/+$/, '');\n }\n\n enableHA(options: EnableHAOptions): void {\n const params = new URLSearchParams({\n group_id: options.groupId,\n context_id: options.contextId,\n });\n if (options.redirectUrl) {\n params.set('redirect_url', options.redirectUrl);\n }\n window.open(`${this.baseUrl}/enable-ha?${params.toString()}`);\n }\n\n disableHA(options: DisableHAOptions): void {\n const params = new URLSearchParams({\n group_id: options.groupId,\n context_id: options.contextId,\n });\n if (options.redirectUrl) {\n params.set('redirect_url', options.redirectUrl);\n }\n window.open(`${this.baseUrl}/disable-ha?${params.toString()}`);\n }\n}\n", "// Member capability bitmask constants \u2014 mirrors core's `MemberCapabilities`\n// (crates/context/config/src/lib.rs). The value stored per-member is a u32\n// bitmask. Core currently assigns bits 0..=8; bits 9 and above are unassigned\n// and may be claimed by future core versions, so an application MUST NOT\n// assume any particular bit is safe for its own use unless core documents it\n// as reserved for applications.\n\n/**\n * Capability bits as defined by core's `MemberCapabilities`.\n *\n * The per-member value is a u32 bitmask. Core currently assigns bits 0..=8\n * (the entries below); bits 9 and above are unassigned \u2014 do not repurpose\n * them for application data, as a future core release may claim them.\n */\nexport const CAPABILITIES = {\n CAN_CREATE_CONTEXT: 1 << 0,\n CAN_INVITE_MEMBERS: 1 << 1,\n CAN_JOIN_OPEN_SUBGROUPS: 1 << 2,\n MANAGE_MEMBERS: 1 << 3,\n MANAGE_APPLICATION: 1 << 4,\n CAN_CREATE_SUBGROUP: 1 << 5,\n CAN_DELETE_SUBGROUP: 1 << 6,\n CAN_MANAGE_VISIBILITY: 1 << 7,\n CAN_MANAGE_METADATA: 1 << 8,\n} as const;\n\nexport type CapabilityName = keyof typeof CAPABILITIES;\nexport type CapabilityBit = (typeof CAPABILITIES)[CapabilityName];\n\n/**\n * Returns true if `mask` has every bit of `cap` set. Both operands are\n * coerced to unsigned 32-bit (`>>> 0`) before comparing so a high bit such\n * as `1 << 31` doesn't fall foul of `&` yielding a signed result.\n */\nexport function hasCap(mask: number, cap: number): boolean {\n const capU32 = cap >>> 0;\n return ((mask & capU32) >>> 0) === capU32;\n}\n\n/** Returns `mask` with every bit of `cap` set (u32-normalized). */\nexport function withCap(mask: number, cap: number): number {\n return (mask | cap) >>> 0;\n}\n\n/** Returns `mask` with every bit of `cap` cleared (u32-normalized). */\nexport function withoutCap(mask: number, cap: number): number {\n return (mask & ~cap) >>> 0;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["combineSignals", "signals", "list", "AbortSignalAny", "controller", "onAbort", "evt", "s", "createTimeoutSignal", "timeoutMs", "HTTPError", "status", "statusText", "url", "headers", "bodyText", "headersToRecord", "record", "value", "key", "WebHttpClient", "transport", "path", "init", "body", "response", "retryCount", "requestStartTime", "startTime", "signal", "headersObj", "requestInit", "isStreamBody", "retrySignal", "timeoutMs", "elapsed", "remaining", "httpError", "userAborted", "refreshPromise", "newToken", "onTokenRefreshPromise", "refreshError", "error", "baseUrl", "signals", "createTimeoutSignal", "combineSignals", "initHeaders", "token", "parse", "text", "createHttpClient", "transport", "WebHttpClient", "createBrowserHttpClient", "options", "url", "init", "createNodeHttpClient", "fetchImpl", "createUniversalHttpClient", "defaultRetryCondition", "error", "attempt", "name", "errorWithStatus", "status", "calculateDelay", "delay", "jitter", "withRetry", "fn", "options", "attempts", "lastError", "delayMs", "retryAfter", "seconds", "date", "waitTime", "resolve", "createRetryableMethod", "method", "retryOptions", "args", "AuthApiClient", "httpClient", "response", "request", "token", "keyId", "clientId", "permissions", "MockHttpClient", "createBrowserAuthApiClient", "_config", "httpClient", "AuthApiClient", "createNodeAuthApiClient", "createAuthApiClient", "createAuthApiClientFromHttpClient", "unwrap", "response", "compareSemver", "a", "b", "pa", "pb", "i", "sa", "sb", "na", "nb", "c", "AdminApiClient", "httpClient", "request", "registryUrl", "packageName", "version", "base", "manifestUrl", "resp", "bundle", "pkg", "ver", "artifactUrl", "url", "bundles", "v", "appId", "contextId", "applicationId", "data", "blobId", "name", "namespaceId", "groupId", "safeId", "identity", "id", "parentGroupId", "MockHttpClient", "createBrowserAdminApiClient", "_config", "httpClient", "AdminApiClient", "createNodeAdminApiClient", "createAdminApiClient", "createAdminApiClientFromHttpClient", "parseAuthCallback", "url", "hashIndex", "hash", "params", "accessToken", "buildAuthLoginUrl", "nodeUrl", "opts", "RpcError", "code", "message", "data", "type", "RpcClient", "opts", "params", "body", "response", "err", "contextId", "SseClient", "opts", "event", "handler", "key", "arr", "idx", "listener", "ev", "d", "arg", "token", "response", "err", "error", "body", "reader", "decoder", "buffer", "done", "value", "lines", "line", "jsonStr", "msg", "eventData", "bytes", "text", "contextIds", "newIds", "id", "hadIds", "method", "_WsClient", "opts", "event", "handler", "key", "arr", "idx", "arg", "token", "wsUrl", "err", "error", "raw", "msg", "eventData", "bytes", "text", "contextIds", "id", "delay", "WsClient", "expiresAtFromJwt", "token", "fallbackMs", "parts", "b64", "payload", "MeroJs", "config", "isTauri", "createBrowserHttpClient", "newToken", "createAuthApiClientFromHttpClient", "createAdminApiClientFromHttpClient", "RpcClient", "SseClient", "WsClient", "credentials", "creds", "requestBody", "response", "accessToken", "error", "data", "expiresAt", "url", "parseAuthCallback", "nodeUrl", "opts", "buildAuthLoginUrl", "createMeroJs", "MemoryTokenStore", "data", "STORAGE_KEY", "LocalStorageTokenStore", "key", "raw", "parsed", "CloudClient", "config", "options", "params", "CAPABILITIES", "hasCap", "mask", "cap", "capU32", "withCap", "withoutCap"]
|
|
7
7
|
}
|