@atzentis/booking-sdk 0.0.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/dist/index.cjs +536 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +209 -2
- package/dist/index.d.ts +209 -2
- package/dist/index.js +518 -2
- package/dist/index.js.map +1 -1
- package/package.json +8 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @atzentis/booking-sdk\n// Placeholder — implementation starts in P01\nexport const VERSION = \"0.0.0\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,IAAM,UAAU;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/errors.ts","../src/http.ts","../src/client.ts","../src/pagination.ts"],"sourcesContent":["// @atzentis/booking-sdk\nexport const VERSION = \"0.1.0\";\n\nexport { BookingClient } from \"./client.js\";\nexport { bookingClientConfigSchema } from \"./config.js\";\nexport type {\n BookingClientConfig,\n ResolvedBookingClientConfig,\n} from \"./config.js\";\n\nexport { HttpClient } from \"./http.js\";\nexport type {\n HttpClientOptions,\n HttpMethod,\n HttpResponse,\n RequestOptions,\n} from \"./types/http.js\";\n\nexport {\n AuthenticationError,\n BookingError,\n ConflictError,\n createErrorFromResponse,\n ForbiddenError,\n NotFoundError,\n PaymentError,\n RateLimitError,\n ServerError,\n TimeoutError,\n ValidationError,\n} from \"./errors.js\";\nexport type { BookingErrorOptions } from \"./errors.js\";\n\nexport type { Logger, RetryConfig, RetryOptions } from \"./types/config.js\";\n\nexport { firstPage, paginate } from \"./pagination.js\";\nexport type {\n PageFetcher,\n Paginated,\n PaginationOptions,\n} from \"./types/pagination.js\";\n","// Configuration schema for @atzentis/booking-sdk\n\nimport { z } from \"zod\";\n\nexport const bookingClientConfigSchema = z.object({\n apiKey: z.string().min(1, \"apiKey is required\"),\n baseUrl: z.string().url().default(\"https://api.atzentis.io\"),\n tenantId: z.string().min(1).optional(),\n timeout: z.number().int().positive().default(30_000),\n retry: z\n .object({\n maxRetries: z.number().int().min(0).max(10).default(3),\n baseDelay: z.number().int().positive().default(500),\n })\n .optional(),\n debug: z.boolean().default(false),\n logger: z\n .object({\n debug: z.custom<(message: string, ...args: unknown[]) => void>(\n (val) => typeof val === \"function\",\n ),\n })\n .optional(),\n});\n\n/** Input type for BookingClient constructor (optional fields truly optional) */\nexport type BookingClientConfig = z.input<typeof bookingClientConfigSchema>;\n\n/** Resolved config type after Zod defaults are applied */\nexport type ResolvedBookingClientConfig = z.output<typeof bookingClientConfigSchema>;\n","// Error class hierarchy for @atzentis/booking-sdk\n\n/** Options for constructing a BookingError */\nexport interface BookingErrorOptions {\n code: string;\n status?: number;\n details?: Record<string, unknown>;\n}\n\n/** Base error class for all SDK errors */\nexport class BookingError extends Error {\n readonly code: string;\n readonly status: number | undefined;\n readonly details: Record<string, unknown>;\n\n constructor(message: string, options: BookingErrorOptions) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"BookingError\";\n this.code = options.code;\n this.status = options.status;\n this.details = options.details ?? {};\n }\n}\n\n/** HTTP 401 — invalid or missing API key */\nexport class AuthenticationError extends BookingError {\n constructor(\n message = \"Authentication failed: invalid or missing API key\",\n details?: Record<string, unknown>,\n ) {\n super(message, { code: \"AUTHENTICATION_ERROR\", status: 401, details });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"AuthenticationError\";\n }\n}\n\n/** HTTP 402 — payment required or payment failed */\nexport class PaymentError extends BookingError {\n constructor(message = \"Payment required or payment failed\", details?: Record<string, unknown>) {\n super(message, { code: \"PAYMENT_ERROR\", status: 402, details });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"PaymentError\";\n }\n}\n\n/** HTTP 403 — insufficient permissions */\nexport class ForbiddenError extends BookingError {\n constructor(\n message = \"Insufficient permissions to perform this action\",\n details?: Record<string, unknown>,\n ) {\n super(message, { code: \"FORBIDDEN_ERROR\", status: 403, details });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"ForbiddenError\";\n }\n}\n\n/** HTTP 404 — resource not found */\nexport class NotFoundError extends BookingError {\n constructor(message = \"The requested resource was not found\", details?: Record<string, unknown>) {\n super(message, { code: \"NOT_FOUND_ERROR\", status: 404, details });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"NotFoundError\";\n }\n}\n\n/** HTTP 409 — resource conflict */\nexport class ConflictError extends BookingError {\n constructor(\n message = \"Resource conflict — the booking may already exist\",\n details?: Record<string, unknown>,\n ) {\n super(message, { code: \"CONFLICT_ERROR\", status: 409, details });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"ConflictError\";\n }\n}\n\n/** HTTP 422 — request validation failed with field-level errors */\nexport class ValidationError extends BookingError {\n readonly fieldErrors: Record<string, string[]>;\n\n constructor(\n message = \"Request validation failed\",\n fieldErrors: Record<string, string[]> = {},\n details?: Record<string, unknown>,\n ) {\n super(message, { code: \"VALIDATION_ERROR\", status: 422, details });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"ValidationError\";\n this.fieldErrors = fieldErrors;\n }\n}\n\n/** HTTP 429 — rate limit exceeded */\nexport class RateLimitError extends BookingError {\n readonly retryAfter: number;\n\n constructor(message = \"Rate limit exceeded\", retryAfter = 60) {\n super(message, { code: \"RATE_LIMIT_ERROR\", status: 429 });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"RateLimitError\";\n this.retryAfter = retryAfter;\n }\n}\n\n/** HTTP 5xx — unexpected server error */\nexport class ServerError extends BookingError {\n constructor(\n message = \"An unexpected server error occurred\",\n status = 500,\n details?: Record<string, unknown>,\n ) {\n super(message, { code: \"SERVER_ERROR\", status, details });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"ServerError\";\n }\n}\n\n/** Timeout error — request was aborted by AbortController */\nexport class TimeoutError extends BookingError {\n constructor(message = \"The request timed out\") {\n super(message, { code: \"TIMEOUT_ERROR\" });\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = \"TimeoutError\";\n }\n}\n\n// --- Factory helpers ---\n\nfunction parseRetryAfter(header: string | null | undefined): number {\n if (!header) return 60;\n\n const seconds = Number.parseInt(header, 10);\n if (Number.isFinite(seconds) && seconds > 0) return seconds;\n\n const date = new Date(header);\n if (!Number.isNaN(date.getTime())) {\n return Math.max(0, Math.round((date.getTime() - Date.now()) / 1000));\n }\n\n return 60;\n}\n\nfunction extractBody(body: unknown): Record<string, unknown> {\n if (typeof body === \"object\" && body !== null && !Array.isArray(body)) {\n return body as Record<string, unknown>;\n }\n return {};\n}\n\nfunction extractMessage(body: Record<string, unknown>, fallback: string): string {\n if (typeof body.message === \"string\" && body.message.length > 0) {\n return body.message;\n }\n return fallback;\n}\n\nfunction parseFieldErrors(errors: unknown): Record<string, string[]> {\n if (typeof errors !== \"object\" || errors === null || Array.isArray(errors)) {\n return {};\n }\n\n const result: Record<string, string[]> = {};\n for (const [key, value] of Object.entries(errors as Record<string, unknown>)) {\n if (Array.isArray(value)) {\n result[key] = value.map(String);\n } else if (typeof value === \"string\") {\n result[key] = [value];\n }\n }\n return result;\n}\n\n/** Creates a typed BookingError from an HTTP response and parsed body */\nexport function createErrorFromResponse(\n response: Response,\n body: unknown,\n retryAfterHeader?: string | null,\n): BookingError {\n const bodyObj = extractBody(body);\n const status = response.status;\n\n switch (status) {\n case 401:\n return new AuthenticationError(\n extractMessage(bodyObj, \"Authentication failed: invalid or missing API key\"),\n bodyObj,\n );\n case 402:\n return new PaymentError(\n extractMessage(bodyObj, \"Payment required or payment failed\"),\n bodyObj,\n );\n case 403:\n return new ForbiddenError(\n extractMessage(bodyObj, \"Insufficient permissions to perform this action\"),\n bodyObj,\n );\n case 404:\n return new NotFoundError(\n extractMessage(bodyObj, \"The requested resource was not found\"),\n bodyObj,\n );\n case 409:\n return new ConflictError(extractMessage(bodyObj, \"Resource conflict\"), bodyObj);\n case 422:\n return new ValidationError(\n extractMessage(bodyObj, \"Request validation failed\"),\n parseFieldErrors(bodyObj.errors),\n bodyObj,\n );\n case 429:\n return new RateLimitError(\n extractMessage(bodyObj, \"Rate limit exceeded\"),\n parseRetryAfter(retryAfterHeader ?? null),\n );\n default:\n if (status >= 500) {\n return new ServerError(\n extractMessage(bodyObj, \"An unexpected server error occurred\"),\n status,\n bodyObj,\n );\n }\n return new BookingError(extractMessage(bodyObj, `HTTP ${status} error`), {\n code: \"HTTP_ERROR\",\n status,\n details: bodyObj,\n });\n }\n}\n","// Core HTTP client — wraps native fetch with typed methods\n\nimport { TimeoutError, createErrorFromResponse } from \"./errors.js\";\nimport type { Logger, RetryConfig } from \"./types/config.js\";\nimport type { HttpClientOptions, HttpMethod, RequestOptions } from \"./types/http.js\";\n\nconst RETRYABLE_STATUSES = new Set([500, 502, 503, 504]);\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 500,\n retryOnMethods: [\"GET\", \"DELETE\"],\n};\n\n/** Parse Retry-After header as integer seconds. Returns 1 on invalid/missing. */\nfunction parseRetryAfterHeader(header: string | null): number {\n if (!header) return 1;\n const seconds = Number.parseInt(header, 10);\n if (Number.isNaN(seconds) || seconds < 0) return 1;\n return seconds;\n}\n\nfunction createDefaultLogger(): Logger {\n return {\n debug(message: string, ...args: unknown[]) {\n console.debug(message, ...args);\n },\n };\n}\n\nfunction redactHeaders(headers: Record<string, string>): Record<string, string> {\n const result = { ...headers };\n if (result.Authorization) {\n result.Authorization = \"Bearer ***\";\n }\n return result;\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly fetchFn: typeof globalThis.fetch;\n private defaultHeaders: Record<string, string>;\n #apiKey: string;\n #tenantId: string | undefined;\n #retryConfig: RetryConfig;\n #timeout: number;\n #debug: boolean;\n #logger: Logger;\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl;\n this.fetchFn = options.fetch ?? globalThis.fetch;\n this.defaultHeaders = { ...options.defaultHeaders };\n this.#apiKey = options.apiKey;\n this.#tenantId = options.tenantId;\n this.#retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...options.retryConfig,\n };\n this.#timeout = options.timeout ?? 30_000;\n this.#debug = options.debug ?? false;\n this.#logger = options.logger ?? createDefaultLogger();\n }\n\n async request<T>(method: HttpMethod, path: string, options?: RequestOptions): Promise<T> {\n if (!this.#apiKey) {\n throw new Error(\"BookingSDK: apiKey is required but was not provided\");\n }\n\n const url = this.buildUrl(path, options?.query);\n const headers = this.buildHeaders(options?.headers);\n\n if (options?.body !== undefined) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n // Auth headers applied last — always override per-request headers\n headers.Authorization = `Bearer ${this.#apiKey}`;\n if (this.#tenantId) {\n headers[\"X-Tenant-ID\"] = this.#tenantId;\n }\n\n const init: RequestInit = {\n method,\n headers,\n };\n\n if (options?.body !== undefined) {\n init.body = JSON.stringify(options.body);\n }\n\n // Merge global retry config with per-request overrides\n const effectiveRetry = {\n maxRetries: options?.retry?.maxRetries ?? this.#retryConfig.maxRetries,\n baseDelay: options?.retry?.baseDelay ?? this.#retryConfig.baseDelay,\n retryOnMethods: this.#retryConfig.retryOnMethods,\n force: options?.retry?.force ?? false,\n maxRetryAfter: this.#retryConfig.maxRetryAfter ?? 60,\n };\n\n if (this.#debug) {\n this.#logger.debug(`[BookingSDK] --> ${method} ${url}`, {\n headers: redactHeaders(headers),\n ...(options?.body ? { body: JSON.stringify(options.body).slice(0, 200) } : {}),\n });\n }\n\n const timeoutMs = options?.timeout ?? this.#timeout;\n const startTime = Date.now();\n let lastError: unknown;\n let wasRateLimited = false;\n\n for (let attempt = 0; attempt <= effectiveRetry.maxRetries; attempt++) {\n // Exponential backoff before retry (skip after 429 — already slept for Retry-After)\n if (attempt > 0 && !wasRateLimited) {\n await this.sleep(this.calculateDelay(attempt - 1, effectiveRetry.baseDelay));\n }\n wasRateLimited = false;\n\n // Fresh AbortController per attempt for timeout\n let timedOut = false;\n const controller = new AbortController();\n const timer: ReturnType<typeof setTimeout> = setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, timeoutMs);\n\n // Propagate user-initiated abort to timeout controller\n if (options?.signal) {\n if (options.signal.aborted) {\n clearTimeout(timer);\n controller.abort();\n } else {\n options.signal.addEventListener(\"abort\", () => controller.abort(), { once: true });\n }\n }\n\n try {\n const response = await this.fetchFn(url, {\n ...init,\n signal: controller.signal,\n });\n\n if (this.#debug) {\n const elapsed = Date.now() - startTime;\n this.#logger.debug(`[BookingSDK] <-- ${response.status} (${elapsed}ms)`);\n }\n\n if (!response.ok) {\n // 429 Rate Limit — wait Retry-After and retry\n if (response.status === 429 && this.shouldRetry(method, effectiveRetry, attempt)) {\n const retryAfterHeader = response.headers.get(\"Retry-After\");\n const retryAfterSeconds = parseRetryAfterHeader(retryAfterHeader);\n const cappedSeconds = Math.min(retryAfterSeconds, effectiveRetry.maxRetryAfter);\n if (this.#debug) {\n this.#logger.debug(\n `[BookingSDK] retry attempt ${attempt + 1}/${effectiveRetry.maxRetries} in ${cappedSeconds * 1000}ms (reason: 429 Rate Limited)`,\n );\n }\n await this.sleep(cappedSeconds * 1000);\n wasRateLimited = true;\n lastError = response;\n continue;\n }\n\n // 5xx Server Error — retry with exponential backoff\n if (\n RETRYABLE_STATUSES.has(response.status) &&\n this.shouldRetry(method, effectiveRetry, attempt)\n ) {\n if (this.#debug) {\n const delay = this.calculateDelay(attempt, effectiveRetry.baseDelay);\n this.#logger.debug(\n `[BookingSDK] retry attempt ${attempt + 1}/${effectiveRetry.maxRetries} in ${delay}ms (reason: ${response.status})`,\n );\n }\n lastError = response;\n continue;\n }\n\n // Non-retryable error — throw immediately\n const body = await response.json().catch(() => ({}));\n const retryAfterHeader = response.headers.get(\"Retry-After\");\n throw createErrorFromResponse(response, body, retryAfterHeader);\n }\n\n if (this.#debug) {\n const text = await response\n .clone()\n .text()\n .catch(() => \"\");\n if (text) {\n this.#logger.debug(`[BookingSDK] body preview: ${text.slice(0, 500)}`);\n }\n }\n\n return response.json() as Promise<T>;\n } catch (error) {\n // Abort: timeout or user-initiated\n if (error instanceof Error && error.name === \"AbortError\") {\n if (timedOut) {\n throw new TimeoutError(`Request timed out after ${timeoutMs}ms`);\n }\n throw error;\n }\n\n // Already a typed BookingError — don't retry\n if (!(error instanceof TypeError)) {\n throw error;\n }\n\n // Network error (TypeError from fetch) — retry if eligible\n if (!this.shouldRetry(method, effectiveRetry, attempt)) {\n throw error;\n }\n\n lastError = error;\n } finally {\n clearTimeout(timer);\n }\n }\n\n // Exhausted all retries\n if (lastError instanceof Response) {\n const body = await (lastError as Response).json().catch(() => ({}));\n const retryAfterHeader = (lastError as Response).headers.get(\"Retry-After\");\n throw createErrorFromResponse(lastError as Response, body, retryAfterHeader);\n }\n\n throw lastError;\n }\n\n async get<T>(path: string, options?: Omit<RequestOptions, \"body\">): Promise<T> {\n return this.request<T>(\"GET\", path, options);\n }\n\n async post<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>(\"POST\", path, options);\n }\n\n async put<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>(\"PUT\", path, options);\n }\n\n async patch<T>(path: string, options?: RequestOptions): Promise<T> {\n return this.request<T>(\"PATCH\", path, options);\n }\n\n async delete<T>(path: string, options?: Omit<RequestOptions, \"body\">): Promise<T> {\n return this.request<T>(\"DELETE\", path, options);\n }\n\n setApiKey(key: string): void {\n this.#apiKey = key;\n }\n\n setTenantId(id: string | undefined): void {\n this.#tenantId = id;\n }\n\n setDefaultHeader(key: string, value: string): void {\n this.defaultHeaders[key] = value;\n }\n\n removeDefaultHeader(key: string): void {\n delete this.defaultHeaders[key];\n }\n\n private shouldRetry(\n method: HttpMethod,\n config: { retryOnMethods: HttpMethod[]; force: boolean; maxRetries: number },\n attempt: number,\n ): boolean {\n if (attempt >= config.maxRetries) return false;\n if (config.force) return true;\n return config.retryOnMethods.includes(method);\n }\n\n private calculateDelay(attempt: number, baseDelay: number): number {\n return baseDelay * 2 ** attempt + Math.floor(Math.random() * 100);\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n private buildUrl(path: string, query?: RequestOptions[\"query\"]): string {\n const cleanPath = path.startsWith(\"/\") ? path.slice(1) : path;\n let url = `${this.baseUrl}/${cleanPath}`;\n\n if (query) {\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n params.append(key, item);\n }\n } else {\n params.set(key, String(value));\n }\n }\n\n const qs = params.toString();\n if (qs) {\n url = `${url}?${qs}`;\n }\n }\n\n return url;\n }\n\n private buildHeaders(perRequestHeaders?: Record<string, string>): Record<string, string> {\n return {\n Accept: \"application/json\",\n ...this.defaultHeaders,\n ...perRequestHeaders,\n };\n }\n}\n","// BookingClient — primary public entry point for @atzentis/booking-sdk\n\nimport { type BookingClientConfig, bookingClientConfigSchema } from \"./config.js\";\nimport { HttpClient } from \"./http.js\";\n\n/**\n * Main SDK client for the Atzentis Booking API.\n *\n * @example\n * ```typescript\n * import { BookingClient } from \"@atzentis/booking-sdk\";\n * const booking = new BookingClient({ apiKey: \"atz_io_live_xxxxx\" });\n * ```\n */\nexport class BookingClient {\n readonly httpClient: HttpClient;\n\n constructor(config: BookingClientConfig) {\n const validated = bookingClientConfigSchema.parse(config);\n\n this.httpClient = new HttpClient({\n baseUrl: validated.baseUrl,\n apiKey: validated.apiKey,\n tenantId: validated.tenantId,\n timeout: validated.timeout,\n retryConfig: validated.retry\n ? {\n maxRetries: validated.retry.maxRetries,\n baseDelay: validated.retry.baseDelay,\n }\n : undefined,\n debug: validated.debug,\n logger: validated.logger,\n });\n }\n\n setApiKey(key: string): void {\n if (!key || key.trim().length === 0) {\n throw new Error(\"apiKey must be a non-empty string\");\n }\n this.httpClient.setApiKey(key);\n }\n\n setTenantId(id: string): void {\n if (!id || id.trim().length === 0) {\n throw new Error(\"tenantId must be a non-empty string\");\n }\n this.httpClient.setTenantId(id);\n }\n}\n","// Cursor-based pagination helpers for @atzentis/booking-sdk\n\nimport type { PageFetcher, Paginated, PaginationOptions } from \"./types/pagination.js\";\n\n/**\n * Returns an AsyncIterable that yields each page's data array in order.\n * Iteration stops automatically when hasMore is false or cursor is null.\n *\n * @example\n * for await (const page of paginate(fetcher, { limit: 50 })) {\n * for (const item of page) {\n * process(item);\n * }\n * }\n */\nexport function paginate<T>(\n fetcher: PageFetcher<T>,\n options?: PaginationOptions,\n): AsyncIterable<T[]> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T[]> {\n let cursor: string | undefined = options?.cursor;\n let done = false;\n\n return {\n async next(): Promise<IteratorResult<T[]>> {\n if (done) return { value: undefined as unknown as T[], done: true };\n\n const result = await fetcher({ ...(options ?? {}), cursor });\n\n if (!result.hasMore || result.cursor === null) {\n done = true;\n } else {\n cursor = result.cursor;\n }\n\n return { value: result.data, done: false };\n },\n };\n },\n };\n}\n\n/**\n * Fetches only the first page and returns the full Paginated<T> result.\n * Useful when callers only need one page and don't want to use for-await.\n *\n * @example\n * const result = await firstPage(fetcher, { limit: 10 });\n * console.log(result.data, result.hasMore);\n */\nexport async function firstPage<T>(\n fetcher: PageFetcher<T>,\n options?: PaginationOptions,\n): Promise<Paginated<T>> {\n return fetcher({ ...(options ?? {}) });\n}\n"],"mappings":"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","names":["retryAfterHeader"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,210 @@
|
|
|
1
|
-
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
declare const bookingClientConfigSchema: z.ZodObject<{
|
|
4
|
+
apiKey: z.ZodString;
|
|
5
|
+
baseUrl: z.ZodDefault<z.ZodString>;
|
|
6
|
+
tenantId: z.ZodOptional<z.ZodString>;
|
|
7
|
+
timeout: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
retry: z.ZodOptional<z.ZodObject<{
|
|
9
|
+
maxRetries: z.ZodDefault<z.ZodNumber>;
|
|
10
|
+
baseDelay: z.ZodDefault<z.ZodNumber>;
|
|
11
|
+
}, z.core.$strip>>;
|
|
12
|
+
debug: z.ZodDefault<z.ZodBoolean>;
|
|
13
|
+
logger: z.ZodOptional<z.ZodObject<{
|
|
14
|
+
debug: z.ZodCustom<(message: string, ...args: unknown[]) => void, (message: string, ...args: unknown[]) => void>;
|
|
15
|
+
}, z.core.$strip>>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
/** Input type for BookingClient constructor (optional fields truly optional) */
|
|
18
|
+
type BookingClientConfig = z.input<typeof bookingClientConfigSchema>;
|
|
19
|
+
/** Resolved config type after Zod defaults are applied */
|
|
20
|
+
type ResolvedBookingClientConfig = z.output<typeof bookingClientConfigSchema>;
|
|
21
|
+
|
|
22
|
+
interface RetryConfig {
|
|
23
|
+
/** Maximum number of retry attempts. Default: 3 */
|
|
24
|
+
maxRetries: number;
|
|
25
|
+
/** Base delay in milliseconds for exponential backoff. Default: 500 */
|
|
26
|
+
baseDelay: number;
|
|
27
|
+
/** HTTP methods eligible for retry. Default: ["GET", "DELETE", "HEAD"] */
|
|
28
|
+
retryOnMethods: HttpMethod[];
|
|
29
|
+
/** Cap for Retry-After header value in seconds. Default: 60. */
|
|
30
|
+
maxRetryAfter?: number;
|
|
31
|
+
}
|
|
32
|
+
interface RetryOptions {
|
|
33
|
+
/** Override maxRetries for this specific request */
|
|
34
|
+
maxRetries?: number;
|
|
35
|
+
/** Override baseDelay for this specific request */
|
|
36
|
+
baseDelay?: number;
|
|
37
|
+
/** Force retry even for non-idempotent methods (POST/PUT/PATCH) */
|
|
38
|
+
force?: boolean;
|
|
39
|
+
}
|
|
40
|
+
interface Logger {
|
|
41
|
+
debug(message: string, ...args: unknown[]): void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
45
|
+
interface RequestOptions<TBody = unknown> {
|
|
46
|
+
body?: TBody;
|
|
47
|
+
query?: Record<string, string | string[] | number | boolean | null | undefined>;
|
|
48
|
+
headers?: Record<string, string>;
|
|
49
|
+
signal?: AbortSignal;
|
|
50
|
+
retry?: RetryOptions;
|
|
51
|
+
/** Per-request timeout in milliseconds. Overrides global config.timeout. */
|
|
52
|
+
timeout?: number;
|
|
53
|
+
}
|
|
54
|
+
interface HttpResponse<T> {
|
|
55
|
+
data: T;
|
|
56
|
+
status: number;
|
|
57
|
+
headers: Headers;
|
|
58
|
+
}
|
|
59
|
+
interface HttpClientOptions {
|
|
60
|
+
baseUrl: string;
|
|
61
|
+
apiKey: string;
|
|
62
|
+
tenantId?: string;
|
|
63
|
+
fetch?: typeof globalThis.fetch;
|
|
64
|
+
defaultHeaders?: Record<string, string>;
|
|
65
|
+
retryConfig?: Partial<RetryConfig>;
|
|
66
|
+
/** Global timeout for all requests in milliseconds. Default: 30000. */
|
|
67
|
+
timeout?: number;
|
|
68
|
+
/** Enable debug logging. Default: false. */
|
|
69
|
+
debug?: boolean;
|
|
70
|
+
/** Custom logger instance. Uses console.debug when debug is true and no logger is provided. */
|
|
71
|
+
logger?: Logger;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
declare class HttpClient {
|
|
75
|
+
#private;
|
|
76
|
+
private readonly baseUrl;
|
|
77
|
+
private readonly fetchFn;
|
|
78
|
+
private defaultHeaders;
|
|
79
|
+
constructor(options: HttpClientOptions);
|
|
80
|
+
request<T>(method: HttpMethod, path: string, options?: RequestOptions): Promise<T>;
|
|
81
|
+
get<T>(path: string, options?: Omit<RequestOptions, "body">): Promise<T>;
|
|
82
|
+
post<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
83
|
+
put<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
84
|
+
patch<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
85
|
+
delete<T>(path: string, options?: Omit<RequestOptions, "body">): Promise<T>;
|
|
86
|
+
setApiKey(key: string): void;
|
|
87
|
+
setTenantId(id: string | undefined): void;
|
|
88
|
+
setDefaultHeader(key: string, value: string): void;
|
|
89
|
+
removeDefaultHeader(key: string): void;
|
|
90
|
+
private shouldRetry;
|
|
91
|
+
private calculateDelay;
|
|
92
|
+
private sleep;
|
|
93
|
+
private buildUrl;
|
|
94
|
+
private buildHeaders;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Main SDK client for the Atzentis Booking API.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* import { BookingClient } from "@atzentis/booking-sdk";
|
|
103
|
+
* const booking = new BookingClient({ apiKey: "atz_io_live_xxxxx" });
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
declare class BookingClient {
|
|
107
|
+
readonly httpClient: HttpClient;
|
|
108
|
+
constructor(config: BookingClientConfig);
|
|
109
|
+
setApiKey(key: string): void;
|
|
110
|
+
setTenantId(id: string): void;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Options for constructing a BookingError */
|
|
114
|
+
interface BookingErrorOptions {
|
|
115
|
+
code: string;
|
|
116
|
+
status?: number;
|
|
117
|
+
details?: Record<string, unknown>;
|
|
118
|
+
}
|
|
119
|
+
/** Base error class for all SDK errors */
|
|
120
|
+
declare class BookingError extends Error {
|
|
121
|
+
readonly code: string;
|
|
122
|
+
readonly status: number | undefined;
|
|
123
|
+
readonly details: Record<string, unknown>;
|
|
124
|
+
constructor(message: string, options: BookingErrorOptions);
|
|
125
|
+
}
|
|
126
|
+
/** HTTP 401 — invalid or missing API key */
|
|
127
|
+
declare class AuthenticationError extends BookingError {
|
|
128
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
129
|
+
}
|
|
130
|
+
/** HTTP 402 — payment required or payment failed */
|
|
131
|
+
declare class PaymentError extends BookingError {
|
|
132
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
133
|
+
}
|
|
134
|
+
/** HTTP 403 — insufficient permissions */
|
|
135
|
+
declare class ForbiddenError extends BookingError {
|
|
136
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
137
|
+
}
|
|
138
|
+
/** HTTP 404 — resource not found */
|
|
139
|
+
declare class NotFoundError extends BookingError {
|
|
140
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
141
|
+
}
|
|
142
|
+
/** HTTP 409 — resource conflict */
|
|
143
|
+
declare class ConflictError extends BookingError {
|
|
144
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
145
|
+
}
|
|
146
|
+
/** HTTP 422 — request validation failed with field-level errors */
|
|
147
|
+
declare class ValidationError extends BookingError {
|
|
148
|
+
readonly fieldErrors: Record<string, string[]>;
|
|
149
|
+
constructor(message?: string, fieldErrors?: Record<string, string[]>, details?: Record<string, unknown>);
|
|
150
|
+
}
|
|
151
|
+
/** HTTP 429 — rate limit exceeded */
|
|
152
|
+
declare class RateLimitError extends BookingError {
|
|
153
|
+
readonly retryAfter: number;
|
|
154
|
+
constructor(message?: string, retryAfter?: number);
|
|
155
|
+
}
|
|
156
|
+
/** HTTP 5xx — unexpected server error */
|
|
157
|
+
declare class ServerError extends BookingError {
|
|
158
|
+
constructor(message?: string, status?: number, details?: Record<string, unknown>);
|
|
159
|
+
}
|
|
160
|
+
/** Timeout error — request was aborted by AbortController */
|
|
161
|
+
declare class TimeoutError extends BookingError {
|
|
162
|
+
constructor(message?: string);
|
|
163
|
+
}
|
|
164
|
+
/** Creates a typed BookingError from an HTTP response and parsed body */
|
|
165
|
+
declare function createErrorFromResponse(response: Response, body: unknown, retryAfterHeader?: string | null): BookingError;
|
|
166
|
+
|
|
167
|
+
/** The standard paginated response shape returned by all v4.0 list endpoints */
|
|
168
|
+
interface Paginated<T> {
|
|
169
|
+
/** The items for this page */
|
|
170
|
+
data: T[];
|
|
171
|
+
/** Opaque cursor for the next page; null when on the last page */
|
|
172
|
+
cursor: string | null;
|
|
173
|
+
/** True if more pages exist beyond this one */
|
|
174
|
+
hasMore: boolean;
|
|
175
|
+
}
|
|
176
|
+
/** Options for configuring pagination behavior */
|
|
177
|
+
interface PaginationOptions {
|
|
178
|
+
/** Number of items per page (defaults to API default if omitted) */
|
|
179
|
+
limit?: number;
|
|
180
|
+
/** Initial cursor — omit to start from the first page */
|
|
181
|
+
cursor?: string;
|
|
182
|
+
}
|
|
183
|
+
/** Callback type: a function that fetches one page given current cursor options */
|
|
184
|
+
type PageFetcher<T> = (options: PaginationOptions) => Promise<Paginated<T>>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Returns an AsyncIterable that yields each page's data array in order.
|
|
188
|
+
* Iteration stops automatically when hasMore is false or cursor is null.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* for await (const page of paginate(fetcher, { limit: 50 })) {
|
|
192
|
+
* for (const item of page) {
|
|
193
|
+
* process(item);
|
|
194
|
+
* }
|
|
195
|
+
* }
|
|
196
|
+
*/
|
|
197
|
+
declare function paginate<T>(fetcher: PageFetcher<T>, options?: PaginationOptions): AsyncIterable<T[]>;
|
|
198
|
+
/**
|
|
199
|
+
* Fetches only the first page and returns the full Paginated<T> result.
|
|
200
|
+
* Useful when callers only need one page and don't want to use for-await.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* const result = await firstPage(fetcher, { limit: 10 });
|
|
204
|
+
* console.log(result.data, result.hasMore);
|
|
205
|
+
*/
|
|
206
|
+
declare function firstPage<T>(fetcher: PageFetcher<T>, options?: PaginationOptions): Promise<Paginated<T>>;
|
|
207
|
+
|
|
208
|
+
declare const VERSION = "0.1.0";
|
|
209
|
+
|
|
210
|
+
export { AuthenticationError, BookingClient, type BookingClientConfig, BookingError, type BookingErrorOptions, ConflictError, ForbiddenError, HttpClient, type HttpClientOptions, type HttpMethod, type HttpResponse, type Logger, NotFoundError, type PageFetcher, type Paginated, type PaginationOptions, PaymentError, RateLimitError, type RequestOptions, type ResolvedBookingClientConfig, type RetryConfig, type RetryOptions, ServerError, TimeoutError, VERSION, ValidationError, bookingClientConfigSchema, createErrorFromResponse, firstPage, paginate };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,210 @@
|
|
|
1
|
-
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
declare const bookingClientConfigSchema: z.ZodObject<{
|
|
4
|
+
apiKey: z.ZodString;
|
|
5
|
+
baseUrl: z.ZodDefault<z.ZodString>;
|
|
6
|
+
tenantId: z.ZodOptional<z.ZodString>;
|
|
7
|
+
timeout: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
retry: z.ZodOptional<z.ZodObject<{
|
|
9
|
+
maxRetries: z.ZodDefault<z.ZodNumber>;
|
|
10
|
+
baseDelay: z.ZodDefault<z.ZodNumber>;
|
|
11
|
+
}, z.core.$strip>>;
|
|
12
|
+
debug: z.ZodDefault<z.ZodBoolean>;
|
|
13
|
+
logger: z.ZodOptional<z.ZodObject<{
|
|
14
|
+
debug: z.ZodCustom<(message: string, ...args: unknown[]) => void, (message: string, ...args: unknown[]) => void>;
|
|
15
|
+
}, z.core.$strip>>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
/** Input type for BookingClient constructor (optional fields truly optional) */
|
|
18
|
+
type BookingClientConfig = z.input<typeof bookingClientConfigSchema>;
|
|
19
|
+
/** Resolved config type after Zod defaults are applied */
|
|
20
|
+
type ResolvedBookingClientConfig = z.output<typeof bookingClientConfigSchema>;
|
|
21
|
+
|
|
22
|
+
interface RetryConfig {
|
|
23
|
+
/** Maximum number of retry attempts. Default: 3 */
|
|
24
|
+
maxRetries: number;
|
|
25
|
+
/** Base delay in milliseconds for exponential backoff. Default: 500 */
|
|
26
|
+
baseDelay: number;
|
|
27
|
+
/** HTTP methods eligible for retry. Default: ["GET", "DELETE", "HEAD"] */
|
|
28
|
+
retryOnMethods: HttpMethod[];
|
|
29
|
+
/** Cap for Retry-After header value in seconds. Default: 60. */
|
|
30
|
+
maxRetryAfter?: number;
|
|
31
|
+
}
|
|
32
|
+
interface RetryOptions {
|
|
33
|
+
/** Override maxRetries for this specific request */
|
|
34
|
+
maxRetries?: number;
|
|
35
|
+
/** Override baseDelay for this specific request */
|
|
36
|
+
baseDelay?: number;
|
|
37
|
+
/** Force retry even for non-idempotent methods (POST/PUT/PATCH) */
|
|
38
|
+
force?: boolean;
|
|
39
|
+
}
|
|
40
|
+
interface Logger {
|
|
41
|
+
debug(message: string, ...args: unknown[]): void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
45
|
+
interface RequestOptions<TBody = unknown> {
|
|
46
|
+
body?: TBody;
|
|
47
|
+
query?: Record<string, string | string[] | number | boolean | null | undefined>;
|
|
48
|
+
headers?: Record<string, string>;
|
|
49
|
+
signal?: AbortSignal;
|
|
50
|
+
retry?: RetryOptions;
|
|
51
|
+
/** Per-request timeout in milliseconds. Overrides global config.timeout. */
|
|
52
|
+
timeout?: number;
|
|
53
|
+
}
|
|
54
|
+
interface HttpResponse<T> {
|
|
55
|
+
data: T;
|
|
56
|
+
status: number;
|
|
57
|
+
headers: Headers;
|
|
58
|
+
}
|
|
59
|
+
interface HttpClientOptions {
|
|
60
|
+
baseUrl: string;
|
|
61
|
+
apiKey: string;
|
|
62
|
+
tenantId?: string;
|
|
63
|
+
fetch?: typeof globalThis.fetch;
|
|
64
|
+
defaultHeaders?: Record<string, string>;
|
|
65
|
+
retryConfig?: Partial<RetryConfig>;
|
|
66
|
+
/** Global timeout for all requests in milliseconds. Default: 30000. */
|
|
67
|
+
timeout?: number;
|
|
68
|
+
/** Enable debug logging. Default: false. */
|
|
69
|
+
debug?: boolean;
|
|
70
|
+
/** Custom logger instance. Uses console.debug when debug is true and no logger is provided. */
|
|
71
|
+
logger?: Logger;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
declare class HttpClient {
|
|
75
|
+
#private;
|
|
76
|
+
private readonly baseUrl;
|
|
77
|
+
private readonly fetchFn;
|
|
78
|
+
private defaultHeaders;
|
|
79
|
+
constructor(options: HttpClientOptions);
|
|
80
|
+
request<T>(method: HttpMethod, path: string, options?: RequestOptions): Promise<T>;
|
|
81
|
+
get<T>(path: string, options?: Omit<RequestOptions, "body">): Promise<T>;
|
|
82
|
+
post<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
83
|
+
put<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
84
|
+
patch<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
85
|
+
delete<T>(path: string, options?: Omit<RequestOptions, "body">): Promise<T>;
|
|
86
|
+
setApiKey(key: string): void;
|
|
87
|
+
setTenantId(id: string | undefined): void;
|
|
88
|
+
setDefaultHeader(key: string, value: string): void;
|
|
89
|
+
removeDefaultHeader(key: string): void;
|
|
90
|
+
private shouldRetry;
|
|
91
|
+
private calculateDelay;
|
|
92
|
+
private sleep;
|
|
93
|
+
private buildUrl;
|
|
94
|
+
private buildHeaders;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Main SDK client for the Atzentis Booking API.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* import { BookingClient } from "@atzentis/booking-sdk";
|
|
103
|
+
* const booking = new BookingClient({ apiKey: "atz_io_live_xxxxx" });
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
declare class BookingClient {
|
|
107
|
+
readonly httpClient: HttpClient;
|
|
108
|
+
constructor(config: BookingClientConfig);
|
|
109
|
+
setApiKey(key: string): void;
|
|
110
|
+
setTenantId(id: string): void;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Options for constructing a BookingError */
|
|
114
|
+
interface BookingErrorOptions {
|
|
115
|
+
code: string;
|
|
116
|
+
status?: number;
|
|
117
|
+
details?: Record<string, unknown>;
|
|
118
|
+
}
|
|
119
|
+
/** Base error class for all SDK errors */
|
|
120
|
+
declare class BookingError extends Error {
|
|
121
|
+
readonly code: string;
|
|
122
|
+
readonly status: number | undefined;
|
|
123
|
+
readonly details: Record<string, unknown>;
|
|
124
|
+
constructor(message: string, options: BookingErrorOptions);
|
|
125
|
+
}
|
|
126
|
+
/** HTTP 401 — invalid or missing API key */
|
|
127
|
+
declare class AuthenticationError extends BookingError {
|
|
128
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
129
|
+
}
|
|
130
|
+
/** HTTP 402 — payment required or payment failed */
|
|
131
|
+
declare class PaymentError extends BookingError {
|
|
132
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
133
|
+
}
|
|
134
|
+
/** HTTP 403 — insufficient permissions */
|
|
135
|
+
declare class ForbiddenError extends BookingError {
|
|
136
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
137
|
+
}
|
|
138
|
+
/** HTTP 404 — resource not found */
|
|
139
|
+
declare class NotFoundError extends BookingError {
|
|
140
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
141
|
+
}
|
|
142
|
+
/** HTTP 409 — resource conflict */
|
|
143
|
+
declare class ConflictError extends BookingError {
|
|
144
|
+
constructor(message?: string, details?: Record<string, unknown>);
|
|
145
|
+
}
|
|
146
|
+
/** HTTP 422 — request validation failed with field-level errors */
|
|
147
|
+
declare class ValidationError extends BookingError {
|
|
148
|
+
readonly fieldErrors: Record<string, string[]>;
|
|
149
|
+
constructor(message?: string, fieldErrors?: Record<string, string[]>, details?: Record<string, unknown>);
|
|
150
|
+
}
|
|
151
|
+
/** HTTP 429 — rate limit exceeded */
|
|
152
|
+
declare class RateLimitError extends BookingError {
|
|
153
|
+
readonly retryAfter: number;
|
|
154
|
+
constructor(message?: string, retryAfter?: number);
|
|
155
|
+
}
|
|
156
|
+
/** HTTP 5xx — unexpected server error */
|
|
157
|
+
declare class ServerError extends BookingError {
|
|
158
|
+
constructor(message?: string, status?: number, details?: Record<string, unknown>);
|
|
159
|
+
}
|
|
160
|
+
/** Timeout error — request was aborted by AbortController */
|
|
161
|
+
declare class TimeoutError extends BookingError {
|
|
162
|
+
constructor(message?: string);
|
|
163
|
+
}
|
|
164
|
+
/** Creates a typed BookingError from an HTTP response and parsed body */
|
|
165
|
+
declare function createErrorFromResponse(response: Response, body: unknown, retryAfterHeader?: string | null): BookingError;
|
|
166
|
+
|
|
167
|
+
/** The standard paginated response shape returned by all v4.0 list endpoints */
|
|
168
|
+
interface Paginated<T> {
|
|
169
|
+
/** The items for this page */
|
|
170
|
+
data: T[];
|
|
171
|
+
/** Opaque cursor for the next page; null when on the last page */
|
|
172
|
+
cursor: string | null;
|
|
173
|
+
/** True if more pages exist beyond this one */
|
|
174
|
+
hasMore: boolean;
|
|
175
|
+
}
|
|
176
|
+
/** Options for configuring pagination behavior */
|
|
177
|
+
interface PaginationOptions {
|
|
178
|
+
/** Number of items per page (defaults to API default if omitted) */
|
|
179
|
+
limit?: number;
|
|
180
|
+
/** Initial cursor — omit to start from the first page */
|
|
181
|
+
cursor?: string;
|
|
182
|
+
}
|
|
183
|
+
/** Callback type: a function that fetches one page given current cursor options */
|
|
184
|
+
type PageFetcher<T> = (options: PaginationOptions) => Promise<Paginated<T>>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Returns an AsyncIterable that yields each page's data array in order.
|
|
188
|
+
* Iteration stops automatically when hasMore is false or cursor is null.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* for await (const page of paginate(fetcher, { limit: 50 })) {
|
|
192
|
+
* for (const item of page) {
|
|
193
|
+
* process(item);
|
|
194
|
+
* }
|
|
195
|
+
* }
|
|
196
|
+
*/
|
|
197
|
+
declare function paginate<T>(fetcher: PageFetcher<T>, options?: PaginationOptions): AsyncIterable<T[]>;
|
|
198
|
+
/**
|
|
199
|
+
* Fetches only the first page and returns the full Paginated<T> result.
|
|
200
|
+
* Useful when callers only need one page and don't want to use for-await.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* const result = await firstPage(fetcher, { limit: 10 });
|
|
204
|
+
* console.log(result.data, result.hasMore);
|
|
205
|
+
*/
|
|
206
|
+
declare function firstPage<T>(fetcher: PageFetcher<T>, options?: PaginationOptions): Promise<Paginated<T>>;
|
|
207
|
+
|
|
208
|
+
declare const VERSION = "0.1.0";
|
|
209
|
+
|
|
210
|
+
export { AuthenticationError, BookingClient, type BookingClientConfig, BookingError, type BookingErrorOptions, ConflictError, ForbiddenError, HttpClient, type HttpClientOptions, type HttpMethod, type HttpResponse, type Logger, NotFoundError, type PageFetcher, type Paginated, type PaginationOptions, PaymentError, RateLimitError, type RequestOptions, type ResolvedBookingClientConfig, type RetryConfig, type RetryOptions, ServerError, TimeoutError, VERSION, ValidationError, bookingClientConfigSchema, createErrorFromResponse, firstPage, paginate };
|