@calimero-network/mero-js 0.1.0 → 1.1.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../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/mero-js.ts"],
4
- "sourcesContent": ["// Mero.js - Pure JavaScript SDK for Calimero\n// This will contain the pure JavaScript SDK without React dependencies\n\n// Main SDK class\nexport { MeroJs, createMeroJs } from './mero-js';\nexport type { MeroJsConfig, TokenData } from './mero-js';\n\n// HTTP client module (Web Standards based)\nexport * from './http-client';\n\n// Auth API client\nexport * from './auth-api';\n\n// Admin API client\nexport * from './admin-api';\n\n// Utilities\n", "// 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 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 ): Promise<T> {\n const url = this.buildUrl(path);\n // Detect Tauri - check multiple ways since __TAURI_INTERNALS__ might not be available\n // Also use minimal path if credentials is 'omit' (Tauri workaround)\n const hasTauriInternals = typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;\n const hasTauri = typeof window !== 'undefined' && '__TAURI__' in window;\n const isTauri = hasTauriInternals || hasTauri || this.transport.credentials === 'omit';\n \n // In Tauri, use absolute minimal RequestInit - just like a direct fetch call\n if (isTauri) {\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 // Build minimal RequestInit - only what's absolutely necessary\n const requestInit: RequestInit = {};\n \n if (init?.method && init.method !== 'GET') {\n requestInit.method = init.method;\n }\n \n if (headersObj && Object.keys(headersObj).length > 0) {\n requestInit.headers = headersObj;\n }\n \n if (init?.body !== undefined && init.body !== null) {\n requestInit.body = init.body;\n }\n \n if (this.transport.credentials !== undefined) {\n requestInit.credentials = this.transport.credentials;\n }\n \n try {\n const response = await globalThis.fetch(url, requestInit);\n \n if (!response.ok) {\n const bodyText = await this.getBodyText(response);\n throw new HTTPError(\n response.status,\n response.statusText,\n url,\n response.headers,\n bodyText,\n );\n }\n \n return this.parseResponse<T>(response, init?.parse);\n } catch (error) {\n if (error instanceof HTTPError) {\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 // Non-Tauri: use full implementation with signals, etc.\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 if (init?.body !== undefined) {\n requestInit.body = init.body;\n }\n \n if (signal) {\n requestInit.signal = signal;\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 throw new HTTPError(\n response.status,\n response.statusText,\n url,\n response.headers,\n bodyText,\n );\n }\n\n return this.parseResponse<T>(response, init?.parse);\n } catch (error) {\n if (error instanceof HTTPError) {\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 // Skip AbortSignal in Tauri - it causes HTTP 0 Network Error\n const isTauri = typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;\n if (isTauri) {\n return undefined;\n }\n\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 defaultHeaders?: Record<string, string>;\n timeoutMs?: number;\n credentials?: RequestCredentials;\n defaultAbortSignal?: AbortSignal;\n}): HttpClient {\n const transport: Transport = {\n fetch: globalThis.fetch,\n baseUrl: options.baseUrl,\n getAuthToken: options.getAuthToken,\n onTokenRefresh: options.onTokenRefresh,\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 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 const transport: Transport = {\n fetch: fetchImpl,\n baseUrl: options.baseUrl,\n getAuthToken: options.getAuthToken,\n onTokenRefresh: options.onTokenRefresh,\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 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 {\n // Common types\n ApiResponse,\n // Health and Status\n HealthStatus,\n AdminAuthStatus,\n\n // Applications\n InstallApplicationRequest,\n InstallDevApplicationRequest,\n InstallApplicationResponse,\n UninstallApplicationResponse,\n ListApplicationsResponse,\n GetApplicationResponse,\n\n // Contexts\n CreateContextRequest,\n CreateContextResponse,\n DeleteContextResponse,\n ListContextsResponse,\n GetContextResponse,\n\n // Blobs\n UploadBlobRequest,\n UploadBlobResponse,\n DeleteBlobResponse,\n ListBlobsResponse,\n GetBlobResponse,\n\n // Aliases\n CreateAliasRequest,\n CreateAliasResponse,\n DeleteAliasResponse,\n ListAliasesResponse,\n GetAliasResponse,\n\n // Network\n GetNetworkPeersResponse,\n GetNetworkStatsResponse,\n GetNetworkConfigResponse,\n UpdateNetworkConfigRequest,\n UpdateNetworkConfigResponse,\n\n // System\n GetSystemInfoResponse,\n GetSystemLogsResponse,\n GetSystemMetricsResponse,\n RestartSystemResponse,\n ShutdownSystemResponse,\n} from './admin-types';\n\nexport class AdminApiClient {\n constructor(private httpClient: HttpClient) {}\n\n // Health and Status Endpoints\n async healthCheck(): Promise<HealthStatus> {\n const response =\n await this.httpClient.get<ApiResponse<HealthStatus>>('/health');\n if (!response.data) {\n throw new Error('Health response data is null');\n }\n return response.data;\n }\n\n async isAuthed(): Promise<AdminAuthStatus> {\n return this.httpClient.get<AdminAuthStatus>('/is-authed');\n }\n\n // Application Management Endpoints\n async installApplication(\n request: InstallApplicationRequest,\n ): Promise<InstallApplicationResponse> {\n return this.httpClient.post<InstallApplicationResponse>(\n '/install-application',\n request,\n );\n }\n\n async installDevApplication(\n request: InstallDevApplicationRequest,\n ): Promise<InstallApplicationResponse> {\n return this.httpClient.post<InstallApplicationResponse>(\n '/install-dev-application',\n request,\n );\n }\n\n async uninstallApplication(\n appId: string,\n ): Promise<UninstallApplicationResponse> {\n return this.httpClient.delete<UninstallApplicationResponse>(\n `/applications/${appId}`,\n );\n }\n\n async listApplications(): Promise<ListApplicationsResponse> {\n return this.httpClient.get<ListApplicationsResponse>('/applications');\n }\n\n async getApplication(appId: string): Promise<GetApplicationResponse> {\n return this.httpClient.get<GetApplicationResponse>(\n `/applications/${appId}`,\n );\n }\n\n // Context Management Endpoints\n async createContext(\n request: CreateContextRequest,\n ): Promise<CreateContextResponse> {\n return this.httpClient.post<CreateContextResponse>('/contexts', request);\n }\n\n async deleteContext(contextId: string): Promise<DeleteContextResponse> {\n return this.httpClient.delete<DeleteContextResponse>(\n `/contexts/${contextId}`,\n );\n }\n\n async getContexts(): Promise<ListContextsResponse> {\n return this.httpClient.get<ListContextsResponse>('/contexts');\n }\n\n async getContext(contextId: string): Promise<GetContextResponse> {\n return this.httpClient.get<GetContextResponse>(`/contexts/${contextId}`);\n }\n\n // Blob Management Endpoints\n async uploadBlob(request: UploadBlobRequest): Promise<UploadBlobResponse> {\n return this.httpClient.post<UploadBlobResponse>('/blobs', request);\n }\n\n async deleteBlob(blobId: string): Promise<DeleteBlobResponse> {\n return this.httpClient.delete<DeleteBlobResponse>(`/blobs/${blobId}`);\n }\n\n async listBlobs(): Promise<ListBlobsResponse> {\n return this.httpClient.get<ListBlobsResponse>('/blobs');\n }\n\n async getBlob(blobId: string): Promise<GetBlobResponse> {\n return this.httpClient.get<GetBlobResponse>(`/blobs/${blobId}`);\n }\n\n // Alias Management Endpoints\n async createAlias(request: CreateAliasRequest): Promise<CreateAliasResponse> {\n return this.httpClient.post<CreateAliasResponse>('/alias', request);\n }\n\n async deleteAlias(aliasId: string): Promise<DeleteAliasResponse> {\n return this.httpClient.delete<DeleteAliasResponse>(`/alias/${aliasId}`);\n }\n\n async listAliases(): Promise<ListAliasesResponse> {\n return this.httpClient.get<ListAliasesResponse>('/alias');\n }\n\n async getAlias(aliasId: string): Promise<GetAliasResponse> {\n return this.httpClient.get<GetAliasResponse>(`/alias/${aliasId}`);\n }\n\n // Network Management Endpoints\n async getNetworkPeers(): Promise<GetNetworkPeersResponse> {\n return this.httpClient.get<GetNetworkPeersResponse>('/network/peers');\n }\n\n async getNetworkStats(): Promise<GetNetworkStatsResponse> {\n return this.httpClient.get<GetNetworkStatsResponse>('/network/stats');\n }\n\n async getNetworkConfig(): Promise<GetNetworkConfigResponse> {\n return this.httpClient.get<GetNetworkConfigResponse>('/network/config');\n }\n\n async updateNetworkConfig(\n request: UpdateNetworkConfigRequest,\n ): Promise<UpdateNetworkConfigResponse> {\n return this.httpClient.put<UpdateNetworkConfigResponse>(\n '/network/config',\n request,\n );\n }\n\n async getPeersCount(): Promise<{ count: number }> {\n return this.httpClient.get<{ count: number }>('/network/peers/count');\n }\n\n // System Management Endpoints\n async getSystemInfo(): Promise<GetSystemInfoResponse> {\n return this.httpClient.get<GetSystemInfoResponse>('/system/info');\n }\n\n async getSystemLogs(): Promise<GetSystemLogsResponse> {\n return this.httpClient.get<GetSystemLogsResponse>('/system/logs');\n }\n\n async getSystemMetrics(): Promise<GetSystemMetricsResponse> {\n return this.httpClient.get<GetSystemMetricsResponse>('/system/metrics');\n }\n\n async restartSystem(): Promise<RestartSystemResponse> {\n return this.httpClient.post<RestartSystemResponse>('/system/restart');\n }\n\n async shutdownSystem(): Promise<ShutdownSystemResponse> {\n return this.httpClient.post<ShutdownSystemResponse>('/system/shutdown');\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", "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';\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}\n\nexport interface TokenData {\n access_token: string;\n refresh_token: string;\n expires_at: number;\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\n constructor(config: MeroJsConfig) {\n this.config = {\n timeoutMs: 10000,\n ...config,\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 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 // Token management is in-memory only\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 * 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 this.tokenData = {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n expires_at: Date.now() + 24 * 60 * 60 * 1000, // Default to 24 hours\n };\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, refreshing if necessary\n */\n private async getValidToken(): Promise<TokenData | null> {\n if (!this.tokenData) {\n return null;\n }\n\n // Check if token is expired (with 5 minute buffer)\n const bufferTime = 5 * 60 * 1000; // 5 minutes\n if (Date.now() >= this.tokenData.expires_at - bufferTime) {\n return await this.refreshToken();\n }\n\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 this.tokenData = {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n expires_at: Date.now() + 24 * 60 * 60 * 1000, // Default to 24 hours\n };\n\n return this.tokenData;\n } catch (error) {\n // If refresh fails, clear the token and require re-authentication\n this.clearToken();\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 }\n\n /**\n * Check if the SDK is authenticated\n */\n public isAuthenticated(): boolean {\n return this.tokenData !== null;\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/**\n * Create a new MeroJs SDK instance\n */\nexport function createMeroJs(config: MeroJsConfig): MeroJs {\n return new MeroJs(config);\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCO,SAAS,eACd,SACyB;AACzB,QAAM,OAAO,QAAQ,OAAO,OAAO;AACnC,MAAI,KAAK,WAAW,EAAG,QAAO;AAG9B,QAAM,iBAAiB;AAGvB,MAAI,OAAO,eAAe,QAAQ,YAAY;AAC5C,QAAI;AACF,aAAO,eAAe,IAAI,IAAI;AAAA,IAChC,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,UAAU,CAAC,QAAe;AAC9B,eAAW,MAAO,IAAI,OAAuB,MAAM;AACnD,eAAW,KAAK,KAAM,GAAE,oBAAoB,SAAS,OAAO;AAAA,EAC9D;AAEA,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,QAAS,QAAO,YAAY,MAAM,EAAE,MAAM;AAChD,MAAE,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,EACrD;AAEA,SAAO,WAAW;AACpB;AAGO,SAAS,oBAAoB,WAAgC;AAElE,MAAI,OAAO,YAAY,YAAY,YAAY;AAC7C,WAAO,YAAY,QAAQ,SAAS;AAAA,EACtC;AAGA,QAAM,aAAa,IAAI,gBAAgB;AACvC,aAAW,MAAM;AACf,eAAW,MAAM,IAAI,aAAa,WAAW,cAAc,CAAC;AAAA,EAC9D,GAAG,SAAS;AAEZ,SAAO,WAAW;AACpB;;;ACrCO,IAAM,YAAN,cAAwB,MAAM;AAAA,EAGnC,YACS,QACA,YACA,KACA,SACA,UACP;AACA,UAAM,QAAQ,MAAM,IAAI,UAAU,EAAE;AAN7B;AACA;AACA;AACA;AACA;AAPT,gBAAO;AAAA,EAUP;AAAA,EAEA,SAME;AACA,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,MACjB,KAAK,KAAK;AAAA,MACV,SAAS,gBAAgB,KAAK,OAAO;AAAA,MACrC,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AACF;AAGA,SAAS,gBAAgB,SAA0C;AACjE,QAAM,SAAiC,CAAC;AACxC,UAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,WAAO,GAAG,IAAI;AAAA,EAChB,CAAC;AACD,SAAO;AACT;AAGO,IAAM,gBAAN,MAA0C;AAAA,EAC/C,YAAoB,WAAsB;AAAtB;AAAA,EAAuB;AAAA,EAE3C,MAAM,IAAO,MAAc,MAAmC;AAC5D,WAAO,KAAK,QAAW,MAAM,EAAE,GAAG,MAAM,QAAQ,MAAM,CAAC;AAAA,EACzD;AAAA,EAEA,MAAM,KACJ,MACA,MACA,MACY;AACZ,WAAO,KAAK,QAAW,MAAM;AAAA,MAC3B,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACpC,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IACJ,MACA,MACA,MACY;AACZ,WAAO,KAAK,QAAW,MAAM;AAAA,MAC3B,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACpC,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAU,MAAc,MAAmC;AAC/D,WAAO,KAAK,QAAW,MAAM,EAAE,GAAG,MAAM,QAAQ,SAAS,CAAC;AAAA,EAC5D;AAAA,EAEA,MAAM,MACJ,MACA,MACA,MACY;AACZ,WAAO,KAAK,QAAW,MAAM;AAAA,MAC3B,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACpC,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KACJ,MACA,MAC8D;AAC9D,UAAM,WAAW,MAAM,KAAK,YAAsB,MAAM;AAAA,MACtD,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,OAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,MACL,SAAS,gBAAgB,SAAS,OAAO;AAAA,MACzC,QAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,QAAW,MAAc,MAAmC;AAChE,WAAO,KAAK,YAAe,MAAM,IAAI;AAAA,EACvC;AAAA,EAEA,MAAc,YACZ,MACA,MACY;AACZ,UAAM,MAAM,KAAK,SAAS,IAAI;AAG9B,UAAM,oBAAoB,OAAO,WAAW,eAAe,yBAAyB;AACpF,UAAM,WAAW,OAAO,WAAW,eAAe,eAAe;AACjE,UAAM,UAAU,qBAAqB,YAAY,KAAK,UAAU,gBAAgB;AAGhF,QAAI,SAAS;AACX,YAAMA,WAAU,MAAM,KAAK,aAAa,MAAM,OAAO;AACrD,UAAIC;AACJ,UAAID,oBAAmB,SAAS;AAC9B,QAAAC,cAAa,CAAC;AACd,QAAAD,SAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,UAAAC,YAAW,GAAG,IAAI;AAAA,QACpB,CAAC;AAAA,MACH,OAAO;AACL,QAAAA,cAAaD;AAAA,MACf;AAGA,YAAME,eAA2B,CAAC;AAElC,UAAI,MAAM,UAAU,KAAK,WAAW,OAAO;AACzC,QAAAA,aAAY,SAAS,KAAK;AAAA,MAC5B;AAEA,UAAID,eAAc,OAAO,KAAKA,WAAU,EAAE,SAAS,GAAG;AACpD,QAAAC,aAAY,UAAUD;AAAA,MACxB;AAEA,UAAI,MAAM,SAAS,UAAa,KAAK,SAAS,MAAM;AAClD,QAAAC,aAAY,OAAO,KAAK;AAAA,MAC1B;AAEA,UAAI,KAAK,UAAU,gBAAgB,QAAW;AAC5C,QAAAA,aAAY,cAAc,KAAK,UAAU;AAAA,MAC3C;AAEA,UAAI;AACF,cAAM,WAAW,MAAM,WAAW,MAAM,KAAKA,YAAW;AAExD,YAAI,CAAC,SAAS,IAAI;AAChB,gBAAM,WAAW,MAAM,KAAK,YAAY,QAAQ;AAChD,gBAAM,IAAI;AAAA,YACR,SAAS;AAAA,YACT,SAAS;AAAA,YACT;AAAA,YACA,SAAS;AAAA,YACT;AAAA,UACF;AAAA,QACF;AAEA,eAAO,KAAK,cAAiB,UAAU,MAAM,KAAK;AAAA,MACpD,SAAS,OAAO;AACd,YAAI,iBAAiB,WAAW;AAC9B,gBAAM;AAAA,QACR;AACA,cAAM,IAAI;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,UACA,IAAI,QAAQ;AAAA,UACZ,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAGA,UAAM,SAAS,KAAK,kBAAkB,IAAI;AAC1C,UAAM,UAAU,MAAM,KAAK,aAAa,MAAM,OAAO;AACrD,QAAI;AACJ,QAAI,mBAAmB,SAAS;AAC9B,mBAAa,CAAC;AACd,cAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,mBAAW,GAAG,IAAI;AAAA,MACpB,CAAC;AAAA,IACH,OAAO;AACL,mBAAa;AAAA,IACf;AAEA,UAAM,cAA2B;AAAA,MAC/B,QAAQ,MAAM,UAAU;AAAA,MACxB,SAAS;AAAA,IACX;AAEA,QAAI,MAAM,SAAS,QAAW;AAC5B,kBAAY,OAAO,KAAK;AAAA,IAC1B;AAEA,QAAI,QAAQ;AACV,kBAAY,SAAS;AAAA,IACvB;AAEA,QAAI,KAAK,UAAU,gBAAgB,QAAW;AAC5C,kBAAY,cAAc,KAAK,UAAU;AAAA,IAC3C;AAEA,QAAI,MAAM,SAAS,QAAW;AAC5B,kBAAY,OAAO,KAAK;AAAA,IAC1B;AACA,QAAI,MAAM,UAAU,QAAW;AAC7B,kBAAY,QAAQ,KAAK;AAAA,IAC3B;AACA,QAAI,MAAM,aAAa,QAAW;AAChC,kBAAY,WAAW,KAAK;AAAA,IAC9B;AACA,QAAI,MAAM,aAAa,QAAW;AAChC,kBAAY,WAAW,KAAK;AAAA,IAC9B;AACA,QAAI,MAAM,mBAAmB,QAAW;AACtC,kBAAY,iBAAiB,KAAK;AAAA,IACpC;AACA,QAAI,MAAM,cAAc,QAAW;AACjC,kBAAY,YAAY,KAAK;AAAA,IAC/B;AACA,QAAI,MAAM,cAAc,QAAW;AACjC,kBAAY,YAAY,KAAK;AAAA,IAC/B;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,UAAU,MAAM,KAAK,WAAW;AAE5D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,WAAW,MAAM,KAAK,YAAY,QAAQ;AAChD,cAAM,IAAI;AAAA,UACR,SAAS;AAAA,UACT,SAAS;AAAA,UACT;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAEA,aAAO,KAAK,cAAiB,UAAU,MAAM,KAAK;AAAA,IACpD,SAAS,OAAO;AACd,UAAI,iBAAiB,WAAW;AAC9B,cAAM;AAAA,MACR;AACA,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,QAAQ;AAAA,QACZ,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,SAAS,MAAsB;AAErC,QAAI,KAAK,WAAW,SAAS,KAAK,KAAK,WAAW,UAAU,GAAG;AAC7D,aAAO;AAAA,IACT;AAGA,UAAM,UAAU,KAAK,UAAU;AAC/B,QAAI,KAAK,WAAW,GAAG,GAAG;AAExB,YAAM,OAAO,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AAC5D,aAAO,GAAG,IAAI,GAAG,IAAI;AAAA,IACvB,OAAO;AAEL,YAAM,OAAO,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,OAAO;AACzD,aAAO,GAAG,IAAI,GAAG,IAAI;AAAA,IACvB;AAAA,EACF;AAAA,EAEQ,kBAAkB,MAAgD;AAExE,UAAM,UAAU,OAAO,WAAW,eAAe,yBAAyB;AAC1E,QAAI,SAAS;AACX,aAAO;AAAA,IACT;AAEA,UAAM,UAAyB,CAAC;AAEhC,QAAI,KAAK,UAAU,oBAAoB;AACrC,cAAQ,KAAK,KAAK,UAAU,kBAAkB;AAAA,IAChD;AAEA,QAAI,MAAM,QAAQ;AAChB,cAAQ,KAAK,KAAK,MAAM;AAAA,IAC1B;AAEA,UAAM,YAAY,MAAM,aAAa,KAAK,UAAU;AACpD,QAAI,WAAW;AACb,cAAQ,KAAK,oBAAoB,SAAS,CAAC;AAAA,IAC7C;AAEA,WAAO,QAAQ,SAAS,IAAI,eAAe,OAAO,IAAI;AAAA,EACxD;AAAA,EAEA,MAAc,aACZ,aACiC;AACjC,UAAM,UAAkC;AAAA,MACtC,GAAG,KAAK,UAAU;AAAA,IACpB;AAGA,QAAI,KAAK,UAAU,cAAc;AAC/B,UAAI;AACF,cAAM,QAAQ,MAAM,KAAK,UAAU,aAAa;AAChD,YAAI,SAAS,MAAM,KAAK,MAAM,IAAI;AAChC,kBAAQ,gBAAgB,UAAU,KAAK;AAAA,QACzC;AAAA,MACF,SAAS,OAAO;AAAA,MAEhB;AAAA,IACF;AAGA,QAAI,aAAa;AACf,UAAI,uBAAuB,SAAS;AAClC,oBAAY,QAAQ,CAAC,OAAO,QAAQ;AAClC,kBAAQ,GAAG,IAAI;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,MAAM,QAAQ,WAAW,GAAG;AACrC,oBAAY,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACpC,kBAAQ,GAAG,IAAI;AAAA,QACjB,CAAC;AAAA,MACH,OAAO;AACL,eAAO,OAAO,SAAS,WAAW;AAAA,MACpC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cACZ,UACA,OACY;AACZ,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,eAAQ,MAAM,SAAS,KAAK;AAAA,MAC9B,KAAK;AACH,eAAQ,MAAM,SAAS,KAAK;AAAA,MAC9B,KAAK;AACH,eAAQ,MAAM,SAAS,YAAY;AAAA,MACrC,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL;AACE,eAAO,MAAM,SAAS,KAAK;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAc,YAAY,UAAqC;AAC7D,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,KAAK,SAAS,QAAQ,KAAK,MAAM,GAAG,KAAK,IAAI,QAAQ;AAAA,IAC9D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACjYO,SAAS,iBAAiB,WAAkC;AACjE,SAAO,IAAI,cAAc,SAAS;AACpC;AAGO,SAAS,wBAAwB,SAQzB;AACb,QAAM,YAAuB;AAAA,IAC3B,OAAO,WAAW;AAAA,IAClB,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ;AAAA,IACtB,gBAAgB,QAAQ;AAAA,IACxB,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA;AAAA,IACrB,oBAAoB,QAAQ;AAAA,EAC9B;AAEA,SAAO,iBAAiB,SAAS;AACnC;AAGO,SAAS,qBAAqB,SAStB;AAEb,QAAM,YAAY,QAAQ,SAAS,WAAW;AAE9C,MAAI,CAAC,WAAW;AACd,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,YAAuB;AAAA,IAC3B,OAAO;AAAA,IACP,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ;AAAA,IACtB,gBAAgB,QAAQ;AAAA,IACxB,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA;AAAA,IACrB,oBAAoB,QAAQ;AAAA,EAC9B;AAEA,SAAO,iBAAiB,SAAS;AACnC;AAGO,SAAS,0BAA0B,SAS3B;AAEb,MAAI,OAAO,WAAW,aAAa;AAEjC,WAAO,wBAAwB,OAAO;AAAA,EACxC,OAAO;AAEL,WAAO,qBAAqB,OAAO;AAAA,EACrC;AACF;;;ACnEA,SAAS,sBAAsB,OAAc,SAA0B;AAErE,MAAI,WAAW,EAAG,QAAO;AAKzB,QAAM,gBAAgB;AACtB,QAAM,OAAO,eAAe;AAC5B,MAAI,SAAS,eAAgB,QAAO;AACpC,MAAI,SAAS,aAAc,QAAO;AAGlC,QAAM,kBAAkB;AACxB,MACE,YAAY,mBACZ,OAAO,gBAAgB,WAAW,UAClC;AACA,UAAM,SAAS,gBAAgB;AAC/B,WAAO,UAAU,OAAO,WAAW;AAAA,EACrC;AAEA,MAAI,SAAS,YAAa,QAAO;AAEjC,SAAO;AACT;AAGA,SAAS,eAAe,SAAyB;AAC/C,QAAM,cAAc;AACpB,QAAM,QAAQ,cAAc,KAAK,IAAI,GAAG,UAAU,CAAC;AAGnD,QAAM,UAAU,KAAK,OAAO,IAAI,OAAO,MAAM;AAC7C,SAAO,KAAK,IAAI,GAAG,QAAQ,MAAM;AACnC;AAGA,eAAsB,UACpB,IACA,UAAwB,CAAC,GACb;AACZ,QAAM,EAAE,WAAW,EAAE,IAAI;AAEzB,MAAI;AAEJ,WAAS,UAAU,GAAG,WAAW,UAAU,WAAW;AACpD,QAAI;AACF,aAAO,MAAM,GAAG,OAAO;AAAA,IACzB,SAAS,OAAO;AACd,kBAAY;AAGZ,UAAI,CAAC,sBAAsB,WAAW,WAAW,OAAO,GAAG;AACzD,cAAM;AAAA,MACR;AAGA,UAAI,UAAU,eAAe,OAAO;AAGpC,YAAM,mBAAmB;AACzB,YAAM,OAAO,iBAAiB;AAC9B,YAAM,aAAa,MAAM,MAAM,aAAa;AAC5C,UAAI,YAAY;AAEd,cAAM,UAAU,SAAS,YAAY,EAAE;AACvC,YAAI,CAAC,MAAM,OAAO,GAAG;AACnB,oBAAU,KAAK,IAAI,SAAS,UAAU,GAAI;AAAA,QAC5C,OAAO;AAEL,gBAAM,OAAO,IAAI,KAAK,UAAU;AAChC,cAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,GAAG;AAC1B,kBAAM,WAAW,KAAK,IAAI,GAAG,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC;AAExD,sBAAU,KAAK,IAAI,SAAS,KAAK,IAAI,UAAU,GAAK,CAAC;AAAA,UACvD;AAAA,QACF;AAAA,MACF;AAGA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,OAAO,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,MAAM,4BAA4B;AAC3D;AAGO,SAAS,sBACd,QACA,eAA6B,CAAC,GAC9B;AACA,SAAO,UAAU,SAAwB;AACvC,WAAO,UAAU,MAAM,OAAO,GAAG,IAAI,GAAG,YAAY;AAAA,EACtD;AACF;;;AClFO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAAoB,YAAwB;AAAxB;AAAA,EAAyB;AAAA;AAAA,EAG7C,MAAM,YAAqC;AACzC,UAAM,WACJ,MAAM,KAAK,WAAW,IAAiC,cAAc;AACvE,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,cAAyC;AAC7C,UAAM,WACJ,MAAM,KAAK,WAAW;AAAA,MACpB;AAAA,IACF;AACF,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,eAA2C;AAC/C,UAAM,WACJ,MAAM,KAAK,WAAW;AAAA,MACpB;AAAA,IACF;AACF,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,eAAgC;AACpC,WAAO,KAAK,WAAW,IAAY,eAAe,EAAE,OAAO,OAAO,CAAC;AAAA,EACrE;AAAA,EAEA,MAAM,eAAe,SAA+C;AAClE,WAAO,KAAK,WAAW,KAAoB,eAAe,OAAO;AAAA,EACnE;AAAA,EAEA,MAAM,aAAa,SAAsD;AACvE,WAAO,KAAK,WAAW,KAAoB,iBAAiB,OAAO;AAAA,EACrE;AAAA,EAEA,MAAM,mBAAmB,SAAmD;AAC1E,WAAO,KAAK,WAAW,KAAoB,oBAAoB,OAAO;AAAA,EACxE;AAAA,EAEA,MAAM,eAA2C;AAC/C,WAAO,KAAK,WAAW,IAAuB,iBAAiB;AAAA,EACjE;AAAA,EAEA,MAAM,cAAc,OAIjB;AACD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,iBAAiB,KAAK;AAClD,aAAO;AAAA,QACL,OAAO,SAAS,WAAW;AAAA,QAC3B,SAAS,SAAS;AAAA,QAClB,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SAAS,CAAC;AAAA,QACV,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iBACJ,OAC8D;AAC9D,UAAM,WAAW,MAAM,KAAK,WAAW,KAAK,kBAAkB;AAAA,MAC5D,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,IAC9C,CAAC;AACD,WAAO;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB,SAAS,SAAS;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,WAAgC;AACpC,WAAO,KAAK,WAAW,IAAgB,iBAAiB;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,aACJ,SAC8B;AAC9B,WAAO,KAAK,WAAW,KAA0B,iBAAiB,OAAO;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,eAA0C;AAC9C,UAAM,WACJ,MAAM,KAAK,WAAW,IAAmC,aAAa;AACxE,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,cAAc,SAAuD;AACzE,WAAO,KAAK,WAAW,KAAwB,eAAe,OAAO;AAAA,EACvE;AAAA,EAEA,MAAM,cAAc,OAA2C;AAC7D,WAAO,KAAK,WAAW,OAA0B,eAAe,KAAK,EAAE;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,iBAA8C;AAClD,UAAM,WAAW,MAAM,KAAK,WAAW;AAAA,MACrC;AAAA,IACF;AACA,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,kBACJ,SACwB;AACxB,WAAO,KAAK,WAAW,KAAoB,qBAAqB,OAAO;AAAA,EACzE;AAAA,EAEA,MAAM,gBACJ,OACA,UAC+B;AAC/B,WAAO,KAAK,WAAW;AAAA,MACrB,eAAe,KAAK,YAAY,QAAQ;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,kBAAkB,OAA4C;AAClE,WAAO,KAAK,WAAW;AAAA,MACrB,eAAe,KAAK;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,qBACJ,OACA,aAC6B;AAC7B,WAAO,KAAK,WAAW;AAAA,MACrB,eAAe,KAAK;AAAA,MACpB,EAAE,YAAY;AAAA,IAChB;AAAA,EACF;AACF;;;AC5LA,IAAM,iBAAN,MAA2C;AAAA,EACzC,MAAM,MAAqB;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAsB;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,MAAqB;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,SAAwB;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,QAAuB;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAqE;AACzE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,UAAyB;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,2BACd,SACe;AACf,QAAM,aAAa,IAAI,eAAe;AACtC,SAAO,IAAI,cAAc,UAAU;AACrC;AAEO,SAAS,wBACd,SACe;AACf,QAAM,aAAa,IAAI,eAAe;AACtC,SAAO,IAAI,cAAc,UAAU;AACrC;AAEO,SAAS,oBACd,SACe;AACf,QAAM,aAAa,IAAI,eAAe;AACtC,SAAO,IAAI,cAAc,UAAU;AACrC;AAEO,SAAS,kCACd,YACA,SACe;AACf,SAAO,IAAI,cAAc,UAAU;AACrC;;;AClBO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAAoB,YAAwB;AAAxB;AAAA,EAAyB;AAAA;AAAA,EAG7C,MAAM,cAAqC;AACzC,UAAM,WACJ,MAAM,KAAK,WAAW,IAA+B,SAAS;AAChE,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,WAAqC;AACzC,WAAO,KAAK,WAAW,IAAqB,YAAY;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,mBACJ,SACqC;AACrC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,sBACJ,SACqC;AACrC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,qBACJ,OACuC;AACvC,WAAO,KAAK,WAAW;AAAA,MACrB,iBAAiB,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,mBAAsD;AAC1D,WAAO,KAAK,WAAW,IAA8B,eAAe;AAAA,EACtE;AAAA,EAEA,MAAM,eAAe,OAAgD;AACnE,WAAO,KAAK,WAAW;AAAA,MACrB,iBAAiB,KAAK;AAAA,IACxB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cACJ,SACgC;AAChC,WAAO,KAAK,WAAW,KAA4B,aAAa,OAAO;AAAA,EACzE;AAAA,EAEA,MAAM,cAAc,WAAmD;AACrE,WAAO,KAAK,WAAW;AAAA,MACrB,aAAa,SAAS;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,cAA6C;AACjD,WAAO,KAAK,WAAW,IAA0B,WAAW;AAAA,EAC9D;AAAA,EAEA,MAAM,WAAW,WAAgD;AAC/D,WAAO,KAAK,WAAW,IAAwB,aAAa,SAAS,EAAE;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,WAAW,SAAyD;AACxE,WAAO,KAAK,WAAW,KAAyB,UAAU,OAAO;AAAA,EACnE;AAAA,EAEA,MAAM,WAAW,QAA6C;AAC5D,WAAO,KAAK,WAAW,OAA2B,UAAU,MAAM,EAAE;AAAA,EACtE;AAAA,EAEA,MAAM,YAAwC;AAC5C,WAAO,KAAK,WAAW,IAAuB,QAAQ;AAAA,EACxD;AAAA,EAEA,MAAM,QAAQ,QAA0C;AACtD,WAAO,KAAK,WAAW,IAAqB,UAAU,MAAM,EAAE;AAAA,EAChE;AAAA;AAAA,EAGA,MAAM,YAAY,SAA2D;AAC3E,WAAO,KAAK,WAAW,KAA0B,UAAU,OAAO;AAAA,EACpE;AAAA,EAEA,MAAM,YAAY,SAA+C;AAC/D,WAAO,KAAK,WAAW,OAA4B,UAAU,OAAO,EAAE;AAAA,EACxE;AAAA,EAEA,MAAM,cAA4C;AAChD,WAAO,KAAK,WAAW,IAAyB,QAAQ;AAAA,EAC1D;AAAA,EAEA,MAAM,SAAS,SAA4C;AACzD,WAAO,KAAK,WAAW,IAAsB,UAAU,OAAO,EAAE;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,kBAAoD;AACxD,WAAO,KAAK,WAAW,IAA6B,gBAAgB;AAAA,EACtE;AAAA,EAEA,MAAM,kBAAoD;AACxD,WAAO,KAAK,WAAW,IAA6B,gBAAgB;AAAA,EACtE;AAAA,EAEA,MAAM,mBAAsD;AAC1D,WAAO,KAAK,WAAW,IAA8B,iBAAiB;AAAA,EACxE;AAAA,EAEA,MAAM,oBACJ,SACsC;AACtC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,gBAA4C;AAChD,WAAO,KAAK,WAAW,IAAuB,sBAAsB;AAAA,EACtE;AAAA;AAAA,EAGA,MAAM,gBAAgD;AACpD,WAAO,KAAK,WAAW,IAA2B,cAAc;AAAA,EAClE;AAAA,EAEA,MAAM,gBAAgD;AACpD,WAAO,KAAK,WAAW,IAA2B,cAAc;AAAA,EAClE;AAAA,EAEA,MAAM,mBAAsD;AAC1D,WAAO,KAAK,WAAW,IAA8B,iBAAiB;AAAA,EACxE;AAAA,EAEA,MAAM,gBAAgD;AACpD,WAAO,KAAK,WAAW,KAA4B,iBAAiB;AAAA,EACtE;AAAA,EAEA,MAAM,iBAAkD;AACtD,WAAO,KAAK,WAAW,KAA6B,kBAAkB;AAAA,EACxE;AACF;;;AC1MA,IAAMC,kBAAN,MAA2C;AAAA,EACzC,MAAM,MAAqB;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAsB;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,MAAqB;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,SAAwB;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,QAAuB;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAqE;AACzE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,UAAyB;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,4BACd,SACgB;AAChB,QAAM,aAAa,IAAIA,gBAAe;AACtC,SAAO,IAAI,eAAe,UAAU;AACtC;AAEO,SAAS,yBACd,SACgB;AAChB,QAAM,aAAa,IAAIA,gBAAe;AACtC,SAAO,IAAI,eAAe,UAAU;AACtC;AAEO,SAAS,qBACd,SACgB;AAChB,QAAM,aAAa,IAAIA,gBAAe;AACtC,SAAO,IAAI,eAAe,UAAU;AACtC;AAEO,SAAS,mCACd,YACA,SACgB;AAChB,SAAO,IAAI,eAAe,UAAU;AACtC;;;ACxCO,IAAM,SAAN,MAAa;AAAA,EAQlB,YAAY,QAAsB;AAHlC,SAAQ,YAA8B;AACtC,SAAQ,iBAA4C;AAGlD,SAAK,SAAS;AAAA,MACZ,WAAW;AAAA,MACX,GAAG;AAAA,IACL;AAIA,UAAM,UAAU,OAAO,WAAW,eAAe,yBAAyB;AAC1E,SAAK,aAAa,wBAAwB;AAAA,MACxC,SAAS,KAAK,OAAO;AAAA,MACrB,cAAc,YAAY;AACxB,cAAM,QAAQ,MAAM,KAAK,cAAc;AACvC,eAAO,OAAO,gBAAgB;AAAA,MAChC;AAAA,MACA,WAAW,KAAK,OAAO;AAAA,MACvB,aAAa,KAAK,OAAO,uBAAuB,UAAU,SAAS;AAAA,IACrE,CAAC;AAGD,SAAK,aAAa,kCAAkC,KAAK,YAAY;AAAA,MACnE,SAAS,KAAK,OAAO;AAAA,MACrB,cAAc,YAAY;AACxB,cAAM,QAAQ,MAAM,KAAK,cAAc;AACvC,eAAO,OAAO,gBAAgB;AAAA,MAChC;AAAA,MACA,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AAED,SAAK,cAAc,mCAAmC,KAAK,YAAY;AAAA,MACrE,SAAS,KAAK,OAAO;AAAA,MACrB,cAAc,YAAY;AACxB,cAAM,QAAQ,MAAM,KAAK,cAAc;AACvC,eAAO,OAAO,gBAAgB;AAAA,MAChC;AAAA,MACA,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AAAA,EAGH;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAwB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,aAGI;AACrB,UAAM,QAAQ,eAAe,KAAK,OAAO;AACzC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAEA,QAAI;AACF,YAAM,cAAc;AAAA,QAClB,aAAa;AAAA,QACb,YAAY,MAAM;AAAA,QAClB,aAAa;AAAA,QACb,aAAa,CAAC,OAAO;AAAA,QACrB,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,QACvC,eAAe;AAAA,UACb,UAAU,MAAM;AAAA,UAChB,UAAU,MAAM;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,KAAK,WAAW,eAAe,WAAW;AAEjE,WAAK,YAAY;AAAA,QACf,cAAc,SAAS,KAAK;AAAA,QAC5B,eAAe,SAAS,KAAK;AAAA,QAC7B,YAAY,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK;AAAA;AAAA,MAC1C;AAEA,aAAO,KAAK;AAAA,IACd,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBAA2C;AACvD,QAAI,CAAC,KAAK,WAAW;AACnB,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,IAAI,KAAK;AAC5B,QAAI,KAAK,IAAI,KAAK,KAAK,UAAU,aAAa,YAAY;AACxD,aAAO,MAAM,KAAK,aAAa;AAAA,IACjC;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAmC;AAC/C,QAAI,CAAC,KAAK,WAAW,eAAe;AAClC,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAGA,QAAI,KAAK,gBAAgB;AACvB,aAAO,KAAK;AAAA,IACd;AAEA,SAAK,iBAAiB,KAAK,oBAAoB;AAE/C,QAAI;AACF,YAAM,WAAW,MAAM,KAAK;AAC5B,aAAO;AAAA,IACT,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,sBAA0C;AACtD,QAAI,CAAC,KAAK,WAAW,eAAe;AAClC,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW,aAAa;AAAA,QAClD,cAAc,KAAK,UAAU;AAAA,QAC7B,eAAe,KAAK,UAAU;AAAA,MAChC,CAAC;AAED,WAAK,YAAY;AAAA,QACf,cAAc,SAAS,KAAK;AAAA,QAC5B,eAAe,SAAS,KAAK;AAAA,QAC7B,YAAY,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK;AAAA;AAAA,MAC1C;AAEA,aAAO,KAAK;AAAA,IACd,SAAS,OAAO;AAEd,WAAK,WAAW;AAChB,YAAM,IAAI;AAAA,QACR,yBAAyB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,aAAmB;AACxB,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKO,kBAA2B;AAChC,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKO,eAAiC;AACtC,WAAO,KAAK;AAAA,EACd;AACF;AAKO,SAAS,aAAa,QAA8B;AACzD,SAAO,IAAI,OAAO,MAAM;AAC1B;",
6
- "names": ["headers", "headersObj", "requestInit", "MockHttpClient"]
4
+ "sourcesContent": ["// Mero.js - Pure JavaScript SDK for Calimero\n// This will contain the pure JavaScript SDK without React dependencies\n\n// Main SDK class\nexport { MeroJs, createMeroJs } from './mero-js';\nexport type { MeroJsConfig, TokenData } from './mero-js';\n\n// HTTP client module (Web Standards based)\nexport * from './http-client';\n\n// Auth API client\nexport * from './auth-api';\n\n// Admin API client\nexport * from './admin-api';\n\n// Utilities\n", "// 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 // Don't retry if user aborted the request\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 && // Can't retry with stream bodies\n !userAborted // Don't retry if user aborted\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 {\n // Common types\n ApiResponse,\n // Health and Status\n HealthStatus,\n AdminAuthStatus,\n\n // Applications\n InstallApplicationRequest,\n InstallDevApplicationRequest,\n InstallApplicationResponse,\n UninstallApplicationResponse,\n ListApplicationsResponse,\n GetApplicationResponse,\n\n // Contexts\n CreateContextRequest,\n CreateContextResponse,\n DeleteContextResponse,\n ListContextsResponse,\n GetContextResponse,\n\n // Blobs\n UploadBlobRequest,\n UploadBlobResponse,\n DeleteBlobResponse,\n ListBlobsResponse,\n GetBlobResponse,\n\n // Aliases\n CreateAliasRequest,\n CreateAliasResponse,\n DeleteAliasResponse,\n ListAliasesResponse,\n GetAliasResponse,\n\n // Network\n GetNetworkPeersResponse,\n GetNetworkStatsResponse,\n GetNetworkConfigResponse,\n UpdateNetworkConfigRequest,\n UpdateNetworkConfigResponse,\n\n // System\n GetSystemInfoResponse,\n GetSystemLogsResponse,\n GetSystemMetricsResponse,\n RestartSystemResponse,\n ShutdownSystemResponse,\n} from './admin-types';\n\nexport class AdminApiClient {\n constructor(private httpClient: HttpClient) {}\n\n // Health and Status Endpoints\n async healthCheck(): Promise<HealthStatus> {\n const response =\n await this.httpClient.get<ApiResponse<HealthStatus>>('/health');\n if (!response.data) {\n throw new Error('Health response data is null');\n }\n return response.data;\n }\n\n async isAuthed(): Promise<AdminAuthStatus> {\n return this.httpClient.get<AdminAuthStatus>('/is-authed');\n }\n\n // Application Management Endpoints\n async installApplication(\n request: InstallApplicationRequest,\n ): Promise<InstallApplicationResponse> {\n return this.httpClient.post<InstallApplicationResponse>(\n '/install-application',\n request,\n );\n }\n\n async installDevApplication(\n request: InstallDevApplicationRequest,\n ): Promise<InstallApplicationResponse> {\n return this.httpClient.post<InstallApplicationResponse>(\n '/install-dev-application',\n request,\n );\n }\n\n async uninstallApplication(\n appId: string,\n ): Promise<UninstallApplicationResponse> {\n return this.httpClient.delete<UninstallApplicationResponse>(\n `/applications/${appId}`,\n );\n }\n\n async listApplications(): Promise<ListApplicationsResponse> {\n return this.httpClient.get<ListApplicationsResponse>('/applications');\n }\n\n async getApplication(appId: string): Promise<GetApplicationResponse> {\n return this.httpClient.get<GetApplicationResponse>(\n `/applications/${appId}`,\n );\n }\n\n // Context Management Endpoints\n async createContext(\n request: CreateContextRequest,\n ): Promise<CreateContextResponse> {\n return this.httpClient.post<CreateContextResponse>('/contexts', request);\n }\n\n async deleteContext(contextId: string): Promise<DeleteContextResponse> {\n return this.httpClient.delete<DeleteContextResponse>(\n `/contexts/${contextId}`,\n );\n }\n\n async getContexts(): Promise<ListContextsResponse> {\n return this.httpClient.get<ListContextsResponse>('/contexts');\n }\n\n async getContext(contextId: string): Promise<GetContextResponse> {\n return this.httpClient.get<GetContextResponse>(`/contexts/${contextId}`);\n }\n\n // Blob Management Endpoints\n async uploadBlob(request: UploadBlobRequest): Promise<UploadBlobResponse> {\n return this.httpClient.post<UploadBlobResponse>('/blobs', request);\n }\n\n async deleteBlob(blobId: string): Promise<DeleteBlobResponse> {\n return this.httpClient.delete<DeleteBlobResponse>(`/blobs/${blobId}`);\n }\n\n async listBlobs(): Promise<ListBlobsResponse> {\n return this.httpClient.get<ListBlobsResponse>('/blobs');\n }\n\n async getBlob(blobId: string): Promise<GetBlobResponse> {\n return this.httpClient.get<GetBlobResponse>(`/blobs/${blobId}`);\n }\n\n // Alias Management Endpoints\n async createAlias(request: CreateAliasRequest): Promise<CreateAliasResponse> {\n return this.httpClient.post<CreateAliasResponse>('/alias', request);\n }\n\n async deleteAlias(aliasId: string): Promise<DeleteAliasResponse> {\n return this.httpClient.delete<DeleteAliasResponse>(`/alias/${aliasId}`);\n }\n\n async listAliases(): Promise<ListAliasesResponse> {\n return this.httpClient.get<ListAliasesResponse>('/alias');\n }\n\n async getAlias(aliasId: string): Promise<GetAliasResponse> {\n return this.httpClient.get<GetAliasResponse>(`/alias/${aliasId}`);\n }\n\n // Network Management Endpoints\n async getNetworkPeers(): Promise<GetNetworkPeersResponse> {\n return this.httpClient.get<GetNetworkPeersResponse>('/network/peers');\n }\n\n async getNetworkStats(): Promise<GetNetworkStatsResponse> {\n return this.httpClient.get<GetNetworkStatsResponse>('/network/stats');\n }\n\n async getNetworkConfig(): Promise<GetNetworkConfigResponse> {\n return this.httpClient.get<GetNetworkConfigResponse>('/network/config');\n }\n\n async updateNetworkConfig(\n request: UpdateNetworkConfigRequest,\n ): Promise<UpdateNetworkConfigResponse> {\n return this.httpClient.put<UpdateNetworkConfigResponse>(\n '/network/config',\n request,\n );\n }\n\n async getPeersCount(): Promise<{ count: number }> {\n return this.httpClient.get<{ count: number }>('/network/peers/count');\n }\n\n // System Management Endpoints\n async getSystemInfo(): Promise<GetSystemInfoResponse> {\n return this.httpClient.get<GetSystemInfoResponse>('/system/info');\n }\n\n async getSystemLogs(): Promise<GetSystemLogsResponse> {\n return this.httpClient.get<GetSystemLogsResponse>('/system/logs');\n }\n\n async getSystemMetrics(): Promise<GetSystemMetricsResponse> {\n return this.httpClient.get<GetSystemMetricsResponse>('/system/metrics');\n }\n\n async restartSystem(): Promise<RestartSystemResponse> {\n return this.httpClient.post<RestartSystemResponse>('/system/restart');\n }\n\n async shutdownSystem(): Promise<ShutdownSystemResponse> {\n return this.httpClient.post<ShutdownSystemResponse>('/system/shutdown');\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", "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';\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}\n\nexport interface TokenData {\n access_token: string;\n refresh_token: string;\n expires_at: number;\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\n constructor(config: MeroJsConfig) {\n this.config = {\n timeoutMs: 10000,\n ...config,\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 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 // Token management is in-memory only\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 * 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 this.tokenData = {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n expires_at: Date.now() + 24 * 60 * 60 * 1000, // Default to 24 hours\n };\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, refreshing if necessary\n */\n private async getValidToken(): Promise<TokenData | null> {\n if (!this.tokenData) {\n return null;\n }\n\n // Check if token is expired (with 5 minute buffer)\n const bufferTime = 5 * 60 * 1000; // 5 minutes\n if (Date.now() >= this.tokenData.expires_at - bufferTime) {\n return await this.refreshToken();\n }\n\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 this.tokenData = {\n access_token: response.data.access_token,\n refresh_token: response.data.refresh_token,\n expires_at: Date.now() + 24 * 60 * 60 * 1000, // Default to 24 hours\n };\n\n return this.tokenData;\n } catch (error) {\n // If refresh fails, clear the token and require re-authentication\n this.clearToken();\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 }\n\n /**\n * Check if the SDK is authenticated\n */\n public isAuthenticated(): boolean {\n return this.tokenData !== null;\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/**\n * Create a new MeroJs SDK instance\n */\nexport function createMeroJs(config: MeroJsConfig): MeroJs {\n return new MeroJs(config);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCO,SAAS,eACd,SACyB;AACzB,QAAM,OAAO,QAAQ,OAAO,OAAO;AACnC,MAAI,KAAK,WAAW,EAAG,QAAO;AAG9B,QAAM,iBAAiB;AAGvB,MAAI,OAAO,eAAe,QAAQ,YAAY;AAC5C,QAAI;AACF,aAAO,eAAe,IAAI,IAAI;AAAA,IAChC,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,UAAU,CAAC,QAAe;AAC9B,eAAW,MAAO,IAAI,OAAuB,MAAM;AACnD,eAAW,KAAK,KAAM,GAAE,oBAAoB,SAAS,OAAO;AAAA,EAC9D;AAEA,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,QAAS,QAAO,YAAY,MAAM,EAAE,MAAM;AAChD,MAAE,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,EACrD;AAEA,SAAO,WAAW;AACpB;AAGO,SAAS,oBAAoB,WAAgC;AAElE,MAAI,OAAO,YAAY,YAAY,YAAY;AAC7C,WAAO,YAAY,QAAQ,SAAS;AAAA,EACtC;AAGA,QAAM,aAAa,IAAI,gBAAgB;AACvC,aAAW,MAAM;AACf,eAAW,MAAM,IAAI,aAAa,WAAW,cAAc,CAAC;AAAA,EAC9D,GAAG,SAAS;AAEZ,SAAO,WAAW;AACpB;;;ACrCO,IAAM,YAAN,cAAwB,MAAM;AAAA,EAGnC,YACS,QACA,YACA,KACA,SACA,UACP;AACA,UAAM,QAAQ,MAAM,IAAI,UAAU,EAAE;AAN7B;AACA;AACA;AACA;AACA;AAPT,gBAAO;AAAA,EAUP;AAAA,EAEA,SAME;AACA,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,MACjB,KAAK,KAAK;AAAA,MACV,SAAS,gBAAgB,KAAK,OAAO;AAAA,MACrC,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AACF;AAGA,SAAS,gBAAgB,SAA0C;AACjE,QAAM,SAAiC,CAAC;AACxC,UAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,WAAO,GAAG,IAAI;AAAA,EAChB,CAAC;AACD,SAAO;AACT;AAGO,IAAM,gBAAN,MAA0C;AAAA,EAM/C,YAAoB,WAAsB;AAAtB;AAJpB;AAAA,SAAQ,sBAA8C;AAEtD;AAAA,SAAQ,wBAA8C;AAAA,EAEX;AAAA,EAE3C,MAAM,IAAO,MAAc,MAAmC;AAC5D,WAAO,KAAK,QAAW,MAAM,EAAE,GAAG,MAAM,QAAQ,MAAM,CAAC;AAAA,EACzD;AAAA,EAEA,MAAM,KACJ,MACA,MACA,MACY;AACZ,WAAO,KAAK,QAAW,MAAM;AAAA,MAC3B,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACpC,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,IACJ,MACA,MACA,MACY;AACZ,WAAO,KAAK,QAAW,MAAM;AAAA,MAC3B,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACpC,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAU,MAAc,MAAmC;AAC/D,WAAO,KAAK,QAAW,MAAM,EAAE,GAAG,MAAM,QAAQ,SAAS,CAAC;AAAA,EAC5D;AAAA,EAEA,MAAM,MACJ,MACA,MACA,MACY;AACZ,WAAO,KAAK,QAAW,MAAM;AAAA,MAC3B,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACpC,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,GAAG,MAAM;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,KACJ,MACA,MAC8D;AAC9D,UAAM,WAAW,MAAM,KAAK,YAAsB,MAAM;AAAA,MACtD,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,OAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,MACL,SAAS,gBAAgB,SAAS,OAAO;AAAA,MACzC,QAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,QAAW,MAAc,MAAmC;AAChE,WAAO,KAAK,YAAe,MAAM,IAAI;AAAA,EACvC;AAAA,EAEA,MAAc,YACZ,MACA,MACA,aAAa,GACb,kBACY;AAEZ,UAAM,qBAAqB;AAC3B,UAAM,MAAM,KAAK,SAAS,IAAI;AAI9B,UAAM,YAAY,oBAAoB,KAAK,IAAI;AAG/C,UAAM,SAAS,KAAK,kBAAkB,IAAI;AAC1C,UAAM,UAAU,MAAM,KAAK,aAAa,MAAM,OAAO;AACrD,QAAI;AACJ,QAAI,mBAAmB,SAAS;AAC9B,mBAAa,CAAC;AACd,cAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC9B,mBAAW,GAAG,IAAI;AAAA,MACpB,CAAC;AAAA,IACH,OAAO;AACL,mBAAa;AAAA,IACf;AAEA,UAAM,cAA2B;AAAA,MAC/B,QAAQ,MAAM,UAAU;AAAA,MACxB,SAAS;AAAA,IACX;AAIA,UAAM,eAAe,MAAM,gBAAgB,kBACtB,OAAO,MAAM,SAAS,YAAY,MAAM,SAAS,QAAQ,eAAe,KAAK,QAAQ,EAAE,KAAK,gBAAgB;AAEjI,QAAI,MAAM,SAAS,UAAa,CAAC,cAAc;AAC7C,kBAAY,OAAO,KAAK;AAAA,IAC1B,WAAW,MAAM,SAAS,UAAa,gBAAgB,eAAe,GAAG;AAEvE,kBAAY,OAAO,KAAK;AAAA,IAC1B;AAMA,QAAI;AACJ,QAAI,aAAa,KAAK,qBAAqB,QAAW;AACpD,YAAM,YAAY,MAAM,aAAa,KAAK,UAAU;AACpD,UAAI,WAAW;AAEb,cAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,cAAM,YAAY,KAAK,IAAI,GAAG,YAAY,OAAO;AAEjD,sBAAc,KAAK,kBAAkB,EAAE,GAAG,MAAM,WAAW,UAAU,CAAC;AAAA,MACxE,OAAO;AAEL,sBAAc,KAAK,kBAAkB,IAAI;AAAA,MAC3C;AAAA,IACF,OAAO;AACL,oBAAc;AAAA,IAChB;AAEA,QAAI,aAAa;AACf,kBAAY,SAAS;AAAA,IACvB;AAEA,QAAI,KAAK,UAAU,gBAAgB,QAAW;AAC5C,kBAAY,cAAc,KAAK,UAAU;AAAA,IAC3C;AAEA,QAAI,MAAM,SAAS,QAAW;AAC5B,kBAAY,OAAO,KAAK;AAAA,IAC1B;AACA,QAAI,MAAM,UAAU,QAAW;AAC7B,kBAAY,QAAQ,KAAK;AAAA,IAC3B;AACA,QAAI,MAAM,aAAa,QAAW;AAChC,kBAAY,WAAW,KAAK;AAAA,IAC9B;AACA,QAAI,MAAM,aAAa,QAAW;AAChC,kBAAY,WAAW,KAAK;AAAA,IAC9B;AACA,QAAI,MAAM,mBAAmB,QAAW;AACtC,kBAAY,iBAAiB,KAAK;AAAA,IACpC;AACA,QAAI,MAAM,cAAc,QAAW;AACjC,kBAAY,YAAY,KAAK;AAAA,IAC/B;AACA,QAAI,MAAM,cAAc,QAAW;AACjC,kBAAY,YAAY,KAAK;AAAA,IAC/B;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,UAAU,MAAM,KAAK,WAAW;AAE5D,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,WAAW,MAAM,KAAK,YAAY,QAAQ;AAChD,cAAM,YAAY,IAAI;AAAA,UACpB,SAAS;AAAA,UACT,SAAS;AAAA,UACT;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AAIA,cAAM,cAAc,MAAM,QAAQ,YAAY;AAC9C,YACE,SAAS,WAAW,OACpB,KAAK,UAAU,gBACf,SAAS,QAAQ,IAAI,cAAc,MAAM,mBACzC,aAAa,sBACb,CAAC;AAAA,QACD,CAAC,aACD;AACA,cAAI;AAEF,gBAAI,iBAAiB,KAAK;AAC1B,gBAAI,CAAC,gBAAgB;AACnB,+BAAiB,KAAK,UAAU,aAAa;AAC7C,mBAAK,sBAAsB;AAAA,YAC7B;AAGA,kBAAM,WAAW,MAAM;AAGvB,gBAAI,CAAC,YAAY,SAAS,KAAK,MAAM,IAAI;AAEvC,mBAAK,sBAAsB;AAC3B,mBAAK,wBAAwB;AAC7B,oBAAM,IAAI,MAAM,oCAAoC;AAAA,YACtD;AAIA,gBAAI,CAAC,KAAK,UAAU,gBAAgB;AAElC,mBAAK,sBAAsB;AAC3B,mBAAK,wBAAwB;AAC7B,oBAAM,IAAI;AAAA,gBACR;AAAA,cAEF;AAAA,YACF;AAIA,gBAAI,wBAAwB,KAAK;AACjC,gBAAI,CAAC,uBAAuB;AAC1B,sCAAwB,KAAK,UAAU,eAAe,QAAQ;AAC9D,mBAAK,wBAAwB;AAAA,YAC/B;AAKA,kBAAM;AAGN,iBAAK,sBAAsB;AAC3B,iBAAK,wBAAwB;AAK7B,kBAAM,YAAY,MAAM,aAAa,KAAK,UAAU;AACpD,gBAAI,aAAa,qBAAqB,QAAW;AAC/C,oBAAM,UAAU,KAAK,IAAI,IAAI;AAC7B,oBAAM,YAAY,YAAY;AAC9B,kBAAI,aAAa,GAAG;AAGlB,sBAAM;AAAA,cACR;AAAA,YACF;AAIA,mBAAO,KAAK,YAAe,MAAM,MAAM,aAAa,GAAG,SAAS;AAAA,UAClE,SAAS,cAAc;AAErB,iBAAK,sBAAsB;AAC3B,iBAAK,wBAAwB;AAE7B,gBAAI,wBAAwB,SAAS,aAAa,QAAQ,SAAS,gBAAgB,GAAG;AACpF,oBAAM;AAAA,YACR;AAIA,kBAAM;AAAA,UACR;AAAA,QACF;AAEA,cAAM;AAAA,MACR;AAEA,aAAO,KAAK,cAAiB,UAAU,MAAM,KAAK;AAAA,IACpD,SAAS,OAAO;AACd,UAAI,iBAAiB,WAAW;AAC9B,cAAM;AAAA,MACR;AAEA,UAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,gBAAgB,GAAG;AACtE,cAAM;AAAA,MACR;AACA,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA,IAAI,QAAQ;AAAA,QACZ,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,SAAS,MAAsB;AAErC,QAAI,KAAK,WAAW,SAAS,KAAK,KAAK,WAAW,UAAU,GAAG;AAC7D,aAAO;AAAA,IACT;AAGA,UAAM,UAAU,KAAK,UAAU;AAC/B,QAAI,KAAK,WAAW,GAAG,GAAG;AAExB,YAAM,OAAO,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AAC5D,aAAO,GAAG,IAAI,GAAG,IAAI;AAAA,IACvB,OAAO;AAEL,YAAM,OAAO,QAAQ,SAAS,GAAG,IAAI,UAAU,GAAG,OAAO;AACzD,aAAO,GAAG,IAAI,GAAG,IAAI;AAAA,IACvB;AAAA,EACF;AAAA,EAEQ,kBAAkB,MAAgD;AACxE,UAAM,UAAyB,CAAC;AAEhC,QAAI,KAAK,UAAU,oBAAoB;AACrC,cAAQ,KAAK,KAAK,UAAU,kBAAkB;AAAA,IAChD;AAEA,QAAI,MAAM,QAAQ;AAChB,cAAQ,KAAK,KAAK,MAAM;AAAA,IAC1B;AAEA,UAAM,YAAY,MAAM,aAAa,KAAK,UAAU;AACpD,QAAI,WAAW;AACb,cAAQ,KAAK,oBAAoB,SAAS,CAAC;AAAA,IAC7C;AAEA,WAAO,QAAQ,SAAS,IAAI,eAAe,OAAO,IAAI;AAAA,EACxD;AAAA,EAEA,MAAc,aACZ,aACiC;AACjC,UAAM,UAAkC;AAAA,MACtC,GAAG,KAAK,UAAU;AAAA,IACpB;AAGA,QAAI,KAAK,UAAU,cAAc;AAC/B,UAAI;AACF,cAAM,QAAQ,MAAM,KAAK,UAAU,aAAa;AAChD,YAAI,SAAS,MAAM,KAAK,MAAM,IAAI;AAChC,kBAAQ,gBAAgB,UAAU,KAAK;AAAA,QACzC;AAAA,MACF,SAAS,OAAO;AAAA,MAEhB;AAAA,IACF;AAGA,QAAI,aAAa;AACf,UAAI,uBAAuB,SAAS;AAClC,oBAAY,QAAQ,CAAC,OAAO,QAAQ;AAClC,kBAAQ,GAAG,IAAI;AAAA,QACjB,CAAC;AAAA,MACH,WAAW,MAAM,QAAQ,WAAW,GAAG;AACrC,oBAAY,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACpC,kBAAQ,GAAG,IAAI;AAAA,QACjB,CAAC;AAAA,MACH,OAAO;AACL,eAAO,OAAO,SAAS,WAAW;AAAA,MACpC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cACZ,UACA,OACY;AACZ,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,eAAQ,MAAM,SAAS,KAAK;AAAA,MAC9B,KAAK;AACH,eAAQ,MAAM,SAAS,KAAK;AAAA,MAC9B,KAAK;AACH,eAAQ,MAAM,SAAS,YAAY;AAAA,MACrC,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AAAA,MACL;AACE,eAAO,MAAM,SAAS,KAAK;AAAA,IAC/B;AAAA,EACF;AAAA,EAEA,MAAc,YAAY,UAAqC;AAC7D,QAAI;AACF,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,KAAK,SAAS,QAAQ,KAAK,MAAM,GAAG,KAAK,IAAI,QAAQ;AAAA,IAC9D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACpcO,SAAS,iBAAiB,WAAkC;AACjE,SAAO,IAAI,cAAc,SAAS;AACpC;AAGO,SAAS,wBAAwB,SAczB;AACb,QAAM,YAAuB;AAAA;AAAA;AAAA,IAG3B,OAAO,CAAC,KAAwB,SAAuB,WAAW,MAAM,KAAK,IAAI;AAAA,IACjF,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ;AAAA,IACtB,gBAAgB,QAAQ;AAAA,IACxB,cAAc,QAAQ;AAAA,IACtB,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA;AAAA,IACrB,oBAAoB,QAAQ;AAAA,EAC9B;AAEA,SAAO,iBAAiB,SAAS;AACnC;AAGO,SAAS,qBAAqB,SAetB;AAEb,QAAM,YAAY,QAAQ,SAAS,WAAW;AAE9C,MAAI,CAAC,WAAW;AACd,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAKA,QAAM,iBAAiB,cAAc,WAAW;AAEhD,QAAM,YAAuB;AAAA;AAAA;AAAA;AAAA,IAI3B,OAAO,iBACH,CAAC,KAAwB,SAAuB,WAAW,MAAM,KAAK,IAAI,IAC1E,CAAC,KAAwB,SAAuB,UAAU,KAAK,IAAI;AAAA,IACvE,SAAS,QAAQ;AAAA,IACjB,cAAc,QAAQ;AAAA,IACtB,gBAAgB,QAAQ;AAAA,IACxB,cAAc,QAAQ;AAAA,IACtB,gBAAgB,QAAQ;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA;AAAA,IACrB,oBAAoB,QAAQ;AAAA,EAC9B;AAEA,SAAO,iBAAiB,SAAS;AACnC;AAGO,SAAS,0BAA0B,SAe3B;AAEb,MAAI,OAAO,WAAW,aAAa;AAEjC,WAAO,wBAAwB,OAAO;AAAA,EACxC,OAAO;AAEL,WAAO,qBAAqB,OAAO;AAAA,EACrC;AACF;;;ACnGA,SAAS,sBAAsB,OAAc,SAA0B;AAErE,MAAI,WAAW,EAAG,QAAO;AAKzB,QAAM,gBAAgB;AACtB,QAAM,OAAO,eAAe;AAC5B,MAAI,SAAS,eAAgB,QAAO;AACpC,MAAI,SAAS,aAAc,QAAO;AAGlC,QAAM,kBAAkB;AACxB,MACE,YAAY,mBACZ,OAAO,gBAAgB,WAAW,UAClC;AACA,UAAM,SAAS,gBAAgB;AAC/B,WAAO,UAAU,OAAO,WAAW;AAAA,EACrC;AAEA,MAAI,SAAS,YAAa,QAAO;AAEjC,SAAO;AACT;AAGA,SAAS,eAAe,SAAyB;AAC/C,QAAM,cAAc;AACpB,QAAM,QAAQ,cAAc,KAAK,IAAI,GAAG,UAAU,CAAC;AAGnD,QAAM,UAAU,KAAK,OAAO,IAAI,OAAO,MAAM;AAC7C,SAAO,KAAK,IAAI,GAAG,QAAQ,MAAM;AACnC;AAGA,eAAsB,UACpB,IACA,UAAwB,CAAC,GACb;AACZ,QAAM,EAAE,WAAW,EAAE,IAAI;AAEzB,MAAI;AAEJ,WAAS,UAAU,GAAG,WAAW,UAAU,WAAW;AACpD,QAAI;AACF,aAAO,MAAM,GAAG,OAAO;AAAA,IACzB,SAAS,OAAO;AACd,kBAAY;AAGZ,UAAI,CAAC,sBAAsB,WAAW,WAAW,OAAO,GAAG;AACzD,cAAM;AAAA,MACR;AAGA,UAAI,UAAU,eAAe,OAAO;AAGpC,YAAM,mBAAmB;AACzB,YAAM,OAAO,iBAAiB;AAC9B,YAAM,aAAa,MAAM,MAAM,aAAa;AAC5C,UAAI,YAAY;AAEd,cAAM,UAAU,SAAS,YAAY,EAAE;AACvC,YAAI,CAAC,MAAM,OAAO,GAAG;AACnB,oBAAU,KAAK,IAAI,SAAS,UAAU,GAAI;AAAA,QAC5C,OAAO;AAEL,gBAAM,OAAO,IAAI,KAAK,UAAU;AAChC,cAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,GAAG;AAC1B,kBAAM,WAAW,KAAK,IAAI,GAAG,KAAK,QAAQ,IAAI,KAAK,IAAI,CAAC;AAExD,sBAAU,KAAK,IAAI,SAAS,KAAK,IAAI,UAAU,GAAK,CAAC;AAAA,UACvD;AAAA,QACF;AAAA,MACF;AAGA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,OAAO,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,MAAM,4BAA4B;AAC3D;AAGO,SAAS,sBACd,QACA,eAA6B,CAAC,GAC9B;AACA,SAAO,UAAU,SAAwB;AACvC,WAAO,UAAU,MAAM,OAAO,GAAG,IAAI,GAAG,YAAY;AAAA,EACtD;AACF;;;AClFO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAAoB,YAAwB;AAAxB;AAAA,EAAyB;AAAA;AAAA,EAG7C,MAAM,YAAqC;AACzC,UAAM,WACJ,MAAM,KAAK,WAAW,IAAiC,cAAc;AACvE,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,cAAyC;AAC7C,UAAM,WACJ,MAAM,KAAK,WAAW;AAAA,MACpB;AAAA,IACF;AACF,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,eAA2C;AAC/C,UAAM,WACJ,MAAM,KAAK,WAAW;AAAA,MACpB;AAAA,IACF;AACF,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,eAAgC;AACpC,WAAO,KAAK,WAAW,IAAY,eAAe,EAAE,OAAO,OAAO,CAAC;AAAA,EACrE;AAAA,EAEA,MAAM,eAAe,SAA+C;AAClE,WAAO,KAAK,WAAW,KAAoB,eAAe,OAAO;AAAA,EACnE;AAAA,EAEA,MAAM,aAAa,SAAsD;AACvE,WAAO,KAAK,WAAW,KAAoB,iBAAiB,OAAO;AAAA,EACrE;AAAA,EAEA,MAAM,mBAAmB,SAAmD;AAC1E,WAAO,KAAK,WAAW,KAAoB,oBAAoB,OAAO;AAAA,EACxE;AAAA,EAEA,MAAM,eAA2C;AAC/C,WAAO,KAAK,WAAW,IAAuB,iBAAiB;AAAA,EACjE;AAAA,EAEA,MAAM,cAAc,OAIjB;AACD,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,iBAAiB,KAAK;AAClD,aAAO;AAAA,QACL,OAAO,SAAS,WAAW;AAAA,QAC3B,SAAS,SAAS;AAAA,QAClB,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,OAAO;AAAA,QACP,SAAS,CAAC;AAAA,QACV,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,iBACJ,OAC8D;AAC9D,UAAM,WAAW,MAAM,KAAK,WAAW,KAAK,kBAAkB;AAAA,MAC5D,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,IAC9C,CAAC;AACD,WAAO;AAAA,MACL,QAAQ,SAAS;AAAA,MACjB,SAAS,SAAS;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,WAAgC;AACpC,WAAO,KAAK,WAAW,IAAgB,iBAAiB;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,aACJ,SAC8B;AAC9B,WAAO,KAAK,WAAW,KAA0B,iBAAiB,OAAO;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,eAA0C;AAC9C,UAAM,WACJ,MAAM,KAAK,WAAW,IAAmC,aAAa;AACxE,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,cAAc,SAAuD;AACzE,WAAO,KAAK,WAAW,KAAwB,eAAe,OAAO;AAAA,EACvE;AAAA,EAEA,MAAM,cAAc,OAA2C;AAC7D,WAAO,KAAK,WAAW,OAA0B,eAAe,KAAK,EAAE;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,iBAA8C;AAClD,UAAM,WAAW,MAAM,KAAK,WAAW;AAAA,MACrC;AAAA,IACF;AACA,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,kBACJ,SACwB;AACxB,WAAO,KAAK,WAAW,KAAoB,qBAAqB,OAAO;AAAA,EACzE;AAAA,EAEA,MAAM,gBACJ,OACA,UAC+B;AAC/B,WAAO,KAAK,WAAW;AAAA,MACrB,eAAe,KAAK,YAAY,QAAQ;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,kBAAkB,OAA4C;AAClE,WAAO,KAAK,WAAW;AAAA,MACrB,eAAe,KAAK;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,qBACJ,OACA,aAC6B;AAC7B,WAAO,KAAK,WAAW;AAAA,MACrB,eAAe,KAAK;AAAA,MACpB,EAAE,YAAY;AAAA,IAChB;AAAA,EACF;AACF;;;AC5LA,IAAM,iBAAN,MAA2C;AAAA,EACzC,MAAM,MAAqB;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAsB;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,MAAqB;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,SAAwB;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,QAAuB;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAqE;AACzE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,UAAyB;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,2BACd,SACe;AACf,QAAM,aAAa,IAAI,eAAe;AACtC,SAAO,IAAI,cAAc,UAAU;AACrC;AAEO,SAAS,wBACd,SACe;AACf,QAAM,aAAa,IAAI,eAAe;AACtC,SAAO,IAAI,cAAc,UAAU;AACrC;AAEO,SAAS,oBACd,SACe;AACf,QAAM,aAAa,IAAI,eAAe;AACtC,SAAO,IAAI,cAAc,UAAU;AACrC;AAEO,SAAS,kCACd,YACA,SACe;AACf,SAAO,IAAI,cAAc,UAAU;AACrC;;;AClBO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAAoB,YAAwB;AAAxB;AAAA,EAAyB;AAAA;AAAA,EAG7C,MAAM,cAAqC;AACzC,UAAM,WACJ,MAAM,KAAK,WAAW,IAA+B,SAAS;AAChE,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AACA,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,WAAqC;AACzC,WAAO,KAAK,WAAW,IAAqB,YAAY;AAAA,EAC1D;AAAA;AAAA,EAGA,MAAM,mBACJ,SACqC;AACrC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,sBACJ,SACqC;AACrC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,qBACJ,OACuC;AACvC,WAAO,KAAK,WAAW;AAAA,MACrB,iBAAiB,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,mBAAsD;AAC1D,WAAO,KAAK,WAAW,IAA8B,eAAe;AAAA,EACtE;AAAA,EAEA,MAAM,eAAe,OAAgD;AACnE,WAAO,KAAK,WAAW;AAAA,MACrB,iBAAiB,KAAK;AAAA,IACxB;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cACJ,SACgC;AAChC,WAAO,KAAK,WAAW,KAA4B,aAAa,OAAO;AAAA,EACzE;AAAA,EAEA,MAAM,cAAc,WAAmD;AACrE,WAAO,KAAK,WAAW;AAAA,MACrB,aAAa,SAAS;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAM,cAA6C;AACjD,WAAO,KAAK,WAAW,IAA0B,WAAW;AAAA,EAC9D;AAAA,EAEA,MAAM,WAAW,WAAgD;AAC/D,WAAO,KAAK,WAAW,IAAwB,aAAa,SAAS,EAAE;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,WAAW,SAAyD;AACxE,WAAO,KAAK,WAAW,KAAyB,UAAU,OAAO;AAAA,EACnE;AAAA,EAEA,MAAM,WAAW,QAA6C;AAC5D,WAAO,KAAK,WAAW,OAA2B,UAAU,MAAM,EAAE;AAAA,EACtE;AAAA,EAEA,MAAM,YAAwC;AAC5C,WAAO,KAAK,WAAW,IAAuB,QAAQ;AAAA,EACxD;AAAA,EAEA,MAAM,QAAQ,QAA0C;AACtD,WAAO,KAAK,WAAW,IAAqB,UAAU,MAAM,EAAE;AAAA,EAChE;AAAA;AAAA,EAGA,MAAM,YAAY,SAA2D;AAC3E,WAAO,KAAK,WAAW,KAA0B,UAAU,OAAO;AAAA,EACpE;AAAA,EAEA,MAAM,YAAY,SAA+C;AAC/D,WAAO,KAAK,WAAW,OAA4B,UAAU,OAAO,EAAE;AAAA,EACxE;AAAA,EAEA,MAAM,cAA4C;AAChD,WAAO,KAAK,WAAW,IAAyB,QAAQ;AAAA,EAC1D;AAAA,EAEA,MAAM,SAAS,SAA4C;AACzD,WAAO,KAAK,WAAW,IAAsB,UAAU,OAAO,EAAE;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,kBAAoD;AACxD,WAAO,KAAK,WAAW,IAA6B,gBAAgB;AAAA,EACtE;AAAA,EAEA,MAAM,kBAAoD;AACxD,WAAO,KAAK,WAAW,IAA6B,gBAAgB;AAAA,EACtE;AAAA,EAEA,MAAM,mBAAsD;AAC1D,WAAO,KAAK,WAAW,IAA8B,iBAAiB;AAAA,EACxE;AAAA,EAEA,MAAM,oBACJ,SACsC;AACtC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,gBAA4C;AAChD,WAAO,KAAK,WAAW,IAAuB,sBAAsB;AAAA,EACtE;AAAA;AAAA,EAGA,MAAM,gBAAgD;AACpD,WAAO,KAAK,WAAW,IAA2B,cAAc;AAAA,EAClE;AAAA,EAEA,MAAM,gBAAgD;AACpD,WAAO,KAAK,WAAW,IAA2B,cAAc;AAAA,EAClE;AAAA,EAEA,MAAM,mBAAsD;AAC1D,WAAO,KAAK,WAAW,IAA8B,iBAAiB;AAAA,EACxE;AAAA,EAEA,MAAM,gBAAgD;AACpD,WAAO,KAAK,WAAW,KAA4B,iBAAiB;AAAA,EACtE;AAAA,EAEA,MAAM,iBAAkD;AACtD,WAAO,KAAK,WAAW,KAA6B,kBAAkB;AAAA,EACxE;AACF;;;AC1MA,IAAMA,kBAAN,MAA2C;AAAA,EACzC,MAAM,MAAqB;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAsB;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,MAAqB;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,SAAwB;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,QAAuB;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAqE;AACzE,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,UAAyB;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAGO,SAAS,4BACd,SACgB;AAChB,QAAM,aAAa,IAAIA,gBAAe;AACtC,SAAO,IAAI,eAAe,UAAU;AACtC;AAEO,SAAS,yBACd,SACgB;AAChB,QAAM,aAAa,IAAIA,gBAAe;AACtC,SAAO,IAAI,eAAe,UAAU;AACtC;AAEO,SAAS,qBACd,SACgB;AAChB,QAAM,aAAa,IAAIA,gBAAe;AACtC,SAAO,IAAI,eAAe,UAAU;AACtC;AAEO,SAAS,mCACd,YACA,SACgB;AAChB,SAAO,IAAI,eAAe,UAAU;AACtC;;;ACxCO,IAAM,SAAN,MAAa;AAAA,EAQlB,YAAY,QAAsB;AAHlC,SAAQ,YAA8B;AACtC,SAAQ,iBAA4C;AAGlD,SAAK,SAAS;AAAA,MACZ,WAAW;AAAA,MACX,GAAG;AAAA,IACL;AAIA,UAAM,UAAU,OAAO,WAAW,eAAe,yBAAyB;AAC1E,SAAK,aAAa,wBAAwB;AAAA,MACxC,SAAS,KAAK,OAAO;AAAA,MACrB,cAAc,YAAY;AACxB,cAAM,QAAQ,MAAM,KAAK,cAAc;AACvC,eAAO,OAAO,gBAAgB;AAAA,MAChC;AAAA,MACA,WAAW,KAAK,OAAO;AAAA,MACvB,aAAa,KAAK,OAAO,uBAAuB,UAAU,SAAS;AAAA,IACrE,CAAC;AAGD,SAAK,aAAa,kCAAkC,KAAK,YAAY;AAAA,MACnE,SAAS,KAAK,OAAO;AAAA,MACrB,cAAc,YAAY;AACxB,cAAM,QAAQ,MAAM,KAAK,cAAc;AACvC,eAAO,OAAO,gBAAgB;AAAA,MAChC;AAAA,MACA,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AAED,SAAK,cAAc,mCAAmC,KAAK,YAAY;AAAA,MACrE,SAAS,KAAK,OAAO;AAAA,MACrB,cAAc,YAAY;AACxB,cAAM,QAAQ,MAAM,KAAK,cAAc;AACvC,eAAO,OAAO,gBAAgB;AAAA,MAChC;AAAA,MACA,WAAW,KAAK,OAAO;AAAA,IACzB,CAAC;AAAA,EAGH;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAwB;AAC1B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,aAGI;AACrB,UAAM,QAAQ,eAAe,KAAK,OAAO;AACzC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,4CAA4C;AAAA,IAC9D;AAEA,QAAI;AACF,YAAM,cAAc;AAAA,QAClB,aAAa;AAAA,QACb,YAAY,MAAM;AAAA,QAClB,aAAa;AAAA,QACb,aAAa,CAAC,OAAO;AAAA,QACrB,WAAW,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAAA,QACvC,eAAe;AAAA,UACb,UAAU,MAAM;AAAA,UAChB,UAAU,MAAM;AAAA,QAClB;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,KAAK,WAAW,eAAe,WAAW;AAEjE,WAAK,YAAY;AAAA,QACf,cAAc,SAAS,KAAK;AAAA,QAC5B,eAAe,SAAS,KAAK;AAAA,QAC7B,YAAY,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK;AAAA;AAAA,MAC1C;AAEA,aAAO,KAAK;AAAA,IACd,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBAA2C;AACvD,QAAI,CAAC,KAAK,WAAW;AACnB,aAAO;AAAA,IACT;AAGA,UAAM,aAAa,IAAI,KAAK;AAC5B,QAAI,KAAK,IAAI,KAAK,KAAK,UAAU,aAAa,YAAY;AACxD,aAAO,MAAM,KAAK,aAAa;AAAA,IACjC;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eAAmC;AAC/C,QAAI,CAAC,KAAK,WAAW,eAAe;AAClC,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAGA,QAAI,KAAK,gBAAgB;AACvB,aAAO,KAAK;AAAA,IACd;AAEA,SAAK,iBAAiB,KAAK,oBAAoB;AAE/C,QAAI;AACF,YAAM,WAAW,MAAM,KAAK;AAC5B,aAAO;AAAA,IACT,UAAE;AACA,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,sBAA0C;AACtD,QAAI,CAAC,KAAK,WAAW,eAAe;AAClC,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAEA,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,WAAW,aAAa;AAAA,QAClD,cAAc,KAAK,UAAU;AAAA,QAC7B,eAAe,KAAK,UAAU;AAAA,MAChC,CAAC;AAED,WAAK,YAAY;AAAA,QACf,cAAc,SAAS,KAAK;AAAA,QAC5B,eAAe,SAAS,KAAK;AAAA,QAC7B,YAAY,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK;AAAA;AAAA,MAC1C;AAEA,aAAO,KAAK;AAAA,IACd,SAAS,OAAO;AAEd,WAAK,WAAW;AAChB,YAAM,IAAI;AAAA,QACR,yBAAyB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,aAAmB;AACxB,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKO,kBAA2B;AAChC,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKO,eAAiC;AACtC,WAAO,KAAK;AAAA,EACd;AACF;AAKO,SAAS,aAAa,QAA8B;AACzD,SAAO,IAAI,OAAO,MAAM;AAC1B;",
6
+ "names": ["MockHttpClient"]
7
7
  }
package/dist/index.mjs CHANGED
@@ -62,6 +62,10 @@ function headersToRecord(headers) {
62
62
  var WebHttpClient = class {
63
63
  constructor(transport) {
64
64
  this.transport = transport;
65
+ // Cache for concurrent refresh token calls to prevent race conditions
66
+ this.refreshTokenPromise = null;
67
+ // Cache for concurrent onTokenRefresh calls to prevent duplicate callbacks
68
+ this.onTokenRefreshPromise = null;
65
69
  }
66
70
  async get(path, init) {
67
71
  return this.request(path, { ...init, method: "GET" });
@@ -116,61 +120,10 @@ var WebHttpClient = class {
116
120
  async request(path, init) {
117
121
  return this.makeRequest(path, init);
118
122
  }
119
- async makeRequest(path, init) {
123
+ async makeRequest(path, init, retryCount = 0, requestStartTime) {
124
+ const MAX_RETRY_ATTEMPTS = 1;
120
125
  const url = this.buildUrl(path);
121
- const hasTauriInternals = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
122
- const hasTauri = typeof window !== "undefined" && "__TAURI__" in window;
123
- const isTauri = hasTauriInternals || hasTauri || this.transport.credentials === "omit";
124
- if (isTauri) {
125
- const headers2 = await this.buildHeaders(init?.headers);
126
- let headersObj2;
127
- if (headers2 instanceof Headers) {
128
- headersObj2 = {};
129
- headers2.forEach((value, key) => {
130
- headersObj2[key] = value;
131
- });
132
- } else {
133
- headersObj2 = headers2;
134
- }
135
- const requestInit2 = {};
136
- if (init?.method && init.method !== "GET") {
137
- requestInit2.method = init.method;
138
- }
139
- if (headersObj2 && Object.keys(headersObj2).length > 0) {
140
- requestInit2.headers = headersObj2;
141
- }
142
- if (init?.body !== void 0 && init.body !== null) {
143
- requestInit2.body = init.body;
144
- }
145
- if (this.transport.credentials !== void 0) {
146
- requestInit2.credentials = this.transport.credentials;
147
- }
148
- try {
149
- const response = await globalThis.fetch(url, requestInit2);
150
- if (!response.ok) {
151
- const bodyText = await this.getBodyText(response);
152
- throw new HTTPError(
153
- response.status,
154
- response.statusText,
155
- url,
156
- response.headers,
157
- bodyText
158
- );
159
- }
160
- return this.parseResponse(response, init?.parse);
161
- } catch (error) {
162
- if (error instanceof HTTPError) {
163
- throw error;
164
- }
165
- throw new HTTPError(
166
- 0,
167
- "Network Error",
168
- url,
169
- new Headers(),
170
- error instanceof Error ? error.message : "Unknown error"
171
- );
172
- }
173
- }
126
+ const startTime = requestStartTime ?? Date.now();
174
127
  const signal = this.createAbortSignal(init);
175
128
  const headers = await this.buildHeaders(init?.headers);
176
129
  let headersObj;
@@ -186,11 +139,27 @@ var WebHttpClient = class {
186
139
  method: init?.method || "GET",
187
140
  headers: headersObj
188
141
  };
189
- if (init?.body !== void 0) {
142
+ const isStreamBody = init?.body instanceof ReadableStream || typeof init?.body === "object" && init?.body !== null && "getReader" in init.body && !(init.body instanceof Blob);
143
+ if (init?.body !== void 0 && !isStreamBody) {
190
144
  requestInit.body = init.body;
145
+ } else if (init?.body !== void 0 && isStreamBody && retryCount === 0) {
146
+ requestInit.body = init.body;
147
+ }
148
+ let retrySignal;
149
+ if (retryCount > 0 && requestStartTime !== void 0) {
150
+ const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;
151
+ if (timeoutMs) {
152
+ const elapsed = Date.now() - startTime;
153
+ const remaining = Math.max(0, timeoutMs - elapsed);
154
+ retrySignal = this.createAbortSignal({ ...init, timeoutMs: remaining });
155
+ } else {
156
+ retrySignal = this.createAbortSignal(init);
157
+ }
158
+ } else {
159
+ retrySignal = signal;
191
160
  }
192
- if (signal) {
193
- requestInit.signal = signal;
161
+ if (retrySignal) {
162
+ requestInit.signal = retrySignal;
194
163
  }
195
164
  if (this.transport.credentials !== void 0) {
196
165
  requestInit.credentials = this.transport.credentials;
@@ -220,19 +189,71 @@ var WebHttpClient = class {
220
189
  const response = await this.transport.fetch(url, requestInit);
221
190
  if (!response.ok) {
222
191
  const bodyText = await this.getBodyText(response);
223
- throw new HTTPError(
192
+ const httpError = new HTTPError(
224
193
  response.status,
225
194
  response.statusText,
226
195
  url,
227
196
  response.headers,
228
197
  bodyText
229
198
  );
199
+ const userAborted = init?.signal?.aborted === true;
200
+ if (response.status === 401 && this.transport.refreshToken && response.headers.get("x-auth-error") === "token_expired" && retryCount < MAX_RETRY_ATTEMPTS && !isStreamBody && // Can't retry with stream bodies
201
+ !userAborted) {
202
+ try {
203
+ let refreshPromise = this.refreshTokenPromise;
204
+ if (!refreshPromise) {
205
+ refreshPromise = this.transport.refreshToken();
206
+ this.refreshTokenPromise = refreshPromise;
207
+ }
208
+ const newToken = await refreshPromise;
209
+ if (!newToken || newToken.trim() === "") {
210
+ this.refreshTokenPromise = null;
211
+ this.onTokenRefreshPromise = null;
212
+ throw new Error("Refresh token returned empty token");
213
+ }
214
+ if (!this.transport.onTokenRefresh) {
215
+ this.refreshTokenPromise = null;
216
+ this.onTokenRefreshPromise = null;
217
+ throw new Error(
218
+ "onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token."
219
+ );
220
+ }
221
+ let onTokenRefreshPromise = this.onTokenRefreshPromise;
222
+ if (!onTokenRefreshPromise) {
223
+ onTokenRefreshPromise = this.transport.onTokenRefresh(newToken);
224
+ this.onTokenRefreshPromise = onTokenRefreshPromise;
225
+ }
226
+ await onTokenRefreshPromise;
227
+ this.refreshTokenPromise = null;
228
+ this.onTokenRefreshPromise = null;
229
+ const timeoutMs = init?.timeoutMs || this.transport.timeoutMs;
230
+ if (timeoutMs && requestStartTime !== void 0) {
231
+ const elapsed = Date.now() - startTime;
232
+ const remaining = timeoutMs - elapsed;
233
+ if (remaining <= 0) {
234
+ throw httpError;
235
+ }
236
+ }
237
+ return this.makeRequest(path, init, retryCount + 1, startTime);
238
+ } catch (refreshError) {
239
+ this.refreshTokenPromise = null;
240
+ this.onTokenRefreshPromise = null;
241
+ if (refreshError instanceof Error && refreshError.message.includes("onTokenRefresh")) {
242
+ throw refreshError;
243
+ }
244
+ throw httpError;
245
+ }
246
+ }
247
+ throw httpError;
230
248
  }
231
249
  return this.parseResponse(response, init?.parse);
232
250
  } catch (error) {
233
251
  if (error instanceof HTTPError) {
234
252
  throw error;
235
253
  }
254
+ if (error instanceof Error && error.message.includes("onTokenRefresh")) {
255
+ throw error;
256
+ }
236
257
  throw new HTTPError(
237
258
  0,
238
259
  "Network Error",
@@ -256,10 +277,6 @@ var WebHttpClient = class {
256
277
  }
257
278
  }
258
279
  createAbortSignal(init) {
259
- const isTauri = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
260
- if (isTauri) {
261
- return void 0;
262
- }
263
280
  const signals = [];
264
281
  if (this.transport.defaultAbortSignal) {
265
282
  signals.push(this.transport.defaultAbortSignal);
@@ -332,10 +349,13 @@ function createHttpClient(transport) {
332
349
  }
333
350
  function createBrowserHttpClient(options) {
334
351
  const transport = {
335
- fetch: globalThis.fetch,
352
+ // Wrap fetch in arrow function to prevent "Illegal invocation" error
353
+ // This preserves the correct 'this' context when fetch is called
354
+ fetch: (url, init) => globalThis.fetch(url, init),
336
355
  baseUrl: options.baseUrl,
337
356
  getAuthToken: options.getAuthToken,
338
357
  onTokenRefresh: options.onTokenRefresh,
358
+ refreshToken: options.refreshToken,
339
359
  defaultHeaders: options.defaultHeaders,
340
360
  timeoutMs: options.timeoutMs,
341
361
  credentials: options.credentials,
@@ -351,11 +371,16 @@ function createNodeHttpClient(options) {
351
371
  "No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support."
352
372
  );
353
373
  }
374
+ const isDefaultFetch = fetchImpl === globalThis.fetch;
354
375
  const transport = {
355
- fetch: fetchImpl,
376
+ // Wrap fetch in arrow function to prevent "Illegal invocation" error
377
+ // For globalThis.fetch, call it directly to preserve 'this' context
378
+ // For custom implementations, calling through the variable is safe
379
+ fetch: isDefaultFetch ? (url, init) => globalThis.fetch(url, init) : (url, init) => fetchImpl(url, init),
356
380
  baseUrl: options.baseUrl,
357
381
  getAuthToken: options.getAuthToken,
358
382
  onTokenRefresh: options.onTokenRefresh,
383
+ refreshToken: options.refreshToken,
359
384
  defaultHeaders: options.defaultHeaders,
360
385
  timeoutMs: options.timeoutMs,
361
386
  credentials: options.credentials,