@andev2005/movie-glu-sdk 1.0.0 → 1.0.2
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 +167 -0
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +40 -4
- package/dist/index.mjs +40 -4
- package/package.json +1 -1
- package/src/index.ts +48 -2
- package/src/type.ts +11 -2
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# @andev2005/movie-glu-sdk
|
|
2
|
+
|
|
3
|
+
SDK Node.js/TypeScript để gọi MovieGlu API (phim đang chiếu, phim sắp chiếu, rạp gần đây, chi tiết phim/rạp, lịch chiếu).
|
|
4
|
+
|
|
5
|
+
## Cài đặt
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @andev2005/movie-glu-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Hoặc:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm i @andev2005/movie-glu-sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Yêu cầu
|
|
18
|
+
|
|
19
|
+
- Có `apiKey` của MovieGlu
|
|
20
|
+
- Runtime có `fetch` (Node.js 18+) hoặc truyền `fetch` custom vào client
|
|
21
|
+
|
|
22
|
+
## Sử dụng nhanh
|
|
23
|
+
|
|
24
|
+
### TypeScript / JavaScript
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { createMovieGluClient } from '@andev2005/movie-glu-sdk';
|
|
28
|
+
|
|
29
|
+
const movieGlu = createMovieGluClient({
|
|
30
|
+
apiKey: process.env.MOVIE_GLU_API_KEY!,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
async function main() {
|
|
34
|
+
const nowShowing = await movieGlu.films.nowShowing({ limit: 10 });
|
|
35
|
+
console.log(nowShowing.films);
|
|
36
|
+
|
|
37
|
+
const comingSoon = await movieGlu.films.comingSoon({ limit: 10 });
|
|
38
|
+
console.log(comingSoon.films);
|
|
39
|
+
|
|
40
|
+
const cinemas = await movieGlu.cinemas.nearby({ limit: 5 });
|
|
41
|
+
console.log(cinemas.cinemas);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
main().catch(console.error);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Khởi tạo client
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { createMovieGluClient } from '@andev2005/movie-glu-sdk';
|
|
51
|
+
|
|
52
|
+
const client = createMovieGluClient({
|
|
53
|
+
apiKey: 'your-api-key',
|
|
54
|
+
// Tuỳ chọn:
|
|
55
|
+
// baseUrl: 'https://api-gate2.movieglu.com',
|
|
56
|
+
// headers: { 'x-custom-header': 'value' },
|
|
57
|
+
// fetch: customFetch, // dùng khi môi trường không có global fetch
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## API hiện có
|
|
62
|
+
|
|
63
|
+
### `films`
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
// Phim đang chiếu
|
|
67
|
+
await client.films.nowShowing({ limit: 10 });
|
|
68
|
+
|
|
69
|
+
// Phim sắp chiếu
|
|
70
|
+
await client.films.comingSoon({ limit: 10 });
|
|
71
|
+
|
|
72
|
+
// Chi tiết phim
|
|
73
|
+
await client.films.details(12345);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `cinemas`
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
// Rạp gần đây
|
|
80
|
+
await client.cinemas.nearby({ limit: 10 });
|
|
81
|
+
|
|
82
|
+
// Chi tiết rạp
|
|
83
|
+
await client.cinemas.details(1001);
|
|
84
|
+
|
|
85
|
+
// Lịch chiếu rạp theo ngày
|
|
86
|
+
await client.cinemas.showTimes({
|
|
87
|
+
cinemaId: 1001,
|
|
88
|
+
date: '2026-02-25', // YYYY-MM-DD
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Lọc lịch chiếu theo phim + sắp xếp
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { SORT_TYPE } from '@andev2005/movie-glu-sdk';
|
|
96
|
+
|
|
97
|
+
await client.cinemas.showTimes({
|
|
98
|
+
cinemaId: 1001,
|
|
99
|
+
filmId: 12345,
|
|
100
|
+
date: '2026-02-25',
|
|
101
|
+
sort: SORT_TYPE.POPULARITY, // hoặc SORT_TYPE.ALPHABETICAL
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Xử lý lỗi
|
|
106
|
+
|
|
107
|
+
SDK sẽ throw `MovieGluError` nếu request thất bại (HTTP status không thành công).
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { MovieGluError } from '@andev2005/movie-glu-sdk';
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const data = await client.films.nowShowing({ limit: 10 });
|
|
114
|
+
console.log(data);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
if (error instanceof MovieGluError) {
|
|
117
|
+
console.error('MovieGluError:', error.message);
|
|
118
|
+
console.error('status:', error.status);
|
|
119
|
+
console.error('details:', error.details);
|
|
120
|
+
} else {
|
|
121
|
+
console.error(error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Validate tham số
|
|
127
|
+
|
|
128
|
+
SDK có kiểm tra đầu vào và sẽ throw `TypeError` nếu:
|
|
129
|
+
|
|
130
|
+
- `apiKey` bị thiếu/rỗng
|
|
131
|
+
- `limit` không phải số nguyên dương
|
|
132
|
+
- `id`, `cinemaId`, `filmId` không phải số nguyên dương
|
|
133
|
+
- `date` không đúng định dạng `YYYY-MM-DD`
|
|
134
|
+
|
|
135
|
+
## Utility build URL (tuỳ chọn)
|
|
136
|
+
|
|
137
|
+
Nếu bạn chỉ muốn lấy URL endpoint (không gửi request), có thể dùng `MOVIE_GLU`:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { MOVIE_GLU } from '@andev2005/movie-glu-sdk';
|
|
141
|
+
|
|
142
|
+
const url = MOVIE_GLU.FILM_NOWSHOWING(10);
|
|
143
|
+
console.log(url);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Các helper có sẵn:
|
|
147
|
+
|
|
148
|
+
- `MOVIE_GLU.FILM_NOWSHOWING(limit)`
|
|
149
|
+
- `MOVIE_GLU.CINEMA_NEARBY(limit)`
|
|
150
|
+
- `MOVIE_GLU.FILMS_COMING_SOON(limit)`
|
|
151
|
+
- `MOVIE_GLU.FILMS_DETAIL(id)`
|
|
152
|
+
- `MOVIE_GLU.CINEMA_DETAIL(id)`
|
|
153
|
+
- `MOVIE_GLU.CINEMA_SHOWTIME({ cinemaId, date, filmId?, sort? })`
|
|
154
|
+
|
|
155
|
+
## Export chính
|
|
156
|
+
|
|
157
|
+
- `createMovieGluClient`
|
|
158
|
+
- `MOVIE_GLU`
|
|
159
|
+
- `SORT_TYPE`
|
|
160
|
+
- `MovieGluError`
|
|
161
|
+
- Tất cả TypeScript types (`FilmDetailsResponse`, `CinemaShowTimesResponse`, ...)
|
|
162
|
+
|
|
163
|
+
## Build package
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npm run build
|
|
167
|
+
```
|
package/dist/index.d.mts
CHANGED
|
@@ -22,12 +22,14 @@ type Client = {
|
|
|
22
22
|
baseUrl: string;
|
|
23
23
|
apiKey: string;
|
|
24
24
|
headers?: Record<string, string>;
|
|
25
|
+
geolocation?: GeolocationInput;
|
|
25
26
|
fetch?: FetchLike;
|
|
26
27
|
};
|
|
27
28
|
type MovieGluClientConfig = {
|
|
28
29
|
apiKey: string;
|
|
29
30
|
baseUrl?: string;
|
|
30
31
|
headers?: Record<string, string>;
|
|
32
|
+
geolocation?: GeolocationInput;
|
|
31
33
|
fetch?: FetchLike;
|
|
32
34
|
};
|
|
33
35
|
type CinemaShowTimesParams = {
|
|
@@ -39,6 +41,10 @@ type CinemaShowTimesParams = {
|
|
|
39
41
|
type ListParams = {
|
|
40
42
|
limit: number;
|
|
41
43
|
};
|
|
44
|
+
type GeolocationInput = string | UserLocation;
|
|
45
|
+
type CinemasNearbyParams = ListParams;
|
|
46
|
+
type CinemasNearbyRequestOptions = Pick<RequestOptions, 'headers'>;
|
|
47
|
+
type CinemaDetailsRequestOptions = Pick<RequestOptions, 'headers'>;
|
|
42
48
|
type MovieGluSdk = {
|
|
43
49
|
films: {
|
|
44
50
|
nowShowing(params: ListParams): Promise<FilmsNowShowing>;
|
|
@@ -46,8 +52,8 @@ type MovieGluSdk = {
|
|
|
46
52
|
details(id: number): Promise<FilmDetailsResponse>;
|
|
47
53
|
};
|
|
48
54
|
cinemas: {
|
|
49
|
-
nearby(params:
|
|
50
|
-
details(id: number): Promise<CinemaDetailsResponse>;
|
|
55
|
+
nearby(params: CinemasNearbyParams, options?: CinemasNearbyRequestOptions): Promise<CinemasNearbyResponse>;
|
|
56
|
+
details(id: number, options?: CinemaDetailsRequestOptions): Promise<CinemaDetailsResponse>;
|
|
51
57
|
showTimes(params: CinemaShowTimesParams): Promise<CinemaShowTimesResponse>;
|
|
52
58
|
};
|
|
53
59
|
};
|
|
@@ -310,4 +316,4 @@ declare const MOVIE_GLU: {
|
|
|
310
316
|
};
|
|
311
317
|
declare function createMovieGluClient(config: MovieGluClientConfig): MovieGluSdk;
|
|
312
318
|
|
|
313
|
-
export { type AgeRating, type AlternateVersion, type Cast, type Cinema, type CinemaDetailsResponse, type CinemaShowTimesCinema, type CinemaShowTimesFilm, type CinemaShowTimesParams, type CinemaShowTimesResponse, 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 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 };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -22,12 +22,14 @@ type Client = {
|
|
|
22
22
|
baseUrl: string;
|
|
23
23
|
apiKey: string;
|
|
24
24
|
headers?: Record<string, string>;
|
|
25
|
+
geolocation?: GeolocationInput;
|
|
25
26
|
fetch?: FetchLike;
|
|
26
27
|
};
|
|
27
28
|
type MovieGluClientConfig = {
|
|
28
29
|
apiKey: string;
|
|
29
30
|
baseUrl?: string;
|
|
30
31
|
headers?: Record<string, string>;
|
|
32
|
+
geolocation?: GeolocationInput;
|
|
31
33
|
fetch?: FetchLike;
|
|
32
34
|
};
|
|
33
35
|
type CinemaShowTimesParams = {
|
|
@@ -39,6 +41,10 @@ type CinemaShowTimesParams = {
|
|
|
39
41
|
type ListParams = {
|
|
40
42
|
limit: number;
|
|
41
43
|
};
|
|
44
|
+
type GeolocationInput = string | UserLocation;
|
|
45
|
+
type CinemasNearbyParams = ListParams;
|
|
46
|
+
type CinemasNearbyRequestOptions = Pick<RequestOptions, 'headers'>;
|
|
47
|
+
type CinemaDetailsRequestOptions = Pick<RequestOptions, 'headers'>;
|
|
42
48
|
type MovieGluSdk = {
|
|
43
49
|
films: {
|
|
44
50
|
nowShowing(params: ListParams): Promise<FilmsNowShowing>;
|
|
@@ -46,8 +52,8 @@ type MovieGluSdk = {
|
|
|
46
52
|
details(id: number): Promise<FilmDetailsResponse>;
|
|
47
53
|
};
|
|
48
54
|
cinemas: {
|
|
49
|
-
nearby(params:
|
|
50
|
-
details(id: number): Promise<CinemaDetailsResponse>;
|
|
55
|
+
nearby(params: CinemasNearbyParams, options?: CinemasNearbyRequestOptions): Promise<CinemasNearbyResponse>;
|
|
56
|
+
details(id: number, options?: CinemaDetailsRequestOptions): Promise<CinemaDetailsResponse>;
|
|
51
57
|
showTimes(params: CinemaShowTimesParams): Promise<CinemaShowTimesResponse>;
|
|
52
58
|
};
|
|
53
59
|
};
|
|
@@ -310,4 +316,4 @@ declare const MOVIE_GLU: {
|
|
|
310
316
|
};
|
|
311
317
|
declare function createMovieGluClient(config: MovieGluClientConfig): MovieGluSdk;
|
|
312
318
|
|
|
313
|
-
export { type AgeRating, type AlternateVersion, type Cast, type Cinema, type CinemaDetailsResponse, type CinemaShowTimesCinema, type CinemaShowTimesFilm, type CinemaShowTimesParams, type CinemaShowTimesResponse, 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 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -154,11 +154,28 @@ function assertPositiveInteger(value, name) {
|
|
|
154
154
|
throw new TypeError(`${name} must be a positive integer`);
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
|
+
function assertFiniteNumber(value, name) {
|
|
158
|
+
if (!Number.isFinite(value)) {
|
|
159
|
+
throw new TypeError(`${name} must be a finite number`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
157
162
|
function assertDateString(value, name) {
|
|
158
163
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
159
164
|
throw new TypeError(`${name} must be in YYYY-MM-DD format`);
|
|
160
165
|
}
|
|
161
166
|
}
|
|
167
|
+
function formatGeolocationHeader(geolocation) {
|
|
168
|
+
if (typeof geolocation === "string") {
|
|
169
|
+
const value = geolocation.trim();
|
|
170
|
+
if (!value) {
|
|
171
|
+
throw new TypeError("geolocation header must not be empty");
|
|
172
|
+
}
|
|
173
|
+
return value;
|
|
174
|
+
}
|
|
175
|
+
assertFiniteNumber(geolocation.lat, "geolocation.lat");
|
|
176
|
+
assertFiniteNumber(geolocation.lng, "geolocation.lng");
|
|
177
|
+
return `${geolocation.lat};${geolocation.lng}`;
|
|
178
|
+
}
|
|
162
179
|
function toListQuery(params) {
|
|
163
180
|
assertPositiveInteger(params.limit, "limit");
|
|
164
181
|
return { n: params.limit };
|
|
@@ -209,6 +226,7 @@ function createMovieGluClient(config) {
|
|
|
209
226
|
baseUrl: normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL),
|
|
210
227
|
apiKey: config.apiKey,
|
|
211
228
|
headers: config.headers,
|
|
229
|
+
geolocation: config.geolocation,
|
|
212
230
|
fetch: config.fetch
|
|
213
231
|
};
|
|
214
232
|
return {
|
|
@@ -231,15 +249,33 @@ function createMovieGluClient(config) {
|
|
|
231
249
|
}
|
|
232
250
|
},
|
|
233
251
|
cinemas: {
|
|
234
|
-
nearby(params) {
|
|
252
|
+
nearby(params, options) {
|
|
253
|
+
var _a;
|
|
254
|
+
const geolocationHeader = (_a = options == null ? void 0 : options.headers) == null ? void 0 : _a.geolocation;
|
|
255
|
+
const geolocation = geolocationHeader ?? client.geolocation;
|
|
256
|
+
if (!geolocation) {
|
|
257
|
+
throw new TypeError(
|
|
258
|
+
"geolocation header is required for cinemas.nearby. Pass nearby(..., { headers: { geolocation } }) or createMovieGluClient({ geolocation })."
|
|
259
|
+
);
|
|
260
|
+
}
|
|
235
261
|
return httpRequest(client, ENDPOINT_PATH.CINEMA_NEARBY, {
|
|
236
|
-
queryParams: toListQuery(params)
|
|
262
|
+
queryParams: toListQuery(params),
|
|
263
|
+
headers: {
|
|
264
|
+
...options == null ? void 0 : options.headers,
|
|
265
|
+
geolocation: formatGeolocationHeader(geolocation)
|
|
266
|
+
}
|
|
237
267
|
});
|
|
238
268
|
},
|
|
239
|
-
details(id) {
|
|
269
|
+
details(id, options) {
|
|
270
|
+
var _a;
|
|
240
271
|
assertPositiveInteger(id, "id");
|
|
272
|
+
const geolocationHeader = (_a = options == null ? void 0 : options.headers) == null ? void 0 : _a.geolocation;
|
|
241
273
|
return httpRequest(client, ENDPOINT_PATH.CINEMA_DETAIL, {
|
|
242
|
-
queryParams: { cinema_id: id }
|
|
274
|
+
queryParams: { cinema_id: id },
|
|
275
|
+
headers: {
|
|
276
|
+
...options == null ? void 0 : options.headers,
|
|
277
|
+
...geolocationHeader ? { geolocation: formatGeolocationHeader(geolocationHeader) } : {}
|
|
278
|
+
}
|
|
243
279
|
});
|
|
244
280
|
},
|
|
245
281
|
showTimes(params) {
|
package/dist/index.mjs
CHANGED
|
@@ -125,11 +125,28 @@ function assertPositiveInteger(value, name) {
|
|
|
125
125
|
throw new TypeError(`${name} must be a positive integer`);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
+
function assertFiniteNumber(value, name) {
|
|
129
|
+
if (!Number.isFinite(value)) {
|
|
130
|
+
throw new TypeError(`${name} must be a finite number`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
128
133
|
function assertDateString(value, name) {
|
|
129
134
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
130
135
|
throw new TypeError(`${name} must be in YYYY-MM-DD format`);
|
|
131
136
|
}
|
|
132
137
|
}
|
|
138
|
+
function formatGeolocationHeader(geolocation) {
|
|
139
|
+
if (typeof geolocation === "string") {
|
|
140
|
+
const value = geolocation.trim();
|
|
141
|
+
if (!value) {
|
|
142
|
+
throw new TypeError("geolocation header must not be empty");
|
|
143
|
+
}
|
|
144
|
+
return value;
|
|
145
|
+
}
|
|
146
|
+
assertFiniteNumber(geolocation.lat, "geolocation.lat");
|
|
147
|
+
assertFiniteNumber(geolocation.lng, "geolocation.lng");
|
|
148
|
+
return `${geolocation.lat};${geolocation.lng}`;
|
|
149
|
+
}
|
|
133
150
|
function toListQuery(params) {
|
|
134
151
|
assertPositiveInteger(params.limit, "limit");
|
|
135
152
|
return { n: params.limit };
|
|
@@ -180,6 +197,7 @@ function createMovieGluClient(config) {
|
|
|
180
197
|
baseUrl: normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL),
|
|
181
198
|
apiKey: config.apiKey,
|
|
182
199
|
headers: config.headers,
|
|
200
|
+
geolocation: config.geolocation,
|
|
183
201
|
fetch: config.fetch
|
|
184
202
|
};
|
|
185
203
|
return {
|
|
@@ -202,15 +220,33 @@ function createMovieGluClient(config) {
|
|
|
202
220
|
}
|
|
203
221
|
},
|
|
204
222
|
cinemas: {
|
|
205
|
-
nearby(params) {
|
|
223
|
+
nearby(params, options) {
|
|
224
|
+
var _a;
|
|
225
|
+
const geolocationHeader = (_a = options == null ? void 0 : options.headers) == null ? void 0 : _a.geolocation;
|
|
226
|
+
const geolocation = geolocationHeader ?? client.geolocation;
|
|
227
|
+
if (!geolocation) {
|
|
228
|
+
throw new TypeError(
|
|
229
|
+
"geolocation header is required for cinemas.nearby. Pass nearby(..., { headers: { geolocation } }) or createMovieGluClient({ geolocation })."
|
|
230
|
+
);
|
|
231
|
+
}
|
|
206
232
|
return httpRequest(client, ENDPOINT_PATH.CINEMA_NEARBY, {
|
|
207
|
-
queryParams: toListQuery(params)
|
|
233
|
+
queryParams: toListQuery(params),
|
|
234
|
+
headers: {
|
|
235
|
+
...options == null ? void 0 : options.headers,
|
|
236
|
+
geolocation: formatGeolocationHeader(geolocation)
|
|
237
|
+
}
|
|
208
238
|
});
|
|
209
239
|
},
|
|
210
|
-
details(id) {
|
|
240
|
+
details(id, options) {
|
|
241
|
+
var _a;
|
|
211
242
|
assertPositiveInteger(id, "id");
|
|
243
|
+
const geolocationHeader = (_a = options == null ? void 0 : options.headers) == null ? void 0 : _a.geolocation;
|
|
212
244
|
return httpRequest(client, ENDPOINT_PATH.CINEMA_DETAIL, {
|
|
213
|
-
queryParams: { cinema_id: id }
|
|
245
|
+
queryParams: { cinema_id: id },
|
|
246
|
+
headers: {
|
|
247
|
+
...options == null ? void 0 : options.headers,
|
|
248
|
+
...geolocationHeader ? { geolocation: formatGeolocationHeader(geolocationHeader) } : {}
|
|
249
|
+
}
|
|
214
250
|
});
|
|
215
251
|
},
|
|
216
252
|
showTimes(params) {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { httpRequest } from './http';
|
|
2
2
|
import type {
|
|
3
|
+
CinemaDetailsRequestOptions,
|
|
3
4
|
CinemaShowTimesParams,
|
|
4
5
|
CinemaShowTimesResponse,
|
|
5
6
|
CinemaDetailsResponse,
|
|
7
|
+
CinemasNearbyParams,
|
|
8
|
+
CinemasNearbyRequestOptions,
|
|
6
9
|
CinemasNearbyResponse,
|
|
7
10
|
FilmDetailsResponse,
|
|
8
11
|
FilmsComingSoonResponse,
|
|
9
12
|
FilmsNowShowing,
|
|
13
|
+
GeolocationInput,
|
|
10
14
|
ListParams,
|
|
11
15
|
MovieGluClientConfig,
|
|
12
16
|
MovieGluSdk,
|
|
@@ -52,12 +56,35 @@ function assertPositiveInteger(value: number, name: string): void {
|
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
|
|
59
|
+
function assertFiniteNumber(value: number, name: string): void {
|
|
60
|
+
if (!Number.isFinite(value)) {
|
|
61
|
+
throw new TypeError(`${name} must be a finite number`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
55
65
|
function assertDateString(value: string, name: string): void {
|
|
56
66
|
if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
57
67
|
throw new TypeError(`${name} must be in YYYY-MM-DD format`);
|
|
58
68
|
}
|
|
59
69
|
}
|
|
60
70
|
|
|
71
|
+
function formatGeolocationHeader(geolocation: GeolocationInput): string {
|
|
72
|
+
if (typeof geolocation === 'string') {
|
|
73
|
+
const value = geolocation.trim();
|
|
74
|
+
if (!value) {
|
|
75
|
+
throw new TypeError('geolocation header must not be empty');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
assertFiniteNumber(geolocation.lat, 'geolocation.lat');
|
|
82
|
+
assertFiniteNumber(geolocation.lng, 'geolocation.lng');
|
|
83
|
+
|
|
84
|
+
// MovieGlu accepts geolocation in "lat;lng" format.
|
|
85
|
+
return `${geolocation.lat};${geolocation.lng}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
61
88
|
function toListQuery(params: ListParams): { n: number } {
|
|
62
89
|
assertPositiveInteger(params.limit, 'limit');
|
|
63
90
|
return { n: params.limit };
|
|
@@ -119,6 +146,7 @@ export function createMovieGluClient(config: MovieGluClientConfig): MovieGluSdk
|
|
|
119
146
|
baseUrl: normalizeBaseUrl(config.baseUrl ?? DEFAULT_BASE_URL),
|
|
120
147
|
apiKey: config.apiKey,
|
|
121
148
|
headers: config.headers,
|
|
149
|
+
geolocation: config.geolocation,
|
|
122
150
|
fetch: config.fetch,
|
|
123
151
|
};
|
|
124
152
|
|
|
@@ -142,15 +170,33 @@ export function createMovieGluClient(config: MovieGluClientConfig): MovieGluSdk
|
|
|
142
170
|
},
|
|
143
171
|
},
|
|
144
172
|
cinemas: {
|
|
145
|
-
nearby(params:
|
|
173
|
+
nearby(params: CinemasNearbyParams, options?: CinemasNearbyRequestOptions): Promise<CinemasNearbyResponse> {
|
|
174
|
+
const geolocationHeader = options?.headers?.geolocation;
|
|
175
|
+
const geolocation = geolocationHeader ?? client.geolocation;
|
|
176
|
+
if (!geolocation) {
|
|
177
|
+
throw new TypeError(
|
|
178
|
+
'geolocation header is required for cinemas.nearby. Pass nearby(..., { headers: { geolocation } }) or createMovieGluClient({ geolocation }).',
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
146
182
|
return httpRequest<CinemasNearbyResponse>(client, ENDPOINT_PATH.CINEMA_NEARBY, {
|
|
147
183
|
queryParams: toListQuery(params),
|
|
184
|
+
headers: {
|
|
185
|
+
...options?.headers,
|
|
186
|
+
geolocation: formatGeolocationHeader(geolocation),
|
|
187
|
+
},
|
|
148
188
|
});
|
|
149
189
|
},
|
|
150
|
-
details(id: number): Promise<CinemaDetailsResponse> {
|
|
190
|
+
details(id: number, options?: CinemaDetailsRequestOptions): Promise<CinemaDetailsResponse> {
|
|
151
191
|
assertPositiveInteger(id, 'id');
|
|
192
|
+
const geolocationHeader = options?.headers?.geolocation;
|
|
193
|
+
|
|
152
194
|
return httpRequest<CinemaDetailsResponse>(client, ENDPOINT_PATH.CINEMA_DETAIL, {
|
|
153
195
|
queryParams: { cinema_id: id },
|
|
196
|
+
headers: {
|
|
197
|
+
...options?.headers,
|
|
198
|
+
...(geolocationHeader ? { geolocation: formatGeolocationHeader(geolocationHeader) } : {}),
|
|
199
|
+
},
|
|
154
200
|
});
|
|
155
201
|
},
|
|
156
202
|
showTimes(params: CinemaShowTimesParams): Promise<CinemaShowTimesResponse> {
|
package/src/type.ts
CHANGED
|
@@ -27,6 +27,7 @@ export type Client = {
|
|
|
27
27
|
baseUrl: string;
|
|
28
28
|
apiKey: string;
|
|
29
29
|
headers?: Record<string, string>;
|
|
30
|
+
geolocation?: GeolocationInput;
|
|
30
31
|
fetch?: FetchLike;
|
|
31
32
|
};
|
|
32
33
|
|
|
@@ -34,6 +35,7 @@ export type MovieGluClientConfig = {
|
|
|
34
35
|
apiKey: string;
|
|
35
36
|
baseUrl?: string;
|
|
36
37
|
headers?: Record<string, string>;
|
|
38
|
+
geolocation?: GeolocationInput;
|
|
37
39
|
fetch?: FetchLike;
|
|
38
40
|
};
|
|
39
41
|
|
|
@@ -48,6 +50,13 @@ export type ListParams = {
|
|
|
48
50
|
limit: number;
|
|
49
51
|
};
|
|
50
52
|
|
|
53
|
+
export type GeolocationInput = string | UserLocation;
|
|
54
|
+
|
|
55
|
+
export type CinemasNearbyParams = ListParams;
|
|
56
|
+
|
|
57
|
+
export type CinemasNearbyRequestOptions = Pick<RequestOptions, 'headers'>;
|
|
58
|
+
export type CinemaDetailsRequestOptions = Pick<RequestOptions, 'headers'>;
|
|
59
|
+
|
|
51
60
|
export type MovieGluSdk = {
|
|
52
61
|
films: {
|
|
53
62
|
nowShowing(params: ListParams): Promise<FilmsNowShowing>;
|
|
@@ -55,8 +64,8 @@ export type MovieGluSdk = {
|
|
|
55
64
|
details(id: number): Promise<FilmDetailsResponse>;
|
|
56
65
|
};
|
|
57
66
|
cinemas: {
|
|
58
|
-
nearby(params:
|
|
59
|
-
details(id: number): Promise<CinemaDetailsResponse>;
|
|
67
|
+
nearby(params: CinemasNearbyParams, options?: CinemasNearbyRequestOptions): Promise<CinemasNearbyResponse>;
|
|
68
|
+
details(id: number, options?: CinemaDetailsRequestOptions): Promise<CinemaDetailsResponse>;
|
|
60
69
|
showTimes(params: CinemaShowTimesParams): Promise<CinemaShowTimesResponse>;
|
|
61
70
|
};
|
|
62
71
|
};
|