@blimu/client 1.1.4 → 1.2.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.
Files changed (46) hide show
  1. package/dist/client-DKebla0_.d.ts +33 -0
  2. package/dist/client-iMSJXw0U.d.mts +33 -0
  3. package/dist/client.cjs.map +1 -1
  4. package/dist/client.d.mts +1 -16
  5. package/dist/client.d.ts +1 -16
  6. package/dist/client.mjs.map +1 -1
  7. package/dist/index.cjs +6 -6
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.mts +45 -5
  10. package/dist/index.d.ts +45 -5
  11. package/dist/index.mjs +3 -3
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/tsconfig.tsbuildinfo +1 -1
  14. package/package.json +2 -2
  15. package/dist/__tests__/example.test.cjs +0 -17135
  16. package/dist/__tests__/example.test.cjs.map +0 -1
  17. package/dist/__tests__/example.test.d.mts +0 -2
  18. package/dist/__tests__/example.test.d.ts +0 -2
  19. package/dist/__tests__/example.test.mjs +0 -17134
  20. package/dist/__tests__/example.test.mjs.map +0 -1
  21. package/dist/auth-strategies.cjs +0 -40
  22. package/dist/auth-strategies.cjs.map +0 -1
  23. package/dist/auth-strategies.d.mts +0 -9
  24. package/dist/auth-strategies.d.ts +0 -9
  25. package/dist/auth-strategies.mjs +0 -15
  26. package/dist/auth-strategies.mjs.map +0 -1
  27. package/dist/schema.zod-BaQz36Pd.d.mts +0 -44
  28. package/dist/schema.zod-BaQz36Pd.d.ts +0 -44
  29. package/dist/schema.zod.cjs +0 -67
  30. package/dist/schema.zod.cjs.map +0 -1
  31. package/dist/schema.zod.d.mts +0 -2
  32. package/dist/schema.zod.d.ts +0 -2
  33. package/dist/schema.zod.mjs +0 -39
  34. package/dist/schema.zod.mjs.map +0 -1
  35. package/dist/services/auth.cjs +0 -97
  36. package/dist/services/auth.cjs.map +0 -1
  37. package/dist/services/auth.d.mts +0 -15
  38. package/dist/services/auth.d.ts +0 -15
  39. package/dist/services/auth.mjs +0 -70
  40. package/dist/services/auth.mjs.map +0 -1
  41. package/dist/services/entitlements.cjs +0 -53
  42. package/dist/services/entitlements.cjs.map +0 -1
  43. package/dist/services/entitlements.d.mts +0 -11
  44. package/dist/services/entitlements.d.ts +0 -11
  45. package/dist/services/entitlements.mjs +0 -28
  46. package/dist/services/entitlements.mjs.map +0 -1
