@blimu/client 1.1.0 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -26
- package/dist/__tests__/example.test.cjs +17135 -0
- package/dist/__tests__/example.test.cjs.map +1 -0
- package/dist/__tests__/example.test.d.mts +2 -0
- package/dist/__tests__/example.test.d.ts +2 -0
- package/dist/__tests__/example.test.mjs +17134 -0
- package/dist/__tests__/example.test.mjs.map +1 -0
- package/dist/auth-strategies.cjs +40 -0
- package/dist/auth-strategies.cjs.map +1 -0
- package/dist/auth-strategies.d.mts +9 -0
- package/dist/auth-strategies.d.ts +9 -0
- package/dist/auth-strategies.mjs +15 -0
- package/dist/auth-strategies.mjs.map +1 -0
- package/dist/{client.js → client.cjs} +159 -66
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.mts +12 -18
- package/dist/client.d.ts +12 -18
- package/dist/client.mjs +155 -64
- package/dist/client.mjs.map +1 -1
- package/dist/{index.js → index.cjs} +115 -132
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +6 -19
- package/dist/index.d.ts +6 -19
- package/dist/index.mjs +112 -130
- package/dist/index.mjs.map +1 -1
- package/dist/{schema-B4iFbKly.d.mts → schema-Z0doltxY.d.mts} +8 -10
- package/dist/{schema-B4iFbKly.d.ts → schema-Z0doltxY.d.ts} +8 -10
- package/dist/{schema.js → schema.cjs} +2 -1
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.mts +1 -2
- package/dist/schema.d.ts +1 -2
- package/dist/{schema.zod-CyY7RTSY.d.mts → schema.zod-BaQz36Pd.d.mts} +2 -6
- package/dist/{schema.zod-CyY7RTSY.d.ts → schema.zod-BaQz36Pd.d.ts} +2 -6
- package/dist/{schema.zod.js → schema.zod.cjs} +16 -25
- package/dist/schema.zod.cjs.map +1 -0
- package/dist/schema.zod.d.mts +1 -1
- package/dist/schema.zod.d.ts +1 -1
- package/dist/schema.zod.mjs +14 -22
- package/dist/schema.zod.mjs.map +1 -1
- package/dist/services/{auth.js → auth.cjs} +16 -5
- package/dist/services/auth.cjs.map +1 -0
- package/dist/services/auth.d.mts +6 -8
- package/dist/services/auth.d.ts +6 -8
- package/dist/services/auth.mjs +12 -4
- package/dist/services/auth.mjs.map +1 -1
- package/dist/services/{entitlements.js → entitlements.cjs} +4 -6
- package/dist/services/entitlements.cjs.map +1 -0
- package/dist/services/entitlements.d.mts +4 -6
- package/dist/services/entitlements.d.ts +4 -6
- package/dist/services/entitlements.mjs +2 -5
- package/dist/services/entitlements.mjs.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{utils.js → utils.cjs} +45 -26
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.mts +4 -3
- package/dist/utils.d.ts +4 -3
- package/dist/utils.mjs +42 -25
- package/dist/utils.mjs.map +1 -1
- package/package.json +32 -13
- package/dist/client.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/schema.js.map +0 -1
- package/dist/schema.zod.js.map +0 -1
- package/dist/services/auth.js.map +0 -1
- package/dist/services/entitlements.js.map +0 -1
- package/dist/utils.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.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"],"sourcesContent":["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","/**\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"],"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/utils.d.mts
CHANGED
|
@@ -4,17 +4,18 @@ type PaginableQuery = {
|
|
|
4
4
|
limit?: number;
|
|
5
5
|
offset?: number;
|
|
6
6
|
} & Record<string, unknown>;
|
|
7
|
-
declare function paginate<T>(fetchPage: (query?:
|
|
7
|
+
declare function paginate<T>(fetchPage: (query?: PaginableQuery, init?: Omit<RequestInit, 'method' | 'body'>) => Promise<{
|
|
8
8
|
data?: T[];
|
|
9
9
|
hasMore?: boolean;
|
|
10
10
|
limit?: number;
|
|
11
11
|
offset?: number;
|
|
12
12
|
}>, initialQuery?: PaginableQuery, pageSize?: number): AsyncGenerator<T, void, unknown>;
|
|
13
|
-
declare function listAll<T>(fetchPage: (query?:
|
|
13
|
+
declare function listAll<T>(fetchPage: (query?: PaginableQuery, init?: Omit<RequestInit, 'method' | 'body'>) => Promise<{
|
|
14
14
|
data?: T[];
|
|
15
15
|
hasMore?: boolean;
|
|
16
16
|
limit?: number;
|
|
17
17
|
offset?: number;
|
|
18
18
|
}>, query?: PaginableQuery, pageSize?: number): Promise<T[]>;
|
|
19
|
+
declare function isNotUndefined<T extends readonly unknown[]>(arr: T): T;
|
|
19
20
|
|
|
20
|
-
export { type PaginableQuery, listAll, paginate };
|
|
21
|
+
export { type PaginableQuery, isNotUndefined, listAll, paginate };
|
package/dist/utils.d.ts
CHANGED
|
@@ -4,17 +4,18 @@ type PaginableQuery = {
|
|
|
4
4
|
limit?: number;
|
|
5
5
|
offset?: number;
|
|
6
6
|
} & Record<string, unknown>;
|
|
7
|
-
declare function paginate<T>(fetchPage: (query?:
|
|
7
|
+
declare function paginate<T>(fetchPage: (query?: PaginableQuery, init?: Omit<RequestInit, 'method' | 'body'>) => Promise<{
|
|
8
8
|
data?: T[];
|
|
9
9
|
hasMore?: boolean;
|
|
10
10
|
limit?: number;
|
|
11
11
|
offset?: number;
|
|
12
12
|
}>, initialQuery?: PaginableQuery, pageSize?: number): AsyncGenerator<T, void, unknown>;
|
|
13
|
-
declare function listAll<T>(fetchPage: (query?:
|
|
13
|
+
declare function listAll<T>(fetchPage: (query?: PaginableQuery, init?: Omit<RequestInit, 'method' | 'body'>) => Promise<{
|
|
14
14
|
data?: T[];
|
|
15
15
|
hasMore?: boolean;
|
|
16
16
|
limit?: number;
|
|
17
17
|
offset?: number;
|
|
18
18
|
}>, query?: PaginableQuery, pageSize?: number): Promise<T[]>;
|
|
19
|
+
declare function isNotUndefined<T extends readonly unknown[]>(arr: T): T;
|
|
19
20
|
|
|
20
|
-
export { type PaginableQuery, listAll, paginate };
|
|
21
|
+
export { type PaginableQuery, isNotUndefined, listAll, paginate };
|
package/dist/utils.mjs
CHANGED
|
@@ -236,7 +236,7 @@ var HookRegistry = class {
|
|
|
236
236
|
if (!this.hooks.has(stage)) {
|
|
237
237
|
this.hooks.set(stage, []);
|
|
238
238
|
}
|
|
239
|
-
this.hooks.get(stage)
|
|
239
|
+
this.hooks.get(stage)?.push(hook);
|
|
240
240
|
}
|
|
241
241
|
/**
|
|
242
242
|
* Remove a specific hook from a stage
|
|
@@ -282,7 +282,14 @@ var HookRegistry = class {
|
|
|
282
282
|
* Check if any hooks are registered for a stage
|
|
283
283
|
*/
|
|
284
284
|
has(stage) {
|
|
285
|
-
|
|
285
|
+
if (!this.hooks.has(stage)) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
const hooks = this.hooks.get(stage);
|
|
289
|
+
if (!hooks) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
return hooks.length > 0;
|
|
286
293
|
}
|
|
287
294
|
};
|
|
288
295
|
var exponentialStrategy = /* @__PURE__ */ __name((attempt, baseBackoffMs) => {
|
|
@@ -397,7 +404,7 @@ async function* parseNDJSONStream(response) {
|
|
|
397
404
|
try {
|
|
398
405
|
const parsed = JSON.parse(trimmed);
|
|
399
406
|
yield parsed;
|
|
400
|
-
} catch
|
|
407
|
+
} catch {
|
|
401
408
|
console.warn("Skipping invalid JSON line:", trimmed);
|
|
402
409
|
}
|
|
403
410
|
}
|
|
@@ -406,7 +413,7 @@ async function* parseNDJSONStream(response) {
|
|
|
406
413
|
try {
|
|
407
414
|
const parsed = JSON.parse(buffer.trim());
|
|
408
415
|
yield parsed;
|
|
409
|
-
} catch
|
|
416
|
+
} catch {
|
|
410
417
|
console.warn("Skipping invalid JSON in buffer:", buffer.trim());
|
|
411
418
|
}
|
|
412
419
|
}
|
|
@@ -611,19 +618,17 @@ var FetchClient = class {
|
|
|
611
618
|
* Add an authentication strategy
|
|
612
619
|
*/
|
|
613
620
|
addAuthStrategy(strategy) {
|
|
614
|
-
if (!this.cfg.
|
|
615
|
-
this.cfg.
|
|
616
|
-
strategies: []
|
|
617
|
-
};
|
|
621
|
+
if (!this.cfg.authStrategies) {
|
|
622
|
+
this.cfg.authStrategies = [];
|
|
618
623
|
}
|
|
619
|
-
this.cfg.
|
|
624
|
+
this.cfg.authStrategies.push(strategy);
|
|
620
625
|
}
|
|
621
626
|
/**
|
|
622
627
|
* Remove all authentication strategies
|
|
623
628
|
*/
|
|
624
629
|
clearAuthStrategies() {
|
|
625
|
-
if (this.cfg.
|
|
626
|
-
this.cfg.
|
|
630
|
+
if (this.cfg.authStrategies) {
|
|
631
|
+
this.cfg.authStrategies = [];
|
|
627
632
|
}
|
|
628
633
|
}
|
|
629
634
|
/**
|
|
@@ -647,8 +652,9 @@ var FetchClient = class {
|
|
|
647
652
|
/**
|
|
648
653
|
* Make an HTTP request
|
|
649
654
|
*/
|
|
655
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
650
656
|
async request(init) {
|
|
651
|
-
|
|
657
|
+
const url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
|
|
652
658
|
const headers = new Headers(this.cfg.headers || {});
|
|
653
659
|
if (init.headers) {
|
|
654
660
|
if (init.headers instanceof Headers) {
|
|
@@ -685,7 +691,7 @@ var FetchClient = class {
|
|
|
685
691
|
let lastError;
|
|
686
692
|
for (let attempt = 0; attempt <= retries + 1; attempt++) {
|
|
687
693
|
try {
|
|
688
|
-
|
|
694
|
+
const attemptUrl = buildUrl(this.cfg.baseURL || "", init.path, init.query);
|
|
689
695
|
const attemptHeaders = new Headers(headers);
|
|
690
696
|
await this.applyAuthentication(attemptHeaders, attemptUrl);
|
|
691
697
|
return await this.doRequest(attemptUrl, init, attemptHeaders, attempt, bodyContentType);
|
|
@@ -694,11 +700,13 @@ var FetchClient = class {
|
|
|
694
700
|
const shouldRetry = this.shouldRetry(err, attempt, retries, retryOn);
|
|
695
701
|
if (shouldRetry) {
|
|
696
702
|
if (this.hookRegistry.has("beforeRetry")) {
|
|
703
|
+
const serializedBody = serializeBody(init.body, bodyContentType);
|
|
697
704
|
await this.hookRegistry.execute("beforeRetry", {
|
|
698
705
|
url: url.toString(),
|
|
699
706
|
init: {
|
|
700
707
|
...init,
|
|
701
|
-
headers
|
|
708
|
+
headers,
|
|
709
|
+
body: serializedBody
|
|
702
710
|
},
|
|
703
711
|
attempt,
|
|
704
712
|
error: err,
|
|
@@ -708,11 +716,13 @@ var FetchClient = class {
|
|
|
708
716
|
const delay = calculateRetryDelay(attempt, retryStrategy, baseBackoff);
|
|
709
717
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
710
718
|
if (this.hookRegistry.has("afterRetry")) {
|
|
719
|
+
const serializedBody = serializeBody(init.body, bodyContentType);
|
|
711
720
|
await this.hookRegistry.execute("afterRetry", {
|
|
712
721
|
url: url.toString(),
|
|
713
722
|
init: {
|
|
714
723
|
...init,
|
|
715
|
-
headers
|
|
724
|
+
headers,
|
|
725
|
+
body: serializedBody
|
|
716
726
|
},
|
|
717
727
|
attempt,
|
|
718
728
|
error: err,
|
|
@@ -731,7 +741,7 @@ var FetchClient = class {
|
|
|
731
741
|
* Make a streaming HTTP request
|
|
732
742
|
*/
|
|
733
743
|
async *requestStream(init) {
|
|
734
|
-
|
|
744
|
+
const url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
|
|
735
745
|
const headers = new Headers(this.cfg.headers || {});
|
|
736
746
|
if (init.headers) {
|
|
737
747
|
if (init.headers instanceof Headers) {
|
|
@@ -805,7 +815,8 @@ var FetchClient = class {
|
|
|
805
815
|
}
|
|
806
816
|
if (!res.ok) {
|
|
807
817
|
const parsed = await parseResponse(res);
|
|
808
|
-
const
|
|
818
|
+
const message = parsed?.message;
|
|
819
|
+
const error = createFetchError(res.status, message || `HTTP ${res.status}`, parsed, res.headers);
|
|
809
820
|
if (this.hookRegistry.has("onError")) {
|
|
810
821
|
await this.hookRegistry.execute("onError", {
|
|
811
822
|
url: url.toString(),
|
|
@@ -827,7 +838,7 @@ var FetchClient = class {
|
|
|
827
838
|
const streamingFormat = init.streamingFormat || "chunked";
|
|
828
839
|
if (streamingFormat === "sse") {
|
|
829
840
|
for await (const chunk of parseSSEStream(res)) {
|
|
830
|
-
|
|
841
|
+
const transformedChunk = chunk;
|
|
831
842
|
if (this.hookRegistry.has("onStreamChunk")) {
|
|
832
843
|
await this.hookRegistry.execute("onStreamChunk", {
|
|
833
844
|
url: url.toString(),
|
|
@@ -840,7 +851,7 @@ var FetchClient = class {
|
|
|
840
851
|
}
|
|
841
852
|
} else if (streamingFormat === "ndjson") {
|
|
842
853
|
for await (const chunk of parseNDJSONStream(res)) {
|
|
843
|
-
|
|
854
|
+
const transformedChunk = chunk;
|
|
844
855
|
if (this.hookRegistry.has("onStreamChunk")) {
|
|
845
856
|
await this.hookRegistry.execute("onStreamChunk", {
|
|
846
857
|
url: url.toString(),
|
|
@@ -853,7 +864,7 @@ var FetchClient = class {
|
|
|
853
864
|
}
|
|
854
865
|
} else {
|
|
855
866
|
for await (const chunk of parseChunkedStream(res)) {
|
|
856
|
-
|
|
867
|
+
const transformedChunk = chunk;
|
|
857
868
|
if (this.hookRegistry.has("onStreamChunk")) {
|
|
858
869
|
await this.hookRegistry.execute("onStreamChunk", {
|
|
859
870
|
url: url.toString(),
|
|
@@ -958,7 +969,8 @@ var FetchClient = class {
|
|
|
958
969
|
});
|
|
959
970
|
}
|
|
960
971
|
if (!isSuccessResponse(res)) {
|
|
961
|
-
const
|
|
972
|
+
const message = parsed?.message;
|
|
973
|
+
const error = createFetchError(res.status, message || `HTTP ${res.status}`, parsed, res.headers);
|
|
962
974
|
if (this.hookRegistry.has("onError")) {
|
|
963
975
|
await this.hookRegistry.execute("onError", {
|
|
964
976
|
url: url.toString(),
|
|
@@ -1001,10 +1013,10 @@ var FetchClient = class {
|
|
|
1001
1013
|
* Apply authentication strategies
|
|
1002
1014
|
*/
|
|
1003
1015
|
async applyAuthentication(headers, url) {
|
|
1004
|
-
if (!this.cfg.
|
|
1016
|
+
if (!this.cfg.authStrategies) {
|
|
1005
1017
|
return;
|
|
1006
1018
|
}
|
|
1007
|
-
for (const strategy of this.cfg.
|
|
1019
|
+
for (const strategy of this.cfg.authStrategies) {
|
|
1008
1020
|
await this.applyAuthStrategy(strategy, headers, url);
|
|
1009
1021
|
}
|
|
1010
1022
|
}
|
|
@@ -1082,11 +1094,16 @@ async function* paginate(fetchPage, initialQuery = {}, pageSize = 100) {
|
|
|
1082
1094
|
}
|
|
1083
1095
|
async function listAll(fetchPage, query = {}, pageSize = 100) {
|
|
1084
1096
|
const out = [];
|
|
1085
|
-
for await (const item of paginate(fetchPage, query, pageSize))
|
|
1086
|
-
out.push(item);
|
|
1097
|
+
for await (const item of paginate(fetchPage, query, pageSize)) out.push(item);
|
|
1087
1098
|
return out;
|
|
1088
1099
|
}
|
|
1100
|
+
function isNotUndefined(arr) {
|
|
1101
|
+
return arr.filter(
|
|
1102
|
+
(item) => item !== void 0
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1089
1105
|
export {
|
|
1106
|
+
isNotUndefined,
|
|
1090
1107
|
listAll,
|
|
1091
1108
|
paginate,
|
|
1092
1109
|
parseNDJSONStream,
|