@theatrical/sdk 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.
- package/LICENSE +21 -0
- package/dist/index.d.mts +2243 -0
- package/dist/index.d.ts +2243 -0
- package/dist/index.js +2116 -0
- package/dist/index.mjs +2080 -0
- package/package.json +56 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,2243 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Vista platform environments
|
|
5
|
+
*/
|
|
6
|
+
type TheatricalEnvironment = 'sandbox' | 'staging' | 'production';
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for the TheatricalClient
|
|
9
|
+
*/
|
|
10
|
+
interface TheatricalConfig {
|
|
11
|
+
/** Vista API key — obtain from your Vista representative */
|
|
12
|
+
apiKey: string;
|
|
13
|
+
/** Target environment. Defaults to 'sandbox' */
|
|
14
|
+
environment?: TheatricalEnvironment;
|
|
15
|
+
/** Override the base URL. Normally derived from environment */
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
/** Request timeout in milliseconds. Defaults to 30000 */
|
|
18
|
+
timeout?: number;
|
|
19
|
+
/** Maximum retry attempts for failed requests. Defaults to 3 */
|
|
20
|
+
maxRetries?: number;
|
|
21
|
+
/** Enable debug logging. Defaults to false */
|
|
22
|
+
debug?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Client for Vista's Global Authentication Service (GAS)
|
|
27
|
+
* Handles JWT token acquisition from auth.moviexchange.com
|
|
28
|
+
*/
|
|
29
|
+
interface GASConfig {
|
|
30
|
+
apiKey: string;
|
|
31
|
+
authUrl: string;
|
|
32
|
+
}
|
|
33
|
+
interface GASToken {
|
|
34
|
+
accessToken: string;
|
|
35
|
+
tokenType: string;
|
|
36
|
+
expiresIn: number;
|
|
37
|
+
issuedAt: number;
|
|
38
|
+
}
|
|
39
|
+
declare class GASClient {
|
|
40
|
+
private readonly config;
|
|
41
|
+
constructor(config: GASConfig);
|
|
42
|
+
/**
|
|
43
|
+
* Request a new JWT token from the Global Authentication Service
|
|
44
|
+
*/
|
|
45
|
+
requestToken(): Promise<GASToken>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Manages JWT token lifecycle — caching, refresh, and expiry detection.
|
|
50
|
+
* Ensures API requests always have a valid token without redundant auth calls.
|
|
51
|
+
*/
|
|
52
|
+
declare class TokenManager {
|
|
53
|
+
private readonly gasClient;
|
|
54
|
+
private currentToken;
|
|
55
|
+
private refreshPromise;
|
|
56
|
+
/** Buffer before expiry to trigger refresh (5 minutes) */
|
|
57
|
+
private readonly expiryBuffer;
|
|
58
|
+
constructor(gasClient: GASClient);
|
|
59
|
+
/**
|
|
60
|
+
* Get a valid access token, refreshing if necessary.
|
|
61
|
+
* Deduplicates concurrent refresh requests.
|
|
62
|
+
*/
|
|
63
|
+
getToken(): Promise<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Force a token refresh regardless of current token state
|
|
66
|
+
*/
|
|
67
|
+
refresh(): Promise<GASToken>;
|
|
68
|
+
/**
|
|
69
|
+
* Check if a token is expired or within the expiry buffer
|
|
70
|
+
*/
|
|
71
|
+
private isExpired;
|
|
72
|
+
/**
|
|
73
|
+
* Clear the current token (e.g., on 401 response)
|
|
74
|
+
*/
|
|
75
|
+
invalidate(): void;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Retry utilities for the Theatrical HTTP client.
|
|
80
|
+
* Provides configurable exponential backoff with optional jitter,
|
|
81
|
+
* designed for resilient communication with Vista's OCAPI platform.
|
|
82
|
+
*
|
|
83
|
+
* @module http/retry
|
|
84
|
+
*/
|
|
85
|
+
/** Configuration for automatic request retry behaviour. */
|
|
86
|
+
interface RetryConfig {
|
|
87
|
+
/**
|
|
88
|
+
* Maximum number of retry attempts. The initial request is not counted.
|
|
89
|
+
* A value of 3 means up to 4 total attempts (initial + 3 retries).
|
|
90
|
+
* @default 3
|
|
91
|
+
*/
|
|
92
|
+
maxRetries: number;
|
|
93
|
+
/**
|
|
94
|
+
* Base delay in milliseconds for the first retry.
|
|
95
|
+
* Subsequent retries use exponential backoff: `baseDelay * 2^(attempt - 1)`.
|
|
96
|
+
* @default 1000
|
|
97
|
+
*/
|
|
98
|
+
baseDelay: number;
|
|
99
|
+
/**
|
|
100
|
+
* Maximum delay cap in milliseconds.
|
|
101
|
+
* Prevents backoff from growing unbounded on high retry counts.
|
|
102
|
+
* @default 30_000
|
|
103
|
+
*/
|
|
104
|
+
maxDelay: number;
|
|
105
|
+
/**
|
|
106
|
+
* When true, adds randomised full jitter to each delay.
|
|
107
|
+
* Spreads retry storms across the Vista API cluster.
|
|
108
|
+
* @default true
|
|
109
|
+
*/
|
|
110
|
+
jitter: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Optional predicate — when provided, retries only if this function returns
|
|
113
|
+
* true for the thrown error. Use to avoid retrying non-recoverable errors
|
|
114
|
+
* such as 400 Bad Request or 401 Unauthorised.
|
|
115
|
+
*/
|
|
116
|
+
shouldRetry?: (error: unknown) => boolean;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Sliding-window rate limiter for the Theatrical HTTP client.
|
|
121
|
+
* Prevents the SDK from exceeding Vista's OCAPI rate limits by queuing
|
|
122
|
+
* requests proactively rather than recovering from 429 responses after the fact.
|
|
123
|
+
*
|
|
124
|
+
* @module http/rate-limiter
|
|
125
|
+
*/
|
|
126
|
+
/** Configuration for the sliding-window rate limiter. */
|
|
127
|
+
interface RateLimiterConfig {
|
|
128
|
+
/**
|
|
129
|
+
* Maximum number of requests allowed within the rolling window.
|
|
130
|
+
* Matches Vista's OCAPI per-key limit for the configured window.
|
|
131
|
+
*/
|
|
132
|
+
maxRequests: number;
|
|
133
|
+
/**
|
|
134
|
+
* Duration of the sliding window in milliseconds.
|
|
135
|
+
* Timestamps older than `now - windowMs` are evicted and no longer count.
|
|
136
|
+
* @default 60_000
|
|
137
|
+
*/
|
|
138
|
+
windowMs: number;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Sliding-window rate limiter using a timestamp queue.
|
|
142
|
+
*
|
|
143
|
+
* Tracks the wall-clock time of each accepted request. When the in-window
|
|
144
|
+
* request count reaches `maxRequests`, `waitForSlot()` blocks until the oldest
|
|
145
|
+
* recorded timestamp exits the window, then records the new request and resolves.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* const limiter = new RateLimiter({ maxRequests: 100, windowMs: 60_000 });
|
|
149
|
+
*
|
|
150
|
+
* // In the HTTP client, before each fetch:
|
|
151
|
+
* await limiter.waitForSlot();
|
|
152
|
+
* const response = await fetch(url, options);
|
|
153
|
+
*/
|
|
154
|
+
declare class RateLimiter {
|
|
155
|
+
private readonly config;
|
|
156
|
+
private readonly timestamps;
|
|
157
|
+
/**
|
|
158
|
+
* Creates a new RateLimiter.
|
|
159
|
+
* @param config - Limits and window size. Defaults to {@link DEFAULT_RATE_LIMITER_CONFIG}.
|
|
160
|
+
*/
|
|
161
|
+
constructor(config?: RateLimiterConfig);
|
|
162
|
+
/**
|
|
163
|
+
* Waits until a request slot is available within the current window,
|
|
164
|
+
* records the request timestamp, and resolves.
|
|
165
|
+
*
|
|
166
|
+
* Callers `await` this before making an HTTP request. If the limit has been
|
|
167
|
+
* reached, the call suspends until the oldest in-window request expires.
|
|
168
|
+
*
|
|
169
|
+
* @returns Promise that resolves when it is safe to proceed with a request
|
|
170
|
+
*/
|
|
171
|
+
waitForSlot(): Promise<void>;
|
|
172
|
+
/**
|
|
173
|
+
* Returns the number of requests recorded within the current rolling window.
|
|
174
|
+
* Useful for diagnostics and integration tests.
|
|
175
|
+
*/
|
|
176
|
+
get activeCount(): number;
|
|
177
|
+
/**
|
|
178
|
+
* Clears all recorded timestamps, resetting the limiter to a clean state.
|
|
179
|
+
* Primarily intended for use in tests.
|
|
180
|
+
*/
|
|
181
|
+
reset(): void;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Request/response interceptor types and chain runner for the Theatrical HTTP client.
|
|
186
|
+
* Interceptors allow consumers to inspect or mutate requests before they are sent
|
|
187
|
+
* and responses before they are returned — useful for logging, auth header injection,
|
|
188
|
+
* response normalisation, and telemetry.
|
|
189
|
+
*
|
|
190
|
+
* @module http/interceptors
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* A function that receives a {@link RequestConfig} before a request is sent
|
|
194
|
+
* and returns a (possibly mutated) config to use instead.
|
|
195
|
+
*
|
|
196
|
+
* Return the same object to pass through unchanged, or return a new object to
|
|
197
|
+
* override headers, the URL, the body, etc.
|
|
198
|
+
*
|
|
199
|
+
* Async interceptors are fully supported — return a `Promise<RequestConfig>` to
|
|
200
|
+
* perform async work (e.g. look up a secondary token, log to an external service).
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* const addCorrelationId: RequestInterceptor = (config) => ({
|
|
204
|
+
* ...config,
|
|
205
|
+
* headers: { ...config.headers, 'X-Correlation-ID': uuid() },
|
|
206
|
+
* });
|
|
207
|
+
*/
|
|
208
|
+
type RequestInterceptor = (config: RequestConfig) => RequestConfig | Promise<RequestConfig>;
|
|
209
|
+
/**
|
|
210
|
+
* A function that receives a `Response` after a successful HTTP call and returns
|
|
211
|
+
* a (possibly mutated) `Response` to pass upstream.
|
|
212
|
+
*
|
|
213
|
+
* Note: interceptors run only on responses that pass the `response.ok` check.
|
|
214
|
+
* Error responses are handled by the client's error-mapping logic before
|
|
215
|
+
* interceptors are invoked.
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* const logLatency: ResponseInterceptor = (response) => {
|
|
219
|
+
* console.log(`[theatrical] ${response.url} — ${response.status}`);
|
|
220
|
+
* return response;
|
|
221
|
+
* };
|
|
222
|
+
*/
|
|
223
|
+
type ResponseInterceptor = (response: Response) => Response | Promise<Response>;
|
|
224
|
+
/**
|
|
225
|
+
* A plain-object snapshot of the mutable parts of a fetch request.
|
|
226
|
+
* Passed through the {@link RequestInterceptor} chain before each call.
|
|
227
|
+
*/
|
|
228
|
+
interface RequestConfig {
|
|
229
|
+
/** Fully-qualified URL for the request (base URL + path + query string). */
|
|
230
|
+
url: string;
|
|
231
|
+
/** HTTP method. */
|
|
232
|
+
method: string;
|
|
233
|
+
/** Request headers (merged with auth and content-type defaults). */
|
|
234
|
+
headers: Record<string, string>;
|
|
235
|
+
/** Serialised request body, or undefined for GET/DELETE. */
|
|
236
|
+
body?: string;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
interface HTTPClientConfig {
|
|
240
|
+
baseUrl: string;
|
|
241
|
+
timeout: number;
|
|
242
|
+
maxRetries: number;
|
|
243
|
+
tokenManager: TokenManager;
|
|
244
|
+
debug: boolean;
|
|
245
|
+
/** Optional retry configuration. Defaults to {@link DEFAULT_RETRY_CONFIG}. */
|
|
246
|
+
retry?: RetryConfig;
|
|
247
|
+
/**
|
|
248
|
+
* Optional rate limiter instance for proactive request throttling.
|
|
249
|
+
*
|
|
250
|
+
* When provided, `waitForSlot()` is called before each outgoing request to
|
|
251
|
+
* ensure the SDK never exceeds Vista's OCAPI rate limits. If not provided,
|
|
252
|
+
* no proactive limiting is applied — the client falls back to reactive
|
|
253
|
+
* handling of 429 responses.
|
|
254
|
+
*
|
|
255
|
+
* Inject a shared `RateLimiter` when multiple SDK instances target the same
|
|
256
|
+
* Vista operator key, so all instances contribute to the same window count.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* import { RateLimiter } from '@theatrical/sdk';
|
|
261
|
+
*
|
|
262
|
+
* const limiter = new RateLimiter({ maxRequests: 60, windowMs: 60_000 });
|
|
263
|
+
* const client = new TheatricalHTTPClient({ ..., rateLimiter: limiter });
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
rateLimiter?: RateLimiter;
|
|
267
|
+
/**
|
|
268
|
+
* Ordered list of request interceptors.
|
|
269
|
+
* Each interceptor receives the {@link RequestConfig} built for the outgoing
|
|
270
|
+
* request and may return a mutated copy. Interceptors run in array order
|
|
271
|
+
* before the `fetch` call is made.
|
|
272
|
+
*/
|
|
273
|
+
onRequest?: RequestInterceptor[];
|
|
274
|
+
/**
|
|
275
|
+
* Ordered list of response interceptors.
|
|
276
|
+
* Each interceptor receives the raw `Response` object after a successful
|
|
277
|
+
* (`response.ok`) fetch and may return a mutated copy. Interceptors run in
|
|
278
|
+
* array order before the response body is decoded.
|
|
279
|
+
*/
|
|
280
|
+
onResponse?: ResponseInterceptor[];
|
|
281
|
+
}
|
|
282
|
+
interface RequestOptions {
|
|
283
|
+
method?: string;
|
|
284
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
285
|
+
body?: unknown;
|
|
286
|
+
headers?: Record<string, string>;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Core HTTP client for all Vista API communication.
|
|
290
|
+
* Handles authentication, retries, rate limiting, and error transformation.
|
|
291
|
+
*/
|
|
292
|
+
declare class TheatricalHTTPClient {
|
|
293
|
+
private readonly config;
|
|
294
|
+
constructor(config: HTTPClientConfig);
|
|
295
|
+
get<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
296
|
+
post<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
297
|
+
put<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
298
|
+
delete<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
299
|
+
private request;
|
|
300
|
+
private buildUrl;
|
|
301
|
+
private generateRequestId;
|
|
302
|
+
private delay;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Zod schema for presentation format — validates format strings from the API.
|
|
307
|
+
*/
|
|
308
|
+
declare const sessionFormatSchema: z.ZodEnum<["2D", "3D", "IMAX", "IMAX3D", "4DX", "DOLBY_CINEMA", "SCREENX", "STANDARD"]>;
|
|
309
|
+
/**
|
|
310
|
+
* Zod schema for seat status — validates seat availability state from the API.
|
|
311
|
+
*/
|
|
312
|
+
declare const seatStatusSchema: z.ZodEnum<["available", "taken", "reserved", "wheelchair", "companion", "blocked"]>;
|
|
313
|
+
/**
|
|
314
|
+
* A cinema session (showtime) — a specific screening of a film
|
|
315
|
+
* at a specific site, screen, date, and time.
|
|
316
|
+
*/
|
|
317
|
+
interface Session {
|
|
318
|
+
/** Unique session identifier */
|
|
319
|
+
id: string;
|
|
320
|
+
/** Film being screened */
|
|
321
|
+
filmId: string;
|
|
322
|
+
/** Film title */
|
|
323
|
+
filmTitle: string;
|
|
324
|
+
/** Cinema site ID */
|
|
325
|
+
siteId: string;
|
|
326
|
+
/** Screen/auditorium identifier */
|
|
327
|
+
screenId: string;
|
|
328
|
+
/** Screen name (e.g., "Screen 3", "IMAX") */
|
|
329
|
+
screenName: string;
|
|
330
|
+
/** Session start time (ISO 8601) */
|
|
331
|
+
startTime: string;
|
|
332
|
+
/** Session end time (ISO 8601) */
|
|
333
|
+
endTime: string;
|
|
334
|
+
/** Presentation format */
|
|
335
|
+
format: SessionFormat;
|
|
336
|
+
/** Whether the session is bookable */
|
|
337
|
+
isBookable: boolean;
|
|
338
|
+
/** Whether the session is sold out */
|
|
339
|
+
isSoldOut: boolean;
|
|
340
|
+
/** Available seat count */
|
|
341
|
+
seatsAvailable: number;
|
|
342
|
+
/** Total seat capacity */
|
|
343
|
+
seatsTotal: number;
|
|
344
|
+
/** Minimum ticket price in local currency */
|
|
345
|
+
priceFrom?: number;
|
|
346
|
+
/** Currency code (ISO 4217) */
|
|
347
|
+
currency?: string;
|
|
348
|
+
/** Additional attributes */
|
|
349
|
+
attributes: Record<string, string>;
|
|
350
|
+
}
|
|
351
|
+
/** Presentation format for a cinema session */
|
|
352
|
+
type SessionFormat = z.infer<typeof sessionFormatSchema>;
|
|
353
|
+
interface SessionFilter {
|
|
354
|
+
/** Filter by cinema site */
|
|
355
|
+
siteId?: string;
|
|
356
|
+
/** Filter by film */
|
|
357
|
+
filmId?: string;
|
|
358
|
+
/** Filter by date (YYYY-MM-DD) */
|
|
359
|
+
date?: string;
|
|
360
|
+
/** Filter by date range start */
|
|
361
|
+
dateFrom?: string;
|
|
362
|
+
/** Filter by date range end */
|
|
363
|
+
dateTo?: string;
|
|
364
|
+
/** Filter by format */
|
|
365
|
+
format?: SessionFormat;
|
|
366
|
+
/** Only bookable sessions */
|
|
367
|
+
bookableOnly?: boolean;
|
|
368
|
+
/** Maximum results to return */
|
|
369
|
+
limit?: number;
|
|
370
|
+
/** Numeric page offset — mutually exclusive with `cursor` */
|
|
371
|
+
offset?: number;
|
|
372
|
+
/**
|
|
373
|
+
* Opaque cursor string from a previous response's `nextCursor` field.
|
|
374
|
+
* Preferred over `offset` for real-time session data — cursors are stable
|
|
375
|
+
* when new sessions are added between pages.
|
|
376
|
+
* Mutually exclusive with `offset`.
|
|
377
|
+
*/
|
|
378
|
+
cursor?: string;
|
|
379
|
+
}
|
|
380
|
+
interface SessionListResponse {
|
|
381
|
+
/** List of sessions matching the filter */
|
|
382
|
+
sessions: Session[];
|
|
383
|
+
/** Total count of matching sessions */
|
|
384
|
+
total: number;
|
|
385
|
+
/** Whether more results are available */
|
|
386
|
+
hasMore: boolean;
|
|
387
|
+
/** Numeric offset for the next page (offset-based pagination) */
|
|
388
|
+
nextOffset?: number;
|
|
389
|
+
/** Opaque cursor for the next page (cursor-based pagination) */
|
|
390
|
+
nextCursor?: string;
|
|
391
|
+
}
|
|
392
|
+
/** Seat status in an availability map */
|
|
393
|
+
type SeatStatus = z.infer<typeof seatStatusSchema>;
|
|
394
|
+
/** Individual seat in the auditorium */
|
|
395
|
+
interface Seat {
|
|
396
|
+
/** Seat identifier */
|
|
397
|
+
id: string;
|
|
398
|
+
/** Row label (e.g., "H") */
|
|
399
|
+
row: string;
|
|
400
|
+
/** Seat number within the row */
|
|
401
|
+
number: number;
|
|
402
|
+
/** Current availability status */
|
|
403
|
+
status: SeatStatus;
|
|
404
|
+
/** X position for rendering */
|
|
405
|
+
x: number;
|
|
406
|
+
/** Y position for rendering */
|
|
407
|
+
y: number;
|
|
408
|
+
/** Seat type/category */
|
|
409
|
+
type?: string;
|
|
410
|
+
/** Whether this is an accessible seat */
|
|
411
|
+
isAccessible: boolean;
|
|
412
|
+
}
|
|
413
|
+
/** Seat availability response for a session */
|
|
414
|
+
interface SeatAvailability {
|
|
415
|
+
/** Session ID */
|
|
416
|
+
sessionId: string;
|
|
417
|
+
/** Screen name */
|
|
418
|
+
screenName: string;
|
|
419
|
+
/** All seats in the auditorium */
|
|
420
|
+
seats: Seat[];
|
|
421
|
+
/** Number of rows */
|
|
422
|
+
rowCount: number;
|
|
423
|
+
/** Screen orientation hint for rendering */
|
|
424
|
+
screenPosition: 'top' | 'bottom';
|
|
425
|
+
/** Available seat count */
|
|
426
|
+
availableCount: number;
|
|
427
|
+
/** Total seat count */
|
|
428
|
+
totalCount: number;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Pagination strategy supported by Vista's OCAPI endpoints.
|
|
433
|
+
*
|
|
434
|
+
* - `'cursor'` — opaque cursor string returned with each page; preferred for
|
|
435
|
+
* real-time data (sessions, orders) where rows may shift between requests.
|
|
436
|
+
* - `'offset'` — numeric offset/limit; suitable for stable result sets
|
|
437
|
+
* (films, sites) where insertion order rarely changes mid-request.
|
|
438
|
+
*/
|
|
439
|
+
type PaginationStrategy = 'cursor' | 'offset';
|
|
440
|
+
/**
|
|
441
|
+
* Generic paginated response envelope.
|
|
442
|
+
*
|
|
443
|
+
* All list endpoints return data wrapped in this shape once pagination
|
|
444
|
+
* is normalised. The `data` array contains the current page of results;
|
|
445
|
+
* `hasMore` indicates whether additional pages exist.
|
|
446
|
+
*
|
|
447
|
+
* @typeParam T - The resource type contained in each page
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* ```typescript
|
|
451
|
+
* const page: PaginatedResponse<Session> = await client.sessions.list({
|
|
452
|
+
* siteId: 'roxy-wellington',
|
|
453
|
+
* limit: 25,
|
|
454
|
+
* });
|
|
455
|
+
*
|
|
456
|
+
* console.log(page.data.length); // up to 25
|
|
457
|
+
* console.log(page.hasMore); // true if more pages exist
|
|
458
|
+
* ```
|
|
459
|
+
*/
|
|
460
|
+
interface PaginatedResponse<T> {
|
|
461
|
+
/** The current page of results */
|
|
462
|
+
data: T[];
|
|
463
|
+
/** Total number of matching results across all pages */
|
|
464
|
+
total: number;
|
|
465
|
+
/** Whether additional pages are available */
|
|
466
|
+
hasMore: boolean;
|
|
467
|
+
/** Opaque cursor for the next page (cursor-based pagination) */
|
|
468
|
+
nextCursor?: string;
|
|
469
|
+
/** Numeric offset for the next page (offset-based pagination) */
|
|
470
|
+
nextOffset?: number;
|
|
471
|
+
/** The pagination strategy used for this response */
|
|
472
|
+
strategy: PaginationStrategy;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Options for controlling pagination behaviour on list endpoints.
|
|
476
|
+
*/
|
|
477
|
+
interface PaginationParams {
|
|
478
|
+
/** Maximum number of results per page (default: 50, max: 500) */
|
|
479
|
+
limit?: number;
|
|
480
|
+
/** Opaque cursor from a previous response — mutually exclusive with `offset` */
|
|
481
|
+
cursor?: string;
|
|
482
|
+
/** Numeric offset — mutually exclusive with `cursor` */
|
|
483
|
+
offset?: number;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Sessions resource — showtimes, availability, and seat maps.
|
|
488
|
+
*
|
|
489
|
+
* @example
|
|
490
|
+
* ```typescript
|
|
491
|
+
* const sessions = await client.sessions.list({
|
|
492
|
+
* siteId: 'roxy-wellington',
|
|
493
|
+
* date: '2026-04-08',
|
|
494
|
+
* });
|
|
495
|
+
*
|
|
496
|
+
* const seats = await client.sessions.availability(sessions[0].id);
|
|
497
|
+
* ```
|
|
498
|
+
*
|
|
499
|
+
* @example Auto-paginate all sessions
|
|
500
|
+
* ```typescript
|
|
501
|
+
* for await (const session of client.sessions.listAll({ siteId: 'roxy-wellington' })) {
|
|
502
|
+
* console.log(session.filmTitle, session.startTime);
|
|
503
|
+
* }
|
|
504
|
+
* ```
|
|
505
|
+
*/
|
|
506
|
+
declare class SessionsResource {
|
|
507
|
+
private readonly http;
|
|
508
|
+
constructor(http: TheatricalHTTPClient);
|
|
509
|
+
/**
|
|
510
|
+
* List sessions (showtimes) with optional filters.
|
|
511
|
+
* Response is validated at runtime using Zod — malformed API responses throw a parse error.
|
|
512
|
+
* @throws {TheatricalError} When the API returns an error response
|
|
513
|
+
* @throws {z.ZodError} When the response fails schema validation
|
|
514
|
+
* @see https://developer.vista.co/digital-platform/sessions/
|
|
515
|
+
*/
|
|
516
|
+
list(filters?: SessionFilter): Promise<SessionListResponse>;
|
|
517
|
+
/**
|
|
518
|
+
* List sessions with explicit pagination control.
|
|
519
|
+
*
|
|
520
|
+
* Returns a normalised `PaginatedResponse<Session>` envelope that includes
|
|
521
|
+
* the pagination strategy and cursor/offset for the next page.
|
|
522
|
+
*
|
|
523
|
+
* @param filters - Session filters (site, film, date range, etc.)
|
|
524
|
+
* @param pagination - Page size and cursor/offset position
|
|
525
|
+
* @returns A single page of sessions with pagination metadata
|
|
526
|
+
*
|
|
527
|
+
* @example
|
|
528
|
+
* ```typescript
|
|
529
|
+
* const page = await client.sessions.listPaginated(
|
|
530
|
+
* { siteId: 'roxy-wellington' },
|
|
531
|
+
* { limit: 25 },
|
|
532
|
+
* );
|
|
533
|
+
* console.log(page.data.length, page.hasMore);
|
|
534
|
+
* ```
|
|
535
|
+
*/
|
|
536
|
+
listPaginated(filters?: SessionFilter, pagination?: PaginationParams): Promise<PaginatedResponse<Session>>;
|
|
537
|
+
/**
|
|
538
|
+
* Async generator that automatically paginates through all matching sessions.
|
|
539
|
+
*
|
|
540
|
+
* Yields individual `Session` objects, fetching the next page transparently
|
|
541
|
+
* when the current page is exhausted. Uses offset-based pagination internally
|
|
542
|
+
* since Vista's session endpoints support numeric offsets.
|
|
543
|
+
*
|
|
544
|
+
* @param filters - Session filters (site, film, date range, etc.)
|
|
545
|
+
* @param pageSize - Number of sessions to fetch per page (default: 50, max: 500)
|
|
546
|
+
*
|
|
547
|
+
* @example
|
|
548
|
+
* ```typescript
|
|
549
|
+
* const allSessions: Session[] = [];
|
|
550
|
+
* for await (const session of client.sessions.listAll({ siteId: 'roxy-wellington' })) {
|
|
551
|
+
* allSessions.push(session);
|
|
552
|
+
* }
|
|
553
|
+
* ```
|
|
554
|
+
*
|
|
555
|
+
* @example Collect with early termination
|
|
556
|
+
* ```typescript
|
|
557
|
+
* for await (const session of client.sessions.listAll({ date: '2026-04-10' })) {
|
|
558
|
+
* if (session.isSoldOut) continue;
|
|
559
|
+
* console.log(`${session.filmTitle} — ${session.screenName} @ ${session.startTime}`);
|
|
560
|
+
* if (!session.isBookable) break; // stop on first unbookable
|
|
561
|
+
* }
|
|
562
|
+
* ```
|
|
563
|
+
*/
|
|
564
|
+
listAll(filters?: SessionFilter, pageSize?: number): AsyncGenerator<Session, void, undefined>;
|
|
565
|
+
/**
|
|
566
|
+
* Get a single session by ID.
|
|
567
|
+
* Response is validated at runtime using Zod.
|
|
568
|
+
*/
|
|
569
|
+
get(sessionId: string): Promise<Session>;
|
|
570
|
+
/**
|
|
571
|
+
* Get seat availability for a session.
|
|
572
|
+
* Returns the complete auditorium seat map with status for each seat.
|
|
573
|
+
* Response is validated at runtime using Zod.
|
|
574
|
+
*/
|
|
575
|
+
availability(sessionId: string): Promise<SeatAvailability>;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Zod schema for a cinema screen/auditorium.
|
|
580
|
+
* `formats` is a list of presentation formats (e.g. '2D', 'IMAX', 'DOLBY_ATMOS').
|
|
581
|
+
*/
|
|
582
|
+
declare const screenSchema: z.ZodObject<{
|
|
583
|
+
id: z.ZodString;
|
|
584
|
+
name: z.ZodString;
|
|
585
|
+
seatCount: z.ZodNumber;
|
|
586
|
+
formats: z.ZodArray<z.ZodString, "many">;
|
|
587
|
+
isAccessible: z.ZodBoolean;
|
|
588
|
+
}, "strip", z.ZodTypeAny, {
|
|
589
|
+
id: string;
|
|
590
|
+
isAccessible: boolean;
|
|
591
|
+
name: string;
|
|
592
|
+
seatCount: number;
|
|
593
|
+
formats: string[];
|
|
594
|
+
}, {
|
|
595
|
+
id: string;
|
|
596
|
+
isAccessible: boolean;
|
|
597
|
+
name: string;
|
|
598
|
+
seatCount: number;
|
|
599
|
+
formats: string[];
|
|
600
|
+
}>;
|
|
601
|
+
/**
|
|
602
|
+
* Zod schema for site booking and operational configuration.
|
|
603
|
+
*/
|
|
604
|
+
declare const siteConfigSchema: z.ZodObject<{
|
|
605
|
+
bookingLeadTime: z.ZodNumber;
|
|
606
|
+
maxTicketsPerOrder: z.ZodNumber;
|
|
607
|
+
loyaltyEnabled: z.ZodBoolean;
|
|
608
|
+
fnbEnabled: z.ZodBoolean;
|
|
609
|
+
}, "strip", z.ZodTypeAny, {
|
|
610
|
+
bookingLeadTime: number;
|
|
611
|
+
maxTicketsPerOrder: number;
|
|
612
|
+
loyaltyEnabled: boolean;
|
|
613
|
+
fnbEnabled: boolean;
|
|
614
|
+
}, {
|
|
615
|
+
bookingLeadTime: number;
|
|
616
|
+
maxTicketsPerOrder: number;
|
|
617
|
+
loyaltyEnabled: boolean;
|
|
618
|
+
fnbEnabled: boolean;
|
|
619
|
+
}>;
|
|
620
|
+
/**
|
|
621
|
+
* Zod schema for a cinema site (location).
|
|
622
|
+
* Validates the full shape of a site returned from Vista's OCAPI.
|
|
623
|
+
*/
|
|
624
|
+
declare const siteSchema: z.ZodObject<{
|
|
625
|
+
id: z.ZodString;
|
|
626
|
+
name: z.ZodString;
|
|
627
|
+
address: z.ZodObject<{
|
|
628
|
+
line1: z.ZodString;
|
|
629
|
+
line2: z.ZodOptional<z.ZodString>;
|
|
630
|
+
city: z.ZodString;
|
|
631
|
+
state: z.ZodOptional<z.ZodString>;
|
|
632
|
+
postalCode: z.ZodString;
|
|
633
|
+
country: z.ZodString;
|
|
634
|
+
}, "strip", z.ZodTypeAny, {
|
|
635
|
+
line1: string;
|
|
636
|
+
city: string;
|
|
637
|
+
postalCode: string;
|
|
638
|
+
country: string;
|
|
639
|
+
line2?: string | undefined;
|
|
640
|
+
state?: string | undefined;
|
|
641
|
+
}, {
|
|
642
|
+
line1: string;
|
|
643
|
+
city: string;
|
|
644
|
+
postalCode: string;
|
|
645
|
+
country: string;
|
|
646
|
+
line2?: string | undefined;
|
|
647
|
+
state?: string | undefined;
|
|
648
|
+
}>;
|
|
649
|
+
location: z.ZodObject<{
|
|
650
|
+
latitude: z.ZodNumber;
|
|
651
|
+
longitude: z.ZodNumber;
|
|
652
|
+
}, "strip", z.ZodTypeAny, {
|
|
653
|
+
latitude: number;
|
|
654
|
+
longitude: number;
|
|
655
|
+
}, {
|
|
656
|
+
latitude: number;
|
|
657
|
+
longitude: number;
|
|
658
|
+
}>;
|
|
659
|
+
screens: z.ZodArray<z.ZodObject<{
|
|
660
|
+
id: z.ZodString;
|
|
661
|
+
name: z.ZodString;
|
|
662
|
+
seatCount: z.ZodNumber;
|
|
663
|
+
formats: z.ZodArray<z.ZodString, "many">;
|
|
664
|
+
isAccessible: z.ZodBoolean;
|
|
665
|
+
}, "strip", z.ZodTypeAny, {
|
|
666
|
+
id: string;
|
|
667
|
+
isAccessible: boolean;
|
|
668
|
+
name: string;
|
|
669
|
+
seatCount: number;
|
|
670
|
+
formats: string[];
|
|
671
|
+
}, {
|
|
672
|
+
id: string;
|
|
673
|
+
isAccessible: boolean;
|
|
674
|
+
name: string;
|
|
675
|
+
seatCount: number;
|
|
676
|
+
formats: string[];
|
|
677
|
+
}>, "many">;
|
|
678
|
+
config: z.ZodObject<{
|
|
679
|
+
bookingLeadTime: z.ZodNumber;
|
|
680
|
+
maxTicketsPerOrder: z.ZodNumber;
|
|
681
|
+
loyaltyEnabled: z.ZodBoolean;
|
|
682
|
+
fnbEnabled: z.ZodBoolean;
|
|
683
|
+
}, "strip", z.ZodTypeAny, {
|
|
684
|
+
bookingLeadTime: number;
|
|
685
|
+
maxTicketsPerOrder: number;
|
|
686
|
+
loyaltyEnabled: boolean;
|
|
687
|
+
fnbEnabled: boolean;
|
|
688
|
+
}, {
|
|
689
|
+
bookingLeadTime: number;
|
|
690
|
+
maxTicketsPerOrder: number;
|
|
691
|
+
loyaltyEnabled: boolean;
|
|
692
|
+
fnbEnabled: boolean;
|
|
693
|
+
}>;
|
|
694
|
+
timezone: z.ZodString;
|
|
695
|
+
currency: z.ZodString;
|
|
696
|
+
isActive: z.ZodBoolean;
|
|
697
|
+
amenities: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
698
|
+
/** Amenity identifier (e.g. 'parking', 'bar', 'vip_lounge', 'imax') */
|
|
699
|
+
id: z.ZodString;
|
|
700
|
+
/** Human-readable label */
|
|
701
|
+
label: z.ZodString;
|
|
702
|
+
/** Optional icon key for rendering */
|
|
703
|
+
icon: z.ZodOptional<z.ZodString>;
|
|
704
|
+
}, "strip", z.ZodTypeAny, {
|
|
705
|
+
id: string;
|
|
706
|
+
label: string;
|
|
707
|
+
icon?: string | undefined;
|
|
708
|
+
}, {
|
|
709
|
+
id: string;
|
|
710
|
+
label: string;
|
|
711
|
+
icon?: string | undefined;
|
|
712
|
+
}>, "many">>;
|
|
713
|
+
}, "strip", z.ZodTypeAny, {
|
|
714
|
+
config: {
|
|
715
|
+
bookingLeadTime: number;
|
|
716
|
+
maxTicketsPerOrder: number;
|
|
717
|
+
loyaltyEnabled: boolean;
|
|
718
|
+
fnbEnabled: boolean;
|
|
719
|
+
};
|
|
720
|
+
id: string;
|
|
721
|
+
currency: string;
|
|
722
|
+
name: string;
|
|
723
|
+
address: {
|
|
724
|
+
line1: string;
|
|
725
|
+
city: string;
|
|
726
|
+
postalCode: string;
|
|
727
|
+
country: string;
|
|
728
|
+
line2?: string | undefined;
|
|
729
|
+
state?: string | undefined;
|
|
730
|
+
};
|
|
731
|
+
location: {
|
|
732
|
+
latitude: number;
|
|
733
|
+
longitude: number;
|
|
734
|
+
};
|
|
735
|
+
screens: {
|
|
736
|
+
id: string;
|
|
737
|
+
isAccessible: boolean;
|
|
738
|
+
name: string;
|
|
739
|
+
seatCount: number;
|
|
740
|
+
formats: string[];
|
|
741
|
+
}[];
|
|
742
|
+
timezone: string;
|
|
743
|
+
isActive: boolean;
|
|
744
|
+
amenities?: {
|
|
745
|
+
id: string;
|
|
746
|
+
label: string;
|
|
747
|
+
icon?: string | undefined;
|
|
748
|
+
}[] | undefined;
|
|
749
|
+
}, {
|
|
750
|
+
config: {
|
|
751
|
+
bookingLeadTime: number;
|
|
752
|
+
maxTicketsPerOrder: number;
|
|
753
|
+
loyaltyEnabled: boolean;
|
|
754
|
+
fnbEnabled: boolean;
|
|
755
|
+
};
|
|
756
|
+
id: string;
|
|
757
|
+
currency: string;
|
|
758
|
+
name: string;
|
|
759
|
+
address: {
|
|
760
|
+
line1: string;
|
|
761
|
+
city: string;
|
|
762
|
+
postalCode: string;
|
|
763
|
+
country: string;
|
|
764
|
+
line2?: string | undefined;
|
|
765
|
+
state?: string | undefined;
|
|
766
|
+
};
|
|
767
|
+
location: {
|
|
768
|
+
latitude: number;
|
|
769
|
+
longitude: number;
|
|
770
|
+
};
|
|
771
|
+
screens: {
|
|
772
|
+
id: string;
|
|
773
|
+
isAccessible: boolean;
|
|
774
|
+
name: string;
|
|
775
|
+
seatCount: number;
|
|
776
|
+
formats: string[];
|
|
777
|
+
}[];
|
|
778
|
+
timezone: string;
|
|
779
|
+
isActive: boolean;
|
|
780
|
+
amenities?: {
|
|
781
|
+
id: string;
|
|
782
|
+
label: string;
|
|
783
|
+
icon?: string | undefined;
|
|
784
|
+
}[] | undefined;
|
|
785
|
+
}>;
|
|
786
|
+
/** Cinema screen/auditorium configuration */
|
|
787
|
+
type Screen = z.infer<typeof screenSchema>;
|
|
788
|
+
/** Site booking and operational configuration */
|
|
789
|
+
type SiteConfig = z.infer<typeof siteConfigSchema>;
|
|
790
|
+
/**
|
|
791
|
+
* A cinema site (location) — the physical venue with screens, address, and config.
|
|
792
|
+
*
|
|
793
|
+
* @example
|
|
794
|
+
* ```typescript
|
|
795
|
+
* const sites = await client.sites.list();
|
|
796
|
+
* const active = sites.filter(s => s.isActive);
|
|
797
|
+
* ```
|
|
798
|
+
*/
|
|
799
|
+
type Site = z.infer<typeof siteSchema>;
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Sites resource — cinema locations, screens, and geographic discovery.
|
|
803
|
+
*
|
|
804
|
+
* @example
|
|
805
|
+
* ```typescript
|
|
806
|
+
* const sites = await client.sites.list();
|
|
807
|
+
* const active = sites.filter(s => s.isActive);
|
|
808
|
+
* ```
|
|
809
|
+
*
|
|
810
|
+
* @example Geographic discovery
|
|
811
|
+
* ```typescript
|
|
812
|
+
* // Find cinemas within 10 km of central Wellington
|
|
813
|
+
* const nearby = await client.sites.nearby(-41.2865, 174.7762, 10);
|
|
814
|
+
* ```
|
|
815
|
+
*/
|
|
816
|
+
declare class SitesResource {
|
|
817
|
+
private readonly http;
|
|
818
|
+
constructor(http: TheatricalHTTPClient);
|
|
819
|
+
/**
|
|
820
|
+
* List all cinema sites, with optional search query or geographic filter.
|
|
821
|
+
* Response is validated at runtime using Zod.
|
|
822
|
+
*
|
|
823
|
+
* @param filters - Optional filters: `query` (text search), `latitude`/`longitude`/`radius`
|
|
824
|
+
* @returns Array of cinema sites
|
|
825
|
+
* @throws {TheatricalError} When the API returns an error response
|
|
826
|
+
* @throws {z.ZodError} When the response fails schema validation
|
|
827
|
+
*
|
|
828
|
+
* @example
|
|
829
|
+
* ```typescript
|
|
830
|
+
* const sites = await client.sites.list({ query: 'Embassy' });
|
|
831
|
+
* ```
|
|
832
|
+
*/
|
|
833
|
+
list(filters?: {
|
|
834
|
+
query?: string;
|
|
835
|
+
latitude?: number;
|
|
836
|
+
longitude?: number;
|
|
837
|
+
radius?: number;
|
|
838
|
+
}): Promise<Site[]>;
|
|
839
|
+
/**
|
|
840
|
+
* Get a single cinema site by ID.
|
|
841
|
+
* Response is validated at runtime using Zod.
|
|
842
|
+
*
|
|
843
|
+
* @param siteId - Vista site identifier
|
|
844
|
+
* @returns The site record
|
|
845
|
+
*
|
|
846
|
+
* @example
|
|
847
|
+
* ```typescript
|
|
848
|
+
* const roxy = await client.sites.get('site_roxy_wellington');
|
|
849
|
+
* console.log(roxy.screens.length); // number of auditoriums
|
|
850
|
+
* ```
|
|
851
|
+
*/
|
|
852
|
+
get(siteId: string): Promise<Site>;
|
|
853
|
+
/**
|
|
854
|
+
* Get the screen (auditorium) configurations for a site.
|
|
855
|
+
* Returns each screen's capacity, supported formats, and accessibility status.
|
|
856
|
+
* Response is validated at runtime using Zod.
|
|
857
|
+
*
|
|
858
|
+
* @param siteId - Vista site identifier
|
|
859
|
+
* @returns Array of screen configurations
|
|
860
|
+
*
|
|
861
|
+
* @example
|
|
862
|
+
* ```typescript
|
|
863
|
+
* const screens = await client.sites.screens('site_embassy_wellington');
|
|
864
|
+
* const imax = screens.find(s => s.formats.includes('IMAX'));
|
|
865
|
+
* ```
|
|
866
|
+
*/
|
|
867
|
+
screens(siteId: string): Promise<Screen[]>;
|
|
868
|
+
/**
|
|
869
|
+
* Find cinema sites within a geographic radius.
|
|
870
|
+
*
|
|
871
|
+
* Returns sites sorted by distance from the given coordinates.
|
|
872
|
+
* Uses Vista's OCAPI geographic search which accepts decimal lat/lng
|
|
873
|
+
* and a radius in kilometres.
|
|
874
|
+
*
|
|
875
|
+
* @param latitude - Decimal latitude of the search centre (−90 to 90)
|
|
876
|
+
* @param longitude - Decimal longitude of the search centre (−180 to 180)
|
|
877
|
+
* @param radiusKm - Search radius in kilometres
|
|
878
|
+
* @returns Sites within the radius, sorted nearest-first
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* ```typescript
|
|
882
|
+
* // Find cinemas within 5 km of Roxy Cinema Wellington
|
|
883
|
+
* const nearby = await client.sites.nearby(-41.3007, 174.7766, 5);
|
|
884
|
+
* console.log(nearby.map(s => s.name));
|
|
885
|
+
* ```
|
|
886
|
+
*
|
|
887
|
+
* @example Discover cinemas near central Auckland
|
|
888
|
+
* ```typescript
|
|
889
|
+
* const auckland = await client.sites.nearby(-36.8509, 174.7645, 10);
|
|
890
|
+
* ```
|
|
891
|
+
*/
|
|
892
|
+
nearby(latitude: number, longitude: number, radiusKm: number): Promise<Site[]>;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/** Bounded genre enum. Unknown values from Vista's API indicate the schema needs updating. */
|
|
896
|
+
declare const GENRES: readonly ["action", "adventure", "animation", "comedy", "crime", "documentary", "drama", "family", "fantasy", "horror", "musical", "mystery", "romance", "sci-fi", "thriller", "war", "western"];
|
|
897
|
+
type Genre = typeof GENRES[number];
|
|
898
|
+
/** Bounded screening format enum. */
|
|
899
|
+
declare const FILM_FORMATS: readonly ["2D", "3D", "IMAX", "IMAX 3D", "4DX", "Dolby Atmos", "ScreenX"];
|
|
900
|
+
type FilmFormat = typeof FILM_FORMATS[number];
|
|
901
|
+
/** Bounded language code enum (BCP-47 subset for NZ market). */
|
|
902
|
+
declare const FILM_LANGUAGES: readonly ["en", "es", "fr", "de", "ja", "ko", "zh", "hi", "te", "mi"];
|
|
903
|
+
type FilmLanguage = typeof FILM_LANGUAGES[number];
|
|
904
|
+
/**
|
|
905
|
+
* Age classification rating (e.g., NZ: G, PG, M, R13, R16, R18;
|
|
906
|
+
* US: G, PG, PG-13, R, NC-17).
|
|
907
|
+
*/
|
|
908
|
+
interface Rating {
|
|
909
|
+
/** Rating classification code (e.g., 'M', 'PG-13', 'R16') */
|
|
910
|
+
classification: string;
|
|
911
|
+
/** Human-readable content advisory (e.g., 'Violence, offensive language') */
|
|
912
|
+
description?: string;
|
|
913
|
+
}
|
|
914
|
+
/** An actor appearing in the film */
|
|
915
|
+
interface CastMember {
|
|
916
|
+
/** Full name of the actor */
|
|
917
|
+
name: string;
|
|
918
|
+
/** Character name or role description */
|
|
919
|
+
role?: string;
|
|
920
|
+
}
|
|
921
|
+
/** A crew member (director, writer, cinematographer, etc.) */
|
|
922
|
+
interface CrewMember {
|
|
923
|
+
name: string;
|
|
924
|
+
department: string;
|
|
925
|
+
job: string;
|
|
926
|
+
}
|
|
927
|
+
/** A rating from a specific source (IMDB, Rotten Tomatoes, Metacritic, etc.) */
|
|
928
|
+
interface FilmRating {
|
|
929
|
+
source: string;
|
|
930
|
+
score: string;
|
|
931
|
+
outOf?: string;
|
|
932
|
+
}
|
|
933
|
+
/**
|
|
934
|
+
* A film available for screening — core list representation.
|
|
935
|
+
*
|
|
936
|
+
* This is the shape returned by list endpoints (`nowShowing`, `comingSoon`, `search`).
|
|
937
|
+
* For full detail including crew, ratings, and formats, use `FilmDetail` via `getDetail()`.
|
|
938
|
+
*/
|
|
939
|
+
interface Film {
|
|
940
|
+
/** Unique film identifier (UUID) */
|
|
941
|
+
id: string;
|
|
942
|
+
/** Display title in the local market */
|
|
943
|
+
title: string;
|
|
944
|
+
/** Marketing synopsis / plot summary */
|
|
945
|
+
synopsis: string;
|
|
946
|
+
/** Genre classifications */
|
|
947
|
+
genres: Genre[];
|
|
948
|
+
/** Runtime in minutes */
|
|
949
|
+
runtime: number;
|
|
950
|
+
/** Age classification rating */
|
|
951
|
+
rating: Rating;
|
|
952
|
+
/** Theatrical release date (ISO 8601 date string) */
|
|
953
|
+
releaseDate: string;
|
|
954
|
+
/** URL to the film's poster image */
|
|
955
|
+
posterUrl?: string;
|
|
956
|
+
/** URL to the official trailer */
|
|
957
|
+
trailerUrl?: string;
|
|
958
|
+
/** Principal cast members */
|
|
959
|
+
cast: CastMember[];
|
|
960
|
+
/** Primary director name */
|
|
961
|
+
director: string;
|
|
962
|
+
/** Distribution company */
|
|
963
|
+
distributor?: string;
|
|
964
|
+
/** Whether the film is currently screening */
|
|
965
|
+
isNowShowing: boolean;
|
|
966
|
+
/** Whether the film is announced but not yet released */
|
|
967
|
+
isComingSoon: boolean;
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Full film detail — returned by `films.getDetail(id)`.
|
|
971
|
+
*
|
|
972
|
+
* Extends the base Film with crew, multiple rating sources,
|
|
973
|
+
* available formats, language options, and production metadata.
|
|
974
|
+
*/
|
|
975
|
+
interface FilmDetail extends Film {
|
|
976
|
+
crew: CrewMember[];
|
|
977
|
+
ratings: FilmRating[];
|
|
978
|
+
formats: FilmFormat[];
|
|
979
|
+
languages: FilmLanguage[];
|
|
980
|
+
originalTitle?: string;
|
|
981
|
+
productionCountries?: string[];
|
|
982
|
+
budget?: number;
|
|
983
|
+
boxOffice?: number;
|
|
984
|
+
website?: string;
|
|
985
|
+
}
|
|
986
|
+
/** Basic filter options for film list and search endpoints */
|
|
987
|
+
interface FilmFilter {
|
|
988
|
+
/** Restrict results to a specific cinema site */
|
|
989
|
+
siteId?: string;
|
|
990
|
+
/** Filter by genre classification */
|
|
991
|
+
genre?: Genre;
|
|
992
|
+
/** Free-text search across title and synopsis */
|
|
993
|
+
query?: string;
|
|
994
|
+
/** Only return films currently screening */
|
|
995
|
+
nowShowing?: boolean;
|
|
996
|
+
/** Only return upcoming / announced films */
|
|
997
|
+
comingSoon?: boolean;
|
|
998
|
+
/** Maximum number of results to return */
|
|
999
|
+
limit?: number;
|
|
1000
|
+
/** Offset for pagination */
|
|
1001
|
+
offset?: number;
|
|
1002
|
+
}
|
|
1003
|
+
/**
|
|
1004
|
+
* Extended search filters for `films.advancedSearch()`.
|
|
1005
|
+
*
|
|
1006
|
+
* Adds format, language, rating, runtime range, date range, and sorting
|
|
1007
|
+
* on top of the base FilmFilter fields.
|
|
1008
|
+
*/
|
|
1009
|
+
interface FilmSearchFilter extends FilmFilter {
|
|
1010
|
+
/** Filter by age rating classification (e.g., 'PG', 'M', 'R16') */
|
|
1011
|
+
ratingClassification?: string;
|
|
1012
|
+
/** Filter by screening format (e.g., 'IMAX', '3D', 'Dolby Atmos') */
|
|
1013
|
+
format?: FilmFormat;
|
|
1014
|
+
/** Filter by audio/subtitle language (ISO 639-1 code) */
|
|
1015
|
+
language?: FilmLanguage;
|
|
1016
|
+
/** Films released on or after this date (ISO 8601) */
|
|
1017
|
+
releaseDateFrom?: string;
|
|
1018
|
+
/** Films released on or before this date (ISO 8601) */
|
|
1019
|
+
releaseDateTo?: string;
|
|
1020
|
+
/** Minimum runtime in minutes */
|
|
1021
|
+
minRuntime?: number;
|
|
1022
|
+
/** Maximum runtime in minutes */
|
|
1023
|
+
maxRuntime?: number;
|
|
1024
|
+
/** Sort field */
|
|
1025
|
+
sortBy?: 'title' | 'releaseDate' | 'runtime' | 'popularity';
|
|
1026
|
+
/** Sort direction */
|
|
1027
|
+
sortOrder?: 'asc' | 'desc';
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Films resource — now showing, coming soon, search, and detailed film information.
|
|
1032
|
+
*
|
|
1033
|
+
* Provides access to the Vista OCAPI film catalogue. Supports browsing
|
|
1034
|
+
* current and upcoming releases, searching with rich filters (genre, format,
|
|
1035
|
+
* language, rating, runtime), and retrieving full film detail including
|
|
1036
|
+
* cast, crew, and ratings from multiple sources.
|
|
1037
|
+
*/
|
|
1038
|
+
declare class FilmsResource {
|
|
1039
|
+
private readonly http;
|
|
1040
|
+
constructor(http: TheatricalHTTPClient);
|
|
1041
|
+
/**
|
|
1042
|
+
* Parse and validate a raw film response from the API.
|
|
1043
|
+
* Throws a ZodError if the response doesn't match the expected shape.
|
|
1044
|
+
*/
|
|
1045
|
+
private parseFilm;
|
|
1046
|
+
/**
|
|
1047
|
+
* Parse and validate an array of films from the API.
|
|
1048
|
+
*/
|
|
1049
|
+
private parseFilms;
|
|
1050
|
+
/**
|
|
1051
|
+
* Parse and validate a full film detail response.
|
|
1052
|
+
*/
|
|
1053
|
+
private parseFilmDetail;
|
|
1054
|
+
/**
|
|
1055
|
+
* List films currently showing at a given site (or across all sites).
|
|
1056
|
+
*
|
|
1057
|
+
* @param filters - Optional site filter
|
|
1058
|
+
* @returns Array of films currently in cinemas
|
|
1059
|
+
*/
|
|
1060
|
+
nowShowing(filters?: {
|
|
1061
|
+
siteId?: string;
|
|
1062
|
+
}): Promise<Film[]>;
|
|
1063
|
+
/**
|
|
1064
|
+
* List films coming soon — announced but not yet in cinemas.
|
|
1065
|
+
*
|
|
1066
|
+
* @param filters - Optional site filter
|
|
1067
|
+
* @returns Array of upcoming films
|
|
1068
|
+
*/
|
|
1069
|
+
comingSoon(filters?: {
|
|
1070
|
+
siteId?: string;
|
|
1071
|
+
}): Promise<Film[]>;
|
|
1072
|
+
/**
|
|
1073
|
+
* Retrieve a film by its unique identifier.
|
|
1074
|
+
*
|
|
1075
|
+
* @param filmId - The UUID of the film
|
|
1076
|
+
* @returns The base film record
|
|
1077
|
+
*/
|
|
1078
|
+
get(filmId: string): Promise<Film>;
|
|
1079
|
+
/**
|
|
1080
|
+
* Retrieve full film detail including cast, crew, ratings, formats, and languages.
|
|
1081
|
+
*
|
|
1082
|
+
* This returns the extended `FilmDetail` type with nested crew arrays,
|
|
1083
|
+
* multiple rating sources (IMDB, Rotten Tomatoes, Metacritic), available
|
|
1084
|
+
* screening formats, and language options.
|
|
1085
|
+
*
|
|
1086
|
+
* @param filmId - The UUID of the film
|
|
1087
|
+
* @returns Full film detail with cast, crew, and ratings
|
|
1088
|
+
*/
|
|
1089
|
+
getDetail(filmId: string): Promise<FilmDetail>;
|
|
1090
|
+
/**
|
|
1091
|
+
* Search films with basic filters.
|
|
1092
|
+
*
|
|
1093
|
+
* @throws {TheatricalError} When the API returns an error response
|
|
1094
|
+
* @throws {z.ZodError} When the response fails schema validation
|
|
1095
|
+
* @param filters - Genre, query string, site, and showing status filters
|
|
1096
|
+
* @returns Array of matching films
|
|
1097
|
+
*/
|
|
1098
|
+
search(filters: FilmFilter): Promise<Film[]>;
|
|
1099
|
+
/**
|
|
1100
|
+
* Advanced film search with extended filters.
|
|
1101
|
+
*
|
|
1102
|
+
* Supports filtering by format (IMAX, 3D, Dolby Atmos), language,
|
|
1103
|
+
* rating classification, runtime range, release date range, and sorting.
|
|
1104
|
+
*
|
|
1105
|
+
* @param filters - Extended search filters including format, language, runtime range, sorting
|
|
1106
|
+
* @returns Array of matching films
|
|
1107
|
+
*/
|
|
1108
|
+
advancedSearch(filters: FilmSearchFilter): Promise<Film[]>;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
/**
|
|
1112
|
+
* Represents the lifecycle state of a cinema booking order.
|
|
1113
|
+
*
|
|
1114
|
+
* State transitions follow a strict flow:
|
|
1115
|
+
* ```
|
|
1116
|
+
* draft → pending → confirmed → completed
|
|
1117
|
+
* ↗ held ↗ ↘ cancelled
|
|
1118
|
+
* confirmed → refunded
|
|
1119
|
+
* ```
|
|
1120
|
+
*
|
|
1121
|
+
* The `held` state is a Vista-specific pause: seats are reserved but payment not yet initiated.
|
|
1122
|
+
* A held order transitions to `pending` when the hold window elapses or the caller invokes release.
|
|
1123
|
+
*/
|
|
1124
|
+
type OrderStatus = 'draft' | 'pending' | 'held' | 'confirmed' | 'completed' | 'cancelled' | 'refunded';
|
|
1125
|
+
/** A single ticket within a booking order */
|
|
1126
|
+
interface Ticket {
|
|
1127
|
+
id: string;
|
|
1128
|
+
type: string;
|
|
1129
|
+
seatId: string;
|
|
1130
|
+
seatLabel: string;
|
|
1131
|
+
price: number;
|
|
1132
|
+
discount?: number;
|
|
1133
|
+
}
|
|
1134
|
+
/** A concession or merchandise item added to an order */
|
|
1135
|
+
interface OrderItem {
|
|
1136
|
+
id: string;
|
|
1137
|
+
name: string;
|
|
1138
|
+
category: string;
|
|
1139
|
+
quantity: number;
|
|
1140
|
+
unitPrice: number;
|
|
1141
|
+
totalPrice: number;
|
|
1142
|
+
}
|
|
1143
|
+
/** A booking order — the transactional core of the cinema experience */
|
|
1144
|
+
interface Order {
|
|
1145
|
+
id: string;
|
|
1146
|
+
sessionId: string;
|
|
1147
|
+
status: OrderStatus;
|
|
1148
|
+
tickets: Ticket[];
|
|
1149
|
+
items: OrderItem[];
|
|
1150
|
+
subtotal: number;
|
|
1151
|
+
tax: number;
|
|
1152
|
+
discount: number;
|
|
1153
|
+
total: number;
|
|
1154
|
+
currency: string;
|
|
1155
|
+
loyaltyMemberId?: string;
|
|
1156
|
+
loyaltyPointsEarned?: number;
|
|
1157
|
+
loyaltyPointsRedeemed?: number;
|
|
1158
|
+
createdAt: string;
|
|
1159
|
+
updatedAt?: string;
|
|
1160
|
+
/** ISO timestamp when the order entered the `held` state */
|
|
1161
|
+
heldAt?: string;
|
|
1162
|
+
/** ISO timestamp when the hold expires — after this the order auto-transitions to `pending` */
|
|
1163
|
+
heldUntil?: string;
|
|
1164
|
+
confirmedAt?: string;
|
|
1165
|
+
completedAt?: string;
|
|
1166
|
+
cancelledAt?: string;
|
|
1167
|
+
refundedAt?: string;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Input for replacing tickets on a draft order.
|
|
1171
|
+
*
|
|
1172
|
+
* Call `orders.addTickets()` after creating a draft order to assign specific seats.
|
|
1173
|
+
* The Vista OCAPI replaces all existing tickets on the order — include every desired
|
|
1174
|
+
* ticket in a single call to avoid partial state.
|
|
1175
|
+
*/
|
|
1176
|
+
interface AddTicketsInput {
|
|
1177
|
+
tickets: Array<{
|
|
1178
|
+
/** Ticket category — e.g. `'adult'`, `'child'`, `'senior'` */
|
|
1179
|
+
type: string;
|
|
1180
|
+
/** Seat ID from the session availability response */
|
|
1181
|
+
seatId: string;
|
|
1182
|
+
}>;
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Input for adding concession or merchandise items to an order.
|
|
1186
|
+
*
|
|
1187
|
+
* Items can be added at any point before the order is confirmed.
|
|
1188
|
+
* Duplicate `menuItemId` entries are merged — quantities accumulate.
|
|
1189
|
+
*/
|
|
1190
|
+
interface AddItemsInput {
|
|
1191
|
+
items: Array<{
|
|
1192
|
+
/** Menu item ID from the F&B menu response */
|
|
1193
|
+
menuItemId: string;
|
|
1194
|
+
/** Number of units to add (must be ≥ 1) */
|
|
1195
|
+
quantity: number;
|
|
1196
|
+
}>;
|
|
1197
|
+
}
|
|
1198
|
+
/**
|
|
1199
|
+
* Input for applying a loyalty account to an order.
|
|
1200
|
+
*
|
|
1201
|
+
* Attaches a loyalty member to earn points on the purchase. Optionally redeems
|
|
1202
|
+
* accumulated points to reduce the order total — Vista enforces per-transaction
|
|
1203
|
+
* redemption limits based on the member's tier.
|
|
1204
|
+
*/
|
|
1205
|
+
interface ApplyLoyaltyInput {
|
|
1206
|
+
/** Loyalty member ID to attach to this order */
|
|
1207
|
+
memberId: string;
|
|
1208
|
+
/** Number of loyalty points to redeem — reduces order total at ~1pt = $0.01 NZD */
|
|
1209
|
+
pointsToRedeem?: number;
|
|
1210
|
+
}
|
|
1211
|
+
/** Filter parameters for querying order history */
|
|
1212
|
+
interface OrderHistoryFilter {
|
|
1213
|
+
/** Filter by order status */
|
|
1214
|
+
status?: OrderStatus;
|
|
1215
|
+
/** ISO date string — orders created after this date */
|
|
1216
|
+
since?: string;
|
|
1217
|
+
/** ISO date string — orders created before this date */
|
|
1218
|
+
until?: string;
|
|
1219
|
+
/** Maximum number of results to return */
|
|
1220
|
+
limit?: number;
|
|
1221
|
+
/** Pagination cursor from a previous response */
|
|
1222
|
+
cursor?: string;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/**
|
|
1226
|
+
* Input for creating a new draft order.
|
|
1227
|
+
*
|
|
1228
|
+
* A draft order locks the requested seats for a short window (typically 10 minutes)
|
|
1229
|
+
* while the customer completes checkout. If the order is not confirmed within that
|
|
1230
|
+
* window, Vista automatically cancels it and releases the seats.
|
|
1231
|
+
*
|
|
1232
|
+
* @example
|
|
1233
|
+
* ```typescript
|
|
1234
|
+
* const order = await client.orders.create({
|
|
1235
|
+
* sessionId: 'sess_abc123',
|
|
1236
|
+
* tickets: [
|
|
1237
|
+
* { type: 'adult', seatId: 'seat_d5' },
|
|
1238
|
+
* { type: 'child', seatId: 'seat_d6' },
|
|
1239
|
+
* ],
|
|
1240
|
+
* loyaltyMemberId: 'mem_xyz',
|
|
1241
|
+
* });
|
|
1242
|
+
* ```
|
|
1243
|
+
*/
|
|
1244
|
+
interface CreateOrderInput {
|
|
1245
|
+
/** ID of the session (showtime) to book */
|
|
1246
|
+
sessionId: string;
|
|
1247
|
+
/** Tickets to reserve — each entry specifies a ticket type and the seat to assign */
|
|
1248
|
+
tickets: Array<{
|
|
1249
|
+
/** Ticket category — e.g. `'adult'`, `'child'`, `'senior'`, `'concession'` */
|
|
1250
|
+
type: string;
|
|
1251
|
+
/** Seat ID from the availability response (e.g. `'seat_d5'`) */
|
|
1252
|
+
seatId: string;
|
|
1253
|
+
}>;
|
|
1254
|
+
/** Optional concession or merchandise items to include at order creation time */
|
|
1255
|
+
items?: Array<{
|
|
1256
|
+
menuItemId: string;
|
|
1257
|
+
quantity: number;
|
|
1258
|
+
}>;
|
|
1259
|
+
/** Loyalty member ID — attach to earn points on this booking */
|
|
1260
|
+
loyaltyMemberId?: string;
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Orders resource — the full booking lifecycle.
|
|
1264
|
+
*
|
|
1265
|
+
* Covers the entire booking flow for Vista OCAPI:
|
|
1266
|
+
* create → add tickets → optionally add F&B → apply loyalty → confirm → complete.
|
|
1267
|
+
* Orders can also be cancelled or refunded depending on their current state.
|
|
1268
|
+
*
|
|
1269
|
+
* All responses are validated at runtime using Zod schemas to ensure
|
|
1270
|
+
* the API response matches the expected shape before reaching application code.
|
|
1271
|
+
*/
|
|
1272
|
+
declare class OrdersResource {
|
|
1273
|
+
private readonly http;
|
|
1274
|
+
constructor(http: TheatricalHTTPClient);
|
|
1275
|
+
/**
|
|
1276
|
+
* Parse and validate a raw order response from the API.
|
|
1277
|
+
* Throws a ZodError if the response doesn't match the expected shape.
|
|
1278
|
+
*/
|
|
1279
|
+
private parseOrder;
|
|
1280
|
+
/**
|
|
1281
|
+
* Parse and validate a paginated order response from the API.
|
|
1282
|
+
*/
|
|
1283
|
+
private parsePaginatedOrders;
|
|
1284
|
+
/**
|
|
1285
|
+
* Create a new draft order for a session.
|
|
1286
|
+
*
|
|
1287
|
+
* @throws {TheatricalError} When the API returns an error response
|
|
1288
|
+
* @throws {z.ZodError} When the response fails schema validation
|
|
1289
|
+
* @param input - Session ID, initial tickets, optional F * @param input - Session ID, initial tickets, optional F&B items, optional loyalty memberB items, optional loyalty member
|
|
1290
|
+
* @returns The newly created order in 'draft' status
|
|
1291
|
+
*/
|
|
1292
|
+
create(input: CreateOrderInput): Promise<Order>;
|
|
1293
|
+
/**
|
|
1294
|
+
* Retrieve an order by its unique identifier.
|
|
1295
|
+
*
|
|
1296
|
+
* @param orderId - The UUID of the order to retrieve
|
|
1297
|
+
*/
|
|
1298
|
+
get(orderId: string): Promise<Order>;
|
|
1299
|
+
/**
|
|
1300
|
+
* Set tickets on a draft order. Each ticket specifies a seat and ticket type.
|
|
1301
|
+
* The Vista OCAPI replaces all existing tickets — pass the full desired set in one call.
|
|
1302
|
+
*
|
|
1303
|
+
* @param orderId - The UUID of the draft order
|
|
1304
|
+
* @param input - Tickets to set (replaces any previously assigned tickets)
|
|
1305
|
+
* @returns The updated order with the new ticket set
|
|
1306
|
+
*/
|
|
1307
|
+
addTickets(orderId: string, input: AddTicketsInput): Promise<Order>;
|
|
1308
|
+
/**
|
|
1309
|
+
* Add concession or merchandise items to an order.
|
|
1310
|
+
* F&B items can be added to orders in 'draft' or 'pending' status.
|
|
1311
|
+
*
|
|
1312
|
+
* @param orderId - The UUID of the order
|
|
1313
|
+
* @param input - Items to add (menuItemId + quantity pairs)
|
|
1314
|
+
* @returns The updated order with new items included
|
|
1315
|
+
*/
|
|
1316
|
+
addItems(orderId: string, input: AddItemsInput): Promise<Order>;
|
|
1317
|
+
/**
|
|
1318
|
+
* Confirm an order, transitioning it from 'pending' to 'confirmed'.
|
|
1319
|
+
* This locks in the seat selection and pricing.
|
|
1320
|
+
*
|
|
1321
|
+
* @param orderId - The UUID of the order to confirm
|
|
1322
|
+
*/
|
|
1323
|
+
confirm(orderId: string): Promise<Order>;
|
|
1324
|
+
/**
|
|
1325
|
+
* Cancel an order. Can be applied to 'pending' or 'confirmed' orders.
|
|
1326
|
+
* Releases any held seats back to the pool.
|
|
1327
|
+
*
|
|
1328
|
+
* @param orderId - The UUID of the order to cancel
|
|
1329
|
+
*/
|
|
1330
|
+
cancel(orderId: string): Promise<Order>;
|
|
1331
|
+
/**
|
|
1332
|
+
* Apply a loyalty membership discount to an order.
|
|
1333
|
+
* Links the member to the order and optionally redeems loyalty points
|
|
1334
|
+
* for a discount on the total.
|
|
1335
|
+
*
|
|
1336
|
+
* @param orderId - The UUID of the order
|
|
1337
|
+
* @param input - Loyalty member ID and optional points to redeem
|
|
1338
|
+
* @returns The updated order with loyalty discount applied
|
|
1339
|
+
*/
|
|
1340
|
+
applyLoyalty(orderId: string, input: ApplyLoyaltyInput): Promise<Order>;
|
|
1341
|
+
/**
|
|
1342
|
+
* Request a refund for a confirmed or completed order.
|
|
1343
|
+
* Triggers the refund workflow in Vista's payment system.
|
|
1344
|
+
*
|
|
1345
|
+
* @param orderId - The UUID of the order to refund
|
|
1346
|
+
*/
|
|
1347
|
+
refund(orderId: string): Promise<Order>;
|
|
1348
|
+
/**
|
|
1349
|
+
* Mark a confirmed order as completed (e.g., after the screening).
|
|
1350
|
+
*
|
|
1351
|
+
* @param orderId - The UUID of the confirmed order
|
|
1352
|
+
*/
|
|
1353
|
+
complete(orderId: string): Promise<Order>;
|
|
1354
|
+
/**
|
|
1355
|
+
* Retrieve order history for a loyalty member.
|
|
1356
|
+
* Returns a paginated list of orders, newest first.
|
|
1357
|
+
*
|
|
1358
|
+
* @param memberId - The loyalty member's unique identifier
|
|
1359
|
+
* @param filter - Optional filters for status, date range, and pagination
|
|
1360
|
+
*/
|
|
1361
|
+
history(memberId: string, filter?: OrderHistoryFilter): Promise<PaginatedResponse<Order>>;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
/** Loyalty tier levels available in Vista cinema programs. */
|
|
1365
|
+
type LoyaltyTierName = 'Bronze' | 'Silver' | 'Gold' | 'Platinum';
|
|
1366
|
+
/** A loyalty program tier with benefits and point thresholds. */
|
|
1367
|
+
interface LoyaltyTier {
|
|
1368
|
+
id: string;
|
|
1369
|
+
name: LoyaltyTierName;
|
|
1370
|
+
/** Numeric rank: 1 = Bronze … 4 = Platinum */
|
|
1371
|
+
level: number;
|
|
1372
|
+
benefits: string[];
|
|
1373
|
+
/** Lifetime points required to reach this tier. */
|
|
1374
|
+
pointsThreshold: number;
|
|
1375
|
+
}
|
|
1376
|
+
/** A loyalty program member. */
|
|
1377
|
+
interface LoyaltyMember {
|
|
1378
|
+
id: string;
|
|
1379
|
+
email: string;
|
|
1380
|
+
firstName: string;
|
|
1381
|
+
lastName: string;
|
|
1382
|
+
tier: LoyaltyTier;
|
|
1383
|
+
/** Current redeemable points balance. */
|
|
1384
|
+
points: number;
|
|
1385
|
+
/** All-time accumulated points (never decremented). */
|
|
1386
|
+
lifetimePoints: number;
|
|
1387
|
+
memberSince: string;
|
|
1388
|
+
/** Linked subscription plan ID, if any. */
|
|
1389
|
+
subscriptionId?: string;
|
|
1390
|
+
/** ISO-8601 date of most recent transaction. */
|
|
1391
|
+
lastActivityDate?: string;
|
|
1392
|
+
/** Whether the member account is currently active. */
|
|
1393
|
+
active: boolean;
|
|
1394
|
+
}
|
|
1395
|
+
/** A single points earn or redeem transaction. */
|
|
1396
|
+
interface PointsTransaction {
|
|
1397
|
+
id: string;
|
|
1398
|
+
memberId: string;
|
|
1399
|
+
type: 'earn' | 'redeem' | 'adjust' | 'expire';
|
|
1400
|
+
points: number;
|
|
1401
|
+
/** Signed net change — negative for redemptions and expirations. */
|
|
1402
|
+
balanceAfter: number;
|
|
1403
|
+
description: string;
|
|
1404
|
+
/** ISO-8601 datetime */
|
|
1405
|
+
createdAt: string;
|
|
1406
|
+
/** Order reference for earn/redeem transactions, if applicable. */
|
|
1407
|
+
orderId?: string;
|
|
1408
|
+
/** Cinema site reference, if applicable. */
|
|
1409
|
+
siteId?: string;
|
|
1410
|
+
}
|
|
1411
|
+
/** An option that members can redeem points for. */
|
|
1412
|
+
interface RedemptionOption {
|
|
1413
|
+
id: string;
|
|
1414
|
+
name: string;
|
|
1415
|
+
description: string;
|
|
1416
|
+
/** Points cost to redeem. */
|
|
1417
|
+
pointsCost: number;
|
|
1418
|
+
category: 'ticket' | 'concession' | 'upgrade' | 'merchandise';
|
|
1419
|
+
/** Whether the option is currently available. */
|
|
1420
|
+
available: boolean;
|
|
1421
|
+
/** ISO-8601 expiry date of the offer, if limited. */
|
|
1422
|
+
expiresAt?: string;
|
|
1423
|
+
}
|
|
1424
|
+
/** Input payload for redeeming points against an option. */
|
|
1425
|
+
interface RedeemPointsInput {
|
|
1426
|
+
optionId: string;
|
|
1427
|
+
/** Order to apply the redemption to, if applicable. */
|
|
1428
|
+
orderId?: string;
|
|
1429
|
+
/** Quantity of the option to redeem (default 1). */
|
|
1430
|
+
quantity?: number;
|
|
1431
|
+
}
|
|
1432
|
+
/** Filters for querying a member's transaction history. */
|
|
1433
|
+
interface PointsHistoryFilter {
|
|
1434
|
+
type?: PointsTransaction['type'];
|
|
1435
|
+
/** ISO-8601 start date (inclusive) */
|
|
1436
|
+
from?: string;
|
|
1437
|
+
/** ISO-8601 end date (inclusive) */
|
|
1438
|
+
to?: string;
|
|
1439
|
+
limit?: number;
|
|
1440
|
+
offset?: number;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* Loyalty resource — member management, points, tiers.
|
|
1445
|
+
*
|
|
1446
|
+
* Wraps the Vista OCAPI loyalty endpoints for full member lifecycle management:
|
|
1447
|
+
* authentication, balance queries, transaction history, and points redemption.
|
|
1448
|
+
*/
|
|
1449
|
+
declare class LoyaltyResource {
|
|
1450
|
+
private readonly http;
|
|
1451
|
+
constructor(http: TheatricalHTTPClient);
|
|
1452
|
+
/**
|
|
1453
|
+
* Fetch a loyalty member by their unique ID.
|
|
1454
|
+
*
|
|
1455
|
+
* @param memberId - Vista loyalty member identifier
|
|
1456
|
+
* @throws {TheatricalError} When the API returns an error response
|
|
1457
|
+
*/
|
|
1458
|
+
getMember(memberId: string): Promise<LoyaltyMember>;
|
|
1459
|
+
/**
|
|
1460
|
+
* Authenticate a member using their email address and password (cookie-based
|
|
1461
|
+
* session). Returns the authenticated member record on success.
|
|
1462
|
+
*
|
|
1463
|
+
* @param email - Member's registered email
|
|
1464
|
+
* @param password - Account password (transmitted over TLS)
|
|
1465
|
+
*/
|
|
1466
|
+
authenticate(email: string, password: string): Promise<LoyaltyMember>;
|
|
1467
|
+
/**
|
|
1468
|
+
* Return the current redeemable points balance for a member.
|
|
1469
|
+
*
|
|
1470
|
+
* @param memberId - Vista loyalty member identifier
|
|
1471
|
+
*/
|
|
1472
|
+
getPointsBalance(memberId: string): Promise<{
|
|
1473
|
+
points: number;
|
|
1474
|
+
lifetimePoints: number;
|
|
1475
|
+
}>;
|
|
1476
|
+
/**
|
|
1477
|
+
* Retrieve a paginated transaction history for a member.
|
|
1478
|
+
*
|
|
1479
|
+
* @param memberId - Vista loyalty member identifier
|
|
1480
|
+
* @param filter - Optional date range, type, and pagination filters
|
|
1481
|
+
*/
|
|
1482
|
+
getHistory(memberId: string, filter?: PointsHistoryFilter): Promise<PaginatedResponse<PointsTransaction>>;
|
|
1483
|
+
/**
|
|
1484
|
+
* List available redemption options for the loyalty program.
|
|
1485
|
+
* Options are filtered to those the member is eligible for based on their
|
|
1486
|
+
* tier and current points balance.
|
|
1487
|
+
*
|
|
1488
|
+
* @param memberId - Vista loyalty member identifier
|
|
1489
|
+
*/
|
|
1490
|
+
listRedemptionOptions(memberId: string): Promise<RedemptionOption[]>;
|
|
1491
|
+
/**
|
|
1492
|
+
* Redeem points against a catalog option for a member.
|
|
1493
|
+
* Deducts points from the member's balance and applies the benefit.
|
|
1494
|
+
*
|
|
1495
|
+
* @param memberId - Vista loyalty member identifier
|
|
1496
|
+
* @param input - Redemption option, optional order linkage, and quantity
|
|
1497
|
+
*/
|
|
1498
|
+
redeemPoints(memberId: string, input: RedeemPointsInput): Promise<PointsTransaction>;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
/** Billing interval for a subscription plan. */
|
|
1502
|
+
type SubscriptionInterval = 'monthly' | 'annual';
|
|
1503
|
+
/** Current lifecycle state of a member's subscription. */
|
|
1504
|
+
type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'expired' | 'pending';
|
|
1505
|
+
/** Category of a subscription benefit. */
|
|
1506
|
+
type BenefitCategory = 'booking' | 'concession' | 'companion' | 'priority' | 'exclusive';
|
|
1507
|
+
/**
|
|
1508
|
+
* A specific benefit included with a subscription plan.
|
|
1509
|
+
*
|
|
1510
|
+
* Benefits define the concrete perks of a plan beyond the base booking
|
|
1511
|
+
* allowance — e.g., companion passes, F&B discounts, priority booking windows.
|
|
1512
|
+
*/
|
|
1513
|
+
interface SubscriptionBenefit {
|
|
1514
|
+
id: string;
|
|
1515
|
+
category: BenefitCategory;
|
|
1516
|
+
name: string;
|
|
1517
|
+
description: string;
|
|
1518
|
+
/** Maximum number of times this benefit may be used per billing period. */
|
|
1519
|
+
usesPerPeriod?: number;
|
|
1520
|
+
/** Whether this benefit is currently active on the plan. */
|
|
1521
|
+
active: boolean;
|
|
1522
|
+
}
|
|
1523
|
+
/**
|
|
1524
|
+
* A subscribable cinema pass plan (e.g. Hoyts LoyaltyCinema Pass, Event Select).
|
|
1525
|
+
*
|
|
1526
|
+
* Plans define pricing, booking allowances, and the list of benefits included
|
|
1527
|
+
* for subscribers. Equivalent to AMC A-List or Cineworld Unlimited in structure.
|
|
1528
|
+
*/
|
|
1529
|
+
interface SubscriptionPlan {
|
|
1530
|
+
id: string;
|
|
1531
|
+
name: string;
|
|
1532
|
+
description: string;
|
|
1533
|
+
price: number;
|
|
1534
|
+
currency: string;
|
|
1535
|
+
interval: SubscriptionInterval;
|
|
1536
|
+
/** Number of bookings included per billing period. Undefined = unlimited. */
|
|
1537
|
+
bookingsIncluded?: number;
|
|
1538
|
+
benefits: SubscriptionBenefit[];
|
|
1539
|
+
/** Whether new subscriptions can currently be purchased. */
|
|
1540
|
+
available: boolean;
|
|
1541
|
+
/** Minimum commitment period in months (e.g. 3 for lock-in plans). */
|
|
1542
|
+
minimumTermMonths?: number;
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Usage statistics for a member's active subscription in the current period.
|
|
1546
|
+
*/
|
|
1547
|
+
interface SubscriptionUsage {
|
|
1548
|
+
subscriptionId: string;
|
|
1549
|
+
memberId: string;
|
|
1550
|
+
/** ISO-8601 start of the current billing period. */
|
|
1551
|
+
periodStart: string;
|
|
1552
|
+
/** ISO-8601 end of the current billing period. */
|
|
1553
|
+
periodEnd: string;
|
|
1554
|
+
bookingsUsed: number;
|
|
1555
|
+
/** Null when the plan has unlimited bookings. */
|
|
1556
|
+
bookingsIncluded: number | null;
|
|
1557
|
+
/** Derived: bookingsIncluded - bookingsUsed. Null for unlimited plans. */
|
|
1558
|
+
bookingsRemaining: number | null;
|
|
1559
|
+
/** Per-benefit usage counts keyed by benefit ID. */
|
|
1560
|
+
benefitUsage: Record<string, number>;
|
|
1561
|
+
}
|
|
1562
|
+
/**
|
|
1563
|
+
* A member's active or historical subscription record.
|
|
1564
|
+
*/
|
|
1565
|
+
interface MemberSubscription {
|
|
1566
|
+
id: string;
|
|
1567
|
+
planId: string;
|
|
1568
|
+
plan?: SubscriptionPlan;
|
|
1569
|
+
memberId: string;
|
|
1570
|
+
status: SubscriptionStatus;
|
|
1571
|
+
/** ISO-8601 date the subscription started. */
|
|
1572
|
+
startDate: string;
|
|
1573
|
+
/** ISO-8601 date of the next renewal. Null if cancelled or expired. */
|
|
1574
|
+
renewalDate: string | null;
|
|
1575
|
+
/** ISO-8601 date the subscription was cancelled, if applicable. */
|
|
1576
|
+
cancelledAt?: string;
|
|
1577
|
+
/** ISO-8601 date the subscription expires, if applicable. */
|
|
1578
|
+
expiresAt?: string;
|
|
1579
|
+
/** Whether auto-renewal is enabled. */
|
|
1580
|
+
autoRenew: boolean;
|
|
1581
|
+
/** Shorthand usage for current period (populated on detail views). */
|
|
1582
|
+
usage?: SubscriptionUsage;
|
|
1583
|
+
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Input for suspending a member's subscription temporarily.
|
|
1586
|
+
*/
|
|
1587
|
+
interface SuspendSubscriptionInput {
|
|
1588
|
+
/** ISO-8601 date to resume the subscription. Required for timed suspension. */
|
|
1589
|
+
resumeDate?: string;
|
|
1590
|
+
reason?: string;
|
|
1591
|
+
}
|
|
1592
|
+
/**
|
|
1593
|
+
* Input for cancelling a member's subscription.
|
|
1594
|
+
*/
|
|
1595
|
+
interface CancelSubscriptionInput {
|
|
1596
|
+
/** When true, cancel immediately. When false, cancel at end of period. */
|
|
1597
|
+
immediate?: boolean;
|
|
1598
|
+
reason?: string;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
/**
|
|
1602
|
+
* Subscriptions resource — cinema pass plans and member subscription lifecycle.
|
|
1603
|
+
*
|
|
1604
|
+
* Wraps the Vista OCAPI subscription endpoints, covering plan discovery,
|
|
1605
|
+
* member subscription state, usage tracking, benefit eligibility checks,
|
|
1606
|
+
* and administrative actions (suspend, cancel).
|
|
1607
|
+
*/
|
|
1608
|
+
declare class SubscriptionsResource {
|
|
1609
|
+
private readonly http;
|
|
1610
|
+
constructor(http: TheatricalHTTPClient);
|
|
1611
|
+
/**
|
|
1612
|
+
* List all available subscription plans for a Vista site.
|
|
1613
|
+
*
|
|
1614
|
+
* Returns only plans that are available for new subscriptions unless
|
|
1615
|
+
* {@link includeUnavailable} is set to true (useful for admin UIs).
|
|
1616
|
+
*
|
|
1617
|
+
* @param siteId - Vista site identifier to scope plans to
|
|
1618
|
+
* @param includeUnavailable - When true, include discontinued plans
|
|
1619
|
+
*/
|
|
1620
|
+
listPlans(siteId?: string, includeUnavailable?: boolean): Promise<SubscriptionPlan[]>;
|
|
1621
|
+
/**
|
|
1622
|
+
* Retrieve the active (or most recent) subscription for a member.
|
|
1623
|
+
*
|
|
1624
|
+
* @param memberId - Vista loyalty member identifier
|
|
1625
|
+
*/
|
|
1626
|
+
getMemberSubscription(memberId: string): Promise<MemberSubscription>;
|
|
1627
|
+
/**
|
|
1628
|
+
* Get usage statistics for a member's subscription in the current billing period.
|
|
1629
|
+
*
|
|
1630
|
+
* Returns booking counts, remaining allowance, and per-benefit usage.
|
|
1631
|
+
* Use this before allowing a booking to check whether the member has
|
|
1632
|
+
* bookings remaining under their plan.
|
|
1633
|
+
*
|
|
1634
|
+
* @param memberId - Vista loyalty member identifier
|
|
1635
|
+
*/
|
|
1636
|
+
getUsage(memberId: string): Promise<SubscriptionUsage>;
|
|
1637
|
+
/**
|
|
1638
|
+
* Check whether a member is eligible to use a specific benefit.
|
|
1639
|
+
*
|
|
1640
|
+
* Returns true if the benefit is included in their plan, is currently active,
|
|
1641
|
+
* and the member has remaining uses for the current period.
|
|
1642
|
+
*
|
|
1643
|
+
* @param memberId - Vista loyalty member identifier
|
|
1644
|
+
* @param benefitId - Benefit ID from the plan's benefits array
|
|
1645
|
+
*/
|
|
1646
|
+
checkBenefitEligibility(memberId: string, benefitId: string): Promise<{
|
|
1647
|
+
eligible: boolean;
|
|
1648
|
+
usesRemaining: number | null;
|
|
1649
|
+
reason?: string;
|
|
1650
|
+
}>;
|
|
1651
|
+
/**
|
|
1652
|
+
* Suspend a member's subscription temporarily.
|
|
1653
|
+
*
|
|
1654
|
+
* The subscription status transitions to `paused`. Billing is paused for the
|
|
1655
|
+
* suspension period. If {@link SuspendSubscriptionInput.resumeDate} is
|
|
1656
|
+
* provided, the subscription will auto-resume on that date; otherwise it must
|
|
1657
|
+
* be manually resumed.
|
|
1658
|
+
*
|
|
1659
|
+
* @param memberId - Vista loyalty member identifier
|
|
1660
|
+
* @param input - Optional resume date and reason
|
|
1661
|
+
*/
|
|
1662
|
+
suspend(memberId: string, input?: SuspendSubscriptionInput): Promise<MemberSubscription>;
|
|
1663
|
+
/**
|
|
1664
|
+
* Cancel a member's subscription.
|
|
1665
|
+
*
|
|
1666
|
+
* By default cancels at the end of the current billing period. Set
|
|
1667
|
+
* {@link CancelSubscriptionInput.immediate} to `true` for an immediate
|
|
1668
|
+
* cancellation with no refund.
|
|
1669
|
+
*
|
|
1670
|
+
* @param memberId - Vista loyalty member identifier
|
|
1671
|
+
* @param input - Whether to cancel immediately and optional reason
|
|
1672
|
+
*/
|
|
1673
|
+
cancel(memberId: string, input?: CancelSubscriptionInput): Promise<MemberSubscription>;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
/** Ticket type grouping — matches Vista OCAPI ticket type categories. */
|
|
1677
|
+
type TicketCategory = 'adult' | 'child' | 'senior' | 'student' | 'family' | 'concession' | 'loyalty-member';
|
|
1678
|
+
interface TicketType {
|
|
1679
|
+
id: string;
|
|
1680
|
+
name: string;
|
|
1681
|
+
description?: string;
|
|
1682
|
+
/** Base price in minor currency units (e.g., cents). */
|
|
1683
|
+
price: number;
|
|
1684
|
+
currency: string;
|
|
1685
|
+
category: TicketCategory;
|
|
1686
|
+
isDefault: boolean;
|
|
1687
|
+
requiresLoyalty: boolean;
|
|
1688
|
+
/** Minimum age for this ticket type (e.g. senior >= 65). */
|
|
1689
|
+
minimumAge?: number;
|
|
1690
|
+
/** Maximum age (e.g. child <= 14). */
|
|
1691
|
+
maximumAge?: number;
|
|
1692
|
+
/** Whether this ticket type is currently purchasable. */
|
|
1693
|
+
isAvailable: boolean;
|
|
1694
|
+
}
|
|
1695
|
+
interface TicketTypeFilter {
|
|
1696
|
+
sessionId: string;
|
|
1697
|
+
/** Filter by category (e.g., only loyalty-eligible types). */
|
|
1698
|
+
category?: TicketCategory;
|
|
1699
|
+
/** Exclude unavailable ticket types. Defaults to true. */
|
|
1700
|
+
availableOnly?: boolean;
|
|
1701
|
+
}
|
|
1702
|
+
/**
|
|
1703
|
+
* Regional tax configuration for price display.
|
|
1704
|
+
*
|
|
1705
|
+
* NZ cinema operators present tax-inclusive prices; Australian operators
|
|
1706
|
+
* sometimes break GST out separately in B2B contexts.
|
|
1707
|
+
*/
|
|
1708
|
+
interface TaxConfig {
|
|
1709
|
+
/** ISO 4217 currency code. */
|
|
1710
|
+
currency: string;
|
|
1711
|
+
/** Tax rate as a decimal fraction (e.g. 0.15 for 15% NZ GST). */
|
|
1712
|
+
rate: number;
|
|
1713
|
+
/** Label shown on receipts (e.g. "GST", "VAT"). */
|
|
1714
|
+
label: string;
|
|
1715
|
+
/**
|
|
1716
|
+
* When true, all prices are tax-inclusive (consumer-facing display).
|
|
1717
|
+
* When false, tax is added on top (B2B / booking-system context).
|
|
1718
|
+
*/
|
|
1719
|
+
inclusive: boolean;
|
|
1720
|
+
}
|
|
1721
|
+
type DiscountSource = 'loyalty-tier' | 'coupon' | 'promo' | 'member' | 'employee' | 'group';
|
|
1722
|
+
interface Discount {
|
|
1723
|
+
id: string;
|
|
1724
|
+
source: DiscountSource;
|
|
1725
|
+
/** Human-readable label (e.g. "Gold Member Discount"). */
|
|
1726
|
+
label: string;
|
|
1727
|
+
/** Discount amount in minor units. */
|
|
1728
|
+
amount: number;
|
|
1729
|
+
/** Percentage discount, 0–100. Informational only when `amount` is authoritative. */
|
|
1730
|
+
percentage?: number;
|
|
1731
|
+
/** Coupon code that triggered this discount, if applicable. */
|
|
1732
|
+
couponCode?: string;
|
|
1733
|
+
}
|
|
1734
|
+
type SurchargeReason = 'format' | 'seat-type' | 'booking-fee' | 'service-fee' | 'peak-surcharge';
|
|
1735
|
+
interface Surcharge {
|
|
1736
|
+
id: string;
|
|
1737
|
+
reason: SurchargeReason;
|
|
1738
|
+
/** Human-readable label (e.g. "IMAX Surcharge"). */
|
|
1739
|
+
label: string;
|
|
1740
|
+
/** Surcharge amount in minor units. */
|
|
1741
|
+
amount: number;
|
|
1742
|
+
}
|
|
1743
|
+
/**
|
|
1744
|
+
* Itemised price breakdown for a single ticket or a quantity of tickets.
|
|
1745
|
+
*
|
|
1746
|
+
* All amounts are in minor units of `currency` (e.g. cents for NZD).
|
|
1747
|
+
*/
|
|
1748
|
+
interface PriceBreakdown {
|
|
1749
|
+
/** Base price per ticket before adjustments. */
|
|
1750
|
+
basePrice: number;
|
|
1751
|
+
/** Ordered list of discounts applied. */
|
|
1752
|
+
discounts: Discount[];
|
|
1753
|
+
/** Ordered list of surcharges applied. */
|
|
1754
|
+
surcharges: Surcharge[];
|
|
1755
|
+
/** Tax amount. Zero when `taxConfig.inclusive` is true. */
|
|
1756
|
+
taxAmount: number;
|
|
1757
|
+
/** Sum of all discounts. */
|
|
1758
|
+
totalDiscount: number;
|
|
1759
|
+
/** Sum of all surcharges. */
|
|
1760
|
+
totalSurcharge: number;
|
|
1761
|
+
/** Per-ticket price after all adjustments. */
|
|
1762
|
+
pricePerTicket: number;
|
|
1763
|
+
/** `pricePerTicket * quantity`. */
|
|
1764
|
+
totalPrice: number;
|
|
1765
|
+
quantity: number;
|
|
1766
|
+
currency: string;
|
|
1767
|
+
taxConfig: TaxConfig;
|
|
1768
|
+
}
|
|
1769
|
+
/**
|
|
1770
|
+
* Full price calculation response from the Vista pricing engine.
|
|
1771
|
+
*
|
|
1772
|
+
* Returned by `PricingResource.calculate()`. The `breakdown` field gives
|
|
1773
|
+
* full itemisation; legacy integrations can use the flat fields.
|
|
1774
|
+
*/
|
|
1775
|
+
interface PriceCalculation {
|
|
1776
|
+
sessionId: string;
|
|
1777
|
+
ticketTypeId: string;
|
|
1778
|
+
/** Total price, minor units. */
|
|
1779
|
+
totalPrice: number;
|
|
1780
|
+
currency: string;
|
|
1781
|
+
/** Whether returned price includes tax. */
|
|
1782
|
+
taxInclusive: boolean;
|
|
1783
|
+
/** Detailed, itemised breakdown. */
|
|
1784
|
+
breakdown: PriceBreakdown;
|
|
1785
|
+
/** ISO 8601 timestamp — price is valid until this time. */
|
|
1786
|
+
validUntil: string;
|
|
1787
|
+
}
|
|
1788
|
+
interface ApplyCouponsInput {
|
|
1789
|
+
sessionId: string;
|
|
1790
|
+
ticketTypeId: string;
|
|
1791
|
+
quantity: number;
|
|
1792
|
+
couponCodes: string[];
|
|
1793
|
+
/** Loyalty member ID for tier-based discount resolution. */
|
|
1794
|
+
membershipId?: string;
|
|
1795
|
+
}
|
|
1796
|
+
interface CouponApplicationResult {
|
|
1797
|
+
applied: Discount[];
|
|
1798
|
+
rejected: Array<{
|
|
1799
|
+
code: string;
|
|
1800
|
+
reason: string;
|
|
1801
|
+
}>;
|
|
1802
|
+
updatedBreakdown: PriceBreakdown;
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
/**
|
|
1806
|
+
* Pricing resource — ticket types, price calculations, tax handling, and coupon application.
|
|
1807
|
+
*
|
|
1808
|
+
* Handles the complexity of Vista's pricing model: matinee vs peak pricing,
|
|
1809
|
+
* format surcharges (IMAX, 4DX), loyalty tier discounts, and coupon stacking.
|
|
1810
|
+
*/
|
|
1811
|
+
declare class PricingResource {
|
|
1812
|
+
private readonly http;
|
|
1813
|
+
constructor(http: TheatricalHTTPClient);
|
|
1814
|
+
/**
|
|
1815
|
+
* List available ticket types for a session.
|
|
1816
|
+
*
|
|
1817
|
+
* @param sessionId - The Vista session ID.
|
|
1818
|
+
* @param filter - Optional filter params (category, availableOnly).
|
|
1819
|
+
*/
|
|
1820
|
+
ticketTypes(sessionId: string, filter?: Omit<TicketTypeFilter, 'sessionId'>): Promise<TicketType[]>;
|
|
1821
|
+
/**
|
|
1822
|
+
* Calculate the price for a ticket type and quantity.
|
|
1823
|
+
*
|
|
1824
|
+
* Returns an itemised {@link PriceBreakdown} including base price, discounts,
|
|
1825
|
+
* surcharges, and tax. The breakdown reflects the caller's Vista site tax
|
|
1826
|
+
* configuration (inclusive vs exclusive).
|
|
1827
|
+
*
|
|
1828
|
+
* @param sessionId - The Vista session ID.
|
|
1829
|
+
* @param ticketTypeId - Ticket type to price.
|
|
1830
|
+
* @param quantity - Number of tickets (default 1).
|
|
1831
|
+
*/
|
|
1832
|
+
calculate(sessionId: string, ticketTypeId: string, quantity?: number): Promise<PriceCalculation>;
|
|
1833
|
+
/**
|
|
1834
|
+
* Apply coupon codes and resolve loyalty-tier discounts.
|
|
1835
|
+
*
|
|
1836
|
+
* Validates each coupon code, stacks applicable discounts, and returns
|
|
1837
|
+
* an updated {@link PriceBreakdown}. Invalid or expired codes are listed
|
|
1838
|
+
* in the `rejected` array rather than throwing.
|
|
1839
|
+
*
|
|
1840
|
+
* @param input - Session, ticket type, quantity, coupon codes, and optional member ID.
|
|
1841
|
+
*/
|
|
1842
|
+
applyCoupons(input: ApplyCouponsInput): Promise<CouponApplicationResult>;
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
/**
|
|
1846
|
+
* Dietary classification flags.
|
|
1847
|
+
*
|
|
1848
|
+
* Multiple flags can apply simultaneously (e.g. vegan items are also vegetarian).
|
|
1849
|
+
*/
|
|
1850
|
+
type DietaryFlag = 'vegetarian' | 'vegan' | 'gluten-free' | 'dairy-free' | 'nut-free' | 'halal' | 'kosher';
|
|
1851
|
+
/** Broad menu section groupings used for candy-bar display ordering. */
|
|
1852
|
+
type MenuSectionType = 'hot-food' | 'cold-food' | 'drinks' | 'combos' | 'snacks' | 'ice-cream' | 'alcohol';
|
|
1853
|
+
interface MenuCategory {
|
|
1854
|
+
id: string;
|
|
1855
|
+
name: string;
|
|
1856
|
+
sectionType: MenuSectionType;
|
|
1857
|
+
/** Display rank — lower numbers appear first in UI. */
|
|
1858
|
+
displayOrder: number;
|
|
1859
|
+
/** Whether this category is currently visible on the menu. */
|
|
1860
|
+
isActive: boolean;
|
|
1861
|
+
}
|
|
1862
|
+
interface MenuItem {
|
|
1863
|
+
id: string;
|
|
1864
|
+
name: string;
|
|
1865
|
+
description?: string;
|
|
1866
|
+
/** Price in minor currency units (e.g. cents). */
|
|
1867
|
+
price: number;
|
|
1868
|
+
currency: string;
|
|
1869
|
+
/** Parent category. */
|
|
1870
|
+
categoryId: string;
|
|
1871
|
+
/** Human-readable category name for convenience. */
|
|
1872
|
+
categoryName?: string;
|
|
1873
|
+
imageUrl?: string;
|
|
1874
|
+
/** Dietary classifications. Empty array means no special designation. */
|
|
1875
|
+
dietary: DietaryFlag[];
|
|
1876
|
+
isAvailable: boolean;
|
|
1877
|
+
/** When true, item can be added to an active pre-order. */
|
|
1878
|
+
isPreOrderEligible: boolean;
|
|
1879
|
+
/** ID of a combo offer this item belongs to, if any. */
|
|
1880
|
+
comboDealId?: string;
|
|
1881
|
+
/** Calories as listed on menu (optional — site-dependent). */
|
|
1882
|
+
calories?: number;
|
|
1883
|
+
/** Customisation options (e.g. "Size", "Flavour"). */
|
|
1884
|
+
customisations?: ItemCustomisation[];
|
|
1885
|
+
}
|
|
1886
|
+
interface ItemCustomisation {
|
|
1887
|
+
id: string;
|
|
1888
|
+
name: string;
|
|
1889
|
+
required: boolean;
|
|
1890
|
+
options: Array<{
|
|
1891
|
+
id: string;
|
|
1892
|
+
name: string;
|
|
1893
|
+
/** Price delta in minor units — positive means extra charge, negative means discount. */
|
|
1894
|
+
priceDelta: number;
|
|
1895
|
+
}>;
|
|
1896
|
+
}
|
|
1897
|
+
/**
|
|
1898
|
+
* A bundled combo deal — e.g. "Large Popcorn + Large Drink = $18.50"
|
|
1899
|
+
*
|
|
1900
|
+
* Combos are priced as a unit; the `savings` field shows value vs buying
|
|
1901
|
+
* items individually, suitable for upsell copy.
|
|
1902
|
+
*/
|
|
1903
|
+
interface ComboOffer {
|
|
1904
|
+
id: string;
|
|
1905
|
+
name: string;
|
|
1906
|
+
description?: string;
|
|
1907
|
+
/** Total combo price in minor units. */
|
|
1908
|
+
price: number;
|
|
1909
|
+
currency: string;
|
|
1910
|
+
/** IDs of MenuItem that make up this combo. */
|
|
1911
|
+
itemIds: string[];
|
|
1912
|
+
/** Saving in minor units vs buying all items individually at full price. */
|
|
1913
|
+
savings: number;
|
|
1914
|
+
isAvailable: boolean;
|
|
1915
|
+
/** Whether this combo can be added via pre-order. */
|
|
1916
|
+
isPreOrderEligible: boolean;
|
|
1917
|
+
imageUrl?: string;
|
|
1918
|
+
}
|
|
1919
|
+
interface FnbOrderLineItem {
|
|
1920
|
+
itemId: string;
|
|
1921
|
+
quantity: number;
|
|
1922
|
+
/** Selected customisation option IDs, keyed by customisation ID. */
|
|
1923
|
+
customisations?: Record<string, string>;
|
|
1924
|
+
/** Unit price at time of ordering (minor units). */
|
|
1925
|
+
unitPrice: number;
|
|
1926
|
+
}
|
|
1927
|
+
interface AddToOrderInput {
|
|
1928
|
+
/** Vista order ID to attach F&B items to. */
|
|
1929
|
+
orderId: string;
|
|
1930
|
+
items: FnbOrderLineItem[];
|
|
1931
|
+
/** Pre-order session ID — required when `isPreOrderEligible` items are included. */
|
|
1932
|
+
sessionId?: string;
|
|
1933
|
+
}
|
|
1934
|
+
interface FnbOrderConfirmation {
|
|
1935
|
+
orderId: string;
|
|
1936
|
+
addedItems: FnbOrderLineItem[];
|
|
1937
|
+
/** Updated F&B subtotal in minor units. */
|
|
1938
|
+
fnbSubtotal: number;
|
|
1939
|
+
currency: string;
|
|
1940
|
+
}
|
|
1941
|
+
interface MenuFilter {
|
|
1942
|
+
siteId: string;
|
|
1943
|
+
categoryId?: string;
|
|
1944
|
+
dietary?: DietaryFlag[];
|
|
1945
|
+
/** Return only items with isAvailable = true. Defaults to true. */
|
|
1946
|
+
availableOnly?: boolean;
|
|
1947
|
+
/** Filter for pre-order-eligible items only. */
|
|
1948
|
+
preOrderOnly?: boolean;
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
/**
|
|
1952
|
+
* Food & Beverage resource — menus, ordering, combo deals, and dietary filtering.
|
|
1953
|
+
*
|
|
1954
|
+
* Covers the Vista OCAPI candy-bar endpoints used to surface F&B options
|
|
1955
|
+
* on digital kiosks, mobile apps, and web booking flows.
|
|
1956
|
+
*/
|
|
1957
|
+
declare class FoodAndBeverageResource {
|
|
1958
|
+
private readonly http;
|
|
1959
|
+
constructor(http: TheatricalHTTPClient);
|
|
1960
|
+
/**
|
|
1961
|
+
* List menu items for a site, with optional filtering.
|
|
1962
|
+
*
|
|
1963
|
+
* Results include dietary tags and customisation options. Use `filter.dietary`
|
|
1964
|
+
* to surface only vegan / gluten-free items. Use `filter.preOrderOnly` when
|
|
1965
|
+
* building a pre-order flow tied to a session.
|
|
1966
|
+
*
|
|
1967
|
+
* @param siteId - The Vista site ID.
|
|
1968
|
+
* @param filter - Optional filter (dietary, category, availability).
|
|
1969
|
+
*/
|
|
1970
|
+
menu(siteId: string, filter?: Omit<MenuFilter, 'siteId'>): Promise<MenuItem[]>;
|
|
1971
|
+
/**
|
|
1972
|
+
* List available menu categories for a site.
|
|
1973
|
+
*
|
|
1974
|
+
* Categories define the candy-bar section groupings (popcorn, drinks,
|
|
1975
|
+
* combos, snacks). Ordered by `displayOrder` ascending.
|
|
1976
|
+
*
|
|
1977
|
+
* @param siteId - The Vista site ID.
|
|
1978
|
+
*/
|
|
1979
|
+
categories(siteId: string): Promise<MenuCategory[]>;
|
|
1980
|
+
/**
|
|
1981
|
+
* Fetch full detail for a single menu item.
|
|
1982
|
+
*
|
|
1983
|
+
* Includes customisation options (size, flavour) not always returned in
|
|
1984
|
+
* the full menu list. Use this before presenting an add-to-order form.
|
|
1985
|
+
*
|
|
1986
|
+
* @param siteId - The Vista site ID.
|
|
1987
|
+
* @param itemId - The menu item ID.
|
|
1988
|
+
*/
|
|
1989
|
+
itemDetail(siteId: string, itemId: string): Promise<MenuItem>;
|
|
1990
|
+
/**
|
|
1991
|
+
* List combo deals available at a site.
|
|
1992
|
+
*
|
|
1993
|
+
* Combos are pre-configured bundles (e.g. "Large Popcorn + Large Drink").
|
|
1994
|
+
* The `savings` field on each {@link ComboOffer} indicates the discount
|
|
1995
|
+
* vs buying items individually — useful for upsell copy.
|
|
1996
|
+
*
|
|
1997
|
+
* @param siteId - The Vista site ID.
|
|
1998
|
+
*/
|
|
1999
|
+
combos(siteId: string): Promise<ComboOffer[]>;
|
|
2000
|
+
/**
|
|
2001
|
+
* Add F&B items to an existing Vista order.
|
|
2002
|
+
*
|
|
2003
|
+
* Attaches concession items to a booking in progress. When adding
|
|
2004
|
+
* pre-order items tied to a specific session, pass `input.sessionId`
|
|
2005
|
+
* to enable collection-slot logic on the Vista side.
|
|
2006
|
+
*
|
|
2007
|
+
* Returns a confirmation with updated F&B subtotal for display.
|
|
2008
|
+
*
|
|
2009
|
+
* @param input - Order ID, items to add, optional session ID.
|
|
2010
|
+
*/
|
|
2011
|
+
addToOrder(input: AddToOrderInput): Promise<FnbOrderConfirmation>;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
/**
|
|
2015
|
+
* TheatricalClient — the primary entry point for the Theatrical SDK.
|
|
2016
|
+
*
|
|
2017
|
+
* Provides type-safe access to cinema platform API resources through
|
|
2018
|
+
* lazily-initialised resource modules.
|
|
2019
|
+
*
|
|
2020
|
+
* Configuration is validated at construction time using Zod schemas.
|
|
2021
|
+
* Invalid configs throw a `ValidationError` immediately so misconfigurations
|
|
2022
|
+
* surface at startup rather than at runtime.
|
|
2023
|
+
*
|
|
2024
|
+
* @example
|
|
2025
|
+
* ```typescript
|
|
2026
|
+
* const client = new TheatricalClient({
|
|
2027
|
+
* apiKey: 'your-api-key',
|
|
2028
|
+
* environment: 'sandbox',
|
|
2029
|
+
* });
|
|
2030
|
+
*
|
|
2031
|
+
* const sessions = await client.sessions.list({
|
|
2032
|
+
* siteId: 'roxy-wellington',
|
|
2033
|
+
* date: '2026-04-09',
|
|
2034
|
+
* });
|
|
2035
|
+
* ```
|
|
2036
|
+
*
|
|
2037
|
+
* @example Static factory
|
|
2038
|
+
* ```typescript
|
|
2039
|
+
* const client = TheatricalClient.create({
|
|
2040
|
+
* apiKey: process.env.THEATRICAL_API_KEY!,
|
|
2041
|
+
* environment: 'production',
|
|
2042
|
+
* });
|
|
2043
|
+
* ```
|
|
2044
|
+
*
|
|
2045
|
+
* @example Singleton
|
|
2046
|
+
* ```typescript
|
|
2047
|
+
* TheatricalClient.setGlobal({ apiKey: 'key', environment: 'sandbox' });
|
|
2048
|
+
* const client = TheatricalClient.global();
|
|
2049
|
+
* ```
|
|
2050
|
+
*/
|
|
2051
|
+
declare class TheatricalClient {
|
|
2052
|
+
private readonly config;
|
|
2053
|
+
private readonly httpClient;
|
|
2054
|
+
private readonly tokenManager;
|
|
2055
|
+
private _sessions?;
|
|
2056
|
+
private _sites?;
|
|
2057
|
+
private _films?;
|
|
2058
|
+
private _orders?;
|
|
2059
|
+
private _loyalty?;
|
|
2060
|
+
private _subscriptions?;
|
|
2061
|
+
private _pricing?;
|
|
2062
|
+
private _fnb?;
|
|
2063
|
+
/**
|
|
2064
|
+
* Constructs a TheatricalClient with validated configuration.
|
|
2065
|
+
*
|
|
2066
|
+
* Throws `ValidationError` immediately if config is invalid.
|
|
2067
|
+
*
|
|
2068
|
+
* @param config - SDK configuration
|
|
2069
|
+
* @throws {ValidationError} if config fails schema validation
|
|
2070
|
+
*/
|
|
2071
|
+
constructor(config: TheatricalConfig);
|
|
2072
|
+
/**
|
|
2073
|
+
* Creates a new TheatricalClient instance.
|
|
2074
|
+
*
|
|
2075
|
+
* Equivalent to `new TheatricalClient(config)` but provided as a static
|
|
2076
|
+
* factory for clarity in configuration-heavy setups.
|
|
2077
|
+
*
|
|
2078
|
+
* @param config - SDK configuration
|
|
2079
|
+
* @returns New TheatricalClient instance
|
|
2080
|
+
* @throws {ValidationError} if config fails schema validation
|
|
2081
|
+
*
|
|
2082
|
+
* @example
|
|
2083
|
+
* ```typescript
|
|
2084
|
+
* const client = TheatricalClient.create({
|
|
2085
|
+
* apiKey: process.env.THEATRICAL_API_KEY!,
|
|
2086
|
+
* environment: 'production',
|
|
2087
|
+
* timeout: 15_000,
|
|
2088
|
+
* });
|
|
2089
|
+
* ```
|
|
2090
|
+
*/
|
|
2091
|
+
static create(config: TheatricalConfig): TheatricalClient;
|
|
2092
|
+
/**
|
|
2093
|
+
* Returns the global singleton TheatricalClient instance.
|
|
2094
|
+
*
|
|
2095
|
+
* Throws if no global instance has been configured via `setGlobal()`.
|
|
2096
|
+
* Useful for applications that initialise the client once at startup and
|
|
2097
|
+
* access it throughout without passing the instance around.
|
|
2098
|
+
*
|
|
2099
|
+
* @returns The global TheatricalClient instance
|
|
2100
|
+
* @throws {Error} if setGlobal() has not been called
|
|
2101
|
+
*
|
|
2102
|
+
* @example
|
|
2103
|
+
* ```typescript
|
|
2104
|
+
* // At startup:
|
|
2105
|
+
* TheatricalClient.setGlobal({ apiKey: 'key', environment: 'production' });
|
|
2106
|
+
*
|
|
2107
|
+
* // Anywhere in your app:
|
|
2108
|
+
* const client = TheatricalClient.global();
|
|
2109
|
+
* const films = await client.films.nowShowing({ siteId: 'roxy-wellington' });
|
|
2110
|
+
* ```
|
|
2111
|
+
*/
|
|
2112
|
+
static global(): TheatricalClient;
|
|
2113
|
+
/**
|
|
2114
|
+
* Configures the global singleton TheatricalClient instance.
|
|
2115
|
+
*
|
|
2116
|
+
* Replaces any existing global instance. Subsequent calls to
|
|
2117
|
+
* `TheatricalClient.global()` will return this instance.
|
|
2118
|
+
*
|
|
2119
|
+
* @param config - SDK configuration
|
|
2120
|
+
* @throws {ValidationError} if config fails schema validation
|
|
2121
|
+
*
|
|
2122
|
+
* @example
|
|
2123
|
+
* ```typescript
|
|
2124
|
+
* TheatricalClient.setGlobal({
|
|
2125
|
+
* apiKey: process.env.THEATRICAL_API_KEY!,
|
|
2126
|
+
* environment: 'production',
|
|
2127
|
+
* });
|
|
2128
|
+
* ```
|
|
2129
|
+
*/
|
|
2130
|
+
static setGlobal(config: TheatricalConfig): void;
|
|
2131
|
+
/**
|
|
2132
|
+
* Resets the global singleton instance.
|
|
2133
|
+
*
|
|
2134
|
+
* Primarily intended for testing — allows tests to start with a clean slate.
|
|
2135
|
+
*
|
|
2136
|
+
* @example
|
|
2137
|
+
* ```typescript
|
|
2138
|
+
* afterEach(() => {
|
|
2139
|
+
* TheatricalClient.resetGlobal();
|
|
2140
|
+
* });
|
|
2141
|
+
* ```
|
|
2142
|
+
*/
|
|
2143
|
+
static resetGlobal(): void;
|
|
2144
|
+
/**
|
|
2145
|
+
* Creates an offline mock client that returns pre-defined NZ cinema fixture data.
|
|
2146
|
+
*
|
|
2147
|
+
* Ideal for demos, prototypes, and evaluators without a Vista API key.
|
|
2148
|
+
* The mock covers films, sessions, sites, orders, and loyalty endpoints.
|
|
2149
|
+
*
|
|
2150
|
+
* @param fixtureOverrides - Optional URL-keyed fixture map to replace specific responses
|
|
2151
|
+
*
|
|
2152
|
+
* @example
|
|
2153
|
+
* ```typescript
|
|
2154
|
+
* const client = import.meta.env.VITE_THEATRICAL_MOCK
|
|
2155
|
+
* ? TheatricalClient.createMock()
|
|
2156
|
+
* : TheatricalClient.create({ apiKey: process.env.THEATRICAL_API_KEY! });
|
|
2157
|
+
* ```
|
|
2158
|
+
*
|
|
2159
|
+
* @see https://developer.vista.co
|
|
2160
|
+
*/
|
|
2161
|
+
static createMock(fixtureOverrides?: Record<string, unknown>): TheatricalClient;
|
|
2162
|
+
/** Sessions — showtimes, availability, seat maps */
|
|
2163
|
+
get sessions(): SessionsResource;
|
|
2164
|
+
/** Sites — cinema locations, screens, configurations */
|
|
2165
|
+
get sites(): SitesResource;
|
|
2166
|
+
/** Films — now showing, coming soon, search */
|
|
2167
|
+
get films(): FilmsResource;
|
|
2168
|
+
/** Orders — booking lifecycle: create, confirm, cancel */
|
|
2169
|
+
get orders(): OrdersResource;
|
|
2170
|
+
/** Loyalty — member management, points, tiers */
|
|
2171
|
+
get loyalty(): LoyaltyResource;
|
|
2172
|
+
/** Subscriptions — plans, member subscriptions */
|
|
2173
|
+
get subscriptions(): SubscriptionsResource;
|
|
2174
|
+
/** Pricing — ticket types, price calculations, tax handling */
|
|
2175
|
+
get pricing(): PricingResource;
|
|
2176
|
+
/** Food & Beverage — menus, ordering, dietary information */
|
|
2177
|
+
get fnb(): FoodAndBeverageResource;
|
|
2178
|
+
}
|
|
2179
|
+
|
|
2180
|
+
/**
|
|
2181
|
+
* Base error class for all Theatrical SDK errors
|
|
2182
|
+
*/
|
|
2183
|
+
declare class TheatricalError extends Error {
|
|
2184
|
+
readonly statusCode: number;
|
|
2185
|
+
readonly vistaErrorCode?: string;
|
|
2186
|
+
readonly requestId?: string;
|
|
2187
|
+
constructor(message: string, statusCode: number, vistaErrorCode?: string, requestId?: string);
|
|
2188
|
+
toJSON(): {
|
|
2189
|
+
name: string;
|
|
2190
|
+
message: string;
|
|
2191
|
+
statusCode: number;
|
|
2192
|
+
vistaErrorCode: string | undefined;
|
|
2193
|
+
requestId: string | undefined;
|
|
2194
|
+
};
|
|
2195
|
+
}
|
|
2196
|
+
declare class AuthenticationError extends TheatricalError {
|
|
2197
|
+
constructor(message?: string, vistaErrorCode?: string, requestId?: string);
|
|
2198
|
+
}
|
|
2199
|
+
declare class RateLimitError extends TheatricalError {
|
|
2200
|
+
readonly retryAfter: number;
|
|
2201
|
+
constructor(retryAfter: number, requestId?: string);
|
|
2202
|
+
}
|
|
2203
|
+
declare class ValidationError extends TheatricalError {
|
|
2204
|
+
readonly fields: Record<string, string>;
|
|
2205
|
+
constructor(message: string, fields?: Record<string, string>, requestId?: string);
|
|
2206
|
+
}
|
|
2207
|
+
declare class NotFoundError extends TheatricalError {
|
|
2208
|
+
readonly resource: string;
|
|
2209
|
+
readonly resourceId: string;
|
|
2210
|
+
constructor(resource: string, resourceId: string, requestId?: string);
|
|
2211
|
+
}
|
|
2212
|
+
declare class ServerError extends TheatricalError {
|
|
2213
|
+
constructor(message?: string, requestId?: string);
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
/**
|
|
2217
|
+
* A lightweight mock HTTP adapter for offline development and testing.
|
|
2218
|
+
*
|
|
2219
|
+
* Replaces `TheatricalHTTPClient` inside a mock `TheatricalClient`.
|
|
2220
|
+
* Matches URL paths against a fixture map and returns pre-defined responses.
|
|
2221
|
+
*
|
|
2222
|
+
* @see TheatricalClient.createMock()
|
|
2223
|
+
*/
|
|
2224
|
+
declare class MockHTTPAdapter {
|
|
2225
|
+
private readonly responses;
|
|
2226
|
+
constructor(overrides?: Record<string, unknown>);
|
|
2227
|
+
/** Normalise a concrete path to a pattern key by replacing segments that look like IDs. */
|
|
2228
|
+
private matchPattern;
|
|
2229
|
+
private lookup;
|
|
2230
|
+
get<T>(path: string): Promise<T>;
|
|
2231
|
+
post<T>(path: string, options?: {
|
|
2232
|
+
body?: unknown;
|
|
2233
|
+
}): Promise<T>;
|
|
2234
|
+
put<T>(path: string, options?: {
|
|
2235
|
+
body?: unknown;
|
|
2236
|
+
}): Promise<T>;
|
|
2237
|
+
delete<T>(path: string): Promise<T>;
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
declare const SDK_VERSION = "0.1.0";
|
|
2241
|
+
declare const SDK_USER_AGENT = "theatrical-sdk/0.1.0 (Node.js)";
|
|
2242
|
+
|
|
2243
|
+
export { AuthenticationError, type Film, type FilmFilter, type LoyaltyMember, type LoyaltyTier, type MemberSubscription, type MenuCategory, type MenuItem, MockHTTPAdapter, NotFoundError, type Order, type OrderItem, type OrderStatus, type PriceCalculation, RateLimitError, SDK_USER_AGENT, SDK_VERSION, type Screen, type Seat, type SeatAvailability, type SeatStatus, ServerError, type Session, type SessionFilter, type SessionListResponse, type Site, type SiteConfig, type SubscriptionBenefit, type SubscriptionPlan, type SubscriptionUsage, TheatricalClient, type TheatricalConfig, type TheatricalEnvironment, TheatricalError, type Ticket, type TicketType, ValidationError };
|