@andev2005/movie-glu-sdk 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,7 +16,6 @@ npm i @andev2005/movie-glu-sdk
16
16
 
17
17
  ## Yêu cầu
18
18
 
19
- - Có `apiKey` của MovieGlu
20
19
  - Runtime có `fetch` (Node.js 18+) hoặc truyền `fetch` custom vào client
21
20
 
22
21
  ## Sử dụng nhanh
@@ -27,7 +26,8 @@ npm i @andev2005/movie-glu-sdk
27
26
  import { createMovieGluClient } from '@andev2005/movie-glu-sdk';
28
27
 
29
28
  const movieGlu = createMovieGluClient({
30
- apiKey: process.env.MOVIE_GLU_API_KEY!,
29
+ // apiKey là optional, mặc định đã được gắn theo cấu hình ANDE/XX
30
+ // apiKey: process.env.MOVIE_GLU_API_KEY,
31
31
  });
32
32
 
33
33
  async function main() {
@@ -50,7 +50,6 @@ main().catch(console.error);
50
50
  import { createMovieGluClient } from '@andev2005/movie-glu-sdk';
51
51
 
52
52
  const client = createMovieGluClient({
53
- apiKey: 'your-api-key',
54
53
  // Tuỳ chọn:
55
54
  // baseUrl: 'https://api-gate2.movieglu.com',
56
55
  // headers: { 'x-custom-header': 'value' },
@@ -63,14 +62,27 @@ const client = createMovieGluClient({
63
62
  ### `films`
64
63
 
65
64
  ```ts
66
- // Phim đang chiếu
65
+ // Phim đang chiếu (limit optional, default 10)
67
66
  await client.films.nowShowing({ limit: 10 });
68
67
 
69
- // Phim sắp chiếu
68
+ // Phim sắp chiếu (limit optional, default 10)
70
69
  await client.films.comingSoon({ limit: 10 });
71
70
 
72
71
  // Chi tiết phim
73
72
  await client.films.details(12345);
73
+
74
+ // Chi tiết phim + size_category
75
+ await client.films.details({
76
+ filmId: 12345,
77
+ sizeCategory: ['small', 'medium'],
78
+ });
79
+
80
+ // Lịch chiếu theo phim + ngày
81
+ await client.films.showTimes({
82
+ filmId: 12345,
83
+ date: '2026-02-25',
84
+ limit: 10,
85
+ });
74
86
  ```
75
87
 
76
88
  ### `cinemas`
@@ -106,6 +118,16 @@ await client.cinemas.showTimes({
106
118
 
107
119
  SDK sẽ throw `MovieGluError` nếu request thất bại (HTTP status không thành công).
108
120
 
121
+ Mỗi request tự động gửi các header mặc định:
122
+
123
+ - `client: ANDE`
124
+ - `x-api-key: Bcg2m9aHOI8QSg5h8EDNK8ecPZRTiove3dsbZVuz`
125
+ - `authorization: Basic QU5ERV9YWDpWMEhoUjYzSHZOalM=`
126
+ - `territory: XX`
127
+ - `api-version: v201`
128
+ - `geolocation: -22.0;14.0`
129
+ - `device-datetime: <ISO datetime hiện tại>`
130
+
109
131
  ```ts
110
132
  import { MovieGluError } from '@andev2005/movie-glu-sdk';
111
133
 
@@ -127,9 +149,10 @@ try {
127
149
 
128
150
  SDK có kiểm tra đầu vào và sẽ throw `TypeError` nếu:
129
151
 
130
- - `apiKey` bị thiếu/rỗng
152
+ - `apiKey` rỗng (nếu bạn truyền vào)
131
153
  - `limit` không phải số nguyên dương
132
- - `id`, `cinemaId`, `filmId` không phải số nguyên dương
154
+ - `id/filmId/cinemaId` không phải số nguyên dương
155
+ - `sizeCategory` không thuộc `small|medium|large|xlarge|xxlarge`
133
156
  - `date` không đúng định dạng `YYYY-MM-DD`
134
157
 
135
158
  ## Utility build URL (tuỳ chọn)
@@ -148,7 +171,8 @@ Các helper có sẵn:
148
171
  - `MOVIE_GLU.FILM_NOWSHOWING(limit)`
149
172
  - `MOVIE_GLU.CINEMA_NEARBY(limit)`
150
173
  - `MOVIE_GLU.FILMS_COMING_SOON(limit)`
151
- - `MOVIE_GLU.FILMS_DETAIL(id)`
174
+ - `MOVIE_GLU.FILM_SHOWTIME({ filmId, date, limit? })`
175
+ - `MOVIE_GLU.FILMS_DETAIL(idOrParams)`
152
176
  - `MOVIE_GLU.CINEMA_DETAIL(id)`
153
177
  - `MOVIE_GLU.CINEMA_SHOWTIME({ cinemaId, date, filmId?, sort? })`
154
178
 
package/dist/index.d.mts CHANGED
@@ -26,7 +26,7 @@ type Client = {
26
26
  fetch?: FetchLike;
27
27
  };
28
28
  type MovieGluClientConfig = {
29
- apiKey: string;
29
+ apiKey?: string;
30
30
  baseUrl?: string;
31
31
  headers?: Record<string, string>;
32
32
  geolocation?: GeolocationInput;
@@ -38,8 +38,25 @@ type CinemaShowTimesParams = {
38
38
  filmId?: number;
39
39
  sort?: SortType;
40
40
  };
41
+ declare const IMAGE_SIZE_CATEGORY: {
42
+ readonly SMALL: "small";
43
+ readonly MEDIUM: "medium";
44
+ readonly LARGE: "large";
45
+ readonly XLARGE: "xlarge";
46
+ readonly XXLARGE: "xxlarge";
47
+ };
48
+ type ImageSizeCategory = (typeof IMAGE_SIZE_CATEGORY)[keyof typeof IMAGE_SIZE_CATEGORY];
49
+ type FilmDetailsParams = {
50
+ filmId: number;
51
+ sizeCategory?: ImageSizeCategory | ImageSizeCategory[];
52
+ };
53
+ type FilmShowTimesParams = {
54
+ date: string;
55
+ filmId: number;
56
+ limit?: number;
57
+ };
41
58
  type ListParams = {
42
- limit: number;
59
+ limit?: number;
43
60
  };
44
61
  type GeolocationInput = string | UserLocation;
45
62
  type CinemasNearbyParams = ListParams;
@@ -49,7 +66,8 @@ type MovieGluSdk = {
49
66
  films: {
50
67
  nowShowing(params: ListParams): Promise<FilmsNowShowing>;
51
68
  comingSoon(params: ListParams): Promise<FilmsComingSoonResponse>;
52
- details(id: number): Promise<FilmDetailsResponse>;
69
+ details(idOrParams: number | FilmDetailsParams): Promise<FilmDetailsResponse>;
70
+ showTimes(params: FilmShowTimesParams): Promise<FilmShowTimesResponse>;
53
71
  };
54
72
  cinemas: {
55
73
  nearby(params: CinemasNearbyParams, options?: CinemasNearbyRequestOptions): Promise<CinemasNearbyResponse>;
@@ -76,47 +94,48 @@ type FilmsComingSoonResponse = {
76
94
  };
77
95
  type FilmDetailsResponse = {
78
96
  film_id: number;
79
- imdb_id: number;
80
- imdb_title_id: string;
97
+ imdb_id?: number;
98
+ imdb_title_id?: string;
81
99
  film_name: string;
82
- other_titles: OtherTitles;
83
- version_type: string;
84
- images: FilmImages;
85
- synopsis_long: string;
86
- distributor_id: number;
87
- distributor: string;
88
- release_dates: ReleaseDate[];
89
- age_rating: AgeRating[];
90
- duration_mins: number;
91
- review_stars: number;
92
- review_txt: string;
93
- trailers: Trailer[] | null;
94
- genres: Genre[];
95
- cast: Cast[];
96
- directors: Director[];
97
- producers: Producer[];
98
- writers: Writer[];
99
- show_dates: ShowDate[];
100
- alternate_versions: AlternateVersion[];
100
+ other_titles?: OtherTitles;
101
+ version_type?: string;
102
+ images?: FilmImages;
103
+ synopsis_short?: string;
104
+ synopsis_long?: string;
105
+ distributor_id?: number;
106
+ distributor?: string;
107
+ release_dates?: ReleaseDate[];
108
+ age_rating?: AgeRating[];
109
+ duration_mins?: number;
110
+ review_stars?: number | string;
111
+ review_txt?: string;
112
+ trailers?: Trailers | null;
113
+ genres?: Genre[];
114
+ cast?: Cast[];
115
+ directors?: Director[];
116
+ producers?: Producer[];
117
+ writers?: Writer[];
118
+ show_dates?: ShowDate[];
119
+ alternate_versions?: AlternateVersion[];
101
120
  status: Status;
102
121
  };
103
122
  type CinemaDetailsResponse = {
104
123
  cinema_id: number;
105
124
  cinema_name: string;
106
125
  address: string;
107
- address2: string;
126
+ address2?: string;
108
127
  city: string;
109
- state: string;
110
- county: string;
111
- country: string;
128
+ state?: string;
129
+ county?: string;
130
+ country?: string;
112
131
  postcode: string;
113
- phone: string;
132
+ phone?: string;
114
133
  lat: number;
115
134
  lng: number;
116
- distance: number;
117
- ticketing: number;
118
- directions: string;
119
- logo_url: string;
135
+ distance?: number;
136
+ ticketing?: number;
137
+ directions?: string;
138
+ logo_url?: string;
120
139
  show_dates: ShowDate[];
121
140
  status: Status;
122
141
  };
@@ -144,13 +163,13 @@ type Status = {
144
163
  };
145
164
  type OtherTitles = Record<string, string>;
146
165
  type ReleaseDate = {
147
- release_date: string;
148
- notes: string;
166
+ release_date?: string;
167
+ notes?: string;
149
168
  };
150
169
  type AgeRating = {
151
- rating: string;
152
- age_rating_image: string;
153
- age_advisory: string;
170
+ rating?: string;
171
+ age_rating_image?: string;
172
+ age_advisory?: string;
154
173
  };
155
174
  type FilmImageSize = {
156
175
  film_image: string;
@@ -167,8 +186,8 @@ type Still = {
167
186
  medium: FilmImageSize;
168
187
  };
169
188
  type FilmImages = {
170
- poster: KeyNumberObject<Poster>;
171
- still: KeyNumberObject<Still>;
189
+ poster?: KeyNumberObject<Poster>;
190
+ still?: KeyNumberObject<Still>;
172
191
  };
173
192
  type ShowDate = {
174
193
  date: string;
@@ -177,10 +196,10 @@ type Cinema = {
177
196
  cinema_id: number;
178
197
  cinema_name: string;
179
198
  address: string;
180
- address2: string;
199
+ address2?: string;
181
200
  city: string;
182
- state: string;
183
- county: string;
201
+ state?: string;
202
+ county?: string;
184
203
  country?: string;
185
204
  postcode: string;
186
205
  phone?: string;
@@ -193,8 +212,8 @@ type Cinema = {
193
212
  };
194
213
  type Film = {
195
214
  film_id: number;
196
- imdb_id: number;
197
- imdb_title_id: string;
215
+ imdb_id?: number;
216
+ imdb_title_id?: string;
198
217
  film_name: string;
199
218
  other_titles?: OtherTitles;
200
219
  release_dates: ReleaseDate[];
@@ -205,10 +224,10 @@ type Film = {
205
224
  };
206
225
  type FilmComingSoon = {
207
226
  film_id: number;
208
- imdb_id: number;
209
- imdb_title_id: string;
227
+ imdb_id?: number;
228
+ imdb_title_id?: string;
210
229
  film_name: string;
211
- other_titles: OtherTitles;
230
+ other_titles?: OtherTitles;
212
231
  release_dates: ReleaseDate[];
213
232
  age_rating: AgeRating[];
214
233
  film_trailer: string | null;
@@ -240,11 +259,15 @@ type AlternateVersion = {
240
259
  film_name: string;
241
260
  version_type: string;
242
261
  };
243
- type Trailer = {
244
- trailer_url?: string;
262
+ type TrailerItem = {
263
+ film_trailer?: string;
245
264
  trailer_image?: string;
246
- trailer_type?: string;
247
- [key: string]: string | number | boolean | null | undefined;
265
+ version?: number;
266
+ quality?: string;
267
+ region?: string;
268
+ };
269
+ type Trailers = {
270
+ [quality: string]: TrailerItem[];
248
271
  };
249
272
  type ShowtimeTime = {
250
273
  start_time: string;
@@ -262,10 +285,10 @@ type CinemaShowTimesCinema = {
262
285
  };
263
286
  type CinemaShowTimesFilm = {
264
287
  film_id: number;
265
- imdb_id: number;
266
- imdb_title_id: string;
288
+ imdb_id?: number;
289
+ imdb_title_id?: string;
267
290
  film_name: string;
268
- other_titles: OtherTitles;
291
+ other_titles?: OtherTitles;
269
292
  version_type: string;
270
293
  age_rating: AgeRating[];
271
294
  film_image: string;
@@ -276,10 +299,10 @@ type CinemaShowTimesFilm = {
276
299
  };
277
300
  type FilmShowTimesFilm = {
278
301
  film_id: number;
279
- imdb_id: number;
280
- imdb_title_id: string;
302
+ imdb_id?: number;
303
+ imdb_title_id?: string;
281
304
  film_name: string;
282
- other_titles: OtherTitles;
305
+ other_titles?: OtherTitles;
283
306
  version_type: string;
284
307
  age_rating: AgeRating[];
285
308
  film_image: string;
@@ -310,10 +333,11 @@ declare const MOVIE_GLU: {
310
333
  FILM_NOWSHOWING(limit: number): string;
311
334
  CINEMA_NEARBY(limit: number): string;
312
335
  FILMS_COMING_SOON(limit: number): string;
313
- FILMS_DETAIL(id: number): string;
336
+ FILM_SHOWTIME(params: FilmShowTimesParams): string;
337
+ FILMS_DETAIL(idOrParams: number | FilmDetailsParams): string;
314
338
  CINEMA_DETAIL(id: number): string;
315
339
  CINEMA_SHOWTIME(params: CinemaShowTimesParams): string;
316
340
  };
317
341
  declare function createMovieGluClient(config: MovieGluClientConfig): MovieGluSdk;
318
342
 
319
- export { type AgeRating, type AlternateVersion, type Cast, type Cinema, type CinemaDetailsRequestOptions, type CinemaDetailsResponse, type CinemaShowTimesCinema, type CinemaShowTimesFilm, type CinemaShowTimesParams, type CinemaShowTimesResponse, type CinemasNearbyParams, type CinemasNearbyRequestOptions, type CinemasNearbyResponse, type Client, DEFAULT_BASE_URL, type Director, type FetchLike, type Film, type FilmComingSoon, type FilmDetailsResponse, type FilmImageSize, type FilmImages, type FilmShowTimesCinema, type FilmShowTimesFilm, type FilmShowTimesResponse, type FilmsComingSoonResponse, type FilmsNowShowing, type Genre, type GeolocationInput, type KeyNumberObject, type ListParams, MOVIE_GLU, type MovieGluClientConfig, MovieGluError, type MovieGluSdk, type OtherTitles, type Poster, type Producer, type ReleaseDate, type RequestOptions, SORT_TYPE, type ShowDate, type Showings, type ShowtimeGroup, type ShowtimeTime, type SortType, type Status, type Still, type Trailer, type UserLocation, type Writer, createMovieGluClient };
343
+ export { type AgeRating, type AlternateVersion, type Cast, type Cinema, type CinemaDetailsRequestOptions, type CinemaDetailsResponse, type CinemaShowTimesCinema, type CinemaShowTimesFilm, type CinemaShowTimesParams, type CinemaShowTimesResponse, type CinemasNearbyParams, type CinemasNearbyRequestOptions, type CinemasNearbyResponse, type Client, DEFAULT_BASE_URL, type Director, type FetchLike, type Film, type FilmComingSoon, type FilmDetailsParams, type FilmDetailsResponse, type FilmImageSize, type FilmImages, type FilmShowTimesCinema, type FilmShowTimesFilm, type FilmShowTimesParams, type FilmShowTimesResponse, type FilmsComingSoonResponse, type FilmsNowShowing, type Genre, type GeolocationInput, IMAGE_SIZE_CATEGORY, type ImageSizeCategory, type KeyNumberObject, type ListParams, MOVIE_GLU, type MovieGluClientConfig, MovieGluError, type MovieGluSdk, type OtherTitles, type Poster, type Producer, type ReleaseDate, type RequestOptions, SORT_TYPE, type ShowDate, type Showings, type ShowtimeGroup, type ShowtimeTime, type SortType, type Status, type Still, type TrailerItem, type Trailers, type UserLocation, type Writer, createMovieGluClient };
package/dist/index.d.ts CHANGED
@@ -26,7 +26,7 @@ type Client = {
26
26
  fetch?: FetchLike;
27
27
  };
28
28
  type MovieGluClientConfig = {
29
- apiKey: string;
29
+ apiKey?: string;
30
30
  baseUrl?: string;
31
31
  headers?: Record<string, string>;
32
32
  geolocation?: GeolocationInput;
@@ -38,8 +38,25 @@ type CinemaShowTimesParams = {
38
38
  filmId?: number;
39
39
  sort?: SortType;
40
40
  };
41
+ declare const IMAGE_SIZE_CATEGORY: {
42
+ readonly SMALL: "small";
43
+ readonly MEDIUM: "medium";
44
+ readonly LARGE: "large";
45
+ readonly XLARGE: "xlarge";
46
+ readonly XXLARGE: "xxlarge";
47
+ };
48
+ type ImageSizeCategory = (typeof IMAGE_SIZE_CATEGORY)[keyof typeof IMAGE_SIZE_CATEGORY];
49
+ type FilmDetailsParams = {
50
+ filmId: number;
51
+ sizeCategory?: ImageSizeCategory | ImageSizeCategory[];
52
+ };
53
+ type FilmShowTimesParams = {
54
+ date: string;
55
+ filmId: number;
56
+ limit?: number;
57
+ };
41
58
  type ListParams = {
42
- limit: number;
59
+ limit?: number;
43
60
  };
44
61
  type GeolocationInput = string | UserLocation;
45
62
  type CinemasNearbyParams = ListParams;
@@ -49,7 +66,8 @@ type MovieGluSdk = {
49
66
  films: {
50
67
  nowShowing(params: ListParams): Promise<FilmsNowShowing>;
51
68
  comingSoon(params: ListParams): Promise<FilmsComingSoonResponse>;
52
- details(id: number): Promise<FilmDetailsResponse>;
69
+ details(idOrParams: number | FilmDetailsParams): Promise<FilmDetailsResponse>;
70
+ showTimes(params: FilmShowTimesParams): Promise<FilmShowTimesResponse>;
53
71
  };
54
72
  cinemas: {
55
73
  nearby(params: CinemasNearbyParams, options?: CinemasNearbyRequestOptions): Promise<CinemasNearbyResponse>;
@@ -76,47 +94,48 @@ type FilmsComingSoonResponse = {
76
94
  };
77
95
  type FilmDetailsResponse = {
78
96
  film_id: number;
79
- imdb_id: number;
80
- imdb_title_id: string;
97
+ imdb_id?: number;
98
+ imdb_title_id?: string;
81
99
  film_name: string;
82
- other_titles: OtherTitles;
83
- version_type: string;
84
- images: FilmImages;
85
- synopsis_long: string;
86
- distributor_id: number;
87
- distributor: string;
88
- release_dates: ReleaseDate[];
89
- age_rating: AgeRating[];
90
- duration_mins: number;
91
- review_stars: number;
92
- review_txt: string;
93
- trailers: Trailer[] | null;
94
- genres: Genre[];
95
- cast: Cast[];
96
- directors: Director[];
97
- producers: Producer[];
98
- writers: Writer[];
99
- show_dates: ShowDate[];
100
- alternate_versions: AlternateVersion[];
100
+ other_titles?: OtherTitles;
101
+ version_type?: string;
102
+ images?: FilmImages;
103
+ synopsis_short?: string;
104
+ synopsis_long?: string;
105
+ distributor_id?: number;
106
+ distributor?: string;
107
+ release_dates?: ReleaseDate[];
108
+ age_rating?: AgeRating[];
109
+ duration_mins?: number;
110
+ review_stars?: number | string;
111
+ review_txt?: string;
112
+ trailers?: Trailers | null;
113
+ genres?: Genre[];
114
+ cast?: Cast[];
115
+ directors?: Director[];
116
+ producers?: Producer[];
117
+ writers?: Writer[];
118
+ show_dates?: ShowDate[];
119
+ alternate_versions?: AlternateVersion[];
101
120
  status: Status;
102
121
  };
103
122
  type CinemaDetailsResponse = {
104
123
  cinema_id: number;
105
124
  cinema_name: string;
106
125
  address: string;
107
- address2: string;
126
+ address2?: string;
108
127
  city: string;
109
- state: string;
110
- county: string;
111
- country: string;
128
+ state?: string;
129
+ county?: string;
130
+ country?: string;
112
131
  postcode: string;
113
- phone: string;
132
+ phone?: string;
114
133
  lat: number;
115
134
  lng: number;
116
- distance: number;
117
- ticketing: number;
118
- directions: string;
119
- logo_url: string;
135
+ distance?: number;
136
+ ticketing?: number;
137
+ directions?: string;
138
+ logo_url?: string;
120
139
  show_dates: ShowDate[];
121
140
  status: Status;
122
141
  };
@@ -144,13 +163,13 @@ type Status = {
144
163
  };
145
164
  type OtherTitles = Record<string, string>;
146
165
  type ReleaseDate = {
147
- release_date: string;
148
- notes: string;
166
+ release_date?: string;
167
+ notes?: string;
149
168
  };
150
169
  type AgeRating = {
151
- rating: string;
152
- age_rating_image: string;
153
- age_advisory: string;
170
+ rating?: string;
171
+ age_rating_image?: string;
172
+ age_advisory?: string;
154
173
  };
155
174
  type FilmImageSize = {
156
175
  film_image: string;
@@ -167,8 +186,8 @@ type Still = {
167
186
  medium: FilmImageSize;
168
187
  };
169
188
  type FilmImages = {
170
- poster: KeyNumberObject<Poster>;
171
- still: KeyNumberObject<Still>;
189
+ poster?: KeyNumberObject<Poster>;
190
+ still?: KeyNumberObject<Still>;
172
191
  };
173
192
  type ShowDate = {
174
193
  date: string;
@@ -177,10 +196,10 @@ type Cinema = {
177
196
  cinema_id: number;
178
197
  cinema_name: string;
179
198
  address: string;
180
- address2: string;
199
+ address2?: string;
181
200
  city: string;
182
- state: string;
183
- county: string;
201
+ state?: string;
202
+ county?: string;
184
203
  country?: string;
185
204
  postcode: string;
186
205
  phone?: string;
@@ -193,8 +212,8 @@ type Cinema = {
193
212
  };
194
213
  type Film = {
195
214
  film_id: number;
196
- imdb_id: number;
197
- imdb_title_id: string;
215
+ imdb_id?: number;
216
+ imdb_title_id?: string;
198
217
  film_name: string;
199
218
  other_titles?: OtherTitles;
200
219
  release_dates: ReleaseDate[];
@@ -205,10 +224,10 @@ type Film = {
205
224
  };
206
225
  type FilmComingSoon = {
207
226
  film_id: number;
208
- imdb_id: number;
209
- imdb_title_id: string;
227
+ imdb_id?: number;
228
+ imdb_title_id?: string;
210
229
  film_name: string;
211
- other_titles: OtherTitles;
230
+ other_titles?: OtherTitles;
212
231
  release_dates: ReleaseDate[];
213
232
  age_rating: AgeRating[];
214
233
  film_trailer: string | null;
@@ -240,11 +259,15 @@ type AlternateVersion = {
240
259
  film_name: string;
241
260
  version_type: string;
242
261
  };
243
- type Trailer = {
244
- trailer_url?: string;
262
+ type TrailerItem = {
263
+ film_trailer?: string;
245
264
  trailer_image?: string;
246
- trailer_type?: string;
247
- [key: string]: string | number | boolean | null | undefined;
265
+ version?: number;
266
+ quality?: string;
267
+ region?: string;
268
+ };
269
+ type Trailers = {
270
+ [quality: string]: TrailerItem[];
248
271
  };
249
272
  type ShowtimeTime = {
250
273
  start_time: string;
@@ -262,10 +285,10 @@ type CinemaShowTimesCinema = {
262
285
  };
263
286
  type CinemaShowTimesFilm = {
264
287
  film_id: number;
265
- imdb_id: number;
266
- imdb_title_id: string;
288
+ imdb_id?: number;
289
+ imdb_title_id?: string;
267
290
  film_name: string;
268
- other_titles: OtherTitles;
291
+ other_titles?: OtherTitles;
269
292
  version_type: string;
270
293
  age_rating: AgeRating[];
271
294
  film_image: string;
@@ -276,10 +299,10 @@ type CinemaShowTimesFilm = {
276
299
  };
277
300
  type FilmShowTimesFilm = {
278
301
  film_id: number;
279
- imdb_id: number;
280
- imdb_title_id: string;
302
+ imdb_id?: number;
303
+ imdb_title_id?: string;
281
304
  film_name: string;
282
- other_titles: OtherTitles;
305
+ other_titles?: OtherTitles;
283
306
  version_type: string;
284
307
  age_rating: AgeRating[];
285
308
  film_image: string;
@@ -310,10 +333,11 @@ declare const MOVIE_GLU: {
310
333
  FILM_NOWSHOWING(limit: number): string;
311
334
  CINEMA_NEARBY(limit: number): string;
312
335
  FILMS_COMING_SOON(limit: number): string;
313
- FILMS_DETAIL(id: number): string;
336
+ FILM_SHOWTIME(params: FilmShowTimesParams): string;
337
+ FILMS_DETAIL(idOrParams: number | FilmDetailsParams): string;
314
338
  CINEMA_DETAIL(id: number): string;
315
339
  CINEMA_SHOWTIME(params: CinemaShowTimesParams): string;
316
340
  };
317
341
  declare function createMovieGluClient(config: MovieGluClientConfig): MovieGluSdk;
318
342
 
319
- export { type AgeRating, type AlternateVersion, type Cast, type Cinema, type CinemaDetailsRequestOptions, type CinemaDetailsResponse, type CinemaShowTimesCinema, type CinemaShowTimesFilm, type CinemaShowTimesParams, type CinemaShowTimesResponse, type CinemasNearbyParams, type CinemasNearbyRequestOptions, type CinemasNearbyResponse, type Client, DEFAULT_BASE_URL, type Director, type FetchLike, type Film, type FilmComingSoon, type FilmDetailsResponse, type FilmImageSize, type FilmImages, type FilmShowTimesCinema, type FilmShowTimesFilm, type FilmShowTimesResponse, type FilmsComingSoonResponse, type FilmsNowShowing, type Genre, type GeolocationInput, type KeyNumberObject, type ListParams, MOVIE_GLU, type MovieGluClientConfig, MovieGluError, type MovieGluSdk, type OtherTitles, type Poster, type Producer, type ReleaseDate, type RequestOptions, SORT_TYPE, type ShowDate, type Showings, type ShowtimeGroup, type ShowtimeTime, type SortType, type Status, type Still, type Trailer, type UserLocation, type Writer, createMovieGluClient };
343
+ export { type AgeRating, type AlternateVersion, type Cast, type Cinema, type CinemaDetailsRequestOptions, type CinemaDetailsResponse, type CinemaShowTimesCinema, type CinemaShowTimesFilm, type CinemaShowTimesParams, type CinemaShowTimesResponse, type CinemasNearbyParams, type CinemasNearbyRequestOptions, type CinemasNearbyResponse, type Client, DEFAULT_BASE_URL, type Director, type FetchLike, type Film, type FilmComingSoon, type FilmDetailsParams, type FilmDetailsResponse, type FilmImageSize, type FilmImages, type FilmShowTimesCinema, type FilmShowTimesFilm, type FilmShowTimesParams, type FilmShowTimesResponse, type FilmsComingSoonResponse, type FilmsNowShowing, type Genre, type GeolocationInput, IMAGE_SIZE_CATEGORY, type ImageSizeCategory, type KeyNumberObject, type ListParams, MOVIE_GLU, type MovieGluClientConfig, MovieGluError, type MovieGluSdk, type OtherTitles, type Poster, type Producer, type ReleaseDate, type RequestOptions, SORT_TYPE, type ShowDate, type Showings, type ShowtimeGroup, type ShowtimeTime, type SortType, type Status, type Still, type TrailerItem, type Trailers, type UserLocation, type Writer, createMovieGluClient };
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  var index_exports = {};
21
21
  __export(index_exports, {
22
22
  DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
23
+ IMAGE_SIZE_CATEGORY: () => IMAGE_SIZE_CATEGORY,
23
24
  MOVIE_GLU: () => MOVIE_GLU,
24
25
  MovieGluError: () => MovieGluError,
25
26
  SORT_TYPE: () => SORT_TYPE,
@@ -96,7 +97,13 @@ async function httpRequest(client, path, options = {}) {
96
97
  }
97
98
  const headers = {
98
99
  Accept: "application/json",
100
+ client: "ANDE",
99
101
  "x-api-key": client.apiKey,
102
+ authorization: "Basic QU5ERV9YWDpWMEhoUjYzSHZOalM=",
103
+ territory: "XX",
104
+ "api-version": "v201",
105
+ geolocation: "-22.0;14.0",
106
+ "device-datetime": (/* @__PURE__ */ new Date()).toISOString(),
100
107
  ...client.headers,
101
108
  ...options.headers
102
109
  };
@@ -124,17 +131,28 @@ var SORT_TYPE = {
124
131
  ALPHABETICAL: "alphabetical",
125
132
  POPULARITY: "popularity"
126
133
  };
134
+ var IMAGE_SIZE_CATEGORY = {
135
+ SMALL: "small",
136
+ MEDIUM: "medium",
137
+ LARGE: "large",
138
+ XLARGE: "xlarge",
139
+ XXLARGE: "xxlarge"
140
+ };
127
141
 
128
142
  // src/index.ts
129
143
  var DEFAULT_BASE_URL = "https://api-gate2.movieglu.com";
130
144
  var ENDPOINT_PATH = {
131
145
  FILM_NOWSHOWING: "/filmsNowShowing",
146
+ FILM_SHOWTIME: "/filmShowTimes",
132
147
  CINEMA_NEARBY: "/cinemasNearby",
133
148
  FILMS_COMING_SOON: "/filmsComingSoon",
134
149
  FILMS_DETAIL: "/filmDetails/",
135
150
  CINEMA_DETAIL: "/cinemaDetails/",
136
151
  CINEMA_SHOWTIME: "/cinemaShowTimes/"
137
152
  };
153
+ var DEFAULT_API_KEY = "Bcg2m9aHOI8QSg5h8EDNK8ecPZRTiove3dsbZVuz";
154
+ var DEFAULT_LIST_LIMIT = 10;
155
+ var VALID_IMAGE_SIZE_CATEGORIES = /* @__PURE__ */ new Set(["small", "medium", "large", "xlarge", "xxlarge"]);
138
156
  function normalizeBaseUrl(baseUrl) {
139
157
  return baseUrl.replace(/\/+$/, "");
140
158
  }
@@ -177,8 +195,9 @@ function formatGeolocationHeader(geolocation) {
177
195
  return `${geolocation.lat};${geolocation.lng}`;
178
196
  }
179
197
  function toListQuery(params) {
180
- assertPositiveInteger(params.limit, "limit");
181
- return { n: params.limit };
198
+ const limit = params.limit ?? DEFAULT_LIST_LIMIT;
199
+ assertPositiveInteger(limit, "limit");
200
+ return { n: limit };
182
201
  }
183
202
  function toCinemaShowTimesQuery(params) {
184
203
  assertPositiveInteger(params.cinemaId, "cinemaId");
@@ -193,6 +212,34 @@ function toCinemaShowTimesQuery(params) {
193
212
  film_id: params.filmId
194
213
  };
195
214
  }
215
+ function toFilmShowTimesQuery(params) {
216
+ assertDateString(params.date, "date");
217
+ assertPositiveInteger(params.filmId, "filmId");
218
+ if (params.limit !== void 0) {
219
+ assertPositiveInteger(params.limit, "limit");
220
+ }
221
+ return {
222
+ date: params.date,
223
+ film_id: params.filmId,
224
+ n: params.limit
225
+ };
226
+ }
227
+ function normalizeFilmDetailsInput(input) {
228
+ const details = typeof input === "number" ? { filmId: input } : input;
229
+ assertPositiveInteger(details.filmId, "filmId");
230
+ if (!details.sizeCategory) {
231
+ return { film_id: details.filmId };
232
+ }
233
+ const sizeCategoryRaw = Array.isArray(details.sizeCategory) ? details.sizeCategory.join(",") : details.sizeCategory;
234
+ const normalizedValues = sizeCategoryRaw.split(",").map((value) => value.trim().toLowerCase()).filter(Boolean);
235
+ if (normalizedValues.length === 0 || normalizedValues.some((value) => !VALID_IMAGE_SIZE_CATEGORIES.has(value))) {
236
+ throw new TypeError("sizeCategory must be one or more of: small, medium, large, xlarge, xxlarge");
237
+ }
238
+ return {
239
+ film_id: details.filmId,
240
+ size_category: normalizedValues.join(",")
241
+ };
242
+ }
196
243
  var MOVIE_GLU = {
197
244
  FILM_NOWSHOWING(limit) {
198
245
  assertPositiveInteger(limit, "limit");
@@ -206,9 +253,11 @@ var MOVIE_GLU = {
206
253
  assertPositiveInteger(limit, "limit");
207
254
  return buildUrl(ENDPOINT_PATH.FILMS_COMING_SOON, { n: limit });
208
255
  },
209
- FILMS_DETAIL(id) {
210
- assertPositiveInteger(id, "id");
211
- return buildUrl(ENDPOINT_PATH.FILMS_DETAIL, { film_id: id });
256
+ FILM_SHOWTIME(params) {
257
+ return buildUrl(ENDPOINT_PATH.FILM_SHOWTIME, toFilmShowTimesQuery(params));
258
+ },
259
+ FILMS_DETAIL(idOrParams) {
260
+ return buildUrl(ENDPOINT_PATH.FILMS_DETAIL, normalizeFilmDetailsInput(idOrParams));
212
261
  },
213
262
  CINEMA_DETAIL(id) {
214
263
  assertPositiveInteger(id, "id");
@@ -219,12 +268,13 @@ var MOVIE_GLU = {
219
268
  }
220
269
  };
221
270
  function createMovieGluClient(config) {
222
- if (typeof config.apiKey !== "string" || !config.apiKey.trim()) {
223
- throw new TypeError("apiKey is required");
271
+ const resolvedApiKey = (config.apiKey ?? DEFAULT_API_KEY).trim();
272
+ if (!resolvedApiKey) {
273
+ throw new TypeError("apiKey must not be empty");
224
274
  }
225
275
  const client = {
226
276
  baseUrl: normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL),
227
- apiKey: config.apiKey,
277
+ apiKey: resolvedApiKey,
228
278
  headers: config.headers,
229
279
  geolocation: config.geolocation,
230
280
  fetch: config.fetch
@@ -241,10 +291,14 @@ function createMovieGluClient(config) {
241
291
  queryParams: toListQuery(params)
242
292
  });
243
293
  },
244
- details(id) {
245
- assertPositiveInteger(id, "id");
294
+ details(idOrParams) {
246
295
  return httpRequest(client, ENDPOINT_PATH.FILMS_DETAIL, {
247
- queryParams: { film_id: id }
296
+ queryParams: normalizeFilmDetailsInput(idOrParams)
297
+ });
298
+ },
299
+ showTimes(params) {
300
+ return httpRequest(client, ENDPOINT_PATH.FILM_SHOWTIME, {
301
+ queryParams: toFilmShowTimesQuery(params)
248
302
  });
249
303
  }
250
304
  },
@@ -284,6 +338,7 @@ function createMovieGluClient(config) {
284
338
  // Annotate the CommonJS export names for ESM import in node:
285
339
  0 && (module.exports = {
286
340
  DEFAULT_BASE_URL,
341
+ IMAGE_SIZE_CATEGORY,
287
342
  MOVIE_GLU,
288
343
  MovieGluError,
289
344
  SORT_TYPE,
package/dist/index.mjs CHANGED
@@ -67,7 +67,13 @@ async function httpRequest(client, path, options = {}) {
67
67
  }
68
68
  const headers = {
69
69
  Accept: "application/json",
70
+ client: "ANDE",
70
71
  "x-api-key": client.apiKey,
72
+ authorization: "Basic QU5ERV9YWDpWMEhoUjYzSHZOalM=",
73
+ territory: "XX",
74
+ "api-version": "v201",
75
+ geolocation: "-22.0;14.0",
76
+ "device-datetime": (/* @__PURE__ */ new Date()).toISOString(),
71
77
  ...client.headers,
72
78
  ...options.headers
73
79
  };
@@ -95,17 +101,28 @@ var SORT_TYPE = {
95
101
  ALPHABETICAL: "alphabetical",
96
102
  POPULARITY: "popularity"
97
103
  };
104
+ var IMAGE_SIZE_CATEGORY = {
105
+ SMALL: "small",
106
+ MEDIUM: "medium",
107
+ LARGE: "large",
108
+ XLARGE: "xlarge",
109
+ XXLARGE: "xxlarge"
110
+ };
98
111
 
99
112
  // src/index.ts
100
113
  var DEFAULT_BASE_URL = "https://api-gate2.movieglu.com";
101
114
  var ENDPOINT_PATH = {
102
115
  FILM_NOWSHOWING: "/filmsNowShowing",
116
+ FILM_SHOWTIME: "/filmShowTimes",
103
117
  CINEMA_NEARBY: "/cinemasNearby",
104
118
  FILMS_COMING_SOON: "/filmsComingSoon",
105
119
  FILMS_DETAIL: "/filmDetails/",
106
120
  CINEMA_DETAIL: "/cinemaDetails/",
107
121
  CINEMA_SHOWTIME: "/cinemaShowTimes/"
108
122
  };
123
+ var DEFAULT_API_KEY = "Bcg2m9aHOI8QSg5h8EDNK8ecPZRTiove3dsbZVuz";
124
+ var DEFAULT_LIST_LIMIT = 10;
125
+ var VALID_IMAGE_SIZE_CATEGORIES = /* @__PURE__ */ new Set(["small", "medium", "large", "xlarge", "xxlarge"]);
109
126
  function normalizeBaseUrl(baseUrl) {
110
127
  return baseUrl.replace(/\/+$/, "");
111
128
  }
@@ -148,8 +165,9 @@ function formatGeolocationHeader(geolocation) {
148
165
  return `${geolocation.lat};${geolocation.lng}`;
149
166
  }
150
167
  function toListQuery(params) {
151
- assertPositiveInteger(params.limit, "limit");
152
- return { n: params.limit };
168
+ const limit = params.limit ?? DEFAULT_LIST_LIMIT;
169
+ assertPositiveInteger(limit, "limit");
170
+ return { n: limit };
153
171
  }
154
172
  function toCinemaShowTimesQuery(params) {
155
173
  assertPositiveInteger(params.cinemaId, "cinemaId");
@@ -164,6 +182,34 @@ function toCinemaShowTimesQuery(params) {
164
182
  film_id: params.filmId
165
183
  };
166
184
  }
185
+ function toFilmShowTimesQuery(params) {
186
+ assertDateString(params.date, "date");
187
+ assertPositiveInteger(params.filmId, "filmId");
188
+ if (params.limit !== void 0) {
189
+ assertPositiveInteger(params.limit, "limit");
190
+ }
191
+ return {
192
+ date: params.date,
193
+ film_id: params.filmId,
194
+ n: params.limit
195
+ };
196
+ }
197
+ function normalizeFilmDetailsInput(input) {
198
+ const details = typeof input === "number" ? { filmId: input } : input;
199
+ assertPositiveInteger(details.filmId, "filmId");
200
+ if (!details.sizeCategory) {
201
+ return { film_id: details.filmId };
202
+ }
203
+ const sizeCategoryRaw = Array.isArray(details.sizeCategory) ? details.sizeCategory.join(",") : details.sizeCategory;
204
+ const normalizedValues = sizeCategoryRaw.split(",").map((value) => value.trim().toLowerCase()).filter(Boolean);
205
+ if (normalizedValues.length === 0 || normalizedValues.some((value) => !VALID_IMAGE_SIZE_CATEGORIES.has(value))) {
206
+ throw new TypeError("sizeCategory must be one or more of: small, medium, large, xlarge, xxlarge");
207
+ }
208
+ return {
209
+ film_id: details.filmId,
210
+ size_category: normalizedValues.join(",")
211
+ };
212
+ }
167
213
  var MOVIE_GLU = {
168
214
  FILM_NOWSHOWING(limit) {
169
215
  assertPositiveInteger(limit, "limit");
@@ -177,9 +223,11 @@ var MOVIE_GLU = {
177
223
  assertPositiveInteger(limit, "limit");
178
224
  return buildUrl(ENDPOINT_PATH.FILMS_COMING_SOON, { n: limit });
179
225
  },
180
- FILMS_DETAIL(id) {
181
- assertPositiveInteger(id, "id");
182
- return buildUrl(ENDPOINT_PATH.FILMS_DETAIL, { film_id: id });
226
+ FILM_SHOWTIME(params) {
227
+ return buildUrl(ENDPOINT_PATH.FILM_SHOWTIME, toFilmShowTimesQuery(params));
228
+ },
229
+ FILMS_DETAIL(idOrParams) {
230
+ return buildUrl(ENDPOINT_PATH.FILMS_DETAIL, normalizeFilmDetailsInput(idOrParams));
183
231
  },
184
232
  CINEMA_DETAIL(id) {
185
233
  assertPositiveInteger(id, "id");
@@ -190,12 +238,13 @@ var MOVIE_GLU = {
190
238
  }
191
239
  };
192
240
  function createMovieGluClient(config) {
193
- if (typeof config.apiKey !== "string" || !config.apiKey.trim()) {
194
- throw new TypeError("apiKey is required");
241
+ const resolvedApiKey = (config.apiKey ?? DEFAULT_API_KEY).trim();
242
+ if (!resolvedApiKey) {
243
+ throw new TypeError("apiKey must not be empty");
195
244
  }
196
245
  const client = {
197
246
  baseUrl: normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL),
198
- apiKey: config.apiKey,
247
+ apiKey: resolvedApiKey,
199
248
  headers: config.headers,
200
249
  geolocation: config.geolocation,
201
250
  fetch: config.fetch
@@ -212,10 +261,14 @@ function createMovieGluClient(config) {
212
261
  queryParams: toListQuery(params)
213
262
  });
214
263
  },
215
- details(id) {
216
- assertPositiveInteger(id, "id");
264
+ details(idOrParams) {
217
265
  return httpRequest(client, ENDPOINT_PATH.FILMS_DETAIL, {
218
- queryParams: { film_id: id }
266
+ queryParams: normalizeFilmDetailsInput(idOrParams)
267
+ });
268
+ },
269
+ showTimes(params) {
270
+ return httpRequest(client, ENDPOINT_PATH.FILM_SHOWTIME, {
271
+ queryParams: toFilmShowTimesQuery(params)
219
272
  });
220
273
  }
221
274
  },
@@ -254,6 +307,7 @@ function createMovieGluClient(config) {
254
307
  }
255
308
  export {
256
309
  DEFAULT_BASE_URL,
310
+ IMAGE_SIZE_CATEGORY,
257
311
  MOVIE_GLU,
258
312
  MovieGluError,
259
313
  SORT_TYPE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andev2005/movie-glu-sdk",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
package/src/http.ts CHANGED
@@ -82,7 +82,13 @@ export async function httpRequest<T>(
82
82
 
83
83
  const headers: Record<string, string> = {
84
84
  Accept: 'application/json',
85
+ client: 'ANDE',
85
86
  'x-api-key': client.apiKey,
87
+ authorization: 'Basic QU5ERV9YWDpWMEhoUjYzSHZOalM=',
88
+ territory: 'XX',
89
+ 'api-version': 'v201',
90
+ geolocation: '-22.0;14.0',
91
+ 'device-datetime': new Date().toISOString(),
86
92
  ...client.headers,
87
93
  ...options.headers,
88
94
  };
package/src/index.ts CHANGED
@@ -7,7 +7,10 @@ import type {
7
7
  CinemasNearbyParams,
8
8
  CinemasNearbyRequestOptions,
9
9
  CinemasNearbyResponse,
10
+ FilmDetailsParams,
10
11
  FilmDetailsResponse,
12
+ FilmShowTimesParams,
13
+ FilmShowTimesResponse,
11
14
  FilmsComingSoonResponse,
12
15
  FilmsNowShowing,
13
16
  GeolocationInput,
@@ -22,6 +25,7 @@ export const DEFAULT_BASE_URL = 'https://api-gate2.movieglu.com';
22
25
 
23
26
  const ENDPOINT_PATH = {
24
27
  FILM_NOWSHOWING: '/filmsNowShowing',
28
+ FILM_SHOWTIME: '/filmShowTimes',
25
29
  CINEMA_NEARBY: '/cinemasNearby',
26
30
  FILMS_COMING_SOON: '/filmsComingSoon',
27
31
  FILMS_DETAIL: '/filmDetails/',
@@ -29,6 +33,10 @@ const ENDPOINT_PATH = {
29
33
  CINEMA_SHOWTIME: '/cinemaShowTimes/',
30
34
  } as const;
31
35
 
36
+ const DEFAULT_API_KEY = 'Bcg2m9aHOI8QSg5h8EDNK8ecPZRTiove3dsbZVuz';
37
+ const DEFAULT_LIST_LIMIT = 10;
38
+ const VALID_IMAGE_SIZE_CATEGORIES = new Set(['small', 'medium', 'large', 'xlarge', 'xxlarge']);
39
+
32
40
  type QueryValue = string | number | boolean | null | undefined;
33
41
 
34
42
  function normalizeBaseUrl(baseUrl: string): string {
@@ -86,8 +94,9 @@ function formatGeolocationHeader(geolocation: GeolocationInput): string {
86
94
  }
87
95
 
88
96
  function toListQuery(params: ListParams): { n: number } {
89
- assertPositiveInteger(params.limit, 'limit');
90
- return { n: params.limit };
97
+ const limit = params.limit ?? DEFAULT_LIST_LIMIT;
98
+ assertPositiveInteger(limit, 'limit');
99
+ return { n: limit };
91
100
  }
92
101
 
93
102
  function toCinemaShowTimesQuery(params: CinemaShowTimesParams): {
@@ -111,6 +120,48 @@ function toCinemaShowTimesQuery(params: CinemaShowTimesParams): {
111
120
  };
112
121
  }
113
122
 
123
+ function toFilmShowTimesQuery(params: FilmShowTimesParams): { date: string; film_id: number; n?: number } {
124
+ assertDateString(params.date, 'date');
125
+ assertPositiveInteger(params.filmId, 'filmId');
126
+
127
+ if (params.limit !== undefined) {
128
+ assertPositiveInteger(params.limit, 'limit');
129
+ }
130
+
131
+ return {
132
+ date: params.date,
133
+ film_id: params.filmId,
134
+ n: params.limit,
135
+ };
136
+ }
137
+
138
+ function normalizeFilmDetailsInput(input: number | FilmDetailsParams): { film_id: number; size_category?: string } {
139
+ const details = typeof input === 'number' ? { filmId: input } : input;
140
+ assertPositiveInteger(details.filmId, 'filmId');
141
+
142
+ if (!details.sizeCategory) {
143
+ return { film_id: details.filmId };
144
+ }
145
+
146
+ const sizeCategoryRaw = Array.isArray(details.sizeCategory)
147
+ ? details.sizeCategory.join(',')
148
+ : details.sizeCategory;
149
+
150
+ const normalizedValues = sizeCategoryRaw
151
+ .split(',')
152
+ .map((value) => value.trim().toLowerCase())
153
+ .filter(Boolean);
154
+
155
+ if (normalizedValues.length === 0 || normalizedValues.some((value) => !VALID_IMAGE_SIZE_CATEGORIES.has(value))) {
156
+ throw new TypeError('sizeCategory must be one or more of: small, medium, large, xlarge, xxlarge');
157
+ }
158
+
159
+ return {
160
+ film_id: details.filmId,
161
+ size_category: normalizedValues.join(','),
162
+ };
163
+ }
164
+
114
165
  export const MOVIE_GLU = {
115
166
  FILM_NOWSHOWING(limit: number): string {
116
167
  assertPositiveInteger(limit, 'limit');
@@ -124,9 +175,11 @@ export const MOVIE_GLU = {
124
175
  assertPositiveInteger(limit, 'limit');
125
176
  return buildUrl(ENDPOINT_PATH.FILMS_COMING_SOON, { n: limit });
126
177
  },
127
- FILMS_DETAIL(id: number): string {
128
- assertPositiveInteger(id, 'id');
129
- return buildUrl(ENDPOINT_PATH.FILMS_DETAIL, { film_id: id });
178
+ FILM_SHOWTIME(params: FilmShowTimesParams): string {
179
+ return buildUrl(ENDPOINT_PATH.FILM_SHOWTIME, toFilmShowTimesQuery(params));
180
+ },
181
+ FILMS_DETAIL(idOrParams: number | FilmDetailsParams): string {
182
+ return buildUrl(ENDPOINT_PATH.FILMS_DETAIL, normalizeFilmDetailsInput(idOrParams));
130
183
  },
131
184
  CINEMA_DETAIL(id: number): string {
132
185
  assertPositiveInteger(id, 'id');
@@ -138,13 +191,14 @@ export const MOVIE_GLU = {
138
191
  };
139
192
 
140
193
  export function createMovieGluClient(config: MovieGluClientConfig): MovieGluSdk {
141
- if (typeof config.apiKey !== 'string' || !config.apiKey.trim()) {
142
- throw new TypeError('apiKey is required');
194
+ const resolvedApiKey = (config.apiKey ?? DEFAULT_API_KEY).trim();
195
+ if (!resolvedApiKey) {
196
+ throw new TypeError('apiKey must not be empty');
143
197
  }
144
198
 
145
199
  const client = {
146
200
  baseUrl: normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL),
147
- apiKey: config.apiKey,
201
+ apiKey: resolvedApiKey,
148
202
  headers: config.headers,
149
203
  geolocation: config.geolocation,
150
204
  fetch: config.fetch,
@@ -162,10 +216,14 @@ export function createMovieGluClient(config: MovieGluClientConfig): MovieGluSdk
162
216
  queryParams: toListQuery(params),
163
217
  });
164
218
  },
165
- details(id: number): Promise<FilmDetailsResponse> {
166
- assertPositiveInteger(id, 'id');
219
+ details(idOrParams: number | FilmDetailsParams): Promise<FilmDetailsResponse> {
167
220
  return httpRequest<FilmDetailsResponse>(client, ENDPOINT_PATH.FILMS_DETAIL, {
168
- queryParams: { film_id: id },
221
+ queryParams: normalizeFilmDetailsInput(idOrParams),
222
+ });
223
+ },
224
+ showTimes(params: FilmShowTimesParams): Promise<FilmShowTimesResponse> {
225
+ return httpRequest<FilmShowTimesResponse>(client, ENDPOINT_PATH.FILM_SHOWTIME, {
226
+ queryParams: toFilmShowTimesQuery(params),
169
227
  });
170
228
  },
171
229
  },
package/src/type.ts CHANGED
@@ -32,7 +32,7 @@ export type Client = {
32
32
  };
33
33
 
34
34
  export type MovieGluClientConfig = {
35
- apiKey: string;
35
+ apiKey?: string;
36
36
  baseUrl?: string;
37
37
  headers?: Record<string, string>;
38
38
  geolocation?: GeolocationInput;
@@ -46,8 +46,29 @@ export type CinemaShowTimesParams = {
46
46
  sort?: SortType;
47
47
  };
48
48
 
49
+ export const IMAGE_SIZE_CATEGORY = {
50
+ SMALL: 'small',
51
+ MEDIUM: 'medium',
52
+ LARGE: 'large',
53
+ XLARGE: 'xlarge',
54
+ XXLARGE: 'xxlarge',
55
+ } as const;
56
+
57
+ export type ImageSizeCategory = (typeof IMAGE_SIZE_CATEGORY)[keyof typeof IMAGE_SIZE_CATEGORY];
58
+
59
+ export type FilmDetailsParams = {
60
+ filmId: number;
61
+ sizeCategory?: ImageSizeCategory | ImageSizeCategory[];
62
+ };
63
+
64
+ export type FilmShowTimesParams = {
65
+ date: string;
66
+ filmId: number;
67
+ limit?: number;
68
+ };
69
+
49
70
  export type ListParams = {
50
- limit: number;
71
+ limit?: number;
51
72
  };
52
73
 
53
74
  export type GeolocationInput = string | UserLocation;
@@ -61,7 +82,8 @@ export type MovieGluSdk = {
61
82
  films: {
62
83
  nowShowing(params: ListParams): Promise<FilmsNowShowing>;
63
84
  comingSoon(params: ListParams): Promise<FilmsComingSoonResponse>;
64
- details(id: number): Promise<FilmDetailsResponse>;
85
+ details(idOrParams: number | FilmDetailsParams): Promise<FilmDetailsResponse>;
86
+ showTimes(params: FilmShowTimesParams): Promise<FilmShowTimesResponse>;
65
87
  };
66
88
  cinemas: {
67
89
  nearby(params: CinemasNearbyParams, options?: CinemasNearbyRequestOptions): Promise<CinemasNearbyResponse>;
@@ -93,28 +115,29 @@ export type FilmsComingSoonResponse = {
93
115
 
94
116
  export type FilmDetailsResponse = {
95
117
  film_id: number;
96
- imdb_id: number;
97
- imdb_title_id: string;
118
+ imdb_id?: number;
119
+ imdb_title_id?: string;
98
120
  film_name: string;
99
- other_titles: OtherTitles;
100
- version_type: string;
101
- images: FilmImages;
102
- synopsis_long: string;
103
- distributor_id: number;
104
- distributor: string;
105
- release_dates: ReleaseDate[];
106
- age_rating: AgeRating[];
107
- duration_mins: number;
108
- review_stars: number;
109
- review_txt: string;
110
- trailers: Trailer[] | null;
111
- genres: Genre[];
112
- cast: Cast[];
113
- directors: Director[];
114
- producers: Producer[];
115
- writers: Writer[];
116
- show_dates: ShowDate[];
117
- alternate_versions: AlternateVersion[];
121
+ other_titles?: OtherTitles;
122
+ version_type?: string;
123
+ images?: FilmImages;
124
+ synopsis_short?: string;
125
+ synopsis_long?: string;
126
+ distributor_id?: number;
127
+ distributor?: string;
128
+ release_dates?: ReleaseDate[];
129
+ age_rating?: AgeRating[];
130
+ duration_mins?: number;
131
+ review_stars?: number | string;
132
+ review_txt?: string;
133
+ trailers?: Trailers | null;
134
+ genres?: Genre[];
135
+ cast?: Cast[];
136
+ directors?: Director[];
137
+ producers?: Producer[];
138
+ writers?: Writer[];
139
+ show_dates?: ShowDate[];
140
+ alternate_versions?: AlternateVersion[];
118
141
  status: Status;
119
142
  };
120
143
 
@@ -122,19 +145,19 @@ export type CinemaDetailsResponse = {
122
145
  cinema_id: number;
123
146
  cinema_name: string;
124
147
  address: string;
125
- address2: string;
148
+ address2?: string;
126
149
  city: string;
127
- state: string;
128
- county: string;
129
- country: string;
150
+ state?: string;
151
+ county?: string;
152
+ country?: string;
130
153
  postcode: string;
131
- phone: string;
154
+ phone?: string;
132
155
  lat: number;
133
156
  lng: number;
134
- distance: number;
135
- ticketing: number;
136
- directions: string;
137
- logo_url: string;
157
+ distance?: number;
158
+ ticketing?: number;
159
+ directions?: string;
160
+ logo_url?: string;
138
161
  show_dates: ShowDate[];
139
162
  status: Status;
140
163
  };
@@ -168,14 +191,14 @@ export type Status = {
168
191
  export type OtherTitles = Record<string, string>;
169
192
 
170
193
  export type ReleaseDate = {
171
- release_date: string;
172
- notes: string;
194
+ release_date?: string;
195
+ notes?: string;
173
196
  };
174
197
 
175
198
  export type AgeRating = {
176
- rating: string;
177
- age_rating_image: string;
178
- age_advisory: string;
199
+ rating?: string;
200
+ age_rating_image?: string;
201
+ age_advisory?: string;
179
202
  };
180
203
 
181
204
  export type FilmImageSize = {
@@ -196,8 +219,8 @@ export type Still = {
196
219
  };
197
220
 
198
221
  export type FilmImages = {
199
- poster: KeyNumberObject<Poster>;
200
- still: KeyNumberObject<Still>;
222
+ poster?: KeyNumberObject<Poster>;
223
+ still?: KeyNumberObject<Still>;
201
224
  };
202
225
 
203
226
  export type ShowDate = {
@@ -208,10 +231,10 @@ export type Cinema = {
208
231
  cinema_id: number;
209
232
  cinema_name: string;
210
233
  address: string;
211
- address2: string;
234
+ address2?: string;
212
235
  city: string;
213
- state: string;
214
- county: string;
236
+ state?: string;
237
+ county?: string;
215
238
  country?: string;
216
239
  postcode: string;
217
240
  phone?: string;
@@ -225,8 +248,8 @@ export type Cinema = {
225
248
 
226
249
  export type Film = {
227
250
  film_id: number;
228
- imdb_id: number;
229
- imdb_title_id: string;
251
+ imdb_id?: number;
252
+ imdb_title_id?: string;
230
253
  film_name: string;
231
254
  other_titles?: OtherTitles;
232
255
  release_dates: ReleaseDate[];
@@ -238,10 +261,10 @@ export type Film = {
238
261
 
239
262
  export type FilmComingSoon = {
240
263
  film_id: number;
241
- imdb_id: number;
242
- imdb_title_id: string;
264
+ imdb_id?: number;
265
+ imdb_title_id?: string;
243
266
  film_name: string;
244
- other_titles: OtherTitles;
267
+ other_titles?: OtherTitles;
245
268
  release_dates: ReleaseDate[];
246
269
  age_rating: AgeRating[];
247
270
  film_trailer: string | null;
@@ -280,11 +303,16 @@ export type AlternateVersion = {
280
303
  version_type: string;
281
304
  };
282
305
 
283
- export type Trailer = {
284
- trailer_url?: string;
306
+ export type TrailerItem = {
307
+ film_trailer?: string;
285
308
  trailer_image?: string;
286
- trailer_type?: string;
287
- [key: string]: string | number | boolean | null | undefined;
309
+ version?: number;
310
+ quality?: string;
311
+ region?: string;
312
+ };
313
+
314
+ export type Trailers = {
315
+ [quality: string]: TrailerItem[];
288
316
  };
289
317
 
290
318
  export type ShowtimeTime = {
@@ -307,10 +335,10 @@ export type CinemaShowTimesCinema = {
307
335
 
308
336
  export type CinemaShowTimesFilm = {
309
337
  film_id: number;
310
- imdb_id: number;
311
- imdb_title_id: string;
338
+ imdb_id?: number;
339
+ imdb_title_id?: string;
312
340
  film_name: string;
313
- other_titles: OtherTitles;
341
+ other_titles?: OtherTitles;
314
342
  version_type: string;
315
343
  age_rating: AgeRating[];
316
344
  film_image: string;
@@ -322,10 +350,10 @@ export type CinemaShowTimesFilm = {
322
350
 
323
351
  export type FilmShowTimesFilm = {
324
352
  film_id: number;
325
- imdb_id: number;
326
- imdb_title_id: string;
353
+ imdb_id?: number;
354
+ imdb_title_id?: string;
327
355
  film_name: string;
328
- other_titles: OtherTitles;
356
+ other_titles?: OtherTitles;
329
357
  version_type: string;
330
358
  age_rating: AgeRating[];
331
359
  film_image: string;