@@ -0,0 +1,33 @@
1
+ import { FetchClient, FetchClientConfig, BearerAuthStrategy, FetchError } from '@blimu/fetch';
2
+ import { A as AuthRefreshQuery, R as RefreshResponse, S as SessionResponse, E as EntitlementsListResult } from './schema-Z0doltxY.js';
3
+
4
+ declare class AuthService {
5
+ private core;
6
+ constructor(core: FetchClient);
7
+ logout(init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown>;
8
+ logout__queryKeys(): readonly ['v1/auth/logout'];
9
+ refresh(query?: AuthRefreshQuery, init?: Omit<RequestInit, 'method' | 'body'>): Promise<RefreshResponse>;
10
+ refresh__queryKeys(query?: AuthRefreshQuery): readonly string[];
11
+ getSession(init?: Omit<RequestInit, 'method' | 'body'>): Promise<SessionResponse>;
12
+ getSession__queryKeys(): readonly ['v1/auth/session'];
13
+ }
14
+
15
+ declare class EntitlementsService {
16
+ private core;
17
+ constructor(core: FetchClient);
18
+ listForTenant(tenantResourceId: string, init?: Omit<RequestInit, 'method' | 'body'>): Promise<EntitlementsListResult>;
19
+ listForTenant__queryKeys(tenantResourceId: string): readonly ['v1/client/entitlements/list-for-tenant', string];
20
+ }
21
+
22
+ type ClientOption = FetchClientConfig & {
23
+ bearer?: BearerAuthStrategy['token'];
24
+ };
25
+ declare class Blimu {
26
+ readonly auth: AuthService;
27
+ readonly entitlements: EntitlementsService;
28
+ constructor(options?: ClientOption);
29
+ }
30
+
31
+ declare const BlimuError: typeof FetchError;
32
+
33
+ export { AuthService as A, Blimu as B, type ClientOption as C, EntitlementsService as E, BlimuError as a };
@@ -0,0 +1,33 @@
1
+ import { FetchClient, FetchClientConfig, BearerAuthStrategy, FetchError } from '@blimu/fetch';
2
+ import { A as AuthRefreshQuery, R as RefreshResponse, S as SessionResponse, E as EntitlementsListResult } from './schema-Z0doltxY.mjs';
3
+
4
+ declare class AuthService {
5
+ private core;
6
+ constructor(core: FetchClient);
7
+ logout(init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown>;
8
+ logout__queryKeys(): readonly ['v1/auth/logout'];
9
+ refresh(query?: AuthRefreshQuery, init?: Omit<RequestInit, 'method' | 'body'>): Promise<RefreshResponse>;
10
+ refresh__queryKeys(query?: AuthRefreshQuery): readonly string[];
11
+ getSession(init?: Omit<RequestInit, 'method' | 'body'>): Promise<SessionResponse>;
12
+ getSession__queryKeys(): readonly ['v1/auth/session'];
13
+ }
14
+
15
+ declare class EntitlementsService {
16
+ private core;
17
+ constructor(core: FetchClient);
18
+ listForTenant(tenantResourceId: string, init?: Omit<RequestInit, 'method' | 'body'>): Promise<EntitlementsListResult>;
19
+ listForTenant__queryKeys(tenantResourceId: string): readonly ['v1/client/entitlements/list-for-tenant', string];
20
+ }
21
+
22
+ type ClientOption = FetchClientConfig & {
23
+ bearer?: BearerAuthStrategy['token'];
24
+ };
25
+ declare class Blimu {
26
+ readonly auth: AuthService;
27
+ readonly entitlements: EntitlementsService;
28
+ constructor(options?: ClientOption);
29
+ }
30
+
31
+ declare const BlimuError: typeof FetchError;
32
+
33
+ export { AuthService as A, Blimu as B, type ClientOption as C, EntitlementsService as E, BlimuError as a };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../../../node_modules/@blimu/fetch/src/errors.ts","../../../node_modules/@blimu/fetch/src/hooks/registry.ts","../../../node_modules/@blimu/fetch/src/retry/strategies.ts","../../../node_modules/@blimu/fetch/src/streaming/parsers.ts","../../../node_modules/@blimu/fetch/src/utils/environment.ts","../../../node_modules/@blimu/fetch/src/utils/request.ts","../../../node_modules/@blimu/fetch/src/utils/response.ts","../../../node_modules/@blimu/fetch/src/client.ts","../src/auth-strategies.ts","../src/utils.ts","../src/services/auth.ts","../src/services/entitlements.ts"],"sourcesContent":["import { FetchClient, FetchError } from '@blimu/fetch';\nimport { type FetchClientConfig, type BearerAuthStrategy } from '@blimu/fetch';\nimport { buildAuthStrategies } from './auth-strategies';\nimport { AuthService } from './services/auth';\nimport { EntitlementsService } from './services/entitlements';\n\nexport type ClientOption = FetchClientConfig & {\n bearer?: BearerAuthStrategy['token'];\n};\n\nexport class Blimu {\n readonly auth: AuthService;\n readonly entitlements: EntitlementsService;\n\n constructor(options?: ClientOption) {\n const restCfg = { ...(options ?? {}) };\n delete restCfg.bearer;\n\n const authStrategies = buildAuthStrategies(options ?? {});\n\n const core = new FetchClient({\n ...restCfg,\n baseURL: options?.baseURL ?? 'https://api.blimu.dev',\n ...(authStrategies.length > 0 ? { authStrategies } : {}),\n });\n\n this.auth = new AuthService(core);\n this.entitlements = new EntitlementsService(core);\n }\n}\n\n// Re-export FetchError for backward compatibility\nexport { FetchError };\nexport const BlimuError = FetchError;\n","/**\n * Base error class for all fetch-related errors\n */\nexport class FetchError<T = unknown> extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly data?: T,\n public readonly headers?: Headers\n ) {\n super(message);\n this.name = 'FetchError';\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, FetchError);\n }\n }\n}\n\n/**\n * Base class for all 4xx client errors\n */\nexport class ClientError<T = unknown> extends FetchError<T> {\n constructor(message: string, status: number, data?: T, headers?: Headers) {\n super(message, status, data, headers);\n this.name = 'ClientError';\n }\n}\n\n/**\n * Base class for all 5xx server errors\n */\nexport class ServerError<T = unknown> extends FetchError<T> {\n constructor(message: string, status: number, data?: T, headers?: Headers) {\n super(message, status, data, headers);\n this.name = 'ServerError';\n }\n}\n\n// 4xx Client Errors\nexport class BadRequestError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Bad Request', data?: T, headers?: Headers) {\n super(message, 400, data, headers);\n this.name = 'BadRequestError';\n }\n}\n\nexport class UnauthorizedError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Unauthorized', data?: T, headers?: Headers) {\n super(message, 401, data, headers);\n this.name = 'UnauthorizedError';\n }\n}\n\nexport class ForbiddenError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Forbidden', data?: T, headers?: Headers) {\n super(message, 403, data, headers);\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Not Found', data?: T, headers?: Headers) {\n super(message, 404, data, headers);\n this.name = 'NotFoundError';\n }\n}\n\nexport class MethodNotAllowedError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Method Not Allowed',\n data?: T,\n headers?: Headers\n ) {\n super(message, 405, data, headers);\n this.name = 'MethodNotAllowedError';\n }\n}\n\nexport class ConflictError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Conflict', data?: T, headers?: Headers) {\n super(message, 409, data, headers);\n this.name = 'ConflictError';\n }\n}\n\nexport class UnprocessableEntityError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Unprocessable Entity',\n data?: T,\n headers?: Headers\n ) {\n super(message, 422, data, headers);\n this.name = 'UnprocessableEntityError';\n }\n}\n\nexport class TooManyRequestsError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Too Many Requests',\n data?: T,\n headers?: Headers\n ) {\n super(message, 429, data, headers);\n this.name = 'TooManyRequestsError';\n }\n}\n\n// 5xx Server Errors\nexport class InternalServerError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Internal Server Error',\n data?: T,\n headers?: Headers\n ) {\n super(message, 500, data, headers);\n this.name = 'InternalServerError';\n }\n}\n\nexport class BadGatewayError<T = unknown> extends ServerError<T> {\n constructor(message: string = 'Bad Gateway', data?: T, headers?: Headers) {\n super(message, 502, data, headers);\n this.name = 'BadGatewayError';\n }\n}\n\nexport class ServiceUnavailableError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Service Unavailable',\n data?: T,\n headers?: Headers\n ) {\n super(message, 503, data, headers);\n this.name = 'ServiceUnavailableError';\n }\n}\n\nexport class GatewayTimeoutError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Gateway Timeout',\n data?: T,\n headers?: Headers\n ) {\n super(message, 504, data, headers);\n this.name = 'GatewayTimeoutError';\n }\n}\n\n/**\n * Factory function to create the appropriate error class based on status code\n */\nexport function createFetchError<T = unknown>(\n status: number,\n message?: string,\n data?: T,\n headers?: Headers\n): FetchError<T> {\n const defaultMessage = message || `HTTP ${status}`;\n\n // 4xx Client Errors\n switch (status) {\n case 400:\n return new BadRequestError(defaultMessage, data, headers);\n case 401:\n return new UnauthorizedError(defaultMessage, data, headers);\n case 403:\n return new ForbiddenError(defaultMessage, data, headers);\n case 404:\n return new NotFoundError(defaultMessage, data, headers);\n case 405:\n return new MethodNotAllowedError(defaultMessage, data, headers);\n case 409:\n return new ConflictError(defaultMessage, data, headers);\n case 422:\n return new UnprocessableEntityError(defaultMessage, data, headers);\n case 429:\n return new TooManyRequestsError(defaultMessage, data, headers);\n // Generic 4xx\n case 402:\n case 406:\n case 407:\n case 408:\n case 410:\n case 411:\n case 412:\n case 413:\n case 414:\n case 415:\n case 416:\n case 417:\n case 418:\n case 421:\n case 423:\n case 424:\n case 425:\n case 426:\n case 428:\n case 431:\n case 451:\n return new ClientError(defaultMessage, status, data, headers);\n\n // 5xx Server Errors\n case 500:\n return new InternalServerError(defaultMessage, data, headers);\n case 502:\n return new BadGatewayError(defaultMessage, data, headers);\n case 503:\n return new ServiceUnavailableError(defaultMessage, data, headers);\n case 504:\n return new GatewayTimeoutError(defaultMessage, data, headers);\n // Generic 5xx\n case 501:\n case 505:\n case 506:\n case 507:\n case 508:\n case 510:\n case 511:\n return new ServerError(defaultMessage, status, data, headers);\n\n default:\n // For any other status code, return base FetchError\n return new FetchError(defaultMessage, status, data, headers);\n }\n}\n","import type { Hook, HookContext, HookStage, HooksConfig } from './types';\n\n/**\n * Hook registry that manages hooks for different lifecycle stages\n */\nexport class HookRegistry {\n private hooks: Map<HookStage, Hook[]> = new Map();\n\n constructor(config?: HooksConfig) {\n if (config) {\n this.registerFromConfig(config);\n }\n }\n\n /**\n * Register hooks from a configuration object\n */\n registerFromConfig(config: HooksConfig): void {\n for (const [stage, hooks] of Object.entries(config)) {\n if (hooks && Array.isArray(hooks)) {\n for (const hook of hooks) {\n this.register(stage as HookStage, hook);\n }\n }\n }\n }\n\n /**\n * Register a hook for a specific stage\n */\n register(stage: HookStage, hook: Hook): void {\n if (!this.hooks.has(stage)) {\n this.hooks.set(stage, []);\n }\n\n this.hooks.get(stage)?.push(hook);\n }\n\n /**\n * Remove a specific hook from a stage\n */\n remove(stage: HookStage, hook: Hook): boolean {\n const hooks = this.hooks.get(stage);\n if (!hooks) {\n return false;\n }\n\n const index = hooks.indexOf(hook);\n if (index === -1) {\n return false;\n }\n\n hooks.splice(index, 1);\n return true;\n }\n\n /**\n * Clear all hooks for a specific stage, or all hooks if no stage is provided\n */\n clear(stage?: HookStage): void {\n if (stage) {\n this.hooks.delete(stage);\n } else {\n this.hooks.clear();\n }\n }\n\n /**\n * Get all hooks for a specific stage\n */\n get(stage: HookStage): Hook[] {\n return this.hooks.get(stage) || [];\n }\n\n /**\n * Execute all hooks for a specific stage in registration order\n */\n async execute(stage: HookStage, context: HookContext): Promise<void> {\n const hooks = this.get(stage);\n for (const hook of hooks) {\n await hook(context);\n }\n }\n\n /**\n * Check if any hooks are registered for a stage\n */\n has(stage: HookStage): boolean {\n if (!this.hooks.has(stage)) {\n return false;\n }\n const hooks = this.hooks.get(stage);\n if (!hooks) {\n return false;\n }\n return hooks.length > 0;\n }\n}\n","import type { RetryStrategyFunction } from './types';\n\n/**\n * Exponential backoff strategy\n * Delay = baseBackoffMs * 2^attempt\n */\nexport const exponentialStrategy: RetryStrategyFunction = (\n attempt: number,\n baseBackoffMs: number\n): number => {\n return baseBackoffMs * Math.pow(2, attempt);\n};\n\n/**\n * Linear backoff strategy\n * Delay = baseBackoffMs * (attempt + 1)\n */\nexport const linearStrategy: RetryStrategyFunction = (\n attempt: number,\n baseBackoffMs: number\n): number => {\n return baseBackoffMs * (attempt + 1);\n};\n\n/**\n * Get the retry strategy function based on the strategy name or function\n */\nexport function getRetryStrategy(\n strategy: 'exponential' | 'linear' | RetryStrategyFunction\n): RetryStrategyFunction {\n if (typeof strategy === 'function') {\n return strategy;\n }\n\n switch (strategy) {\n case 'exponential':\n return exponentialStrategy;\n case 'linear':\n return linearStrategy;\n default:\n return exponentialStrategy;\n }\n}\n\n/**\n * Calculate the delay for a retry attempt\n */\nexport function calculateRetryDelay(\n attempt: number,\n strategy: 'exponential' | 'linear' | RetryStrategyFunction,\n baseBackoffMs: number\n): number {\n const strategyFn = getRetryStrategy(strategy);\n return strategyFn(attempt, baseBackoffMs);\n}\n","/**\n * Parse Server-Sent Events (SSE) stream\n * Extracts data fields from text/event-stream format\n */\nexport async function* parseSSEStream(\n response: Response\n): AsyncGenerator<string, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n\n let currentEvent: { type?: string; data?: string; id?: string } = {};\n\n for (const line of lines) {\n if (line.trim() === '') {\n // Empty line indicates end of event\n if (currentEvent.data !== undefined) {\n yield currentEvent.data;\n }\n currentEvent = {};\n continue;\n }\n\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) continue;\n\n const field = line.substring(0, colonIndex).trim();\n const value = line.substring(colonIndex + 1).trim();\n\n if (field === 'data') {\n currentEvent.data = currentEvent.data\n ? currentEvent.data + '\\n' + value\n : value;\n } else if (field === 'event') {\n currentEvent.type = value;\n } else if (field === 'id') {\n currentEvent.id = value;\n }\n }\n }\n\n // Handle any remaining event in buffer\n if (buffer.trim()) {\n const lines = buffer.split('\\n');\n let currentEvent: { data?: string } = {};\n for (const line of lines) {\n if (line.trim() === '' && currentEvent.data !== undefined) {\n yield currentEvent.data;\n currentEvent = {};\n continue;\n }\n const colonIndex = line.indexOf(':');\n if (colonIndex !== -1) {\n const field = line.substring(0, colonIndex).trim();\n const value = line.substring(colonIndex + 1).trim();\n if (field === 'data') {\n currentEvent.data = currentEvent.data\n ? currentEvent.data + '\\n' + value\n : value;\n }\n }\n }\n if (currentEvent.data !== undefined) {\n yield currentEvent.data;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\ntype AnyParsedNDJSON = string | object | ArrayBuffer | unknown;\n\n/**\n * Parse NDJSON (Newline-Delimited JSON) stream\n * Yields each JSON object as it arrives\n */\nexport async function* parseNDJSONStream<T = AnyParsedNDJSON>(\n response: Response\n): AsyncGenerator<T, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed === '') continue;\n\n try {\n const parsed = JSON.parse(trimmed) as T;\n yield parsed;\n } catch {\n // Skip invalid JSON lines\n console.warn('Skipping invalid JSON line:', trimmed);\n }\n }\n }\n\n // Handle any remaining line in buffer\n if (buffer.trim()) {\n try {\n const parsed = JSON.parse(buffer.trim()) as T;\n yield parsed;\n } catch {\n // Skip invalid JSON\n console.warn('Skipping invalid JSON in buffer:', buffer.trim());\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Parse generic chunked stream\n * Yields raw chunks as strings\n */\nexport async function* parseChunkedStream<T = string>(\n response: Response\n): AsyncGenerator<T, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n yield chunk as T;\n }\n } finally {\n reader.releaseLock();\n }\n}\n","/**\n * Detects if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return (\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as unknown as { window: unknown }).window !==\n 'undefined' &&\n typeof (globalThis as unknown as { window: { document: unknown } }).window\n .document !== 'undefined'\n );\n}\n\n/**\n * Detects if the code is running in a Node.js environment\n */\nexport function isNode(): boolean {\n return (\n typeof process !== 'undefined' &&\n process.versions != null &&\n process.versions.node != null\n );\n}\n\n/**\n * Encodes a string to Base64, using the appropriate method for the environment\n * @param str - String to encode\n * @returns Base64 encoded string\n */\nexport function encodeBase64(str: string): string {\n if (isBrowser()) {\n // Browser environment - use btoa\n if (typeof btoa !== 'undefined') {\n return btoa(str);\n }\n // Fallback for environments where btoa might not be available\n throw new Error(\n 'btoa is not available. This should not happen in a browser environment.'\n );\n } else {\n // Node.js environment - use Buffer\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'utf-8').toString('base64');\n }\n throw new Error(\n \"Buffer is not available. Please ensure you're running in Node.js or provide a polyfill.\"\n );\n }\n}\n\n/**\n * Checks if the native fetch API is available\n * @returns true if fetch is available, false otherwise\n */\nexport function isFetchAvailable(): boolean {\n return typeof fetch !== 'undefined';\n}\n\n/**\n * Checks if AbortController is available\n * @returns true if AbortController is available, false otherwise\n */\nexport function isAbortControllerAvailable(): boolean {\n return typeof AbortController !== 'undefined';\n}\n\n/**\n * Gets a helpful error message if fetch is not available\n * @returns Error message with suggestions\n */\nexport function getFetchErrorMessage(): string {\n if (isBrowser()) {\n return 'fetch is not available in this browser. Please use a modern browser or provide a polyfill.';\n } else {\n return \"fetch is not available. Node.js 22+ includes native fetch. For older versions, please provide a custom fetch implementation (e.g., from 'undici' or 'node-fetch').\";\n }\n}\n","import type { QueryParams } from '../types';\n\n/**\n * Serializes query parameters into a URLSearchParams object\n * Handles arrays, objects, and primitive values\n */\nexport function serializeQueryParams(query: QueryParams): URLSearchParams {\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n // Append each array item\n for (const item of value) {\n if (item !== undefined && item !== null) {\n params.append(key, String(item));\n }\n }\n } else {\n params.set(key, String(value));\n }\n }\n\n return params;\n}\n\n/**\n * Builds a URL with query parameters\n * @param baseUrl - Base URL\n * @param path - Path to append\n * @param query - Query parameters object\n * @returns Complete URL with query string\n */\nexport function buildUrl(\n baseUrl: string,\n path: string,\n query?: QueryParams | undefined\n): URL {\n // Normalize path - remove trailing slash if present (except for root)\n let normalizedPath = path || '';\n if (normalizedPath.length > 1 && normalizedPath.endsWith('/')) {\n normalizedPath = normalizedPath.slice(0, -1);\n }\n\n // Normalize baseURL to ensure it has a trailing slash if it has a path component\n // This is needed because new URL('path', 'https://example.com/base') creates\n // 'https://example.com/path' (treats base as a file), but\n // new URL('path', 'https://example.com/base/') creates 'https://example.com/base/path' (correct)\n let normalizedBaseUrl = baseUrl || '';\n if (normalizedBaseUrl) {\n try {\n const baseUrlObj = new URL(normalizedBaseUrl);\n // If baseURL has a path component and doesn't end with /, add it\n if (\n baseUrlObj.pathname &&\n baseUrlObj.pathname !== '/' &&\n !normalizedBaseUrl.endsWith('/')\n ) {\n normalizedBaseUrl = normalizedBaseUrl + '/';\n }\n } catch {\n // If baseUrl is not a valid URL, proceed as-is\n }\n }\n\n // If path starts with /, strip it so it appends to baseURL instead of replacing it\n if (normalizedPath.startsWith('/')) {\n normalizedPath = normalizedPath.slice(1);\n }\n\n const url = new URL(normalizedPath, normalizedBaseUrl);\n\n if (query) {\n const params = serializeQueryParams(query);\n // Merge with existing search params\n // Get all unique keys first\n const keys = Array.from(new Set(params.keys()));\n for (const key of keys) {\n // Remove existing values for this key\n url.searchParams.delete(key);\n // Append all values (handles arrays correctly)\n for (const value of params.getAll(key)) {\n url.searchParams.append(key, value);\n }\n }\n }\n\n return url;\n}\n\n/**\n * Determines the content type from a body value\n * @param body - Request body\n * @returns Content type string or undefined\n */\nexport function getContentType(body: unknown): string | undefined {\n if (body === null || body === undefined) {\n return undefined;\n }\n\n if (body instanceof FormData) {\n // FormData sets its own content-type with boundary\n return undefined; // Let the browser set it\n }\n\n if (body instanceof URLSearchParams) {\n return 'application/x-www-form-urlencoded';\n }\n\n if (typeof body === 'string') {\n // Try to detect if it's JSON\n try {\n JSON.parse(body);\n return 'application/json';\n } catch {\n return 'text/plain';\n }\n }\n\n if (typeof body === 'object') {\n return 'application/json';\n }\n\n return undefined;\n}\n\n/**\n * Serializes a request body based on its type\n * @param body - Request body to serialize\n * @param contentType - Optional content type hint to guide serialization\n * @returns Serialized body (string, FormData, Blob, ArrayBuffer, etc.)\n */\nexport function serializeBody(\n body: unknown,\n contentType?: string\n): RequestInit['body'] | null {\n if (body === null || body === undefined) {\n return null;\n }\n\n // If it's already a valid body type, return as-is\n if (\n typeof body === 'string' ||\n body instanceof FormData ||\n body instanceof URLSearchParams ||\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n ArrayBuffer.isView(body)\n ) {\n return body as RequestInit['body'];\n }\n\n // Handle form-urlencoded: convert object to URLSearchParams\n if (\n contentType === 'application/x-www-form-urlencoded' &&\n typeof body === 'object' &&\n body !== null &&\n !Array.isArray(body)\n ) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(body)) {\n if (value !== null && value !== undefined) {\n if (Array.isArray(value)) {\n // Handle array values (multiple params with same key)\n for (const item of value) {\n params.append(key, String(item));\n }\n } else {\n params.append(key, String(value));\n }\n }\n }\n return params;\n }\n\n // For objects, serialize to JSON (default)\n if (typeof body === 'object') {\n return JSON.stringify(body);\n }\n\n // For primitives, convert to string\n return String(body);\n}\n","/**\n * Parses a response based on its content type\n * @param response - Fetch Response object\n * @returns Parsed response data\n */\n\ntype AnyPromiseResponse = Promise<string | object | ArrayBuffer | unknown>;\n\nexport async function parseResponse(response: Response): AnyPromiseResponse {\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n return await response.json();\n } else if (contentType.startsWith('text/')) {\n return await response.text();\n } else {\n // Binary or unknown content type - return ArrayBuffer\n return await response.arrayBuffer();\n }\n}\n\n/**\n * Checks if a response indicates success (status 200-299)\n * @param response - Fetch Response object\n * @returns true if response is successful\n */\nexport function isSuccessResponse(response: Response): boolean {\n return response.ok;\n}\n","import { createFetchError, FetchError } from './errors';\nimport { HookRegistry } from './hooks';\nimport type { Hook, HookStage } from './hooks/types';\nimport { calculateRetryDelay } from './retry';\nimport {\n parseSSEStream,\n parseNDJSONStream,\n parseChunkedStream,\n} from './streaming';\nimport type {\n FetchClientConfig,\n QueryParams,\n RequestOptions,\n StreamingRequestOptions,\n AuthStrategy,\n} from './types';\nimport {\n buildUrl,\n serializeBody,\n getContentType,\n parseResponse,\n isSuccessResponse,\n} from './utils';\nimport {\n isFetchAvailable,\n getFetchErrorMessage,\n encodeBase64,\n} from './utils/environment';\n\n/**\n * Universal HTTP fetch client with hooks, retries, and streaming support\n */\nexport class FetchClient {\n private hookRegistry: HookRegistry;\n private cfg: FetchClientConfig;\n\n constructor(config: FetchClientConfig = {}) {\n this.cfg = config;\n\n // Set default base URL if not provided\n if (!this.cfg.baseURL) {\n this.cfg.baseURL = '';\n }\n\n // Initialize hook registry\n this.hookRegistry = new HookRegistry(this.cfg.hooks);\n\n // Check fetch availability\n if (!isFetchAvailable() && !this.cfg.fetch) {\n throw new Error(getFetchErrorMessage());\n }\n }\n\n /**\n * Add an authentication strategy\n */\n addAuthStrategy(strategy: AuthStrategy): void {\n if (!this.cfg.authStrategies) {\n this.cfg.authStrategies = [];\n }\n this.cfg.authStrategies.push(strategy);\n }\n\n /**\n * Remove all authentication strategies\n */\n clearAuthStrategies(): void {\n if (this.cfg.authStrategies) {\n this.cfg.authStrategies = [];\n }\n }\n\n /**\n * Register a hook for a specific lifecycle stage\n */\n useHook(stage: HookStage, hook: Hook): void {\n this.hookRegistry.register(stage, hook);\n }\n\n /**\n * Remove a hook\n */\n removeHook(stage: HookStage, hook: Hook): boolean {\n return this.hookRegistry.remove(stage, hook);\n }\n\n /**\n * Clear hooks for a stage or all hooks\n */\n clearHooks(stage?: HookStage): void {\n this.hookRegistry.clear(stage);\n }\n\n /**\n * Make an HTTP request\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async request<T = any>(init: RequestOptions): Promise<T> {\n const url = buildUrl(this.cfg.baseURL || '', init.path, init.query);\n // Create headers, handling both plain objects and Headers instances\n const headers = new Headers(this.cfg.headers || {});\n if (init.headers) {\n if (init.headers instanceof Headers) {\n // Copy from Headers object\n init.headers.forEach((value, key) => {\n headers.set(key, value);\n });\n } else {\n // Merge from plain object\n Object.entries(init.headers).forEach(([key, value]) => {\n headers.set(key, String(value));\n });\n }\n }\n\n // Apply authentication (may modify URL for query-based auth)\n await this.applyAuthentication(headers, url);\n\n // Set content type if body is provided (check before serialization)\n let bodyContentType: string | undefined;\n if (init.body !== undefined) {\n // Check if Content-Type is already set in headers\n bodyContentType = headers.get('Content-Type') || undefined;\n if (!bodyContentType) {\n bodyContentType = getContentType(init.body);\n if (bodyContentType) {\n headers.set('Content-Type', bodyContentType);\n }\n }\n }\n\n const retries = this.cfg.retry?.retries ?? 0;\n const baseBackoff = this.cfg.retry?.backoffMs ?? 300;\n const retryOn = this.cfg.retry?.retryOn ?? [429, 500, 502, 503, 504];\n const retryStrategy = this.cfg.retry?.strategy ?? 'exponential';\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries + 1; attempt++) {\n try {\n // Rebuild URL for each attempt (in case query params were modified by auth)\n const attemptUrl = buildUrl(\n this.cfg.baseURL || '',\n init.path,\n init.query\n );\n // Clone headers for each attempt\n const attemptHeaders = new Headers(headers);\n // Re-apply authentication for each attempt\n await this.applyAuthentication(attemptHeaders, attemptUrl);\n return await this.doRequest<T>(\n attemptUrl,\n init,\n attemptHeaders,\n attempt,\n bodyContentType\n );\n } catch (err) {\n lastError = err;\n\n // Check if we should retry\n const shouldRetry = this.shouldRetry(err, attempt, retries, retryOn);\n\n if (shouldRetry) {\n // Execute beforeRetry hook\n if (this.hookRegistry.has('beforeRetry')) {\n const serializedBody = serializeBody(init.body, bodyContentType);\n await this.hookRegistry.execute('beforeRetry', {\n url: url.toString(),\n init: { ...init, headers, body: serializedBody },\n attempt,\n error: err,\n retryCount: attempt,\n });\n }\n\n // Calculate delay\n const delay = calculateRetryDelay(\n attempt,\n retryStrategy,\n baseBackoff\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n\n // Execute afterRetry hook\n if (this.hookRegistry.has('afterRetry')) {\n const serializedBody = serializeBody(init.body, bodyContentType);\n await this.hookRegistry.execute('afterRetry', {\n url: url.toString(),\n init: { ...init, headers, body: serializedBody },\n attempt,\n error: err,\n retryCount: attempt,\n success: false, // Will be updated if retry succeeds\n });\n }\n\n continue;\n }\n\n // Not retrying - throw the error\n throw err;\n }\n }\n\n throw lastError as unknown;\n }\n\n /**\n * Make a streaming HTTP request\n */\n async *requestStream<T = unknown>(\n init: StreamingRequestOptions\n ): AsyncGenerator<T, void, unknown> {\n const url = buildUrl(this.cfg.baseURL || '', init.path, init.query);\n // Create headers, handling both plain objects and Headers instances\n const headers = new Headers(this.cfg.headers || {});\n if (init.headers) {\n if (init.headers instanceof Headers) {\n // Copy from Headers object\n init.headers.forEach((value, key) => {\n headers.set(key, value);\n });\n } else {\n // Merge from plain object\n Object.entries(init.headers).forEach(([key, value]) => {\n headers.set(key, String(value));\n });\n }\n }\n\n // Apply authentication (may modify URL for query-based auth)\n await this.applyAuthentication(headers, url);\n\n // Determine content type for body serialization\n let bodyContentType: string | undefined =\n headers.get('Content-Type') || undefined;\n if (init.contentType && !bodyContentType) {\n bodyContentType = init.contentType;\n headers.set('Content-Type', bodyContentType);\n }\n\n const fetchInit: Omit<RequestInit, 'body'> & {\n path: string;\n method: string;\n query?: QueryParams | undefined;\n headers: Headers;\n body: RequestInit['body'] | undefined;\n } = {\n ...init,\n headers,\n body: serializeBody(init.body, bodyContentType),\n };\n\n // Set credentials from config if provided\n if (this.cfg.credentials !== undefined) {\n fetchInit.credentials = this.cfg.credentials;\n }\n\n // Execute beforeRequest hook\n if (this.hookRegistry.has('beforeRequest')) {\n await this.hookRegistry.execute('beforeRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n });\n }\n\n let controller: AbortController | undefined;\n let timeoutId: NodeJS.Timeout | undefined;\n const existingSignal = fetchInit.signal;\n\n // Setup timeout\n if (this.cfg.timeoutMs && typeof AbortController !== 'undefined') {\n controller = new AbortController();\n if (existingSignal) {\n if (existingSignal.aborted) {\n controller.abort();\n } else {\n existingSignal.addEventListener('abort', () => {\n controller?.abort();\n });\n }\n }\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => {\n controller?.abort();\n // Execute onTimeout hook\n if (this.hookRegistry.has('onTimeout')) {\n this.hookRegistry.execute('onTimeout', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n timeoutMs: this.cfg.timeoutMs,\n });\n }\n }, this.cfg.timeoutMs);\n }\n\n try {\n const fetchFn = this.cfg.fetch || fetch;\n const res = await fetchFn(url.toString(), fetchInit as RequestInit);\n\n // Execute afterRequest hook\n if (this.hookRegistry.has('afterRequest')) {\n await this.hookRegistry.execute('afterRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n\n if (!res.ok) {\n const parsed = await parseResponse(res);\n const message = (parsed as { message?: string })?.message as\n | string\n | undefined;\n const error = createFetchError(\n res.status,\n message || `HTTP ${res.status}`,\n parsed,\n res.headers\n );\n\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n error,\n });\n }\n\n throw error;\n }\n\n // Execute onStreamStart hook\n if (this.hookRegistry.has('onStreamStart')) {\n await this.hookRegistry.execute('onStreamStart', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n\n // Route to appropriate parser based on streaming format\n const streamingFormat = init.streamingFormat || 'chunked';\n\n if (streamingFormat === 'sse') {\n for await (const chunk of parseSSEStream(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n } else if (streamingFormat === 'ndjson') {\n for await (const chunk of parseNDJSONStream<T>(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n } else {\n // Generic chunked streaming\n for await (const chunk of parseChunkedStream<T>(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n }\n\n // Execute onStreamEnd hook\n if (this.hookRegistry.has('onStreamEnd')) {\n await this.hookRegistry.execute('onStreamEnd', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n } catch (err) {\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n error: err,\n });\n }\n throw err;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Internal method to execute a single request attempt\n */\n private async doRequest<T>(\n url: URL,\n init: RequestOptions,\n baseHeaders: Headers,\n attempt: number,\n contentType?: string\n ): Promise<T> {\n // Headers are already cloned and auth is already applied\n const requestHeaders = baseHeaders;\n\n const fetchInit: Omit<RequestInit, 'body'> & {\n path: string;\n method: string;\n\n query?: QueryParams | undefined;\n headers: Headers;\n body: RequestInit['body'] | undefined;\n } = {\n ...init,\n headers: requestHeaders,\n body: serializeBody(init.body, contentType),\n };\n\n // Set credentials from config if provided\n if (this.cfg.credentials !== undefined) {\n fetchInit.credentials = this.cfg.credentials;\n }\n\n // Execute beforeRequest hook\n if (this.hookRegistry.has('beforeRequest')) {\n await this.hookRegistry.execute('beforeRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n });\n }\n\n let controller: AbortController | undefined;\n let timeoutId: NodeJS.Timeout | undefined;\n const existingSignal = fetchInit.signal;\n\n // Setup timeout\n if (this.cfg.timeoutMs && typeof AbortController !== 'undefined') {\n controller = new AbortController();\n if (existingSignal) {\n if (existingSignal.aborted) {\n controller.abort();\n } else {\n existingSignal.addEventListener('abort', () => {\n controller?.abort();\n });\n }\n }\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => {\n controller?.abort();\n // Execute onTimeout hook\n if (this.hookRegistry.has('onTimeout')) {\n this.hookRegistry.execute('onTimeout', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n timeoutMs: this.cfg.timeoutMs,\n });\n }\n }, this.cfg.timeoutMs);\n }\n\n try {\n const fetchFn = this.cfg.fetch || fetch;\n const res = await fetchFn(url.toString(), fetchInit as RequestInit);\n\n // Execute afterRequest hook\n if (this.hookRegistry.has('afterRequest')) {\n await this.hookRegistry.execute('afterRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n response: res,\n });\n }\n\n const parsed = await parseResponse(res);\n\n // Execute afterResponse hook\n if (this.hookRegistry.has('afterResponse')) {\n await this.hookRegistry.execute('afterResponse', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n response: res,\n data: parsed,\n });\n }\n\n if (!isSuccessResponse(res)) {\n const message = (parsed as { message?: string })?.message as\n | string\n | undefined;\n const error = createFetchError(\n res.status,\n message || `HTTP ${res.status}`,\n parsed,\n res.headers\n );\n\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n error,\n });\n }\n\n throw error;\n }\n\n return parsed as T;\n } catch (err) {\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n error: err,\n });\n }\n\n // Re-throw with proper error type if needed\n if (err instanceof DOMException) {\n throw err;\n }\n if (err instanceof FetchError) {\n throw err;\n }\n\n // For network errors, try to extract status if available\n const status = (err as unknown as { status?: number })?.status as\n | number\n | undefined;\n const statusCode = typeof status === 'number' ? status : 0;\n if (typeof err === 'string') {\n throw createFetchError(statusCode, err);\n }\n throw createFetchError(\n statusCode,\n (err as Error)?.message || 'Network error'\n );\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Apply authentication strategies\n */\n private async applyAuthentication(headers: Headers, url: URL): Promise<void> {\n if (!this.cfg.authStrategies) {\n return;\n }\n\n for (const strategy of this.cfg.authStrategies) {\n await this.applyAuthStrategy(strategy, headers, url);\n }\n }\n\n /**\n * Apply a single authentication strategy\n */\n private async applyAuthStrategy(\n strategy: AuthStrategy,\n headers: Headers,\n url: URL\n ): Promise<void> {\n switch (strategy.type) {\n case 'bearer': {\n const token =\n typeof strategy.token === 'function'\n ? await strategy.token()\n : strategy.token;\n if (token != null) {\n const headerName = strategy.headerName || 'Authorization';\n headers.set(headerName, `Bearer ${String(token)}`);\n }\n break;\n }\n\n case 'basic': {\n const encoded = encodeBase64(\n `${strategy.username}:${strategy.password}`\n );\n headers.set('Authorization', `Basic ${encoded}`);\n break;\n }\n\n case 'apiKey': {\n const key =\n typeof strategy.key === 'function'\n ? await strategy.key()\n : strategy.key;\n if (key != null) {\n switch (strategy.location) {\n case 'header':\n headers.set(strategy.name, String(key));\n break;\n case 'query':\n url.searchParams.set(strategy.name, String(key));\n break;\n case 'cookie':\n headers.set('Cookie', `${strategy.name}=${String(key)}`);\n break;\n }\n }\n break;\n }\n\n case 'custom':\n await strategy.apply(headers, url);\n break;\n }\n }\n\n /**\n * Determine if an error should be retried\n */\n private shouldRetry(\n error: unknown,\n attempt: number,\n maxRetries: number,\n retryOn: number[]\n ): boolean {\n if (attempt >= maxRetries) {\n return false;\n }\n\n // Check custom retry condition\n if (this.cfg.retry?.retryOnError) {\n return this.cfg.retry.retryOnError(error);\n }\n\n // Check if it's a FetchError with a retryable status code\n if (error instanceof FetchError) {\n return retryOn.includes(error.status);\n }\n\n // Network errors (no status code) should be retried\n return true;\n }\n}\n","import type { AuthStrategy } from '@blimu/fetch';\nimport type { ClientOption } from './client';\n\nexport function buildAuthStrategies(cfg: ClientOption): AuthStrategy[] {\n const authStrategies: AuthStrategy[] = [...(cfg?.authStrategies ?? [])];\n\n if (cfg.bearer) {\n authStrategies.push({\n type: 'bearer',\n token: cfg.bearer,\n });\n }\n return authStrategies;\n}\n","import { parseSSEStream, parseNDJSONStream } from '@blimu/fetch';\n\nexport type PaginableQuery = { limit?: number; offset?: number } & Record<string, unknown>;\n\nexport async function* paginate<T>(\n fetchPage: (\n query?: PaginableQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ) => Promise<{ data?: T[]; hasMore?: boolean; limit?: number; offset?: number }>,\n initialQuery: PaginableQuery = {},\n pageSize = 100\n): AsyncGenerator<T, void, unknown> {\n let offset = Number(initialQuery.offset ?? 0);\n const limit = Number(initialQuery.limit ?? pageSize);\n // shallow copy to avoid mutating caller\n const baseQuery: PaginableQuery = { ...initialQuery };\n while (true) {\n const page = await fetchPage({ ...baseQuery, limit, offset });\n const items = page.data ?? [];\n for (const item of items) {\n yield item;\n }\n if (!page.hasMore || items.length < limit) break;\n offset += limit;\n }\n}\n\nexport async function listAll<T>(\n fetchPage: (\n query?: PaginableQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ) => Promise<{ data?: T[]; hasMore?: boolean; limit?: number; offset?: number }>,\n query: PaginableQuery = {},\n pageSize = 100\n): Promise<T[]> {\n const out: T[] = [];\n for await (const item of paginate<T>(fetchPage, query, pageSize)) out.push(item);\n return out;\n}\n\n/**\n * Filters out undefined values from an array while preserving type safety\n * Useful for query keys where optional parameters might be undefined\n * Preserves tuple types when no undefined values are present\n */\nexport function isNotUndefined<T extends readonly unknown[]>(arr: T): T {\n // Type assertion: when no undefined values exist, tuple is preserved\n // When undefined values exist, they are filtered but type system can't infer exact tuple shape\n return arr.filter(\n (item): item is Exclude<T[number], undefined> => item !== undefined\n ) as unknown as T;\n}\n\n// Re-export streaming parsers from @blimu/fetch\nexport { parseSSEStream, parseNDJSONStream };\n","import { FetchClient } from '@blimu/fetch';\nimport * as Schema from '../schema';\nimport { isNotUndefined } from '../utils';\n\nexport class AuthService {\n constructor(private core: FetchClient) {}\n\n /**\n * POST /v1/auth/logout*\n * @summary Logout and invalidate session*/\n logout(init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown> {\n return this.core.request({\n method: 'POST',\n path: `/v1/auth/logout`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for logout\n * @returns ['v1/auth/logout']\n */\n logout__queryKeys(): readonly ['v1/auth/logout'] {\n return ['v1/auth/logout'] as const;\n }\n\n /**\n * POST /v1/auth/refresh*\n * @summary Refresh session token*/\n refresh(\n query?: Schema.AuthRefreshQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.RefreshResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/auth/refresh`,\n query,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for refresh\n * @returns ['v1/auth/refresh', query]\n */\n refresh__queryKeys(query?: Schema.AuthRefreshQuery): readonly string[] {\n const keys = ['v1/auth/refresh', query] as const;\n return isNotUndefined(keys) as readonly string[];\n }\n\n /**\n * GET /v1/auth/session*\n * @summary Get current session*/\n getSession(init?: Omit<RequestInit, 'method' | 'body'>): Promise<Schema.SessionResponse> {\n return this.core.request({\n method: 'GET',\n path: `/v1/auth/session`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for getSession\n * @returns ['v1/auth/session']\n */\n getSession__queryKeys(): readonly ['v1/auth/session'] {\n return ['v1/auth/session'] as const;\n }\n}\n","import { FetchClient } from '@blimu/fetch';\nimport * as Schema from '../schema';\n\nexport class EntitlementsService {\n constructor(private core: FetchClient) {}\n\n /**\n * GET /v1/client/entitlements/list-for-tenant/{tenantResourceId}*\n * @summary List entitlements for a tenant and all its sub-resources*\n * @description Returns entitlements for a tenant resource and all its descendant resources for the authenticated user. This endpoint scopes queries to a single tenant, preventing cross-tenant data access. Only evaluates roles and plans (excludes limits). Results are cached per resource for performance. The tenant resource type is automatically determined from the environment definition (resource marked as `is_tenant: true`).*/\n listForTenant(\n tenantResourceId: string,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.EntitlementsListResult> {\n return this.core.request({\n method: 'GET',\n path: `/v1/client/entitlements/list-for-tenant/${encodeURIComponent(tenantResourceId)}`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for listForTenant\n * @returns ['v1/client/entitlements/list-for-tenant', tenantResourceId]\n */\n listForTenant__queryKeys(\n tenantResourceId: string\n ): readonly ['v1/client/entitlements/list-for-tenant', string] {\n return ['v1/client/entitlements/list-for-tenant', tenantResourceId] as const;\n }\n}\n"],"mappings":"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","names":["FetchError","Error","message","status","data","headers","name","captureStackTrace","ClientError","ServerError","BadRequestError","UnauthorizedError","ForbiddenError","NotFoundError","MethodNotAllowedError","ConflictError","UnprocessableEntityError","TooManyRequestsError","InternalServerError","BadGatewayError","ServiceUnavailableError","GatewayTimeoutError","createFetchError","defaultMessage","HookRegistry","hooks","Map","config","registerFromConfig","stage","Object","entries","Array","isArray","hook","register","has","set","get","push","remove","index","indexOf","splice","clear","delete","execute","context","length","exponentialStrategy","attempt","baseBackoffMs","Math","pow","linearStrategy","getRetryStrategy","strategy","calculateRetryDelay","strategyFn","parseSSEStream","response","body","reader","getReader","decoder","TextDecoder","buffer","done","value","read","decode","stream","lines","split","pop","currentEvent","line","trim","undefined","colonIndex","field","substring","type","id","releaseLock","parseNDJSONStream","trimmed","parsed","JSON","parse","console","warn","parseChunkedStream","chunk","isBrowser","globalThis","window","document","isNode","process","versions","node","encodeBase64","str","btoa","Buffer","from","toString","isFetchAvailable","fetch","isAbortControllerAvailable","AbortController","getFetchErrorMessage","serializeQueryParams","query","params","URLSearchParams","key","item","append","String","buildUrl","baseUrl","path","normalizedPath","endsWith","slice","normalizedBaseUrl","baseUrlObj","URL","pathname","startsWith","url","keys","Set","searchParams","getAll","getContentType","FormData","serializeBody","contentType","Blob","ArrayBuffer","isView","stringify","parseResponse","includes","json","text","arrayBuffer","isSuccessResponse","ok","FetchClient","hookRegistry","cfg","baseURL","addAuthStrategy","authStrategies","clearAuthStrategies","useHook","removeHook","clearHooks","request","init","Headers","forEach","applyAuthentication","bodyContentType","retries","retry","baseBackoff","backoffMs","retryOn","retryStrategy","lastError","attemptUrl","attemptHeaders","doRequest","err","shouldRetry","serializedBody","error","retryCount","delay","Promise","resolve","setTimeout","success","requestStream","fetchInit","credentials","controller","timeoutId","existingSignal","signal","timeoutMs","aborted","abort","addEventListener","fetchFn","res","streamingFormat","transformedChunk","clearTimeout","baseHeaders","requestHeaders","DOMException","statusCode","applyAuthStrategy","token","headerName","encoded","username","password","location","apply","maxRetries","retryOnError"]}
1
+ {"version":3,"sources":["../src/client.ts","../../../node_modules/@blimu/fetch/src/errors.ts","../../../node_modules/@blimu/fetch/src/hooks/registry.ts","../../../node_modules/@blimu/fetch/src/retry/strategies.ts","../../../node_modules/@blimu/fetch/src/streaming/parsers.ts","../../../node_modules/@blimu/fetch/src/utils/environment.ts","../../../node_modules/@blimu/fetch/src/utils/request.ts","../../../node_modules/@blimu/fetch/src/utils/response.ts","../../../node_modules/@blimu/fetch/src/client.ts","../src/auth-strategies.ts","../src/utils.ts","../src/services/auth.ts","../src/services/entitlements.ts"],"sourcesContent":["import { FetchClient, FetchError } from '@blimu/fetch';\nimport { type FetchClientConfig, type BearerAuthStrategy } from '@blimu/fetch';\nimport { buildAuthStrategies } from './auth-strategies';\nimport { AuthService } from './services/auth';\nimport { EntitlementsService } from './services/entitlements';\n\nexport type ClientOption = FetchClientConfig & {\n bearer?: BearerAuthStrategy['token'];\n};\n\nexport class Blimu {\n readonly auth: AuthService;\n readonly entitlements: EntitlementsService;\n\n constructor(options?: ClientOption) {\n const restCfg = { ...(options ?? {}) };\n delete restCfg.bearer;\n\n const authStrategies = buildAuthStrategies(options ?? {});\n\n const core = new FetchClient({\n ...restCfg,\n baseURL: options?.baseURL ?? 'https://api.blimu.dev',\n ...(authStrategies.length > 0 ? { authStrategies } : {}),\n });\n\n this.auth = new AuthService(core);\n this.entitlements = new EntitlementsService(core);\n }\n}\n\n// Re-export FetchError for backward compatibility\nexport { FetchError };\nexport const BlimuError = FetchError;\n","/**\n * Base error class for all fetch-related errors\n */\nexport class FetchError<T = unknown> extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly data?: T,\n public readonly headers?: Headers\n ) {\n super(message);\n this.name = 'FetchError';\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, FetchError);\n }\n }\n}\n\n/**\n * Base class for all 4xx client errors\n */\nexport class ClientError<T = unknown> extends FetchError<T> {\n constructor(message: string, status: number, data?: T, headers?: Headers) {\n super(message, status, data, headers);\n this.name = 'ClientError';\n }\n}\n\n/**\n * Base class for all 5xx server errors\n */\nexport class ServerError<T = unknown> extends FetchError<T> {\n constructor(message: string, status: number, data?: T, headers?: Headers) {\n super(message, status, data, headers);\n this.name = 'ServerError';\n }\n}\n\n// 4xx Client Errors\nexport class BadRequestError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Bad Request', data?: T, headers?: Headers) {\n super(message, 400, data, headers);\n this.name = 'BadRequestError';\n }\n}\n\nexport class UnauthorizedError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Unauthorized', data?: T, headers?: Headers) {\n super(message, 401, data, headers);\n this.name = 'UnauthorizedError';\n }\n}\n\nexport class ForbiddenError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Forbidden', data?: T, headers?: Headers) {\n super(message, 403, data, headers);\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Not Found', data?: T, headers?: Headers) {\n super(message, 404, data, headers);\n this.name = 'NotFoundError';\n }\n}\n\nexport class MethodNotAllowedError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Method Not Allowed',\n data?: T,\n headers?: Headers\n ) {\n super(message, 405, data, headers);\n this.name = 'MethodNotAllowedError';\n }\n}\n\nexport class ConflictError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Conflict', data?: T, headers?: Headers) {\n super(message, 409, data, headers);\n this.name = 'ConflictError';\n }\n}\n\nexport class UnprocessableEntityError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Unprocessable Entity',\n data?: T,\n headers?: Headers\n ) {\n super(message, 422, data, headers);\n this.name = 'UnprocessableEntityError';\n }\n}\n\nexport class TooManyRequestsError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Too Many Requests',\n data?: T,\n headers?: Headers\n ) {\n super(message, 429, data, headers);\n this.name = 'TooManyRequestsError';\n }\n}\n\n// 5xx Server Errors\nexport class InternalServerError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Internal Server Error',\n data?: T,\n headers?: Headers\n ) {\n super(message, 500, data, headers);\n this.name = 'InternalServerError';\n }\n}\n\nexport class BadGatewayError<T = unknown> extends ServerError<T> {\n constructor(message: string = 'Bad Gateway', data?: T, headers?: Headers) {\n super(message, 502, data, headers);\n this.name = 'BadGatewayError';\n }\n}\n\nexport class ServiceUnavailableError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Service Unavailable',\n data?: T,\n headers?: Headers\n ) {\n super(message, 503, data, headers);\n this.name = 'ServiceUnavailableError';\n }\n}\n\nexport class GatewayTimeoutError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Gateway Timeout',\n data?: T,\n headers?: Headers\n ) {\n super(message, 504, data, headers);\n this.name = 'GatewayTimeoutError';\n }\n}\n\n/**\n * Factory function to create the appropriate error class based on status code\n */\nexport function createFetchError<T = unknown>(\n status: number,\n message?: string,\n data?: T,\n headers?: Headers\n): FetchError<T> {\n const defaultMessage = message || `HTTP ${status}`;\n\n // 4xx Client Errors\n switch (status) {\n case 400:\n return new BadRequestError(defaultMessage, data, headers);\n case 401:\n return new UnauthorizedError(defaultMessage, data, headers);\n case 403:\n return new ForbiddenError(defaultMessage, data, headers);\n case 404:\n return new NotFoundError(defaultMessage, data, headers);\n case 405:\n return new MethodNotAllowedError(defaultMessage, data, headers);\n case 409:\n return new ConflictError(defaultMessage, data, headers);\n case 422:\n return new UnprocessableEntityError(defaultMessage, data, headers);\n case 429:\n return new TooManyRequestsError(defaultMessage, data, headers);\n // Generic 4xx\n case 402:\n case 406:\n case 407:\n case 408:\n case 410:\n case 411:\n case 412:\n case 413:\n case 414:\n case 415:\n case 416:\n case 417:\n case 418:\n case 421:\n case 423:\n case 424:\n case 425:\n case 426:\n case 428:\n case 431:\n case 451:\n return new ClientError(defaultMessage, status, data, headers);\n\n // 5xx Server Errors\n case 500:\n return new InternalServerError(defaultMessage, data, headers);\n case 502:\n return new BadGatewayError(defaultMessage, data, headers);\n case 503:\n return new ServiceUnavailableError(defaultMessage, data, headers);\n case 504:\n return new GatewayTimeoutError(defaultMessage, data, headers);\n // Generic 5xx\n case 501:\n case 505:\n case 506:\n case 507:\n case 508:\n case 510:\n case 511:\n return new ServerError(defaultMessage, status, data, headers);\n\n default:\n // For any other status code, return base FetchError\n return new FetchError(defaultMessage, status, data, headers);\n }\n}\n","import type { Hook, HookContext, HookStage, HooksConfig } from './types';\n\n/**\n * Hook registry that manages hooks for different lifecycle stages\n */\nexport class HookRegistry {\n private hooks: Map<HookStage, Hook[]> = new Map();\n\n constructor(config?: HooksConfig) {\n if (config) {\n this.registerFromConfig(config);\n }\n }\n\n /**\n * Register hooks from a configuration object\n */\n registerFromConfig(config: HooksConfig): void {\n for (const [stage, hooks] of Object.entries(config)) {\n if (hooks && Array.isArray(hooks)) {\n for (const hook of hooks) {\n this.register(stage as HookStage, hook);\n }\n }\n }\n }\n\n /**\n * Register a hook for a specific stage\n */\n register(stage: HookStage, hook: Hook): void {\n if (!this.hooks.has(stage)) {\n this.hooks.set(stage, []);\n }\n\n this.hooks.get(stage)?.push(hook);\n }\n\n /**\n * Remove a specific hook from a stage\n */\n remove(stage: HookStage, hook: Hook): boolean {\n const hooks = this.hooks.get(stage);\n if (!hooks) {\n return false;\n }\n\n const index = hooks.indexOf(hook);\n if (index === -1) {\n return false;\n }\n\n hooks.splice(index, 1);\n return true;\n }\n\n /**\n * Clear all hooks for a specific stage, or all hooks if no stage is provided\n */\n clear(stage?: HookStage): void {\n if (stage) {\n this.hooks.delete(stage);\n } else {\n this.hooks.clear();\n }\n }\n\n /**\n * Get all hooks for a specific stage\n */\n get(stage: HookStage): Hook[] {\n return this.hooks.get(stage) || [];\n }\n\n /**\n * Execute all hooks for a specific stage in registration order\n */\n async execute(stage: HookStage, context: HookContext): Promise<void> {\n const hooks = this.get(stage);\n for (const hook of hooks) {\n await hook(context);\n }\n }\n\n /**\n * Check if any hooks are registered for a stage\n */\n has(stage: HookStage): boolean {\n if (!this.hooks.has(stage)) {\n return false;\n }\n const hooks = this.hooks.get(stage);\n if (!hooks) {\n return false;\n }\n return hooks.length > 0;\n }\n}\n","import type { RetryStrategyFunction } from './types';\n\n/**\n * Exponential backoff strategy\n * Delay = baseBackoffMs * 2^attempt\n */\nexport const exponentialStrategy: RetryStrategyFunction = (\n attempt: number,\n baseBackoffMs: number\n): number => {\n return baseBackoffMs * Math.pow(2, attempt);\n};\n\n/**\n * Linear backoff strategy\n * Delay = baseBackoffMs * (attempt + 1)\n */\nexport const linearStrategy: RetryStrategyFunction = (\n attempt: number,\n baseBackoffMs: number\n): number => {\n return baseBackoffMs * (attempt + 1);\n};\n\n/**\n * Get the retry strategy function based on the strategy name or function\n */\nexport function getRetryStrategy(\n strategy: 'exponential' | 'linear' | RetryStrategyFunction\n): RetryStrategyFunction {\n if (typeof strategy === 'function') {\n return strategy;\n }\n\n switch (strategy) {\n case 'exponential':\n return exponentialStrategy;\n case 'linear':\n return linearStrategy;\n default:\n return exponentialStrategy;\n }\n}\n\n/**\n * Calculate the delay for a retry attempt\n */\nexport function calculateRetryDelay(\n attempt: number,\n strategy: 'exponential' | 'linear' | RetryStrategyFunction,\n baseBackoffMs: number\n): number {\n const strategyFn = getRetryStrategy(strategy);\n return strategyFn(attempt, baseBackoffMs);\n}\n","/**\n * Parse Server-Sent Events (SSE) stream\n * Extracts data fields from text/event-stream format\n */\nexport async function* parseSSEStream(\n response: Response\n): AsyncGenerator<string, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n\n let currentEvent: { type?: string; data?: string; id?: string } = {};\n\n for (const line of lines) {\n if (line.trim() === '') {\n // Empty line indicates end of event\n if (currentEvent.data !== undefined) {\n yield currentEvent.data;\n }\n currentEvent = {};\n continue;\n }\n\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) continue;\n\n const field = line.substring(0, colonIndex).trim();\n const value = line.substring(colonIndex + 1).trim();\n\n if (field === 'data') {\n currentEvent.data = currentEvent.data\n ? currentEvent.data + '\\n' + value\n : value;\n } else if (field === 'event') {\n currentEvent.type = value;\n } else if (field === 'id') {\n currentEvent.id = value;\n }\n }\n }\n\n // Handle any remaining event in buffer\n if (buffer.trim()) {\n const lines = buffer.split('\\n');\n let currentEvent: { data?: string } = {};\n for (const line of lines) {\n if (line.trim() === '' && currentEvent.data !== undefined) {\n yield currentEvent.data;\n currentEvent = {};\n continue;\n }\n const colonIndex = line.indexOf(':');\n if (colonIndex !== -1) {\n const field = line.substring(0, colonIndex).trim();\n const value = line.substring(colonIndex + 1).trim();\n if (field === 'data') {\n currentEvent.data = currentEvent.data\n ? currentEvent.data + '\\n' + value\n : value;\n }\n }\n }\n if (currentEvent.data !== undefined) {\n yield currentEvent.data;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\ntype AnyParsedNDJSON = string | object | ArrayBuffer | unknown;\n\n/**\n * Parse NDJSON (Newline-Delimited JSON) stream\n * Yields each JSON object as it arrives\n */\nexport async function* parseNDJSONStream<T = AnyParsedNDJSON>(\n response: Response\n): AsyncGenerator<T, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed === '') continue;\n\n try {\n const parsed = JSON.parse(trimmed) as T;\n yield parsed;\n } catch {\n // Skip invalid JSON lines\n console.warn('Skipping invalid JSON line:', trimmed);\n }\n }\n }\n\n // Handle any remaining line in buffer\n if (buffer.trim()) {\n try {\n const parsed = JSON.parse(buffer.trim()) as T;\n yield parsed;\n } catch {\n // Skip invalid JSON\n console.warn('Skipping invalid JSON in buffer:', buffer.trim());\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Parse generic chunked stream\n * Yields raw chunks as strings\n */\nexport async function* parseChunkedStream<T = string>(\n response: Response\n): AsyncGenerator<T, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n yield chunk as T;\n }\n } finally {\n reader.releaseLock();\n }\n}\n","/**\n * Detects if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return (\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as unknown as { window: unknown }).window !==\n 'undefined' &&\n typeof (globalThis as unknown as { window: { document: unknown } }).window\n .document !== 'undefined'\n );\n}\n\n/**\n * Detects if the code is running in a Node.js environment\n */\nexport function isNode(): boolean {\n return (\n typeof process !== 'undefined' &&\n process.versions != null &&\n process.versions.node != null\n );\n}\n\n/**\n * Encodes a string to Base64, using the appropriate method for the environment\n * @param str - String to encode\n * @returns Base64 encoded string\n */\nexport function encodeBase64(str: string): string {\n if (isBrowser()) {\n // Browser environment - use btoa\n if (typeof btoa !== 'undefined') {\n return btoa(str);\n }\n // Fallback for environments where btoa might not be available\n throw new Error(\n 'btoa is not available. This should not happen in a browser environment.'\n );\n } else {\n // Node.js environment - use Buffer\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'utf-8').toString('base64');\n }\n throw new Error(\n \"Buffer is not available. Please ensure you're running in Node.js or provide a polyfill.\"\n );\n }\n}\n\n/**\n * Checks if the native fetch API is available\n * @returns true if fetch is available, false otherwise\n */\nexport function isFetchAvailable(): boolean {\n return typeof fetch !== 'undefined';\n}\n\n/**\n * Checks if AbortController is available\n * @returns true if AbortController is available, false otherwise\n */\nexport function isAbortControllerAvailable(): boolean {\n return typeof AbortController !== 'undefined';\n}\n\n/**\n * Gets a helpful error message if fetch is not available\n * @returns Error message with suggestions\n */\nexport function getFetchErrorMessage(): string {\n if (isBrowser()) {\n return 'fetch is not available in this browser. Please use a modern browser or provide a polyfill.';\n } else {\n return \"fetch is not available. Node.js 22+ includes native fetch. For older versions, please provide a custom fetch implementation (e.g., from 'undici' or 'node-fetch').\";\n }\n}\n","import type { QueryParams } from '../types';\n\n/**\n * Serializes query parameters into a URLSearchParams object\n * Handles arrays, objects, and primitive values\n */\nexport function serializeQueryParams(query: QueryParams): URLSearchParams {\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n // Append each array item\n for (const item of value) {\n if (item !== undefined && item !== null) {\n params.append(key, String(item));\n }\n }\n } else {\n params.set(key, String(value));\n }\n }\n\n return params;\n}\n\n/**\n * Builds a URL with query parameters\n * @param baseUrl - Base URL\n * @param path - Path to append\n * @param query - Query parameters object\n * @returns Complete URL with query string\n */\nexport function buildUrl(\n baseUrl: string,\n path: string,\n query?: QueryParams | undefined\n): URL {\n // Normalize path - remove trailing slash if present (except for root)\n let normalizedPath = path || '';\n if (normalizedPath.length > 1 && normalizedPath.endsWith('/')) {\n normalizedPath = normalizedPath.slice(0, -1);\n }\n\n // Normalize baseURL to ensure it has a trailing slash if it has a path component\n // This is needed because new URL('path', 'https://example.com/base') creates\n // 'https://example.com/path' (treats base as a file), but\n // new URL('path', 'https://example.com/base/') creates 'https://example.com/base/path' (correct)\n let normalizedBaseUrl = baseUrl || '';\n if (normalizedBaseUrl) {\n try {\n const baseUrlObj = new URL(normalizedBaseUrl);\n // If baseURL has a path component and doesn't end with /, add it\n if (\n baseUrlObj.pathname &&\n baseUrlObj.pathname !== '/' &&\n !normalizedBaseUrl.endsWith('/')\n ) {\n normalizedBaseUrl = normalizedBaseUrl + '/';\n }\n } catch {\n // If baseUrl is not a valid URL, proceed as-is\n }\n }\n\n // If path starts with /, strip it so it appends to baseURL instead of replacing it\n if (normalizedPath.startsWith('/')) {\n normalizedPath = normalizedPath.slice(1);\n }\n\n const url = new URL(normalizedPath, normalizedBaseUrl);\n\n if (query) {\n const params = serializeQueryParams(query);\n // Merge with existing search params\n // Get all unique keys first\n const keys = Array.from(new Set(params.keys()));\n for (const key of keys) {\n // Remove existing values for this key\n url.searchParams.delete(key);\n // Append all values (handles arrays correctly)\n for (const value of params.getAll(key)) {\n url.searchParams.append(key, value);\n }\n }\n }\n\n return url;\n}\n\n/**\n * Determines the content type from a body value\n * @param body - Request body\n * @returns Content type string or undefined\n */\nexport function getContentType(body: unknown): string | undefined {\n if (body === null || body === undefined) {\n return undefined;\n }\n\n if (body instanceof FormData) {\n // FormData sets its own content-type with boundary\n return undefined; // Let the browser set it\n }\n\n if (body instanceof URLSearchParams) {\n return 'application/x-www-form-urlencoded';\n }\n\n if (typeof body === 'string') {\n // Try to detect if it's JSON\n try {\n JSON.parse(body);\n return 'application/json';\n } catch {\n return 'text/plain';\n }\n }\n\n if (typeof body === 'object') {\n return 'application/json';\n }\n\n return undefined;\n}\n\n/**\n * Serializes a request body based on its type\n * @param body - Request body to serialize\n * @param contentType - Optional content type hint to guide serialization\n * @returns Serialized body (string, FormData, Blob, ArrayBuffer, etc.)\n */\nexport function serializeBody(\n body: unknown,\n contentType?: string\n): RequestInit['body'] | null {\n if (body === null || body === undefined) {\n return null;\n }\n\n // If it's already a valid body type, return as-is\n if (\n typeof body === 'string' ||\n body instanceof FormData ||\n body instanceof URLSearchParams ||\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n ArrayBuffer.isView(body)\n ) {\n return body as RequestInit['body'];\n }\n\n // Handle form-urlencoded: convert object to URLSearchParams\n if (\n contentType === 'application/x-www-form-urlencoded' &&\n typeof body === 'object' &&\n body !== null &&\n !Array.isArray(body)\n ) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(body)) {\n if (value !== null && value !== undefined) {\n if (Array.isArray(value)) {\n // Handle array values (multiple params with same key)\n for (const item of value) {\n params.append(key, String(item));\n }\n } else {\n params.append(key, String(value));\n }\n }\n }\n return params;\n }\n\n // For objects, serialize to JSON (default)\n if (typeof body === 'object') {\n return JSON.stringify(body);\n }\n\n // For primitives, convert to string\n return String(body);\n}\n","/**\n * Parses a response based on its content type\n * @param response - Fetch Response object\n * @returns Parsed response data\n */\n\ntype AnyPromiseResponse = Promise<string | object | ArrayBuffer | unknown>;\n\nexport async function parseResponse(response: Response): AnyPromiseResponse {\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n return await response.json();\n } else if (contentType.startsWith('text/')) {\n return await response.text();\n } else {\n // Binary or unknown content type - return ArrayBuffer\n return await response.arrayBuffer();\n }\n}\n\n/**\n * Checks if a response indicates success (status 200-299)\n * @param response - Fetch Response object\n * @returns true if response is successful\n */\nexport function isSuccessResponse(response: Response): boolean {\n return response.ok;\n}\n","import { createFetchError, FetchError } from './errors';\nimport { HookRegistry } from './hooks';\nimport type { Hook, HookStage } from './hooks/types';\nimport { calculateRetryDelay } from './retry';\nimport {\n parseSSEStream,\n parseNDJSONStream,\n parseChunkedStream,\n} from './streaming';\nimport type {\n FetchClientConfig,\n QueryParams,\n RequestOptions,\n StreamingRequestOptions,\n AuthStrategy,\n} from './types';\nimport {\n buildUrl,\n serializeBody,\n getContentType,\n parseResponse,\n isSuccessResponse,\n} from './utils';\nimport {\n isFetchAvailable,\n getFetchErrorMessage,\n encodeBase64,\n} from './utils/environment';\n\n/**\n * Universal HTTP fetch client with hooks, retries, and streaming support\n */\nexport class FetchClient {\n private hookRegistry: HookRegistry;\n private cfg: FetchClientConfig;\n\n constructor(config: FetchClientConfig = {}) {\n this.cfg = config;\n\n // Set default base URL if not provided\n if (!this.cfg.baseURL) {\n this.cfg.baseURL = '';\n }\n\n // Initialize hook registry\n this.hookRegistry = new HookRegistry(this.cfg.hooks);\n\n // Check fetch availability\n if (!isFetchAvailable() && !this.cfg.fetch) {\n throw new Error(getFetchErrorMessage());\n }\n }\n\n /**\n * Add an authentication strategy\n */\n addAuthStrategy(strategy: AuthStrategy): void {\n if (!this.cfg.authStrategies) {\n this.cfg.authStrategies = [];\n }\n this.cfg.authStrategies.push(strategy);\n }\n\n /**\n * Remove all authentication strategies\n */\n clearAuthStrategies(): void {\n if (this.cfg.authStrategies) {\n this.cfg.authStrategies = [];\n }\n }\n\n /**\n * Register a hook for a specific lifecycle stage\n */\n useHook(stage: HookStage, hook: Hook): void {\n this.hookRegistry.register(stage, hook);\n }\n\n /**\n * Remove a hook\n */\n removeHook(stage: HookStage, hook: Hook): boolean {\n return this.hookRegistry.remove(stage, hook);\n }\n\n /**\n * Clear hooks for a stage or all hooks\n */\n clearHooks(stage?: HookStage): void {\n this.hookRegistry.clear(stage);\n }\n\n /**\n * Make an HTTP request\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async request<T = any>(init: RequestOptions): Promise<T> {\n const url = buildUrl(this.cfg.baseURL || '', init.path, init.query);\n // Create headers, handling both plain objects and Headers instances\n const headers = new Headers(this.cfg.headers || {});\n if (init.headers) {\n if (init.headers instanceof Headers) {\n // Copy from Headers object\n init.headers.forEach((value, key) => {\n headers.set(key, value);\n });\n } else {\n // Merge from plain object\n Object.entries(init.headers).forEach(([key, value]) => {\n headers.set(key, String(value));\n });\n }\n }\n\n // Apply authentication (may modify URL for query-based auth)\n await this.applyAuthentication(headers, url);\n\n // Set content type if body is provided (check before serialization)\n let bodyContentType: string | undefined;\n if (init.body !== undefined) {\n // Check if Content-Type is already set in headers\n bodyContentType = headers.get('Content-Type') || undefined;\n if (!bodyContentType) {\n bodyContentType = getContentType(init.body);\n if (bodyContentType) {\n headers.set('Content-Type', bodyContentType);\n }\n }\n }\n\n const retries = this.cfg.retry?.retries ?? 0;\n const baseBackoff = this.cfg.retry?.backoffMs ?? 300;\n const retryOn = this.cfg.retry?.retryOn ?? [429, 500, 502, 503, 504];\n const retryStrategy = this.cfg.retry?.strategy ?? 'exponential';\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries + 1; attempt++) {\n try {\n // Rebuild URL for each attempt (in case query params were modified by auth)\n const attemptUrl = buildUrl(\n this.cfg.baseURL || '',\n init.path,\n init.query\n );\n // Clone headers for each attempt\n const attemptHeaders = new Headers(headers);\n // Re-apply authentication for each attempt\n await this.applyAuthentication(attemptHeaders, attemptUrl);\n return await this.doRequest<T>(\n attemptUrl,\n init,\n attemptHeaders,\n attempt,\n bodyContentType\n );\n } catch (err) {\n lastError = err;\n\n // Check if we should retry\n const shouldRetry = this.shouldRetry(err, attempt, retries, retryOn);\n\n if (shouldRetry) {\n // Execute beforeRetry hook\n if (this.hookRegistry.has('beforeRetry')) {\n const serializedBody = serializeBody(init.body, bodyContentType);\n await this.hookRegistry.execute('beforeRetry', {\n url: url.toString(),\n init: { ...init, headers, body: serializedBody },\n attempt,\n error: err,\n retryCount: attempt,\n });\n }\n\n // Calculate delay\n const delay = calculateRetryDelay(\n attempt,\n retryStrategy,\n baseBackoff\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n\n // Execute afterRetry hook\n if (this.hookRegistry.has('afterRetry')) {\n const serializedBody = serializeBody(init.body, bodyContentType);\n await this.hookRegistry.execute('afterRetry', {\n url: url.toString(),\n init: { ...init, headers, body: serializedBody },\n attempt,\n error: err,\n retryCount: attempt,\n success: false, // Will be updated if retry succeeds\n });\n }\n\n continue;\n }\n\n // Not retrying - throw the error\n throw err;\n }\n }\n\n throw lastError as unknown;\n }\n\n /**\n * Make a streaming HTTP request\n */\n async *requestStream<T = unknown>(\n init: StreamingRequestOptions\n ): AsyncGenerator<T, void, unknown> {\n const url = buildUrl(this.cfg.baseURL || '', init.path, init.query);\n // Create headers, handling both plain objects and Headers instances\n const headers = new Headers(this.cfg.headers || {});\n if (init.headers) {\n if (init.headers instanceof Headers) {\n // Copy from Headers object\n init.headers.forEach((value, key) => {\n headers.set(key, value);\n });\n } else {\n // Merge from plain object\n Object.entries(init.headers).forEach(([key, value]) => {\n headers.set(key, String(value));\n });\n }\n }\n\n // Apply authentication (may modify URL for query-based auth)\n await this.applyAuthentication(headers, url);\n\n // Determine content type for body serialization\n let bodyContentType: string | undefined =\n headers.get('Content-Type') || undefined;\n if (init.contentType && !bodyContentType) {\n bodyContentType = init.contentType;\n headers.set('Content-Type', bodyContentType);\n }\n\n const fetchInit: Omit<RequestInit, 'body'> & {\n path: string;\n method: string;\n query?: QueryParams | undefined;\n headers: Headers;\n body: RequestInit['body'] | undefined;\n } = {\n ...init,\n headers,\n body: serializeBody(init.body, bodyContentType),\n };\n\n // Set credentials from config if provided\n if (this.cfg.credentials !== undefined) {\n fetchInit.credentials = this.cfg.credentials;\n }\n\n // Execute beforeRequest hook\n if (this.hookRegistry.has('beforeRequest')) {\n await this.hookRegistry.execute('beforeRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n });\n }\n\n let controller: AbortController | undefined;\n let timeoutId: NodeJS.Timeout | undefined;\n const existingSignal = fetchInit.signal;\n\n // Setup timeout\n if (this.cfg.timeoutMs && typeof AbortController !== 'undefined') {\n controller = new AbortController();\n if (existingSignal) {\n if (existingSignal.aborted) {\n controller.abort();\n } else {\n existingSignal.addEventListener('abort', () => {\n controller?.abort();\n });\n }\n }\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => {\n controller?.abort();\n // Execute onTimeout hook\n if (this.hookRegistry.has('onTimeout')) {\n this.hookRegistry.execute('onTimeout', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n timeoutMs: this.cfg.timeoutMs,\n });\n }\n }, this.cfg.timeoutMs);\n }\n\n try {\n const fetchFn = this.cfg.fetch || fetch;\n const res = await fetchFn(url.toString(), fetchInit as RequestInit);\n\n // Execute afterRequest hook\n if (this.hookRegistry.has('afterRequest')) {\n await this.hookRegistry.execute('afterRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n\n if (!res.ok) {\n const parsed = await parseResponse(res);\n const message = (parsed as { message?: string })?.message as\n | string\n | undefined;\n const error = createFetchError(\n res.status,\n message || `HTTP ${res.status}`,\n parsed,\n res.headers\n );\n\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n error,\n });\n }\n\n throw error;\n }\n\n // Execute onStreamStart hook\n if (this.hookRegistry.has('onStreamStart')) {\n await this.hookRegistry.execute('onStreamStart', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n\n // Route to appropriate parser based on streaming format\n const streamingFormat = init.streamingFormat || 'chunked';\n\n if (streamingFormat === 'sse') {\n for await (const chunk of parseSSEStream(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n } else if (streamingFormat === 'ndjson') {\n for await (const chunk of parseNDJSONStream<T>(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n } else {\n // Generic chunked streaming\n for await (const chunk of parseChunkedStream<T>(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n }\n\n // Execute onStreamEnd hook\n if (this.hookRegistry.has('onStreamEnd')) {\n await this.hookRegistry.execute('onStreamEnd', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n } catch (err) {\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n error: err,\n });\n }\n throw err;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Internal method to execute a single request attempt\n */\n private async doRequest<T>(\n url: URL,\n init: RequestOptions,\n baseHeaders: Headers,\n attempt: number,\n contentType?: string\n ): Promise<T> {\n // Headers are already cloned and auth is already applied\n const requestHeaders = baseHeaders;\n\n const fetchInit: Omit<RequestInit, 'body'> & {\n path: string;\n method: string;\n\n query?: QueryParams | undefined;\n headers: Headers;\n body: RequestInit['body'] | undefined;\n } = {\n ...init,\n headers: requestHeaders,\n body: serializeBody(init.body, contentType),\n };\n\n // Set credentials from config if provided\n if (this.cfg.credentials !== undefined) {\n fetchInit.credentials = this.cfg.credentials;\n }\n\n // Execute beforeRequest hook\n if (this.hookRegistry.has('beforeRequest')) {\n await this.hookRegistry.execute('beforeRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n });\n }\n\n let controller: AbortController | undefined;\n let timeoutId: NodeJS.Timeout | undefined;\n const existingSignal = fetchInit.signal;\n\n // Setup timeout\n if (this.cfg.timeoutMs && typeof AbortController !== 'undefined') {\n controller = new AbortController();\n if (existingSignal) {\n if (existingSignal.aborted) {\n controller.abort();\n } else {\n existingSignal.addEventListener('abort', () => {\n controller?.abort();\n });\n }\n }\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => {\n controller?.abort();\n // Execute onTimeout hook\n if (this.hookRegistry.has('onTimeout')) {\n this.hookRegistry.execute('onTimeout', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n timeoutMs: this.cfg.timeoutMs,\n });\n }\n }, this.cfg.timeoutMs);\n }\n\n try {\n const fetchFn = this.cfg.fetch || fetch;\n const res = await fetchFn(url.toString(), fetchInit as RequestInit);\n\n // Execute afterRequest hook\n if (this.hookRegistry.has('afterRequest')) {\n await this.hookRegistry.execute('afterRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n response: res,\n });\n }\n\n const parsed = await parseResponse(res);\n\n // Execute afterResponse hook\n if (this.hookRegistry.has('afterResponse')) {\n await this.hookRegistry.execute('afterResponse', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n response: res,\n data: parsed,\n });\n }\n\n if (!isSuccessResponse(res)) {\n const message = (parsed as { message?: string })?.message as\n | string\n | undefined;\n const error = createFetchError(\n res.status,\n message || `HTTP ${res.status}`,\n parsed,\n res.headers\n );\n\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n error,\n });\n }\n\n throw error;\n }\n\n return parsed as T;\n } catch (err) {\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n error: err,\n });\n }\n\n // Re-throw with proper error type if needed\n if (err instanceof DOMException) {\n throw err;\n }\n if (err instanceof FetchError) {\n throw err;\n }\n\n // For network errors, try to extract status if available\n const status = (err as unknown as { status?: number })?.status as\n | number\n | undefined;\n const statusCode = typeof status === 'number' ? status : 0;\n if (typeof err === 'string') {\n throw createFetchError(statusCode, err);\n }\n throw createFetchError(\n statusCode,\n (err as Error)?.message || 'Network error'\n );\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Apply authentication strategies\n */\n private async applyAuthentication(headers: Headers, url: URL): Promise<void> {\n if (!this.cfg.authStrategies) {\n return;\n }\n\n for (const strategy of this.cfg.authStrategies) {\n await this.applyAuthStrategy(strategy, headers, url);\n }\n }\n\n /**\n * Apply a single authentication strategy\n */\n private async applyAuthStrategy(\n strategy: AuthStrategy,\n headers: Headers,\n url: URL\n ): Promise<void> {\n switch (strategy.type) {\n case 'bearer': {\n const token =\n typeof strategy.token === 'function'\n ? await strategy.token()\n : strategy.token;\n if (token != null) {\n const headerName = strategy.headerName || 'Authorization';\n headers.set(headerName, `Bearer ${String(token)}`);\n }\n break;\n }\n\n case 'basic': {\n const encoded = encodeBase64(\n `${strategy.username}:${strategy.password}`\n );\n headers.set('Authorization', `Basic ${encoded}`);\n break;\n }\n\n case 'apiKey': {\n const key =\n typeof strategy.key === 'function'\n ? await strategy.key()\n : strategy.key;\n if (key != null) {\n switch (strategy.location) {\n case 'header':\n headers.set(strategy.name, String(key));\n break;\n case 'query':\n url.searchParams.set(strategy.name, String(key));\n break;\n case 'cookie':\n headers.set('Cookie', `${strategy.name}=${String(key)}`);\n break;\n }\n }\n break;\n }\n\n case 'custom':\n await strategy.apply(headers, url);\n break;\n }\n }\n\n /**\n * Determine if an error should be retried\n */\n private shouldRetry(\n error: unknown,\n attempt: number,\n maxRetries: number,\n retryOn: number[]\n ): boolean {\n if (attempt >= maxRetries) {\n return false;\n }\n\n // Check custom retry condition\n if (this.cfg.retry?.retryOnError) {\n return this.cfg.retry.retryOnError(error);\n }\n\n // Check if it's a FetchError with a retryable status code\n if (error instanceof FetchError) {\n return retryOn.includes(error.status);\n }\n\n // Network errors (no status code) should be retried\n return true;\n }\n}\n","import type { AuthStrategy } from '@blimu/fetch';\nimport type { ClientOption } from './client';\n\nexport function buildAuthStrategies(cfg: ClientOption): AuthStrategy[] {\n const authStrategies: AuthStrategy[] = [...(cfg?.authStrategies ?? [])];\n\n if (cfg.bearer) {\n authStrategies.push({\n type: 'bearer',\n token: cfg.bearer,\n });\n }\n return authStrategies;\n}\n","import { parseSSEStream, parseNDJSONStream } from '@blimu/fetch';\n\nexport type PaginableQuery = { limit?: number; offset?: number } & Record<string, unknown>;\n\nexport async function* paginate<T>(\n fetchPage: (\n query?: PaginableQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ) => Promise<{ data?: T[]; hasMore?: boolean; limit?: number; offset?: number }>,\n initialQuery: PaginableQuery = {},\n pageSize = 100\n): AsyncGenerator<T, void, unknown> {\n let offset = Number(initialQuery.offset ?? 0);\n const limit = Number(initialQuery.limit ?? pageSize);\n // shallow copy to avoid mutating caller\n const baseQuery: PaginableQuery = { ...initialQuery };\n while (true) {\n const page = await fetchPage({ ...baseQuery, limit, offset });\n const items = page.data ?? [];\n for (const item of items) {\n yield item;\n }\n if (!page.hasMore || items.length < limit) break;\n offset += limit;\n }\n}\n\nexport async function listAll<T>(\n fetchPage: (\n query?: PaginableQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ) => Promise<{ data?: T[]; hasMore?: boolean; limit?: number; offset?: number }>,\n query: PaginableQuery = {},\n pageSize = 100\n): Promise<T[]> {\n const out: T[] = [];\n for await (const item of paginate<T>(fetchPage, query, pageSize)) out.push(item);\n return out;\n}\n\n/**\n * Filters out undefined values from an array while preserving type safety\n * Useful for query keys where optional parameters might be undefined\n * Preserves tuple types when no undefined values are present\n */\nexport function isNotUndefined<T extends readonly unknown[]>(arr: T): T {\n // Type assertion: when no undefined values exist, tuple is preserved\n // When undefined values exist, they are filtered but type system can't infer exact tuple shape\n return arr.filter(\n (item): item is Exclude<T[number], undefined> => item !== undefined\n ) as unknown as T;\n}\n\n// Re-export streaming parsers from @blimu/fetch\nexport { parseSSEStream, parseNDJSONStream };\n","import type { FetchClient } from '@blimu/fetch';\nimport type * as Schema from '../schema';\nimport { isNotUndefined } from '../utils';\n\nexport class AuthService {\n constructor(private core: FetchClient) {}\n\n /**\n * POST /v1/auth/logout*\n * @summary Logout and invalidate session*/\n logout(init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown> {\n return this.core.request({\n method: 'POST',\n path: `/v1/auth/logout`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for logout\n * @returns ['v1/auth/logout']\n */\n logout__queryKeys(): readonly ['v1/auth/logout'] {\n return ['v1/auth/logout'] as const;\n }\n\n /**\n * POST /v1/auth/refresh*\n * @summary Refresh session token*/\n refresh(\n query?: Schema.AuthRefreshQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.RefreshResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/auth/refresh`,\n query,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for refresh\n * @returns ['v1/auth/refresh', query]\n */\n refresh__queryKeys(query?: Schema.AuthRefreshQuery): readonly string[] {\n const keys = ['v1/auth/refresh', query] as const;\n return isNotUndefined(keys) as readonly string[];\n }\n\n /**\n * GET /v1/auth/session*\n * @summary Get current session*/\n getSession(init?: Omit<RequestInit, 'method' | 'body'>): Promise<Schema.SessionResponse> {\n return this.core.request({\n method: 'GET',\n path: `/v1/auth/session`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for getSession\n * @returns ['v1/auth/session']\n */\n getSession__queryKeys(): readonly ['v1/auth/session'] {\n return ['v1/auth/session'] as const;\n }\n}\n","import type { FetchClient } from '@blimu/fetch';\nimport type * as Schema from '../schema';\n\nexport class EntitlementsService {\n constructor(private core: FetchClient) {}\n\n /**\n * GET /v1/client/entitlements/list-for-tenant/{tenantResourceId}*\n * @summary List entitlements for a tenant and all its sub-resources*\n * @description Returns entitlements for a tenant resource and all its descendant resources for the authenticated user. This endpoint scopes queries to a single tenant, preventing cross-tenant data access. Only evaluates roles and plans (excludes limits). Results are cached per resource for performance. The tenant resource type is automatically determined from the environment definition (resource marked as `is_tenant: true`).*/\n listForTenant(\n tenantResourceId: string,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.EntitlementsListResult> {\n return this.core.request({\n method: 'GET',\n path: `/v1/client/entitlements/list-for-tenant/${encodeURIComponent(tenantResourceId)}`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for listForTenant\n * @returns ['v1/client/entitlements/list-for-tenant', tenantResourceId]\n */\n listForTenant__queryKeys(\n tenantResourceId: string\n ): readonly ['v1/client/entitlements/list-for-tenant', string] {\n return ['v1/client/entitlements/list-for-tenant', tenantResourceId] as const;\n }\n}\n"],"mappings":"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","names":["FetchError","Error","message","status","data","headers","name","captureStackTrace","ClientError","ServerError","BadRequestError","UnauthorizedError","ForbiddenError","NotFoundError","MethodNotAllowedError","ConflictError","UnprocessableEntityError","TooManyRequestsError","InternalServerError","BadGatewayError","ServiceUnavailableError","GatewayTimeoutError","createFetchError","defaultMessage","HookRegistry","hooks","Map","config","registerFromConfig","stage","Object","entries","Array","isArray","hook","register","has","set","get","push","remove","index","indexOf","splice","clear","delete","execute","context","length","exponentialStrategy","attempt","baseBackoffMs","Math","pow","linearStrategy","getRetryStrategy","strategy","calculateRetryDelay","strategyFn","parseSSEStream","response","body","reader","getReader","decoder","TextDecoder","buffer","done","value","read","decode","stream","lines","split","pop","currentEvent","line","trim","undefined","colonIndex","field","substring","type","id","releaseLock","parseNDJSONStream","trimmed","parsed","JSON","parse","console","warn","parseChunkedStream","chunk","isBrowser","globalThis","window","document","isNode","process","versions","node","encodeBase64","str","btoa","Buffer","from","toString","isFetchAvailable","fetch","isAbortControllerAvailable","AbortController","getFetchErrorMessage","serializeQueryParams","query","params","URLSearchParams","key","item","append","String","buildUrl","baseUrl","path","normalizedPath","endsWith","slice","normalizedBaseUrl","baseUrlObj","URL","pathname","startsWith","url","keys","Set","searchParams","getAll","getContentType","FormData","serializeBody","contentType","Blob","ArrayBuffer","isView","stringify","parseResponse","includes","json","text","arrayBuffer","isSuccessResponse","ok","FetchClient","hookRegistry","cfg","baseURL","addAuthStrategy","authStrategies","clearAuthStrategies","useHook","removeHook","clearHooks","request","init","Headers","forEach","applyAuthentication","bodyContentType","retries","retry","baseBackoff","backoffMs","retryOn","retryStrategy","lastError","attemptUrl","attemptHeaders","doRequest","err","shouldRetry","serializedBody","error","retryCount","delay","Promise","resolve","setTimeout","success","requestStream","fetchInit","credentials","controller","timeoutId","existingSignal","signal","timeoutMs","aborted","abort","addEventListener","fetchFn","res","streamingFormat","transformedChunk","clearTimeout","baseHeaders","requestHeaders","DOMException","statusCode","applyAuthStrategy","token","headerName","encoded","username","password","location","apply","maxRetries","retryOnError"]}
package/dist/client.d.mts CHANGED
@@ -1,18 +1,3 @@
1
- import { FetchClientConfig, BearerAuthStrategy, FetchError } from '@blimu/fetch';
2
1
  export { FetchError } from '@blimu/fetch';
3
- import { AuthService } from './services/auth.mjs';
4
- import { EntitlementsService } from './services/entitlements.mjs';
2
+ export { B as Blimu, a as BlimuError, C as ClientOption } from './client-iMSJXw0U.mjs';
5
3
  import './schema-Z0doltxY.mjs';
6
-
7
- type ClientOption = FetchClientConfig & {
8
- bearer?: BearerAuthStrategy['token'];
9
- };
10
- declare class Blimu {
11
- readonly auth: AuthService;
12
- readonly entitlements: EntitlementsService;
13
- constructor(options?: ClientOption);
14
- }
15
-
16
- declare const BlimuError: typeof FetchError;
17
-
18
- export { Blimu, BlimuError, type ClientOption };
package/dist/client.d.ts CHANGED
@@ -1,18 +1,3 @@
1
- import { FetchClientConfig, BearerAuthStrategy, FetchError } from '@blimu/fetch';
2
1
  export { FetchError } from '@blimu/fetch';
3
- import { AuthService } from './services/auth.js';
4
- import { EntitlementsService } from './services/entitlements.js';
2
+ export { B as Blimu, a as BlimuError, C as ClientOption } from './client-DKebla0_.js';
5
3
  import './schema-Z0doltxY.js';
6
-
7
- type ClientOption = FetchClientConfig & {
8
- bearer?: BearerAuthStrategy['token'];
9
- };
10
- declare class Blimu {
11
- readonly auth: AuthService;
12
- readonly entitlements: EntitlementsService;
13
- constructor(options?: ClientOption);
14
- }
15
-
16
- declare const BlimuError: typeof FetchError;
17
-
18
- export { Blimu, BlimuError, type ClientOption };