hospitable 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth/token-manager.ts","../src/errors.ts","../src/http/retry.ts","../src/utils/sanitize.ts","../src/http/client.ts","../src/resources/calendar.ts","../src/resources/messages.ts","../src/resources/properties.ts","../src/resources/reservations.ts","../src/resources/reviews.ts","../src/client.ts","../src/http/paginate.ts","../src/filters/reservation-filter.ts","../src/filters/property-filter.ts","../src/index.ts"],"sourcesContent":["declare const process: { env: Record<string, string | undefined> }\n\nexport interface TokenManagerConfig {\n token?: string\n refreshToken?: string\n clientId?: string\n clientSecret?: string\n baseURL: string\n}\n\ninterface OAuthTokenResponse {\n access_token: string\n refresh_token?: string\n expires_in: number\n token_type: string\n}\n\nexport class TokenManager {\n private accessToken: string | undefined\n private refreshToken: string | undefined\n private expiresAt: number = 0\n private refreshPromise: Promise<void> | null = null\n\n constructor(private readonly config: TokenManagerConfig) {\n if (config.token && !config.refreshToken && !config.clientId) {\n this.accessToken = config.token\n this.expiresAt = Infinity\n } else if (config.token) {\n this.accessToken = config.token\n this.refreshToken = config.refreshToken\n this.expiresAt = Date.now() + 60_000\n } else {\n const envPat = process.env['HOSPITABLE_PAT']\n if (envPat) {\n this.accessToken = envPat\n this.expiresAt = Infinity\n }\n }\n }\n\n async getAuthHeader(): Promise<string> {\n if (this.needsRefresh()) {\n await this.ensureRefreshed()\n }\n /* v8 ignore next 3 */\n if (!this.accessToken) {\n throw new Error('No access token available. Provide token or clientId+clientSecret.')\n }\n return `Bearer ${this.accessToken}`\n }\n\n private needsRefresh(): boolean {\n if (this.expiresAt === Infinity) return false\n return Date.now() >= this.expiresAt - 60_000\n }\n\n private async ensureRefreshed(): Promise<void> {\n if (this.refreshPromise) {\n await this.refreshPromise\n return\n }\n this.refreshPromise = this.doRefresh().finally(() => {\n this.refreshPromise = null\n })\n await this.refreshPromise\n }\n\n private async doRefresh(): Promise<void> {\n const { clientId, clientSecret, baseURL } = this.config\n if (!clientId || !clientSecret) {\n throw new Error('Cannot refresh token: clientId and clientSecret are required')\n }\n\n const body = this.refreshToken\n ? new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: this.refreshToken,\n client_id: clientId,\n client_secret: clientSecret,\n })\n : new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: clientId,\n client_secret: clientSecret,\n })\n\n const response = await fetch(`${baseURL}/oauth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n\n if (!response.ok) {\n const text = await response.text()\n throw new Error(`Token refresh failed (${response.status}): ${text}`)\n }\n\n const data = (await response.json()) as OAuthTokenResponse\n this.accessToken = data.access_token\n if (data.refresh_token) this.refreshToken = data.refresh_token\n this.expiresAt = Date.now() + data.expires_in * 1000\n }\n\n async handleUnauthorized(): Promise<void> {\n this.expiresAt = 0\n await this.ensureRefreshed()\n }\n}\n","export class HospitableError extends Error {\n readonly statusCode: number\n readonly requestId: string | undefined\n\n constructor(message: string, statusCode: number, requestId?: string) {\n super(message)\n this.name = 'HospitableError'\n this.statusCode = statusCode\n this.requestId = requestId\n Object.setPrototypeOf(this, new.target.prototype)\n }\n}\n\nexport class AuthenticationError extends HospitableError {\n constructor(message = 'Authentication failed', requestId?: string) {\n super(message, 401, requestId)\n this.name = 'AuthenticationError'\n }\n}\n\nexport class RateLimitError extends HospitableError {\n readonly retryAfter: number\n\n constructor(retryAfter: number, requestId?: string) {\n super(`Rate limit exceeded. Retry after ${retryAfter}s`, 429, requestId)\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n }\n}\n\nexport class NotFoundError extends HospitableError {\n readonly resource: string | undefined\n\n constructor(message = 'Resource not found', requestId?: string, resource?: string) {\n super(message, 404, requestId)\n this.name = 'NotFoundError'\n this.resource = resource\n }\n}\n\nexport class ValidationError extends HospitableError {\n readonly fields: Record<string, string[]>\n\n constructor(message: string, fields: Record<string, string[]> = {}, requestId?: string) {\n super(message, 422, requestId)\n this.name = 'ValidationError'\n this.fields = fields\n }\n}\n\nexport class ForbiddenError extends HospitableError {\n constructor(message = 'Forbidden', requestId?: string) {\n super(message, 403, requestId)\n this.name = 'ForbiddenError'\n }\n}\n\nexport class ServerError extends HospitableError {\n readonly attempts: number\n\n constructor(message: string, statusCode: number, attempts: number, requestId?: string) {\n super(message, statusCode, requestId)\n this.name = 'ServerError'\n this.attempts = attempts\n }\n}\n\nexport function createErrorFromResponse(\n statusCode: number,\n body: Record<string, unknown>,\n requestId?: string,\n attempts = 1,\n): HospitableError {\n const message = (body['message'] as string | undefined) ?? `HTTP ${statusCode}`\n\n switch (statusCode) {\n case 401:\n return new AuthenticationError(message, requestId)\n case 403:\n return new ForbiddenError(message, requestId)\n case 404:\n return new NotFoundError(message, requestId)\n case 422: {\n const errors = (body['errors'] as Record<string, string[]> | undefined) ?? {}\n return new ValidationError(message, errors, requestId)\n }\n case 429: {\n const retryAfter = (body['retryAfter'] as number | undefined) ?? 60\n return new RateLimitError(retryAfter, requestId)\n }\n default:\n return new ServerError(message, statusCode, attempts, requestId)\n }\n}\n","import { ServerError } from '../errors'\n\nexport interface RetryConfig {\n maxAttempts?: number\n baseDelay?: number\n maxDelay?: number\n onRateLimit?: (info: { retryAfter: number; endpoint: string; attempt: number }) => void\n}\n\nconst RETRYABLE_STATUS_CODES = new Set([429, 500, 502, 503, 504])\n\nfunction jitteredDelay(base: number, attempt: number, max: number): number {\n const exponential = Math.min(base * Math.pow(2, attempt - 1), max)\n const jitter = exponential * 0.25 * (Math.random() * 2 - 1)\n return Math.max(0, exponential + jitter)\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n endpoint: string,\n config: RetryConfig = {},\n): Promise<T> {\n const {\n maxAttempts = 4,\n baseDelay = 1000,\n maxDelay = 60_000,\n onRateLimit,\n } = config\n\n let lastError: unknown\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn()\n } catch (error) {\n lastError = error\n\n const statusCode = getStatusCode(error)\n if (statusCode === null || !RETRYABLE_STATUS_CODES.has(statusCode)) {\n throw error\n }\n\n if (attempt === maxAttempts) {\n break\n }\n\n let delay: number\n if (statusCode === 429 && error instanceof Error) {\n const retryAfter = extractRetryAfter(error)\n delay = retryAfter > 0 ? retryAfter * 1000 : jitteredDelay(baseDelay, attempt, maxDelay)\n onRateLimit?.({ retryAfter, endpoint, attempt })\n } else {\n delay = jitteredDelay(baseDelay, attempt, maxDelay)\n }\n\n await sleep(delay)\n }\n }\n\n const statusCode = getStatusCode(lastError) ?? 500\n const message = lastError instanceof Error ? lastError.message : `Request failed after ${maxAttempts} attempts`\n throw new ServerError(message, statusCode, maxAttempts)\n}\n\nfunction getStatusCode(error: unknown): number | null {\n if (error != null && typeof error === 'object' && 'statusCode' in error) {\n const code = (error as { statusCode: unknown }).statusCode\n if (typeof code === 'number') return code\n }\n return null\n}\n\nfunction extractRetryAfter(error: Error): number {\n if ('retryAfter' in error && typeof (error as { retryAfter: unknown }).retryAfter === 'number') {\n return (error as { retryAfter: number }).retryAfter\n }\n return 60\n}\n","const PII_FIELD_PATTERN = /^(email|phone|firstName|lastName|passportNumber|fullName|dateOfBirth)$/i\nconst SENSITIVE_PATTERN = /token|secret|password|credential|apiKey|api_key/i\n\n/**\n * Recursively masks PII and sensitive fields in an object for safe logging.\n * Does NOT mutate the original — returns a new object with masked values.\n * Only affects log output; never called on actual API payloads.\n */\nexport function sanitize(value: unknown, depth = 0): unknown {\n if (depth > 10) return value // prevent infinite recursion\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map((item) => sanitize(item, depth + 1))\n\n const result: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n if (PII_FIELD_PATTERN.test(key) || SENSITIVE_PATTERN.test(key)) {\n result[key] = '***'\n } else {\n result[key] = sanitize(val, depth + 1)\n }\n }\n return result\n}\n","import { VERSION } from '../index'\nimport { withRetry, type RetryConfig } from './retry'\nimport { sanitize } from '../utils/sanitize'\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n\nexport interface RequestOptions {\n method?: HttpMethod\n params?: Record<string, string | number | boolean | string[] | undefined>\n body?: unknown\n headers?: Record<string, string>\n}\n\nexport interface HttpClientConfig {\n baseURL: string\n getAuthHeader: () => Promise<string>\n onUnauthorized?: () => Promise<void>\n debug?: boolean\n retryConfig?: RetryConfig\n}\n\n// NOTE: We inline error creation here to avoid circular dep — the real errors\n// module will be implemented in a sibling PR. This file uses a simple inline\n// error class that matches the final interface so it can be swapped in later.\nexport class HttpError extends Error {\n constructor(\n readonly statusCode: number,\n message: string,\n readonly requestId: string | undefined,\n readonly body: Record<string, unknown>,\n readonly attempts: number = 1,\n ) {\n super(message)\n this.name = 'HttpError'\n }\n}\n\nfunction buildURL(base: string, path: string, params?: RequestOptions['params']): string {\n const url = new URL(path, base)\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined) continue\n if (Array.isArray(value)) {\n value.forEach((v) => url.searchParams.append(key, v))\n } else {\n url.searchParams.set(key, String(value))\n }\n }\n }\n return url.toString()\n}\n\nexport class HttpClient {\n constructor(private readonly config: HttpClientConfig) {}\n\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const { method = 'GET', params, body, headers: extraHeaders = {} } = options\n const url = buildURL(this.config.baseURL, path, params)\n\n return withRetry(\n async () => {\n const authHeader = await this.config.getAuthHeader()\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n Authorization: authHeader,\n 'User-Agent': `hospitable-ts/${VERSION}`,\n ...extraHeaders,\n }\n\n if (this.config.debug) {\n console.debug(`[hospitable] ${method} ${url}`)\n if (body !== undefined) {\n console.debug('[hospitable] body:', sanitize(body))\n }\n }\n\n const response = await fetch(url, {\n method,\n headers,\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n })\n\n const requestId = response.headers.get('x-request-id') ?? undefined\n\n if (!response.ok) {\n let errorBody: Record<string, unknown> = {}\n try {\n errorBody = (await response.json()) as Record<string, unknown>\n } catch {\n // ignore parse errors\n }\n const message = (errorBody['message'] as string | undefined) ?? `HTTP ${response.status}`\n if (this.config.debug) {\n console.debug('[hospitable] error body:', sanitize(errorBody))\n }\n if (response.status === 401 && this.config.onUnauthorized) {\n await this.config.onUnauthorized()\n // Re-fetch auth header with the fresh token and retry once\n const freshAuth = await this.config.getAuthHeader()\n const retryResponse = await fetch(url, {\n method,\n headers: { ...headers, Authorization: freshAuth },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n })\n if (retryResponse.ok) {\n if (retryResponse.status === 204) return undefined as T\n return retryResponse.json() as Promise<T>\n }\n let retryBody: Record<string, unknown> = {}\n try { retryBody = (await retryResponse.json()) as Record<string, unknown> } catch { /* ignore */ }\n const retryMessage = (retryBody['message'] as string | undefined) ?? `HTTP ${retryResponse.status}`\n throw new HttpError(retryResponse.status, retryMessage, retryResponse.headers.get('x-request-id') ?? undefined, retryBody)\n }\n throw new HttpError(response.status, message, requestId, errorBody)\n }\n\n if (response.status === 204) {\n return undefined as T\n }\n\n return response.json() as Promise<T>\n },\n url,\n this.config.retryConfig,\n )\n }\n\n get<T>(path: string, params?: RequestOptions['params']): Promise<T> {\n return this.request<T>(path, { method: 'GET', ...(params !== undefined ? { params } : {}) })\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, { method: 'POST', body })\n }\n\n put<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, { method: 'PUT', body })\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, { method: 'PATCH', body })\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' })\n }\n}\n","import type { HttpClient } from '../http/client'\nimport type { CalendarDay, CalendarUpdate } from '../models/calendar'\nimport type { PaginatedResponse } from '../models/pagination'\n\nexport class CalendarResource {\n constructor(private readonly http: HttpClient) {}\n\n async get(\n propertyId: string,\n startDate: string,\n endDate: string,\n ): Promise<PaginatedResponse<CalendarDay>> {\n return this.http.get<PaginatedResponse<CalendarDay>>(\n `/v2/properties/${propertyId}/calendar`,\n { startDate, endDate },\n )\n }\n\n async update(propertyId: string, updates: CalendarUpdate[]): Promise<void> {\n await this.http.put<void>(`/v2/properties/${propertyId}/calendar`, { data: updates })\n }\n\n async block(\n propertyId: string,\n startDate: string,\n endDate: string,\n reason?: string,\n ): Promise<void> {\n const body: Record<string, string> = { startDate, endDate }\n if (reason !== undefined) body['reason'] = reason\n await this.http.post<void>(`/v2/properties/${propertyId}/calendar/block`, body)\n }\n\n async unblock(propertyId: string, startDate: string, endDate: string): Promise<void> {\n await this.http.post<void>(`/v2/properties/${propertyId}/calendar/unblock`, {\n startDate,\n endDate,\n })\n }\n}\n","import type { HttpClient } from '../http/client'\nimport type {\n Message,\n MessageThread,\n MessageTemplate,\n SendMessageRequest,\n} from '../models/message'\n\nexport class MessagesResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(reservationId: string): Promise<MessageThread> {\n return this.http.get<MessageThread>(`/v2/reservations/${reservationId}/messages`)\n }\n\n async send(reservationId: string, body: string): Promise<Message> {\n const payload: SendMessageRequest = { body }\n return this.http.post<Message>(`/v2/reservations/${reservationId}/messages`, payload)\n }\n\n async listTemplates(): Promise<MessageTemplate[]> {\n const response = await this.http.get<{ data: MessageTemplate[] }>('/v2/message-templates')\n return response.data\n }\n\n async sendTemplate(\n reservationId: string,\n templateId: string,\n variables: Record<string, string> = {},\n ): Promise<Message> {\n return this.http.post<Message>(\n `/v2/reservations/${reservationId}/messages/template`,\n { templateId, variables },\n )\n }\n}\n","import type { HttpClient, RequestOptions } from '../http/client'\nimport type { Property, PropertyList, PropertyTag } from '../models/property'\nimport type { CalendarDay, CalendarUpdate } from '../models/calendar'\nimport type { PaginatedResponse } from '../models/pagination'\n\nexport interface PropertyListParams {\n cursor?: string\n perPage?: number\n tags?: string[]\n}\n\nexport class PropertiesResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(params: PropertyListParams = {}): Promise<PropertyList> {\n return this.http.get<PropertyList>('/v2/properties', params as RequestOptions['params'])\n }\n\n async get(id: string): Promise<Property> {\n return this.http.get<Property>(`/v2/properties/${id}`)\n }\n\n async listTags(id: string): Promise<PropertyTag[]> {\n const response = await this.http.get<{ data: PropertyTag[] }>(`/v2/properties/${id}/tags`)\n return response.data\n }\n\n async getCalendar(\n id: string,\n startDate: string,\n endDate: string,\n ): Promise<PaginatedResponse<CalendarDay>> {\n return this.http.get<PaginatedResponse<CalendarDay>>(`/v2/properties/${id}/calendar`, {\n startDate,\n endDate,\n })\n }\n\n async updateCalendar(id: string, updates: CalendarUpdate[]): Promise<void> {\n await this.http.put<void>(`/v2/properties/${id}/calendar`, { data: updates })\n }\n\n async *iter(params: Omit<PropertyListParams, 'cursor'> = {}): AsyncGenerator<Property> {\n let cursor: string | null = null\n do {\n const listParams: PropertyListParams = { ...params }\n if (cursor !== null) {\n listParams.cursor = cursor\n }\n const page = await this.list(listParams)\n for (const item of page.data) {\n yield item\n }\n cursor = page.meta.nextCursor\n } while (cursor !== null)\n }\n}\n","import type { HttpClient } from '../http/client'\nimport type {\n Reservation,\n ReservationList,\n ReservationListParams,\n} from '../models/reservation'\n\nexport class ReservationsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(params: ReservationListParams = {}): Promise<ReservationList> {\n const normalized: Record<string, string | number | boolean | string[] | undefined> = {\n ...params,\n properties: params.properties,\n status: Array.isArray(params.status) ? params.status.join(',') : params.status,\n }\n return this.http.get<ReservationList>('/v2/reservations', normalized)\n }\n\n async get(id: string, include?: string): Promise<Reservation> {\n return this.http.get<Reservation>(`/v2/reservations/${id}`, include ? { include } : undefined)\n }\n\n async getUpcoming(\n propertyIds: string[],\n options: { include?: string } = {},\n ): Promise<ReservationList> {\n const today = new Date().toISOString().split('T')[0]!\n return this.list({\n properties: propertyIds,\n startDate: today,\n status: 'confirmed',\n include: options.include ?? 'guest,properties',\n })\n }\n\n async *iter(params: Omit<ReservationListParams, 'cursor'> = {}): AsyncGenerator<Reservation> {\n let cursor: string | undefined\n do {\n const pageParams: ReservationListParams = { ...params }\n if (cursor !== undefined) pageParams.cursor = cursor\n const page = await this.list(pageParams)\n for (const item of page.data) {\n yield item\n }\n cursor = page.meta.nextCursor ?? undefined\n } while (cursor !== undefined)\n }\n}\n","import type { HttpClient } from '../http/client'\nimport type { Review, ReviewList, ReviewListParams } from '../models/review'\n\nexport class ReviewsResource {\n constructor(private readonly http: HttpClient) {}\n\n async list(params: ReviewListParams = {}): Promise<ReviewList> {\n const normalized: Record<string, string | number | boolean | string[] | undefined> = {\n propertyId: params.propertyId,\n responded: params.responded,\n cursor: params.cursor,\n perPage: params.perPage,\n }\n return this.http.get<ReviewList>('/v2/reviews', normalized)\n }\n\n async get(id: string): Promise<Review> {\n return this.http.get<Review>(`/v2/reviews/${id}`)\n }\n\n async respond(id: string, responseText: string): Promise<Review> {\n return this.http.post<Review>(`/v2/reviews/${id}/response`, { response: responseText })\n }\n\n async *iter(params: Omit<ReviewListParams, 'cursor'> = {}): AsyncGenerator<Review> {\n let cursor: string | null = null\n do {\n const pageParams: ReviewListParams = { ...params }\n if (cursor !== null) pageParams.cursor = cursor\n const page = await this.list(pageParams)\n for (const item of page.data) yield item\n cursor = page.meta.nextCursor\n } while (cursor !== null)\n }\n}\n","import { TokenManager } from './auth'\nimport type { TokenManagerConfig } from './auth'\nimport { HttpClient } from './http/client'\nimport type { RetryConfig } from './http/retry'\nimport { CalendarResource } from './resources/calendar'\nimport { MessagesResource } from './resources/messages'\nimport { PropertiesResource } from './resources/properties'\nimport { ReservationsResource } from './resources/reservations'\nimport { ReviewsResource } from './resources/reviews'\n\nexport interface HospitableClientConfig {\n /** Personal Access Token. Also read from HOSPITABLE_PAT env var. */\n token?: string\n /** OAuth2 refresh token */\n refreshToken?: string\n /** OAuth2 client ID */\n clientId?: string\n /** OAuth2 client secret */\n clientSecret?: string\n /** API base URL. Defaults to https://api.hospitable.com */\n baseURL?: string\n /** Retry configuration */\n retry?: RetryConfig\n /** Enable debug logging */\n debug?: boolean\n}\n\nexport class HospitableClient {\n readonly properties: PropertiesResource\n readonly reservations: ReservationsResource\n readonly calendar: CalendarResource\n readonly messages: MessagesResource\n readonly reviews: ReviewsResource\n\n constructor(config: HospitableClientConfig = {}) {\n const baseURL = config.baseURL ?? 'https://api.hospitable.com'\n\n const tokenConfig: TokenManagerConfig = {\n ...(config.token !== undefined ? { token: config.token } : {}),\n ...(config.refreshToken !== undefined ? { refreshToken: config.refreshToken } : {}),\n ...(config.clientId !== undefined ? { clientId: config.clientId } : {}),\n ...(config.clientSecret !== undefined ? { clientSecret: config.clientSecret } : {}),\n baseURL,\n }\n\n const tokenManager = new TokenManager(tokenConfig)\n\n const httpClient = new HttpClient({\n baseURL,\n getAuthHeader: () => tokenManager.getAuthHeader(),\n onUnauthorized: () => tokenManager.handleUnauthorized(),\n ...(config.debug !== undefined ? { debug: config.debug } : {}),\n ...(config.retry !== undefined ? { retryConfig: config.retry } : {}),\n })\n\n this.properties = new PropertiesResource(httpClient)\n this.reservations = new ReservationsResource(httpClient)\n this.calendar = new CalendarResource(httpClient)\n this.messages = new MessagesResource(httpClient)\n this.reviews = new ReviewsResource(httpClient)\n }\n}\n","import type { PaginatedResponse } from '../models/pagination'\n\nexport interface PageFetcher<T, P extends { cursor?: string; perPage?: number }> {\n (params: P): Promise<PaginatedResponse<T>>\n}\n\nexport async function* paginate<T, P extends { cursor?: string; perPage?: number }>(\n fetcher: PageFetcher<T, P>,\n params: Omit<P, 'cursor'>,\n perPage = 100,\n): AsyncGenerator<T> {\n let cursor: string | null = null\n\n do {\n const page = await fetcher({\n ...params,\n cursor: cursor ?? undefined,\n perPage,\n } as P)\n\n for (const item of page.data) {\n yield item\n }\n\n cursor = page.meta.nextCursor\n } while (cursor !== null)\n}\n\nexport async function collectAll<T, P extends { cursor?: string; perPage?: number }>(\n fetcher: PageFetcher<T, P>,\n params: Omit<P, 'cursor'>,\n perPage = 100,\n): Promise<T[]> {\n const results: T[] = []\n for await (const item of paginate(fetcher, params, perPage)) {\n results.push(item)\n }\n return results\n}\n","import type { ReservationListParams, ReservationStatus } from '../models/reservation'\n\nexport class ReservationFilter {\n private readonly params: ReservationListParams\n\n constructor(params: ReservationListParams = {}) {\n this.params = params\n }\n\n checkinAfter(date: string): ReservationFilter {\n return new ReservationFilter({ ...this.params, startDate: date })\n }\n\n checkinBefore(date: string): ReservationFilter {\n return new ReservationFilter({ ...this.params, endDate: date })\n }\n\n status(status: ReservationStatus | ReservationStatus[]): ReservationFilter {\n return new ReservationFilter({ ...this.params, status })\n }\n\n properties(ids: string[]): ReservationFilter {\n return new ReservationFilter({ ...this.params, properties: ids })\n }\n\n include(...fields: string[]): ReservationFilter {\n return new ReservationFilter({ ...this.params, include: fields.join(',') })\n }\n\n perPage(n: number): ReservationFilter {\n return new ReservationFilter({ ...this.params, perPage: n })\n }\n\n toParams(): ReservationListParams {\n return { ...this.params }\n }\n}\n","import type { PropertyListParams } from '../resources/properties'\n\nexport class PropertyFilter {\n private readonly params: PropertyListParams\n\n constructor(params: PropertyListParams = {}) {\n this.params = params\n }\n\n tags(tagIds: string[]): PropertyFilter {\n return new PropertyFilter({ ...this.params, tags: tagIds })\n }\n\n perPage(n: number): PropertyFilter {\n return new PropertyFilter({ ...this.params, perPage: n })\n }\n\n toParams(): PropertyListParams {\n return { ...this.params }\n }\n}\n","export const VERSION = '0.1.0'\n\nexport { HospitableClient } from './client'\nexport type { HospitableClientConfig } from './client'\n\nexport {\n HospitableError,\n AuthenticationError,\n RateLimitError,\n NotFoundError,\n ValidationError,\n ForbiddenError,\n ServerError,\n createErrorFromResponse,\n} from './errors'\n\nexport * from './models/index'\n\nexport { TokenManager } from './auth'\nexport type { TokenManagerConfig } from './auth'\n\nexport { paginate, collectAll } from './http/paginate'\nexport type { PageFetcher } from './http/paginate'\n\nexport { PropertiesResource } from './resources'\nexport type { PropertyListParams } from './resources'\n\nexport { ReservationsResource } from './resources'\n\nexport { MessagesResource } from './resources'\n\nexport { CalendarResource } from './resources'\n\nexport { ReviewsResource } from './resources'\n\nexport { sanitize } from './utils'\n\nexport { ReservationFilter, PropertyFilter } from './filters'\n"],"mappings":"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","names":["statusCode"]}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "hospitable",
3
+ "version": "0.1.0",
4
+ "author": "Khanh Cao <tyrocium@gmail.com>",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/kacao/hospitable.git"
8
+ },
9
+ "homepage": "https://github.com/kacao/hospitable#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/kacao/hospitable/issues"
12
+ },
13
+ "description": "TypeScript SDK for the Hospitable Public API",
14
+ "main": "./dist/index.cjs",
15
+ "module": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "import": "./dist/index.js",
21
+ "require": "./dist/index.cjs"
22
+ }
23
+ },
24
+ "type": "module",
25
+ "files": ["dist"],
26
+ "scripts": {
27
+ "build": "tsup",
28
+ "dev": "tsup --watch",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest",
31
+ "test:coverage": "vitest run --coverage",
32
+ "lint": "eslint src --ext .ts",
33
+ "typecheck": "tsc --noEmit",
34
+ "prepublishOnly": "npm run build"
35
+ },
36
+ "keywords": ["hospitable", "api", "sdk", "short-term-rental", "airbnb"],
37
+ "license": "MIT",
38
+ "devDependencies": {
39
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
40
+ "@typescript-eslint/parser": "^8.0.0",
41
+ "@vitest/coverage-v8": "^4.0.18",
42
+ "eslint": "^9.0.0",
43
+ "tsup": "^8.0.0",
44
+ "typescript": "^5.5.0",
45
+ "vitest": "^4.0.18"
46
+ }
47
+ }